Skip to content

Commit 943ed58

Browse files
authored
Merge pull request #142 from HackRU/unregistered-teammates-bug
Unregistered teammates bug
2 parents c6a48f6 + 4eabe91 commit 943ed58

2 files changed

Lines changed: 127 additions & 1 deletion

File tree

src/functions/teams/create/handler.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ const teamsCreate: ValidatedEventAPIGatewayProxyEvent<typeof schema> = async (ev
7474
};
7575
}
7676

77+
// Check if auth user has valid registration status for team creation
78+
const validStatesForTeamCreation = ['registered', 'confirmation', 'coming'];
79+
if (!validStatesForTeamCreation.includes(authUser.registration_status)) {
80+
return {
81+
statusCode: 400,
82+
body: JSON.stringify({
83+
statusCode: 400,
84+
message: `User must be in 'registered', 'confirmation', or 'coming' state to create a team. Current state: ${authUser.registration_status}`,
85+
}),
86+
};
87+
}
88+
7789
// Check if user already leads a team
7890
if (authUser.team_info?.role === 'leader') {
7991
return {
@@ -112,11 +124,14 @@ const teamsCreate: ValidatedEventAPIGatewayProxyEvent<typeof schema> = async (ev
112124

113125
const invalidEmails = [];
114126
const emailsAlreadyInTeams = [];
127+
const emailsWithInvalidStatus = [];
115128

116129
for (const email of memberEmails) {
117130
const user = await users.findOne({ email: email });
118131
if (!user) invalidEmails.push(email);
119132
else if (user.confirmed_team === true) emailsAlreadyInTeams.push(email);
133+
else if (!validStatesForTeamCreation.includes(user.registration_status))
134+
emailsWithInvalidStatus.push({ email, status: user.registration_status });
120135
}
121136

122137
// Return errors if any validation failed
@@ -142,6 +157,18 @@ const teamsCreate: ValidatedEventAPIGatewayProxyEvent<typeof schema> = async (ev
142157
};
143158
}
144159

160+
if (emailsWithInvalidStatus.length > 0) {
161+
return {
162+
statusCode: 400,
163+
body: JSON.stringify({
164+
statusCode: 400,
165+
message: 'Some users have invalid registration status for team creation',
166+
invalid_status_users: emailsWithInvalidStatus,
167+
required_status: validStatesForTeamCreation,
168+
}),
169+
};
170+
}
171+
145172
// Validate team size (leader + members <= 4)
146173
if (memberEmails.length > 3) {
147174
return {

tests/teams-create.test.ts

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const mockTeamsCollection = {
2424
const mockDbInstance = {
2525
connect: jest.fn(),
2626
getClient: jest.fn(() => mockClient),
27-
getCollection: jest.fn((name: string) => {
27+
getCollection: jest.fn((name) => {
2828
if (name === 'users') return mockUsersCollection;
2929
if (name === 'teams') return mockTeamsCollection;
3030
return null;
@@ -78,12 +78,14 @@ describe('Teams Create Handler', () => {
7878
email: 'leader@test.com',
7979
confirmed_team: false,
8080
team_info: null,
81+
registration_status: 'registered',
8182
};
8283

8384
const mockMemberUser = {
8485
email: 'member1@test.com',
8586
confirmed_team: false,
8687
team_info: null,
88+
registration_status: 'registered',
8789
};
8890

8991
it('should successfully create team and send invitations', async () => {
@@ -381,4 +383,101 @@ describe('Teams Create Handler', () => {
381383
expect.objectContaining({ session: mockSession })
382384
);
383385
});
386+
387+
it('should return 400 when leader has unregistered status', async () => {
388+
const unregisteredLeader = {
389+
...mockLeaderUser,
390+
registration_status: 'unregistered',
391+
};
392+
mockUsersCollection.findOne.mockResolvedValue(unregisteredLeader);
393+
394+
const mockEvent = createEvent(mockEventData, '/teams/create', 'POST');
395+
const result = await main(mockEvent, mockContext);
396+
397+
expect(result.statusCode).toBe(400);
398+
const body = JSON.parse(result.body);
399+
expect(body.message).toBe(
400+
"User must be in 'registered', 'confirmation', or 'coming' state to create a team. Current state: unregistered"
401+
);
402+
});
403+
404+
it('should return 400 when leader has rejected status', async () => {
405+
const rejectedLeader = {
406+
...mockLeaderUser,
407+
registration_status: 'rejected',
408+
};
409+
mockUsersCollection.findOne.mockResolvedValue(rejectedLeader);
410+
411+
const mockEvent = createEvent(mockEventData, '/teams/create', 'POST');
412+
const result = await main(mockEvent, mockContext);
413+
414+
expect(result.statusCode).toBe(400);
415+
const body = JSON.parse(result.body);
416+
expect(body.message).toBe(
417+
"User must be in 'registered', 'confirmation', or 'coming' state to create a team. Current state: rejected"
418+
);
419+
});
420+
421+
it('should return 400 when some members have invalid registration status', async () => {
422+
const unregisteredMember = {
423+
...mockMemberUser,
424+
email: 'member1@test.com',
425+
registration_status: 'unregistered',
426+
};
427+
428+
const waitlistMember = {
429+
...mockMemberUser,
430+
email: 'member2@test.com',
431+
registration_status: 'waitlist',
432+
};
433+
434+
mockUsersCollection.findOne
435+
.mockResolvedValueOnce(mockLeaderUser) // Auth user lookup
436+
.mockResolvedValueOnce(unregisteredMember) // member1@test.com lookup
437+
.mockResolvedValueOnce(waitlistMember); // member2@test.com lookup
438+
439+
const mockEvent = createEvent(mockEventData, '/teams/create', 'POST');
440+
const result = await main(mockEvent, mockContext);
441+
442+
expect(result.statusCode).toBe(400);
443+
const body = JSON.parse(result.body);
444+
expect(body.message).toBe('Some users have invalid registration status for team creation');
445+
expect(body.invalid_status_users).toEqual([
446+
{ email: 'member1@test.com', status: 'unregistered' },
447+
{ email: 'member2@test.com', status: 'waitlist' },
448+
]);
449+
expect(body.required_status).toEqual(['registered', 'confirmation', 'coming']);
450+
});
451+
452+
it('should successfully create team when all users have valid registration statuses', async () => {
453+
const confirmationLeader = {
454+
...mockLeaderUser,
455+
registration_status: 'confirmation',
456+
};
457+
458+
const comingMember = {
459+
...mockMemberUser,
460+
email: 'member1@test.com',
461+
registration_status: 'coming',
462+
};
463+
464+
const registeredMember = {
465+
...mockMemberUser,
466+
email: 'member2@test.com',
467+
registration_status: 'registered',
468+
};
469+
470+
mockUsersCollection.findOne
471+
.mockResolvedValueOnce(confirmationLeader) // Auth user lookup
472+
.mockResolvedValueOnce(comingMember) // member1@test.com lookup
473+
.mockResolvedValueOnce(registeredMember); // member2@test.com lookup
474+
475+
const mockEvent = createEvent(mockEventData, '/teams/create', 'POST');
476+
const result = await main(mockEvent, mockContext);
477+
478+
expect(result.statusCode).toBe(200);
479+
const body = JSON.parse(result.body);
480+
expect(body.message).toBe('Team created successfully');
481+
expect(body.team_id).toBeDefined();
482+
});
384483
});

0 commit comments

Comments
 (0)