From ffd7ad8d5805280694d2a96b3b917589b48c6955 Mon Sep 17 00:00:00 2001 From: Andrew Hahn Date: Tue, 25 Jun 2024 15:13:27 -0700 Subject: [PATCH 01/10] feat: added unit tests --- .../test/plugin/fetch_current_device.dart | 122 ++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device.dart diff --git a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device.dart b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device.dart new file mode 100644 index 0000000000..c68f1509eb --- /dev/null +++ b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device.dart @@ -0,0 +1,122 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import 'package:amplify_auth_cognito_dart/amplify_auth_cognito_dart.dart'; +import 'package:amplify_auth_cognito_dart/src/credentials/cognito_keys.dart'; +import 'package:amplify_auth_cognito_dart/src/credentials/device_metadata_repository.dart'; +import 'package:amplify_auth_cognito_dart/src/sdk/cognito_identity_provider.dart'; +import 'package:amplify_auth_cognito_dart/src/state/cognito_state_machine.dart'; +import 'package:amplify_auth_cognito_test/common/mock_clients.dart'; +import 'package:amplify_auth_cognito_test/common/mock_config.dart'; +import 'package:amplify_auth_cognito_test/common/mock_secure_storage.dart'; +import 'package:amplify_core/amplify_core.dart'; +import 'package:test/test.dart'; + +void main() { + AmplifyLogger().logLevel = LogLevel.verbose; + + final userPoolKeys = CognitoUserPoolKeys(userPoolConfig); + final identityPoolKeys = CognitoIdentityPoolKeys(identityPoolConfig); + final testAuthRepo = AmplifyAuthProviderRepository(); + final mockDevice = DeviceType(deviceKey: deviceKey); + final mockDeviceResponse = GetDeviceResponse(device: mockDevice); + + late DeviceMetadataRepository repo; + late AmplifyAuthCognitoDart plugin; + late CognitoAuthStateMachine stateMachine; + late MockSecureStorage secureStorage; + + Future getDeviceKey() async { + final secrets = await repo.get(username); + return secrets?.deviceKey; + } + + group( + 'fetchCurrentDevice expected return value and DeviceNotTrackedException', + () { + setUp(() async { + secureStorage = MockSecureStorage(); + seedStorage( + secureStorage, + userPoolKeys: userPoolKeys, + identityPoolKeys: identityPoolKeys, + deviceKeys: CognitoDeviceKeys(userPoolConfig, username), + ); + plugin = AmplifyAuthCognitoDart( + secureStorageFactory: (_) => secureStorage, + ); + stateMachine = plugin.stateMachine; + await plugin.configure( + config: mockConfig, + authProviderRepo: testAuthRepo, + ); + final mockIdp = MockCognitoIdentityProviderClient( + getDevice: () async => mockDeviceResponse, + forgetDevice: () async {}, + ); + stateMachine.addInstance(mockIdp); + repo = stateMachine.getOrCreate(); + }); + + test( + 'should get the current device. current device id should be equal to the local device id', + () async { + final currentDeviceKey = await getDeviceKey(); + expect(currentDeviceKey, isNotNull); + final currentDevice = await plugin.fetchCurrentDevice(); + expect(currentDeviceKey, currentDevice.id); + }); + + test( + 'should should throw a DeviceNotTrackedException when current device key is null', + () async { + await plugin.forgetDevice(); + await expectLater( + plugin.fetchCurrentDevice, + throwsA(isA()), + ); + }); + + tearDown(() async { + await plugin.close(); + }); + }); + + group('fetchCurrentDevice AWSHttpException', () { + setUp(() async { + secureStorage = MockSecureStorage(); + seedStorage( + secureStorage, + userPoolKeys: userPoolKeys, + identityPoolKeys: identityPoolKeys, + deviceKeys: CognitoDeviceKeys(userPoolConfig, username), + ); + plugin = AmplifyAuthCognitoDart( + secureStorageFactory: (_) => secureStorage, + ); + stateMachine = plugin.stateMachine; + await plugin.configure( + config: mockConfig, + authProviderRepo: testAuthRepo, + ); + final mockIdp = MockCognitoIdentityProviderClient( + getDevice: () async => throw AWSHttpException( + AWSHttpRequest.get(Uri.parse('https://www.amazon.com')), + ), + ); + stateMachine.addInstance(mockIdp); + repo = stateMachine.getOrCreate(); + }); + + test('should throw a NetworkException', () async { + await expectLater( + plugin.fetchCurrentDevice, + throwsA(isA()), + ); + }); + + tearDown(() async { + await plugin.close(); + }); + }); +} From 97e6278bae26578707186e34d2a9a3c15540015d Mon Sep 17 00:00:00 2001 From: Andrew Hahn Date: Mon, 1 Jul 2024 12:13:14 -0700 Subject: [PATCH 02/10] chore: append test to file name --- .../{fetch_current_device.dart => fetch_current_device_test.dart} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/auth/amplify_auth_cognito_test/test/plugin/{fetch_current_device.dart => fetch_current_device_test.dart} (100%) diff --git a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device.dart b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart similarity index 100% rename from packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device.dart rename to packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart From 685fa377bce5bfc105d18dddceccfb9383813d3e Mon Sep 17 00:00:00 2001 From: Andrew Hahn Date: Mon, 1 Jul 2024 14:01:32 -0700 Subject: [PATCH 03/10] feat: adding implementation for unit test ci --- .../lib/src/auth_plugin_impl.dart | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/packages/auth/amplify_auth_cognito_dart/lib/src/auth_plugin_impl.dart b/packages/auth/amplify_auth_cognito_dart/lib/src/auth_plugin_impl.dart index 608fd09bf0..2c2c788f5a 100644 --- a/packages/auth/amplify_auth_cognito_dart/lib/src/auth_plugin_impl.dart +++ b/packages/auth/amplify_auth_cognito_dart/lib/src/auth_plugin_impl.dart @@ -31,6 +31,7 @@ import 'package:amplify_auth_cognito_dart/src/sdk/cognito_identity_provider.dart ForgotPasswordRequest, GetUserAttributeVerificationCodeRequest, GetUserRequest, + GetDeviceRequest, ListDevicesRequest, ResendConfirmationCodeRequest, UserContextDataType, @@ -39,6 +40,7 @@ import 'package:amplify_auth_cognito_dart/src/sdk/cognito_identity_provider.dart VerifyUserAttributeRequest; import 'package:amplify_auth_cognito_dart/src/sdk/sdk_bridge.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/analytics_metadata_type.dart'; +import 'package:amplify_auth_cognito_dart/src/sdk/src/cognito_identity_provider/model/get_device_response.dart'; import 'package:amplify_auth_cognito_dart/src/state/cognito_state_machine.dart'; import 'package:amplify_auth_cognito_dart/src/state/state.dart'; import 'package:amplify_auth_cognito_dart/src/util/cognito_iam_auth_provider.dart'; @@ -97,6 +99,7 @@ class AmplifyAuthCognitoDart extends AuthPluginInterface late CognitoAuthStateMachine _stateMachine = CognitoAuthStateMachine( dependencyManager: dependencies, ); + StreamSubscription? _stateMachineSubscription; /// The underlying state machine, for use in subclasses. @@ -993,6 +996,46 @@ class AmplifyAuthCognitoDart extends AuthPluginInterface .result; } + @override + Future fetchCurrentDevice() async { + final tokens = await stateMachine.getUserPoolTokens(); + final deviceSecrets = await _deviceRepo.get(tokens.username); + final deviceKey = deviceSecrets?.deviceKey; + if (deviceSecrets == null || deviceKey == null) { + throw const DeviceNotTrackedException(); + } + + late GetDeviceResponse response; + + try { + response = await _cognitoIdp + .getDevice( + cognito.GetDeviceRequest( + deviceKey: deviceKey, + accessToken: tokens.accessToken.raw, + ), + ) + .result; + } on Exception catch (error) { + throw AuthException.fromException(error); + } + + final device = response.device; + final attributes = + device.deviceAttributes ?? const []; + + return CognitoDevice( + id: deviceKey, + attributes: { + for (final attribute in attributes) + attribute.name: attribute.value ?? '', + }, + createdDate: device.deviceCreateDate, + lastAuthenticatedDate: device.deviceLastAuthenticatedDate, + lastModifiedDate: device.deviceLastModifiedDate, + ); + } + @override Future> fetchDevices() async { final allDevices = []; From 1cbc9fa2fa68f74bbf98d7504efa52158ebd5118 Mon Sep 17 00:00:00 2001 From: Andrew Hahn Date: Mon, 15 Jul 2024 10:31:48 -0700 Subject: [PATCH 04/10] test: restructure fetchcurrentdevice test --- .../plugin/fetch_current_device_test.dart | 107 +++++++----------- 1 file changed, 43 insertions(+), 64 deletions(-) diff --git a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart index c68f1509eb..be88b2142c 100644 --- a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart +++ b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart @@ -5,7 +5,6 @@ import 'package:amplify_auth_cognito_dart/amplify_auth_cognito_dart.dart'; import 'package:amplify_auth_cognito_dart/src/credentials/cognito_keys.dart'; import 'package:amplify_auth_cognito_dart/src/credentials/device_metadata_repository.dart'; import 'package:amplify_auth_cognito_dart/src/sdk/cognito_identity_provider.dart'; -import 'package:amplify_auth_cognito_dart/src/state/cognito_state_machine.dart'; import 'package:amplify_auth_cognito_test/common/mock_clients.dart'; import 'package:amplify_auth_cognito_test/common/mock_config.dart'; import 'package:amplify_auth_cognito_test/common/mock_secure_storage.dart'; @@ -23,19 +22,15 @@ void main() { late DeviceMetadataRepository repo; late AmplifyAuthCognitoDart plugin; - late CognitoAuthStateMachine stateMachine; - late MockSecureStorage secureStorage; Future getDeviceKey() async { final secrets = await repo.get(username); return secrets?.deviceKey; } - group( - 'fetchCurrentDevice expected return value and DeviceNotTrackedException', - () { + group('fetchCurrentDevice', () { setUp(() async { - secureStorage = MockSecureStorage(); + final secureStorage = MockSecureStorage(); seedStorage( secureStorage, userPoolKeys: userPoolKeys, @@ -45,74 +40,58 @@ void main() { plugin = AmplifyAuthCognitoDart( secureStorageFactory: (_) => secureStorage, ); - stateMachine = plugin.stateMachine; await plugin.configure( config: mockConfig, authProviderRepo: testAuthRepo, ); - final mockIdp = MockCognitoIdentityProviderClient( - getDevice: () async => mockDeviceResponse, - forgetDevice: () async {}, - ); - stateMachine.addInstance(mockIdp); - repo = stateMachine.getOrCreate(); + repo = plugin.stateMachine.getOrCreate(); }); - test( - 'should get the current device. current device id should be equal to the local device id', - () async { - final currentDeviceKey = await getDeviceKey(); - expect(currentDeviceKey, isNotNull); - final currentDevice = await plugin.fetchCurrentDevice(); - expect(currentDeviceKey, currentDevice.id); - }); + group('Cognito GetDevice returns successfully', () { + setUp(() async { + final mockIdp = MockCognitoIdentityProviderClient( + getDevice: () async => mockDeviceResponse, + forgetDevice: () async {}, + ); + plugin.stateMachine.addInstance(mockIdp); + }); - test( - 'should should throw a DeviceNotTrackedException when current device key is null', - () async { - await plugin.forgetDevice(); - await expectLater( - plugin.fetchCurrentDevice, - throwsA(isA()), - ); - }); + test( + 'should get the current device. current device id should be equal to the local device id', + () async { + final currentDeviceKey = await getDeviceKey(); + expect(currentDeviceKey, isNotNull); + final currentDevice = await plugin.fetchCurrentDevice(); + expect(currentDeviceKey, currentDevice.id); + }); - tearDown(() async { - await plugin.close(); + test( + 'should should throw a DeviceNotTrackedException when current device key is null', + () async { + await plugin.forgetDevice(); + await expectLater( + plugin.fetchCurrentDevice, + throwsA(isA()), + ); + }); }); - }); - group('fetchCurrentDevice AWSHttpException', () { - setUp(() async { - secureStorage = MockSecureStorage(); - seedStorage( - secureStorage, - userPoolKeys: userPoolKeys, - identityPoolKeys: identityPoolKeys, - deviceKeys: CognitoDeviceKeys(userPoolConfig, username), - ); - plugin = AmplifyAuthCognitoDart( - secureStorageFactory: (_) => secureStorage, - ); - stateMachine = plugin.stateMachine; - await plugin.configure( - config: mockConfig, - authProviderRepo: testAuthRepo, - ); - final mockIdp = MockCognitoIdentityProviderClient( - getDevice: () async => throw AWSHttpException( - AWSHttpRequest.get(Uri.parse('https://www.amazon.com')), - ), - ); - stateMachine.addInstance(mockIdp); - repo = stateMachine.getOrCreate(); - }); + group('Cognito GetDevice throws AWSHttpException', () { + setUp(() async { + final mockIdp = MockCognitoIdentityProviderClient( + getDevice: () async => throw AWSHttpException( + AWSHttpRequest.get(Uri.parse('https://aws.amazon.com/cognito/')), + ), + ); + plugin.stateMachine.addInstance(mockIdp); + }); - test('should throw a NetworkException', () async { - await expectLater( - plugin.fetchCurrentDevice, - throwsA(isA()), - ); + test('should throw a NetworkException', () async { + await expectLater( + plugin.fetchCurrentDevice, + throwsA(isA()), + ); + }); }); tearDown(() async { From aa89197c3c18d98e8f91f0dc26f7c4760ba6c2be Mon Sep 17 00:00:00 2001 From: Andrew Hahn Date: Tue, 16 Jul 2024 12:40:19 -0700 Subject: [PATCH 05/10] test: improve integration test wording --- .../plugin/fetch_current_device_test.dart | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart index be88b2142c..c5630adf58 100644 --- a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart +++ b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart @@ -23,11 +23,6 @@ void main() { late DeviceMetadataRepository repo; late AmplifyAuthCognitoDart plugin; - Future getDeviceKey() async { - final secrets = await repo.get(username); - return secrets?.deviceKey; - } - group('fetchCurrentDevice', () { setUp(() async { final secureStorage = MockSecureStorage(); @@ -47,7 +42,7 @@ void main() { repo = plugin.stateMachine.getOrCreate(); }); - group('Cognito GetDevice returns successfully', () { + group('Cognito GetDevice returns successfully.', () { setUp(() async { final mockIdp = MockCognitoIdentityProviderClient( getDevice: () async => mockDeviceResponse, @@ -57,16 +52,17 @@ void main() { }); test( - 'should get the current device. current device id should be equal to the local device id', + 'This test should get the current device, where the current device id is equal to the local device id', () async { - final currentDeviceKey = await getDeviceKey(); + final secrets = await repo.get(username); + final currentDeviceKey = secrets?.deviceKey; expect(currentDeviceKey, isNotNull); final currentDevice = await plugin.fetchCurrentDevice(); expect(currentDeviceKey, currentDevice.id); }); test( - 'should should throw a DeviceNotTrackedException when current device key is null', + 'This test should throw a DeviceNotTrackedException when current device key is null', () async { await plugin.forgetDevice(); await expectLater( @@ -76,7 +72,8 @@ void main() { }); }); - group('Cognito GetDevice throws AWSHttpException', () { + group('This test should have Cognito GetDevice throw a AWSHttpException', + () { setUp(() async { final mockIdp = MockCognitoIdentityProviderClient( getDevice: () async => throw AWSHttpException( @@ -86,7 +83,8 @@ void main() { plugin.stateMachine.addInstance(mockIdp); }); - test('should throw a NetworkException', () async { + test('This test should have Cognito GetDevice throw a NetworkException', + () async { await expectLater( plugin.fetchCurrentDevice, throwsA(isA()), From 6f573701511f8ae1d76e5ab7ea90d691c669f2da Mon Sep 17 00:00:00 2001 From: Andrew Hahn <58017052+hahnandrew@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:50:49 -0700 Subject: [PATCH 06/10] Update packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart Co-authored-by: Elijah Quartey --- .../test/plugin/fetch_current_device_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart index c5630adf58..231bb51f88 100644 --- a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart +++ b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart @@ -42,7 +42,7 @@ void main() { repo = plugin.stateMachine.getOrCreate(); }); - group('Cognito GetDevice returns successfully.', () { + group('should successfully', () { setUp(() async { final mockIdp = MockCognitoIdentityProviderClient( getDevice: () async => mockDeviceResponse, From 550879a4e78295f841e5ca0614a1b3046c2b4193 Mon Sep 17 00:00:00 2001 From: Andrew Hahn <58017052+hahnandrew@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:50:54 -0700 Subject: [PATCH 07/10] Update packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart Co-authored-by: Elijah Quartey --- .../test/plugin/fetch_current_device_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart index 231bb51f88..fcb7e4fb3d 100644 --- a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart +++ b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart @@ -72,7 +72,7 @@ void main() { }); }); - group('This test should have Cognito GetDevice throw a AWSHttpException', + group('should throw', () { setUp(() async { final mockIdp = MockCognitoIdentityProviderClient( From 93e841f5b9088439abd2805347003f34d7652034 Mon Sep 17 00:00:00 2001 From: Andrew Hahn <58017052+hahnandrew@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:51:31 -0700 Subject: [PATCH 08/10] Update packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart Co-authored-by: Elijah Quartey --- .../test/plugin/fetch_current_device_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart index fcb7e4fb3d..b1083efb37 100644 --- a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart +++ b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart @@ -52,7 +52,7 @@ void main() { }); test( - 'This test should get the current device, where the current device id is equal to the local device id', + 'return the current device where the current device id is equal to the local device id', () async { final secrets = await repo.get(username); final currentDeviceKey = secrets?.deviceKey; From 4bc1f1e72e3044dac58957b8136e140eb76ddf54 Mon Sep 17 00:00:00 2001 From: Andrew Hahn <58017052+hahnandrew@users.noreply.github.com> Date: Tue, 16 Jul 2024 12:51:38 -0700 Subject: [PATCH 09/10] Update packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart Co-authored-by: Elijah Quartey --- .../test/plugin/fetch_current_device_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart index b1083efb37..520472eba4 100644 --- a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart +++ b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart @@ -62,7 +62,7 @@ void main() { }); test( - 'This test should throw a DeviceNotTrackedException when current device key is null', + 'a DeviceNotTrackedException when current device key is null', () async { await plugin.forgetDevice(); await expectLater( From 10e5a0fb1a9053f7bbe2848e356abc01bf6f6bff Mon Sep 17 00:00:00 2001 From: Andrew Hahn Date: Tue, 16 Jul 2024 12:54:03 -0700 Subject: [PATCH 10/10] test: improve wording for clarity --- .../test/plugin/fetch_current_device_test.dart | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart index 520472eba4..7337899eac 100644 --- a/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart +++ b/packages/auth/amplify_auth_cognito_test/test/plugin/fetch_current_device_test.dart @@ -61,8 +61,7 @@ void main() { expect(currentDeviceKey, currentDevice.id); }); - test( - 'a DeviceNotTrackedException when current device key is null', + test('throw a DeviceNotTrackedException when current device key is null', () async { await plugin.forgetDevice(); await expectLater( @@ -72,8 +71,7 @@ void main() { }); }); - group('should throw', - () { + group('should throw', () { setUp(() async { final mockIdp = MockCognitoIdentityProviderClient( getDevice: () async => throw AWSHttpException( @@ -83,8 +81,7 @@ void main() { plugin.stateMachine.addInstance(mockIdp); }); - test('This test should have Cognito GetDevice throw a NetworkException', - () async { + test('a NetworkException', () async { await expectLater( plugin.fetchCurrentDevice, throwsA(isA()),