Skip to content

Commit ae4f748

Browse files
committed
feat(tests): add end-to-end tests for user registration and team permissions
1 parent adba2d6 commit ae4f748

File tree

4 files changed

+804
-2
lines changed

4 files changed

+804
-2
lines changed
Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
import request from 'supertest';
2+
import { FastifyInstance } from 'fastify';
3+
import { getTestContext, updateTestContext } from './testContext';
4+
5+
describe('Team Cross-User Permissions E2E Tests', () => {
6+
let server: FastifyInstance;
7+
let port: number;
8+
9+
beforeAll(() => {
10+
// Access the server instance and port from test context
11+
const context = getTestContext();
12+
server = context.server!;
13+
port = context.port;
14+
});
15+
16+
it('should login regular_user to get fresh session for team creation', async () => {
17+
const context = getTestContext();
18+
19+
// Login with the regular user (global_user) from test 2
20+
const loginResponse = await request(server.server)
21+
.post('/api/auth/email/login')
22+
.send({
23+
24+
password: 'SecurePassword456!'
25+
});
26+
27+
expect(loginResponse.status).toBe(200);
28+
expect(loginResponse.body.success).toBe(true);
29+
expect(loginResponse.body.user.id).toBe(context.secondUserId);
30+
expect(loginResponse.body.user.role_id).toBe('global_user');
31+
32+
// Store fresh session cookie for team creation tests
33+
updateTestContext({
34+
secondUserCrossPermissionCookie: loginResponse.headers['set-cookie'][0]
35+
});
36+
});
37+
38+
it('should login regular_user_2 to get fresh session', async () => {
39+
const context = getTestContext();
40+
41+
// Login with the third user (global_user) from test 2
42+
const loginResponse = await request(server.server)
43+
.post('/api/auth/email/login')
44+
.send({
45+
46+
password: 'SecurePassword789!'
47+
});
48+
49+
expect(loginResponse.status).toBe(200);
50+
expect(loginResponse.body.success).toBe(true);
51+
expect(loginResponse.body.user.id).toBe(context.thirdUserId);
52+
expect(loginResponse.body.user.role_id).toBe('global_user');
53+
54+
// Store fresh session cookie for cross-user tests
55+
updateTestContext({
56+
thirdUserCrossPermissionCookie: loginResponse.headers['set-cookie'][0]
57+
});
58+
});
59+
60+
it('should verify regular_user has teams from previous tests', async () => {
61+
const context = getTestContext();
62+
63+
// Check user's current teams (should have 3 teams from test 10: default + 2 additional)
64+
const teamsResponse = await request(server.server)
65+
.get('/api/teams/me')
66+
.set('Cookie', context.secondUserCrossPermissionCookie!);
67+
68+
expect(teamsResponse.status).toBe(200);
69+
expect(teamsResponse.body).toHaveProperty('success', true);
70+
expect(teamsResponse.body).toHaveProperty('data');
71+
expect(teamsResponse.body.data).toHaveLength(3); // Default + 2 additional from test 10
72+
73+
const teams = teamsResponse.body.data;
74+
75+
// Find the default team
76+
const defaultTeam = teams.find((team: any) => team.name === 'regular_user');
77+
expect(defaultTeam).toBeDefined();
78+
expect(defaultTeam.owner_id).toBe(context.secondUserId);
79+
expect(defaultTeam.role).toBe('team_admin');
80+
81+
// Verify all teams belong to the user
82+
teams.forEach((team: any) => {
83+
expect(team.owner_id).toBe(context.secondUserId);
84+
expect(team.role).toBe('team_admin');
85+
});
86+
});
87+
88+
it('should verify regular_user_2 starts with only default team', async () => {
89+
const context = getTestContext();
90+
91+
// Check user's current teams
92+
const teamsResponse = await request(server.server)
93+
.get('/api/teams/me')
94+
.set('Cookie', context.thirdUserCrossPermissionCookie!);
95+
96+
expect(teamsResponse.status).toBe(200);
97+
expect(teamsResponse.body).toHaveProperty('success', true);
98+
expect(teamsResponse.body).toHaveProperty('data');
99+
expect(teamsResponse.body.data).toHaveLength(1);
100+
101+
const defaultTeam = teamsResponse.body.data[0];
102+
expect(defaultTeam.name).toBe('regular_user_2'); // Default team name is username
103+
expect(defaultTeam.owner_id).toBe(context.thirdUserId);
104+
expect(defaultTeam.role).toBe('team_admin'); // User is admin of their own team
105+
});
106+
107+
it('should delete one existing team to make room for cross-permission test', async () => {
108+
const context = getTestContext();
109+
110+
// Get current teams to find one to delete (not the default team)
111+
const teamsResponse = await request(server.server)
112+
.get('/api/teams/me')
113+
.set('Cookie', context.secondUserCrossPermissionCookie!);
114+
115+
expect(teamsResponse.status).toBe(200);
116+
const teams = teamsResponse.body.data;
117+
118+
// Find a non-default team to delete
119+
const teamToDelete = teams.find((team: any) => team.name !== 'regular_user');
120+
expect(teamToDelete).toBeDefined();
121+
122+
// Delete the team to make room for our test
123+
const deleteResponse = await request(server.server)
124+
.delete(`/api/teams/${teamToDelete.id}`)
125+
.set('Cookie', context.secondUserCrossPermissionCookie!);
126+
127+
expect(deleteResponse.status).toBe(200);
128+
expect(deleteResponse.body).toHaveProperty('success', true);
129+
});
130+
131+
it('should allow regular_user to create a new team', async () => {
132+
const context = getTestContext();
133+
134+
const teamData = {
135+
name: 'Cross Permission Test Team',
136+
description: 'Team created by regular_user for cross-permission testing'
137+
};
138+
139+
const response = await request(server.server)
140+
.post('/api/teams')
141+
.set('Cookie', context.secondUserCrossPermissionCookie!)
142+
.send(teamData);
143+
144+
expect(response.status).toBe(201);
145+
expect(response.body).toHaveProperty('success', true);
146+
expect(response.body).toHaveProperty('data');
147+
expect(response.body).toHaveProperty('message');
148+
149+
const team = response.body.data;
150+
expect(team.name).toBe(teamData.name);
151+
expect(team.description).toBe(teamData.description);
152+
expect(team.owner_id).toBe(context.secondUserId);
153+
expect(team.slug).toBe('cross-permission-test-team'); // Auto-generated slug
154+
expect(team.id).toBeDefined();
155+
expect(team.created_at).toBeDefined();
156+
expect(team.updated_at).toBeDefined();
157+
158+
// Store team ID for cross-user permission tests
159+
updateTestContext({
160+
crossPermissionTestTeamId: team.id
161+
});
162+
});
163+
164+
it('should verify regular_user now has 3 teams', async () => {
165+
const context = getTestContext();
166+
167+
// Check user's current teams (should have 3: default + 1 remaining from test 10 + new test team)
168+
const teamsResponse = await request(server.server)
169+
.get('/api/teams/me')
170+
.set('Cookie', context.secondUserCrossPermissionCookie!);
171+
172+
expect(teamsResponse.status).toBe(200);
173+
expect(teamsResponse.body).toHaveProperty('success', true);
174+
expect(teamsResponse.body).toHaveProperty('data');
175+
expect(teamsResponse.body.data).toHaveLength(3);
176+
177+
// Verify all teams belong to the user
178+
const teams = teamsResponse.body.data;
179+
teams.forEach((team: any) => {
180+
expect(team.owner_id).toBe(context.secondUserId);
181+
expect(team.role).toBe('team_admin'); // User is admin of their own teams
182+
});
183+
184+
// Verify the new test team exists
185+
const testTeam = teams.find((team: any) => team.name === 'Cross Permission Test Team');
186+
expect(testTeam).toBeDefined();
187+
expect(testTeam.id).toBe(context.crossPermissionTestTeamId);
188+
});
189+
190+
it('should prevent regular_user_2 from accessing regular_user team by ID', async () => {
191+
const context = getTestContext();
192+
193+
// Try to get the team created by regular_user using regular_user_2's session
194+
const response = await request(server.server)
195+
.get(`/api/teams/${context.crossPermissionTestTeamId}`)
196+
.set('Cookie', context.thirdUserCrossPermissionCookie!);
197+
198+
expect(response.status).toBe(403);
199+
expect(response.body).toHaveProperty('success', false);
200+
expect(response.body).toHaveProperty('error');
201+
expect(response.body.error.toLowerCase()).toContain('access');
202+
});
203+
204+
it('should prevent regular_user_2 from deleting regular_user team', async () => {
205+
const context = getTestContext();
206+
207+
// Try to delete the team created by regular_user using regular_user_2's session
208+
const response = await request(server.server)
209+
.delete(`/api/teams/${context.crossPermissionTestTeamId}`)
210+
.set('Cookie', context.thirdUserCrossPermissionCookie!);
211+
212+
expect(response.status).toBe(403);
213+
expect(response.body).toHaveProperty('success', false);
214+
expect(response.body).toHaveProperty('error');
215+
expect(response.body.error.toLowerCase()).toContain('owner');
216+
});
217+
218+
it('should prevent regular_user_2 from updating regular_user team', async () => {
219+
const context = getTestContext();
220+
221+
const updateData = {
222+
name: 'Hacked Team Name',
223+
description: 'This should not work'
224+
};
225+
226+
// Try to update the team created by regular_user using regular_user_2's session
227+
const response = await request(server.server)
228+
.put(`/api/teams/${context.crossPermissionTestTeamId}`)
229+
.set('Cookie', context.thirdUserCrossPermissionCookie!)
230+
.send(updateData);
231+
232+
expect(response.status).toBe(403);
233+
expect(response.body).toHaveProperty('success', false);
234+
expect(response.body).toHaveProperty('error');
235+
expect(response.body.error.toLowerCase()).toContain('administrator');
236+
});
237+
238+
it('should verify regular_user_2 only sees their own teams', async () => {
239+
const context = getTestContext();
240+
241+
// Check that regular_user_2 only sees their own team
242+
const teamsResponse = await request(server.server)
243+
.get('/api/teams/me')
244+
.set('Cookie', context.thirdUserCrossPermissionCookie!);
245+
246+
expect(teamsResponse.status).toBe(200);
247+
expect(teamsResponse.body).toHaveProperty('success', true);
248+
expect(teamsResponse.body).toHaveProperty('data');
249+
expect(teamsResponse.body.data).toHaveLength(1);
250+
251+
const team = teamsResponse.body.data[0];
252+
expect(team.name).toBe('regular_user_2'); // Only their default team
253+
expect(team.owner_id).toBe(context.thirdUserId);
254+
expect(team.role).toBe('team_admin');
255+
});
256+
257+
it('should verify the team created by regular_user still exists and is unchanged', async () => {
258+
const context = getTestContext();
259+
260+
// Verify regular_user can still access their team
261+
const teamResponse = await request(server.server)
262+
.get(`/api/teams/${context.crossPermissionTestTeamId}`)
263+
.set('Cookie', context.secondUserCrossPermissionCookie!);
264+
265+
expect(teamResponse.status).toBe(200);
266+
expect(teamResponse.body).toHaveProperty('success', true);
267+
expect(teamResponse.body).toHaveProperty('data');
268+
269+
const team = teamResponse.body.data;
270+
expect(team.name).toBe('Cross Permission Test Team'); // Original name unchanged
271+
expect(team.description).toBe('Team created by regular_user for cross-permission testing');
272+
expect(team.owner_id).toBe(context.secondUserId);
273+
expect(team.slug).toBe('cross-permission-test-team');
274+
});
275+
276+
it('should allow regular_user to delete their own team', async () => {
277+
const context = getTestContext();
278+
279+
// regular_user should be able to delete their own team
280+
const response = await request(server.server)
281+
.delete(`/api/teams/${context.crossPermissionTestTeamId}`)
282+
.set('Cookie', context.secondUserCrossPermissionCookie!);
283+
284+
expect(response.status).toBe(200);
285+
expect(response.body).toHaveProperty('success', true);
286+
expect(response.body).toHaveProperty('message');
287+
});
288+
289+
it('should verify regular_user has 2 teams after deletion', async () => {
290+
const context = getTestContext();
291+
292+
// Check user's current teams after deletion (should have 2: default + 1 remaining from test 10)
293+
const teamsResponse = await request(server.server)
294+
.get('/api/teams/me')
295+
.set('Cookie', context.secondUserCrossPermissionCookie!);
296+
297+
expect(teamsResponse.status).toBe(200);
298+
expect(teamsResponse.body).toHaveProperty('success', true);
299+
expect(teamsResponse.body).toHaveProperty('data');
300+
expect(teamsResponse.body.data).toHaveLength(2);
301+
302+
const teams = teamsResponse.body.data;
303+
304+
// Verify default team exists
305+
const defaultTeam = teams.find((team: any) => team.name === 'regular_user');
306+
expect(defaultTeam).toBeDefined();
307+
expect(defaultTeam.owner_id).toBe(context.secondUserId);
308+
expect(defaultTeam.role).toBe('team_admin');
309+
310+
// Verify the cross-permission test team is gone
311+
const testTeam = teams.find((team: any) => team.name === 'Cross Permission Test Team');
312+
expect(testTeam).toBeUndefined();
313+
});
314+
315+
it('should return 404 when trying to access deleted team', async () => {
316+
const context = getTestContext();
317+
318+
// Try to access the deleted team
319+
const response = await request(server.server)
320+
.get(`/api/teams/${context.crossPermissionTestTeamId}`)
321+
.set('Cookie', context.secondUserCrossPermissionCookie!);
322+
323+
expect(response.status).toBe(404);
324+
expect(response.body).toHaveProperty('success', false);
325+
expect(response.body).toHaveProperty('error');
326+
});
327+
});

0 commit comments

Comments
 (0)