diff --git a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/JsonGenerator.kt b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/JsonGenerator.kt index 837dd9116e..7a7910613f 100644 --- a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/JsonGenerator.kt +++ b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/JsonGenerator.kt @@ -20,6 +20,10 @@ import com.amplifyframework.auth.cognito.featuretest.generators.authstategenerat import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.ConfirmSignInTestCaseGenerator import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.DeleteUserTestCaseGenerator import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.FetchAuthSessionTestCaseGenerator +import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.FetchDevicesTestCaseGenerator +import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.FetchUserAttributesTestCaseGenerator +import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.ForgetDeviceTestCaseGenerator +import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.RememberDeviceTestCaseGenerator import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.ResetPasswordTestCaseGenerator import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.SignInTestCaseGenerator import com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators.SignOutTestCaseGenerator @@ -43,6 +47,10 @@ object JsonGenerator { ConfirmSignInTestCaseGenerator, DeleteUserTestCaseGenerator, FetchAuthSessionTestCaseGenerator, + RememberDeviceTestCaseGenerator, + ForgetDeviceTestCaseGenerator, + FetchDevicesTestCaseGenerator, + FetchUserAttributesTestCaseGenerator, ) fun generate() { diff --git a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/FetchAuthSessionTestCaseGenerator.kt b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/FetchAuthSessionTestCaseGenerator.kt index 02c413dac3..b825671f42 100644 --- a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/FetchAuthSessionTestCaseGenerator.kt +++ b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/FetchAuthSessionTestCaseGenerator.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + package com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators import com.amplifyframework.auth.AWSCredentials diff --git a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/FetchDevicesTestCaseGenerator.kt b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/FetchDevicesTestCaseGenerator.kt new file mode 100644 index 0000000000..f87c12db89 --- /dev/null +++ b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/FetchDevicesTestCaseGenerator.kt @@ -0,0 +1,115 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators + +import aws.sdk.kotlin.services.cognitoidentityprovider.model.AttributeType +import aws.sdk.kotlin.services.cognitoidentityprovider.model.DeviceType +import aws.smithy.kotlin.runtime.time.Instant +import com.amplifyframework.auth.AuthDevice +import com.amplifyframework.auth.cognito.featuretest.API +import com.amplifyframework.auth.cognito.featuretest.AuthAPI +import com.amplifyframework.auth.cognito.featuretest.CognitoType +import com.amplifyframework.auth.cognito.featuretest.ExpectationShapes +import com.amplifyframework.auth.cognito.featuretest.FeatureTestCase +import com.amplifyframework.auth.cognito.featuretest.MockResponse +import com.amplifyframework.auth.cognito.featuretest.PreConditions +import com.amplifyframework.auth.cognito.featuretest.ResponseType +import com.amplifyframework.auth.cognito.featuretest.generators.SerializableProvider +import com.amplifyframework.auth.cognito.featuretest.generators.toJsonElement +import com.amplifyframework.auth.exceptions.SignedOutException +import kotlinx.serialization.json.JsonObject + +object FetchDevicesTestCaseGenerator : SerializableProvider { + + private val expectedSuccess = listOf(AuthDevice.fromId("deviceKey")).toJsonElement() + + private val mockCognitoResponse = MockResponse( + CognitoType.CognitoIdentityProvider, + "listDevices", + ResponseType.Success, + mapOf( + "devices" to listOf( + DeviceType.invoke { + deviceAttributes = listOf( + AttributeType.invoke { + name = "name" + value = "value" + } + ) + deviceKey = "deviceKey" + deviceCreateDate = Instant.now() + deviceLastAuthenticatedDate = Instant.now() + deviceLastModifiedDate = Instant.now() + } + ) + ).toJsonElement() + ) + + private val apiReturnValidation = ExpectationShapes.Amplify( + AuthAPI.fetchDevices, + ResponseType.Success, + expectedSuccess, + ) + + private val baseCase = FeatureTestCase( + description = "Test that Cognito is called with given payload and returns successful data", + preConditions = PreConditions( + "authconfiguration.json", + "SignedIn_SessionEstablished.json", + mockedResponses = listOf(mockCognitoResponse) + ), + api = API( + AuthAPI.fetchDevices, + JsonObject(emptyMap()), + JsonObject(emptyMap()), + ), + validations = listOf(apiReturnValidation) + ) + + private val successCase: FeatureTestCase = baseCase.copy( + description = "List of devices returned when fetch devices API succeeds", + preConditions = baseCase.preConditions.copy(mockedResponses = listOf(mockCognitoResponse)), + validations = baseCase.validations.plus(apiReturnValidation) + ) + + private val errorCase: FeatureTestCase + get() { + val errorResponse = SignedOutException() + return baseCase.copy( + description = "AuthException is thrown when forgetDevice API is called without signing in", + preConditions = baseCase.preConditions.copy( + state = "SignedOut_Configured.json", + mockedResponses = listOf( + MockResponse( + CognitoType.CognitoIdentityProvider, + "forgetDevice", + ResponseType.Failure, + errorResponse.toJsonElement() + ) + ) + ), + validations = listOf( + ExpectationShapes.Amplify( + AuthAPI.forgetDevice, + ResponseType.Failure, + com.amplifyframework.auth.exceptions.SignedOutException().toJsonElement(), + ) + ) + ) + } + + override val serializables: List = listOf(baseCase, errorCase, successCase) +} diff --git a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/FetchUserAttributesTestCaseGenerator.kt b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/FetchUserAttributesTestCaseGenerator.kt new file mode 100644 index 0000000000..1688bf9b50 --- /dev/null +++ b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/FetchUserAttributesTestCaseGenerator.kt @@ -0,0 +1,112 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators +import aws.sdk.kotlin.services.cognitoidentityprovider.model.AttributeType +import com.amplifyframework.auth.AuthUserAttribute +import com.amplifyframework.auth.AuthUserAttributeKey +import com.amplifyframework.auth.cognito.featuretest.API +import com.amplifyframework.auth.cognito.featuretest.AuthAPI +import com.amplifyframework.auth.cognito.featuretest.CognitoType +import com.amplifyframework.auth.cognito.featuretest.ExpectationShapes +import com.amplifyframework.auth.cognito.featuretest.FeatureTestCase +import com.amplifyframework.auth.cognito.featuretest.MockResponse +import com.amplifyframework.auth.cognito.featuretest.PreConditions +import com.amplifyframework.auth.cognito.featuretest.ResponseType +import com.amplifyframework.auth.cognito.featuretest.generators.SerializableProvider +import com.amplifyframework.auth.cognito.featuretest.generators.toJsonElement +import com.amplifyframework.auth.exceptions.SignedOutException +import kotlinx.serialization.json.JsonObject + +object FetchUserAttributesTestCaseGenerator : SerializableProvider { + + private val expectedSuccess = listOf( + AuthUserAttribute(AuthUserAttributeKey.email(), "email@email.com"), + AuthUserAttribute(AuthUserAttributeKey.phoneNumber(), "000-000-0000") + ).toJsonElement() + + private val mockCognitoResponse = MockResponse( + CognitoType.CognitoIdentityProvider, + "getUser", + ResponseType.Success, + mapOf( + "userAttributes" to listOf( + AttributeType.invoke { + name = "email" + value = "email@email.com" + }, + AttributeType.invoke { + name = "phone" + value = "000-000-0000" + } + ) + ).toJsonElement() + ) + + private val apiReturnValidation = ExpectationShapes.Amplify( + AuthAPI.fetchUserAttributes, + ResponseType.Success, + expectedSuccess, + ) + + private val baseCase = FeatureTestCase( + description = "Test that Cognito is called with given payload and returns successful data", + preConditions = PreConditions( + "authconfiguration.json", + "SignedIn_SessionEstablished.json", + mockedResponses = listOf(mockCognitoResponse) + ), + api = API( + AuthAPI.fetchUserAttributes, + JsonObject(emptyMap()), + JsonObject(emptyMap()), + ), + validations = listOf(apiReturnValidation) + ) + + private val successCase: FeatureTestCase = baseCase.copy( + description = "List of user attributes returned when fetch user attributes API succeeds", + preConditions = baseCase.preConditions.copy(mockedResponses = listOf(mockCognitoResponse)), + validations = baseCase.validations.plus(apiReturnValidation) + ) + + private val errorCase: FeatureTestCase + get() { + val errorResponse = SignedOutException() + return baseCase.copy( + description = "AuthException is thrown when fetchUserAttributes API is called without signing in", + preConditions = baseCase.preConditions.copy( + state = "SignedOut_Configured.json", + mockedResponses = listOf( + MockResponse( + CognitoType.CognitoIdentityProvider, + "getUser", + ResponseType.Failure, + errorResponse.toJsonElement() + ) + ) + ), + validations = listOf( + ExpectationShapes.Amplify( + AuthAPI.fetchUserAttributes, + ResponseType.Failure, + SignedOutException().toJsonElement(), + ) + ) + ) + } + + override val serializables: List = listOf(baseCase, errorCase, successCase) +} diff --git a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/ForgetDeviceTestCaseGenerator.kt b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/ForgetDeviceTestCaseGenerator.kt new file mode 100644 index 0000000000..52151d2322 --- /dev/null +++ b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/ForgetDeviceTestCaseGenerator.kt @@ -0,0 +1,96 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators + +import com.amplifyframework.auth.AuthDevice +import com.amplifyframework.auth.cognito.featuretest.API +import com.amplifyframework.auth.cognito.featuretest.AuthAPI +import com.amplifyframework.auth.cognito.featuretest.CognitoType +import com.amplifyframework.auth.cognito.featuretest.ExpectationShapes +import com.amplifyframework.auth.cognito.featuretest.FeatureTestCase +import com.amplifyframework.auth.cognito.featuretest.MockResponse +import com.amplifyframework.auth.cognito.featuretest.PreConditions +import com.amplifyframework.auth.cognito.featuretest.ResponseType +import com.amplifyframework.auth.cognito.featuretest.generators.SerializableProvider +import com.amplifyframework.auth.cognito.featuretest.generators.toJsonElement +import com.amplifyframework.auth.exceptions.SignedOutException +import kotlinx.serialization.json.JsonObject + +object ForgetDeviceTestCaseGenerator : SerializableProvider { + private val mockCognitoResponse = MockResponse( + CognitoType.CognitoIdentityProvider, + "updateDeviceStatus", + ResponseType.Success, + JsonObject(emptyMap()) + ) + + private val apiReturnValidation = ExpectationShapes.Amplify( + AuthAPI.forgetDevice, + ResponseType.Success, + JsonObject(emptyMap()), + ) + + private val baseCase = FeatureTestCase( + description = "Test that Cognito is called with given payload and returns successful data", + preConditions = PreConditions( + "authconfiguration.json", + "SignedIn_SessionEstablished.json", + mockedResponses = listOf(mockCognitoResponse) + ), + api = API( + AuthAPI.forgetDevice, + mapOf( + "device" to AuthDevice.fromId("id", "test") + ).toJsonElement(), + JsonObject(emptyMap()), + ), + validations = listOf(apiReturnValidation) + ) + + private val successCase: FeatureTestCase = baseCase.copy( + description = "Nothing is returned when forget device succeeds", + preConditions = baseCase.preConditions.copy(mockedResponses = listOf(mockCognitoResponse)), + validations = baseCase.validations.plus(apiReturnValidation) + ) + + private val errorCase: FeatureTestCase + get() { + val errorResponse = SignedOutException() + return baseCase.copy( + description = "AuthException is thrown when forgetDevice API is called without signing in", + preConditions = baseCase.preConditions.copy( + state = "SignedOut_Configured.json", + mockedResponses = listOf( + MockResponse( + CognitoType.CognitoIdentityProvider, + "forgetDevice", + ResponseType.Failure, + errorResponse.toJsonElement() + ) + ) + ), + validations = listOf( + ExpectationShapes.Amplify( + AuthAPI.forgetDevice, + ResponseType.Failure, + SignedOutException().toJsonElement(), + ) + ) + ) + } + + override val serializables: List = listOf(baseCase, errorCase, successCase) +} diff --git a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/GetCurrentUserTestCaseGenerator.kt b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/GetCurrentUserTestCaseGenerator.kt index 7eebb704b1..36c8dfbb12 100644 --- a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/GetCurrentUserTestCaseGenerator.kt +++ b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/GetCurrentUserTestCaseGenerator.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + package com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators import aws.sdk.kotlin.services.cognitoidentityprovider.model.NotAuthorizedException diff --git a/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/RememberDeviceTestCaseGenerator.kt b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/RememberDeviceTestCaseGenerator.kt new file mode 100644 index 0000000000..377d787195 --- /dev/null +++ b/aws-auth-cognito/src/test/java/com/amplifyframework/auth/cognito/featuretest/generators/testcasegenerators/RememberDeviceTestCaseGenerator.kt @@ -0,0 +1,85 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://aws.amazon.com/apache2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.amplifyframework.auth.cognito.featuretest.generators.testcasegenerators + +import aws.sdk.kotlin.services.cognitoidentityprovider.model.NotAuthorizedException +import com.amplifyframework.auth.cognito.featuretest.API +import com.amplifyframework.auth.cognito.featuretest.AuthAPI +import com.amplifyframework.auth.cognito.featuretest.CognitoType +import com.amplifyframework.auth.cognito.featuretest.ExpectationShapes +import com.amplifyframework.auth.cognito.featuretest.FeatureTestCase +import com.amplifyframework.auth.cognito.featuretest.MockResponse +import com.amplifyframework.auth.cognito.featuretest.PreConditions +import com.amplifyframework.auth.cognito.featuretest.ResponseType +import com.amplifyframework.auth.cognito.featuretest.generators.SerializableProvider +import com.amplifyframework.auth.cognito.featuretest.generators.toJsonElement +import kotlinx.serialization.json.JsonObject + +object RememberDeviceTestCaseGenerator : SerializableProvider { + private val mockCognitoResponse = MockResponse( + CognitoType.CognitoIdentityProvider, + "updateDeviceStatus", + ResponseType.Success, + JsonObject(emptyMap()) + ) + + private val apiReturnValidation = ExpectationShapes.Amplify( + AuthAPI.rememberDevice, + ResponseType.Success, + JsonObject(emptyMap()), + ) + + private val baseCase = FeatureTestCase( + description = "Test that Cognito is called with given payload and returns successful data", + preConditions = PreConditions( + "authconfiguration.json", + "SignedIn_SessionEstablished.json", + mockedResponses = listOf(mockCognitoResponse) + ), + api = API( + AuthAPI.rememberDevice, + JsonObject(emptyMap()), + JsonObject(emptyMap()) + ), + validations = listOf(apiReturnValidation) + ) + + private val successCase: FeatureTestCase = baseCase.copy( + description = "Nothing is returned when remember device succeeds", + preConditions = baseCase.preConditions.copy(mockedResponses = listOf(mockCognitoResponse)), + validations = baseCase.validations.plus(apiReturnValidation) + ) + + private val errorCase: FeatureTestCase + get() { + val errorResponse = NotAuthorizedException.invoke {} + return baseCase.copy( + description = "AuthException is thrown when rememberDevice API is called without signing in", + preConditions = baseCase.preConditions.copy( + state = "SignedOut_Configured.json" + ), + validations = listOf( + ExpectationShapes.Amplify( + AuthAPI.rememberDevice, + ResponseType.Failure, + com.amplifyframework.auth.exceptions.SignedOutException().toJsonElement(), + ) + ) + ) + } + + override val serializables: List = listOf(baseCase, errorCase, successCase) +} diff --git a/aws-auth-cognito/src/test/java/featureTest/utilities/APICaptorFactory.kt b/aws-auth-cognito/src/test/java/featureTest/utilities/APICaptorFactory.kt index a7a625de8b..8fd7d2c25f 100644 --- a/aws-auth-cognito/src/test/java/featureTest/utilities/APICaptorFactory.kt +++ b/aws-auth-cognito/src/test/java/featureTest/utilities/APICaptorFactory.kt @@ -47,7 +47,9 @@ class APICaptorFactory( AuthAPI.signIn to mockk>(), AuthAPI.deleteUser to mockk(), AuthAPI.fetchAuthSession to mockk(), - AuthAPI.getCurrentUser to mockk() + AuthAPI.getCurrentUser to mockk(), + AuthAPI.rememberDevice to mockk(), + AuthAPI.forgetDevice to mockk() ) val onError = mockk>() val onComplete = mapOf( @@ -105,6 +107,26 @@ class APICaptorFactory( every { consumer.call() } answers { latch.countDown() } successCaptors[apiName] = actionCaptor } + AuthAPI.rememberDevice -> { + val consumer = onSuccess[apiName] as Action + every { consumer.call() } answers { latch.countDown() } + successCaptors[apiName] = actionCaptor + } + AuthAPI.forgetDevice -> { + val consumer = onSuccess[apiName] as Action + every { consumer.call() } answers { latch.countDown() } + successCaptors[apiName] = actionCaptor + } + AuthAPI.fetchDevices -> { + val consumer = onSuccess[apiName] as Action + every { consumer.call() } answers { latch.countDown() } + successCaptors[apiName] = actionCaptor + } + AuthAPI.fetchUserAttributes -> { + val consumer = onSuccess[apiName] as Action + every { consumer.call() } answers { latch.countDown() } + successCaptors[apiName] = actionCaptor + } else -> throw Error("onSuccess for $authApi is not defined!") } } diff --git a/aws-auth-cognito/src/test/java/featureTest/utilities/APIExecutor.kt b/aws-auth-cognito/src/test/java/featureTest/utilities/APIExecutor.kt index 32ebde1094..093bced842 100644 --- a/aws-auth-cognito/src/test/java/featureTest/utilities/APIExecutor.kt +++ b/aws-auth-cognito/src/test/java/featureTest/utilities/APIExecutor.kt @@ -22,7 +22,9 @@ import com.amplifyframework.core.Consumer import com.google.gson.Gson import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit +import kotlin.Exception import kotlin.reflect.KClass +import kotlin.reflect.KFunction import kotlin.reflect.KParameter import kotlin.reflect.full.declaredFunctions import kotlinx.serialization.json.JsonObject @@ -34,25 +36,37 @@ internal val apiExecutor: (AWSCognitoAuthPlugin, API) -> Any = { authPlugin: AWS lateinit var result: Any val latch = CountDownLatch(1) + val targetApis = authPlugin::class.declaredFunctions.filter { it.name == api.name.name } - val targetApi = authPlugin::class.declaredFunctions.first { it.name == api.name.name } - - val requiredParams = targetApi.parameters.associateWith { kParam -> - when { - kParam.kind == KParameter.Kind.INSTANCE -> authPlugin - kParam.type.classifier as KClass<*> == Action::class -> Action { - result = Unit - latch.countDown() - } - kParam.type.classifier as KClass<*> == Consumer::class -> Consumer { value -> - result = value - latch.countDown() + var requiredParams: Map? = null + var targetApi: KFunction<*>? = null + for (currentApi in targetApis) { + try { + val currentParams = currentApi.parameters.associateWith { kParam -> + when { + kParam.kind == KParameter.Kind.INSTANCE -> authPlugin + kParam.type.classifier as KClass<*> == Action::class -> Action { + result = Unit + latch.countDown() + } + kParam.type.classifier as KClass<*> == Consumer::class -> Consumer { value -> + result = value + latch.countDown() + } + kParam.name == "options" -> AuthOptionsFactory.create(api.name, api.options as JsonObject) + else -> kParam.name?.let { getParam(it, kParam, api.params as JsonObject) } + } } - kParam.name == "options" -> AuthOptionsFactory.create(api.name, api.options as JsonObject) - else -> kParam.name?.let { getParam(it, api.params as JsonObject) } + targetApi = currentApi + requiredParams = currentParams + break + } catch (ex: Exception) { + print(ex.toString()) } } + if (targetApi == null || requiredParams == null) + throw Exception("No matching api function with required parameters found") targetApi.callBy(requiredParams) latch.await(5, TimeUnit.SECONDS) @@ -62,10 +76,10 @@ internal val apiExecutor: (AWSCognitoAuthPlugin, API) -> Any = { authPlugin: AWS /** * Traverses given json to find value of paramName */ -private inline fun getParam(paramName: String, paramsObject: Map): T { +private inline fun getParam(paramName: String, kParam: KParameter, paramsObject: Map): kotlin.Any { paramsObject.entries.first { it.key == paramName }.apply { - return Gson().fromJson(value.toString(), T::class.java) + return Gson().fromJson(value.toString(), (kParam.type.classifier as KClass<*>).javaObjectType) } } diff --git a/aws-auth-cognito/src/test/java/featureTest/utilities/AuthOptionsFactory.kt b/aws-auth-cognito/src/test/java/featureTest/utilities/AuthOptionsFactory.kt index 0c386a6690..787c8390a6 100644 --- a/aws-auth-cognito/src/test/java/featureTest/utilities/AuthOptionsFactory.kt +++ b/aws-auth-cognito/src/test/java/featureTest/utilities/AuthOptionsFactory.kt @@ -55,10 +55,10 @@ object AuthOptionsFactory { AuthAPI.fetchAuthSession -> getFetchAuthSessionOptions(optionsData) AuthAPI.fetchDevices -> null AuthAPI.fetchUserAttributes -> TODO() - AuthAPI.forgetDevice -> TODO() + AuthAPI.forgetDevice -> null AuthAPI.getCurrentUser -> null AuthAPI.handleWebUISignInResponse -> TODO() - AuthAPI.rememberDevice -> TODO() + AuthAPI.rememberDevice -> null AuthAPI.resendSignUpCode -> AuthResendSignUpCodeOptions.defaults() AuthAPI.resendUserAttributeConfirmationCode -> AuthResendUserAttributeConfirmationCodeOptions.defaults() signIn -> getSignInOptions(optionsData) diff --git a/aws-auth-cognito/src/test/java/featureTest/utilities/CognitoMockFactory.kt b/aws-auth-cognito/src/test/java/featureTest/utilities/CognitoMockFactory.kt index de657cb440..61ebc7bcd7 100644 --- a/aws-auth-cognito/src/test/java/featureTest/utilities/CognitoMockFactory.kt +++ b/aws-auth-cognito/src/test/java/featureTest/utilities/CognitoMockFactory.kt @@ -20,18 +20,25 @@ import aws.sdk.kotlin.services.cognitoidentity.model.Credentials import aws.sdk.kotlin.services.cognitoidentity.model.GetCredentialsForIdentityResponse import aws.sdk.kotlin.services.cognitoidentity.model.GetIdResponse import aws.sdk.kotlin.services.cognitoidentityprovider.CognitoIdentityProviderClient +import aws.sdk.kotlin.services.cognitoidentityprovider.forgetDevice +import aws.sdk.kotlin.services.cognitoidentityprovider.model.AttributeType import aws.sdk.kotlin.services.cognitoidentityprovider.model.AuthenticationResultType import aws.sdk.kotlin.services.cognitoidentityprovider.model.ChallengeNameType import aws.sdk.kotlin.services.cognitoidentityprovider.model.CodeDeliveryDetailsType import aws.sdk.kotlin.services.cognitoidentityprovider.model.ConfirmDeviceResponse import aws.sdk.kotlin.services.cognitoidentityprovider.model.DeleteUserResponse import aws.sdk.kotlin.services.cognitoidentityprovider.model.DeliveryMediumType +import aws.sdk.kotlin.services.cognitoidentityprovider.model.DeviceType +import aws.sdk.kotlin.services.cognitoidentityprovider.model.ForgetDeviceResponse import aws.sdk.kotlin.services.cognitoidentityprovider.model.ForgotPasswordResponse +import aws.sdk.kotlin.services.cognitoidentityprovider.model.GetUserResponse import aws.sdk.kotlin.services.cognitoidentityprovider.model.GlobalSignOutResponse import aws.sdk.kotlin.services.cognitoidentityprovider.model.InitiateAuthResponse +import aws.sdk.kotlin.services.cognitoidentityprovider.model.ListDevicesResponse import aws.sdk.kotlin.services.cognitoidentityprovider.model.RespondToAuthChallengeResponse import aws.sdk.kotlin.services.cognitoidentityprovider.model.RevokeTokenResponse import aws.sdk.kotlin.services.cognitoidentityprovider.model.SignUpResponse +import aws.sdk.kotlin.services.cognitoidentityprovider.model.UpdateDeviceStatusResponse import aws.smithy.kotlin.runtime.time.Instant import com.amplifyframework.auth.cognito.featuretest.CognitoType import com.amplifyframework.auth.cognito.featuretest.MockResponse @@ -119,6 +126,23 @@ class CognitoMockFactory( } } } + "getUser" -> { + coEvery { mockCognitoIPClient.getUser(any()) } coAnswers { + setupError(mockResponse, responseObject) + GetUserResponse.invoke { + userAttributes = listOf( + AttributeType.invoke { + name = "email" + value = "email@email.com" + }, + AttributeType.invoke { + name = "phone_number" + value = "000-000-0000" + } + ) + } + } + } "getCredentialsForIdentity" -> { coEvery { mockCognitoIdClient.getCredentialsForIdentity(any()) } coAnswers { setupError(mockResponse, responseObject) @@ -145,6 +169,39 @@ class CognitoMockFactory( GlobalSignOutResponse.invoke {} } } + "updateDeviceStatus" -> { + coEvery { mockCognitoIPClient.updateDeviceStatus(any()) } coAnswers { + setupError(mockResponse, responseObject) + UpdateDeviceStatusResponse.invoke { } + } + } + "forgetDevice" -> { + coEvery { mockCognitoIPClient.forgetDevice(any()) } coAnswers { + setupError(mockResponse, responseObject) + ForgetDeviceResponse.invoke {} + } + } + "listDevices" -> { + coEvery { mockCognitoIPClient.listDevices(any()) } coAnswers { + setupError(mockResponse, responseObject) + ListDevicesResponse.invoke { + devices = listOf( + DeviceType.invoke { + deviceAttributes = listOf( + AttributeType.invoke { + name = "name" + value = "value" + } + ) + deviceKey = "deviceKey" + deviceCreateDate = Instant.now() + deviceLastAuthenticatedDate = Instant.now() + deviceLastModifiedDate = Instant.now() + } + ) + } + } + } else -> throw Error("mock for ${mockResponse.apiName} not defined!") } } diff --git a/aws-auth-cognito/src/test/resources/feature-test/states/CustomSignIn_SigningIn.json b/aws-auth-cognito/src/test/resources/feature-test/states/CustomSignIn_SigningIn.json index 5ccb17e359..e69e8f6662 100644 --- a/aws-auth-cognito/src/test/resources/feature-test/states/CustomSignIn_SigningIn.json +++ b/aws-auth-cognito/src/test/resources/feature-test/states/CustomSignIn_SigningIn.json @@ -9,7 +9,7 @@ "authChallenge": { "challengeName": "CUSTOM_CHALLENGE", "username": "username", - "session": "someSession", + "session": null, "parameters": { "SALT": "abc", "SECRET_BLOCK": "secretBlock", diff --git a/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchDevices/AuthException_is_thrown_when_forgetDevice_API_is_called_without_signing_in.json b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchDevices/AuthException_is_thrown_when_forgetDevice_API_is_called_without_signing_in.json new file mode 100644 index 0000000000..7f79fddd9f --- /dev/null +++ b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchDevices/AuthException_is_thrown_when_forgetDevice_API_is_called_without_signing_in.json @@ -0,0 +1,40 @@ +{ + "description": "AuthException is thrown when forgetDevice API is called without signing in", + "preConditions": { + "amplify-configuration": "authconfiguration.json", + "state": "SignedOut_Configured.json", + "mockedResponses": [ + { + "type": "cognitoIdentityProvider", + "apiName": "forgetDevice", + "responseType": "failure", + "response": { + "errorType": "SignedOutException", + "errorMessage": "You are currently signed out.", + "recoverySuggestion": "Please sign in and reattempt the operation.", + "cause": null + } + } + ] + }, + "api": { + "name": "fetchDevices", + "params": { + }, + "options": { + } + }, + "validations": [ + { + "type": "amplify", + "apiName": "forgetDevice", + "responseType": "failure", + "response": { + "errorType": "SignedOutException", + "errorMessage": "You are currently signed out.", + "recoverySuggestion": "Please sign in and reattempt the operation.", + "cause": null + } + } + ] +} \ No newline at end of file diff --git a/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchDevices/List_of_devices_returned_when_fetch_devices_API_succeeds.json b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchDevices/List_of_devices_returned_when_fetch_devices_API_succeeds.json new file mode 100644 index 0000000000..1d0f571325 --- /dev/null +++ b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchDevices/List_of_devices_returned_when_fetch_devices_API_succeeds.json @@ -0,0 +1,74 @@ +{ + "description": "List of devices returned when fetch devices API succeeds", + "preConditions": { + "amplify-configuration": "authconfiguration.json", + "state": "SignedIn_SessionEstablished.json", + "mockedResponses": [ + { + "type": "cognitoIdentityProvider", + "apiName": "listDevices", + "responseType": "success", + "response": { + "devices": [ + { + "deviceAttributes": [ + { + "name": "name", + "value": "value" + } + ], + "deviceCreateDate": { + "value": { + "seconds": 1.671733506E9, + "nanos": 9.95178E8 + } + }, + "deviceKey": "deviceKey", + "deviceLastAuthenticatedDate": { + "value": { + "seconds": 1.671733506E9, + "nanos": 9.95186E8 + } + }, + "deviceLastModifiedDate": { + "value": { + "seconds": 1.671733506E9, + "nanos": 9.95188E8 + } + } + } + ] + } + } + ] + }, + "api": { + "name": "fetchDevices", + "params": { + }, + "options": { + } + }, + "validations": [ + { + "type": "amplify", + "apiName": "fetchDevices", + "responseType": "success", + "response": [ + { + "id": "deviceKey" + } + ] + }, + { + "type": "amplify", + "apiName": "fetchDevices", + "responseType": "success", + "response": [ + { + "id": "deviceKey" + } + ] + } + ] +} \ No newline at end of file diff --git a/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchDevices/Test_that_Cognito_is_called_with_given_payload_and_returns_successful_data.json b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchDevices/Test_that_Cognito_is_called_with_given_payload_and_returns_successful_data.json new file mode 100644 index 0000000000..1290b9a458 --- /dev/null +++ b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchDevices/Test_that_Cognito_is_called_with_given_payload_and_returns_successful_data.json @@ -0,0 +1,64 @@ +{ + "description": "Test that Cognito is called with given payload and returns successful data", + "preConditions": { + "amplify-configuration": "authconfiguration.json", + "state": "SignedIn_SessionEstablished.json", + "mockedResponses": [ + { + "type": "cognitoIdentityProvider", + "apiName": "listDevices", + "responseType": "success", + "response": { + "devices": [ + { + "deviceAttributes": [ + { + "name": "name", + "value": "value" + } + ], + "deviceCreateDate": { + "value": { + "seconds": 1.671733506E9, + "nanos": 9.95178E8 + } + }, + "deviceKey": "deviceKey", + "deviceLastAuthenticatedDate": { + "value": { + "seconds": 1.671733506E9, + "nanos": 9.95186E8 + } + }, + "deviceLastModifiedDate": { + "value": { + "seconds": 1.671733506E9, + "nanos": 9.95188E8 + } + } + } + ] + } + } + ] + }, + "api": { + "name": "fetchDevices", + "params": { + }, + "options": { + } + }, + "validations": [ + { + "type": "amplify", + "apiName": "fetchDevices", + "responseType": "success", + "response": [ + { + "id": "deviceKey" + } + ] + } + ] +} \ No newline at end of file diff --git a/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchUserAttributes/AuthException_is_thrown_when_fetchUserAttributes_API_is_called_without_signing_in.json b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchUserAttributes/AuthException_is_thrown_when_fetchUserAttributes_API_is_called_without_signing_in.json new file mode 100644 index 0000000000..3fae2bff15 --- /dev/null +++ b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchUserAttributes/AuthException_is_thrown_when_fetchUserAttributes_API_is_called_without_signing_in.json @@ -0,0 +1,40 @@ +{ + "description": "AuthException is thrown when fetchUserAttributes API is called without signing in", + "preConditions": { + "amplify-configuration": "authconfiguration.json", + "state": "SignedOut_Configured.json", + "mockedResponses": [ + { + "type": "cognitoIdentityProvider", + "apiName": "getUser", + "responseType": "failure", + "response": { + "errorType": "SignedOutException", + "errorMessage": "You are currently signed out.", + "recoverySuggestion": "Please sign in and reattempt the operation.", + "cause": null + } + } + ] + }, + "api": { + "name": "fetchUserAttributes", + "params": { + }, + "options": { + } + }, + "validations": [ + { + "type": "amplify", + "apiName": "fetchUserAttributes", + "responseType": "failure", + "response": { + "errorType": "SignedOutException", + "errorMessage": "You are currently signed out.", + "recoverySuggestion": "Please sign in and reattempt the operation.", + "cause": null + } + } + ] +} \ No newline at end of file diff --git a/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchUserAttributes/List_of_user_attributes_returned_when_fetch_user_attributes_API_succeeds.json b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchUserAttributes/List_of_user_attributes_returned_when_fetch_user_attributes_API_succeeds.json new file mode 100644 index 0000000000..f29bc29423 --- /dev/null +++ b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchUserAttributes/List_of_user_attributes_returned_when_fetch_user_attributes_API_succeeds.json @@ -0,0 +1,73 @@ +{ + "description": "List of user attributes returned when fetch user attributes API succeeds", + "preConditions": { + "amplify-configuration": "authconfiguration.json", + "state": "SignedIn_SessionEstablished.json", + "mockedResponses": [ + { + "type": "cognitoIdentityProvider", + "apiName": "getUser", + "responseType": "success", + "response": { + "userAttributes": [ + { + "name": "email", + "value": "email@email.com" + }, + { + "name": "phone", + "value": "000-000-0000" + } + ] + } + } + ] + }, + "api": { + "name": "fetchUserAttributes", + "params": { + }, + "options": { + } + }, + "validations": [ + { + "type": "amplify", + "apiName": "fetchUserAttributes", + "responseType": "success", + "response": [ + { + "key": { + "attributeKey": "email" + }, + "value": "email@email.com" + }, + { + "key": { + "attributeKey": "phone_number" + }, + "value": "000-000-0000" + } + ] + }, + { + "type": "amplify", + "apiName": "fetchUserAttributes", + "responseType": "success", + "response": [ + { + "key": { + "attributeKey": "email" + }, + "value": "email@email.com" + }, + { + "key": { + "attributeKey": "phone_number" + }, + "value": "000-000-0000" + } + ] + } + ] +} \ No newline at end of file diff --git a/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchUserAttributes/Test_that_Cognito_is_called_with_given_payload_and_returns_successful_data.json b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchUserAttributes/Test_that_Cognito_is_called_with_given_payload_and_returns_successful_data.json new file mode 100644 index 0000000000..0dcda9da81 --- /dev/null +++ b/aws-auth-cognito/src/test/resources/feature-test/testsuites/fetchUserAttributes/Test_that_Cognito_is_called_with_given_payload_and_returns_successful_data.json @@ -0,0 +1,54 @@ +{ + "description": "Test that Cognito is called with given payload and returns successful data", + "preConditions": { + "amplify-configuration": "authconfiguration.json", + "state": "SignedIn_SessionEstablished.json", + "mockedResponses": [ + { + "type": "cognitoIdentityProvider", + "apiName": "getUser", + "responseType": "success", + "response": { + "userAttributes": [ + { + "name": "email", + "value": "email@email.com" + }, + { + "name": "phone", + "value": "000-000-0000" + } + ] + } + } + ] + }, + "api": { + "name": "fetchUserAttributes", + "params": { + }, + "options": { + } + }, + "validations": [ + { + "type": "amplify", + "apiName": "fetchUserAttributes", + "responseType": "success", + "response": [ + { + "key": { + "attributeKey": "email" + }, + "value": "email@email.com" + }, + { + "key": { + "attributeKey": "phone_number" + }, + "value": "000-000-0000" + } + ] + } + ] +} \ No newline at end of file diff --git a/aws-auth-cognito/src/test/resources/feature-test/testsuites/forgetDevice/AuthException_is_thrown_when_forgetDevice_API_is_called_without_signing_in.json b/aws-auth-cognito/src/test/resources/feature-test/testsuites/forgetDevice/AuthException_is_thrown_when_forgetDevice_API_is_called_without_signing_in.json new file mode 100644 index 0000000000..8b9afeaafd --- /dev/null +++ b/aws-auth-cognito/src/test/resources/feature-test/testsuites/forgetDevice/AuthException_is_thrown_when_forgetDevice_API_is_called_without_signing_in.json @@ -0,0 +1,44 @@ +{ + "description": "AuthException is thrown when forgetDevice API is called without signing in", + "preConditions": { + "amplify-configuration": "authconfiguration.json", + "state": "SignedOut_Configured.json", + "mockedResponses": [ + { + "type": "cognitoIdentityProvider", + "apiName": "forgetDevice", + "responseType": "failure", + "response": { + "errorType": "SignedOutException", + "errorMessage": "You are currently signed out.", + "recoverySuggestion": "Please sign in and reattempt the operation.", + "cause": null + } + } + ] + }, + "api": { + "name": "forgetDevice", + "params": { + "device": { + "id": "id", + "name": "test" + } + }, + "options": { + } + }, + "validations": [ + { + "type": "amplify", + "apiName": "forgetDevice", + "responseType": "failure", + "response": { + "errorType": "SignedOutException", + "errorMessage": "You are currently signed out.", + "recoverySuggestion": "Please sign in and reattempt the operation.", + "cause": null + } + } + ] +} \ No newline at end of file diff --git a/aws-auth-cognito/src/test/resources/feature-test/testsuites/rememberDevice/AuthException_is_thrown_when_rememberDevice_API_is_called_without_signing_in.json b/aws-auth-cognito/src/test/resources/feature-test/testsuites/rememberDevice/AuthException_is_thrown_when_rememberDevice_API_is_called_without_signing_in.json new file mode 100644 index 0000000000..012c0b52dd --- /dev/null +++ b/aws-auth-cognito/src/test/resources/feature-test/testsuites/rememberDevice/AuthException_is_thrown_when_rememberDevice_API_is_called_without_signing_in.json @@ -0,0 +1,36 @@ +{ + "description": "AuthException is thrown when rememberDevice API is called without signing in", + "preConditions": { + "amplify-configuration": "authconfiguration.json", + "state": "SignedOut_Configured.json", + "mockedResponses": [ + { + "type": "cognitoIdentityProvider", + "apiName": "updateDeviceStatus", + "responseType": "success", + "response": { + } + } + ] + }, + "api": { + "name": "rememberDevice", + "params": { + }, + "options": { + } + }, + "validations": [ + { + "type": "amplify", + "apiName": "rememberDevice", + "responseType": "failure", + "response": { + "errorType": "SignedOutException", + "errorMessage": "You are currently signed out.", + "recoverySuggestion": "Please sign in and reattempt the operation.", + "cause": null + } + } + ] +} \ No newline at end of file