From 19ef516a2d3bbaf30be26b9543e73e0e02ac0f0b Mon Sep 17 00:00:00 2001 From: Rachel Schneiderman Date: Tue, 12 Mar 2024 08:19:00 -0700 Subject: [PATCH] 10007: Extract sign up to user gateway function --- .../auth/signUpUserInteractor.test.ts | 61 +++++++------------ .../useCases/auth/signUpUserInteractor.ts | 33 +++------- web-api/src/gateways/user/signUp.test.ts | 47 ++++++++++++++ web-api/src/gateways/user/signUp.ts | 45 ++++++++++++++ web-api/src/getUserGateway.ts | 2 + 5 files changed, 126 insertions(+), 62 deletions(-) create mode 100644 web-api/src/gateways/user/signUp.test.ts create mode 100644 web-api/src/gateways/user/signUp.ts diff --git a/web-api/src/business/useCases/auth/signUpUserInteractor.test.ts b/web-api/src/business/useCases/auth/signUpUserInteractor.test.ts index 106e450abea..3cf9c13b01f 100644 --- a/web-api/src/business/useCases/auth/signUpUserInteractor.test.ts +++ b/web-api/src/business/useCases/auth/signUpUserInteractor.test.ts @@ -6,15 +6,15 @@ import { signUpUserInteractor } from './signUpUserInteractor'; describe('signUpUserInteractor', () => { const email = 'example@example.com'; 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() @@ -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, }); }); @@ -76,7 +61,7 @@ describe('signUpUserInteractor', () => { expect(result).toEqual({ confirmationCode: undefined, email: user.email, - userId, + userId: mockUserId, }); }); @@ -84,7 +69,9 @@ describe('signUpUserInteractor', () => { applicationContext .getCognito() .listUsers.mockResolvedValue({ Users: undefined }); - applicationContext.getCognito().signUp.mockRejectedValue(new Error('abc')); + applicationContext + .getUserGateway() + .signUp.mockRejectedValue(new Error('abc')); await expect( signUpUserInteractor(applicationContext, { @@ -92,7 +79,7 @@ describe('signUpUserInteractor', () => { }), ).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 () => { @@ -112,8 +99,6 @@ 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 () => { @@ -121,7 +106,7 @@ describe('signUpUserInteractor', () => { Users: [ { UserStatus: UserStatusType.CONFIRMED, - userId, + userId: mockUserId, }, ], }); @@ -132,7 +117,7 @@ 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 () => { @@ -140,7 +125,7 @@ describe('signUpUserInteractor', () => { Users: [ { UserStatus: UserStatusType.UNCONFIRMED, - userId, + userId: mockUserId, }, ], }); @@ -151,6 +136,6 @@ describe('signUpUserInteractor', () => { }), ).rejects.toThrow('User exists, email unconfirmed'); - expect(applicationContext.getCognito().signUp).not.toHaveBeenCalled(); + expect(applicationContext.getUserGateway().signUp).not.toHaveBeenCalled(); }); }); diff --git a/web-api/src/business/useCases/auth/signUpUserInteractor.ts b/web-api/src/business/useCases/auth/signUpUserInteractor.ts index c7e15ae26bb..a29459fd9c9 100644 --- a/web-api/src/business/useCases/auth/signUpUserInteractor.ts +++ b/web-api/src/business/useCases/auth/signUpUserInteractor.ts @@ -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() diff --git a/web-api/src/gateways/user/signUp.test.ts b/web-api/src/gateways/user/signUp.test.ts new file mode 100644 index 00000000000..554f0537d6e --- /dev/null +++ b/web-api/src/gateways/user/signUp.test.ts @@ -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 = 'test@example.com'; + 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, + }); + }); +}); diff --git a/web-api/src/gateways/user/signUp.ts b/web-api/src/gateways/user/signUp.ts new file mode 100644 index 00000000000..3e441b999ce --- /dev/null +++ b/web-api/src/gateways/user/signUp.ts @@ -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 }; +} diff --git a/web-api/src/getUserGateway.ts b/web-api/src/getUserGateway.ts index c5597efe5f4..9528d27b501 100644 --- a/web-api/src/getUserGateway.ts +++ b/web-api/src/getUserGateway.ts @@ -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 = () => ({ @@ -17,5 +18,6 @@ export const getUserGateway = () => ({ getUserByEmail, initiateAuth, renewIdToken, + signUp, updateUser, });