Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add missing auto sign-in unit tests #12484

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 158 additions & 12 deletions packages/auth/__tests__/providers/cognito/autoSignIn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@

import {
CognitoUserPoolsTokenProvider,
confirmSignUp,
signUp,
} from '../../../src/providers/cognito';
import { autoSignIn } from '../../../src/providers/cognito/apis/autoSignIn';
import * as signUpClient from '../../../src/providers/cognito/utils/clients/CognitoIdentityProvider';
import {
autoSignIn,
resetAutoSignIn,
} from '../../../src/providers/cognito/apis/autoSignIn';
import * as clients from '../../../src/providers/cognito/utils/clients/CognitoIdentityProvider';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nit: this is importing a single (CognitoIdentityProvider) client, so the plural name could be misleading.

import { authAPITestParams } from './testUtils/authApiTestParams';
import { RespondToAuthChallengeCommandOutput } from '../../../src/providers/cognito/utils/clients/CognitoIdentityProvider/types';
import { Amplify } from 'aws-amplify';
import * as initiateAuthHelpers from '../../../src/providers/cognito/utils/signInHelpers';
import { AuthError } from '../../../src/errors/AuthError';
import { ConfirmSignUpException } from '../../../src/providers/cognito/types/errors';
jest.mock('@aws-amplify/core/lib/clients/handlers/fetch');

const authConfig = {
Expand All @@ -25,18 +30,9 @@ Amplify.configure({
Auth: authConfig,
});
describe('Auto sign-in API Happy Path Cases:', () => {
let signUpSpy;
let handleUserSRPAuthflowSpy;
const { user1 } = authAPITestParams;
beforeEach(async () => {
signUpSpy = jest
.spyOn(signUpClient, 'signUp')
.mockImplementationOnce(async () => {
return {
UserConfirmed: true,
};
});

handleUserSRPAuthflowSpy = jest
.spyOn(initiateAuthHelpers, 'handleUserSRPAuthFlow')
.mockImplementationOnce(
Expand All @@ -45,10 +41,16 @@ describe('Auto sign-in API Happy Path Cases:', () => {
);
});
afterEach(() => {
signUpSpy.mockClear();
handleUserSRPAuthflowSpy.mockClear();
});
test('signUp should enable autoSignIn and return COMPLETE_AUTO_SIGN_IN step', async () => {
const signUpSpy = jest
.spyOn(clients, 'signUp')
.mockImplementationOnce(async () => {
return {
UserConfirmed: true,
};
});
const resp = await signUp({
username: user1.username,
password: user1.password,
Expand All @@ -64,13 +66,157 @@ describe('Auto sign-in API Happy Path Cases:', () => {
},
});
expect(signUpSpy).toBeCalledTimes(1);
signUpSpy.mockClear();
});

test('Auto sign-in should resolve to a signIn output', async () => {
const signInOutput = await autoSignIn();
expect(signInOutput).toEqual(authAPITestParams.signInResult());
expect(handleUserSRPAuthflowSpy).toBeCalledTimes(1);
});

test('Auto sign-in should not resolve if a different user is confirmed', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if this is what is being tested here. It looks like we never test auto sign-in after the first user is confirmed.

const user1 = 'user-1';
const user2 = 'user-2';
const signUpSpy = jest.spyOn(clients, 'signUp').mockReturnValue({
UserConfirmed: false,
UserSub: '1234567890',
CodeDeliveryDetails: {
AttributeName: 'email',
DeliveryMedium: 'EMAIL',
Destination: '[email protected]',
},
});
const confirmSignUpSpy = jest
.spyOn(clients, 'confirmSignUp')
.mockReturnValueOnce({});

// creates user 1
const createUser1 = await signUp({
username: user1,
password: '********',
options: {
userAttributes: { email: '[email protected]' },
autoSignIn: true,
},
});

// creates user 2
const createUser2 = await signUp({
username: user2,
password: '********',
options: {
userAttributes: { email: '[email protected]' },
autoSignIn: true,
},
});

// confirms user 1
const outputFromUser1 = await confirmSignUp({
username: user1,
confirmationCode: '123456',
});

expect(outputFromUser1.nextStep.signUpStep).toEqual('DONE');

signUpSpy.mockClear();
confirmSignUpSpy.mockClear();
});

test('Auto sign-in should not be interrupted if confirmSignUp fails', async () => {
const validCode = '123456';
const invalidCode = '654321';
const username = 'username';
const signUpSpy = jest.spyOn(clients, 'signUp').mockReturnValueOnce({
UserConfirmed: false,
UserSub: '1234567890',
CodeDeliveryDetails: {
AttributeName: 'email',
DeliveryMedium: 'EMAIL',
Destination: '[email protected]',
},
});
const confirmSignUpSpy = jest
.spyOn(clients, 'confirmSignUp')
.mockRejectedValueOnce(
new AuthError({
name: ConfirmSignUpException.CodeMismatchException,
message: 'confirmSignUp failed',
})
)
.mockResolvedValueOnce({});

await signUp({
username,
password: '********',
options: {
userAttributes: { email: '[email protected]' },
autoSignIn: true,
},
});

try {
// first call to confirmSignUp should fail
await confirmSignUp({ username, confirmationCode: invalidCode });
} catch (error) {
if (
error instanceof AuthError &&
error.name === ConfirmSignUpException.CodeMismatchException
) {
// second call to confirmSignUp should succeed
const output = await confirmSignUp({
username,
confirmationCode: validCode,
});
expect(output.nextStep.signUpStep).toEqual('COMPLETE_AUTO_SIGN_IN');
resetAutoSignIn();
}
}

confirmSignUpSpy.mockClear();
signUpSpy.mockClear();
});

test('sign up should return "COMPLETE_AUTO_SIGN_IN" step when autoSignIn is enabled with verification link ', async () => {
Amplify.configure({
Auth: {
Cognito: {
userPoolClientId: '111111-aaaaa-42d8-891d-ee81a1549398',
userPoolId: 'us-west-2_zzzzz',
signUpVerificationMethod: 'link',
},
},
});

const signUpSpy = jest.spyOn(clients, 'signUp').mockReturnValueOnce({
UserConfirmed: false,
UserSub: '1234567890',
CodeDeliveryDetails: {
AttributeName: 'email',
DeliveryMedium: 'EMAIL',
Destination: '[email protected]',
},
});

const output = await signUp({
username: 'username-1',
password: '******',
options: {
userAttributes: { email: 'XXXXXXXXXXXXXXX' },
autoSignIn: true,
},
});
const step = output.nextStep.signUpStep;
expect(step).toEqual('COMPLETE_AUTO_SIGN_IN');
if (step === 'COMPLETE_AUTO_SIGN_IN') {
expect(output.nextStep.codeDeliveryDetails?.deliveryMedium).toEqual(
'EMAIL'
);
}

resetAutoSignIn();
signUpSpy.mockClear();
});
});

describe('Auto sign-in API Error Path Cases:', () => {
Expand Down
Loading