Skip to content

Commit

Permalink
10007: Extract sign up to user gateway function
Browse files Browse the repository at this point in the history
  • Loading branch information
rachelschneiderman committed Mar 12, 2024
1 parent c895bc4 commit 19ef516
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 62 deletions.
61 changes: 23 additions & 38 deletions web-api/src/business/useCases/auth/signUpUserInteractor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import { signUpUserInteractor } from './signUpUserInteractor';
describe('signUpUserInteractor', () => {
const email = '[email protected]';
const name = 'Antoninus Sara';
const userId = 'c3f56e3d-0e6e-44bb-98f1-7c4a91dca1b9';
const mockUserId = 'c3f56e3d-0e6e-44bb-98f1-7c4a91dca1b9';
const password = 'Pa$$w0rd!';
const mockConfirmationCode = '09d0322d-12da-47c8-8d8b-cc76f97022c2';
const user = { confirmPassword: password, email, name, password };

beforeEach(() => {
applicationContext.getUniqueId.mockReturnValue(userId);

applicationContext.getCognito().signUp.mockResolvedValue({});
applicationContext
.getUserGateway()
.signUp.mockResolvedValue({ userId: mockUserId });

applicationContext
.getUseCaseHelpers()
Expand All @@ -32,34 +32,19 @@ describe('signUpUserInteractor', () => {
user,
});

expect(
applicationContext.getCognito().signUp.mock.calls[0][0],
).toMatchObject({
Password: password,
UserAttributes: [
{
Name: 'email',
Value: email,
},
{
Name: 'name',
Value: name,
},
{
Name: 'custom:userId',
Value: userId,
},
{
Name: 'custom:role',
Value: ROLES.petitioner,
},
],
Username: email,
});
expect(applicationContext.getUserGateway().signUp).toHaveBeenCalledWith(
applicationContext,
{
email,
name,
password,
role: ROLES.petitioner,
},
);
expect(result).toEqual({
confirmationCode: mockConfirmationCode,
email: user.email,
userId,
userId: mockUserId,
});
});

Expand All @@ -76,23 +61,25 @@ describe('signUpUserInteractor', () => {
expect(result).toEqual({
confirmationCode: undefined,
email: user.email,
userId,
userId: mockUserId,
});
});

it('should throw an error when an error occurs while trying to create a new user account', async () => {
applicationContext
.getCognito()
.listUsers.mockResolvedValue({ Users: undefined });
applicationContext.getCognito().signUp.mockRejectedValue(new Error('abc'));
applicationContext
.getUserGateway()
.signUp.mockRejectedValue(new Error('abc'));

await expect(
signUpUserInteractor(applicationContext, {
user,
}),
).rejects.toThrow();

expect(applicationContext.getCognito().signUp).toHaveBeenCalled();
expect(applicationContext.getUserGateway().signUp).toHaveBeenCalled();
});

it('should throw an error when the new user is not valid', async () => {
Expand All @@ -112,16 +99,14 @@ describe('signUpUserInteractor', () => {
).rejects.toThrow(
'The NewPetitionerUser entity was invalid. {"password":"Must contain number","confirmPassword":"Passwords must match"}',
);

expect(applicationContext.getCognito().signUp).not.toHaveBeenCalled();
});

it('should throw an error when the provided email already exists for an account in the system and it has been confirmed', async () => {
applicationContext.getCognito().listUsers.mockResolvedValue({
Users: [
{
UserStatus: UserStatusType.CONFIRMED,
userId,
userId: mockUserId,
},
],
});
Expand All @@ -132,15 +117,15 @@ describe('signUpUserInteractor', () => {
}),
).rejects.toThrow('User already exists');

expect(applicationContext.getCognito().signUp).not.toHaveBeenCalled();
expect(applicationContext.getUserGateway().signUp).not.toHaveBeenCalled();
});

it('should throw an error when the provided email already exists for an account in the system and the account has not yet been confirmed', async () => {
applicationContext.getCognito().listUsers.mockResolvedValue({
Users: [
{
UserStatus: UserStatusType.UNCONFIRMED,
userId,
userId: mockUserId,
},
],
});
Expand All @@ -151,6 +136,6 @@ describe('signUpUserInteractor', () => {
}),
).rejects.toThrow('User exists, email unconfirmed');

expect(applicationContext.getCognito().signUp).not.toHaveBeenCalled();
expect(applicationContext.getUserGateway().signUp).not.toHaveBeenCalled();
});
});
33 changes: 9 additions & 24 deletions web-api/src/business/useCases/auth/signUpUserInteractor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,15 @@ export const signUpUserInteractor = async (
}

const newUser = new NewPetitionerUser(user).validate().toRawObject();
const userId = applicationContext.getUniqueId();
await applicationContext.getCognito().signUp({
ClientId: applicationContext.environment.cognitoClientId,
Password: newUser.password,
UserAttributes: [
{
Name: 'email',
Value: newUser.email,
},
{
Name: 'name',
Value: newUser.name,
},
{
Name: 'custom:userId',
Value: userId,
},
{
Name: 'custom:role',
Value: ROLES.petitioner,
},
],
Username: newUser.email,
});

const { userId } = await applicationContext
.getUserGateway()
.signUp(applicationContext, {
email: newUser.email,
name: newUser.name,
password: newUser.password,
role: ROLES.petitioner,
});

const { confirmationCode } = await applicationContext
.getUseCaseHelpers()
Expand Down
47 changes: 47 additions & 0 deletions web-api/src/gateways/user/signUp.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { ROLES } from '@shared/business/entities/EntityConstants';
import { applicationContext } from '../../../../shared/src/business/test/createTestApplicationContext';
import { signUp } from '@web-api/gateways/user/signUp';

describe('signUp', () => {
it('should make a call to disable the user with the provided email', async () => {
const mockEmail = '[email protected]';
const mockName = 'Test Petitioner';
const mockPassword = 'P@ssword!';
const mockRole = ROLES.petitioner;
const mockUserId = '2a1aa887-6350-48dc-bb3b-9fe699eae776';
const mockCognitoClientId = 'test';
applicationContext.environment.cognitoClientId = mockCognitoClientId;
applicationContext.getUniqueId.mockReturnValue(mockUserId);

await signUp(applicationContext, {
email: mockEmail,
name: mockName,
password: mockPassword,
role: mockRole,
});

expect(applicationContext.getCognito().signUp).toHaveBeenCalledWith({
ClientId: mockCognitoClientId,
Password: mockPassword,
UserAttributes: [
{
Name: 'email',
Value: mockEmail,
},
{
Name: 'name',
Value: mockName,
},
{
Name: 'custom:userId',
Value: mockUserId,
},
{
Name: 'custom:role',
Value: mockRole,
},
],
Username: mockEmail,
});
});
});
45 changes: 45 additions & 0 deletions web-api/src/gateways/user/signUp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Role } from '@shared/business/entities/EntityConstants';
import { ServerApplicationContext } from '@web-api/applicationContext';

export async function signUp(
applicationContext: ServerApplicationContext,
{
email,
name,
password,
role,
}: {
password: string;
email: string;
name: string;
role: Role;
},
): Promise<{ userId: string }> {
const userId = applicationContext.getUniqueId();

await applicationContext.getCognito().signUp({
ClientId: applicationContext.environment.cognitoClientId,
Password: password,
UserAttributes: [
{
Name: 'email',
Value: email,
},
{
Name: 'name',
Value: name,
},
{
Name: 'custom:userId',
Value: userId,
},
{
Name: 'custom:role',
Value: role,
},
],
Username: email,
});

return { userId };
}
2 changes: 2 additions & 0 deletions web-api/src/getUserGateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { forgotPassword } from '@web-api/gateways/user/forgotPassword';
import { getUserByEmail } from '@web-api/gateways/user/getUserByEmail';
import { initiateAuth } from '@web-api/gateways/user/initiateAuth';
import { renewIdToken } from '@web-api/gateways/user/renewIdToken';
import { signUp } from '@web-api/gateways/user/signUp';
import { updateUser } from '@web-api/gateways/user/updateUser';

export const getUserGateway = () => ({
Expand All @@ -17,5 +18,6 @@ export const getUserGateway = () => ({
getUserByEmail,
initiateAuth,
renewIdToken,
signUp,
updateUser,
});

0 comments on commit 19ef516

Please sign in to comment.