Skip to content

Commit

Permalink
test: confirm sign in tests (#1176)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jordan-Nelson authored Dec 3, 2021
1 parent 254eb16 commit 8f9e15a
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import 'envs/auth_with_username.dart' as auth_with_username;
/// All envs modeled on:
/// https://github.com/aws-amplify/amplify-ui/blob/main/examples/angular/src/pages/ui/components/authenticator/
const environmentsByConfiguration = {
'ui/components/authenticator/confirm-sign-up': 'auth-with-email',
'ui/components/authenticator/sign-up-with-email': 'auth-with-email',
'ui/components/authenticator/sign-up-with-phone': 'auth-with-phone',
'ui/components/authenticator/sign-up-with-username': 'auth-with-username',
Expand All @@ -35,6 +36,7 @@ const environmentsByConfiguration = {
'ui/components/authenticator/sign-in-with-email-lambda':
'auth-with-email-lambda-signup-trigger',
'ui/components/authenticator/reset-password': 'auth-with-username',
'ui/components/authenticator/verify-user': 'auth-with-email',
};

const environments = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*
* 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.
*/

import 'package:amplify_api/amplify_api.dart';
import 'package:amplify_authenticator/amplify_authenticator.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

import 'config.dart';
import 'pages/confirm_sign_up_page.dart';
import 'pages/sign_in_page.dart';
import 'pages/sign_up_page.dart';
import 'pages/test_utils.dart';
import 'utils/data_utils.dart';
import 'utils/mock_data.dart';

// This test follows the Amplify UI feature "confirm-sign-up"
// https://github.com/aws-amplify/amplify-ui/blob/main/packages/e2e/features/ui/components/authenticator/confirm-sign-up.feature

void main() {
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized()
as IntegrationTestWidgetsFlutterBinding;
// resolves issue on iOS. See: https://github.com/flutter/flutter/issues/89651
binding.deferFirstFrame();

final authenticator = MaterialApp(
home: Authenticator(
child: const Scaffold(
body: Center(
child: SignOutButton(),
),
),
),
);

group('confirm-sign-up', () {
// Given I'm running the example "ui/components/authenticator/confirm-sign-up"
setUpAll(() async {
await loadConfiguration(
'ui/components/authenticator/confirm-sign-up',
additionalConfigs: [AmplifyAPI()],
);
});

// Scenario: Confirm a new username & password with an invalid code
testWidgets(
'Confirm a new username & password with an invalid code',
(tester) async {
SignUpPage signUpPage = SignUpPage(tester: tester);
ConfirmSignUpPage confirmSignUpPage = ConfirmSignUpPage(tester: tester);
SignInPage signInPage = SignInPage(tester: tester);

await loadAuthenticator(tester: tester, authenticator: authenticator);

var username = generateEmail();
var password = generatePassword();

await signInPage.navigateToSignUp();

// When I type a new "email"
await signUpPage.enterUsername(username);

// And I type my password
await signUpPage.enterPassword(password);

// And I confirm my password
await signUpPage.enterPasswordConfirmation(password);

// And I click the "Create Account" button
await signUpPage.submitSignUp();

// And I see "Confirmation Code"
confirmSignUpPage.expectConfirmationCodeIsPresent();

// And I type an invalid confirmation code
await confirmSignUpPage.enterCode('123456');

// And I click the "Confirm" button
await confirmSignUpPage.submitConfirmSignUp();

// Then I see "Username/client id combination not found."
confirmSignUpPage.expectInvalidVerificationCode();
},
);

// Scenario: Confirm a new username & password with a valid code
testWidgets(
'Confirm a new username & password with a valid code',
(tester) async {
SignUpPage signUpPage = SignUpPage(tester: tester);
ConfirmSignUpPage confirmSignUpPage = ConfirmSignUpPage(tester: tester);
SignInPage signInPage = SignInPage(tester: tester);

await loadAuthenticator(tester: tester, authenticator: authenticator);

var username = generateEmail();
var password = generatePassword();

await signInPage.navigateToSignUp();

// When I type a new "email"
await signUpPage.enterUsername(username);

// And I type my password
await signUpPage.enterPassword(password);

// And I confirm my password
await signUpPage.enterPasswordConfirmation(password);

await subscribeToOTPCode(
onSubscriptionEstablished: () async {
// And I click the "Create Account" button
await signUpPage.submitSignUp();

// And I see "Confirmation Code"
confirmSignUpPage.expectConfirmationCodeIsPresent();
},
onCodeRecieved: (String code) async {
// And I type a valid confirmation code
await confirmSignUpPage.enterCode(code);

// And I click the "Confirm" button
await confirmSignUpPage.submitConfirmSignUp();

// Then I see "Sign out"
signInPage.expectAuthenticated();
},
);
},
);

// Scenario: User is already confirmed and then clicks Resend Code
testWidgets(
'User is already confirmed and then clicks Resend Code',
(tester) async {
// TODO: clarify requirements
},
skip: true,
);

// Scenario: Supports "One-Time Code"
testWidgets(
'Supports "One-Time Code"',
(tester) async {
// TODO: clarify requirements
},
skip: true,
);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
* permissions and limitations under the License.
*/

import 'dart:io';

import 'package:amplify_authenticator/amplify_authenticator.dart';
import 'package:amplify_authenticator/src/keys.dart';
import 'package:amplify_authenticator/src/screens/authenticator_screen.dart';
Expand Down Expand Up @@ -105,6 +107,17 @@ abstract class AuthenticatorPage {
expect(expectCombinationNotFound, findsOneWidget);
}

/// Then I see Invalid verification code
Future<void> expectInvalidVerificationCode() async {
if (Platform.isAndroid) {
expectError('Confirmation code entered is not correct.');
} else if (Platform.isIOS) {
expectError('Invalid verification code provided, please try again.');
} else {
throw Exception('Unsupprted platform');
}
}

Future<void> selectCountryCode() async {
expect(countrySelectField, findsOneWidget);
await tester.tap(countrySelectField);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
* permissions and limitations under the License.
*/

import 'dart:async';
import 'dart:convert';

import 'package:amplify_api/amplify_api.dart';
import 'package:amplify_flutter/amplify.dart';
import 'package:flutter_test/flutter_test.dart';

import 'types/admin_create_user_response.dart';
import 'types/confirmation_code_response.dart';
import 'types/delete_user_response.dart';

const deleteDocument = '''mutation DeleteUser(\$Username: String!) {
Expand Down Expand Up @@ -98,3 +102,62 @@ Future<AdminCreateUserResponse?> adminCreateUser(
}
});
}

Future<ConfirmationCodeTestRun> subscribeToOTPCode({
Future<void> Function()? onSubscriptionEstablished,
Future<void> Function(String code)? onCodeRecieved,
}) async {
Completer<ConfirmationCodeTestRun> codeCompleter =
Completer<ConfirmationCodeTestRun>();
String subscriptionDocument = '''subscription MyMutation {
onCreateConfirmSignUpTestRun {
id
}
}''';

String queryDocument = '''query GetCode(\$id: ID!) {
getConfirmSignUpTestRun(id: \$id) {
id
currentCode
}
}''';

Completer<void> subscriptionCompleter = Completer<void>();

final Stream<GraphQLResponse<String>> operation = Amplify.API.subscribe(
GraphQLRequest<String>(document: subscriptionDocument),
onEstablished: () {
subscriptionCompleter.complete();
},
);

// TODO: subscriptionCompleter is not working correctly. Future.delayed is a temp solution
// await subscriptionCompleter.future;
await Future.delayed(const Duration(seconds: 1), () {});

operation.listen((event) async {
Map<dynamic, dynamic> parsedMap = jsonDecode(event.data);
String codeId = parsedMap['onCreateConfirmSignUpTestRun']['id'];
var codeQuery = Amplify.API.query(
request: GraphQLRequest<String>(
document: queryDocument,
variables: <String, String>{'id': codeId},
));

var response = await codeQuery.response;

ConfirmationCodeTestRun result =
ConfirmationCodeTestRun.fromJson(response.data);

if (onCodeRecieved != null) {
await onCodeRecieved(result.code!);
}

codeCompleter.complete(result);
});

if (onSubscriptionEstablished != null) {
await onSubscriptionEstablished();
}
return codeCompleter.future;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* permissions and limitations under the License.
*/

// This test follows the Amplify UI feature "sign-in-with-username"
// This test follows the Amplify UI feature "verify-user"
// https://github.com/aws-amplify/amplify-ui/blob/main/packages/e2e/features/ui/components/authenticator/verify-user.feature

import 'package:amplify_api/amplify_api.dart';
Expand Down Expand Up @@ -45,14 +45,18 @@ void main() {
);

group('verify-user', () {
// Given I'm running the example "ui/components/authenticator/sign-up-with-email"
// Given I'm running the example "ui/components/authenticator/verify-user"
setUpAll(() async {
await loadConfiguration(
'ui/components/authenticator/sign-up-with-email',
'ui/components/authenticator/verify-user',
additionalConfigs: [AmplifyAPI()],
);
});

tearDown(() async {
await Amplify.Auth.signOut();
});

// Scenario: Redirect to "Verify" page
testWidgets('Redirect to "Verify" page', (tester) async {
SignInPage signInPage = SignInPage(tester: tester);
Expand Down

0 comments on commit 8f9e15a

Please sign in to comment.