Skip to content

Commit 754c252

Browse files
committed
Add unit test
1 parent d84ff73 commit 754c252

1 file changed

Lines changed: 197 additions & 0 deletions

File tree

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
import { ErrorCode, OrganizationRole, UserStatus } from '@openops/shared';
2+
import { QueryFailedError } from 'typeorm';
3+
4+
const preSignUpMock = jest.fn();
5+
jest.mock(
6+
'../../../../src/app/authentication/authentication-service/hooks',
7+
() => {
8+
return {
9+
authenticationServiceHooks: {
10+
get: () => ({ preSignUp: preSignUpMock }),
11+
},
12+
};
13+
},
14+
);
15+
16+
const createUserServiceMock = jest.fn();
17+
const deleteUserServiceMock = jest.fn();
18+
jest.mock('../../../../src/app/user/user-service', () => ({
19+
userService: {
20+
create: createUserServiceMock,
21+
delete: deleteUserServiceMock,
22+
},
23+
}));
24+
25+
const createTablesUserMock = jest.fn();
26+
jest.mock('../../../../src/app/openops-tables', () => ({
27+
openopsTables: {
28+
createUser: createTablesUserMock,
29+
},
30+
}));
31+
32+
const generateRandomPasswordMock = jest.fn();
33+
jest.mock('@openops/server-shared', () => ({
34+
cryptoUtils: {
35+
generateRandomPassword: generateRandomPasswordMock,
36+
},
37+
}));
38+
39+
import {
40+
createUser,
41+
createUserWithRandomPassword,
42+
} from '../../../../src/app/authentication/new-user/create-user';
43+
44+
describe('create-user', () => {
45+
const baseParams = {
46+
email: 'john.doe@example.com',
47+
firstName: 'John',
48+
lastName: 'Doe',
49+
trackEvents: true,
50+
newsLetter: false,
51+
verified: true,
52+
organizationId: 'org-1',
53+
referringUserId: 'user-x',
54+
provider: 'email' as any,
55+
};
56+
57+
beforeEach(() => {
58+
jest.clearAllMocks();
59+
});
60+
61+
it('creates user and tables user successfully', async () => {
62+
const createdUser = {
63+
id: 'u1',
64+
email: baseParams.email,
65+
organizationId: baseParams.organizationId,
66+
firstName: baseParams.firstName,
67+
lastName: baseParams.lastName,
68+
status: UserStatus.ACTIVE,
69+
organizationRole: OrganizationRole.MEMBER,
70+
verified: baseParams.verified,
71+
trackEvents: baseParams.trackEvents,
72+
newsLetter: baseParams.newsLetter,
73+
};
74+
75+
createUserServiceMock.mockResolvedValue(createdUser);
76+
createTablesUserMock.mockResolvedValue({
77+
refresh_token: 'tables-token',
78+
});
79+
80+
const res = await createUser({ ...baseParams, password: 'P@ssw0rd' });
81+
82+
expect(preSignUpMock).toHaveBeenCalledWith({
83+
name: 'John Doe',
84+
email: baseParams.email,
85+
password: 'P@ssw0rd',
86+
});
87+
88+
expect(createUserServiceMock).toHaveBeenCalledWith({
89+
email: baseParams.email,
90+
organizationRole: OrganizationRole.MEMBER,
91+
verified: baseParams.verified,
92+
status: UserStatus.ACTIVE,
93+
firstName: baseParams.firstName,
94+
lastName: baseParams.lastName,
95+
trackEvents: baseParams.trackEvents,
96+
newsLetter: baseParams.newsLetter,
97+
password: 'P@ssw0rd',
98+
organizationId: baseParams.organizationId,
99+
});
100+
101+
expect(createTablesUserMock).toHaveBeenCalledWith({
102+
name: 'John Doe',
103+
email: baseParams.email,
104+
password: 'P@ssw0rd',
105+
authenticate: true,
106+
});
107+
108+
expect(res).toEqual({
109+
user: createdUser,
110+
tablesRefreshToken: 'tables-token',
111+
});
112+
});
113+
114+
it('maps duplicate user error to ApplicationError with EXISTING_USER', async () => {
115+
createUserServiceMock.mockRejectedValue(
116+
new QueryFailedError('insert into users', [], new Error('duplicate')),
117+
);
118+
119+
await expect(
120+
createUser({ ...baseParams, password: 'abc' }),
121+
).rejects.toMatchObject({
122+
error: {
123+
code: ErrorCode.EXISTING_USER,
124+
params: {
125+
email: baseParams.email,
126+
organizationId: baseParams.organizationId,
127+
},
128+
},
129+
});
130+
});
131+
132+
it('rolls back created user if tables creation fails', async () => {
133+
const createdUser = {
134+
id: 'u2',
135+
organizationId: baseParams.organizationId,
136+
};
137+
createUserServiceMock.mockResolvedValue(createdUser);
138+
createTablesUserMock.mockRejectedValue(new Error('tables down'));
139+
140+
await expect(
141+
createUser({ ...baseParams, password: 'abc' }),
142+
).rejects.toBeInstanceOf(Error);
143+
144+
expect(deleteUserServiceMock).toHaveBeenCalledWith({
145+
id: 'u2',
146+
organizationId: baseParams.organizationId,
147+
});
148+
});
149+
150+
it('creates user with random password successfully', async () => {
151+
generateRandomPasswordMock.mockResolvedValue('Rand#123');
152+
153+
const createdUser = {
154+
id: 'u3',
155+
organizationId: baseParams.organizationId,
156+
};
157+
createUserServiceMock.mockResolvedValue(createdUser);
158+
createTablesUserMock.mockResolvedValue({ refresh_token: 't2' });
159+
160+
const res = await createUserWithRandomPassword(baseParams);
161+
162+
expect(preSignUpMock).toHaveBeenCalledWith({
163+
name: 'John Doe',
164+
email: baseParams.email,
165+
password: 'Rand#123',
166+
});
167+
168+
expect(createUserServiceMock).toHaveBeenCalledWith(
169+
expect.objectContaining({ password: 'Rand#123' }),
170+
);
171+
172+
expect(createTablesUserMock).toHaveBeenCalledWith(
173+
expect.objectContaining({ password: 'Rand#123' }),
174+
);
175+
176+
expect(res).toEqual({ user: createdUser, tablesRefreshToken: 't2' });
177+
});
178+
179+
it('rolls back user when tables creation fails with random password flow', async () => {
180+
generateRandomPasswordMock.mockResolvedValue('Rand#XYZ');
181+
const createdUser = {
182+
id: 'u4',
183+
organizationId: baseParams.organizationId,
184+
};
185+
createUserServiceMock.mockResolvedValue(createdUser);
186+
createTablesUserMock.mockRejectedValue(new Error('tables err'));
187+
188+
await expect(
189+
createUserWithRandomPassword(baseParams),
190+
).rejects.toBeInstanceOf(Error);
191+
192+
expect(deleteUserServiceMock).toHaveBeenCalledWith({
193+
id: 'u4',
194+
organizationId: baseParams.organizationId,
195+
});
196+
});
197+
});

0 commit comments

Comments
 (0)