From 3df1ef0568925a25732f4e42c81a4bd2b51af494 Mon Sep 17 00:00:00 2001 From: Abhash Kumar Singh Date: Tue, 5 Nov 2024 09:17:48 -0800 Subject: [PATCH] chore(auth): add more auto sign in and sign up state machine/e2e unit tests (#161) * chore(auth): add more auto sign in and sign up state machine/e2e unit tests * Address review comments --- .../Task/AWSAuthSignUpTask.swift | 10 +- .../SignIn/AWSAuthAutoSignInTests.swift | 276 +++++++++++++++ .../SignUp/AWSAuthConfirmSignUpAPITests.swift | 287 +++++++++++++++ .../AWSAuthConfirmSignUpTaskTests.swift | 6 +- .../SignUp/AWSAuthSignUpAPITests.swift | 326 +++++++++++++++++- .../SignUp/AWSAuthSignUpTaskTests.swift | 4 + .../CodableStates/AuthState+Codable.swift | 6 +- .../CodableStates/SignUpState+Codable.swift | 52 +++ .../states/SignedIn_SessionEstablished.json | 3 + .../states/SignedOut_Configured.json | 3 + .../states/SigningIn_SigningIn.json | 3 + 11 files changed, 962 insertions(+), 14 deletions(-) create mode 100644 AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestHarness/CodableStates/SignUpState+Codable.swift diff --git a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/AWSAuthSignUpTask.swift b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/AWSAuthSignUpTask.swift index c7a46cab33..1f18a2bc0a 100644 --- a/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/AWSAuthSignUpTask.swift +++ b/AmplifyPlugins/Auth/Sources/AWSCognitoAuthPlugin/Task/AWSAuthSignUpTask.swift @@ -91,10 +91,16 @@ class AWSAuthSignUpTask: AuthSignUpTask, DefaultLogger { let stateSequences = await authStateMachine.listen() log.verbose("Validating current state") for await state in stateSequences { - guard case .configured(_ , _, _) = state else { + guard case .configured(_ , _, let signUpState) = state else { + continue + } + + switch signUpState { + case .notStarted, .awaitingUserConfirmation, .error, .signedUp: + return + default: continue } - return } } } diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignIn/AWSAuthAutoSignInTests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignIn/AWSAuthAutoSignInTests.swift index 0b83263b5a..2452700b54 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignIn/AWSAuthAutoSignInTests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignIn/AWSAuthAutoSignInTests.swift @@ -56,6 +56,282 @@ class AutoSignInTests: BasePluginTest { } } + /// Test auto sign in failure + /// + /// - Given: Given an auth plugin with mocked service and in `.notStarted` sign up state + /// + /// - When: + /// - I invoke autoSignIn + /// - Then: + /// - I should get a failure with error response + /// + func testAutoSignInFailureFromNotStartedState() async { + let mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init( + codeDeliveryDetails: .init( + attributeName: "some attribute", + deliveryMedium: .email, + destination: "" + ), + userConfirmed: false, + userSub: "userSub" + ) + }, + mockInitiateAuthResponse: { input in + return InitiateAuthOutput( + authenticationResult: .init( + accessToken: Defaults.validAccessToken, + expiresIn: 300, + idToken: "idToken", + newDeviceMetadata: nil, + refreshToken: "refreshToken", + tokenType: "")) + }, + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init(session: "session") + } + ) + + let initialStateNotStarted = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .notStarted) + + + let authPluginNotStarted = configureCustomPluginWith(userPool: { mockIdentityProvider }, + initialState: initialStateNotStarted) + do { + let _ = try await authPluginNotStarted.autoSignIn() + XCTFail("Auto sign in should not be successful from .notStarted state") + } catch { + XCTAssertNotNil(error) + } + } + + /// Test auto sign in failure + /// + /// - Given: Given an auth plugin with mocked service and in `.initiatingSignUp` sign up state + /// + /// - When: + /// - I invoke autoSignIn + /// - Then: + /// - I should get a failure with error response + /// + func testAutoSignInFailureFromInitiatingSignUpState() async { + let mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init( + codeDeliveryDetails: .init( + attributeName: "some attribute", + deliveryMedium: .email, + destination: "" + ), + userConfirmed: false, + userSub: "userSub" + ) + }, + mockInitiateAuthResponse: { input in + return InitiateAuthOutput( + authenticationResult: .init( + accessToken: Defaults.validAccessToken, + expiresIn: 300, + idToken: "idToken", + newDeviceMetadata: nil, + refreshToken: "refreshToken", + tokenType: "")) + }, + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init(session: "session") + } + ) + + let initialStateInitiatingSignUp = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .initiatingSignUp(.init(username: "user"))) + + let authPluginInitiatingSignUp = configureCustomPluginWith(userPool: { mockIdentityProvider }, + initialState: initialStateInitiatingSignUp) + + do { + let _ = try await authPluginInitiatingSignUp.autoSignIn() + XCTFail("Auto sign in should not be successful from .initiatingSignUp state") + } catch { + XCTAssertNotNil(error) + } + } + + /// Test auto sign in failure + /// + /// - Given: Given an auth plugin with mocked service and in `.awaitingUserConfirmation` sign up state + /// + /// - When: + /// - I invoke autoSignIn + /// - Then: + /// - I should get a failure with error response + /// + func testAutoSignInFailureFromAwaitingUserConfirmationState() async { + let mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init( + codeDeliveryDetails: .init( + attributeName: "some attribute", + deliveryMedium: .email, + destination: "" + ), + userConfirmed: false, + userSub: "userSub" + ) + }, + mockInitiateAuthResponse: { input in + return InitiateAuthOutput( + authenticationResult: .init( + accessToken: Defaults.validAccessToken, + expiresIn: 300, + idToken: "idToken", + newDeviceMetadata: nil, + refreshToken: "refreshToken", + tokenType: "")) + }, + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init(session: "session") + } + ) + + let initialStateAwaitingUserConfirmation = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .awaitingUserConfirmation(.init(username: "user"), .init(.completeAutoSignIn("session")))) + + let authPluginAwaitingUserConfirmation = configureCustomPluginWith(userPool: { mockIdentityProvider }, + initialState: initialStateAwaitingUserConfirmation) + + do { + let _ = try await authPluginAwaitingUserConfirmation.autoSignIn() + XCTFail("Auto sign in should not be successful from .awaitingUserConfirmation state") + } catch { + XCTAssertNotNil(error) + } + } + + /// Test auto sign in failure + /// + /// - Given: Given an auth plugin with mocked service and in `.confirmingSignUp` sign up state + /// + /// - When: + /// - I invoke autoSignIn + /// - Then: + /// - I should get a failure with error response + /// + func testAutoSignInFailureFromConfirmingSignUpState() async { + let mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init( + codeDeliveryDetails: .init( + attributeName: "some attribute", + deliveryMedium: .email, + destination: "" + ), + userConfirmed: false, + userSub: "userSub" + ) + }, + mockInitiateAuthResponse: { input in + return InitiateAuthOutput( + authenticationResult: .init( + accessToken: Defaults.validAccessToken, + expiresIn: 300, + idToken: "idToken", + newDeviceMetadata: nil, + refreshToken: "refreshToken", + tokenType: "")) + }, + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init(session: "session") + } + ) + + let initialStateConfirmingSignUp = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .confirmingSignUp(.init(username: "user"))) + + let authPluginConfirmingSignUp = configureCustomPluginWith(userPool: { mockIdentityProvider }, + initialState: initialStateConfirmingSignUp) + + do { + let _ = try await authPluginConfirmingSignUp.autoSignIn() + XCTFail("Auto sign in should not be successful from .confirmingSignUp state") + } catch { + XCTAssertNotNil(error) + } + } + + /// Test auto sign in failure + /// + /// - Given: Given an auth plugin with mocked service and in `.error` sign up state + /// + /// - When: + /// - I invoke autoSignIn + /// - Then: + /// - I should get a failure with error response + /// + func testAutoSignInFailureFromErrorState() async { + let mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init( + codeDeliveryDetails: .init( + attributeName: "some attribute", + deliveryMedium: .email, + destination: "" + ), + userConfirmed: false, + userSub: "userSub" + ) + }, + mockInitiateAuthResponse: { input in + return InitiateAuthOutput( + authenticationResult: .init( + accessToken: Defaults.validAccessToken, + expiresIn: 300, + idToken: "idToken", + newDeviceMetadata: nil, + refreshToken: "refreshToken", + tokenType: "")) + }, + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init(session: "session") + } + ) + + let initialStateError = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .error(.service(error: AuthError.service("Unknown error", "Unknown error")))) + + let authPluginError = configureCustomPluginWith(userPool: { mockIdentityProvider }, + initialState: initialStateError) + + do { + let _ = try await authPluginError.autoSignIn() + XCTFail("Auto sign in should not be successful from .error state") + } catch { + XCTAssertNotNil(error) + } + } + + // MARK: - Service error for initiateAuth /// Test a autoSignIn with an `InternalErrorException` from service diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthConfirmSignUpAPITests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthConfirmSignUpAPITests.swift index eadf74fcf1..749ae40bde 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthConfirmSignUpAPITests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthConfirmSignUpAPITests.swift @@ -24,6 +24,9 @@ class AWSAuthConfirmSignUpAPITests: BasePluginTest { .awaitingUserConfirmation(SignUpEventData(username: "jeffb"), .init(.confirmUser()))) } + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state and a mocked success response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up is complete with `.done` as the next step func testSuccessfulConfirmSignUp() async throws { self.mockIdentityProvider = MockIdentityProvider( @@ -45,7 +48,270 @@ class AWSAuthConfirmSignUpAPITests: BasePluginTest { } XCTAssertTrue(result.isSignUpComplete, "Signin result should be complete") } + + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked success response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up is complete with `.done` as the next step + func testSuccessfulConfirmSignUpFromNotStartedState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init() + } + ) + + let initialStateAwaitingNotStarted = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .notStarted) + + + let authPluginNotStarted = configureCustomPluginWith( + userPool: { mockIdentityProvider }, + initialState: initialStateAwaitingNotStarted + ) + + let result = try await authPluginNotStarted.confirmSignUp( + for: "jeffb", + confirmationCode: "123456", + options: options) + + guard case .done = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signin result should be complete") + } + + /// Given: Configured auth machine in `.signedUp` sign up state and a mocked success response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up is complete with `.done` as the next step + func testSuccessfulConfirmSignUpFromSignedUpState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init() + } + ) + + let initialStateSignedUp = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .signedUp(.init(username: "user1"), .init(.done))) + + + let authPluginSignedUp = configureCustomPluginWith( + userPool: { mockIdentityProvider }, + initialState: initialStateSignedUp + ) + + let result2 = try await authPluginSignedUp.confirmSignUp( + for: "jeffb", + confirmationCode: "123456", + options: options) + + guard case .done = result2.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result2.isSignUpComplete, "Signin result should be complete") + } + + /// Given: Configured auth machine in `.error` sign up state and a mocked success response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up is complete with `.done` as the next step + func testSuccessfulConfirmSignUpFromErrorState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init() + } + ) + + let initialStateError = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .error(.service(error: AuthError.service("Unknown error", "Unknown error")))) + + let authPluginError = configureCustomPluginWith(userPool: { mockIdentityProvider }, + initialState: initialStateError) + + let result = try await authPluginError.confirmSignUp( + for: "jeffb", + confirmationCode: "123456", + options: options) + + guard case .done = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signin result should be complete") + } + + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state and a mocked success response + /// with a `session` string + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up is complete with `.completeAutoSignIn` as the next step + func testSuccessfulPasswordlessConfirmSignUp() async throws { + + self.mockIdentityProvider = MockIdentityProvider( + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init(session: "session") + } + ) + + let result = try await self.plugin.confirmSignUp( + for: "jeffb", + confirmationCode: "123456", + options: options) + + guard case .completeAutoSignIn(let session) = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signin result should be complete") + XCTAssertEqual(session, "session") + } + + /// Given: Configured auth machine in `.notStarted` and a mocked success response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up is complete with `.completeAutoSignIn` as the next step + func testSuccessfulPasswordlessConfirmSignUpFromNotStartedState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init(session: "session") + } + ) + + let initialStateAwaitingNotStarted = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .notStarted) + + + let authPluginNotStarted = configureCustomPluginWith( + userPool: { mockIdentityProvider }, + initialState: initialStateAwaitingNotStarted + ) + + let result = try await authPluginNotStarted.confirmSignUp( + for: "jeffb", + confirmationCode: "123456", + options: options) + + guard case .completeAutoSignIn(let session) = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signin result should be complete") + XCTAssertEqual(session, "session") + } + + /// Given: Configured auth machine in `.notStarted` and a mocked success response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up is complete with `.completeAutoSignIn` as the next step + func testSuccessfulPasswordlessConfirmSignUpFromSignedUpState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init(session: "session") + } + ) + + let initialStateSignedUp = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .signedUp(.init(username: "user1"), .init(.done))) + + + let authPluginSignedUp = configureCustomPluginWith( + userPool: { mockIdentityProvider }, + initialState: initialStateSignedUp + ) + + let result = try await authPluginSignedUp.confirmSignUp( + for: "jeffb", + confirmationCode: "123456", + options: options) + + guard case .completeAutoSignIn(let session) = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signin result should be complete") + XCTAssertEqual(session, "session") + } + + /// Given: Configured auth machine in `.notStarted` and a mocked success response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up is complete with `.completeAutoSignIn` as the next step + func testSuccessfulPasswordlessConfirmSignUpFromErrorState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init(session: "session") + } + ) + + let initialStateError = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .error(.service(error: AuthError.service("Unknown error", "Unknown error")))) + + let authPluginError = configureCustomPluginWith(userPool: { mockIdentityProvider }, + initialState: initialStateError) + + let result = try await authPluginError.confirmSignUp( + for: "jeffb", + confirmationCode: "123456", + options: options) + + guard case .completeAutoSignIn(let session) = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signin result should be complete") + XCTAssertEqual(session, "session") + } + + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state and a mocked success response + /// with a `nil` session string + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up is complete with `.done` as the next step + func testSuccessfulPasswordlessConfirmSignUpWithNilSession() async throws { + + self.mockIdentityProvider = MockIdentityProvider( + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init(session: nil) + } + ) + + let result = try await self.plugin.confirmSignUp( + for: "jeffb", + confirmationCode: "123456", + options: options) + + guard case .done = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signin result should be complete") + } + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state and a mocked success response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked with options + /// Then: Confirm Sign up is complete with `.done` as the next step func testSuccessfulConfirmSignUpWithOptions() async throws { self.mockIdentityProvider = MockIdentityProvider( @@ -73,6 +339,9 @@ class AWSAuthConfirmSignUpAPITests: BasePluginTest { XCTAssertTrue(result.isSignUpComplete, "Signin result should be complete") } + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state and a mocked success response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked with empty username + /// Then: Confirm Sign up fails with error func testConfirmSignUpWithEmptyUsername() async { self.mockIdentityProvider = MockIdentityProvider( @@ -97,6 +366,9 @@ class AWSAuthConfirmSignUpAPITests: BasePluginTest { } } + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state and a mocked success response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked with empty confirmation code + /// Then: Confirm Sign up fails with error func testConfirmSignUpWithEmptyConfirmationCode() async { self.mockIdentityProvider = MockIdentityProvider( @@ -121,6 +393,9 @@ class AWSAuthConfirmSignUpAPITests: BasePluginTest { } } + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state and a mocked service error response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up fails with appropriate error returned func testConfirmSignUpServiceError() async { let errorsToTest: [(confirmSignUpOutputError: Error, cognitoError: AWSCognitoAuthError)] = [ @@ -144,6 +419,10 @@ class AWSAuthConfirmSignUpAPITests: BasePluginTest { } } + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state + /// and a mocked `NotAuthorizedException` response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up fails with `.notAuthorized` error func testConfirmSignUpWithNotAuthorizedException() async { self.mockIdentityProvider = MockIdentityProvider( @@ -176,6 +455,10 @@ class AWSAuthConfirmSignUpAPITests: BasePluginTest { } } + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state + /// and a mocked `InternalErrorException` response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up fails with `.unknown` error func testConfirmSignUpWithInternalErrorException() async { self.mockIdentityProvider = MockIdentityProvider( @@ -204,6 +487,10 @@ class AWSAuthConfirmSignUpAPITests: BasePluginTest { } } + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state + /// and a mocked unknown error response + /// When: `Auth.confirmSignUp(for:confirmationCode:options:)` is invoked + /// Then: Confirm Sign up fails with `.unknown` error func testConfirmSignUpWithUnknownErrorException() async { self.mockIdentityProvider = MockIdentityProvider( diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthConfirmSignUpTaskTests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthConfirmSignUpTaskTests.swift index 4ca5cb51c4..9a491d1d62 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthConfirmSignUpTaskTests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthConfirmSignUpTaskTests.swift @@ -61,9 +61,9 @@ class AWSAuthConfirmSignUpTaskTests: BasePluginTest { ) do { - let confirmSignUpResult = try await plugin.confirmSignUp(for: "jeffb", - confirmationCode: "213", - options: AuthConfirmSignUpRequest.Options()) + let _ = try await plugin.confirmSignUp(for: "jeffb", + confirmationCode: "213", + options: AuthConfirmSignUpRequest.Options()) XCTFail("Should result in failure") } catch(let error) { XCTAssertNotNil(error) diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthSignUpAPITests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthSignUpAPITests.swift index 9921709743..9502c69ced 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthSignUpAPITests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthSignUpAPITests.swift @@ -22,6 +22,9 @@ class AWSAuthSignUpAPITests: BasePluginTest { AuthState.configured(.signedOut(.init(lastKnownUserName: nil)), .configured, .notStarted) } + /// Given: Configured auth machine in `.notStarted` sign up states and a mocked success response + /// When: `Auth.signUp(username:password:options:)` is invoked + /// Then: Sign up is successful with `.done` as the next step func testSuccessfulSignUp() async throws { self.mockIdentityProvider = MockIdentityProvider( @@ -44,6 +47,111 @@ class AWSAuthSignUpAPITests: BasePluginTest { XCTAssertTrue(result.isSignUpComplete, "Signin result should be complete") } + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state and a mocked success response + /// When: `Auth.signUp(username:password:options:)` is invoked + /// Then: Sign up is successful with `.done` as the next step + func testSuccessfulSignUpFromAwaitingUserConfirmationState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init(codeDeliveryDetails: nil, + userConfirmed: true, + userSub: UUID().uuidString) + } + ) + + let initialStateAwaitingUserConfirmation = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .awaitingUserConfirmation(.init(username: "user1"), .init(.confirmUser()))) + + + let authPluginAwaitingUserConfirmation = configureCustomPluginWith( + userPool: { mockIdentityProvider }, + initialState: initialStateAwaitingUserConfirmation + ) + + let result = try await authPluginAwaitingUserConfirmation.signUp( + username: "user2", + password: "Valid&99", + options: options) + + guard case .done = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signup result should be complete") + } + + /// Given: Configured auth machine in `.signedUp` sign up state and a mocked success response + /// When: `Auth.signUp(username:password:options:)` is invoked + /// Then: Sign up is successful with `.done` as the next step + func testSuccessfulSignUpFromSignedUpState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init(codeDeliveryDetails: nil, + userConfirmed: true, + userSub: UUID().uuidString) + } + ) + + let initialStateSignedUp = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .signedUp(.init(username: "user1"), .init(.done))) + + + let authPluginSignedUp = configureCustomPluginWith( + userPool: { mockIdentityProvider }, + initialState: initialStateSignedUp + ) + + let result = try await authPluginSignedUp.signUp( + username: "user2", + password: "Valid&99", + options: options) + + guard case .done = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signup result should be complete") + } + + /// Given: Configured auth machine in `.error` sign up state and a mocked success response + /// When: `Auth.signUp(username:password:options:)` is invoked + /// Then: Sign up is successful with `.done` as the next step + func testSuccessfulSignUpFromErrorState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init(codeDeliveryDetails: nil, + userConfirmed: true, + userSub: UUID().uuidString) + } + ) + + let initialStateError = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .error(.service(error: AuthError.service("Unknown error", "Unknown error")))) + + let authPluginError = configureCustomPluginWith(userPool: { mockIdentityProvider }, + initialState: initialStateError) + + let result = try await authPluginError.signUp( + username: "user2", + password: "Valid&99", + options: options) + + guard case .done = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signup result should be complete") + } + + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked success response + /// When: `Auth.signUp(username:password:options:)` is invoked without a password + /// Then: Sign up is successful with `.done` as the next step func testSuccessfulPasswordlessSignUp() async throws { self.mockIdentityProvider = MockIdentityProvider( @@ -64,7 +172,109 @@ class AWSAuthSignUpAPITests: BasePluginTest { } XCTAssertTrue(result.isSignUpComplete, "Signin result should be complete") } + + /// Given: Configured auth machine in `.awaitingUserConfirmation` sign up state and a mocked success response + /// When: `Auth.signUp(username:password:options:)` is invoked without password + /// Then: Sign up is successful with `.done` as the next step + func testSuccessfulPasswordlessSignUpFromAwaitingUserConfirmationState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init(codeDeliveryDetails: nil, + userConfirmed: true, + userSub: UUID().uuidString) + } + ) + + let initialStateAwaitingUserConfirmation = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .awaitingUserConfirmation(.init(username: "user1"), .init(.confirmUser()))) + + + let authPluginAwaitingUserConfirmation = configureCustomPluginWith( + userPool: { mockIdentityProvider }, + initialState: initialStateAwaitingUserConfirmation + ) + + let result1 = try await authPluginAwaitingUserConfirmation.signUp( + username: "user2", + options: options) + + guard case .done = result1.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result1.isSignUpComplete, "Signup result should be complete") + } + + /// Given: Configured auth machine in `.signedUp` sign up state and a mocked success response + /// When: `Auth.signUp(username:password:options:)` is invoked without password + /// Then: Sign up is successful with `.done` as the next step + func testSuccessfulPasswordlessSignUpFromSignedUpState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init(codeDeliveryDetails: nil, + userConfirmed: true, + userSub: UUID().uuidString) + } + ) + + let initialStateSignedUp = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .signedUp(.init(username: "user1"), .init(.done))) + + + let authPluginSignedUp = configureCustomPluginWith( + userPool: { mockIdentityProvider }, + initialState: initialStateSignedUp + ) + + let result = try await authPluginSignedUp.signUp( + username: "user2", + options: options) + + guard case .done = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signup result should be complete") + } + + /// Given: Configured auth machine in `.error` sign up state and a mocked success response + /// When: `Auth.signUp(username:password:options:)` is invoked without password + /// Then: Sign up is successful with `.done` as the next step + func testSuccessfulPasswordlessSignUpFromErrorState() async throws { + let mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init(codeDeliveryDetails: nil, + userConfirmed: true, + userSub: UUID().uuidString) + } + ) + + let initialStateError = AuthState.configured( + .signedOut(.init(lastKnownUserName: nil)), + .configured, + .error(.service(error: AuthError.service("Unknown error", "Unknown error")))) + + let authPluginError = configureCustomPluginWith(userPool: { mockIdentityProvider }, + initialState: initialStateError) + + let result = try await authPluginError.signUp( + username: "user2", + options: options) + guard case .done = result.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(result.isSignUpComplete, "Signup result should be complete") + } + + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked success response + /// When: `Auth.signUp(username:password:options:)` is invoked with empty username + /// Then: Sign up fails with error func testSignUpWithEmptyUsername() async { self.mockIdentityProvider = MockIdentityProvider( @@ -88,6 +298,9 @@ class AWSAuthSignUpAPITests: BasePluginTest { } } + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked success response + /// When: `Auth.signUp(username:password:options:)` is invoked with empty username and no password + /// Then: Sign up fails with error func testSignUpPasswordlessWithEmptyUsername() async { self.mockIdentityProvider = MockIdentityProvider( @@ -110,6 +323,10 @@ class AWSAuthSignUpAPITests: BasePluginTest { } } + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked success response with + /// code delivery details + /// When: `Auth.signUp(username:password:options:)` is invoked + /// Then: Sign up is successful with `.confirmUser` as next step func testSignUpWithUserConfirmationRequired() async throws { self.mockIdentityProvider = MockIdentityProvider( @@ -141,6 +358,10 @@ class AWSAuthSignUpAPITests: BasePluginTest { XCTAssertFalse(result.isSignUpComplete, "Signin result should be complete") } + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked success response with + /// code delivery details + /// When: `Auth.signUp(username:password:options:)` is invoked without a password + /// Then: Sign up is successful with `.confirmUser` as next step func testSignUpPasswordlessWithUserConfirmationRequired() async throws { self.mockIdentityProvider = MockIdentityProvider( @@ -171,6 +392,10 @@ class AWSAuthSignUpAPITests: BasePluginTest { XCTAssertFalse(result.isSignUpComplete, "Signin result should be complete") } + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked success response with + /// with `nil` responses + /// When: `Auth.signUp(username:password:options:)` is invoked + /// Then: Sign up is successful with `.confirmUser` as next step func testSignUpNilCognitoResponse() async throws { self.mockIdentityProvider = MockIdentityProvider( @@ -199,6 +424,10 @@ class AWSAuthSignUpAPITests: BasePluginTest { XCTAssertFalse(result.isSignUpComplete, "Signin result should be complete") } + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked success response with + /// with `nil` responses + /// When: `Auth.signUp(username:password:options:)` is invoked without a password + /// Then: Sign up is successful with `.confirmUser` as next step func testSignUpPasswordlessNilCognitoResponse() async throws { self.mockIdentityProvider = MockIdentityProvider( @@ -230,7 +459,7 @@ class AWSAuthSignUpAPITests: BasePluginTest { /// When: Invoking `signUp(username:password:options:)` /// Then: The caller should receive an `AuthSignUpResult` where `nextStep == .done` and /// `userID` is the `userSub` returned by the service. - func test_signUp_done_withUserSub() async throws { + func testSignUpDoneWithUserSub() async throws { let sub = UUID().uuidString mockIdentityProvider = MockIdentityProvider( mockSignUpResponse: { _ in @@ -257,7 +486,7 @@ class AWSAuthSignUpAPITests: BasePluginTest { /// When: Invoking `signUp(username:password:options:)` without a password /// Then: The caller should receive an `AuthSignUpResult` where `nextStep == .done` and /// `userID` is the `userSub` returned by the service. - func test_signUpPasswordless_done_withUserSub() async throws { + func testSignUpPasswordlessDoneWithUserSub() async throws { let sub = UUID().uuidString mockIdentityProvider = MockIdentityProvider( mockSignUpResponse: { _ in @@ -284,7 +513,7 @@ class AWSAuthSignUpAPITests: BasePluginTest { /// When: Invoking `signUp(username:password:options:)` /// Then: The caller should receive an `AuthSignUpResult` where `nextStep == .confirmUser` and /// the applicable associated value of that case and the `userID` both equal the `userSub` returned by the service. - func test_signUp_confirmUser_userIDsMatch() async throws { + func testSignUpConfirmUserUserIDsMatch() async throws { let sub = UUID().uuidString mockIdentityProvider = MockIdentityProvider( mockSignUpResponse: { _ in @@ -316,7 +545,7 @@ class AWSAuthSignUpAPITests: BasePluginTest { /// When: Invoking `signUp(username:password:options:)` without a password /// Then: The caller should receive an `AuthSignUpResult` where `nextStep == .confirmUser` and /// the applicable associated value of that case and the `userID` both equal the `userSub` returned by the service. - func test_signUpPasswordless_confirmUser_userIDsMatch() async throws { + func testSignUpPasswordlessConfirmUserUserIDsMatch() async throws { let sub = UUID().uuidString mockIdentityProvider = MockIdentityProvider( mockSignUpResponse: { _ in @@ -343,6 +572,10 @@ class AWSAuthSignUpAPITests: BasePluginTest { XCTAssertEqual(result.userID, userID) } + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked failure response + /// with `NotAuthorizedException` + /// When: `Auth.signUp(username:password:options:)` is invoked + /// Then: Sign up fails with error as `.notAuthorized` func testSignUpWithNotAuthorizedException() async { self.mockIdentityProvider = MockIdentityProvider( @@ -375,6 +608,10 @@ class AWSAuthSignUpAPITests: BasePluginTest { } } + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked failure response + /// with `NotAuthorizedException` + /// When: `Auth.signUp(username:password:options:)` is invoked without a password + /// Then: Sign up fails with error as `.notAuthorized` func testSignUpPasswordlessWithNotAuthorizedException() async { self.mockIdentityProvider = MockIdentityProvider( @@ -405,7 +642,11 @@ class AWSAuthSignUpAPITests: BasePluginTest { XCTAssertNil(notAuthorizedError) } } - + + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked failure response + /// with `InternalErrorException` + /// When: `Auth.signUp(username:password:options:)` is invoked + /// Then: Sign up fails with error as `.unknown` func testSignUpWithInternalErrorException() async { self.mockIdentityProvider = MockIdentityProvider( @@ -434,6 +675,10 @@ class AWSAuthSignUpAPITests: BasePluginTest { } } + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked failure response + /// with `InternalErrorException` + /// When: `Auth.signUp(username:password:options:)` is invoked without a password + /// Then: Sign up fails with error as `.unknown` func testSignUpPasswordlessWithInternalErrorException() async { self.mockIdentityProvider = MockIdentityProvider( @@ -461,6 +706,77 @@ class AWSAuthSignUpAPITests: BasePluginTest { } } + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked success response + /// for Sign Up, Confirm Sign Up and Auto Sign In + /// When: `Auth.signUp(username:password:options:)` is invoked followed by + /// `Auth.signUp(for:confirmationCode:options:)` and `Auth.autoSignIn()` + /// Then: Sign up, Confirm Sign up and Auto sign in are complete + func testSuccessfulSignUpAndAutoSignInEndToEnd() async throws { + let userSub = UUID().uuidString + self.mockIdentityProvider = MockIdentityProvider( + mockSignUpResponse: { _ in + return .init( + codeDeliveryDetails: .init( + attributeName: "some attribute", + deliveryMedium: .email, + destination: "" + ), + userConfirmed: false, + userSub: userSub + ) + }, + mockInitiateAuthResponse: { input in + return InitiateAuthOutput( + authenticationResult: .init( + accessToken: Defaults.validAccessToken, + expiresIn: 300, + idToken: "idToken", + newDeviceMetadata: nil, + refreshToken: "refreshToken", + tokenType: "")) + }, + mockConfirmSignUpResponse: { request in + XCTAssertNil(request.clientMetadata) + XCTAssertNil(request.forceAliasCreation) + return .init(session: "session") + } + ) + + // sign up + let signUpResult = try await self.plugin.signUp( + username: "jeffb", + options: options) + + guard case .confirmUser(_, _, let userID) = signUpResult.nextStep else { + return XCTFail("expected .confirmUser nextStep") + } + XCTAssertEqual(signUpResult.userID, userID) + XCTAssertFalse(signUpResult.isSignUpComplete) + + // confirm sign up + let confirmSignUpResult = try await plugin.confirmSignUp(for: "jeffb", + confirmationCode: "123456", + options: AuthConfirmSignUpRequest.Options()) + guard case .completeAutoSignIn(let session) = confirmSignUpResult.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(confirmSignUpResult.isSignUpComplete, "Confirm Sign up result should be complete") + XCTAssertEqual(session, "session") + + // auto sign in + let autoSignInResult = try await plugin.autoSignIn() + guard case .done = autoSignInResult.nextStep else { + XCTFail("Result should be .done for next step") + return + } + XCTAssertTrue(autoSignInResult.isSignedIn, "Signin result should be complete") + } + + /// Given: Configured auth machine in `.notStarted` sign up state and a mocked failure response + /// with different service errors + /// When: `Auth.signUp(username:password:options:)` is invoked with/without a password + /// Then: Sign up fails with appropriate error type returned func testSignUpServiceError() async { let errorsToTest: [(signUpOutputError: Error, cognitoError: AWSCognitoAuthError)] = [ diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthSignUpTaskTests.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthSignUpTaskTests.swift index 67606cd36d..35a4e7de39 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthSignUpTaskTests.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TaskTests/ClientBehaviorTests/SignUp/AWSAuthSignUpTaskTests.swift @@ -20,6 +20,10 @@ class AWSAuthSignUpTaskTests: BasePluginTest { AuthState.configured(.signedOut(.init(lastKnownUserName: nil)), .configured, .notStarted) } + /// Given: Configured AuthState machine + /// When: A new SignUp operation is added to the queue and mock a success failure + /// Then: Should complete the signUp flow + /// func testSignUpOperationSuccess() async throws { self.mockIdentityProvider = MockIdentityProvider( mockSignUpResponse: { _ in diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestHarness/CodableStates/AuthState+Codable.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestHarness/CodableStates/AuthState+Codable.swift index 314d892e0c..0b57816f72 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestHarness/CodableStates/AuthState+Codable.swift +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestHarness/CodableStates/AuthState+Codable.swift @@ -25,8 +25,7 @@ extension AuthState: Codable { if type == "AuthState.Configured" { let authenticationState = try values.decode(AuthenticationState.self, forKey: .authenticationState) let authorizationState = try values.decode(AuthorizationState.self, forKey: .authorizationState) - // TODO: Make SignUpState conform to `Codable` - // let signUpState = try values.decode(SignUpState.self, forKey: .signUpState) + let signUpState = try values.decode(SignUpState.self, forKey: .signUpState) self = .configured( authenticationState, authorizationState, @@ -42,8 +41,7 @@ extension AuthState: Codable { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(authenticationState, forKey: .authenticationState) try container.encode(authorizationState, forKey: .authorizationState) - // TODO: Make SignUpState conform to `Codable` - // try container.encode(signUpState, forKey: .signUpState) + try container.encode(signUpState, forKey: .signUpState) default: fatalError("not implemented") } diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestHarness/CodableStates/SignUpState+Codable.swift b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestHarness/CodableStates/SignUpState+Codable.swift new file mode 100644 index 0000000000..a67ee04503 --- /dev/null +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestHarness/CodableStates/SignUpState+Codable.swift @@ -0,0 +1,52 @@ +// +// Copyright Amazon.com Inc. or its affiliates. +// All Rights Reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// + +@testable import AWSCognitoAuthPlugin +import Foundation +import Amplify + +extension SignUpState: Codable { + + enum CodingKeys: String, CodingKey { + case type + case SignUpEventData + case AuthSignUpResult + case SignUpError + } + + public init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + let type = try values.decode(String.self, forKey: .type) + if type == "SignUpState.notStarted" { + self = .notStarted + } else if type == "SignUpState.initiatingSignUp" { + let eventData = try values.decode(SignUpEventData.self, forKey: .SignUpEventData) + self = .initiatingSignUp(eventData) + } else if type == "SignUpState.awaitingUserConfirmation" { + let eventData = try values.decode(SignUpEventData.self, forKey: .SignUpEventData) + let result = try values.decode(AuthSignUpResult.self, forKey: .AuthSignUpResult) + self = .awaitingUserConfirmation(eventData, result) + } else if type == "SignUpState.confirmingSignUp" { + let eventData = try values.decode(SignUpEventData.self, forKey: .SignUpEventData) + self = .confirmingSignUp(eventData) + } else if type == "SignUpState.signedUp" { + let eventData = try values.decode(SignUpEventData.self, forKey: .SignUpEventData) + let result = try values.decode(AuthSignUpResult.self, forKey: .AuthSignUpResult) + self = .signedUp(eventData, result) + } else if type == "SignUpState.error" { + let eventError = try values.decode(SignUpError.self, forKey: .SignUpError) + self = .error(eventError) + } else { + fatalError("Decoding not supported") + } + } + + public func encode(to encoder: Encoder) throws { + fatalError("Encoding not supported") + } + +} diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SignedIn_SessionEstablished.json b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SignedIn_SessionEstablished.json index 3b95f8e971..52098e1ed7 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SignedIn_SessionEstablished.json +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SignedIn_SessionEstablished.json @@ -45,5 +45,8 @@ "expiration": 10690446268 } } + }, + "SignUpState" : { + "type": "SignUpState.notStarted" } } diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SignedOut_Configured.json b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SignedOut_Configured.json index 7dcef9586b..803148b38e 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SignedOut_Configured.json +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SignedOut_Configured.json @@ -8,5 +8,8 @@ }, "AuthorizationState": { "type": "AuthorizationState.Configured" + }, + "SignUpState" : { + "type": "SignUpState.notStarted" } } \ No newline at end of file diff --git a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SigningIn_SigningIn.json b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SigningIn_SigningIn.json index 00c6cc3910..fc19266749 100644 --- a/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SigningIn_SigningIn.json +++ b/AmplifyPlugins/Auth/Tests/AWSCognitoAuthPluginUnitTests/TestResources/states/SigningIn_SigningIn.json @@ -20,5 +20,8 @@ }, "AuthorizationState": { "type": "AuthorizationState.Configured" + }, + "SignUpState" : { + "type": "SignUpState.notStarted" } }