From f114079c30f89148dd469a5e2d36fe7dbc65fbfc Mon Sep 17 00:00:00 2001 From: Felix Angelov Date: Mon, 15 May 2023 13:41:06 -0500 Subject: [PATCH] feat(code_push_client): add `createAppCollaborator` (#493) --- .../lib/src/code_push_client.dart | 16 ++++ .../test/src/code_push_client_test.dart | 84 +++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/packages/shorebird_code_push_client/lib/src/code_push_client.dart b/packages/shorebird_code_push_client/lib/src/code_push_client.dart index fecf2cde..ef573669 100644 --- a/packages/shorebird_code_push_client/lib/src/code_push_client.dart +++ b/packages/shorebird_code_push_client/lib/src/code_push_client.dart @@ -40,6 +40,22 @@ class CodePushClient { /// The hosted uri for the Shorebird CodePush API. final Uri hostedUri; + /// Add a new collaborator to the app. + /// Collaborators can manage the app including its releases and patches. + Future createAppCollaborator({ + required String appId, + required int userId, + }) async { + final response = await _httpClient.post( + Uri.parse('$hostedUri/api/v1/apps/$appId/collaborators'), + body: json.encode(CreateAppCollaboratorRequest(userId: userId).toJson()), + ); + + if (response.statusCode != HttpStatus.created) { + throw _parseErrorResponse(response.body); + } + } + /// Fetches the currently logged-in user. Future getCurrentUser() async { final uri = Uri.parse('$hostedUri/api/v1/users/me'); diff --git a/packages/shorebird_code_push_client/test/src/code_push_client_test.dart b/packages/shorebird_code_push_client/test/src/code_push_client_test.dart index 40aa4ca9..da2550c6 100644 --- a/packages/shorebird_code_push_client/test/src/code_push_client_test.dart +++ b/packages/shorebird_code_push_client/test/src/code_push_client_test.dart @@ -53,6 +53,90 @@ void main() { }); }); + group('createAppCollaborator', () { + const appId = 'test-app-id'; + const userId = 42; + + test('throws an exception if the http request fails (unknown)', () async { + when( + () => httpClient.post( + any(), + headers: any(named: 'headers'), + body: any(named: 'body'), + ), + ).thenAnswer( + (_) async => http.Response('', HttpStatus.failedDependency), + ); + + expect( + codePushClient.createAppCollaborator(appId: appId, userId: userId), + throwsA( + isA().having( + (e) => e.message, + 'message', + CodePushClient.unknownErrorMessage, + ), + ), + ); + }); + + test('throws an exception if the http request fails', () async { + when( + () => httpClient.post( + any(), + headers: any(named: 'headers'), + body: any(named: 'body'), + ), + ).thenAnswer( + (_) async => http.Response( + json.encode(errorResponse.toJson()), + HttpStatus.failedDependency, + ), + ); + + expect( + codePushClient.createAppCollaborator(appId: appId, userId: userId), + throwsA( + isA().having( + (e) => e.message, + 'message', + errorResponse.message, + ), + ), + ); + }); + + test('completes when request succeeds', () async { + when( + () => httpClient.post( + any(), + headers: any(named: 'headers'), + body: any(named: 'body'), + ), + ).thenAnswer((_) async => http.Response('', HttpStatus.created)); + + await codePushClient.createAppCollaborator( + appId: appId, + userId: userId, + ); + + final uri = verify( + () => httpClient.post( + captureAny(), + headers: any(named: 'headers'), + body: any(named: 'body'), + ), + ).captured.single as Uri; + + expect( + uri, + codePushClient.hostedUri.replace( + path: '/api/v1/apps/$appId/collaborators', + ), + ); + }); + }); + group('getCurrentUser', () { const user = User(id: 123, email: 'tester@shorebird.dev');