Skip to content

Commit

Permalink
Merge pull request #83 from HackRU/dev
Browse files Browse the repository at this point in the history
additional changes
  • Loading branch information
ethxng authored Oct 25, 2024
2 parents f5c12bc + 2601e18 commit 003ea83
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 9 deletions.
10 changes: 10 additions & 0 deletions src/functions/attend-event/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ const attendEvent: ValidatedEventAPIGatewayProxyEvent<typeof schema> = async (ev
};
}

if (attendEvent.registration_status != 'checked_in') {
return {
statusCode: 409,
body: JSON.stringify({
statusCode: 409,
message: 'User has not checked in. Current status is ' + attendEvent.registration_status,
}),
};
}

// conditions to check a user into events during hackathon
const hackEvent = event.body.event;

Expand Down
41 changes: 34 additions & 7 deletions src/functions/update/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import * as dotenv from 'dotenv';
import { Document, WithId } from 'mongodb';
dotenv.config({ path: path.resolve(process.cwd(), '.env') });

const CHECK_IN_START_DATE = new Date('2024-10-26T10:30:00');
const CHECK_IN_CUT_OFF = new Date(CHECK_IN_START_DATE.getTime() + 3 * 24 * 60 * 60 * 1000); // 3 days after check-in start

const update: ValidatedEventAPIGatewayProxyEvent<typeof schema> = async (event) => {
// if user email = auth email, you're updating auth user
// need to follow FSM for registration status
Expand Down Expand Up @@ -67,8 +70,16 @@ const update: ValidatedEventAPIGatewayProxyEvent<typeof schema> = async (event)
}

// validate updates
const isValidUpdates = validateUpdates(event.body.updates, updatedUser.registration_status, updatedUser);
if (!isValidUpdates) {
const validationResult = validateUpdates(event.body.updates, updatedUser.registration_status, updatedUser);
if (typeof validationResult === 'string') {
return {
statusCode: 400,
body: JSON.stringify({
statusCode: 400,
message: validationResult,
}),
};
} else if (!validationResult) {
return {
statusCode: 400,
body: JSON.stringify({
Expand Down Expand Up @@ -135,13 +146,29 @@ function isValidRegistrationStatusUpdate(current: string, goal: string): boolean

// return true or false whether the proposed update is valid or not

function validateUpdates(updates: Updates, registrationStatus?: string, user?: WithId<Document>): boolean {
function validateUpdates(updates: Updates, registrationStatus?: string, user?: WithId<Document>): boolean | string {
const setUpdates = updates.$set;
if (setUpdates) {
if ('registration_status' in setUpdates) {
const currentDate = new Date();
const goalStatus = setUpdates.registration_status as string;
if (!isValidRegistrationStatusUpdate(registrationStatus || 'unregistered', goalStatus)) return false;
//validates for unregistered users going to registered status

if (goalStatus === 'checked_in') {
if (currentDate > CHECK_IN_CUT_OFF)
return `Registration is closed. The cutoff date was ${CHECK_IN_CUT_OFF.toLocaleString()}.`;
}

const atleastRegistered = ['confirmed', 'waitlist', 'registered', 'coming'].includes(
registrationStatus || 'unregistered'
);
if (goalStatus === 'checked_in' && atleastRegistered) {
if (currentDate >= CHECK_IN_START_DATE || registrationStatus === 'confirmed') return true;
else
return `Current status of this user is ${registrationStatus}. Check-in will be available after ${CHECK_IN_START_DATE.toLocaleString()}.`;
}

if (!isValidRegistrationStatusUpdate(registrationStatus || 'unregistered', goalStatus))
return `Invalid registration status update from ${registrationStatus} to ${goalStatus}`;

if ((registrationStatus === undefined || registrationStatus == 'unregistered') && goalStatus === 'registered') {
if (
Expand All @@ -164,11 +191,11 @@ function validateUpdates(updates: Updates, registrationStatus?: string, user?: W
'phone_number',
].some((registrationField) => !user[registrationField] || user[registrationField] === '')
)
return false;
return 'Missing required fields';
} else return true;
}
if (['_id', 'password', 'discord', 'created_at', 'registered_at'].some((lockedProp) => lockedProp in setUpdates))
return false;
return 'Cannot update locked fields';

return true;
}
Expand Down
26 changes: 26 additions & 0 deletions tests/attend-event.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ describe('Attend-Event tests', () => {
},
},
},
registration_status: 'checked_in',
})
.mockReturnValueOnce({
role: {
Expand All @@ -117,6 +118,7 @@ describe('Attend-Event tests', () => {
findOneMock
.mockReturnValueOnce({
day_of: {},
registration_status: 'checked_in',
})
.mockReturnValueOnce({
role: {
Expand All @@ -135,4 +137,28 @@ describe('Attend-Event tests', () => {
expect(result.statusCode).toBe(200);
expect(JSON.parse(result.body).message).toBe('user successfully checked into event');
});

it('user tries to attend event when they are not checked_in', async () => {
findOneMock
.mockReturnValueOnce({
day_of: {},
registration_status: 'registered',
})
.mockReturnValueOnce({
role: {
hacker: false,
volunteer: true,
judge: false,
sponsor: false,
mentor: false,
organizer: false,
director: true,
},
});
const mockEvent = createEvent(userData, path, httpMethod);
const result = await main(mockEvent, mockContext, mockCallback);

expect(result.statusCode).toBe(409);
expect(JSON.parse(result.body).message).toBe('User has not checked in. Current status is registered');
});
});
11 changes: 9 additions & 2 deletions tests/update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,14 @@ describe('/update endpoint', () => {
const mockEvent = createEvent(invalidUpdate, '/update', 'POST');
const res = await main(mockEvent, mockContext, mockCallback);
expect(res.statusCode).toBe(400);
expect(JSON.parse(res.body).message).toBe('Bad updates.');
/*
The reason this message is being commented out is because with the new error messages,
the error message will be different depending on what field is being updated.
For example, password being update will have different message from registration_status being
updated to a value that is not a part of the graph.
*/
// expect(JSON.parse(res.body).message).toBe('Invalid registration status update from registered to coming');
}
});

Expand Down Expand Up @@ -227,7 +234,7 @@ describe('/update endpoint', () => {
const mockEvent = createEvent(incompleteUserData, '/update', 'POST');
const res = await main(mockEvent, mockContext, mockCallback);
expect(res.statusCode).toBe(400);
expect(JSON.parse(res.body).message).toBe('Bad updates.');
expect(JSON.parse(res.body).message).toBe('Missing required fields');
});
//case 8
it('Completed fields for registration, success', async () => {
Expand Down

0 comments on commit 003ea83

Please sign in to comment.