diff --git a/package-lock.json b/package-lock.json index 2de8eba..55ff583 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "secretsanta", - "version": "5.1.2", + "version": "5.1.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "secretsanta", - "version": "5.1.2", + "version": "5.1.3", "license": "MIT", "dependencies": { "@sendgrid/mail": "^8.1.3", diff --git a/package.json b/package.json index 5c8b482..cc30af1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "secretsanta", - "version": "5.1.2", + "version": "5.1.3", "description": "SecretSanta source code", "author": "Zaista", "license": "MIT", diff --git a/public/admin/santaAdmin.js b/public/admin/santaAdmin.js index a32e080..216bea1 100644 --- a/public/admin/santaAdmin.js +++ b/public/admin/santaAdmin.js @@ -233,6 +233,7 @@ $(async () => { success: (result) => { if (result.success) { $(this).prop('disabled', true); + $('#reveal').prop('disabled', false); } showAlert(result); }, diff --git a/public/history/year/santaYear.js b/public/history/year/santaYear.js index 17d19c3..7798dc8 100644 --- a/public/history/year/santaYear.js +++ b/public/history/year/santaYear.js @@ -61,10 +61,10 @@ $(async () => { const giftElement = $.parseHTML(giftTemplate); let santaName = gift.santa; let childName = gift.child; - if (gift.santa === '') { + if (gift.santa === undefined || gift.santa === '') { santaName = gift.santaEmail; } - if (gift.child === '') { + if (gift.child === undefined || gift.child === '') { childName = gift.childEmail; } $(giftElement).find('[data-id="santa"]').text(santaName); diff --git a/public/profile/santaProfile.js b/public/profile/santaProfile.js index bc61154..f1598e3 100644 --- a/public/profile/santaProfile.js +++ b/public/profile/santaProfile.js @@ -11,6 +11,9 @@ $(async () => { $.get(`${apiUrl}/list?id=${searchParams.get('id')}`, (friend) => { if (friend.error) { showAlert(friend); + $('#image').removeClass('loading-image'); + // TODO disable image click + $('#profileSaveButton').prop('disabled', true); } else { if (friend.imageUploaded) { lazyLoadImage(friend._id, $('#image')).then((image) => { diff --git a/routers/admin-router.js b/routers/admin-router.js index 8c64fed..4973df4 100644 --- a/routers/admin-router.js +++ b/routers/admin-router.js @@ -184,17 +184,19 @@ adminRouter.post('/api/forbidden', async (req, res) => { req.session.activeGroup._id, req.body ); - if (result.insertedId) { + if (result === null) { return res.send({ - success: 'Forbidden pair added', - id: result.insertedId, + error: 'Creating forbidden pair failed', }); } else if (result.error) { return res.send(result); - } else { + } else if (result.insertedId) { return res.send({ - error: 'Something went wrong while creating a forbidden pair', + success: 'Forbidden pair added', + id: result.insertedId, }); + } else { + throw Error('Something went wrong'); } }); @@ -267,7 +269,9 @@ adminRouter.put('/api/reveal', async (req, res) => { if (!req.user) return res.status(401).send({ error: 'User not logged in' }); const history = await getYearsByGroup(req.session.activeGroup._id); - if (history[0].revealed) { + if (history.length === 0) { + return res.send({ error: 'Year not drafted yet' }); + } else if (history[0].revealed) { return res.send({ error: 'Year already revealed' }); } diff --git a/routers/chat-router.js b/routers/chat-router.js index 9d1f495..be5eb41 100644 --- a/routers/chat-router.js +++ b/routers/chat-router.js @@ -67,14 +67,14 @@ chatRouter.post('/api/send', async (req, res) => { response.success = `Message posted in chat and email sent to ${emailTemplate.to}`; response.emailUrl = emailStatus.emailUrl; } else { - res.send({ + return res.send({ error: `Error sending email: ${emailStatus.error}`, }); } } - res.send(response); + return res.send(response); } else { - res.send({ + return res.send({ error: 'Failed to ask the question. Contact the administrator', }); } diff --git a/routers/profile-router.js b/routers/profile-router.js index 7562bcb..0818b21 100644 --- a/routers/profile-router.js +++ b/routers/profile-router.js @@ -30,13 +30,22 @@ profileRouter.get('/api/list', async (req, res) => { let userId = req.user._id; if (req.query.id !== 'null') { userId = ObjectId.createFromHexString(req.query.id); + const friend = await getProfile(userId); + if ( + friend?.groups?.some((group) => + group.groupId.equals(req.session.activeGroup._id) + ) + ) { + return res.send(friend); + } else { + return res.send({ error: 'Profile not found' }); + } } - const friend = await getProfile(userId); - if (friend === null) { - res.send({ error: 'Profile not found' }); - } else { - res.send(friend); + const profile = await getProfile(userId); + if (profile === null) { + return res.send({ error: 'Profile not found' }); } + return res.send(profile); }); profileRouter.post('/api/update', async (req, res) => { diff --git a/tests/admin.spec.js b/tests/admin.spec.js index 2d9a7de..b231498 100644 --- a/tests/admin.spec.js +++ b/tests/admin.spec.js @@ -8,6 +8,7 @@ import { addForbiddenPair, draftSantaPairs, revealSantaPairs, + removeForbiddenPair, } from './helpers/admin.js'; import { createNewGroup, createDraftedGroup } from './helpers/setup.js'; @@ -115,7 +116,7 @@ test.describe('admin tests', () => { }); test('admin cannot add forbidden pair again', async ({ page }) => { - const groupData = await createDraftedGroup(page.request); + const groupData = await createNewGroup(page.request); const forbiddenPair = { forbiddenUser1Id: groupData.users.user1.id, forbiddenUser2Id: groupData.users.user2.id, @@ -135,24 +136,198 @@ test.describe('admin tests', () => { .selectOption(groupData.users.user2.id); await page.getByRole('button', { name: 'Forbid' }).click(); await expect(page.locator('#footerAlert')).toHaveText( - 'Forbidden pair already exists.' + 'Forbidden pair already exists' ); }); - test('forbidden pairs should not draft each other', async ({ page }) => { + test('admin can remove a forbidden pair', async ({ page }) => { const groupData = await createNewGroup(page.request); + await login( + page.request, + groupData.users.admin.email, + groupData.users.admin.password + ); const forbiddenPair = { forbiddenUser1Id: groupData.users.user1.id, forbiddenUser2Id: groupData.users.user2.id, }; await addForbiddenPair(page.request, forbiddenPair); - await draftSantaPairs(page.request); + await login( + page.request, + groupData.users.admin.email, + groupData.users.admin.password + ); + await page.goto('/admin'); + + await page.locator('[data-name="pairDelete"]').click(); + await page.getByRole('button', { name: 'Delete pair' }).click(); + await expect(page.locator('#footerAlert')).toHaveText( + 'The forbidden pair was successfully deleted' + ); + }); + + test('forbidden pairs should not draft each other', async ({ page }) => { + const groupData = await createNewGroup(page.request); + const forbiddenPair = { + forbiddenUser1Id: groupData.users.user1.id, + forbiddenUser2Id: groupData.users.user2.id, + }; + const pairResult = await addForbiddenPair(page.request, forbiddenPair); + const draftFailedResult = await draftSantaPairs(page.request); + expect(draftFailedResult).toHaveProperty('error'); + await removeForbiddenPair(page.request, pairResult.id); + const draftSuccessfulResult = await draftSantaPairs(page.request); + expect(draftSuccessfulResult).toHaveProperty('success'); + }); + + test('multiple forbidden pairs should not draft each other', async ({ + page, + }) => { + const groupData = { + users: { + admin: { + email: faker.internet.email(), + password: 'test', + }, + user2: { + email: faker.internet.email(), + password: 'test', + }, + user3: { + email: faker.internet.email(), + password: 'test', + }, + user4: { + email: faker.internet.email(), + password: 'test', + }, + user5: { + email: faker.internet.email(), + password: 'test', + }, + user6: { + email: faker.internet.email(), + password: 'test', + }, + user7: { + email: faker.internet.email(), + password: 'test', + }, + user8: { + email: faker.internet.email(), + password: 'test', + }, + user9: { + email: faker.internet.email(), + password: 'test', + }, + user10: { + email: faker.internet.email(), + password: 'test', + }, + }, + group: { + name: faker.word.noun(), + }, + }; + + await createNewGroup(page.request, groupData); + const forbiddenPair1 = { + forbiddenUser1Id: groupData.users.admin.id, + forbiddenUser2Id: groupData.users.user2.id, + }; + const forbiddenPair2 = { + forbiddenUser1Id: groupData.users.user3.id, + forbiddenUser2Id: groupData.users.user4.id, + }; + const forbiddenPair3 = { + forbiddenUser1Id: groupData.users.user5.id, + forbiddenUser2Id: groupData.users.user6.id, + }; + const forbiddenPair4 = { + forbiddenUser1Id: groupData.users.user8.id, + forbiddenUser2Id: groupData.users.user7.id, + }; + const forbiddenPair5 = { + forbiddenUser1Id: groupData.users.user10.id, + forbiddenUser2Id: groupData.users.user9.id, + }; + await addForbiddenPair(page.request, forbiddenPair1); + await addForbiddenPair(page.request, forbiddenPair2); + await addForbiddenPair(page.request, forbiddenPair3); + await addForbiddenPair(page.request, forbiddenPair4); + await addForbiddenPair(page.request, forbiddenPair5); + let i = 0; + while (i < 10) { + const result = await draftSantaPairs(page.request); + if ('success' in result) { + break; + } + i++; + } await revealSantaPairs(page.request); await page.goto('/history'); await page.getByText('N/A').click(); - await expect( - page.getByRole('row', { name: groupData.users.user1.name }).first() - ).not.toHaveText(groupData.users.user2.name); + + let santa = page + .locator('*[data-id="santa"]') + .filter({ hasText: groupData.users.admin.email }); + let parent = page.getByRole('row').filter({ has: santa }); + await expect(parent).not.toHaveText(groupData.users.user2.email); + + santa = page + .locator('*[data-id="santa"]') + .filter({ hasText: groupData.users.user2.email }); + parent = page.getByRole('row').filter({ has: santa }); + await expect(parent).not.toHaveText(groupData.users.admin.email); + + santa = page + .locator('*[data-id="santa"]') + .filter({ hasText: groupData.users.user3.email }); + parent = page.getByRole('row').filter({ has: santa }); + await expect(parent).not.toHaveText(groupData.users.user4.email); + + santa = page + .locator('*[data-id="santa"]') + .filter({ hasText: groupData.users.user4.email }); + parent = page.getByRole('row').filter({ has: santa }); + await expect(parent).not.toHaveText(groupData.users.user3.email); + + santa = page + .locator('*[data-id="santa"]') + .filter({ hasText: groupData.users.user5.email }); + parent = page.getByRole('row').filter({ has: santa }); + await expect(parent).not.toHaveText(groupData.users.user6.email); + + santa = page + .locator('*[data-id="santa"]') + .filter({ hasText: groupData.users.user6.email }); + parent = page.getByRole('row').filter({ has: santa }); + await expect(parent).not.toHaveText(groupData.users.user5.email); + + santa = page + .locator('*[data-id="santa"]') + .filter({ hasText: groupData.users.user7.email }); + parent = page.getByRole('row').filter({ has: santa }); + await expect(parent).not.toHaveText(groupData.users.user8.email); + + santa = page + .locator('*[data-id="santa"]') + .filter({ hasText: groupData.users.user8.email }); + parent = page.getByRole('row').filter({ has: santa }); + await expect(parent).not.toHaveText(groupData.users.user7.email); + + santa = page + .locator('*[data-id="santa"]') + .filter({ hasText: groupData.users.user9.email }); + parent = page.getByRole('row').filter({ has: santa }); + await expect(parent).not.toHaveText(groupData.users.user10.email); + + santa = page + .locator('*[data-id="santa"]') + .filter({ hasText: groupData.users.user10.email }); + parent = page.getByRole('row').filter({ has: santa }); + await expect(parent).not.toHaveText(groupData.users.user9.email); }); }); diff --git a/tests/email.spec.js b/tests/email.spec.js index 2721739..bb3c1b6 100644 --- a/tests/email.spec.js +++ b/tests/email.spec.js @@ -7,175 +7,248 @@ import { createDraftedGroup, createNewGroup } from './helpers/setup.js'; import { sendMessage } from './helpers/chat.js'; test.describe('email tests', () => { - test.describe('admin tests', () => { - test('user should receive an email when forgot password is triggered', async ({ - page, - }) => { - const user = { - email: faker.internet.email(), - password: faker.internet.password(), - }; - await registerUser(page.request, user); - const response = await forgotPassword(page.request, user.email); - const responseJson = await response.json(); - await expect(responseJson).toHaveProperty('emailUrl'); - await page.goto(responseJson.emailUrl); + test('user should receive an email when forgot password is triggered', async ({ + page, + }) => { + const user = { + email: faker.internet.email(), + password: faker.internet.password(), + }; + await registerUser(page.request, user); + const response = await forgotPassword(page.request, user.email); + const responseJson = await response.json(); + await expect(responseJson).toHaveProperty('emailUrl'); + await page.goto(responseJson.emailUrl); - await expect(page).toHaveScreenshot('forgot-password-email.png', { - mask: [ - page.locator('.mp_address_group').nth(1), - page.locator('.datestring'), - // Message-ID - page.locator('#message-header div').nth(4).locator('span'), - page.frameLocator('#message iframe').locator('#email-placeholder'), - page.frameLocator('#message iframe').locator('#password-placeholder'), - ], - fullPage: true, - }); + await expect(page).toHaveScreenshot('forgot-password-email.png', { + mask: [ + page.locator('.mp_address_group').nth(1), + page.locator('.datestring'), + // Message-ID + page.locator('#message-header div').nth(4).locator('span'), + page.frameLocator('#message iframe').locator('#email-placeholder'), + page.frameLocator('#message iframe').locator('#password-placeholder'), + ], + fullPage: true, }); + }); - test('new user receives an email when invited to the group', async ({ - page, - }) => { - const groupData = await createNewGroup(page.request); + test('new user receives an email when invited to the group', async ({ + page, + }) => { + const groupData = await createNewGroup(page.request); - await login( - page.request, - groupData.users.admin.email, - groupData.users.admin.password - ); - const resultWithoutUrl = await inviteUserToGroup( - page.request, - faker.internet.email() - ); - const bodyWithoutUrl = await resultWithoutUrl.json(); - await expect(bodyWithoutUrl).not.toHaveProperty('emailUrl'); + await login( + page.request, + groupData.users.admin.email, + groupData.users.admin.password + ); + const resultWithoutUrl = await inviteUserToGroup( + page.request, + faker.internet.email() + ); + await expect(resultWithoutUrl).not.toHaveProperty('emailUrl'); - const updatedGroupData = { - name: groupData.group.name, - userAddedNotification: true, - messageSentNotification: false, - yearDraftedNotification: false, - }; - await updateGroup(page.request, updatedGroupData); + const updatedGroupData = { + name: groupData.group.name, + userAddedNotification: true, + messageSentNotification: false, + yearDraftedNotification: false, + }; + await updateGroup(page.request, updatedGroupData); - const resultWithUrl = await inviteUserToGroup( - page.request, - faker.internet.email() - ); - const bodyWithUrl = await resultWithUrl.json(); - await expect(bodyWithUrl).toHaveProperty('emailUrl'); - await page.goto(bodyWithUrl.emailUrl); + const resultWithUrl = await inviteUserToGroup( + page.request, + faker.internet.email() + ); + await expect(resultWithUrl).toHaveProperty('emailUrl'); + await page.goto(resultWithUrl.emailUrl); - await expect(page).toHaveScreenshot('invite-email.png', { - mask: [ - page.locator('.mp_address_group').nth(1), - page.locator('.datestring'), - // Message-ID - page.locator('#message-header div').nth(4).locator('span'), - page.frameLocator('#message iframe').locator('#group-placeholder'), - page.frameLocator('#message iframe').locator('#password-placeholder'), - ], - fullPage: true, - }); + await expect(page).toHaveScreenshot('invite-email.png', { + mask: [ + page.locator('.mp_address_group').nth(1), + page.locator('.datestring'), + // Message-ID + page.locator('#message-header div').nth(4).locator('span'), + page.frameLocator('#message iframe').locator('#group-placeholder'), + page.frameLocator('#message iframe').locator('#password-placeholder'), + ], + fullPage: true, }); + }); - test('existing user receives an email when invited to the group', async ({ - page, - }) => { - const groupData = await createNewGroup(page.request); - const user1 = faker.internet.email(); - const user2 = faker.internet.email(); - await registerUser(page.request, user1); - await registerUser(page.request, user2); + test('existing user receives an email when invited to the group', async ({ + page, + }) => { + const groupData = await createNewGroup(page.request); + const user1 = faker.internet.email(); + const user2 = faker.internet.email(); + await registerUser(page.request, user1); + await registerUser(page.request, user2); - await login( - page.request, - groupData.users.admin.email, - groupData.users.admin.password - ); - const resultWithoutUrl = await inviteUserToGroup(page.request, user1); - const bodyWithoutUrl = await resultWithoutUrl.json(); - await expect(bodyWithoutUrl).not.toHaveProperty('emailUrl'); + await login( + page.request, + groupData.users.admin.email, + groupData.users.admin.password + ); + const resultWithoutUrl = await inviteUserToGroup(page.request, user1); + await expect(resultWithoutUrl).not.toHaveProperty('emailUrl'); - const updatedGroupData = { - name: groupData.group.name, - userAddedNotification: true, - messageSentNotification: false, - yearDraftedNotification: false, - }; - await updateGroup(page.request, updatedGroupData); + const updatedGroupData = { + name: groupData.group.name, + userAddedNotification: true, + messageSentNotification: false, + yearDraftedNotification: false, + }; + await updateGroup(page.request, updatedGroupData); - const resultWithUrl = await inviteUserToGroup(page.request, user2); - const bodyWithUrl = await resultWithUrl.json(); - await expect(bodyWithUrl).toHaveProperty('emailUrl'); - await page.goto(bodyWithUrl.emailUrl); + const resultWithUrl = await inviteUserToGroup(page.request, user2); + await expect(resultWithUrl).toHaveProperty('emailUrl'); + await page.goto(resultWithUrl.emailUrl); - await expect(page).toHaveScreenshot('invite-email.png', { - mask: [ - page.locator('.mp_address_group').nth(1), - page.locator('.datestring'), - // Message-ID - page.locator('#message-header div').nth(4).locator('span'), - page.frameLocator('#message iframe').locator('#group-placeholder'), - page.frameLocator('#message iframe').locator('#password-placeholder'), - ], - fullPage: true, - }); + await expect(page).toHaveScreenshot('invite-email.png', { + mask: [ + page.locator('.mp_address_group').nth(1), + page.locator('.datestring'), + // Message-ID + page.locator('#message-header div').nth(4).locator('span'), + page.frameLocator('#message iframe').locator('#group-placeholder'), + page.frameLocator('#message iframe').locator('#password-placeholder'), + ], + fullPage: true, }); }); +}); - test.describe('chat tests', () => { - test('user should receive a chat email', async ({ page }) => { - const groupData = await createDraftedGroup(page.request); - const updatedGroupData = { - name: groupData.group.name, - userAddedNotification: false, - messageSentNotification: true, - yearDraftedNotification: false, - }; - await updateGroup(page.request, updatedGroupData); - await login( - page.request, - groupData.users.user1.email, - groupData.users.user1.password - ); - const message = { - userId: groupData.users.user2.id, - email: groupData.users.user2.email, - message: faker.word.words(10), - }; - const messageData = await sendMessage(page.request, message); - await page.goto(messageData.emailUrl); +test.describe('chat tests', () => { + test('user should receive a chat email', async ({ page }) => { + const defaultData = { + users: { + admin: { + email: faker.internet.email(), + password: 'test', + name: faker.person.fullName(), + address: { + street: faker.location.street(), + city: faker.location.city(), + postalCode: faker.location.zipCode(), + state: faker.location.state(), + }, + }, + user1: { + email: faker.internet.email(), + password: 'test', + name: faker.person.fullName(), + address: { + street: faker.location.street(), + city: faker.location.city(), + postalCode: faker.location.zipCode(), + state: faker.location.state(), + }, + }, + user2: { + email: faker.internet.email(), + password: 'test', + name: faker.person.fullName(), + address: { + street: faker.location.street(), + city: faker.location.city(), + postalCode: faker.location.zipCode(), + state: faker.location.state(), + }, + }, + }, + group: { + name: faker.word.noun(), + }, + }; + const groupData = await createDraftedGroup(page.request, defaultData); + const updatedGroupData = { + name: groupData.group.name, + userAddedNotification: false, + messageSentNotification: true, + yearDraftedNotification: false, + }; + await updateGroup(page.request, updatedGroupData); + await login( + page.request, + groupData.users.user1.email, + groupData.users.user1.password + ); + const message = { + userId: groupData.users.user2.id, + email: groupData.users.user2.email, + message: faker.word.words(10), + }; + const messageData = await sendMessage(page.request, message); + await page.goto(messageData.emailUrl); - await expect(page.locator('#message-header')).toContainText( - 'Secret Santa Question' - ); - await expect(page.locator('#message-header')).toContainText( - '' - ); - await expect(page.locator('#message-header')).toContainText( - message.email - ); - await expect( - page.frameLocator('#message iframe').locator('body') - ).toContainText(message.message); - }); + await expect(page.locator('#message-header')).toContainText( + 'Secret Santa Question' + ); + await expect(page.locator('#message-header')).toContainText( + '' + ); + await expect(page.locator('#message-header')).toContainText(message.email); + await expect( + page.frameLocator('#message iframe').locator('body') + ).toContainText(message.message); + }); - test('user should not receives a chat email', async ({ page }) => { - const groupData = await createDraftedGroup(page.request); - await login( - page.request, - groupData.users.user2.email, - groupData.users.user2.password - ); - const message = { - userId: groupData.users.user1.id, - email: groupData.users.user1.email, - message: faker.word.words(10), - }; - const messageData = await sendMessage(page.request, message); - await expect(messageData).not.toHaveProperty('emailUrl'); - }); + test('user should not receives a chat email', async ({ page }) => { + const defaultData = { + users: { + admin: { + email: faker.internet.email(), + password: 'test', + name: faker.person.fullName(), + address: { + street: faker.location.street(), + city: faker.location.city(), + postalCode: faker.location.zipCode(), + state: faker.location.state(), + }, + }, + user1: { + email: faker.internet.email(), + password: 'test', + name: faker.person.fullName(), + address: { + street: faker.location.street(), + city: faker.location.city(), + postalCode: faker.location.zipCode(), + state: faker.location.state(), + }, + }, + user2: { + email: faker.internet.email(), + password: 'test', + name: faker.person.fullName(), + address: { + street: faker.location.street(), + city: faker.location.city(), + postalCode: faker.location.zipCode(), + state: faker.location.state(), + }, + }, + }, + group: { + name: faker.word.noun(), + }, + }; + const groupData = await createNewGroup(page.request, defaultData); + await login( + page.request, + groupData.users.user2.email, + groupData.users.user2.password + ); + const message = { + userId: groupData.users.user1.id, + email: groupData.users.user1.email, + message: faker.word.words(10), + }; + const messageData = await sendMessage(page.request, message); + await expect(messageData).toHaveProperty('success'); + await expect(messageData).not.toHaveProperty('emailUrl'); }); }); diff --git a/tests/helpers/admin.js b/tests/helpers/admin.js index 85df87f..b4794ea 100644 --- a/tests/helpers/admin.js +++ b/tests/helpers/admin.js @@ -11,18 +11,34 @@ export function updateGroup(request, groupData) { } export function inviteUserToGroup(request, email) { - return request.post('admin/api/user', { - form: { email }, - }); + return request + .post('admin/api/user', { + form: { email }, + }) + .then((result) => { + return result.json(); + }); } export function draftSantaPairs(request) { - return request.put('admin/api/draft'); + return request.put('admin/api/draft').then((result) => { + return result.json(); + }); } export function addForbiddenPair(request, forbiddenPair) { - return request.post('admin/api/forbidden', { - form: forbiddenPair, + return request + .post('admin/api/forbidden', { + form: forbiddenPair, + }) + .then((result) => { + return result.json(); + }); +} + +export function removeForbiddenPair(request, forbiddenPairId) { + return request.post('admin/api/forbidden/delete', { + data: { _id: forbiddenPairId }, }); } diff --git a/tests/helpers/setup.js b/tests/helpers/setup.js index 610356f..7a301f7 100644 --- a/tests/helpers/setup.js +++ b/tests/helpers/setup.js @@ -7,8 +7,8 @@ import { import { faker } from '@faker-js/faker'; import { login, registerUser } from './login.js'; -export async function createNewGroup(request) { - const groupData = { +export function getDefaultData() { + return { users: { admin: { email: faker.internet.email(), @@ -48,20 +48,25 @@ export async function createNewGroup(request) { name: faker.word.noun(), }, }; - const adminData = await registerUser(request, groupData.users.admin); - groupData.users.admin.id = adminData.id; - const user1Data = await registerUser(request, groupData.users.user1); - groupData.users.user1.id = user1Data.id; - const user2Data = await registerUser(request, groupData.users.user2); - groupData.users.user2.id = user2Data.id; +} + +export async function createNewGroup(request, groupData = getDefaultData()) { + for (let user in groupData.users) { + const userData = await registerUser(request, groupData.users[user]); + groupData.users[user].id = userData.id; + } await login( request, groupData.users.admin.email, groupData.users.admin.password ); await createGroup(request, groupData.group.name); - await inviteUserToGroup(request, groupData.users.user1.email); - await inviteUserToGroup(request, groupData.users.user2.email); + for (let user in groupData.users) { + if (user === 'admin') { + continue; + } + await inviteUserToGroup(request, groupData.users[user].email); + } return groupData; } diff --git a/utils/adminPipeline.js b/utils/adminPipeline.js index 37c4be6..b08ae7d 100644 --- a/utils/adminPipeline.js +++ b/utils/adminPipeline.js @@ -17,7 +17,6 @@ export async function getUsers(groupId) { return await client.collection('users').find(query, options).toArray(); } catch (err) { log.error('getUsers: ' + err); - await client.close(); return null; } } @@ -48,7 +47,6 @@ export async function getUsersAndRoles(groupId) { return await client.collection('users').aggregate(pipeline).toArray(); } catch (err) { log.error('getUsersAndRoles: ' + err); - await client.close(); return null; } } @@ -61,7 +59,6 @@ export async function checkIfUserExists(email) { return await client.collection('users').findOne(query); } catch (err) { log.error('checkIfUserExists: ' + err); - await client.close(); return null; } } @@ -84,7 +81,6 @@ export async function addUserToGroup(groupId, email, role) { return true; } catch (err) { log.error('addUserToGroup: ' + err); - await client.close(); return null; } } @@ -109,7 +105,6 @@ export async function removeUserFromGroup(userId, groupId) { return true; } catch (err) { log.error('removeUserFromGroup: ' + err); - await client.close(); return null; } } @@ -127,7 +122,6 @@ export async function addNewUser(groupId, email, password) { return await client.collection('users').insertOne(user); } catch (err) { log.error('addNewUser: ' + err); - await client.close(); return null; } } @@ -138,7 +132,6 @@ export async function createNewUser(user) { return await client.collection('users').insertOne(user); } catch (err) { log.error('createNewUser: ' + err); - await client.close(); return null; } } @@ -163,7 +156,6 @@ export async function updateUsersRoles(groupId, usersRoles) { return modifiedCount; } catch (err) { log.error('updateUsersRoles: ' + err); - await client.close(); return null; } } @@ -176,7 +168,6 @@ export async function getGroup(groupId) { return await client.collection('groups').findOne(query); } catch (err) { log.error('getGroup: ' + err); - await client.close(); return null; } } @@ -201,7 +192,6 @@ export async function createGroup(groupName) { return group; } catch (err) { log.error('createGroup: ' + err); - await client.close(); return null; } } @@ -217,20 +207,18 @@ export async function updateGroup(groupId, groupData) { return await client.collection('groups').updateOne(filter, update); } catch (err) { log.error('updateGroup: ' + err); - await client.close(); return null; } } export async function deleteForbiddenPair(_id) { const client = await getClient(); - const filter = { _id: _id }; + const filter = { _id: ObjectId.createFromHexString(_id) }; try { return await client.collection('forbiddenPairs').deleteOne(filter); } catch (err) { log.error('deleteForbiddenPair: ' + err); - await client.close(); return null; } } @@ -278,7 +266,6 @@ export async function getForbiddenPairs(groupId) { .toArray(); } catch (err) { log.error('getForbiddenPairs: ' + err); - await client.close(); return null; } } @@ -288,8 +275,7 @@ export async function createForbiddenPair(groupId, forbiddenPair) { try { const existingPair = await findExistingPair(client, groupId, forbiddenPair); if (existingPair) { - // Forbidden pair already exists, handle accordingly - return { error: 'Forbidden pair already exists.' }; + return { error: 'Forbidden pair already exists' }; } const document = { @@ -303,7 +289,6 @@ export async function createForbiddenPair(groupId, forbiddenPair) { return await client.collection('forbiddenPairs').insertOne(document); } catch (err) { log.error('createForbiddenPair: ' + err); - await client.close(); return null; } } diff --git a/utils/chatPipeline.js b/utils/chatPipeline.js index 574ff19..49ad1d5 100644 --- a/utils/chatPipeline.js +++ b/utils/chatPipeline.js @@ -42,7 +42,6 @@ export async function getChat(groupId) { return await client.collection('chat').aggregate(pipeline).toArray(); } catch (err) { log.error('getChat: ' + err); - await client.close(); return null; } } @@ -55,7 +54,6 @@ export async function deleteChatMessage(_id) { return await client.collection('chat').deleteOne(filter); } catch (err) { log.error('deleteChatMessage: ' + err); - await client.close(); return null; } } @@ -72,7 +70,6 @@ export async function sendMessage(message, userId, groupId) { return await client.collection('chat').insertOne(document); } catch (err) { log.error('sendMessage: ' + err); - await client.close(); return null; } } diff --git a/utils/drafter.js b/utils/drafter.js index 1c49bdb..5948169 100644 --- a/utils/drafter.js +++ b/utils/drafter.js @@ -1,3 +1,5 @@ +import { ObjectId } from 'mongodb'; + export function draftPairs(users, forbiddenPairs) { // prepare a drafting bucket of friends const friends = []; @@ -6,15 +8,19 @@ export function draftPairs(users, forbiddenPairs) { const santaPairs = new Map(); users.forEach((user) => { - friends.push(user._id); + friends.push(user._id.toString()); }); // transform array of forbidden pairs into a map, for ease of use forbiddenPairs.forEach((pair) => { if (forbiddenPairsMap.get(pair.userId) === undefined) { - forbiddenPairsMap.set(pair.userId, [pair.forbiddenPairId]); + forbiddenPairsMap.set(pair.userId.toString(), [ + pair.forbiddenPairId.toString(), + ]); } else { - forbiddenPairsMap.get(pair.userId).push(pair.forbiddenPairId); + forbiddenPairsMap + .get(pair.userId.toString()) + .push(pair.forbiddenPairId.toString()); } }); @@ -58,7 +64,10 @@ export function draftPairs(users, forbiddenPairs) { friends.splice(index, 1); // add the two pairs in the santaPairs list - santaPairs.set(santa, child); + santaPairs.set( + ObjectId.createFromHexString(santa), + ObjectId.createFromHexString(child) + ); // now a child gets to be santa santa = child; @@ -78,7 +87,9 @@ export function draftPairs(users, forbiddenPairs) { return null; } - santaPairs.set(santa, first); - + santaPairs.set( + ObjectId.createFromHexString(santa), + ObjectId.createFromHexString(first) + ); return santaPairs; } diff --git a/utils/friendsPipeline.js b/utils/friendsPipeline.js index 8be02e2..42287d4 100644 --- a/utils/friendsPipeline.js +++ b/utils/friendsPipeline.js @@ -13,7 +13,6 @@ export async function getFriends(groupId) { return await client.collection('users').find(query, options).toArray(); } catch (err) { log.error('getFriends: ' + err); - await client.close(); return null; } } @@ -31,7 +30,6 @@ export async function getProfile(_id) { return await client.collection('users').findOne(query, options); } catch (err) { log.error('getProfile: ' + err); - await client.close(); return null; } } @@ -51,7 +49,6 @@ export async function updateProfile(_id, friend) { return await client.collection('users').updateOne(filter, update); } catch (err) { log.error('updateProfile: ' + err); - await client.close(); return null; } } @@ -69,7 +66,6 @@ export async function updateProfileImage(_id) { return await client.collection('users').updateOne(filter, update); } catch (err) { log.error('updateProfileImage: ' + err); - await client.close(); return null; } } diff --git a/utils/historyPipeline.js b/utils/historyPipeline.js index 763c2fb..a0706c7 100644 --- a/utils/historyPipeline.js +++ b/utils/historyPipeline.js @@ -28,7 +28,6 @@ export async function getYearsByGroup(groupId) { return await client.collection('history').aggregate(pipeline).toArray(); } catch (err) { log.error('getYearsByGroup: ' + err); - await client.close(); return null; } } @@ -108,7 +107,6 @@ export async function getGiftsByYear(groupId, yearId) { return await client.collection('history').aggregate(pipeline).toArray(); } catch (err) { log.error('getClient: ' + err); - await client.close(); return null; } } @@ -139,7 +137,6 @@ export async function addDraftsForNextYear(groupId, santaPairs) { return await client.collection('history').insertOne(document); } catch (err) { log.error('addDraftsForNextYear: ' + err); - await client.close(); return null; } } @@ -157,7 +154,6 @@ export async function isNextYearDrafted(groupId) { return !result; } catch (err) { log.error('isNextYearDrafted: ' + err); - await client.close(); return null; } } @@ -178,7 +174,6 @@ export async function isLastYearRevealed(groupId) { return result?.revealed; } catch (err) { log.error('isLastYearRevealed: ' + err); - await client.close(); return null; } } @@ -195,7 +190,6 @@ export async function setLastYearRevealed(groupId, year) { return await client.collection('history').updateOne(filter, update); } catch (err) { log.error('setLastYearRevealed: ' + err); - await client.close(); return null; } } @@ -213,7 +207,6 @@ export async function updateLocationImage(yearId) { return await client.collection('history').updateOne(filter, update); } catch (err) { log.error('updateLocationImage: ' + err); - await client.close(); return null; } } @@ -234,7 +227,6 @@ export async function updateGiftImage(yearId, giftId) { return await client.collection('history').updateOne(filter, update); } catch (err) { log.error('updateGiftImage: ' + err); - await client.close(); return null; } } @@ -252,7 +244,6 @@ export async function updateGiftDescription(giftId, description) { return await client.collection('history').updateOne(filter, update); } catch (err) { log.error('updateGiftDescription: ' + err); - await client.close(); return null; } } @@ -270,7 +261,6 @@ export async function updateYearDescription(yearId, description) { return await client.collection('history').updateOne(filter, update); } catch (err) { log.error('updateYearDescription: ' + err); - await client.close(); return null; } } diff --git a/utils/loginPipeline.js b/utils/loginPipeline.js index d2de975..39dbf24 100644 --- a/utils/loginPipeline.js +++ b/utils/loginPipeline.js @@ -29,7 +29,6 @@ export async function checkEmail(email) { return await client.collection('users').findOne(query, options); } catch (err) { log.error('checkEmail: ' + err); - await client.close(); return null; } } @@ -105,7 +104,6 @@ async function getUser($match) { return await client.collection('users').aggregate(pipeline).toArray(); } catch (err) { log.error('getUser: ' + err); - await client.close(); return null; } } diff --git a/utils/santaPipeline.js b/utils/santaPipeline.js index 0e2aa26..e98496c 100644 --- a/utils/santaPipeline.js +++ b/utils/santaPipeline.js @@ -54,7 +54,6 @@ export async function getSanta(_id, groupId) { return await client.collection('history').aggregate(pipeline).toArray(); } catch (err) { log.error('getSanta: ' + err); - await client.close(); return null; } }