Skip to content

Commit e355d02

Browse files
committed
chore: add invalid mfa code tests to authenticator
1 parent d5ec3c3 commit e355d02

File tree

3 files changed

+122
-46
lines changed

3 files changed

+122
-46
lines changed

packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_email_test.dart

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ void main() {
1515

1616
group('sign-in-email-mfa', () {
1717
testRunner.withEnvironment(mfaRequiredEmail, (env) {
18-
// Scenario: Sign in using a totp code
19-
testWidgets('Setup & Sign in with EMAIL MFA', (tester) async {
18+
// Scenario: Sign in using a valid email MFA code
19+
testWidgets('Sign in with valid EMAIL MFA code', (tester) async {
2020
final username = env.generateUsername();
2121
final password = generatePassword();
2222

@@ -57,7 +57,7 @@ void main() {
5757
// And I click the "Sign in" button
5858
await signInPage.submitSignIn();
5959

60-
// Then I will be redirected to the totp setup page
60+
// Then I will be redirected to the email MFA code page
6161
await confirmSignInPage.expectConfirmSignInWithEmailMfaCodeIsPresent();
6262

6363
final otpResult = await getOtpCode(
@@ -106,6 +106,59 @@ void main() {
106106

107107
await tester.bloc.close();
108108
});
109+
110+
// Scenario: Sign in using an invalid email MFA code
111+
testWidgets('Sign in with invalid EMAIL MFA code', (tester) async {
112+
final username = env.generateUsername();
113+
final password = generatePassword();
114+
115+
await adminCreateUser(
116+
username,
117+
password,
118+
autoConfirm: true,
119+
attributes: {
120+
AuthUserAttributeKey.email: username,
121+
},
122+
autoFillAttributes: false,
123+
);
124+
125+
await loadAuthenticator(tester: tester);
126+
127+
expect(
128+
tester.bloc.stream,
129+
emitsInOrder([
130+
UnauthenticatedState.signIn,
131+
UnauthenticatedState.confirmSignInWithEmailMfaCode,
132+
emitsDone,
133+
]),
134+
);
135+
136+
final signInPage = SignInPage(tester: tester);
137+
final confirmSignInPage = ConfirmSignInPage(tester: tester);
138+
139+
// When I type my "username"
140+
await signInPage.enterUsername(username);
141+
142+
// And I type my password
143+
await signInPage.enterPassword(password);
144+
145+
// And I click the "Sign in" button
146+
await signInPage.submitSignIn();
147+
148+
// Then I will be redirected to the EMAIL OTP code page
149+
await confirmSignInPage.expectConfirmSignInWithEmailMfaCodeIsPresent();
150+
151+
// And I type an invalid confirmation code
152+
await confirmSignInPage.enterVerificationCode('123456');
153+
154+
// And I click the "Confirm" button
155+
await confirmSignInPage.submitConfirmSignIn();
156+
157+
// Then I see "The code entered is not correct."
158+
confirmSignInPage.expectInvalidVerificationCode();
159+
160+
await tester.bloc.close();
161+
});
109162
});
110163
});
111164
}

packages/authenticator/amplify_authenticator/example/integration_test/sign_in_mfa_username_login_test.dart

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,6 @@ void main() {
3939
UnauthenticatedState.continueSignInWithEmailMfaSetup,
4040
UnauthenticatedState.confirmSignInWithEmailMfaCode,
4141
isA<AuthenticatedState>(),
42-
UnauthenticatedState.signIn,
43-
isA<ContinueSignInWithMfaSelection>(),
44-
UnauthenticatedState.confirmSignInWithTotpMfaCode,
45-
isA<AuthenticatedState>(),
4642
emitsDone,
4743
]),
4844
);
@@ -62,7 +58,7 @@ void main() {
6258
// And I click the "Sign in" button
6359
await signInPage.submitSignIn();
6460

65-
// Then I will be redirected to the confirm email mfa page
61+
// Then I will be redirected to the MFA setup selection page
6662
await confirmSignInPage
6763
.expectContinueSignInWithMfaSetupSelectionIsPresent();
6864

@@ -72,7 +68,7 @@ void main() {
7268
// And I click the "Confirm" button
7369
await confirmSignInPage.submitConfirmSignInMfaSetupSelection();
7470

75-
// Then I will be redirected to the EMAIL mfa setup page
71+
// Then I will be redirected to the EMAIL MFA setup page
7672
await emailMfaSetupPage.expectEmailMfaSetupIsPresent();
7773

7874
// When I type a valid email
@@ -90,15 +86,44 @@ void main() {
9086
// Then I see the authenticated app
9187
await signInPage.expectAuthenticated();
9288

93-
// When I enable TOTP for MFA instead of the default set up by cognito (EMAIL)
94-
await setUpTotp();
89+
await tester.bloc.close();
90+
});
9591

96-
// And I sign out using Auth.signOut()
97-
await Amplify.Auth.signOut();
98-
await tester.pumpAndSettle();
92+
// Scenario: Select TOTP MFA to set up from the setup selection page
93+
testWidgets('can select TOTP MFA to set up', (tester) async {
94+
final username = env.generateUsername();
95+
final password = generatePassword();
96+
late String sharedSecret;
97+
98+
await adminCreateUser(
99+
username,
100+
password,
101+
autoConfirm: true,
102+
verifyAttributes: false,
103+
autoFillAttributes: false,
104+
);
105+
106+
await loadAuthenticator(tester: tester);
107+
108+
tester.bloc.stream.listen((event) {
109+
if (event is ContinueSignInTotpSetup) {
110+
sharedSecret = event.totpSetupDetails.sharedSecret;
111+
}
112+
});
113+
114+
expect(
115+
tester.bloc.stream,
116+
emitsInOrder([
117+
UnauthenticatedState.signIn,
118+
isA<ContinueSignInWithMfaSetupSelection>(),
119+
isA<ContinueSignInTotpSetup>(),
120+
isA<AuthenticatedState>(),
121+
emitsDone,
122+
]),
123+
);
99124

100-
// Then I see the sign in page
101-
signInPage.expectUsername();
125+
final signInPage = SignInPage(tester: tester);
126+
final confirmSignInPage = ConfirmSignInPage(tester: tester);
102127

103128
// When I type my "username"
104129
await signInPage.enterUsername(username);
@@ -109,22 +134,23 @@ void main() {
109134
// And I click the "Sign in" button
110135
await signInPage.submitSignIn();
111136

112-
// Then I will be redirected to the MFA selection page
113-
await confirmSignInPage.expectConfirmSignInMfaSelectionIsPresent();
137+
// Then I will be redirected to the MFA setup selection page
138+
await confirmSignInPage
139+
.expectContinueSignInWithMfaSetupSelectionIsPresent();
114140

115141
// When I select "TOTP"
116-
await confirmSignInPage.selectMfaMethod(mfaMethod: MfaType.totp);
142+
await confirmSignInPage.selectMfaSetupMethod(mfaMethod: MfaType.totp);
117143

118144
// And I click the "Confirm" button
119-
await confirmSignInPage.submitConfirmSignInMfaSelection();
145+
await confirmSignInPage.submitConfirmSignInMfaSetupSelection();
120146

121-
// Then I will be redirected to the TOTP MFA code page
122-
await confirmSignInPage.expectConfirmSignInWithTotpMfaCodeIsPresent();
147+
// Then I will be redirected to the TOTP MFA setup page
148+
await confirmSignInPage.expectSignInTotpSetupIsPresent();
123149

124-
final code_2 = await generateTotpCode();
150+
final totpCode = await generateTotpCode(sharedSecret);
125151

126152
// When I type a valid TOTP code
127-
await confirmSignInPage.enterVerificationCode(code_2);
153+
await confirmSignInPage.enterVerificationCode(totpCode);
128154

129155
// And I click the "Confirm" button
130156
await confirmSignInPage.submitConfirmSignIn();
@@ -135,8 +161,8 @@ void main() {
135161
await tester.bloc.close();
136162
});
137163

138-
// Scenario: Sign in using a EMAIL code when both EMAIL and TOTP are enabled
139-
testWidgets('can select TOTP MFA to set up', (tester) async {
164+
// Scenario: Sign in using an invalid TOTP code
165+
testWidgets('sign in with invalid TOTP code', (tester) async {
140166
final username = env.generateUsername();
141167
final password = generatePassword();
142168
late String sharedSecret;
@@ -166,7 +192,6 @@ void main() {
166192
isA<AuthenticatedState>(),
167193
UnauthenticatedState.signIn,
168194
UnauthenticatedState.confirmSignInWithTotpMfaCode,
169-
isA<AuthenticatedState>(),
170195
emitsDone,
171196
]),
172197
);
@@ -183,7 +208,7 @@ void main() {
183208
// And I click the "Sign in" button
184209
await signInPage.submitSignIn();
185210

186-
// Then I will be redirected to the confirm email mfa page
211+
// Then I will be redirected to the MFA setup selection page
187212
await confirmSignInPage
188213
.expectContinueSignInWithMfaSetupSelectionIsPresent();
189214

@@ -193,12 +218,12 @@ void main() {
193218
// And I click the "Confirm" button
194219
await confirmSignInPage.submitConfirmSignInMfaSetupSelection();
195220

196-
// Then I will be redirected to the TOTP mfa setup page
221+
// Then I will be redirected to the TOTP MFA setup page
197222
await confirmSignInPage.expectSignInTotpSetupIsPresent();
198223

199224
final totpCode = await generateTotpCode(sharedSecret);
200225

201-
// And I type a valid TOTP code
226+
// When I type a valid TOTP code
202227
await confirmSignInPage.enterVerificationCode(totpCode);
203228

204229
// And I click the "Confirm" button
@@ -207,35 +232,27 @@ void main() {
207232
// Then I see the authenticated app
208233
await signInPage.expectAuthenticated();
209234

210-
// And I sign out using Auth.signOut()
235+
// Sign out to test invalid TOTP code during sign-in
211236
await Amplify.Auth.signOut();
212237
await tester.pumpAndSettle();
213238

214-
// Then I see the sign in page
215-
signInPage.expectUsername();
216-
217-
// When I type my "username"
239+
// When I attempt to sign in again
218240
await signInPage.enterUsername(username);
219-
220-
// And I type my password
221241
await signInPage.enterPassword(password);
222-
223-
// And I click the "Sign in" button
224242
await signInPage.submitSignIn();
225243

226244
// Then I will be redirected to the TOTP MFA code page
227-
await confirmSignInPage.expectConfirmSignInWithTotpMfaCodeIsPresent();
245+
await confirmSignInPage
246+
.expectConfirmSignInWithTotpMfaCodeIsPresent();
228247

229-
final code_2 = await generateTotpCode(sharedSecret);
230-
231-
// When I type a valid TOTP code
232-
await confirmSignInPage.enterVerificationCode(code_2);
248+
// When I type an invalid TOTP code
249+
await confirmSignInPage.enterVerificationCode('000000');
233250

234251
// And I click the "Confirm" button
235252
await confirmSignInPage.submitConfirmSignIn();
236253

237-
// Then I see the authenticated app
238-
await signInPage.expectAuthenticated();
254+
// Then I see "Invalid code" error message
255+
confirmSignInPage.expectInvalidVerificationCode();
239256

240257
await tester.bloc.close();
241258
});

packages/authenticator/amplify_authenticator_test/lib/src/pages/confirm_sign_in_page.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ class ConfirmSignInPage extends AuthenticatorPage {
112112
expect(newPasswordField, findsOneWidget);
113113
}
114114

115+
/// Then I see "Invalid verification code"
116+
@override
117+
void expectInvalidVerificationCode() {
118+
expectError('Invalid code');
119+
}
120+
115121
/// When I enter a verification code
116122
Future<void> enterVerificationCode(String code) async {
117123
await tester.ensureVisible(verificationField);

0 commit comments

Comments
 (0)