diff --git a/Dockerfile b/Dockerfile index 4e22a60c..8e4a3cd6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ COPY . . RUN npm ci FROM base AS test -CMD [ "npx", "jest", "--coverage" ] +CMD [ "npx", "jest", "--detectOpenHandles", "--coverage" ] FROM base AS build RUN npm run build diff --git a/__tests__/integration/announcement.test.ts b/__tests__/integration/announcement.test.ts index ae630da8..be2b42b8 100644 --- a/__tests__/integration/announcement.test.ts +++ b/__tests__/integration/announcement.test.ts @@ -1,522 +1,522 @@ -// /* eslint-disable @typescript-eslint/no-explicit-any */ -// import request from 'supertest'; -// import httpStatus from 'http-status'; -// import app from '../../src/app'; -// import setupTestDB, { cleanUpTenantDatabases } from '../utils/setupTestDB'; -// import { userOne, insertUsers, userTwo } from '../fixtures/user.fixture'; -// import { userOneAccessToken } from '../fixtures/token.fixture'; -// import { communityOne, communityTwo, communityThree, insertCommunities } from '../fixtures/community.fixture'; -// import { -// generatePublicDiscordAnnouncement, -// generatePrivateRoleDiscordAnnouncement, -// generatePrivateUserDiscordAnnouncement, -// insertAnnouncement, -// } from '../fixtures/announcement.fixture'; -// import { discordChannel3, discordChannel4, insertChannels } from '../fixtures/discord/channels.fixture'; -// import { Connection } from 'mongoose'; -// import { DatabaseManager } from '@togethercrew.dev/db'; -// import { insertPlatforms, platformOne } from '../fixtures/platform.fixture'; -// import { discordGuildMember1, discordGuildMember2, insertGuildMembers } from '../fixtures/discord/guildMember.fixture'; -// import platform from '../../src/middlewares/platform'; - -// setupTestDB(); - -// describe('Community routes', () => { -// const announcementOne = generatePublicDiscordAnnouncement(communityOne._id, platformOne._id, [ -// discordChannel4.channelId, -// discordChannel3.channelId, -// ]); -// const announcementTwo = generatePrivateUserDiscordAnnouncement(communityOne._id, platformOne._id, [ -// discordGuildMember1.discordId, -// discordGuildMember2.discordId, -// ]); -// const announcementThree = generatePrivateRoleDiscordAnnouncement(communityThree._id, platformOne._id, [ -// userOne._id, -// userTwo._id, -// ]); - -// let connection: Connection; -// beforeAll(async () => { -// connection = await DatabaseManager.getInstance().getTenantDb(platformOne.metadata?.id); -// }); - -// afterAll(async () => { -// await connection.close(); -// }); - -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// userOne.communities = [communityOne._id, communityTwo._id]; -// userTwo.communities = [communityThree._id]; -// communityOne.users = [userOne._id]; -// communityTwo.users = [userOne._id]; -// communityThree.users = [userTwo._id]; -// }); - -// describe('POST api/v1/announcements', () => { -// // TODO: maybe we need to mock bullMQ or delete the job after the test -// // eslint-disable-next-line @typescript-eslint/no-explicit-any -// let newDraftAnnouncement: any; -// const nowDate = new Date(); -// const nextMonthDate = new Date(); -// nextMonthDate.setMonth(nowDate.getMonth() + 1); -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// }); -// test('should return 201 and successfully create a new draft announcement if data is ok', async () => { -// platformOne.community = communityOne._id; -// communityOne.platforms = [platformOne._id]; -// await insertPlatforms([platformOne]); -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertChannels([discordChannel4, discordChannel3], connection); -// await insertGuildMembers([discordGuildMember1, discordGuildMember2], connection); - -// newDraftAnnouncement = { -// title: 'salam azzm', -// communityId: communityOne._id, -// scheduledAt: nextMonthDate.toISOString(), -// draft: true, -// data: [ -// { -// platformId: platformOne._id, -// template: 'sample template wo wo wo', -// options: { -// userIds: [discordGuildMember1.discordId, discordGuildMember2.discordId], -// }, -// }, -// ], -// }; - -// const res = await request(app) -// .post('/api/v1/announcements') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newDraftAnnouncement) -// .expect(httpStatus.CREATED); - -// expect(res.body).toEqual({ -// id: expect.anything(), -// community: userOne.communities?.[0].toString(), -// title: newDraftAnnouncement.title, -// scheduledAt: newDraftAnnouncement.scheduledAt, -// draft: newDraftAnnouncement.draft, -// data: newDraftAnnouncement.data.map((data: any) => { -// const { platformId, ...rest } = data; - -// return { -// ...rest, -// platform: platformOne._id.toString(), -// options: { -// users: [ -// { discordId: '123456789', ngu: 'Behzad', username: 'behzad_rabiei', avatar: null }, -// { discordId: '987654321', ngu: 'Daniel', avatar: 'AvatarLink', username: 'mrjackalop' }, -// ], -// }, -// type: 'discord_private', -// }; -// }), -// }); -// }); - -// test('should return 201 and successfully create a new scheduled announcement if data is ok', async () => { -// platformOne.community = communityOne._id; -// communityOne.platforms = [platformOne._id]; -// await insertPlatforms([platformOne]); -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertChannels([discordChannel4, discordChannel3], connection); -// await insertGuildMembers([discordGuildMember1, discordGuildMember2], connection); -// await insertAnnouncement([announcementOne, announcementTwo]); - -// const newAnnouncement = { -// title: 'salam azzm', -// communityId: communityOne._id, -// scheduledAt: nextMonthDate.toISOString(), -// draft: true, // TODO: change this to false when we found a solution for managing jobs after tests -// data: [ -// { -// platformId: platformOne._id, -// template: 'sample template wo wo wo', -// options: { -// userIds: [discordGuildMember1.discordId, discordGuildMember2.discordId], -// }, -// }, -// ], -// }; - -// const res = await request(app) -// .post('/api/v1/announcements') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newAnnouncement) -// .expect(httpStatus.CREATED); - -// expect(res.body).toEqual({ -// id: expect.anything(), -// community: userOne.communities?.[0].toString(), -// title: newAnnouncement.title, -// scheduledAt: newAnnouncement.scheduledAt, -// draft: newAnnouncement.draft, -// data: newDraftAnnouncement.data.map((data: any) => { -// const { platformId, ...rest } = data; - -// return { -// ...rest, -// platform: platformOne._id.toString(), -// options: { -// users: [ -// { discordId: '123456789', ngu: 'Behzad', username: 'behzad_rabiei', avatar: null }, -// { discordId: '987654321', ngu: 'Daniel', avatar: 'AvatarLink', username: 'mrjackalop' }, -// ], -// }, -// type: 'discord_private', -// }; -// }), -// }); -// }); - -// test('should return 400 error if scheduledAt is not a valid date (not greater than now)', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); - -// const lastMonthDate = new Date(); -// lastMonthDate.setMonth(nowDate.getMonth() - 1); -// const newAnnouncement = { -// title: 'salam azzm', -// communityId: userOne.communities?.[0], -// scheduledAt: lastMonthDate.toISOString(), -// draft: true, -// data: [ -// { -// platformId: '658d530d84267a217f988c73', -// template: 'sample template wo wo wo', -// options: { -// userIds: ['23', '23'], -// }, -// }, -// ], -// }; - -// await request(app) -// .post('/api/v1/announcements') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newAnnouncement) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('Should return 404 error if community is not found', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne, userTwo]); - -// const newAnnouncement = { -// title: 'salam azzm', -// communityId: '658d530d84267a217f988c73', -// scheduledAt: nextMonthDate.toISOString(), -// draft: true, -// data: [ -// { -// platformId: '658d530d84267a217f988c73', -// template: 'sample template wo wo wo', -// options: { -// userIds: ['23', '23'], -// }, -// }, -// ], -// }; - -// await request(app) -// .post('/api/v1/announcements') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newAnnouncement) -// .expect(httpStatus.NOT_FOUND); -// }); -// }); - -// describe('PATCH api/v1/announcements/:announcementId', () => { -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// }); -// test('should return 200 and successfully update announcement if data is ok', async () => { -// platformOne.community = communityOne._id; -// await insertPlatforms([platformOne]); -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertChannels([discordChannel4, discordChannel3], connection); -// await insertGuildMembers([discordGuildMember1, discordGuildMember2], connection); -// await insertAnnouncement([announcementOne, announcementTwo]); - -// const res = await request(app) -// .patch(`/api/v1/announcements/${announcementOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ title: 'Updated Announcement One - 1 is one' }) -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// id: announcementOne._id.toString(), -// title: 'Updated Announcement One - 1 is one', -// scheduledAt: announcementOne.scheduledAt.toISOString(), -// draft: false, -// data: announcementOne.data.map((data: any) => ({ -// ...data, -// platform: data.platform.toString(), -// options: { -// channels: [ -// { -// channelId: '345678901234567000', -// name: 'Channel 4', -// }, -// { -// channelId: '345678901234567890', -// name: 'Channel 3', -// }, -// ], -// }, -// })), -// community: userOne.communities?.[0].toString(), -// }); -// }); - -// test('should return 400 error if announcementId is not a valid mongo id', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertAnnouncement([announcementOne, announcementTwo, announcementThree]); - -// await request(app) -// .patch('/api/v1/announcements/invalidId') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ title: 'Updated Announcement One' }) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 404 error if announcement is not found', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne, userTwo]); - -// await request(app) -// .patch(`/api/v1/announcements/${announcementOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ title: 'Updated Announcement One' }) -// .expect(httpStatus.NOT_FOUND); -// }); - -// test('Should return 404 error if user is not a member of the requested community', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne, userTwo]); -// await insertAnnouncement([announcementOne, announcementTwo, announcementThree]); - -// await request(app) -// .patch(`/api/v1/announcements/${announcementThree._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ title: 'Updated Announcement One' }) -// .expect(httpStatus.NOT_FOUND); -// }); -// }); - -// describe('GET api/v1/announcements', () => { -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// }); -// test('should return 200 and successfully get announcements if data is ok', async () => { -// platformOne.community = communityOne._id; -// await insertPlatforms([platformOne]); -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertChannels([discordChannel4, discordChannel3], connection); -// await insertGuildMembers([discordGuildMember1, discordGuildMember2], connection); -// await insertAnnouncement([announcementOne, announcementTwo]); - -// const res = await request(app) -// .get('/api/v1/announcements') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ communityId: userOne.communities?.[0].toString() }) -// .expect(httpStatus.OK); - -// expect(res.body.results).toHaveLength(2); -// expect(res.body.results).toEqual([ -// { -// id: announcementTwo._id.toString(), -// title: 'Announcement Two', -// scheduledAt: announcementTwo.scheduledAt.toISOString(), -// draft: false, -// data: announcementTwo.data.map((data: any) => { -// const { platformId, ...rest } = data; - -// return { -// ...rest, -// platform: data.platform.toString(), -// options: { -// users: [ -// { discordId: '123456789', ngu: 'Behzad', username: 'behzad_rabiei', avatar: null }, -// { discordId: '987654321', ngu: 'Daniel', avatar: 'AvatarLink', username: 'mrjackalop' }, -// ], -// }, -// }; -// }), -// community: userOne.communities?.[0].toString(), -// }, -// { -// id: announcementOne._id.toString(), -// title: 'Announcement One', -// scheduledAt: announcementOne.scheduledAt.toISOString(), -// draft: false, -// data: announcementOne.data.map((data: any) => ({ -// ...data, -// platform: data.platform.toString(), -// options: { -// channels: [ -// { -// channelId: '345678901234567000', -// name: 'Channel 4', -// }, -// { -// channelId: '345678901234567890', -// name: 'Channel 3', -// }, -// ], -// }, -// })), -// community: userOne.communities?.[0].toString(), -// }, -// ]); -// expect(res.body.page).toEqual(1); -// expect(res.body.limit).toEqual(10); -// expect(res.body.totalPages).toEqual(1); -// expect(res.body.totalResults).toEqual(2); -// }); - -// test('should return 400 error if communityId is not a valid mongo id', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertAnnouncement([announcementOne, announcementTwo, announcementThree]); - -// await request(app) -// .get('/api/v1/announcements') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ communityId: communityOne._id }) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 404 error if community is not found', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne, userTwo]); - -// await request(app) -// .get('/api/v1/announcements') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ communityId: communityThree._id.toString() }) -// .expect(httpStatus.NOT_FOUND); -// }); - -// test('should return 401 error if access token is missing', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne, userTwo]); - -// await request(app) -// .get('/api/v1/announcements') -// .query({ communityId: communityOne._id.toString() }) -// .expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 401 error if access token is invalid', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne, userTwo]); - -// await request(app) -// .get('/api/v1/announcements') -// .set('Authorization', 'Bearer invalidtoken') -// .query({ communityId: communityOne._id.toString() }) -// .expect(httpStatus.UNAUTHORIZED); -// }); -// }); - -// describe('GET api/v1/announcements/:announcementId', () => { -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// }); -// test('should return 200 and successfully get announcement if data is ok', async () => { -// platformOne.community = communityOne._id; -// await insertPlatforms([platformOne]); -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertChannels([discordChannel4, discordChannel3], connection); -// await insertAnnouncement([announcementOne, announcementTwo]); - -// const res = await request(app) -// .get(`/api/v1/announcements/${announcementOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// id: announcementOne._id.toString(), -// title: 'Announcement One', -// scheduledAt: announcementOne.scheduledAt.toISOString(), -// draft: false, -// data: announcementOne.data.map((data: any) => ({ -// ...data, -// platform: data.platform.toString(), -// options: { -// channels: [ -// { -// channelId: '345678901234567000', -// name: 'Channel 4', -// }, -// { -// channelId: '345678901234567890', -// name: 'Channel 3', -// }, -// ], -// }, -// })), -// community: userOne.communities?.[0].toString(), -// }); -// }); - -// test('should return 400 error if announcementId is not a valid mongo id', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertAnnouncement([announcementOne, announcementTwo]); - -// await request(app) -// .get('/api/v1/announcements/invalidId') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 404 error if announcement is not found', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne, userTwo]); - -// await request(app) -// .get(`/api/v1/announcements/${announcementOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .expect(httpStatus.NOT_FOUND); -// }); - -// test('Should return 404 error if user is not a member of the requested community', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne, userTwo]); -// await insertAnnouncement([announcementOne, announcementTwo]); - -// await request(app) -// .get(`/api/v1/announcements/${announcementThree._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .expect(httpStatus.NOT_FOUND); -// }); - -// test('should return 401 error if access token is missing', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne, userTwo]); - -// await request(app).get(`/api/v1/announcements/${announcementOne._id}`).expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 401 error if access token is invalid', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne, userTwo]); - -// await request(app) -// .get(`/api/v1/announcements/${announcementOne._id}`) -// .set('Authorization', `Bearer invalidAccessToken`) -// .expect(httpStatus.UNAUTHORIZED); -// }); -// }); -// }); +/* eslint-disable @typescript-eslint/no-explicit-any */ +import request from 'supertest'; +import httpStatus from 'http-status'; +import app from '../../src/app'; +import setupTestDB, { cleanUpTenantDatabases } from '../utils/setupTestDB'; +import { userOne, insertUsers, userTwo } from '../fixtures/user.fixture'; +import { userOneAccessToken } from '../fixtures/token.fixture'; +import { communityOne, communityTwo, communityThree, insertCommunities } from '../fixtures/community.fixture'; +import { + generatePublicDiscordAnnouncement, + generatePrivateRoleDiscordAnnouncement, + generatePrivateUserDiscordAnnouncement, + insertAnnouncement, +} from '../fixtures/announcement.fixture'; +import { discordChannel3, discordChannel4, insertChannels } from '../fixtures/discord/channels.fixture'; +import { Connection } from 'mongoose'; +import { DatabaseManager } from '@togethercrew.dev/db'; +import { insertPlatforms, platformOne } from '../fixtures/platform.fixture'; +import { discordGuildMember1, discordGuildMember2, insertGuildMembers } from '../fixtures/discord/guildMember.fixture'; +import platform from '../../src/middlewares/platform'; + +setupTestDB(); + +describe('Community routes', () => { + const announcementOne = generatePublicDiscordAnnouncement(communityOne._id, platformOne._id, [ + discordChannel4.channelId, + discordChannel3.channelId, + ]); + const announcementTwo = generatePrivateUserDiscordAnnouncement(communityOne._id, platformOne._id, [ + discordGuildMember1.discordId, + discordGuildMember2.discordId, + ]); + const announcementThree = generatePrivateRoleDiscordAnnouncement(communityThree._id, platformOne._id, [ + userOne._id, + userTwo._id, + ]); + + let connection: Connection; + beforeAll(async () => { + connection = await DatabaseManager.getInstance().getTenantDb(platformOne.metadata?.id); + }); + + afterAll(async () => { + await connection.close(); + }); + + beforeEach(async () => { + cleanUpTenantDatabases(); + userOne.communities = [communityOne._id, communityTwo._id]; + userTwo.communities = [communityThree._id]; + communityOne.users = [userOne._id]; + communityTwo.users = [userOne._id]; + communityThree.users = [userTwo._id]; + }); + + describe('POST api/v1/announcements', () => { + // TODO: maybe we need to mock bullMQ or delete the job after the test + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let newDraftAnnouncement: any; + const nowDate = new Date(); + const nextMonthDate = new Date(); + nextMonthDate.setMonth(nowDate.getMonth() + 1); + beforeEach(async () => { + cleanUpTenantDatabases(); + }); + test('should return 201 and successfully create a new draft announcement if data is ok', async () => { + platformOne.community = communityOne._id; + communityOne.platforms = [platformOne._id]; + await insertPlatforms([platformOne]); + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertChannels([discordChannel4, discordChannel3], connection); + await insertGuildMembers([discordGuildMember1, discordGuildMember2], connection); + + newDraftAnnouncement = { + title: 'salam azzm', + communityId: communityOne._id, + scheduledAt: nextMonthDate.toISOString(), + draft: true, + data: [ + { + platformId: platformOne._id, + template: 'sample template wo wo wo', + options: { + userIds: [discordGuildMember1.discordId, discordGuildMember2.discordId], + }, + }, + ], + }; + + const res = await request(app) + .post('/api/v1/announcements') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newDraftAnnouncement) + .expect(httpStatus.CREATED); + + expect(res.body).toEqual({ + id: expect.anything(), + community: userOne.communities?.[0].toString(), + title: newDraftAnnouncement.title, + scheduledAt: newDraftAnnouncement.scheduledAt, + draft: newDraftAnnouncement.draft, + data: newDraftAnnouncement.data.map((data: any) => { + const { platformId, ...rest } = data; + + return { + ...rest, + platform: platformOne._id.toString(), + options: { + users: [ + { discordId: '123456789', ngu: 'Behzad', username: 'behzad_rabiei', avatar: null }, + { discordId: '987654321', ngu: 'Daniel', avatar: 'AvatarLink', username: 'mrjackalop' }, + ], + }, + type: 'discord_private', + }; + }), + }); + }); + + test('should return 201 and successfully create a new scheduled announcement if data is ok', async () => { + platformOne.community = communityOne._id; + communityOne.platforms = [platformOne._id]; + await insertPlatforms([platformOne]); + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertChannels([discordChannel4, discordChannel3], connection); + await insertGuildMembers([discordGuildMember1, discordGuildMember2], connection); + await insertAnnouncement([announcementOne, announcementTwo]); + + const newAnnouncement = { + title: 'salam azzm', + communityId: communityOne._id, + scheduledAt: nextMonthDate.toISOString(), + draft: true, // TODO: change this to false when we found a solution for managing jobs after tests + data: [ + { + platformId: platformOne._id, + template: 'sample template wo wo wo', + options: { + userIds: [discordGuildMember1.discordId, discordGuildMember2.discordId], + }, + }, + ], + }; + + const res = await request(app) + .post('/api/v1/announcements') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newAnnouncement) + .expect(httpStatus.CREATED); + + expect(res.body).toEqual({ + id: expect.anything(), + community: userOne.communities?.[0].toString(), + title: newAnnouncement.title, + scheduledAt: newAnnouncement.scheduledAt, + draft: newAnnouncement.draft, + data: newDraftAnnouncement.data.map((data: any) => { + const { platformId, ...rest } = data; + + return { + ...rest, + platform: platformOne._id.toString(), + options: { + users: [ + { discordId: '123456789', ngu: 'Behzad', username: 'behzad_rabiei', avatar: null }, + { discordId: '987654321', ngu: 'Daniel', avatar: 'AvatarLink', username: 'mrjackalop' }, + ], + }, + type: 'discord_private', + }; + }), + }); + }); + + test('should return 400 error if scheduledAt is not a valid date (not greater than now)', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + + const lastMonthDate = new Date(); + lastMonthDate.setMonth(nowDate.getMonth() - 1); + const newAnnouncement = { + title: 'salam azzm', + communityId: userOne.communities?.[0], + scheduledAt: lastMonthDate.toISOString(), + draft: true, + data: [ + { + platformId: '658d530d84267a217f988c73', + template: 'sample template wo wo wo', + options: { + userIds: ['23', '23'], + }, + }, + ], + }; + + await request(app) + .post('/api/v1/announcements') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newAnnouncement) + .expect(httpStatus.BAD_REQUEST); + }); + + test('Should return 404 error if community is not found', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne, userTwo]); + + const newAnnouncement = { + title: 'salam azzm', + communityId: '658d530d84267a217f988c73', + scheduledAt: nextMonthDate.toISOString(), + draft: true, + data: [ + { + platformId: '658d530d84267a217f988c73', + template: 'sample template wo wo wo', + options: { + userIds: ['23', '23'], + }, + }, + ], + }; + + await request(app) + .post('/api/v1/announcements') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newAnnouncement) + .expect(httpStatus.NOT_FOUND); + }); + }); + + describe('PATCH api/v1/announcements/:announcementId', () => { + beforeEach(async () => { + cleanUpTenantDatabases(); + }); + test('should return 200 and successfully update announcement if data is ok', async () => { + platformOne.community = communityOne._id; + await insertPlatforms([platformOne]); + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertChannels([discordChannel4, discordChannel3], connection); + await insertGuildMembers([discordGuildMember1, discordGuildMember2], connection); + await insertAnnouncement([announcementOne, announcementTwo]); + + const res = await request(app) + .patch(`/api/v1/announcements/${announcementOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ title: 'Updated Announcement One - 1 is one' }) + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + id: announcementOne._id.toString(), + title: 'Updated Announcement One - 1 is one', + scheduledAt: announcementOne.scheduledAt.toISOString(), + draft: false, + data: announcementOne.data.map((data: any) => ({ + ...data, + platform: data.platform.toString(), + options: { + channels: [ + { + channelId: '345678901234567000', + name: 'Channel 4', + }, + { + channelId: '345678901234567890', + name: 'Channel 3', + }, + ], + }, + })), + community: userOne.communities?.[0].toString(), + }); + }); + + test('should return 400 error if announcementId is not a valid mongo id', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertAnnouncement([announcementOne, announcementTwo, announcementThree]); + + await request(app) + .patch('/api/v1/announcements/invalidId') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ title: 'Updated Announcement One' }) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 404 error if announcement is not found', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne, userTwo]); + + await request(app) + .patch(`/api/v1/announcements/${announcementOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ title: 'Updated Announcement One' }) + .expect(httpStatus.NOT_FOUND); + }); + + test('Should return 404 error if user is not a member of the requested community', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne, userTwo]); + await insertAnnouncement([announcementOne, announcementTwo, announcementThree]); + + await request(app) + .patch(`/api/v1/announcements/${announcementThree._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ title: 'Updated Announcement One' }) + .expect(httpStatus.NOT_FOUND); + }); + }); + + describe('GET api/v1/announcements', () => { + beforeEach(async () => { + cleanUpTenantDatabases(); + }); + test('should return 200 and successfully get announcements if data is ok', async () => { + platformOne.community = communityOne._id; + await insertPlatforms([platformOne]); + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertChannels([discordChannel4, discordChannel3], connection); + await insertGuildMembers([discordGuildMember1, discordGuildMember2], connection); + await insertAnnouncement([announcementOne, announcementTwo]); + + const res = await request(app) + .get('/api/v1/announcements') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ communityId: userOne.communities?.[0].toString() }) + .expect(httpStatus.OK); + + expect(res.body.results).toHaveLength(2); + expect(res.body.results).toEqual([ + { + id: announcementTwo._id.toString(), + title: 'Announcement Two', + scheduledAt: announcementTwo.scheduledAt.toISOString(), + draft: false, + data: announcementTwo.data.map((data: any) => { + const { platformId, ...rest } = data; + + return { + ...rest, + platform: data.platform.toString(), + options: { + users: [ + { discordId: '123456789', ngu: 'Behzad', username: 'behzad_rabiei', avatar: null }, + { discordId: '987654321', ngu: 'Daniel', avatar: 'AvatarLink', username: 'mrjackalop' }, + ], + }, + }; + }), + community: userOne.communities?.[0].toString(), + }, + { + id: announcementOne._id.toString(), + title: 'Announcement One', + scheduledAt: announcementOne.scheduledAt.toISOString(), + draft: false, + data: announcementOne.data.map((data: any) => ({ + ...data, + platform: data.platform.toString(), + options: { + channels: [ + { + channelId: '345678901234567000', + name: 'Channel 4', + }, + { + channelId: '345678901234567890', + name: 'Channel 3', + }, + ], + }, + })), + community: userOne.communities?.[0].toString(), + }, + ]); + expect(res.body.page).toEqual(1); + expect(res.body.limit).toEqual(10); + expect(res.body.totalPages).toEqual(1); + expect(res.body.totalResults).toEqual(2); + }); + + test('should return 400 error if communityId is not a valid mongo id', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertAnnouncement([announcementOne, announcementTwo, announcementThree]); + + await request(app) + .get('/api/v1/announcements') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ communityId: communityOne._id }) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 404 error if community is not found', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne, userTwo]); + + await request(app) + .get('/api/v1/announcements') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ communityId: communityThree._id.toString() }) + .expect(httpStatus.NOT_FOUND); + }); + + test('should return 401 error if access token is missing', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne, userTwo]); + + await request(app) + .get('/api/v1/announcements') + .query({ communityId: communityOne._id.toString() }) + .expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 401 error if access token is invalid', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne, userTwo]); + + await request(app) + .get('/api/v1/announcements') + .set('Authorization', 'Bearer invalidtoken') + .query({ communityId: communityOne._id.toString() }) + .expect(httpStatus.UNAUTHORIZED); + }); + }); + + describe('GET api/v1/announcements/:announcementId', () => { + beforeEach(async () => { + cleanUpTenantDatabases(); + }); + test('should return 200 and successfully get announcement if data is ok', async () => { + platformOne.community = communityOne._id; + await insertPlatforms([platformOne]); + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertChannels([discordChannel4, discordChannel3], connection); + await insertAnnouncement([announcementOne, announcementTwo]); + + const res = await request(app) + .get(`/api/v1/announcements/${announcementOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + id: announcementOne._id.toString(), + title: 'Announcement One', + scheduledAt: announcementOne.scheduledAt.toISOString(), + draft: false, + data: announcementOne.data.map((data: any) => ({ + ...data, + platform: data.platform.toString(), + options: { + channels: [ + { + channelId: '345678901234567000', + name: 'Channel 4', + }, + { + channelId: '345678901234567890', + name: 'Channel 3', + }, + ], + }, + })), + community: userOne.communities?.[0].toString(), + }); + }); + + test('should return 400 error if announcementId is not a valid mongo id', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertAnnouncement([announcementOne, announcementTwo]); + + await request(app) + .get('/api/v1/announcements/invalidId') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 404 error if announcement is not found', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne, userTwo]); + + await request(app) + .get(`/api/v1/announcements/${announcementOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .expect(httpStatus.NOT_FOUND); + }); + + test('Should return 404 error if user is not a member of the requested community', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne, userTwo]); + await insertAnnouncement([announcementOne, announcementTwo]); + + await request(app) + .get(`/api/v1/announcements/${announcementThree._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .expect(httpStatus.NOT_FOUND); + }); + + test('should return 401 error if access token is missing', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne, userTwo]); + + await request(app).get(`/api/v1/announcements/${announcementOne._id}`).expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 401 error if access token is invalid', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne, userTwo]); + + await request(app) + .get(`/api/v1/announcements/${announcementOne._id}`) + .set('Authorization', `Bearer invalidAccessToken`) + .expect(httpStatus.UNAUTHORIZED); + }); + }); +}); diff --git a/__tests__/integration/auth.test.ts b/__tests__/integration/auth.test.ts index 886a0e16..1633c38d 100644 --- a/__tests__/integration/auth.test.ts +++ b/__tests__/integration/auth.test.ts @@ -1,123 +1,123 @@ -// import request from 'supertest'; -// import httpStatus from 'http-status'; -// import moment from 'moment'; -// import app from '../../src/app'; -// import config from '../../src/config'; -// import { tokenService } from '../../src/services'; -// import setupTestDB from '../utils/setupTestDB'; -// import { tokenTypes } from '../../src/config/tokens'; -// import { userOne, insertUsers } from '../fixtures/user.fixture'; -// import { Token } from '@togethercrew.dev/db'; - -// setupTestDB(); - -// describe('Auth routes', () => { -// describe('POST /api/v1/auth/logout', () => { -// test('should return 204 if refresh token is valid', async () => { -// await insertUsers([userOne]); -// const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); -// const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); -// await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH); - -// await request(app).post('/api/v1/auth/logout').send({ refreshToken }).expect(httpStatus.NO_CONTENT); - -// const dbRefreshTokenDoc = await Token.findOne({ token: refreshToken }); -// expect(dbRefreshTokenDoc).toBe(null); -// }); - -// test('should return 404 error if refresh token is not found in the database', async () => { -// await insertUsers([userOne]); -// const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); -// const refreshToken = tokenService.generateToken(userOne, expires, tokenTypes.REFRESH); - -// await request(app).post('/api/v1/auth/logout').send({ refreshToken }).expect(httpStatus.NOT_FOUND); -// }); - -// test('should return 404 error if refresh token is blacklisted', async () => { -// await insertUsers([userOne]); -// const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); -// const refreshToken = tokenService.generateToken(userOne, expires, tokenTypes.REFRESH); -// await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH, true); - -// await request(app).post('/api/v1/auth/logout').send({ refreshToken }).expect(httpStatus.NOT_FOUND); -// }); - -// test('should return 400 if refresh token does not send', async () => { -// await request(app).post('/api/v1/auth/logout').send().expect(httpStatus.BAD_REQUEST); -// }); -// }); - -// describe('POST /api/v1/auth/refresh-tokens', () => { -// test('should return 200 and new auth tokens if refresh token is valid', async () => { -// await insertUsers([userOne]); -// const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); -// const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); -// await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH); - -// const res = await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// access: { token: expect.anything(), expires: expect.anything() }, -// refresh: { token: expect.anything(), expires: expect.anything() }, -// }); - -// const dbRefreshTokenDoc = await Token.findOne({ token: res.body.refresh.token }); -// expect(dbRefreshTokenDoc).toMatchObject({ type: tokenTypes.REFRESH, user: userOne._id, blacklisted: false }); - -// const dbRefreshTokenCount = await Token.countDocuments(); -// expect(dbRefreshTokenCount).toBe(1); -// }); - -// test('should return 401 error if refresh token is signed using an invalid secret', async () => { -// await insertUsers([userOne]); -// const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); -// const refreshToken = tokenService.generateToken( -// { ...userOne, id: userOne._id }, -// expires, -// tokenTypes.REFRESH, -// 'invalidSecret', -// ); -// await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH); - -// await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 401 error if refresh token is not found in the database', async () => { -// await insertUsers([userOne]); -// const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); -// const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); - -// await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 401 error if refresh token is blacklisted', async () => { -// await insertUsers([userOne]); -// const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); -// const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); -// await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH, true); - -// await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 401 error if refresh token is expired', async () => { -// await insertUsers([userOne]); -// const expires = moment().subtract(1, 'minutes'); -// const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); -// await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH); - -// await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 401 error if user is not found', async () => { -// const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); -// const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); -// await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH); - -// await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 400 if refresh token does not send', async () => { -// await request(app).post('/api/v1/auth/refresh-tokens').send().expect(httpStatus.BAD_REQUEST); -// }); -// }); -// }); +import request from 'supertest'; +import httpStatus from 'http-status'; +import moment from 'moment'; +import app from '../../src/app'; +import config from '../../src/config'; +import { tokenService } from '../../src/services'; +import setupTestDB from '../utils/setupTestDB'; +import { tokenTypes } from '../../src/config/tokens'; +import { userOne, insertUsers } from '../fixtures/user.fixture'; +import { Token } from '@togethercrew.dev/db'; + +setupTestDB(); + +describe('Auth routes', () => { + describe('POST /api/v1/auth/logout', () => { + test('should return 204 if refresh token is valid', async () => { + await insertUsers([userOne]); + const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); + const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); + await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH); + + await request(app).post('/api/v1/auth/logout').send({ refreshToken }).expect(httpStatus.NO_CONTENT); + + const dbRefreshTokenDoc = await Token.findOne({ token: refreshToken }); + expect(dbRefreshTokenDoc).toBe(null); + }); + + test('should return 404 error if refresh token is not found in the database', async () => { + await insertUsers([userOne]); + const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); + const refreshToken = tokenService.generateToken(userOne, expires, tokenTypes.REFRESH); + + await request(app).post('/api/v1/auth/logout').send({ refreshToken }).expect(httpStatus.NOT_FOUND); + }); + + test('should return 404 error if refresh token is blacklisted', async () => { + await insertUsers([userOne]); + const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); + const refreshToken = tokenService.generateToken(userOne, expires, tokenTypes.REFRESH); + await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH, true); + + await request(app).post('/api/v1/auth/logout').send({ refreshToken }).expect(httpStatus.NOT_FOUND); + }); + + test('should return 400 if refresh token does not send', async () => { + await request(app).post('/api/v1/auth/logout').send().expect(httpStatus.BAD_REQUEST); + }); + }); + + describe('POST /api/v1/auth/refresh-tokens', () => { + test('should return 200 and new auth tokens if refresh token is valid', async () => { + await insertUsers([userOne]); + const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); + const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); + await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH); + + const res = await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.OK); + + expect(res.body).toEqual({ + access: { token: expect.anything(), expires: expect.anything() }, + refresh: { token: expect.anything(), expires: expect.anything() }, + }); + + const dbRefreshTokenDoc = await Token.findOne({ token: res.body.refresh.token }); + expect(dbRefreshTokenDoc).toMatchObject({ type: tokenTypes.REFRESH, user: userOne._id, blacklisted: false }); + + const dbRefreshTokenCount = await Token.countDocuments(); + expect(dbRefreshTokenCount).toBe(1); + }); + + test('should return 401 error if refresh token is signed using an invalid secret', async () => { + await insertUsers([userOne]); + const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); + const refreshToken = tokenService.generateToken( + { ...userOne, id: userOne._id }, + expires, + tokenTypes.REFRESH, + 'invalidSecret', + ); + await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH); + + await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 401 error if refresh token is not found in the database', async () => { + await insertUsers([userOne]); + const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); + const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); + + await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 401 error if refresh token is blacklisted', async () => { + await insertUsers([userOne]); + const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); + const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); + await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH, true); + + await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 401 error if refresh token is expired', async () => { + await insertUsers([userOne]); + const expires = moment().subtract(1, 'minutes'); + const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); + await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH); + + await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 401 error if user is not found', async () => { + const expires = moment().add(config.jwt.refreshExpirationDays, 'days'); + const refreshToken = tokenService.generateToken({ ...userOne, id: userOne._id }, expires, tokenTypes.REFRESH); + await tokenService.saveToken(refreshToken, userOne._id, expires, tokenTypes.REFRESH); + + await request(app).post('/api/v1/auth/refresh-tokens').send({ refreshToken }).expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 400 if refresh token does not send', async () => { + await request(app).post('/api/v1/auth/refresh-tokens').send().expect(httpStatus.BAD_REQUEST); + }); + }); +}); diff --git a/__tests__/integration/community.test.ts b/__tests__/integration/community.test.ts index 7d2a7342..2a4bccfd 100644 --- a/__tests__/integration/community.test.ts +++ b/__tests__/integration/community.test.ts @@ -1,451 +1,451 @@ -// import request from 'supertest'; -// import httpStatus from 'http-status'; -// import app from '../../src/app'; -// import setupTestDB from '../utils/setupTestDB'; -// import { userOne, insertUsers, userTwo } from '../fixtures/user.fixture'; -// import { userOneAccessToken } from '../fixtures/token.fixture'; -// import { User, Community, ICommunityUpdateBody } from '@togethercrew.dev/db'; -// import { communityOne, communityTwo, communityThree, insertCommunities } from '../fixtures/community.fixture'; - -// setupTestDB(); - -// describe('Community routes', () => { -// beforeEach(() => { -// userOne.communities = [communityOne._id, communityTwo._id]; -// userTwo.communities = [communityThree._id]; -// communityOne.users = [userOne._id]; -// communityTwo.users = [userOne._id]; -// communityThree.users = [userTwo._id]; -// }); - -// describe('POST api/v1/communities', () => { -// // eslint-disable-next-line @typescript-eslint/no-explicit-any -// let newCommunity: any; -// const currentDate = new Date(); - -// beforeEach(() => { -// newCommunity = { -// name: 'Community A', -// avatarURL: 'path', -// tcaAt: currentDate, -// }; -// }); - -// test('should return 201 and successfully create new community if data is ok', async () => { -// await insertUsers([userOne]); - -// const res = await request(app) -// .post(`/api/v1/communities`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newCommunity) -// .expect(httpStatus.CREATED); - -// expect(res.body).toEqual({ -// id: expect.anything(), -// name: newCommunity.name, -// avatarURL: newCommunity.avatarURL, -// users: [userOne._id.toHexString()], -// platforms: [], -// tcaAt: currentDate.toISOString(), -// }); - -// const dbCommunity = await Community.findById(res.body.id); -// expect(dbCommunity).toBeDefined(); -// expect(dbCommunity).toMatchObject({ -// name: newCommunity.name, -// avatarURL: newCommunity.avatarURL, -// users: [userOne._id], -// tcaAt: newCommunity.tcaAt, -// }); - -// const dbUser = await User.findById(userOne._id); -// expect(dbUser?.communities?.map(String)).toEqual(expect.arrayContaining([res.body.id])); -// }); - -// test('should return 401 error if access token is missing', async () => { -// await request(app).post(`/api/v1/communities`).send(newCommunity).expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 400 error if name is invalid', async () => { -// await insertUsers([userOne]); - -// await request(app) -// .post(`/api/v1/communities`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ name: 1 }) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if avatarURL is invalid', async () => { -// await insertUsers([userOne]); -// await request(app) -// .post(`/api/v1/communities`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ name: '1', avatarURL: 1 }) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if tcaAt is invalid', async () => { -// await insertUsers([userOne]); -// await request(app) -// .post(`/api/v1/communities`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ name: '1', tcaAt: 'tcaAt' }) -// .expect(httpStatus.BAD_REQUEST); -// }); -// }); - -// describe('GET /api/v1/communities', () => { -// test('should return 200 and apply the default query options', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); - -// const res = await request(app) -// .get('/api/v1/communities') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(2); - -// expect(res.body.results[0]).toMatchObject({ -// id: communityTwo._id.toHexString(), -// name: communityTwo.name, -// users: [userOne._id.toHexString()], -// platforms: [], -// }); -// expect(res.body.results[1]).toMatchObject({ -// id: communityOne._id.toHexString(), -// name: communityOne.name, -// avatarURL: communityOne.avatarURL, -// users: [userOne._id.toHexString()], -// platforms: [], -// }); -// }); - -// test('should return 401 if access token is missing', async () => { -// await insertUsers([userOne]); - -// await request(app).get('/api/v1/communities').send().expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should correctly apply filter on name field', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); - -// const res = await request(app) -// .get('/api/v1/communities') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ name: communityTwo.name }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 1, -// }); -// expect(res.body.results).toHaveLength(1); -// expect(res.body.results[0].id).toBe(communityTwo._id.toHexString()); -// }); - -// test('should correctly sort the returned array if descending sort param is specified', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); - -// const res = await request(app) -// .get('/api/v1/communities') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ sortBy: 'name:desc' }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(2); -// expect(res.body.results[0].id).toBe(communityTwo._id.toHexString()); -// expect(res.body.results[1].id).toBe(communityOne._id.toHexString()); -// }); - -// test('should correctly sort the returned array if ascending sort param is specified', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); - -// const res = await request(app) -// .get('/api/v1/communities') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ sortBy: 'name:asc' }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(2); -// expect(res.body.results[0].id).toBe(communityOne._id.toHexString()); -// expect(res.body.results[1].id).toBe(communityTwo._id.toHexString()); -// }); - -// test('should limit returned array if limit param is specified', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); - -// const res = await request(app) -// .get('/api/v1/communities') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ limit: 1 }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 1, -// totalPages: 2, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(1); -// expect(res.body.results[0].id).toBe(communityTwo._id.toHexString()); -// }); - -// test('should return the correct page if page and limit params are specified', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); - -// const res = await request(app) -// .get('/api/v1/communities') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ page: 2, limit: 1 }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 2, -// limit: 1, -// totalPages: 2, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(1); -// expect(res.body.results[0].id).toBe(communityOne._id.toHexString()); -// }); -// }); - -// describe('GET /api/v1/communities/:communityId', () => { -// test('should return 200 and the community object if data is ok', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); - -// const res = await request(app) -// .get(`/api/v1/communities/${communityOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// id: communityOne._id.toHexString(), -// name: communityOne.name, -// avatarURL: communityOne.avatarURL, -// users: [userOne._id.toHexString()], -// platforms: [], -// }); -// }); - -// test('should return 401 error if access token is missing', async () => { -// await insertUsers([userOne]); - -// await request(app).get(`/api/v1/communities/${communityOne._id}`).send().expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 404 when user trys to access community they don not belong to', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await request(app) -// .get(`/api/v1/communities/${communityThree._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.NOT_FOUND); -// }); - -// test('should return 400 error if communityId is not a valid mongo id', async () => { -// await insertUsers([userOne]); -// await request(app) -// .get(`/api/v1/communities/invalid`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 404 error if community is not found', async () => { -// await insertUsers([userOne]); -// await request(app) -// .get(`/api/v1/communities/${communityOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.NOT_FOUND); -// }); -// }); - -// describe('PATCH /api/v1/communities/:communityId', () => { -// let updateBody: ICommunityUpdateBody; -// const currentDate = new Date(); - -// beforeEach(() => { -// updateBody = { -// name: 'Community A', -// avatarURL: 'path', -// tcaAt: currentDate, -// }; -// }); -// test('should return 200 and successfully update community if data is ok', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// const res = await request(app) -// .patch(`/api/v1/communities/${communityOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.OK); - -// expect(res.body).toMatchObject({ -// id: communityOne._id.toHexString(), -// name: updateBody.name, -// avatarURL: updateBody.avatarURL, -// tcaAt: currentDate.toISOString(), -// }); - -// const dbCommunity = await Community.findById(communityOne._id); -// expect(dbCommunity).toBeDefined(); -// expect(dbCommunity).toMatchObject({ -// name: updateBody.name, -// avatarURL: updateBody.avatarURL, -// tcaAt: updateBody.tcaAt, -// }); -// }); - -// test('should return 401 error if access token is missing', async () => { -// await insertUsers([userOne]); - -// await request(app) -// .patch(`/api/v1/communities/${communityOne._id}`) -// .send(updateBody) -// .expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 404 when user trys to update community they don not belong to', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); - -// await request(app) -// .patch(`/api/v1/communities/${communityThree._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.NOT_FOUND); -// }); - -// test('should return 400 error if communityId is not a valid mongo id', async () => { -// await insertUsers([userOne]); - -// await request(app) -// .patch(`/api/v1/communities/invalid`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.BAD_REQUEST); -// }); -// test('should return 400 error if name is invalid', async () => { -// await insertUsers([userOne]); -// await request(app) -// .patch(`/api/v1/communities/${communityOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ name: 1 }) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if avatarURL is invalid', async () => { -// await insertUsers([userOne]); -// await request(app) -// .patch(`/api/v1/communities/${communityOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ name: '1', avatarURL: 1 }) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if tcaAt is invalid', async () => { -// await insertUsers([userOne]); -// await request(app) -// .patch(`/api/v1/communities/${communityOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ name: '1', tcaAt: 'tcaAt' }) -// .expect(httpStatus.BAD_REQUEST); -// }); -// }); -// describe('DELETE /api/v1/communities/:communityId', () => { -// test('should return 204 if data is ok', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); - -// await request(app) -// .delete(`/api/v1/communities/${communityOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.NO_CONTENT); - -// const dbCommunity = await Community.findById(communityOne._id); -// expect(dbCommunity).toBeNull(); -// }); - -// test('should return 401 error if access token is missing', async () => { -// await insertUsers([userOne]); - -// await request(app).delete(`/api/v1/communities/${communityOne._id}`).send().expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 404 when user trys to delete community they don not belong to', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); - -// await request(app) -// .delete(`/api/v1/communities/${communityThree._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.NOT_FOUND); -// }); - -// test('should return 400 error if communityId is not a valid mongo id', async () => { -// await insertUsers([userOne]); - -// await request(app) -// .delete(`/api/v1/communities/invalid`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 404 error if community already is not found', async () => { -// await insertUsers([userOne]); - -// await request(app) -// .delete(`/api/v1/communities/${communityOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.NOT_FOUND); -// }); -// }); -// }); +import request from 'supertest'; +import httpStatus from 'http-status'; +import app from '../../src/app'; +import setupTestDB from '../utils/setupTestDB'; +import { userOne, insertUsers, userTwo } from '../fixtures/user.fixture'; +import { userOneAccessToken } from '../fixtures/token.fixture'; +import { User, Community, ICommunityUpdateBody } from '@togethercrew.dev/db'; +import { communityOne, communityTwo, communityThree, insertCommunities } from '../fixtures/community.fixture'; + +setupTestDB(); + +describe('Community routes', () => { + beforeEach(() => { + userOne.communities = [communityOne._id, communityTwo._id]; + userTwo.communities = [communityThree._id]; + communityOne.users = [userOne._id]; + communityTwo.users = [userOne._id]; + communityThree.users = [userTwo._id]; + }); + + describe('POST api/v1/communities', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let newCommunity: any; + const currentDate = new Date(); + + beforeEach(() => { + newCommunity = { + name: 'Community A', + avatarURL: 'path', + tcaAt: currentDate, + }; + }); + + test('should return 201 and successfully create new community if data is ok', async () => { + await insertUsers([userOne]); + + const res = await request(app) + .post(`/api/v1/communities`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newCommunity) + .expect(httpStatus.CREATED); + + expect(res.body).toEqual({ + id: expect.anything(), + name: newCommunity.name, + avatarURL: newCommunity.avatarURL, + users: [userOne._id.toHexString()], + platforms: [], + tcaAt: currentDate.toISOString(), + }); + + const dbCommunity = await Community.findById(res.body.id); + expect(dbCommunity).toBeDefined(); + expect(dbCommunity).toMatchObject({ + name: newCommunity.name, + avatarURL: newCommunity.avatarURL, + users: [userOne._id], + tcaAt: newCommunity.tcaAt, + }); + + const dbUser = await User.findById(userOne._id); + expect(dbUser?.communities?.map(String)).toEqual(expect.arrayContaining([res.body.id])); + }); + + test('should return 401 error if access token is missing', async () => { + await request(app).post(`/api/v1/communities`).send(newCommunity).expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 400 error if name is invalid', async () => { + await insertUsers([userOne]); + + await request(app) + .post(`/api/v1/communities`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ name: 1 }) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if avatarURL is invalid', async () => { + await insertUsers([userOne]); + await request(app) + .post(`/api/v1/communities`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ name: '1', avatarURL: 1 }) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if tcaAt is invalid', async () => { + await insertUsers([userOne]); + await request(app) + .post(`/api/v1/communities`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ name: '1', tcaAt: 'tcaAt' }) + .expect(httpStatus.BAD_REQUEST); + }); + }); + + describe('GET /api/v1/communities', () => { + test('should return 200 and apply the default query options', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + + const res = await request(app) + .get('/api/v1/communities') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(2); + + expect(res.body.results[0]).toMatchObject({ + id: communityTwo._id.toHexString(), + name: communityTwo.name, + users: [userOne._id.toHexString()], + platforms: [], + }); + expect(res.body.results[1]).toMatchObject({ + id: communityOne._id.toHexString(), + name: communityOne.name, + avatarURL: communityOne.avatarURL, + users: [userOne._id.toHexString()], + platforms: [], + }); + }); + + test('should return 401 if access token is missing', async () => { + await insertUsers([userOne]); + + await request(app).get('/api/v1/communities').send().expect(httpStatus.UNAUTHORIZED); + }); + + test('should correctly apply filter on name field', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + + const res = await request(app) + .get('/api/v1/communities') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ name: communityTwo.name }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 1, + }); + expect(res.body.results).toHaveLength(1); + expect(res.body.results[0].id).toBe(communityTwo._id.toHexString()); + }); + + test('should correctly sort the returned array if descending sort param is specified', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + + const res = await request(app) + .get('/api/v1/communities') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ sortBy: 'name:desc' }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(2); + expect(res.body.results[0].id).toBe(communityTwo._id.toHexString()); + expect(res.body.results[1].id).toBe(communityOne._id.toHexString()); + }); + + test('should correctly sort the returned array if ascending sort param is specified', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + + const res = await request(app) + .get('/api/v1/communities') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ sortBy: 'name:asc' }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(2); + expect(res.body.results[0].id).toBe(communityOne._id.toHexString()); + expect(res.body.results[1].id).toBe(communityTwo._id.toHexString()); + }); + + test('should limit returned array if limit param is specified', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + + const res = await request(app) + .get('/api/v1/communities') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ limit: 1 }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 1, + totalPages: 2, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(1); + expect(res.body.results[0].id).toBe(communityTwo._id.toHexString()); + }); + + test('should return the correct page if page and limit params are specified', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + + const res = await request(app) + .get('/api/v1/communities') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ page: 2, limit: 1 }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 2, + limit: 1, + totalPages: 2, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(1); + expect(res.body.results[0].id).toBe(communityOne._id.toHexString()); + }); + }); + + describe('GET /api/v1/communities/:communityId', () => { + test('should return 200 and the community object if data is ok', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + + const res = await request(app) + .get(`/api/v1/communities/${communityOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + id: communityOne._id.toHexString(), + name: communityOne.name, + avatarURL: communityOne.avatarURL, + users: [userOne._id.toHexString()], + platforms: [], + }); + }); + + test('should return 401 error if access token is missing', async () => { + await insertUsers([userOne]); + + await request(app).get(`/api/v1/communities/${communityOne._id}`).send().expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 404 when user trys to access community they don not belong to', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await request(app) + .get(`/api/v1/communities/${communityThree._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.NOT_FOUND); + }); + + test('should return 400 error if communityId is not a valid mongo id', async () => { + await insertUsers([userOne]); + await request(app) + .get(`/api/v1/communities/invalid`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 404 error if community is not found', async () => { + await insertUsers([userOne]); + await request(app) + .get(`/api/v1/communities/${communityOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.NOT_FOUND); + }); + }); + + describe('PATCH /api/v1/communities/:communityId', () => { + let updateBody: ICommunityUpdateBody; + const currentDate = new Date(); + + beforeEach(() => { + updateBody = { + name: 'Community A', + avatarURL: 'path', + tcaAt: currentDate, + }; + }); + test('should return 200 and successfully update community if data is ok', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + const res = await request(app) + .patch(`/api/v1/communities/${communityOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.OK); + + expect(res.body).toMatchObject({ + id: communityOne._id.toHexString(), + name: updateBody.name, + avatarURL: updateBody.avatarURL, + tcaAt: currentDate.toISOString(), + }); + + const dbCommunity = await Community.findById(communityOne._id); + expect(dbCommunity).toBeDefined(); + expect(dbCommunity).toMatchObject({ + name: updateBody.name, + avatarURL: updateBody.avatarURL, + tcaAt: updateBody.tcaAt, + }); + }); + + test('should return 401 error if access token is missing', async () => { + await insertUsers([userOne]); + + await request(app) + .patch(`/api/v1/communities/${communityOne._id}`) + .send(updateBody) + .expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 404 when user trys to update community they don not belong to', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + + await request(app) + .patch(`/api/v1/communities/${communityThree._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.NOT_FOUND); + }); + + test('should return 400 error if communityId is not a valid mongo id', async () => { + await insertUsers([userOne]); + + await request(app) + .patch(`/api/v1/communities/invalid`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.BAD_REQUEST); + }); + test('should return 400 error if name is invalid', async () => { + await insertUsers([userOne]); + await request(app) + .patch(`/api/v1/communities/${communityOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ name: 1 }) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if avatarURL is invalid', async () => { + await insertUsers([userOne]); + await request(app) + .patch(`/api/v1/communities/${communityOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ name: '1', avatarURL: 1 }) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if tcaAt is invalid', async () => { + await insertUsers([userOne]); + await request(app) + .patch(`/api/v1/communities/${communityOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ name: '1', tcaAt: 'tcaAt' }) + .expect(httpStatus.BAD_REQUEST); + }); + }); + describe('DELETE /api/v1/communities/:communityId', () => { + test('should return 204 if data is ok', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + + await request(app) + .delete(`/api/v1/communities/${communityOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.NO_CONTENT); + + const dbCommunity = await Community.findById(communityOne._id); + expect(dbCommunity).toBeNull(); + }); + + test('should return 401 error if access token is missing', async () => { + await insertUsers([userOne]); + + await request(app).delete(`/api/v1/communities/${communityOne._id}`).send().expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 404 when user trys to delete community they don not belong to', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + + await request(app) + .delete(`/api/v1/communities/${communityThree._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.NOT_FOUND); + }); + + test('should return 400 error if communityId is not a valid mongo id', async () => { + await insertUsers([userOne]); + + await request(app) + .delete(`/api/v1/communities/invalid`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 404 error if community already is not found', async () => { + await insertUsers([userOne]); + + await request(app) + .delete(`/api/v1/communities/${communityOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.NOT_FOUND); + }); + }); +}); diff --git a/__tests__/integration/heatmap.test.ts b/__tests__/integration/heatmap.test.ts index c415334e..188c371c 100644 --- a/__tests__/integration/heatmap.test.ts +++ b/__tests__/integration/heatmap.test.ts @@ -1,243 +1,243 @@ -// import request from 'supertest'; -// import httpStatus from 'http-status'; -// import app from '../../src/app'; -// import setupTestDB from '../utils/setupTestDB'; -// import { userOne, insertUsers } from '../fixtures/user.fixture'; -// import { userOneAccessToken } from '../fixtures/token.fixture'; -// import { -// heatmap1, -// heatmap2, -// heatmap3, -// heatmap4, -// heatmap5, -// heatmap6, -// heatmap7, -// heatmap8, -// insertHeatmaps, -// } from '../fixtures/heatmap.fixture'; -// import { communityOne, insertCommunities } from '../fixtures/community.fixture'; -// import { platformOne, insertPlatforms } from '../fixtures/platform.fixture'; -// import { DatabaseManager } from '@togethercrew.dev/db'; -// import { Connection } from 'mongoose'; - -// setupTestDB(); - -// describe('Heatmap routes', () => { -// beforeEach(() => { -// userOne.communities = [communityOne._id]; -// communityOne.users = [userOne._id]; -// communityOne.platforms = [platformOne._id]; -// platformOne.community = communityOne._id; -// }); -// describe('POST /api/v1/heatmaps/:platformId/heatmap-chart', () => { -// let requestBody: { -// startDate: Date; -// endDate: Date; -// timeZone: string; -// channelIds: Array; -// }; -// let connection: Connection; -// beforeEach(async () => { -// connection = await DatabaseManager.getInstance().getTenantDb(platformOne.metadata?.id); - -// await connection.dropDatabase(); -// requestBody = { -// startDate: new Date('2023-01-01'), -// endDate: new Date('2023-01-31'), -// timeZone: 'Universal', // 0 -// channelIds: ['1012430565959553148', '1012430565959553211', '1012430565959553149'], -// }; -// }); - -// test('should return 200 and filter heatmap chart base on date (universal timezone offset) if req data is ok', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertHeatmaps([heatmap1, heatmap2, heatmap5], connection); -// const res = await request(app) -// .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(requestBody) -// .expect(httpStatus.OK); - -// expect(res.body.length).toBe(168); -// expect(res.body[0]).toEqual([0, 1, 18]); -// expect(res.body[1]).toEqual([0, 2, 5]); -// expect(res.body[23]).toEqual([0, 24, 6]); - -// expect(res.body[27]).toEqual([1, 4, 12]); -// expect(res.body[47]).toEqual([1, 24, 9]); -// }); - -// test('should return 200 and filter heatmap chart base on date (positive timezone offset) if req data is ok', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertHeatmaps([heatmap1, heatmap2, heatmap5], connection); -// requestBody.timeZone = 'Asia/Tehran'; // +3:30 - -// const res = await request(app) -// .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(requestBody) -// .expect(httpStatus.OK); - -// expect(res.body.length).toBe(168); -// expect(res.body[3]).toEqual([0, 4, 18]); -// expect(res.body[4]).toEqual([0, 5, 5]); -// expect(res.body[26]).toEqual([1, 3, 6]); - -// expect(res.body[30]).toEqual([1, 7, 12]); -// expect(res.body[50]).toEqual([2, 3, 9]); -// }); - -// test('should return 200 and filter heatmap chart base on date (negative timezone offset) if req data is ok', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertHeatmaps([heatmap1, heatmap2, heatmap5], connection); -// requestBody.timeZone = 'Brazil/East'; // -3:30 - -// const res = await request(app) -// .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(requestBody) -// .expect(httpStatus.OK); - -// expect(res.body.length).toBe(168); -// expect(res.body[165]).toEqual([6, 22, 18]); -// expect(res.body[166]).toEqual([6, 23, 5]); -// expect(res.body[20]).toEqual([0, 21, 6]); - -// expect(res.body[24]).toEqual([1, 1, 12]); -// expect(res.body[44]).toEqual([1, 21, 9]); -// }); - -// test('should return 200 and filter heatmap chart base on date and channelId if req data is ok', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertHeatmaps([heatmap1, heatmap2, heatmap5], connection); -// requestBody.startDate = new Date('2023-01-20'); -// requestBody.endDate = new Date('2023-01-22'); -// requestBody.channelIds = ['1012430565959553148']; -// const res = await request(app) -// .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(requestBody) -// .expect(httpStatus.OK); - -// expect(res.body.length).toBe(168); -// expect(res.body[0]).toEqual([0, 1, 3]); -// expect(res.body[1]).toEqual([0, 2, 5]); -// expect(res.body[23]).toEqual([0, 24, 6]); - -// expect(res.body[27]).toEqual([1, 4, 0]); -// expect(res.body[47]).toEqual([1, 24, 0]); -// }); - -// test('should return 200 and empty chart data if channelIds is empty req data is ok', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertHeatmaps([heatmap1, heatmap2, heatmap5], connection); -// requestBody.startDate = new Date('2023-01-20'); -// requestBody.endDate = new Date('2023-01-22'); -// requestBody.channelIds = []; -// const res = await request(app) -// .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(requestBody) -// .expect(httpStatus.OK); - -// expect(res.body.length).toBe(168); - -// const valuePattern = expect.arrayContaining([expect.anything(), expect.anything(), 0]); -// expect(res.body).toEqual(expect.arrayContaining(Array(168).fill(valuePattern))); -// }); - -// test('should return 401 if access token is missing', async () => { -// await request(app) -// .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) -// .send(requestBody) -// .expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 404 if guild not found', async () => { -// await insertUsers([userOne]); -// await request(app) -// .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(requestBody) -// .expect(httpStatus.NOT_FOUND); -// }); -// }); - -// describe('POST /api/v1/heatmaps/:platformId/line-graph', () => { -// let connection: Connection; -// beforeEach(async () => { -// connection = await DatabaseManager.getInstance().getTenantDb(platformOne.metadata?.id); -// await connection.dropDatabase(); -// }); -// test('should return 200 and line graph data if req data is ok', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertHeatmaps([heatmap3, heatmap4, heatmap5, heatmap6, heatmap7, heatmap8], connection); - -// const res = await request(app) -// .post(`/api/v1/heatmaps/${platformOne._id}/line-graph`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ startDate: new Date('2023-04-01'), endDate: new Date('2023-04-07') }) -// .expect(httpStatus.OK); - -// expect(res.body).toMatchObject({ -// messages: 200, -// emojis: 100, -// msgPercentageChange: 100, -// emojiPercentageChange: 100, -// }); - -// expect(res.body.categories).toEqual(['01 Apr', '02 Apr', '03 Apr', '04 Apr', '05 Apr', '06 Apr', '07 Apr']); -// expect(res.body.series[0].name).toBe('emojis'); -// expect(res.body.series[1].name).toBe('messages'); -// expect(res.body.series[0].data).toEqual([888, 0, 0, 0, 0, 0, 100]); -// expect(res.body.series[1].data).toEqual([777, 0, 0, 0, 0, 0, 200]); -// }); - -// test('should return 200 and line graph data (testing for empty data) if req data is ok', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); - -// const res = await request(app) -// .post(`/api/v1/heatmaps/${platformOne._id}/line-graph`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ startDate: new Date('2021-02-21'), endDate: new Date('2022-02-24') }) -// .expect(httpStatus.OK); - -// expect(res.body).toMatchObject({ -// emojis: 0, -// messages: 0, -// msgPercentageChange: 0, -// emojiPercentageChange: 0, -// }); -// }); - -// test('should return 401 if access token is missing', async () => { -// await request(app) -// .post(`/api/v1/heatmaps/${platformOne._id}/line-graph`) -// .send({ startDate: new Date(), endDate: new Date() }) -// .expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 404 if guild not found', async () => { -// await insertUsers([userOne]); -// await request(app) -// .post(`/api/v1/heatmaps/${platformOne._id}/line-graph`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ startDate: new Date(), endDate: new Date() }) -// .expect(httpStatus.NOT_FOUND); -// }); -// }); -// }); +import request from 'supertest'; +import httpStatus from 'http-status'; +import app from '../../src/app'; +import setupTestDB from '../utils/setupTestDB'; +import { userOne, insertUsers } from '../fixtures/user.fixture'; +import { userOneAccessToken } from '../fixtures/token.fixture'; +import { + heatmap1, + heatmap2, + heatmap3, + heatmap4, + heatmap5, + heatmap6, + heatmap7, + heatmap8, + insertHeatmaps, +} from '../fixtures/heatmap.fixture'; +import { communityOne, insertCommunities } from '../fixtures/community.fixture'; +import { platformOne, insertPlatforms } from '../fixtures/platform.fixture'; +import { DatabaseManager } from '@togethercrew.dev/db'; +import { Connection } from 'mongoose'; + +setupTestDB(); + +describe('Heatmap routes', () => { + beforeEach(() => { + userOne.communities = [communityOne._id]; + communityOne.users = [userOne._id]; + communityOne.platforms = [platformOne._id]; + platformOne.community = communityOne._id; + }); + describe('POST /api/v1/heatmaps/:platformId/heatmap-chart', () => { + let requestBody: { + startDate: Date; + endDate: Date; + timeZone: string; + channelIds: Array; + }; + let connection: Connection; + beforeEach(async () => { + connection = await DatabaseManager.getInstance().getTenantDb(platformOne.metadata?.id); + + await connection.dropDatabase(); + requestBody = { + startDate: new Date('2023-01-01'), + endDate: new Date('2023-01-31'), + timeZone: 'Universal', // 0 + channelIds: ['1012430565959553148', '1012430565959553211', '1012430565959553149'], + }; + }); + + test('should return 200 and filter heatmap chart base on date (universal timezone offset) if req data is ok', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertHeatmaps([heatmap1, heatmap2, heatmap5], connection); + const res = await request(app) + .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(requestBody) + .expect(httpStatus.OK); + + expect(res.body.length).toBe(168); + expect(res.body[0]).toEqual([0, 1, 18]); + expect(res.body[1]).toEqual([0, 2, 5]); + expect(res.body[23]).toEqual([0, 24, 6]); + + expect(res.body[27]).toEqual([1, 4, 12]); + expect(res.body[47]).toEqual([1, 24, 9]); + }); + + test('should return 200 and filter heatmap chart base on date (positive timezone offset) if req data is ok', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertHeatmaps([heatmap1, heatmap2, heatmap5], connection); + requestBody.timeZone = 'Asia/Tehran'; // +3:30 + + const res = await request(app) + .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(requestBody) + .expect(httpStatus.OK); + + expect(res.body.length).toBe(168); + expect(res.body[3]).toEqual([0, 4, 18]); + expect(res.body[4]).toEqual([0, 5, 5]); + expect(res.body[26]).toEqual([1, 3, 6]); + + expect(res.body[30]).toEqual([1, 7, 12]); + expect(res.body[50]).toEqual([2, 3, 9]); + }); + + test('should return 200 and filter heatmap chart base on date (negative timezone offset) if req data is ok', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertHeatmaps([heatmap1, heatmap2, heatmap5], connection); + requestBody.timeZone = 'Brazil/East'; // -3:30 + + const res = await request(app) + .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(requestBody) + .expect(httpStatus.OK); + + expect(res.body.length).toBe(168); + expect(res.body[165]).toEqual([6, 22, 18]); + expect(res.body[166]).toEqual([6, 23, 5]); + expect(res.body[20]).toEqual([0, 21, 6]); + + expect(res.body[24]).toEqual([1, 1, 12]); + expect(res.body[44]).toEqual([1, 21, 9]); + }); + + test('should return 200 and filter heatmap chart base on date and channelId if req data is ok', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertHeatmaps([heatmap1, heatmap2, heatmap5], connection); + requestBody.startDate = new Date('2023-01-20'); + requestBody.endDate = new Date('2023-01-22'); + requestBody.channelIds = ['1012430565959553148']; + const res = await request(app) + .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(requestBody) + .expect(httpStatus.OK); + + expect(res.body.length).toBe(168); + expect(res.body[0]).toEqual([0, 1, 3]); + expect(res.body[1]).toEqual([0, 2, 5]); + expect(res.body[23]).toEqual([0, 24, 6]); + + expect(res.body[27]).toEqual([1, 4, 0]); + expect(res.body[47]).toEqual([1, 24, 0]); + }); + + test('should return 200 and empty chart data if channelIds is empty req data is ok', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertHeatmaps([heatmap1, heatmap2, heatmap5], connection); + requestBody.startDate = new Date('2023-01-20'); + requestBody.endDate = new Date('2023-01-22'); + requestBody.channelIds = []; + const res = await request(app) + .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(requestBody) + .expect(httpStatus.OK); + + expect(res.body.length).toBe(168); + + const valuePattern = expect.arrayContaining([expect.anything(), expect.anything(), 0]); + expect(res.body).toEqual(expect.arrayContaining(Array(168).fill(valuePattern))); + }); + + test('should return 401 if access token is missing', async () => { + await request(app) + .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) + .send(requestBody) + .expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 404 if guild not found', async () => { + await insertUsers([userOne]); + await request(app) + .post(`/api/v1/heatmaps/${platformOne._id}/heatmap-chart`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(requestBody) + .expect(httpStatus.NOT_FOUND); + }); + }); + + describe('POST /api/v1/heatmaps/:platformId/line-graph', () => { + let connection: Connection; + beforeEach(async () => { + connection = await DatabaseManager.getInstance().getTenantDb(platformOne.metadata?.id); + await connection.dropDatabase(); + }); + test('should return 200 and line graph data if req data is ok', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertHeatmaps([heatmap3, heatmap4, heatmap5, heatmap6, heatmap7, heatmap8], connection); + + const res = await request(app) + .post(`/api/v1/heatmaps/${platformOne._id}/line-graph`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ startDate: new Date('2023-04-01'), endDate: new Date('2023-04-07') }) + .expect(httpStatus.OK); + + expect(res.body).toMatchObject({ + messages: 200, + emojis: 100, + msgPercentageChange: 100, + emojiPercentageChange: 100, + }); + + expect(res.body.categories).toEqual(['01 Apr', '02 Apr', '03 Apr', '04 Apr', '05 Apr', '06 Apr', '07 Apr']); + expect(res.body.series[0].name).toBe('emojis'); + expect(res.body.series[1].name).toBe('messages'); + expect(res.body.series[0].data).toEqual([888, 0, 0, 0, 0, 0, 100]); + expect(res.body.series[1].data).toEqual([777, 0, 0, 0, 0, 0, 200]); + }); + + test('should return 200 and line graph data (testing for empty data) if req data is ok', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + + const res = await request(app) + .post(`/api/v1/heatmaps/${platformOne._id}/line-graph`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ startDate: new Date('2021-02-21'), endDate: new Date('2022-02-24') }) + .expect(httpStatus.OK); + + expect(res.body).toMatchObject({ + emojis: 0, + messages: 0, + msgPercentageChange: 0, + emojiPercentageChange: 0, + }); + }); + + test('should return 401 if access token is missing', async () => { + await request(app) + .post(`/api/v1/heatmaps/${platformOne._id}/line-graph`) + .send({ startDate: new Date(), endDate: new Date() }) + .expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 404 if guild not found', async () => { + await insertUsers([userOne]); + await request(app) + .post(`/api/v1/heatmaps/${platformOne._id}/line-graph`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ startDate: new Date(), endDate: new Date() }) + .expect(httpStatus.NOT_FOUND); + }); + }); +}); diff --git a/__tests__/integration/memberActivity.test.ts b/__tests__/integration/memberActivity.test.ts index 07958445..39617a6d 100644 --- a/__tests__/integration/memberActivity.test.ts +++ b/__tests__/integration/memberActivity.test.ts @@ -34,9 +34,6 @@ describe('member-activity routes', () => { beforeAll(async () => { connection = await DatabaseManager.getInstance().getTenantDb(platformOne.metadata?.id); }); - afterAll(async () => { - await connection.close(); - }); beforeEach(async () => { cleanUpTenantDatabases(); userOne.communities = [communityOne._id]; diff --git a/__tests__/integration/platform.test.ts b/__tests__/integration/platform.test.ts index 6370feeb..0736772d 100644 --- a/__tests__/integration/platform.test.ts +++ b/__tests__/integration/platform.test.ts @@ -1,1138 +1,1138 @@ -// import request from 'supertest'; -// import httpStatus from 'http-status'; -// import app from '../../src/app'; -// import setupTestDB, { cleanUpTenantDatabases } from '../utils/setupTestDB'; -// import { userOne, insertUsers, userTwo } from '../fixtures/user.fixture'; -// import { userOneAccessToken } from '../fixtures/token.fixture'; -// import { Platform, Community, IPlatformUpdateBody, DatabaseManager } from '@togethercrew.dev/db'; -// import { communityOne, communityTwo, communityThree, insertCommunities } from '../fixtures/community.fixture'; -// import { -// platformOne, -// platformTwo, -// platformThree, -// platformFour, -// platformFive, -// insertPlatforms, -// } from '../fixtures/platform.fixture'; -// import { discordRole1, discordRole2, discordRole3, discordRole4, insertRoles } from '../fixtures/discord/roles.fixture'; -// import { -// discordChannel1, -// discordChannel2, -// discordChannel3, -// discordChannel4, -// discordChannel5, -// insertChannels, -// } from '../fixtures/discord/channels.fixture'; -// import { -// discordGuildMember1, -// discordGuildMember2, -// discordGuildMember3, -// discordGuildMember4, -// insertGuildMembers, -// } from '../fixtures/discord/guildMember.fixture'; -// import { discordServices } from '../../src/services'; -// import { analyzerAction, analyzerWindow } from '../../src/config/analyzer.statics'; -// import { Connection } from 'mongoose'; -// import mongoose from 'mongoose'; - -// setupTestDB(); - -// describe('Platform routes', () => { -// let connection: Connection; -// beforeAll(async () => { -// connection = await DatabaseManager.getInstance().getTenantDb(platformOne.metadata?.id); -// }); -// afterAll(async () => { -// await connection.close(); -// }); -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// userOne.communities = [communityOne._id, communityTwo._id]; -// userTwo.communities = [communityThree._id]; - -// communityOne.users = [userOne._id]; -// communityTwo.users = [userOne._id]; -// communityThree.users = [userTwo._id]; - -// communityOne.platforms = [platformOne._id, platformTwo._id, platformFive._id]; -// communityTwo.platforms = [platformThree._id]; -// communityThree.platforms = [platformFour._id]; - -// platformOne.community = communityOne._id; -// platformTwo.community = communityOne._id; -// platformThree.community = communityTwo._id; -// platformFour.community = communityThree._id; -// platformFive.community = communityOne._id; -// }); -// describe('POST api/v1/platforms', () => { -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// }); -// // eslint-disable-next-line @typescript-eslint/no-explicit-any -// let newPlatform: any; - -// beforeEach(async () => { -// await connection.collection('connection-platform').deleteMany({}); -// newPlatform = { -// name: 'discord', -// community: communityOne._id, -// metadata: { -// id: '1234', -// name: 'guild', -// icon: 'path', -// }, -// }; -// }); - -// test('should return 201 and successfully create new platform if data is ok', async () => { -// userOne.communities = [communityOne._id]; -// communityOne.users = [userOne._id]; -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); - -// const res = await request(app) -// .post(`/api/v1/platforms`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newPlatform) -// .expect(httpStatus.CREATED); - -// expect(res.body).toEqual({ -// id: expect.anything(), -// name: newPlatform.name, -// metadata: { ...newPlatform.metadata, action: analyzerAction, window: analyzerWindow }, -// community: communityOne._id.toHexString(), -// disconnectedAt: null, -// connectedAt: expect.anything(), -// }); - -// const dbPlatform = await Platform.findById(res.body.id); -// expect(dbPlatform).toBeDefined(); -// expect(dbPlatform).toMatchObject({ -// name: newPlatform.name, -// metadata: newPlatform.metadata, -// }); - -// const dbCommunity = await Community.findById(res.body.community); -// expect(dbCommunity).toMatchObject({ -// id: communityOne._id.toHexString(), -// name: communityOne.name, -// avatarURL: communityOne.avatarURL, -// users: [userOne._id], -// }); -// }); - -// test('should return 201 and successfully connect a disconneced platform if data is ok', async () => { -// userOne.communities = [communityOne._id]; -// communityOne.users = [userOne._id]; -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// platformOne.disconnectedAt = new Date(); -// await insertPlatforms([platformOne]); -// platformOne.disconnectedAt = null; -// newPlatform.metadata.id = platformOne.metadata?.id; - -// const res = await request(app) -// .post(`/api/v1/platforms`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newPlatform) -// .expect(httpStatus.CREATED); - -// expect(res.body).toEqual({ -// id: expect.anything(), -// name: platformOne.name, -// metadata: platformOne.metadata, -// community: communityOne._id.toHexString(), -// disconnectedAt: null, -// connectedAt: expect.anything(), -// }); - -// const dbPlatform = await Platform.findById(res.body.id); -// expect(dbPlatform).toBeDefined(); -// expect(dbPlatform).toMatchObject({ -// name: platformOne.name, -// metadata: platformOne.metadata, -// disconnectedAt: null, -// }); -// }); - -// test('should return 401 error if access token is missing', async () => { -// await request(app).post(`/api/v1/platforms`).send(newPlatform).expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 400 error if user trys to connect a connected platform', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// newPlatform.metadata.id = platformOne.metadata?.id; -// const res = await request(app) -// .post(`/api/v1/platforms`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newPlatform) -// .expect(httpStatus.BAD_REQUEST); - -// expect(res.body.message).toBe('This Platform is already connected'); -// }); - -// test('should return 400 error if user trys to connect a same platform', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// const res = await request(app) -// .post(`/api/v1/platforms`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newPlatform) -// .expect(httpStatus.BAD_REQUEST); - -// expect(res.body.message).toBe('Only can connect one discord platform'); -// }); - -// test('should return 400 error if user trys to connect a platform which is already connected to another community', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne, userTwo]); -// if (platformFour.metadata) { -// platformFour.metadata.id = platformOne.metadata?.id; -// newPlatform.metadata.id = platformOne.metadata?.id; -// await insertPlatforms([platformFour]); -// platformFour.metadata.id = '681946187490000802'; -// } -// const res = await request(app) -// .post(`/api/v1/platforms`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newPlatform) -// .expect(httpStatus.BAD_REQUEST); - -// expect(res.body.message).toBe('This Platform is already connected to another community'); -// }); - -// test('should return 400 error if name is invalid', async () => { -// await insertUsers([userOne]); -// newPlatform.name = 'invalid'; -// await request(app) -// .post(`/api/v1/platforms`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newPlatform) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if community is invalid', async () => { -// await insertUsers([userOne]); -// newPlatform.community = 'invalid'; -// await request(app) -// .post(`/api/v1/platforms`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newPlatform) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if metadata is invalid based on the name field', async () => { -// await insertUsers([userOne]); -// newPlatform.metadata = { username: 'str' }; -// await request(app) -// .post(`/api/v1/platforms`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newPlatform) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if community is invalid', async () => { -// await insertUsers([userOne]); -// newPlatform.name = 'twitter'; -// await request(app) -// .post(`/api/v1/platforms`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(newPlatform) -// .expect(httpStatus.BAD_REQUEST); -// }); -// }); -// describe('GET /api/v1/platforms', () => { -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// }); -// test('should return 200 and apply the default query options', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); -// const res = await request(app) -// .get('/api/v1/platforms') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ community: communityOne._id.toHexString() }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(2); - -// expect(res.body.results[0]).toMatchObject({ -// id: platformTwo._id.toHexString(), -// name: platformTwo.name, -// metadata: platformTwo.metadata, -// community: communityOne._id.toHexString(), -// }); - -// expect(res.body.results[1]).toMatchObject({ -// id: platformOne._id.toHexString(), -// name: platformOne.name, -// metadata: platformOne.metadata, -// community: communityOne._id.toHexString(), -// }); -// }); - -// test('should return 401 if access token is missing', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); -// await request(app).get('/api/v1/platforms').send().expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should correctly apply filter on name field', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); -// const res = await request(app) -// .get('/api/v1/platforms') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ name: platformOne.name, community: communityOne._id.toHexString() }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(2); -// expect(res.body.results[0].id).toBe(platformTwo._id.toHexString()); -// expect(res.body.results[1].id).toBe(platformOne._id.toHexString()); -// }); - -// test('should correctly sort the returned array if descending sort param is specified', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); -// const res = await request(app) -// .get('/api/v1/platforms') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ sortBy: 'name:desc', community: communityOne._id.toHexString() }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(2); -// expect(res.body.results[0].id).toBe(platformOne._id.toHexString()); -// expect(res.body.results[1].id).toBe(platformTwo._id.toHexString()); -// }); - -// test('should correctly sort the returned array if ascending sort param is specified', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); -// const res = await request(app) -// .get('/api/v1/platforms') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ sortBy: 'name:asc', community: communityOne._id.toHexString() }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(2); -// expect(res.body.results[0].id).toBe(platformOne._id.toHexString()); -// expect(res.body.results[1].id).toBe(platformTwo._id.toHexString()); -// }); - -// test('should limit returned array if limit param is specified', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); -// const res = await request(app) -// .get('/api/v1/platforms') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ limit: 1, community: communityOne._id.toHexString() }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 1, -// totalPages: 2, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(1); -// expect(res.body.results[0].id).toBe(platformTwo._id.toHexString()); -// }); - -// test('should return the correct page if page and limit params are specified', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); -// const res = await request(app) -// .get('/api/v1/platforms') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ page: 2, limit: 1, community: communityOne._id.toHexString() }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 2, -// limit: 1, -// totalPages: 2, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(1); -// expect(res.body.results[0].id).toBe(platformOne._id.toHexString()); -// }); -// }); -// describe('GET /api/v1/platforms/:platformId', () => { -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// }); -// discordServices.coreService.getBotPermissions = jest.fn().mockReturnValue(['ViewChannel', 'ReadMessageHistory']); -// test('should return 200 and the platform object if data is ok', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); -// const res = await request(app) -// .get(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// id: expect.anything(), -// name: platformOne.name, -// metadata: { -// ...platformOne.metadata, -// permissions: { -// ReadData: { -// ViewChannel: true, -// ReadMessageHistory: true, -// }, -// Announcement: { -// ViewChannel: true, -// SendMessages: false, -// SendMessagesInThreads: false, -// CreatePublicThreads: false, -// CreatePrivateThreads: false, -// EmbedLinks: false, -// AttachFiles: false, -// MentionEveryone: false, -// Connect: false, -// }, -// }, -// }, -// community: communityOne._id.toHexString(), -// disconnectedAt: null, -// connectedAt: expect.anything(), -// }); -// }); - -// test('should return 401 error if access token is missing', async () => { -// await insertUsers([userOne]); - -// await request(app).get(`/api/v1/platforms/${platformOne._id}`).send().expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 404 when user trys to access platoform they does not belong to', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); - -// await request(app) -// .get(`/api/v1/platforms/${platformFour._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.NOT_FOUND); -// }); - -// test('should return 400 error if platformId is not a valid mongo id', async () => { -// await insertUsers([userOne, userTwo]); -// await request(app) -// .get(`/api/v1/platforms/invalid`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 404 error if platoform is not found', async () => { -// await insertUsers([userOne]); - -// await request(app) -// .get(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.NOT_FOUND); -// }); -// }); -// describe('PATCH /api/v1/platforms/:platformId', () => { -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// }); -// let updateBody: IPlatformUpdateBody; - -// beforeEach(() => { -// updateBody = { -// metadata: { -// selectedChannels: ['8765', '1234'], -// period: new Date(), -// analyzerStartedAt: new Date(), -// }, -// }; -// }); -// test('should return 200 and successfully update platform if data is ok', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// const res = await request(app) -// .patch(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// id: expect.anything(), -// name: platformOne.name, -// metadata: { -// id: platformOne.metadata?.id, -// selectedChannels: updateBody.metadata?.selectedChannels, -// period: updateBody.metadata?.period.toISOString(), -// analyzerStartedAt: expect.anything(), -// }, -// community: communityOne._id.toHexString(), -// disconnectedAt: null, -// connectedAt: expect.anything(), -// }); - -// const dbPlatform = await Platform.findById(res.body.id); -// expect(dbPlatform).toBeDefined(); -// expect(dbPlatform).toMatchObject({ -// name: platformOne.name, -// metadata: { -// id: platformOne.metadata?.id, -// selectedChannels: updateBody.metadata?.selectedChannels, -// period: updateBody.metadata?.period, -// analyzerStartedAt: expect.anything(), -// }, -// }); -// }); - -// test('should return 401 error if access token is missing', async () => { -// await insertUsers([userOne]); -// await request(app).patch(`/api/v1/platforms/${platformOne._id}`).send(updateBody).expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 404 when user trys to update platform they does not belong to', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); -// await request(app) -// .patch(`/api/v1/platforms/${platformFour._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.NOT_FOUND); -// }); - -// test('should return 400 error if platformId is not a valid mongo id', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await request(app) -// .patch(`/api/v1/platforms/invalid`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if metadata is invalid based on the name field', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// updateBody.metadata = { id: '1234' }; -// await request(app) -// .patch(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if metadata selectedChannels is invalid', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// updateBody.metadata = { selectedChannels: '1234' }; -// await request(app) -// .patch(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if metadata period is invalid', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// updateBody.metadata = { period: false }; -// await request(app) -// .patch(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if metadata analyzerStartedAt is invalid', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// updateBody.metadata = { analyzerStartedAt: true }; -// await request(app) -// .patch(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if isInprogress is true and user trys to update selectedChannel', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne]); -// if (platformOne.metadata) platformOne.metadata.isInProgress = true; -// await insertPlatforms([platformOne]); -// if (platformOne.metadata) platformOne.metadata.isInProgress = false; -// await request(app) -// .patch(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if isInprogress is true and user trys to update period', async () => { -// await insertCommunities([communityOne, communityTwo]); -// await insertUsers([userOne]); -// if (platformOne.metadata) platformOne.metadata.isInProgress = true; -// await insertPlatforms([platformOne]); -// if (platformOne.metadata) platformOne.metadata.isInProgress = false; -// await request(app) -// .patch(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.BAD_REQUEST); -// }); -// }); -// describe('DELETE /api/v1/platforms/:platformId', () => { -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// }); -// discordServices.coreService.leaveBotFromGuild = jest.fn().mockReturnValue(null); -// test('should return 204 and soft delete the platform is deleteType is soft', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); - -// await request(app) -// .delete(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ deleteType: 'soft' }) -// .expect(httpStatus.NO_CONTENT); - -// const dbPlatform = await Platform.findById(platformOne._id); -// expect(dbPlatform).toBeDefined(); -// expect(dbPlatform).toMatchObject({ -// disconnectedAt: expect.any(Date), -// }); -// }); - -// test('should return 204 and hard delete the platform is deleteType is hard', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); - -// const res = await request(app) -// .delete(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ deleteType: 'hard' }) -// .expect(httpStatus.NO_CONTENT); - -// const dbPlatform = await Platform.findById(res.body.id); -// expect(dbPlatform).toBeNull(); -// }); - -// test('should return 401 error if access token is missing', async () => { -// await insertUsers([userOne]); - -// await request(app).delete(`/api/v1/platforms/${platformOne._id}`).send().expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 404 when user trys to delete platform they does not belong to', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); - -// await request(app) -// .delete(`/api/v1/platforms/${platformFour._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ deleteType: 'hard' }) -// .expect(httpStatus.NOT_FOUND); -// }); - -// test('should return 400 error if platformId is not a valid mongo id', async () => { -// await insertUsers([userOne]); - -// await request(app) -// .delete(`/api/v1/platforms/invalid`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 404 error if platform already is not found', async () => { -// await insertUsers([userOne]); - -// await request(app) -// .delete(`/api/v1/platforms/${platformOne._id}`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send({ deleteType: 'hard' }) -// .expect(httpStatus.NOT_FOUND); -// }); -// }); -// describe('POST /:platformId/properties', () => { -// beforeEach(async () => { -// cleanUpTenantDatabases(); -// }); -// discordServices.coreService.getBotPermissions = jest.fn().mockReturnValue(['ViewChannel', 'ReadMessageHistory']); -// test('should return 200 and apply the default query options if requested property is discord-role', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); - -// const res = await request(app) -// .post(`/api/v1/platforms/${platformOne._id}/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ property: 'role' }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 3, -// }); -// expect(res.body.results).toHaveLength(3); - -// expect(res.body.results[0]).toMatchObject({ -// roleId: discordRole1.roleId, -// name: discordRole1.name, -// color: discordRole1.color, -// }); -// expect(res.body.results[1]).toMatchObject({ -// roleId: discordRole2.roleId, -// name: discordRole2.name, -// color: discordRole2.color, -// }); - -// expect(res.body.results[2]).toMatchObject({ -// roleId: discordRole3.roleId, -// name: discordRole3.name, -// color: discordRole3.color, -// }); -// }); - -// test('should correctly apply filter on name field if requested property is discord-role', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); - -// const res = await request(app) -// .post(`/api/v1/platforms/${platformOne._id}/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ property: 'role', name: 'Member' }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 1, -// }); -// expect(res.body.results).toHaveLength(1); -// expect(res.body.results[0].roleId).toBe(discordRole3.roleId); -// }); - -// test('should correctly sort the returned array if descending sort param is specified and requested property is discord-role', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); - -// const res = await request(app) -// .post(`/api/v1/platforms/${platformOne._id}/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ property: 'role', sortBy: 'name:desc' }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 3, -// }); -// expect(res.body.results).toHaveLength(3); -// expect(res.body.results[0].roleId).toBe(discordRole2.roleId); -// expect(res.body.results[1].roleId).toBe(discordRole3.roleId); -// expect(res.body.results[2].roleId).toBe(discordRole1.roleId); -// }); - -// test('should correctly sort the returned array if ascending sort param is specified and requested property is discord-role', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); - -// const res = await request(app) -// .post(`/api/v1/platforms/${platformOne._id}/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ property: 'role', sortBy: 'name:asc' }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 3, -// }); -// expect(res.body.results).toHaveLength(3); -// expect(res.body.results[0].roleId).toBe(discordRole1.roleId); -// expect(res.body.results[1].roleId).toBe(discordRole3.roleId); -// expect(res.body.results[2].roleId).toBe(discordRole2.roleId); -// }); - -// test('should limit returned array if limit param is specified and requested property is discord-role', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); - -// const res = await request(app) -// .post(`/api/v1/platforms/${platformOne._id}/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ property: 'role', limit: 1 }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 1, -// totalPages: 3, -// totalResults: 3, -// }); -// expect(res.body.results).toHaveLength(1); -// expect(res.body.results[0].roleId).toBe(discordRole1.roleId); -// }); - -// test('should return the correct page if page and limit params are specified and requested property is discord-role', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); - -// const res = await request(app) -// .post(`/api/v1/platforms/${platformOne._id}/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ property: 'role', page: 2, limit: 1 }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 2, -// limit: 1, -// totalPages: 3, -// totalResults: 3, -// }); -// expect(res.body.results).toHaveLength(1); -// expect(res.body.results[0].roleId).toBe(discordRole2.roleId); -// }); - -// // test('should return 200 and channels data if requested property is discord-channel', async () => { -// // await insertCommunities([communityOne]); -// // await insertUsers([userOne]); -// // await insertPlatforms([platformOne]); -// // await insertChannels([discordChannel1, discordChannel2, discordChannel3, discordChannel4, discordChannel5], connection) - -// // const res = await request(app) -// // .post(`/api/v1/platforms/${platformOne._id}/properties`) -// // .set('Authorization', `Bearer ${userOneAccessToken}`) -// // .query({ property: 'channel' }) -// // .send() -// // .expect(httpStatus.OK); - -// // expect(res.body).toHaveLength(2); -// // expect(res.body[0].subChannels).toHaveLength(2); -// // expect(res.body[1].subChannels).toHaveLength(1); - -// // expect(res.body[0]).toMatchObject({ -// // channelId: "987654321098765432", -// // title: "Channel 1", -// // subChannels: [{ -// // channelId: "234567890123456789", -// // name: "Channel 2", -// // parentId: "987654321098765432", -// // canReadMessageHistoryAndViewChannel: false, -// // announcementAccess: false -// // }, -// // { -// // channelId: "345678901234567890", -// // name: "Channel 3", -// // parentId: "987654321098765432", -// // canReadMessageHistoryAndViewChannel: false, -// // announcementAccess: false -// // }] -// // }); -// // expect(res.body[1]).toMatchObject({ -// // channelId: "0", -// // title: "unCategorized", -// // subChannels: [{ -// // channelId: "345678901234567000", -// // name: "Channel 4", -// // parentId: "345678901234567000", -// // canReadMessageHistoryAndViewChannel: false, -// // announcementAccess: false -// // }] -// // }); -// // }); - -// // test('should correctly apply filter on channelId field if requested property is discord-channel', async () => { -// // await insertCommunities([communityOne]); -// // await insertUsers([userOne]); -// // await insertPlatforms([platformOne]); -// // await insertChannels([discordChannel1, discordChannel2, discordChannel3, discordChannel4, discordChannel5], connection) - -// // const res = await request(app) -// // .post(`/api/v1/platforms/${platformOne._id}/properties`) -// // .set('Authorization', `Bearer ${userOneAccessToken}`) -// // .query({ property: 'channel' }) -// // .send({ channelIds: [discordChannel1.channelId, discordChannel2.channelId, discordChannel3.channelId] }) -// // .expect(httpStatus.OK); - -// // expect(res.body).toHaveLength(1); -// // expect(res.body[0].subChannels).toHaveLength(2); - -// // expect(res.body[0]).toMatchObject({ -// // channelId: "987654321098765432", -// // title: "Channel 1", -// // subChannels: [{ -// // channelId: "234567890123456789", -// // name: "Channel 2", -// // parentId: "987654321098765432", -// // canReadMessageHistoryAndViewChannel: false -// // }, -// // { -// // channelId: "345678901234567890", -// // name: "Channel 3", -// // parentId: "987654321098765432", -// // canReadMessageHistoryAndViewChannel: false -// // }] -// // }); -// // }); - -// test('should return 200 and apply the default query options if requested property is discord-guildMember', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertGuildMembers( -// [discordGuildMember1, discordGuildMember2, discordGuildMember3, discordGuildMember4], -// connection, -// ); - -// const res = await request(app) -// .post(`/api/v1/platforms/${platformOne._id}/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ property: 'guildMember' }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 4, -// }); -// expect(res.body.results).toHaveLength(4); - -// expect(res.body.results[0]).toMatchObject({ -// discordId: discordGuildMember3.discordId, -// username: discordGuildMember3.username, -// ngu: discordGuildMember3.username, -// discriminator: discordGuildMember3.discriminator, -// nickname: discordGuildMember3.nickname, -// globalName: discordGuildMember3.globalName, -// avatar: discordGuildMember3.avatar, -// }); - -// expect(res.body.results[1]).toMatchObject({ -// discordId: discordGuildMember1.discordId, -// username: discordGuildMember1.username, -// ngu: discordGuildMember1.globalName, -// discriminator: discordGuildMember1.discriminator, -// nickname: discordGuildMember1.nickname, -// globalName: discordGuildMember1.globalName, -// avatar: discordGuildMember1.avatar, -// }); -// expect(res.body.results[2]).toMatchObject({ -// discordId: discordGuildMember2.discordId, -// username: discordGuildMember2.username, -// ngu: discordGuildMember2.nickname, -// discriminator: discordGuildMember2.discriminator, -// nickname: discordGuildMember2.nickname, -// globalName: discordGuildMember2.globalName, -// avatar: discordGuildMember2.avatar, -// }); - -// expect(res.body.results[3]).toMatchObject({ -// discordId: discordGuildMember4.discordId, -// username: discordGuildMember4.username + '#' + discordGuildMember4.discriminator, -// ngu: discordGuildMember4.username + '#' + discordGuildMember4.discriminator, -// discriminator: discordGuildMember4.discriminator, -// nickname: discordGuildMember4.nickname, -// globalName: discordGuildMember4.globalName, -// avatar: discordGuildMember4.avatar, -// }); -// }); - -// test('should correctly apply filter on ngu if requested property is discord-guildMember', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertGuildMembers( -// [discordGuildMember1, discordGuildMember2, discordGuildMember3, discordGuildMember4], -// connection, -// ); - -// const res = await request(app) -// .post(`/api/v1/platforms/${platformOne._id}/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ property: 'guildMember', ngu: 'behzad' }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 10, -// totalPages: 1, -// totalResults: 2, -// }); -// expect(res.body.results).toHaveLength(2); -// expect(res.body.results[0].discordId).toBe(discordGuildMember1.discordId); -// expect(res.body.results[1].discordId).toBe(discordGuildMember4.discordId); -// }); - -// test('should limit returned array if limit param is specified and requested property is discord-guildMember', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await insertGuildMembers( -// [discordGuildMember1, discordGuildMember2, discordGuildMember3, discordGuildMember4], -// connection, -// ); - -// const res = await request(app) -// .post(`/api/v1/platforms/${platformOne._id}/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ property: 'guildMember', limit: 1 }) -// .send() -// .expect(httpStatus.OK); - -// expect(res.body).toEqual({ -// results: expect.any(Array), -// page: 1, -// limit: 1, -// totalPages: 4, -// totalResults: 4, -// }); -// expect(res.body.results).toHaveLength(1); -// expect(res.body.results[0].discordId).toBe(discordGuildMember3.discordId); -// }); - -// test('should return 401 error if access token is missing', async () => { -// await insertUsers([userOne]); -// await request(app).post(`/api/v1/platforms/${platformOne._id}/properties`).send().expect(httpStatus.UNAUTHORIZED); -// }); - -// test('should return 404 when user trys to delete platform they does not belong to', async () => { -// await insertCommunities([communityOne, communityTwo, communityThree]); -// await insertUsers([userOne, userTwo]); -// await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); -// await request(app) -// .post(`/api/v1/platforms/${platformFour._id}/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.NOT_FOUND); -// }); - -// test('should return 400 error if platformId is not a valid mongo id', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await request(app) -// .post(`/api/v1/platforms/invalid/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 400 error if requested property is invalid', async () => { -// await insertCommunities([communityOne]); -// await insertUsers([userOne]); -// await insertPlatforms([platformOne]); -// await request(app) -// .post(`/api/v1/platforms/${platformOne._id}/properties`) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .query({ property: 'member' }) -// .send() -// .expect(httpStatus.BAD_REQUEST); -// }); - -// test('should return 404 error if platform already is not found', async () => { -// await insertUsers([userOne]); -// await request(app) -// .post(`/api/v1/platforms/${platformOne._id}/properties`) -// .query({ property: 'role' }) -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send() -// .expect(httpStatus.NOT_FOUND); -// }); -// }); - -// // TODO: add tests for connect platform and request access APIs -// }); +import request from 'supertest'; +import httpStatus from 'http-status'; +import app from '../../src/app'; +import setupTestDB, { cleanUpTenantDatabases } from '../utils/setupTestDB'; +import { userOne, insertUsers, userTwo } from '../fixtures/user.fixture'; +import { userOneAccessToken } from '../fixtures/token.fixture'; +import { Platform, Community, IPlatformUpdateBody, DatabaseManager } from '@togethercrew.dev/db'; +import { communityOne, communityTwo, communityThree, insertCommunities } from '../fixtures/community.fixture'; +import { + platformOne, + platformTwo, + platformThree, + platformFour, + platformFive, + insertPlatforms, +} from '../fixtures/platform.fixture'; +import { discordRole1, discordRole2, discordRole3, discordRole4, insertRoles } from '../fixtures/discord/roles.fixture'; +import { + discordChannel1, + discordChannel2, + discordChannel3, + discordChannel4, + discordChannel5, + insertChannels, +} from '../fixtures/discord/channels.fixture'; +import { + discordGuildMember1, + discordGuildMember2, + discordGuildMember3, + discordGuildMember4, + insertGuildMembers, +} from '../fixtures/discord/guildMember.fixture'; +import { discordServices } from '../../src/services'; +import { analyzerAction, analyzerWindow } from '../../src/config/analyzer.statics'; +import { Connection } from 'mongoose'; +import mongoose from 'mongoose'; + +setupTestDB(); + +describe('Platform routes', () => { + let connection: Connection; + beforeAll(async () => { + connection = await DatabaseManager.getInstance().getTenantDb(platformOne.metadata?.id); + }); + afterAll(async () => { + await connection.close(); + }); + beforeEach(async () => { + cleanUpTenantDatabases(); + userOne.communities = [communityOne._id, communityTwo._id]; + userTwo.communities = [communityThree._id]; + + communityOne.users = [userOne._id]; + communityTwo.users = [userOne._id]; + communityThree.users = [userTwo._id]; + + communityOne.platforms = [platformOne._id, platformTwo._id, platformFive._id]; + communityTwo.platforms = [platformThree._id]; + communityThree.platforms = [platformFour._id]; + + platformOne.community = communityOne._id; + platformTwo.community = communityOne._id; + platformThree.community = communityTwo._id; + platformFour.community = communityThree._id; + platformFive.community = communityOne._id; + }); + describe('POST api/v1/platforms', () => { + beforeEach(async () => { + cleanUpTenantDatabases(); + }); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let newPlatform: any; + + beforeEach(async () => { + await connection.collection('connection-platform').deleteMany({}); + newPlatform = { + name: 'discord', + community: communityOne._id, + metadata: { + id: '1234', + name: 'guild', + icon: 'path', + }, + }; + }); + + test('should return 201 and successfully create new platform if data is ok', async () => { + userOne.communities = [communityOne._id]; + communityOne.users = [userOne._id]; + await insertCommunities([communityOne]); + await insertUsers([userOne]); + + const res = await request(app) + .post(`/api/v1/platforms`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newPlatform) + .expect(httpStatus.CREATED); + + expect(res.body).toEqual({ + id: expect.anything(), + name: newPlatform.name, + metadata: { ...newPlatform.metadata, action: analyzerAction, window: analyzerWindow }, + community: communityOne._id.toHexString(), + disconnectedAt: null, + connectedAt: expect.anything(), + }); + + const dbPlatform = await Platform.findById(res.body.id); + expect(dbPlatform).toBeDefined(); + expect(dbPlatform).toMatchObject({ + name: newPlatform.name, + metadata: newPlatform.metadata, + }); + + const dbCommunity = await Community.findById(res.body.community); + expect(dbCommunity).toMatchObject({ + id: communityOne._id.toHexString(), + name: communityOne.name, + avatarURL: communityOne.avatarURL, + users: [userOne._id], + }); + }); + + test('should return 201 and successfully connect a disconneced platform if data is ok', async () => { + userOne.communities = [communityOne._id]; + communityOne.users = [userOne._id]; + await insertCommunities([communityOne]); + await insertUsers([userOne]); + platformOne.disconnectedAt = new Date(); + await insertPlatforms([platformOne]); + platformOne.disconnectedAt = null; + newPlatform.metadata.id = platformOne.metadata?.id; + + const res = await request(app) + .post(`/api/v1/platforms`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newPlatform) + .expect(httpStatus.CREATED); + + expect(res.body).toEqual({ + id: expect.anything(), + name: platformOne.name, + metadata: platformOne.metadata, + community: communityOne._id.toHexString(), + disconnectedAt: null, + connectedAt: expect.anything(), + }); + + const dbPlatform = await Platform.findById(res.body.id); + expect(dbPlatform).toBeDefined(); + expect(dbPlatform).toMatchObject({ + name: platformOne.name, + metadata: platformOne.metadata, + disconnectedAt: null, + }); + }); + + test('should return 401 error if access token is missing', async () => { + await request(app).post(`/api/v1/platforms`).send(newPlatform).expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 400 error if user trys to connect a connected platform', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + newPlatform.metadata.id = platformOne.metadata?.id; + const res = await request(app) + .post(`/api/v1/platforms`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newPlatform) + .expect(httpStatus.BAD_REQUEST); + + expect(res.body.message).toBe('This Platform is already connected'); + }); + + test('should return 400 error if user trys to connect a same platform', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + const res = await request(app) + .post(`/api/v1/platforms`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newPlatform) + .expect(httpStatus.BAD_REQUEST); + + expect(res.body.message).toBe('Only can connect one discord platform'); + }); + + test('should return 400 error if user trys to connect a platform which is already connected to another community', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne, userTwo]); + if (platformFour.metadata) { + platformFour.metadata.id = platformOne.metadata?.id; + newPlatform.metadata.id = platformOne.metadata?.id; + await insertPlatforms([platformFour]); + platformFour.metadata.id = '681946187490000802'; + } + const res = await request(app) + .post(`/api/v1/platforms`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newPlatform) + .expect(httpStatus.BAD_REQUEST); + + expect(res.body.message).toBe('This Platform is already connected to another community'); + }); + + test('should return 400 error if name is invalid', async () => { + await insertUsers([userOne]); + newPlatform.name = 'invalid'; + await request(app) + .post(`/api/v1/platforms`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newPlatform) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if community is invalid', async () => { + await insertUsers([userOne]); + newPlatform.community = 'invalid'; + await request(app) + .post(`/api/v1/platforms`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newPlatform) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if metadata is invalid based on the name field', async () => { + await insertUsers([userOne]); + newPlatform.metadata = { username: 'str' }; + await request(app) + .post(`/api/v1/platforms`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newPlatform) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if community is invalid', async () => { + await insertUsers([userOne]); + newPlatform.name = 'twitter'; + await request(app) + .post(`/api/v1/platforms`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(newPlatform) + .expect(httpStatus.BAD_REQUEST); + }); + }); + describe('GET /api/v1/platforms', () => { + beforeEach(async () => { + cleanUpTenantDatabases(); + }); + test('should return 200 and apply the default query options', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + const res = await request(app) + .get('/api/v1/platforms') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ community: communityOne._id.toHexString() }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(2); + + expect(res.body.results[0]).toMatchObject({ + id: platformTwo._id.toHexString(), + name: platformTwo.name, + metadata: platformTwo.metadata, + community: communityOne._id.toHexString(), + }); + + expect(res.body.results[1]).toMatchObject({ + id: platformOne._id.toHexString(), + name: platformOne.name, + metadata: platformOne.metadata, + community: communityOne._id.toHexString(), + }); + }); + + test('should return 401 if access token is missing', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + await request(app).get('/api/v1/platforms').send().expect(httpStatus.UNAUTHORIZED); + }); + + test('should correctly apply filter on name field', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + const res = await request(app) + .get('/api/v1/platforms') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ name: platformOne.name, community: communityOne._id.toHexString() }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(2); + expect(res.body.results[0].id).toBe(platformTwo._id.toHexString()); + expect(res.body.results[1].id).toBe(platformOne._id.toHexString()); + }); + + test('should correctly sort the returned array if descending sort param is specified', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + const res = await request(app) + .get('/api/v1/platforms') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ sortBy: 'name:desc', community: communityOne._id.toHexString() }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(2); + expect(res.body.results[0].id).toBe(platformOne._id.toHexString()); + expect(res.body.results[1].id).toBe(platformTwo._id.toHexString()); + }); + + test('should correctly sort the returned array if ascending sort param is specified', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + const res = await request(app) + .get('/api/v1/platforms') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ sortBy: 'name:asc', community: communityOne._id.toHexString() }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(2); + expect(res.body.results[0].id).toBe(platformOne._id.toHexString()); + expect(res.body.results[1].id).toBe(platformTwo._id.toHexString()); + }); + + test('should limit returned array if limit param is specified', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + const res = await request(app) + .get('/api/v1/platforms') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ limit: 1, community: communityOne._id.toHexString() }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 1, + totalPages: 2, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(1); + expect(res.body.results[0].id).toBe(platformTwo._id.toHexString()); + }); + + test('should return the correct page if page and limit params are specified', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + const res = await request(app) + .get('/api/v1/platforms') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ page: 2, limit: 1, community: communityOne._id.toHexString() }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 2, + limit: 1, + totalPages: 2, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(1); + expect(res.body.results[0].id).toBe(platformOne._id.toHexString()); + }); + }); + describe('GET /api/v1/platforms/:platformId', () => { + beforeEach(async () => { + cleanUpTenantDatabases(); + }); + discordServices.coreService.getBotPermissions = jest.fn().mockReturnValue(['ViewChannel', 'ReadMessageHistory']); + test('should return 200 and the platform object if data is ok', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + const res = await request(app) + .get(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + id: expect.anything(), + name: platformOne.name, + metadata: { + ...platformOne.metadata, + permissions: { + ReadData: { + ViewChannel: true, + ReadMessageHistory: true, + }, + Announcement: { + ViewChannel: true, + SendMessages: false, + SendMessagesInThreads: false, + CreatePublicThreads: false, + CreatePrivateThreads: false, + EmbedLinks: false, + AttachFiles: false, + MentionEveryone: false, + Connect: false, + }, + }, + }, + community: communityOne._id.toHexString(), + disconnectedAt: null, + connectedAt: expect.anything(), + }); + }); + + test('should return 401 error if access token is missing', async () => { + await insertUsers([userOne]); + + await request(app).get(`/api/v1/platforms/${platformOne._id}`).send().expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 404 when user trys to access platoform they does not belong to', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + + await request(app) + .get(`/api/v1/platforms/${platformFour._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.NOT_FOUND); + }); + + test('should return 400 error if platformId is not a valid mongo id', async () => { + await insertUsers([userOne, userTwo]); + await request(app) + .get(`/api/v1/platforms/invalid`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 404 error if platoform is not found', async () => { + await insertUsers([userOne]); + + await request(app) + .get(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.NOT_FOUND); + }); + }); + describe('PATCH /api/v1/platforms/:platformId', () => { + beforeEach(async () => { + cleanUpTenantDatabases(); + }); + let updateBody: IPlatformUpdateBody; + + beforeEach(() => { + updateBody = { + metadata: { + selectedChannels: ['8765', '1234'], + period: new Date(), + analyzerStartedAt: new Date(), + }, + }; + }); + test('should return 200 and successfully update platform if data is ok', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + const res = await request(app) + .patch(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + id: expect.anything(), + name: platformOne.name, + metadata: { + id: platformOne.metadata?.id, + selectedChannels: updateBody.metadata?.selectedChannels, + period: updateBody.metadata?.period.toISOString(), + analyzerStartedAt: expect.anything(), + }, + community: communityOne._id.toHexString(), + disconnectedAt: null, + connectedAt: expect.anything(), + }); + + const dbPlatform = await Platform.findById(res.body.id); + expect(dbPlatform).toBeDefined(); + expect(dbPlatform).toMatchObject({ + name: platformOne.name, + metadata: { + id: platformOne.metadata?.id, + selectedChannels: updateBody.metadata?.selectedChannels, + period: updateBody.metadata?.period, + analyzerStartedAt: expect.anything(), + }, + }); + }); + + test('should return 401 error if access token is missing', async () => { + await insertUsers([userOne]); + await request(app).patch(`/api/v1/platforms/${platformOne._id}`).send(updateBody).expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 404 when user trys to update platform they does not belong to', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + await request(app) + .patch(`/api/v1/platforms/${platformFour._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.NOT_FOUND); + }); + + test('should return 400 error if platformId is not a valid mongo id', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await request(app) + .patch(`/api/v1/platforms/invalid`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if metadata is invalid based on the name field', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + updateBody.metadata = { id: '1234' }; + await request(app) + .patch(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if metadata selectedChannels is invalid', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + updateBody.metadata = { selectedChannels: '1234' }; + await request(app) + .patch(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if metadata period is invalid', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + updateBody.metadata = { period: false }; + await request(app) + .patch(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if metadata analyzerStartedAt is invalid', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + updateBody.metadata = { analyzerStartedAt: true }; + await request(app) + .patch(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if isInprogress is true and user trys to update selectedChannel', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne]); + if (platformOne.metadata) platformOne.metadata.isInProgress = true; + await insertPlatforms([platformOne]); + if (platformOne.metadata) platformOne.metadata.isInProgress = false; + await request(app) + .patch(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if isInprogress is true and user trys to update period', async () => { + await insertCommunities([communityOne, communityTwo]); + await insertUsers([userOne]); + if (platformOne.metadata) platformOne.metadata.isInProgress = true; + await insertPlatforms([platformOne]); + if (platformOne.metadata) platformOne.metadata.isInProgress = false; + await request(app) + .patch(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.BAD_REQUEST); + }); + }); + describe('DELETE /api/v1/platforms/:platformId', () => { + beforeEach(async () => { + cleanUpTenantDatabases(); + }); + discordServices.coreService.leaveBotFromGuild = jest.fn().mockReturnValue(null); + test('should return 204 and soft delete the platform is deleteType is soft', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + + await request(app) + .delete(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ deleteType: 'soft' }) + .expect(httpStatus.NO_CONTENT); + + const dbPlatform = await Platform.findById(platformOne._id); + expect(dbPlatform).toBeDefined(); + expect(dbPlatform).toMatchObject({ + disconnectedAt: expect.any(Date), + }); + }); + + test('should return 204 and hard delete the platform is deleteType is hard', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + + const res = await request(app) + .delete(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ deleteType: 'hard' }) + .expect(httpStatus.NO_CONTENT); + + const dbPlatform = await Platform.findById(res.body.id); + expect(dbPlatform).toBeNull(); + }); + + test('should return 401 error if access token is missing', async () => { + await insertUsers([userOne]); + + await request(app).delete(`/api/v1/platforms/${platformOne._id}`).send().expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 404 when user trys to delete platform they does not belong to', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + + await request(app) + .delete(`/api/v1/platforms/${platformFour._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ deleteType: 'hard' }) + .expect(httpStatus.NOT_FOUND); + }); + + test('should return 400 error if platformId is not a valid mongo id', async () => { + await insertUsers([userOne]); + + await request(app) + .delete(`/api/v1/platforms/invalid`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 404 error if platform already is not found', async () => { + await insertUsers([userOne]); + + await request(app) + .delete(`/api/v1/platforms/${platformOne._id}`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send({ deleteType: 'hard' }) + .expect(httpStatus.NOT_FOUND); + }); + }); + describe('POST /:platformId/properties', () => { + beforeEach(async () => { + cleanUpTenantDatabases(); + }); + discordServices.coreService.getBotPermissions = jest.fn().mockReturnValue(['ViewChannel', 'ReadMessageHistory']); + test('should return 200 and apply the default query options if requested property is discord-role', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); + + const res = await request(app) + .post(`/api/v1/platforms/${platformOne._id}/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ property: 'role' }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 3, + }); + expect(res.body.results).toHaveLength(3); + + expect(res.body.results[0]).toMatchObject({ + roleId: discordRole1.roleId, + name: discordRole1.name, + color: discordRole1.color, + }); + expect(res.body.results[1]).toMatchObject({ + roleId: discordRole2.roleId, + name: discordRole2.name, + color: discordRole2.color, + }); + + expect(res.body.results[2]).toMatchObject({ + roleId: discordRole3.roleId, + name: discordRole3.name, + color: discordRole3.color, + }); + }); + + test('should correctly apply filter on name field if requested property is discord-role', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); + + const res = await request(app) + .post(`/api/v1/platforms/${platformOne._id}/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ property: 'role', name: 'Member' }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 1, + }); + expect(res.body.results).toHaveLength(1); + expect(res.body.results[0].roleId).toBe(discordRole3.roleId); + }); + + test('should correctly sort the returned array if descending sort param is specified and requested property is discord-role', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); + + const res = await request(app) + .post(`/api/v1/platforms/${platformOne._id}/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ property: 'role', sortBy: 'name:desc' }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 3, + }); + expect(res.body.results).toHaveLength(3); + expect(res.body.results[0].roleId).toBe(discordRole2.roleId); + expect(res.body.results[1].roleId).toBe(discordRole3.roleId); + expect(res.body.results[2].roleId).toBe(discordRole1.roleId); + }); + + test('should correctly sort the returned array if ascending sort param is specified and requested property is discord-role', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); + + const res = await request(app) + .post(`/api/v1/platforms/${platformOne._id}/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ property: 'role', sortBy: 'name:asc' }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 3, + }); + expect(res.body.results).toHaveLength(3); + expect(res.body.results[0].roleId).toBe(discordRole1.roleId); + expect(res.body.results[1].roleId).toBe(discordRole3.roleId); + expect(res.body.results[2].roleId).toBe(discordRole2.roleId); + }); + + test('should limit returned array if limit param is specified and requested property is discord-role', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); + + const res = await request(app) + .post(`/api/v1/platforms/${platformOne._id}/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ property: 'role', limit: 1 }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 1, + totalPages: 3, + totalResults: 3, + }); + expect(res.body.results).toHaveLength(1); + expect(res.body.results[0].roleId).toBe(discordRole1.roleId); + }); + + test('should return the correct page if page and limit params are specified and requested property is discord-role', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertRoles([discordRole1, discordRole2, discordRole3, discordRole4], connection); + + const res = await request(app) + .post(`/api/v1/platforms/${platformOne._id}/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ property: 'role', page: 2, limit: 1 }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 2, + limit: 1, + totalPages: 3, + totalResults: 3, + }); + expect(res.body.results).toHaveLength(1); + expect(res.body.results[0].roleId).toBe(discordRole2.roleId); + }); + + // test('should return 200 and channels data if requested property is discord-channel', async () => { + // await insertCommunities([communityOne]); + // await insertUsers([userOne]); + // await insertPlatforms([platformOne]); + // await insertChannels([discordChannel1, discordChannel2, discordChannel3, discordChannel4, discordChannel5], connection) + + // const res = await request(app) + // .post(`/api/v1/platforms/${platformOne._id}/properties`) + // .set('Authorization', `Bearer ${userOneAccessToken}`) + // .query({ property: 'channel' }) + // .send() + // .expect(httpStatus.OK); + + // expect(res.body).toHaveLength(2); + // expect(res.body[0].subChannels).toHaveLength(2); + // expect(res.body[1].subChannels).toHaveLength(1); + + // expect(res.body[0]).toMatchObject({ + // channelId: "987654321098765432", + // title: "Channel 1", + // subChannels: [{ + // channelId: "234567890123456789", + // name: "Channel 2", + // parentId: "987654321098765432", + // canReadMessageHistoryAndViewChannel: false, + // announcementAccess: false + // }, + // { + // channelId: "345678901234567890", + // name: "Channel 3", + // parentId: "987654321098765432", + // canReadMessageHistoryAndViewChannel: false, + // announcementAccess: false + // }] + // }); + // expect(res.body[1]).toMatchObject({ + // channelId: "0", + // title: "unCategorized", + // subChannels: [{ + // channelId: "345678901234567000", + // name: "Channel 4", + // parentId: "345678901234567000", + // canReadMessageHistoryAndViewChannel: false, + // announcementAccess: false + // }] + // }); + // }); + + // test('should correctly apply filter on channelId field if requested property is discord-channel', async () => { + // await insertCommunities([communityOne]); + // await insertUsers([userOne]); + // await insertPlatforms([platformOne]); + // await insertChannels([discordChannel1, discordChannel2, discordChannel3, discordChannel4, discordChannel5], connection) + + // const res = await request(app) + // .post(`/api/v1/platforms/${platformOne._id}/properties`) + // .set('Authorization', `Bearer ${userOneAccessToken}`) + // .query({ property: 'channel' }) + // .send({ channelIds: [discordChannel1.channelId, discordChannel2.channelId, discordChannel3.channelId] }) + // .expect(httpStatus.OK); + + // expect(res.body).toHaveLength(1); + // expect(res.body[0].subChannels).toHaveLength(2); + + // expect(res.body[0]).toMatchObject({ + // channelId: "987654321098765432", + // title: "Channel 1", + // subChannels: [{ + // channelId: "234567890123456789", + // name: "Channel 2", + // parentId: "987654321098765432", + // canReadMessageHistoryAndViewChannel: false + // }, + // { + // channelId: "345678901234567890", + // name: "Channel 3", + // parentId: "987654321098765432", + // canReadMessageHistoryAndViewChannel: false + // }] + // }); + // }); + + test('should return 200 and apply the default query options if requested property is discord-guildMember', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertGuildMembers( + [discordGuildMember1, discordGuildMember2, discordGuildMember3, discordGuildMember4], + connection, + ); + + const res = await request(app) + .post(`/api/v1/platforms/${platformOne._id}/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ property: 'guildMember' }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 4, + }); + expect(res.body.results).toHaveLength(4); + + expect(res.body.results[0]).toMatchObject({ + discordId: discordGuildMember3.discordId, + username: discordGuildMember3.username, + ngu: discordGuildMember3.username, + discriminator: discordGuildMember3.discriminator, + nickname: discordGuildMember3.nickname, + globalName: discordGuildMember3.globalName, + avatar: discordGuildMember3.avatar, + }); + + expect(res.body.results[1]).toMatchObject({ + discordId: discordGuildMember1.discordId, + username: discordGuildMember1.username, + ngu: discordGuildMember1.globalName, + discriminator: discordGuildMember1.discriminator, + nickname: discordGuildMember1.nickname, + globalName: discordGuildMember1.globalName, + avatar: discordGuildMember1.avatar, + }); + expect(res.body.results[2]).toMatchObject({ + discordId: discordGuildMember2.discordId, + username: discordGuildMember2.username, + ngu: discordGuildMember2.nickname, + discriminator: discordGuildMember2.discriminator, + nickname: discordGuildMember2.nickname, + globalName: discordGuildMember2.globalName, + avatar: discordGuildMember2.avatar, + }); + + expect(res.body.results[3]).toMatchObject({ + discordId: discordGuildMember4.discordId, + username: discordGuildMember4.username + '#' + discordGuildMember4.discriminator, + ngu: discordGuildMember4.username + '#' + discordGuildMember4.discriminator, + discriminator: discordGuildMember4.discriminator, + nickname: discordGuildMember4.nickname, + globalName: discordGuildMember4.globalName, + avatar: discordGuildMember4.avatar, + }); + }); + + test('should correctly apply filter on ngu if requested property is discord-guildMember', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertGuildMembers( + [discordGuildMember1, discordGuildMember2, discordGuildMember3, discordGuildMember4], + connection, + ); + + const res = await request(app) + .post(`/api/v1/platforms/${platformOne._id}/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ property: 'guildMember', ngu: 'behzad' }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 10, + totalPages: 1, + totalResults: 2, + }); + expect(res.body.results).toHaveLength(2); + expect(res.body.results[0].discordId).toBe(discordGuildMember1.discordId); + expect(res.body.results[1].discordId).toBe(discordGuildMember4.discordId); + }); + + test('should limit returned array if limit param is specified and requested property is discord-guildMember', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await insertGuildMembers( + [discordGuildMember1, discordGuildMember2, discordGuildMember3, discordGuildMember4], + connection, + ); + + const res = await request(app) + .post(`/api/v1/platforms/${platformOne._id}/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ property: 'guildMember', limit: 1 }) + .send() + .expect(httpStatus.OK); + + expect(res.body).toEqual({ + results: expect.any(Array), + page: 1, + limit: 1, + totalPages: 4, + totalResults: 4, + }); + expect(res.body.results).toHaveLength(1); + expect(res.body.results[0].discordId).toBe(discordGuildMember3.discordId); + }); + + test('should return 401 error if access token is missing', async () => { + await insertUsers([userOne]); + await request(app).post(`/api/v1/platforms/${platformOne._id}/properties`).send().expect(httpStatus.UNAUTHORIZED); + }); + + test('should return 404 when user trys to delete platform they does not belong to', async () => { + await insertCommunities([communityOne, communityTwo, communityThree]); + await insertUsers([userOne, userTwo]); + await insertPlatforms([platformOne, platformTwo, platformThree, platformFour, platformFive]); + await request(app) + .post(`/api/v1/platforms/${platformFour._id}/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.NOT_FOUND); + }); + + test('should return 400 error if platformId is not a valid mongo id', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await request(app) + .post(`/api/v1/platforms/invalid/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 400 error if requested property is invalid', async () => { + await insertCommunities([communityOne]); + await insertUsers([userOne]); + await insertPlatforms([platformOne]); + await request(app) + .post(`/api/v1/platforms/${platformOne._id}/properties`) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .query({ property: 'member' }) + .send() + .expect(httpStatus.BAD_REQUEST); + }); + + test('should return 404 error if platform already is not found', async () => { + await insertUsers([userOne]); + await request(app) + .post(`/api/v1/platforms/${platformOne._id}/properties`) + .query({ property: 'role' }) + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send() + .expect(httpStatus.NOT_FOUND); + }); + }); + + // TODO: add tests for connect platform and request access APIs +}); diff --git a/__tests__/integration/user.test.ts b/__tests__/integration/user.test.ts index f182c861..42a1ad3f 100644 --- a/__tests__/integration/user.test.ts +++ b/__tests__/integration/user.test.ts @@ -1,90 +1,90 @@ -// import request from 'supertest'; -// import httpStatus from 'http-status'; -// import app from '../../src/app'; -// import setupTestDB from '../utils/setupTestDB'; -// import { userOne, insertUsers } from '../fixtures/user.fixture'; -// import { User, IUserUpdateBody } from '@togethercrew.dev/db'; +import request from 'supertest'; +import httpStatus from 'http-status'; +import app from '../../src/app'; +import setupTestDB from '../utils/setupTestDB'; +import { userOne, insertUsers } from '../fixtures/user.fixture'; +import { User, IUserUpdateBody } from '@togethercrew.dev/db'; -// import { userOneAccessToken } from '../fixtures/token.fixture'; -// setupTestDB(); +import { userOneAccessToken } from '../fixtures/token.fixture'; +setupTestDB(); -// describe('User routes', () => { -// describe('GET /api/v1/users/@me', () => { -// test('should return 200 and the user object if data is ok', async () => { -// await insertUsers([userOne]); -// const res = await request(app) -// .get('/api/v1/users/@me') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .expect(httpStatus.OK); +describe('User routes', () => { + describe('GET /api/v1/users/@me', () => { + test('should return 200 and the user object if data is ok', async () => { + await insertUsers([userOne]); + const res = await request(app) + .get('/api/v1/users/@me') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .expect(httpStatus.OK); -// expect(res.body).toEqual({ -// id: userOne._id.toHexString(), -// discordId: userOne.discordId, -// email: userOne.email, -// communities: [], -// }); -// }); -// test('should return 401 if access token is missing', async () => { -// await insertUsers([userOne]); -// await request(app).get('/api/v1/users/@me').expect(httpStatus.UNAUTHORIZED); -// }); -// }); + expect(res.body).toEqual({ + id: userOne._id.toHexString(), + discordId: userOne.discordId, + email: userOne.email, + communities: [], + }); + }); + test('should return 401 if access token is missing', async () => { + await insertUsers([userOne]); + await request(app).get('/api/v1/users/@me').expect(httpStatus.UNAUTHORIZED); + }); + }); -// describe('PATCH /api/v1/users/@me', () => { -// let updateBody: IUserUpdateBody; -// const currentDate = new Date(); + describe('PATCH /api/v1/users/@me', () => { + let updateBody: IUserUpdateBody; + const currentDate = new Date(); -// beforeEach(() => { -// updateBody = { -// email: 'email@yahoo.com', -// tcaAt: currentDate, -// }; -// }); -// test('should return 200 and successfully update user if data is ok', async () => { -// await insertUsers([userOne]); -// const res = await request(app) -// .patch('/api/v1/users/@me') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.OK); + beforeEach(() => { + updateBody = { + email: 'email@yahoo.com', + tcaAt: currentDate, + }; + }); + test('should return 200 and successfully update user if data is ok', async () => { + await insertUsers([userOne]); + const res = await request(app) + .patch('/api/v1/users/@me') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.OK); -// expect(res.body).toEqual({ -// id: userOne._id.toHexString(), -// discordId: userOne.discordId, -// email: updateBody.email, -// communities: [], -// tcaAt: currentDate.toISOString(), -// }); + expect(res.body).toEqual({ + id: userOne._id.toHexString(), + discordId: userOne.discordId, + email: updateBody.email, + communities: [], + tcaAt: currentDate.toISOString(), + }); -// const dbUser = await User.findById(userOne._id); -// expect(dbUser).toBeDefined(); -// expect(dbUser).toMatchObject({ email: updateBody.email, tcaAt: updateBody.tcaAt }); -// }); -// test('should return 401 if access token is missing', async () => { -// await insertUsers([userOne]); -// await request(app).patch('/api/v1/users/@me').send(updateBody).expect(httpStatus.UNAUTHORIZED); -// }); + const dbUser = await User.findById(userOne._id); + expect(dbUser).toBeDefined(); + expect(dbUser).toMatchObject({ email: updateBody.email, tcaAt: updateBody.tcaAt }); + }); + test('should return 401 if access token is missing', async () => { + await insertUsers([userOne]); + await request(app).patch('/api/v1/users/@me').send(updateBody).expect(httpStatus.UNAUTHORIZED); + }); -// test('should return 400 if email is invalid', async () => { -// await insertUsers([userOne]); -// const updateBody = { email: 'invalidEmail' }; + test('should return 400 if email is invalid', async () => { + await insertUsers([userOne]); + const updateBody = { email: 'invalidEmail' }; -// await request(app) -// .patch('/api/v1/users/@me') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.BAD_REQUEST); -// }); + await request(app) + .patch('/api/v1/users/@me') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.BAD_REQUEST); + }); -// test('should return 400 error if tcaAt is invalid', async () => { -// const updateBody = { tcaAt: 'tcaAt' }; + test('should return 400 error if tcaAt is invalid', async () => { + const updateBody = { tcaAt: 'tcaAt' }; -// await insertUsers([userOne]); -// await request(app) -// .patch('/api/v1/users/@me') -// .set('Authorization', `Bearer ${userOneAccessToken}`) -// .send(updateBody) -// .expect(httpStatus.BAD_REQUEST); -// }); -// }); -// }); + await insertUsers([userOne]); + await request(app) + .patch('/api/v1/users/@me') + .set('Authorization', `Bearer ${userOneAccessToken}`) + .send(updateBody) + .expect(httpStatus.BAD_REQUEST); + }); + }); +});