From 5df1ba7821a04be3c043eb10e6bfcec288a0818a Mon Sep 17 00:00:00 2001 From: Kraigo Date: Thu, 9 Feb 2023 15:25:42 +0200 Subject: [PATCH 1/2] fix: list value for GET search params --- lib/src/core/service_helper.dart | 10 ++-- .../v1/accounts/accounts_v1_service.dart | 10 +++- test/mocks/client_context_stubs.dart | 37 ++++++++------ .../v1/accounts/accounts_v1_service_test.dart | 48 ++++++++++++++----- .../notifications_v1_service_test.dart | 27 +++++++++-- 5 files changed, 94 insertions(+), 38 deletions(-) diff --git a/lib/src/core/service_helper.dart b/lib/src/core/service_helper.dart index b8cf0db..8adc85a 100644 --- a/lib/src/core/service_helper.dart +++ b/lib/src/core/service_helper.dart @@ -284,7 +284,7 @@ class ServiceHelper implements Service { return object; } - Map _convertQueryParameters( + Map _convertQueryParameters( final Map queryParameters, ) { final serializedParameters = queryParameters.map((key, value) { @@ -301,16 +301,16 @@ class ServiceHelper implements Service { } else if (value is List?) { return MapEntry( key, - value?.toSet().join(','), + value?.map((e) => e.toString()).toList() ); } else if (value is Serializable) { return MapEntry( key, - value.value, + value.value.toString(), ); } - return MapEntry(key, value); + return MapEntry(key, value.toString()); }); return Map.from(_removeNullValues(serializedParameters) ?? {}).map( @@ -322,7 +322,7 @@ class ServiceHelper implements Service { return MapEntry(key, value.toUtc().toIso8601String()); } - return MapEntry(key, value.toString()); + return MapEntry(key, value); }, ); } diff --git a/lib/src/service/v1/accounts/accounts_v1_service.dart b/lib/src/service/v1/accounts/accounts_v1_service.dart index b8b5181..bb66b48 100644 --- a/lib/src/service/v1/accounts/accounts_v1_service.dart +++ b/lib/src/service/v1/accounts/accounts_v1_service.dart @@ -1733,7 +1733,10 @@ class _AccountsV1Service extends BaseService implements AccountsV1Service { super.transformMultiDataResponse( await super.get( UserContext.oauth2Only, - '/api/v1/accounts/relationships?${accountIds.map((e) => 'id[]=$e').join('&')}', + '/api/v1/accounts/relationships', + queryParameters: { + 'id[]': accountIds, + } ), dataBuilder: Relationship.fromJson, ); @@ -1745,7 +1748,10 @@ class _AccountsV1Service extends BaseService implements AccountsV1Service { super.transformMultiDataResponse( await super.get( UserContext.oauth2Only, - '/api/v1/accounts/familiar_followers?${accountIds.map((e) => 'id[]=$e').join('&')}', + '/api/v1/accounts/familiar_followers', + queryParameters: { + 'id[]': accountIds + } ), dataBuilder: FamiliarFollower.fromJson, ); diff --git a/test/mocks/client_context_stubs.dart b/test/mocks/client_context_stubs.dart index 51bcf56..a9b3331 100644 --- a/test/mocks/client_context_stubs.dart +++ b/test/mocks/client_context_stubs.dart @@ -18,15 +18,16 @@ MockClientContext buildGetStub( final UserContext userContext, final String unencodedPath, final String resourcePath, - final Map queryParameters, { + final Map queryParameters, { Map headers = const {}, int statusCode = 200, }) { final mockClientContext = MockClientContext(); + final requestUri = Uri.https(instance, unencodedPath, queryParameters); when(mockClientContext.get( userContext, - Uri.https(instance, unencodedPath, queryParameters), + requestUri, headers: headers, )).thenAnswer( (_) async => Response( @@ -35,7 +36,7 @@ MockClientContext buildGetStub( headers: {'content-type': 'application/json; charset=utf-8'}, request: Request( 'GET', - Uri(), + requestUri, ), ), ); @@ -51,10 +52,11 @@ MockClientContext buildPostStub( int statusCode = 200, }) { final mockClientContext = MockClientContext(); + final requestUri = Uri.https(instance, unencodedPath, {}); when(mockClientContext.post( userContext, - Uri.https(instance, unencodedPath, {}), + requestUri, headers: anyNamed('headers'), body: anyNamed('body'), )).thenAnswer( @@ -66,7 +68,7 @@ MockClientContext buildPostStub( }, request: Request( 'POST', - Uri(), + requestUri, ), ), ); @@ -83,10 +85,11 @@ MockClientContext buildPostMultipartStub( int statusCode = 200, }) { final mockClientContext = MockClientContext(); + final requestUri = Uri.https(instance, unencodedPath, queryParameters); when(mockClientContext.postMultipart( userContext, - Uri.https(instance, unencodedPath, queryParameters), + requestUri, files: anyNamed('files'), )).thenAnswer( (_) async => Response( @@ -97,7 +100,7 @@ MockClientContext buildPostMultipartStub( }, request: Request( 'POST', - Uri(), + requestUri, ), ), ); @@ -112,10 +115,11 @@ MockClientContext buildDeleteStub( int statusCode = 200, }) { final mockClientContext = MockClientContext(); + final requestUri = Uri.https(instance, unencodedPath); when(mockClientContext.delete( UserContext.oauth2Only, - Uri.https(instance, unencodedPath), + requestUri, body: anyNamed('body'), )).thenAnswer( (_) async => Response( @@ -124,7 +128,7 @@ MockClientContext buildDeleteStub( headers: {'content-type': 'application/json; charset=utf-8'}, request: Request( 'DELETE', - Uri(), + requestUri, ), ), ); @@ -139,10 +143,11 @@ MockClientContext buildPutStub( int statusCode = 200, }) { final mockClientContext = MockClientContext(); + final requestUri = Uri.https(instance, unencodedPath); when(mockClientContext.put( UserContext.oauth2Only, - Uri.https(instance, unencodedPath), + requestUri, headers: anyNamed('headers'), body: anyNamed('body'), )).thenAnswer( @@ -152,7 +157,7 @@ MockClientContext buildPutStub( headers: {'content-type': 'application/json; charset=utf-8'}, request: Request( 'PUT', - Uri(), + requestUri, ), ), ); @@ -168,10 +173,11 @@ MockClientContext buildPatchStub( int statusCode = 200, }) { final mockClientContext = MockClientContext(); + final requestUri = Uri.https(instance, unencodedPath); when(mockClientContext.patch( userContext, - Uri.https(instance, unencodedPath), + requestUri, headers: anyNamed('headers'), body: anyNamed('body'), )).thenAnswer( @@ -181,7 +187,7 @@ MockClientContext buildPatchStub( headers: {'content-type': 'application/json; charset=utf-8'}, request: Request( 'PATCH', - Uri(), + requestUri, ), ), ); @@ -197,10 +203,11 @@ MockClientContext buildPatchMultipartStub( int statusCode = 200, }) { final mockClientContext = MockClientContext(); + final requestUri = Uri.https(instance, unencodedPath); when(mockClientContext.patchMultipart( userContext, - Uri.https(instance, unencodedPath), + requestUri, files: anyNamed('files'), )).thenAnswer( (_) async => Response( @@ -209,7 +216,7 @@ MockClientContext buildPatchMultipartStub( headers: {'content-type': 'application/json; charset=utf-8'}, request: Request( 'PATCH', - Uri(), + requestUri, ), ), ); diff --git a/test/src/service/v1/accounts/accounts_v1_service_test.dart b/test/src/service/v1/accounts/accounts_v1_service_test.dart index 964694b..6d1e3c8 100644 --- a/test/src/service/v1/accounts/accounts_v1_service_test.dart +++ b/test/src/service/v1/accounts/accounts_v1_service_test.dart @@ -1313,9 +1313,11 @@ void main() { context: context.buildGetStub( 'test', UserContext.oauth2Only, - '/api/v1/accounts/relationships?id[]=1&id[]=2', + '/api/v1/accounts/relationships', 'test/src/service/v1/accounts/data/lookup_relationships.json', - {}, + { + 'id[]': ['1', '2'], + }, ), ); @@ -1325,6 +1327,12 @@ void main() { expect(response, isA()); expect(response.rateLimit, isA()); expect(response.data, isA>()); + expect( + response.request.url, + Uri.parse("https://test/api/v1/accounts/relationships" + "?id[]=1" + "&id[]=2"), + ); }); test('when unauthorized', () async { @@ -1333,9 +1341,11 @@ void main() { context: context.buildGetStub( 'test', UserContext.oauth2Only, - '/api/v1/accounts/relationships?id[]=1&id[]=2', + '/api/v1/accounts/relationships', 'test/src/service/v1/accounts/data/lookup_relationships.json', - {}, + { + 'id[]': ['1', '2'], + }, statusCode: 401, ), ); @@ -1352,9 +1362,11 @@ void main() { context: context.buildGetStub( 'test', UserContext.oauth2Only, - '/api/v1/accounts/relationships?id[]=1&id[]=2', + '/api/v1/accounts/relationships', 'test/src/service/v1/accounts/data/lookup_relationships.json', - {}, + { + 'id[]': ['1', '2'], + }, statusCode: 429, ), ); @@ -1373,9 +1385,11 @@ void main() { context: context.buildGetStub( 'test', UserContext.oauth2Only, - '/api/v1/accounts/familiar_followers?id[]=1&id[]=2', + '/api/v1/accounts/familiar_followers', 'test/src/service/v1/accounts/data/lookup_familiar_followers.json', - {}, + { + 'id[]': ['1', '2'], + }, ), ); @@ -1385,6 +1399,12 @@ void main() { expect(response, isA()); expect(response.rateLimit, isA()); expect(response.data, isA>()); + expect( + response.request.url, + Uri.parse("https://test/api/v1/accounts/familiar_followers" + "?id[]=1" + "&id[]=2"), + ); }); test('when unauthorized', () async { @@ -1393,9 +1413,11 @@ void main() { context: context.buildGetStub( 'test', UserContext.oauth2Only, - '/api/v1/accounts/familiar_followers?id[]=1&id[]=2', + '/api/v1/accounts/familiar_followers', 'test/src/service/v1/accounts/data/lookup_familiar_followers.json', - {}, + { + 'id[]': ['1', '2'], + }, statusCode: 401, ), ); @@ -1412,9 +1434,11 @@ void main() { context: context.buildGetStub( 'test', UserContext.oauth2Only, - '/api/v1/accounts/familiar_followers?id[]=1&id[]=2', + '/api/v1/accounts/familiar_followers', 'test/src/service/v1/accounts/data/lookup_familiar_followers.json', - {}, + { + 'id[]': ['1', '2'], + }, statusCode: 429, ), ); diff --git a/test/src/service/v1/notifications/notifications_v1_service_test.dart b/test/src/service/v1/notifications/notifications_v1_service_test.dart index 67edbc8..a211352 100644 --- a/test/src/service/v1/notifications/notifications_v1_service_test.dart +++ b/test/src/service/v1/notifications/notifications_v1_service_test.dart @@ -31,8 +31,14 @@ void main() { 'since_id': '0987', 'min_id': '1234', 'limit': '40', - 'types[]': NotificationType.mention.value, - 'exclude_types[]': NotificationType.follow.value, + 'types[]': [ + NotificationType.mention.value, + NotificationType.favourite.value + ], + 'exclude_types[]': [ + NotificationType.follow.value, + NotificationType.poll.value + ], 'account_id': '1111', }), ); @@ -42,14 +48,27 @@ void main() { sinceNotificationId: '0987', minNotificationId: '1234', limit: 40, - types: [NotificationType.mention], - excludeTypes: [NotificationType.follow], + types: [NotificationType.mention, NotificationType.favourite], + excludeTypes: [NotificationType.follow, NotificationType.poll], accountId: '1111', ); expect(response, isA()); expect(response.rateLimit, isA()); expect(response.data, isA>()); + expect( + response.request.url, + Uri.parse("https://test/api/v1/notifications" + "?max_id=5678" + "&since_id=0987" + "&min_id=1234" + "&limit=40" + "&types[]=${NotificationType.mention.value}" + "&types[]=${NotificationType.favourite.value}" + "&exclude_types[]=${NotificationType.follow.value}" + "&exclude_types[]=${NotificationType.poll.value}" + "&account_id=1111"), + ); }); test('when unauthorized', () async { From d2c076dbadac8700e4065c112969f8cea8d42394 Mon Sep 17 00:00:00 2001 From: Kraigo Date: Mon, 13 Feb 2023 19:22:39 +0200 Subject: [PATCH 2/2] fix: remove unnessesary toString for Serializable --- lib/src/core/service_helper.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/core/service_helper.dart b/lib/src/core/service_helper.dart index 8adc85a..343eaef 100644 --- a/lib/src/core/service_helper.dart +++ b/lib/src/core/service_helper.dart @@ -306,7 +306,7 @@ class ServiceHelper implements Service { } else if (value is Serializable) { return MapEntry( key, - value.value.toString(), + value.value, ); }