diff --git a/packages/analytics/amplify_analytics_pinpoint/example/integration_test/identify_user_test.dart b/packages/analytics/amplify_analytics_pinpoint/example/integration_test/identify_user_test.dart index bb7b84f81b1..5378166ca99 100644 --- a/packages/analytics/amplify_analytics_pinpoint/example/integration_test/identify_user_test.dart +++ b/packages/analytics/amplify_analytics_pinpoint/example/integration_test/identify_user_test.dart @@ -25,110 +25,108 @@ void main() { eventsStream = await subscribeToEvents(); }); - testWidgets( - 'properties of identityUser() added to all future events', - (_) async { - final userId = DateTime.now().toIso8601String(); - const name = 'name'; - const email = 'email'; - const plan = 'plan'; + testWidgets('properties of identityUser() added to all future events', ( + _, + ) async { + final userId = DateTime.now().toIso8601String(); + const name = 'name'; + const email = 'email'; + const plan = 'plan'; - const latitude = 43.0; - const longitude = 12.0; - const postalCode = '94070'; - const city = 'city'; - const region = 'region'; - const country = 'USA'; + const latitude = 43.0; + const longitude = 12.0; + const postalCode = '94070'; + const city = 'city'; + const region = 'region'; + const country = 'USA'; - const location = UserProfileLocation( - latitude: latitude, - longitude: longitude, - postalCode: postalCode, - city: city, - region: region, - country: country, - ); + const location = UserProfileLocation( + latitude: latitude, + longitude: longitude, + postalCode: postalCode, + city: city, + region: region, + country: country, + ); - final properties = CustomProperties() - ..addBoolProperty(boolProperty.key, boolProperty.value) - ..addDoubleProperty(doubleProperty.key, doubleProperty.value) - ..addIntProperty(intProperty.key, intProperty.value) - ..addStringProperty(stringProperty.key, stringProperty.value); + final properties = CustomProperties() + ..addBoolProperty(boolProperty.key, boolProperty.value) + ..addDoubleProperty(doubleProperty.key, doubleProperty.value) + ..addIntProperty(intProperty.key, intProperty.value) + ..addStringProperty(stringProperty.key, stringProperty.value); - await Amplify.Analytics.identifyUser( - userId: userId, - userProfile: AWSPinpointUserProfile( - name: name, - email: email, - plan: plan, - location: location, - customProperties: properties, - userAttributes: { - stringProperty.key: [stringProperty.value, stringProperty.value], - }, - ), - ); + await Amplify.Analytics.identifyUser( + userId: userId, + userProfile: AWSPinpointUserProfile( + name: name, + email: email, + plan: plan, + location: location, + customProperties: properties, + userAttributes: { + stringProperty.key: [stringProperty.value, stringProperty.value], + }, + ), + ); - const customEventName = 'identify user event name'; - final customEvent = AnalyticsEvent(customEventName); + const customEventName = 'identify user event name'; + final customEvent = AnalyticsEvent(customEventName); - await Amplify.Analytics.recordEvent(event: customEvent); - await Amplify.Analytics.flushEvents(); + await Amplify.Analytics.recordEvent(event: customEvent); + await Amplify.Analytics.flushEvents(); - await expectLater( - eventsStream, - emits( - isA() - .having((e) => e.eventType, 'eventType', customEventName) - .having( - (e) => e.endpoint.endpointStatus, - 'EndpointStatus', - 'ACTIVE', - ) - .having((e) => e.endpoint.optOut, 'OptOut', 'ALL') - .having( - (e) => e.endpoint.location, - 'Location', - EndpointLocation( - latitude: latitude, - longitude: longitude, - postalCode: postalCode, - city: city, - region: region, - country: country, - ), - ) - .having((e) => e.endpoint.user?.userId, 'UserId', userId) - .having( - (e) => e.endpoint.user?.userAttributes?.toMap() ?? const {}, - 'UserAttributes', - equals({ - stringProperty.key: [ - stringProperty.value, - stringProperty.value, - ], - }), - ) - .having( - (e) => e.endpoint.attributes?.toMap() ?? const {}, - 'Attributes', - equals({ - boolProperty.key: [stringifiedBoolProperty.value], - stringProperty.key: [stringProperty.value], - 'name': [name], - 'plan': [plan], - 'email': [email], - }), - ) - .having( - (e) => e.endpoint.metrics?.toMap() ?? const {}, - 'Metrics', - equals(Map.fromEntries([lossyDoubleProperty, intProperty])), + await expectLater( + eventsStream, + emits( + isA() + .having((e) => e.eventType, 'eventType', customEventName) + .having( + (e) => e.endpoint.endpointStatus, + 'EndpointStatus', + 'ACTIVE', + ) + .having((e) => e.endpoint.optOut, 'OptOut', 'ALL') + .having( + (e) => e.endpoint.location, + 'Location', + EndpointLocation( + latitude: latitude, + longitude: longitude, + postalCode: postalCode, + city: city, + region: region, + country: country, ), - ), - ); - }, - timeout: const Timeout(Duration(minutes: 3)), - ); + ) + .having((e) => e.endpoint.user?.userId, 'UserId', userId) + .having( + (e) => e.endpoint.user?.userAttributes?.toMap() ?? const {}, + 'UserAttributes', + equals({ + stringProperty.key: [ + stringProperty.value, + stringProperty.value, + ], + }), + ) + .having( + (e) => e.endpoint.attributes?.toMap() ?? const {}, + 'Attributes', + equals({ + boolProperty.key: [stringifiedBoolProperty.value], + stringProperty.key: [stringProperty.value], + 'name': [name], + 'plan': [plan], + 'email': [email], + }), + ) + .having( + (e) => e.endpoint.metrics?.toMap() ?? const {}, + 'Metrics', + equals(Map.fromEntries([lossyDoubleProperty, intProperty])), + ), + ), + ); + }, timeout: const Timeout(Duration(minutes: 3))); }); } diff --git a/packages/api/amplify_api_dart/lib/src/graphql/factories/graphql_request_factory.dart b/packages/api/amplify_api_dart/lib/src/graphql/factories/graphql_request_factory.dart index 74fa072355b..798b1ee939c 100644 --- a/packages/api/amplify_api_dart/lib/src/graphql/factories/graphql_request_factory.dart +++ b/packages/api/amplify_api_dart/lib/src/graphql/factories/graphql_request_factory.dart @@ -148,7 +148,9 @@ class GraphQLRequestFactory { // codegen. Instead, just write the value to the document. final bLowerOutput = StringBuffer(_openParen); for (final field in modelIndex.fields) { - var value = modelIdentifier!.serializeAsMap()[field]; + var value = _getSerializedValue( + modelIdentifier!.serializeAsMap()[field], + ); if (value is String) { value = '"$value"'; } @@ -256,6 +258,14 @@ class GraphQLRequestFactory { }; } + Map serializeModelIdentifier({ + required ModelIdentifier modelIdentifier, + }) { + return modelIdentifier.serializeAsMap().map( + (key, dynamic value) => MapEntry(key, _getSerializedValue(value)), + ); + } + Map buildVariablesForMutationRequest({ required Map input, Map? condition, diff --git a/packages/api/amplify_api_dart/lib/src/graphql/factories/model_mutations_factory.dart b/packages/api/amplify_api_dart/lib/src/graphql/factories/model_mutations_factory.dart index f281fd57f61..5e97cb95c17 100644 --- a/packages/api/amplify_api_dart/lib/src/graphql/factories/model_mutations_factory.dart +++ b/packages/api/amplify_api_dart/lib/src/graphql/factories/model_mutations_factory.dart @@ -67,8 +67,9 @@ class ModelMutationsFactory { }) { final condition = GraphQLRequestFactory.instance .queryPredicateToGraphQLFilter(where, modelType); - final input = modelIdentifier - .serializeAsMap(); // Simpler input than other mutations so don't use helper. + final input = GraphQLRequestFactory.instance.serializeModelIdentifier( + modelIdentifier: modelIdentifier, + ); final variables = GraphQLRequestFactory.instance .buildVariablesForMutationRequest(input: input, condition: condition); diff --git a/packages/api/amplify_api_dart/lib/src/graphql/factories/model_queries_factory.dart b/packages/api/amplify_api_dart/lib/src/graphql/factories/model_queries_factory.dart index 7cfb6db9936..4f6086bec21 100644 --- a/packages/api/amplify_api_dart/lib/src/graphql/factories/model_queries_factory.dart +++ b/packages/api/amplify_api_dart/lib/src/graphql/factories/model_queries_factory.dart @@ -22,7 +22,9 @@ class ModelQueriesFactory { APIAuthorizationType? authorizationMode, Map? headers, }) { - final variables = modelIdentifier.serializeAsMap(); + final variables = GraphQLRequestFactory.instance.serializeModelIdentifier( + modelIdentifier: modelIdentifier, + ); return GraphQLRequestFactory.instance.buildRequest( modelType: modelType, modelIdentifier: modelIdentifier, diff --git a/packages/api/amplify_api_dart/test/graphql_test.dart b/packages/api/amplify_api_dart/test/graphql_test.dart index c2d358995c3..6effa97f2ac 100644 --- a/packages/api/amplify_api_dart/test/graphql_test.dart +++ b/packages/api/amplify_api_dart/test/graphql_test.dart @@ -224,6 +224,50 @@ void main() { expect(res.errors, isEmpty); }); + test('Query for a model with a TemporalDateTime in its custom identifier ' + 'serializes without throwing (regression test for #6298)', () { + const hwid = '94B216FCC67F'; + final sessionStart = TemporalDateTime.fromString( + '2025-03-28T23:07:34.000Z', + ); + final serializedDate = sessionStart.toString(); + final expectedDoc = + 'query getCpkTemporalPrimaryKey { getCpkTemporalPrimaryKey(hwid: "$hwid", sessionStart: "$serializedDate") { hwid sessionStart createdAt updatedAt } }'; + + final req = ModelQueries.get( + CpkTemporalPrimaryKey.classType, + CpkTemporalPrimaryKeyModelIdentifier( + hwid: hwid, + sessionStart: sessionStart, + ), + ); + + // request asserts + expect(req.document, expectedDoc); + expect(() => json.encode(req.variables), returnsNormally); + expect(req.variables['sessionStart'], equals(serializedDate)); + }); + + test('Delete for a model with a TemporalDateTime in its custom identifier ' + 'serializes without throwing (regression test for #6298)', () { + const hwid = '94B216FCC67F'; + final sessionStart = TemporalDateTime.fromString( + '2025-03-28T23:07:34.000Z', + ); + final serializedDate = sessionStart.toString(); + + final req = ModelMutations.delete( + CpkTemporalPrimaryKey(hwid: hwid, sessionStart: sessionStart), + ); + + // request asserts + expect(() => json.encode(req.variables), returnsNormally); + expect( + (req.variables['input'] as Map)['sessionStart'], + equals(serializedDate), + ); + }); + test( 'Mutation.create returns proper response.data for Models with custom types', () async { diff --git a/packages/api/amplify_api_dart/test/test_models/CpkTemporalPrimaryKey.dart b/packages/api/amplify_api_dart/test/test_models/CpkTemporalPrimaryKey.dart new file mode 100644 index 00000000000..4b3750bfe6f --- /dev/null +++ b/packages/api/amplify_api_dart/test/test_models/CpkTemporalPrimaryKey.dart @@ -0,0 +1,340 @@ +/* +* Copyright 2021 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. +*/ + +// NOTE: This file is generated and may not follow lint rules defined in your app +// Generated files can be excluded from analysis in analysis_options.yaml +// For more info, see: https://dart.dev/guides/language/analysis-options#excluding-code-from-analysis + +// ignore_for_file: public_member_api_docs, annotate_overrides, dead_code, dead_codepublic_member_api_docs, depend_on_referenced_packages, file_names, library_private_types_in_public_api, no_leading_underscores_for_library_prefixes, no_leading_underscores_for_local_identifiers, non_constant_identifier_names, null_check_on_nullable_type_parameter, override_on_non_overriding_member, prefer_adjacent_string_concatenation, prefer_const_constructors, prefer_if_null_operators, prefer_interpolation_to_compose_strings, slash_for_doc_comments, sort_child_properties_last, unnecessary_const, unnecessary_constructor_name, unnecessary_late, unnecessary_new, unnecessary_null_aware_assignments, unnecessary_nullable_for_final_variable_declarations, unnecessary_string_interpolations, use_build_context_synchronously + +import 'ModelProvider.dart'; +import 'package:amplify_core/amplify_core.dart' as amplify_core; + +/** This is an auto generated class representing the CpkTemporalPrimaryKey type in your schema. */ +class CpkTemporalPrimaryKey extends amplify_core.Model { + static const classType = const _CpkTemporalPrimaryKeyModelType(); + final String? _hwid; + final amplify_core.TemporalDateTime? _sessionStart; + final amplify_core.TemporalDateTime? _createdAt; + final amplify_core.TemporalDateTime? _updatedAt; + + @override + getInstanceType() => classType; + + @Deprecated( + '[getId] is being deprecated in favor of custom primary key feature. Use getter [modelIdentifier] to get model identifier.', + ) + @override + String getId() => modelIdentifier.serializeAsString(); + + CpkTemporalPrimaryKeyModelIdentifier get modelIdentifier { + try { + return CpkTemporalPrimaryKeyModelIdentifier( + hwid: _hwid!, + sessionStart: _sessionStart!, + ); + } catch (e) { + throw amplify_core.AmplifyCodeGenModelException( + amplify_core + .AmplifyExceptionMessages + .codeGenRequiredFieldForceCastExceptionMessage, + recoverySuggestion: amplify_core + .AmplifyExceptionMessages + .codeGenRequiredFieldForceCastRecoverySuggestion, + underlyingException: e.toString(), + ); + } + } + + String get hwid { + try { + return _hwid!; + } catch (e) { + throw amplify_core.AmplifyCodeGenModelException( + amplify_core + .AmplifyExceptionMessages + .codeGenRequiredFieldForceCastExceptionMessage, + recoverySuggestion: amplify_core + .AmplifyExceptionMessages + .codeGenRequiredFieldForceCastRecoverySuggestion, + underlyingException: e.toString(), + ); + } + } + + amplify_core.TemporalDateTime get sessionStart { + try { + return _sessionStart!; + } catch (e) { + throw amplify_core.AmplifyCodeGenModelException( + amplify_core + .AmplifyExceptionMessages + .codeGenRequiredFieldForceCastExceptionMessage, + recoverySuggestion: amplify_core + .AmplifyExceptionMessages + .codeGenRequiredFieldForceCastRecoverySuggestion, + underlyingException: e.toString(), + ); + } + } + + amplify_core.TemporalDateTime? get createdAt { + return _createdAt; + } + + amplify_core.TemporalDateTime? get updatedAt { + return _updatedAt; + } + + const CpkTemporalPrimaryKey._internal({ + required hwid, + required sessionStart, + createdAt, + updatedAt, + }) : _hwid = hwid, + _sessionStart = sessionStart, + _createdAt = createdAt, + _updatedAt = updatedAt; + + factory CpkTemporalPrimaryKey({ + required String hwid, + required amplify_core.TemporalDateTime sessionStart, + }) { + return CpkTemporalPrimaryKey._internal( + hwid: hwid, + sessionStart: sessionStart, + ); + } + + bool equals(Object other) { + return this == other; + } + + @override + bool operator ==(Object other) { + if (identical(other, this)) return true; + return other is CpkTemporalPrimaryKey && + _hwid == other._hwid && + _sessionStart == other._sessionStart; + } + + @override + int get hashCode => toString().hashCode; + + @override + String toString() { + var buffer = new StringBuffer(); + + buffer.write("CpkTemporalPrimaryKey {"); + buffer.write("hwid=" + "$_hwid" + ", "); + buffer.write( + "sessionStart=" + + (_sessionStart != null ? _sessionStart!.format() : "null") + + ", ", + ); + buffer.write( + "createdAt=" + + (_createdAt != null ? _createdAt!.format() : "null") + + ", ", + ); + buffer.write( + "updatedAt=" + (_updatedAt != null ? _updatedAt!.format() : "null"), + ); + buffer.write("}"); + + return buffer.toString(); + } + + CpkTemporalPrimaryKey copyWith() { + return CpkTemporalPrimaryKey._internal( + hwid: hwid, + sessionStart: sessionStart, + ); + } + + CpkTemporalPrimaryKey copyWithModelFieldValues() { + return CpkTemporalPrimaryKey._internal( + hwid: hwid, + sessionStart: sessionStart, + ); + } + + CpkTemporalPrimaryKey.fromJson(Map json) + : _hwid = json['hwid'], + _sessionStart = json['sessionStart'] != null + ? amplify_core.TemporalDateTime.fromString(json['sessionStart']) + : null, + _createdAt = json['createdAt'] != null + ? amplify_core.TemporalDateTime.fromString(json['createdAt']) + : null, + _updatedAt = json['updatedAt'] != null + ? amplify_core.TemporalDateTime.fromString(json['updatedAt']) + : null; + + Map toJson() => { + 'hwid': _hwid, + 'sessionStart': _sessionStart?.format(), + 'createdAt': _createdAt?.format(), + 'updatedAt': _updatedAt?.format(), + }; + + Map toMap() => { + 'hwid': _hwid, + 'sessionStart': _sessionStart, + 'createdAt': _createdAt, + 'updatedAt': _updatedAt, + }; + + static final amplify_core.QueryModelIdentifier< + CpkTemporalPrimaryKeyModelIdentifier + > + MODEL_IDENTIFIER = + amplify_core.QueryModelIdentifier(); + static final HWID = amplify_core.QueryField(fieldName: "hwid"); + static final SESSIONSTART = amplify_core.QueryField( + fieldName: "sessionStart", + ); + static var schema = amplify_core.Model.defineSchema( + define: (amplify_core.ModelSchemaDefinition modelSchemaDefinition) { + modelSchemaDefinition.name = "CpkTemporalPrimaryKey"; + modelSchemaDefinition.pluralName = "CpkTemporalPrimaryKeys"; + + modelSchemaDefinition.authRules = [ + amplify_core.AuthRule( + authStrategy: amplify_core.AuthStrategy.PRIVATE, + operations: const [ + amplify_core.ModelOperation.CREATE, + amplify_core.ModelOperation.UPDATE, + amplify_core.ModelOperation.DELETE, + amplify_core.ModelOperation.READ, + ], + ), + ]; + + modelSchemaDefinition.indexes = [ + amplify_core.ModelIndex( + fields: const ["hwid", "sessionStart"], + name: null, + ), + ]; + + modelSchemaDefinition.addField( + amplify_core.ModelFieldDefinition.field( + key: CpkTemporalPrimaryKey.HWID, + isRequired: true, + ofType: amplify_core.ModelFieldType( + amplify_core.ModelFieldTypeEnum.string, + ), + ), + ); + + modelSchemaDefinition.addField( + amplify_core.ModelFieldDefinition.field( + key: CpkTemporalPrimaryKey.SESSIONSTART, + isRequired: true, + ofType: amplify_core.ModelFieldType( + amplify_core.ModelFieldTypeEnum.dateTime, + ), + ), + ); + + modelSchemaDefinition.addField( + amplify_core.ModelFieldDefinition.nonQueryField( + fieldName: 'createdAt', + isRequired: false, + isReadOnly: true, + ofType: amplify_core.ModelFieldType( + amplify_core.ModelFieldTypeEnum.dateTime, + ), + ), + ); + + modelSchemaDefinition.addField( + amplify_core.ModelFieldDefinition.nonQueryField( + fieldName: 'updatedAt', + isRequired: false, + isReadOnly: true, + ofType: amplify_core.ModelFieldType( + amplify_core.ModelFieldTypeEnum.dateTime, + ), + ), + ); + }, + ); +} + +class _CpkTemporalPrimaryKeyModelType + extends amplify_core.ModelType { + const _CpkTemporalPrimaryKeyModelType(); + + @override + CpkTemporalPrimaryKey fromJson(Map jsonData) { + return CpkTemporalPrimaryKey.fromJson(jsonData); + } + + @override + String modelName() { + return 'CpkTemporalPrimaryKey'; + } +} + +/** + * This is an auto generated class representing the model identifier + * of [CpkTemporalPrimaryKey] in your schema. + */ +class CpkTemporalPrimaryKeyModelIdentifier + implements amplify_core.ModelIdentifier { + final String hwid; + final amplify_core.TemporalDateTime sessionStart; + + /** + * Create an instance of CpkTemporalPrimaryKeyModelIdentifier using [hwid] the primary key. + * And [sessionStart] the sort key. + */ + const CpkTemporalPrimaryKeyModelIdentifier({ + required this.hwid, + required this.sessionStart, + }); + + @override + Map serializeAsMap() => + ({'hwid': hwid, 'sessionStart': sessionStart}); + + @override + List> serializeAsList() => serializeAsMap().entries + .map((entry) => ({entry.key: entry.value})) + .toList(); + + @override + String serializeAsString() => serializeAsMap().values.join('#'); + + @override + String toString() => + 'CpkTemporalPrimaryKeyModelIdentifier(hwid: $hwid, sessionStart: $sessionStart)'; + + @override + bool operator ==(Object other) { + if (identical(this, other)) { + return true; + } + + return other is CpkTemporalPrimaryKeyModelIdentifier && + hwid == other.hwid && + sessionStart == other.sessionStart; + } + + @override + int get hashCode => hwid.hashCode ^ sessionStart.hashCode; +} diff --git a/packages/api/amplify_api_dart/test/test_models/ModelProvider.dart b/packages/api/amplify_api_dart/test/test_models/ModelProvider.dart index 7e5bca7bf57..446ee65bb20 100644 --- a/packages/api/amplify_api_dart/test/test_models/ModelProvider.dart +++ b/packages/api/amplify_api_dart/test/test_models/ModelProvider.dart @@ -27,6 +27,7 @@ import 'CpkIntPrimaryKey.dart'; import 'CpkOneToOneBidirectionalChildExplicitCD.dart'; import 'CpkOneToOneBidirectionalChildImplicitCD.dart'; import 'CpkOneToOneBidirectionalParentCD.dart'; +import 'CpkTemporalPrimaryKey.dart'; import 'CustomOwnerField.dart'; import 'ModelWithAppsyncScalarTypes.dart'; import 'ModelWithCustomType.dart'; @@ -43,6 +44,7 @@ export 'CpkIntPrimaryKey.dart'; export 'CpkOneToOneBidirectionalChildExplicitCD.dart'; export 'CpkOneToOneBidirectionalChildImplicitCD.dart'; export 'CpkOneToOneBidirectionalParentCD.dart'; +export 'CpkTemporalPrimaryKey.dart'; export 'CustomOwnerField.dart'; export 'CustomTypeWithAppsyncScalarTypes.dart'; export 'EnumField.dart'; @@ -65,6 +67,7 @@ class ModelProvider implements amplify_core.ModelProviderInterface { CpkOneToOneBidirectionalChildExplicitCD.schema, CpkOneToOneBidirectionalChildImplicitCD.schema, CpkOneToOneBidirectionalParentCD.schema, + CpkTemporalPrimaryKey.schema, CustomOwnerField.schema, ModelWithAppsyncScalarTypes.schema, ModelWithCustomType.schema, @@ -97,6 +100,8 @@ class ModelProvider implements amplify_core.ModelProviderInterface { return CpkOneToOneBidirectionalChildImplicitCD.classType; case "CpkOneToOneBidirectionalParentCD": return CpkOneToOneBidirectionalParentCD.classType; + case "CpkTemporalPrimaryKey": + return CpkTemporalPrimaryKey.classType; case "CustomOwnerField": return CustomOwnerField.classType; case "ModelWithAppsyncScalarTypes": diff --git a/packages/api/amplify_api_dart/test/test_models/schema.graphql b/packages/api/amplify_api_dart/test/test_models/schema.graphql index c7f0ed51844..4d8cc50c4b7 100644 --- a/packages/api/amplify_api_dart/test/test_models/schema.graphql +++ b/packages/api/amplify_api_dart/test/test_models/schema.graphql @@ -146,6 +146,11 @@ type CpkIntPrimaryKey @model @auth(rules: [{ allow: owner }]) { fieldB: Int! } +type CpkTemporalPrimaryKey @model @auth(rules: [{ allow: private }]) { + hwid: String! @primaryKey(sortKeyFields: ["sessionStart"]) + sessionStart: AWSDateTime! +} + type CustomOwnerField @model @auth(rules: [{ allow: private }, { allow: owner, ownerField: "owners" }]) { diff --git a/packages/auth/amplify_auth_cognito/example/integration_test/sign_in_test.dart b/packages/auth/amplify_auth_cognito/example/integration_test/sign_in_test.dart index 0ff3a176c22..f770045123f 100644 --- a/packages/auth/amplify_auth_cognito/example/integration_test/sign_in_test.dart +++ b/packages/auth/amplify_auth_cognito/example/integration_test/sign_in_test.dart @@ -97,60 +97,56 @@ void main() { expect(result.nextStep.additionalInfo, isEmpty); }); - asyncTest( - 'identity ID should be the same between sessions', - (_) async { - // Get unauthenticated identity - final unauthSession = - await Amplify.Auth.fetchAuthSession() as CognitoAuthSession; - - // Sign in - { - final signInRes = await Amplify.Auth.signIn( - username: username, - password: password, - ); - expect(signInRes.nextStep.signInStep, AuthSignInStep.done); - } - - // Get authenticated identity - final authSession = - await Amplify.Auth.fetchAuthSession() as CognitoAuthSession; - final authenticatedIdentity = authSession.identityIdResult; - expect( - authenticatedIdentity, - isNot(unauthSession.identityIdResult.value), - reason: - 'Unauthenticated identities should be distinct from authenticated ' - 'identities, since unauthenticated identities are vended to all ' - 'new devices when guest access is enabled but should converge to ' - 'a singular authenticated identity across all devices', - ); - expect( - authSession.credentialsResult.value, - isNot(unauthSession.credentialsResult.value), + asyncTest('identity ID should be the same between sessions', (_) async { + // Get unauthenticated identity + final unauthSession = + await Amplify.Auth.fetchAuthSession() as CognitoAuthSession; + + // Sign in + { + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, ); + expect(signInRes.nextStep.signInStep, AuthSignInStep.done); + } + + // Get authenticated identity + final authSession = + await Amplify.Auth.fetchAuthSession() as CognitoAuthSession; + final authenticatedIdentity = authSession.identityIdResult; + expect( + authenticatedIdentity, + isNot(unauthSession.identityIdResult.value), + reason: + 'Unauthenticated identities should be distinct from authenticated ' + 'identities, since unauthenticated identities are vended to all ' + 'new devices when guest access is enabled but should converge to ' + 'a singular authenticated identity across all devices', + ); + expect( + authSession.credentialsResult.value, + isNot(unauthSession.credentialsResult.value), + ); - await Amplify.Auth.signOut(); - { - final signInRes = await Amplify.Auth.signIn( - username: username, - password: password, - ); - expect(signInRes.nextStep.signInStep, AuthSignInStep.done); - } - - final newSession = - await Amplify.Auth.fetchAuthSession() as CognitoAuthSession; - expect( - newSession.identityIdResult.value, - authenticatedIdentity.value, - reason: - 'Authenticated identity should be the same between sessions', + await Amplify.Auth.signOut(); + { + final signInRes = await Amplify.Auth.signIn( + username: username, + password: password, ); - }, - skip: environment.name == 'user-pool-only', - ); + expect(signInRes.nextStep.signInStep, AuthSignInStep.done); + } + + final newSession = + await Amplify.Auth.fetchAuthSession() as CognitoAuthSession; + expect( + newSession.identityIdResult.value, + authenticatedIdentity.value, + reason: + 'Authenticated identity should be the same between sessions', + ); + }, skip: environment.name == 'user-pool-only'); }); } }); diff --git a/packages/authenticator/amplify_authenticator/example/test_driver/integration_test.dart b/packages/authenticator/amplify_authenticator/example/test_driver/integration_test.dart index f726c793c7e..dff7be31a48 100644 --- a/packages/authenticator/amplify_authenticator/example/test_driver/integration_test.dart +++ b/packages/authenticator/amplify_authenticator/example/test_driver/integration_test.dart @@ -5,4 +5,4 @@ import 'package:integration_test/integration_test_driver.dart'; // Required for running integration tests in the browser: // https://docs.flutter.dev/cookbook/testing/integration/introduction#5b-web -Future main() => integrationDriver(); +Future main() => integrationDriver(timeout: const Duration(minutes: 60));