Skip to content

Commit 4d91888

Browse files
committed
chore(test): Add tests
1 parent 285a0c8 commit 4d91888

File tree

9 files changed

+3768
-26
lines changed

9 files changed

+3768
-26
lines changed

src/auth/auth.e2e-spec.ts

Lines changed: 510 additions & 26 deletions
Large diffs are not rendered by default.

src/groups/groups.e2e-spec.ts

Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
import { TestClient } from 'test/test-client';
2+
import { HttpStatus } from '@nestjs/common';
3+
4+
describe('GroupsController (e2e)', () => {
5+
let client: TestClient;
6+
let secondClient: TestClient;
7+
let testGroupId: string;
8+
9+
beforeAll(async () => {
10+
client = await TestClient.create();
11+
secondClient = await TestClient.create();
12+
});
13+
14+
afterAll(async () => {
15+
await client.close();
16+
await secondClient.close();
17+
});
18+
19+
describe('POST /api/v1/namespaces/:namespaceId/groups', () => {
20+
it('should create a new group', async () => {
21+
const createGroupDto = {
22+
title: 'Test Group',
23+
};
24+
25+
const response = await client
26+
.post(`/api/v1/namespaces/${client.namespace.id}/groups`)
27+
.send(createGroupDto)
28+
.expect(HttpStatus.CREATED);
29+
30+
expect(response.body).toHaveProperty('id');
31+
expect(response.body.title).toBe(createGroupDto.title);
32+
expect(response.body.namespace_id).toBe(client.namespace.id);
33+
34+
testGroupId = response.body.id;
35+
});
36+
37+
it('should fail to create group with empty title', async () => {
38+
const createGroupDto = {
39+
title: '',
40+
};
41+
42+
await client
43+
.post(`/api/v1/namespaces/${client.namespace.id}/groups`)
44+
.send(createGroupDto)
45+
.expect(HttpStatus.BAD_REQUEST);
46+
});
47+
48+
it('should fail to create group with missing title', async () => {
49+
const createGroupDto = {};
50+
51+
await client
52+
.post(`/api/v1/namespaces/${client.namespace.id}/groups`)
53+
.send(createGroupDto)
54+
.expect(HttpStatus.BAD_REQUEST);
55+
});
56+
57+
it('should fail to create group in namespace user does not own', async () => {
58+
const createGroupDto = {
59+
title: 'Unauthorized Group',
60+
};
61+
62+
await secondClient
63+
.post(`/api/v1/namespaces/${client.namespace.id}/groups`)
64+
.send(createGroupDto)
65+
.expect(HttpStatus.FORBIDDEN);
66+
});
67+
});
68+
69+
describe('GET /api/v1/namespaces/:namespaceId/groups', () => {
70+
it('should list groups in namespace', async () => {
71+
const response = await client
72+
.get(`/api/v1/namespaces/${client.namespace.id}/groups`)
73+
.expect(HttpStatus.OK);
74+
75+
expect(Array.isArray(response.body)).toBe(true);
76+
expect(response.body.length).toBeGreaterThan(0);
77+
78+
const group = response.body.find((g: any) => g.id === testGroupId);
79+
expect(group).toBeDefined();
80+
expect(group.title).toBe('Test Group');
81+
expect(group.namespace_id).toBe(client.namespace.id);
82+
});
83+
84+
it('should fail to list groups in namespace user does not own', async () => {
85+
await secondClient
86+
.get(`/api/v1/namespaces/${client.namespace.id}/groups`)
87+
.expect(HttpStatus.FORBIDDEN);
88+
});
89+
});
90+
91+
describe('PATCH /api/v1/namespaces/:namespaceId/groups/:groupId', () => {
92+
it('should update group title', async () => {
93+
const updateGroupDto = {
94+
title: 'Updated Test Group',
95+
};
96+
97+
const response = await client
98+
.patch(
99+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}`,
100+
)
101+
.send(updateGroupDto)
102+
.expect(HttpStatus.OK);
103+
104+
expect(response.body.id).toBe(testGroupId);
105+
expect(response.body.title).toBe(updateGroupDto.title);
106+
expect(response.body.namespace_id).toBe(client.namespace.id);
107+
});
108+
109+
it('should fail to update group with empty title', async () => {
110+
const updateGroupDto = {
111+
title: '',
112+
};
113+
114+
await client
115+
.patch(
116+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}`,
117+
)
118+
.send(updateGroupDto)
119+
.expect(HttpStatus.BAD_REQUEST);
120+
});
121+
122+
it('should fail to update group in namespace user does not own', async () => {
123+
const updateGroupDto = {
124+
title: 'Unauthorized Update',
125+
};
126+
127+
await secondClient
128+
.patch(
129+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}`,
130+
)
131+
.send(updateGroupDto)
132+
.expect(HttpStatus.FORBIDDEN);
133+
});
134+
135+
it('should fail to update non-existent group', async () => {
136+
const updateGroupDto = {
137+
title: 'Non-existent Group',
138+
};
139+
140+
await client
141+
.patch(`/api/v1/namespaces/${client.namespace.id}/groups/nonexistent`)
142+
.send(updateGroupDto)
143+
.expect(HttpStatus.INTERNAL_SERVER_ERROR);
144+
});
145+
});
146+
147+
describe('POST /api/v1/namespaces/:namespaceId/groups/:groupId/users', () => {
148+
it('should add users to group', async () => {
149+
const addGroupUserDto = {
150+
userIds: [secondClient.user.id],
151+
};
152+
153+
await client
154+
.post(
155+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}/users`,
156+
)
157+
.send(addGroupUserDto)
158+
.expect(HttpStatus.CREATED);
159+
});
160+
161+
it('should handle empty userIds array', async () => {
162+
const addGroupUserDto = {
163+
userIds: [],
164+
};
165+
166+
await client
167+
.post(
168+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}/users`,
169+
)
170+
.send(addGroupUserDto)
171+
.expect(HttpStatus.CREATED);
172+
});
173+
174+
it('should fail to add users to group in namespace user does not own', async () => {
175+
const addGroupUserDto = {
176+
userIds: [client.user.id],
177+
};
178+
179+
await secondClient
180+
.post(
181+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}/users`,
182+
)
183+
.send(addGroupUserDto)
184+
.expect(HttpStatus.FORBIDDEN);
185+
});
186+
});
187+
188+
describe('GET /api/v1/namespaces/:namespaceId/groups/:groupId/users', () => {
189+
it('should list users in group', async () => {
190+
const response = await client
191+
.get(
192+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}/users`,
193+
)
194+
.expect(HttpStatus.OK);
195+
196+
expect(Array.isArray(response.body)).toBe(true);
197+
expect(response.body.length).toBeGreaterThan(0);
198+
199+
const user = response.body.find(
200+
(u: any) => u.id === secondClient.user.id,
201+
);
202+
expect(user).toBeDefined();
203+
expect(user.email).toBe(secondClient.user.email);
204+
});
205+
206+
it('should fail to list users in group in namespace user does not own', async () => {
207+
await secondClient
208+
.get(
209+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}/users`,
210+
)
211+
.expect(HttpStatus.FORBIDDEN);
212+
});
213+
});
214+
215+
describe('DELETE /api/v1/namespaces/:namespaceId/groups/:groupId/users/:userId', () => {
216+
it('should remove user from group', async () => {
217+
await client
218+
.delete(
219+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}/users/${secondClient.user.id}`,
220+
)
221+
.expect(HttpStatus.OK);
222+
223+
// Verify user was removed
224+
const response = await client
225+
.get(
226+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}/users`,
227+
)
228+
.expect(HttpStatus.OK);
229+
230+
const user = response.body.find(
231+
(u: any) => u.id === secondClient.user.id,
232+
);
233+
expect(user).toBeUndefined();
234+
});
235+
236+
it('should fail to remove user from group in namespace user does not own', async () => {
237+
await secondClient
238+
.delete(
239+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}/users/${client.user.id}`,
240+
)
241+
.expect(HttpStatus.FORBIDDEN);
242+
});
243+
});
244+
245+
describe('DELETE /api/v1/namespaces/:namespaceId/groups/:groupId', () => {
246+
it('should fail to delete group in namespace user does not own', async () => {
247+
await secondClient
248+
.delete(
249+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}`,
250+
)
251+
.expect(HttpStatus.FORBIDDEN);
252+
});
253+
254+
it('should delete group', async () => {
255+
await client
256+
.delete(
257+
`/api/v1/namespaces/${client.namespace.id}/groups/${testGroupId}`,
258+
)
259+
.expect(HttpStatus.OK);
260+
261+
// Verify group was deleted
262+
const response = await client
263+
.get(`/api/v1/namespaces/${client.namespace.id}/groups`)
264+
.expect(HttpStatus.OK);
265+
266+
const group = response.body.find((g: any) => g.id === testGroupId);
267+
expect(group).toBeUndefined();
268+
});
269+
270+
it('should succeed to delete non-existent group (soft delete behavior)', async () => {
271+
await client
272+
.delete(`/api/v1/namespaces/${client.namespace.id}/groups/nonexistent`)
273+
.expect(HttpStatus.OK);
274+
});
275+
});
276+
277+
describe('Edge Cases and Error Handling', () => {
278+
let edgeTestGroupId: string;
279+
280+
beforeAll(async () => {
281+
// Create a group for edge case testing
282+
const response = await client
283+
.post(`/api/v1/namespaces/${client.namespace.id}/groups`)
284+
.send({ title: 'Edge Test Group' })
285+
.expect(HttpStatus.CREATED);
286+
287+
edgeTestGroupId = response.body.id;
288+
});
289+
290+
afterAll(async () => {
291+
// Clean up edge test group
292+
await client
293+
.delete(
294+
`/api/v1/namespaces/${client.namespace.id}/groups/${edgeTestGroupId}`,
295+
)
296+
.catch(() => {}); // Ignore errors if already deleted
297+
});
298+
299+
it('should handle special characters in group title', async () => {
300+
const specialTitleGroup = {
301+
title: 'Test Group with 特殊字符 and émojis 🚀',
302+
};
303+
304+
const response = await client
305+
.post(`/api/v1/namespaces/${client.namespace.id}/groups`)
306+
.send(specialTitleGroup)
307+
.expect(HttpStatus.CREATED);
308+
309+
expect(response.body.title).toBe(specialTitleGroup.title);
310+
311+
// Clean up
312+
await client
313+
.delete(
314+
`/api/v1/namespaces/${client.namespace.id}/groups/${response.body.id}`,
315+
)
316+
.expect(HttpStatus.OK);
317+
});
318+
319+
it('should handle adding duplicate users to group', async () => {
320+
// Add user first time
321+
await client
322+
.post(
323+
`/api/v1/namespaces/${client.namespace.id}/groups/${edgeTestGroupId}/users`,
324+
)
325+
.send({ userIds: [secondClient.user.id] })
326+
.expect(HttpStatus.CREATED);
327+
328+
// Add same user again - should not fail
329+
await client
330+
.post(
331+
`/api/v1/namespaces/${client.namespace.id}/groups/${edgeTestGroupId}/users`,
332+
)
333+
.send({ userIds: [secondClient.user.id] })
334+
.expect(HttpStatus.CREATED);
335+
});
336+
337+
it('should fail when removing user with invalid UUID format', async () => {
338+
await client
339+
.delete(
340+
`/api/v1/namespaces/${client.namespace.id}/groups/${edgeTestGroupId}/users/nonexistent`,
341+
)
342+
.expect(HttpStatus.INTERNAL_SERVER_ERROR);
343+
});
344+
});
345+
});

0 commit comments

Comments
 (0)