Skip to content

Commit

Permalink
Merge #97
Browse files Browse the repository at this point in the history
97: feat:  Added `Lists Pinnings` endpoints (#31) r=myConsciousness a=myConsciousness

# 1. Description

<!-- Provide a description of what this PR is doing.
If you're modifying existing behavior, describe the existing behavior, how this PR is changing it,
and what motivated the change. If this is a breaking change, specify explicitly which APIs have been
changed. -->

## 1.1. Checklist

<!-- Before you create this PR confirm that it meets all requirements listed below by checking the
relevant checkboxes (`[x]`). This will ensure a smooth and quick review process. -->

- [x] The title of my PR starts with a [Conventional Commit] prefix (`fix:`, `feat:`, `docs:` etc).
- [x] I have read the [Contributor Guide] and followed the process outlined for submitting PRs.
- [x] I have updated/added tests for ALL new/updated/fixed functionality.
- [x] I have updated/added relevant documentation in `docs` and added dartdoc comments with `///`.
- [x] I have updated/added relevant examples in `examples`.

## 1.2. Breaking Change

<!-- Does your PR require users to manually update their apps to accommodate your change?

If the PR is a breaking change this should be indicated with suffix "!"  (for example, `feat!:`, `fix!:`). See [Conventional Commit] for details.
-->

- [ ] Yes, this is a breaking change.
- [x] No, this is _not_ a breaking change.

## 1.3. Related Issues

<!-- Provide a list of issues related to this PR from the [issue database].
Indicate which of these issues are resolved or fixed by this PR, i.e. Fixes #xxxx* !-->

<!-- Links -->

[issue database]: https://github.com/twitter-dart/twitter-api-v2/issues
[contributor guide]: https://github.com/twitter-dart/twitter-api-v2/blob/main/CONTRIBUTING.md
[style guide]: https://github.com/twitter-dart/twitter-api-v2/blob/main/STYLEGUIDE.md
[conventional commit]: https://conventionalcommits.org


Co-authored-by: myConsciousness <kato.shinya.dev@gmail.com>
  • Loading branch information
bors[bot] and myConsciousness authored May 10, 2022
2 parents 01f0d35 + 4223e18 commit fb5d8df
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
- DELETE /2/users/:source_user_id/blocking/:target_user_id
- GET /2/users/:id/blocking
- POST /2/users/:id/blocking
- Added **Lists Pinnings** endpoints. ([#31](https://github.com/twitter-dart/twitter-api-v2/issues/31))
- DELETE /2/users/:id/pinned_lists/:list_id
- GET /2/users/:id/pinned_lists
- POST /2/users/:id/pinned_lists

## v1.6.0

Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,15 @@ void main() async {
4. [GET /2/spaces/:id/tweets](https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id-tweets)
5. [GET /2/spaces/by/creator_ids](https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-by-creator-ids)
4. **Lists**

1. **Lookup Lists**
1. [GET /2/lists/:id](https://developer.twitter.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-lists-id)
2. [GET /2/users/:id/owned_lists](https://developer.twitter.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-users-id-owned_lists)
2. **Pinnings**
1. [DELETE /2/users/:id/pinned_lists/:list_id](https://developer.twitter.com/en/docs/twitter-api/lists/pinned-lists/api-reference/delete-users-id-pinned-lists-list_id)
2. [GET /2/users/:id/pinned_lists](https://developer.twitter.com/en/docs/twitter-api/lists/pinned-lists/api-reference/get-users-id-pinned_lists)
3. [POST /2/users/:id/pinned_lists](https://developer.twitter.com/en/docs/twitter-api/lists/pinned-lists/api-reference/post-users-id-pinned-lists)

5. **Compliance**
1. **Batch Compliance**
1. [GET /2/compliance/jobs](https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/get-compliance-jobs)
Expand Down
116 changes: 116 additions & 0 deletions lib/src/service/lists/lists_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,83 @@ abstract class ListsService {
/// - https://developer.twitter.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-users-id-owned_lists
Future<TwitterResponse<List<ListData>, ListMeta>> lookupOwnedBy(
{required String userId, int? maxResults, String? paginationToken});

/// Enables the authenticated user to pin a List.
///
/// ## Parameters
///
/// - [userId]: The user ID who you are pinning a List on behalf of.
/// It must match your own user ID or that of an authenticating
/// user, meaning that you must pass the Access Tokens associated
/// with the user ID when authenticating your request.
///
/// - [listId]: The ID of the List that you would like the user id to pin.
///
/// ## Endpoint Url
///
/// - https://api.twitter.com/2/users/:id/owned_lists
///
/// ## Rate Limits
///
/// - **User rate limit (OAuth 2.0 user Access Token)**:
/// 50 requests per 15-minute window per each authenticated user
///
/// ## Reference
///
/// - https://developer.twitter.com/en/docs/twitter-api/lists/pinned-lists/api-reference/post-users-id-pinned-lists
Future<bool> createPinnedList(
{required String userId, required String listId});

/// Enables the authenticated user to unpin a List.
///
/// ## Parameters
///
/// - [userId]: The user ID who you are unpin a List on behalf of. It must
/// match your own user ID or that of an authenticating user,
/// meaning that you must pass the Access Tokens associated with
/// the user ID when authenticating your request.
///
/// - [listId]: The ID of the List that you would like the user id to unpin.
///
/// ## Endpoint Url
///
/// - https://api.twitter.com/2/users/:id/pinned_lists/:list_id
///
/// ## Rate Limits
///
/// - **User rate limit (OAuth 2.0 user Access Token)**:
/// 50 requests per 15-minute window per each authenticated user
///
/// ## Reference
///
/// - https://developer.twitter.com/en/docs/twitter-api/lists/pinned-lists/api-reference/delete-users-id-pinned-lists-list_id
Future<bool> destroyPinnedList(
{required String userId, required String listId});

/// Returns the Lists pinned by a specified user.
///
/// ## Parameters
///
/// - [userId]: The user ID whose pinned Lists you would like to retrieve.
/// The user’s ID must correspond to the user ID of the
/// authenticating user, meaning that you must pass the Access
/// Tokens associated with the user ID when authenticating your
/// request.
///
/// ## Endpoint Url
///
/// - https://api.twitter.com/2/users/:id/pinned_lists
///
/// ## Rate Limits
///
/// - **User rate limit (OAuth 2.0 user Access Token)**:
/// 15 requests per 15-minute window per each authenticated user
///
/// ## Reference
///
/// - https://developer.twitter.com/en/docs/twitter-api/lists/pinned-lists/api-reference/get-users-id-pinned_lists
Future<TwitterResponse<List<ListData>, ListMeta>> pinnedLists(
{required String userId});
}

class _ListsService extends BaseService implements ListsService {
Expand Down Expand Up @@ -111,4 +188,43 @@ class _ListsService extends BaseService implements ListsService {
meta: ListMeta.fromJson(response['meta']),
);
}

@override
Future<bool> createPinnedList(
{required String userId, required String listId}) async {
final response = await super.post(
UserContext.oauth2OrOAuth1,
'/2/users/$userId/pinned_lists',
body: {'list_id': listId},
);

return response['data']['pinned'];
}

@override
Future<bool> destroyPinnedList(
{required String userId, required String listId}) async {
final response = await super.delete(
UserContext.oauth2OrOAuth1,
'/2/users/$userId/pinned_lists/$listId',
);

return !response['data']['pinned'];
}

@override
Future<TwitterResponse<List<ListData>, ListMeta>> pinnedLists(
{required String userId}) async {
final response = await super.get(
UserContext.oauth2OrOAuth1,
'/2/users/$userId/pinned_lists',
);

return TwitterResponse(
data: response['data']
.map<ListData>((list) => ListData.fromJson(list))
.toList(),
meta: ListMeta.fromJson(response['meta']),
);
}
}
5 changes: 5 additions & 0 deletions test/src/service/lists/data/create_pinned_list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"data": {
"pinned": true
}
}
5 changes: 5 additions & 0 deletions test/src/service/lists/data/destroy_pinned_list.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"data": {
"pinned": false
}
}
11 changes: 11 additions & 0 deletions test/src/service/lists/data/pinned_lists.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"data": [
{
"id": "1451305624956858369",
"name": "Test List"
}
],
"meta": {
"result_count": 1
}
}
54 changes: 54 additions & 0 deletions test/src/service/lists/lists_service_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,58 @@ void main() {
expect(response.meta!.nextToken, 'NEXT_TOKEN');
expect(response.meta!.previousToken, 'PREVIOUS_TOKEN');
});

test('.createPinnedList', () async {
final listsService = ListsService(
context: context.buildPostStub(
UserContext.oauth2OrOAuth1,
'/2/users/5555/pinned_lists',
'test/src/service/lists/data/create_pinned_list.json',
),
);

final response = await listsService.createPinnedList(
userId: '5555',
listId: '1111',
);

expect(response, isA<bool>());
expect(response, isTrue);
});

test('.destroyPinnedList', () async {
final listsService = ListsService(
context: context.buildDeleteStub(
'/2/users/5555/pinned_lists/1111',
'test/src/service/lists/data/destroy_pinned_list.json',
),
);

final response = await listsService.destroyPinnedList(
userId: '5555',
listId: '1111',
);

expect(response, isA<bool>());
expect(response, isTrue);
});

test('.pinnedLists', () async {
final listsService = ListsService(
context: context.buildGetStub(
UserContext.oauth2OrOAuth1,
'/2/users/5555/pinned_lists',
'test/src/service/lists/data/pinned_lists.json',
{},
),
);

final response = await listsService.pinnedLists(userId: '5555');

expect(response, isA<TwitterResponse>());
expect(response.data, isA<List<ListData>>());
expect(response.meta, isA<ListMeta>());
expect(response.data.length, 1);
expect(response.meta!.resultCount, 1);
});
}

0 comments on commit fb5d8df

Please sign in to comment.