diff --git a/apps/meteor/.eslintignore b/apps/meteor/.eslintignore index 2bbdbae00b89..2701a871d981 100644 --- a/apps/meteor/.eslintignore +++ b/apps/meteor/.eslintignore @@ -1,6 +1,5 @@ /node_modules/ #/tests/e2e/ -/tests/data/ /packages/ /app/emoji-emojione/generateEmojiIndex.js /public/ diff --git a/apps/meteor/.mocharc.api.js b/apps/meteor/.mocharc.api.js index eca1284e62e5..b73a24a275e4 100644 --- a/apps/meteor/.mocharc.api.js +++ b/apps/meteor/.mocharc.api.js @@ -1,13 +1,14 @@ 'use strict'; -/** +/* * Mocha configuration for REST API integration tests. */ -module.exports = { +module.exports = /** @satisfies {import('mocha').MochaOptions} */ ({ ...require('./.mocharc.base.json'), // see https://github.com/mochajs/mocha/issues/3916 timeout: 10000, bail: true, - file: 'tests/end-to-end/teardown.js', + retries: 0, + file: 'tests/end-to-end/teardown.ts', spec: ['tests/end-to-end/api/**/*', 'tests/end-to-end/apps/*'], -}; +}); diff --git a/apps/meteor/package.json b/apps/meteor/package.json index 8f44665c204b..816379df08a9 100644 --- a/apps/meteor/package.json +++ b/apps/meteor/package.json @@ -97,7 +97,7 @@ "@types/bcrypt": "^5.0.1", "@types/body-parser": "^1.19.4", "@types/busboy": "^1.5.2", - "@types/chai": "^4.3.9", + "@types/chai": "~4.3.16", "@types/chai-as-promised": "^7.1.7", "@types/chai-datetime": "0.0.38", "@types/chai-dom": "1.11.2", diff --git a/apps/meteor/tests/data/api-data.js b/apps/meteor/tests/data/api-data.js deleted file mode 100644 index cab98c41eb15..000000000000 --- a/apps/meteor/tests/data/api-data.js +++ /dev/null @@ -1,68 +0,0 @@ -import supertest from 'supertest'; - -import { publicChannelName, privateChannelName } from './channel'; -import { roleNameUsers, roleNameSubscriptions, roleScopeUsers, roleScopeSubscriptions, roleDescription } from './role'; -import { username, email, adminUsername, adminPassword } from './user'; - -const apiUrl = process.env.TEST_API_URL || 'http://localhost:3000'; - -export const request = supertest(apiUrl); -const prefix = '/api/v1/'; - -export function wait(cb, time) { - return () => setTimeout(cb, time); -} - -export const apiUsername = `api${username}-${Date.now()}`; -export const apiEmail = `api${email}-${Date.now()}`; -export const apiPrivateChannelName = `api${privateChannelName}-${Date.now()}`; - -export const apiRoleNameUsers = `api${roleNameUsers}`; -export const apiRoleNameSubscriptions = `api${roleNameSubscriptions}`; -export const apiRoleScopeUsers = `${roleScopeUsers}`; -export const apiRoleScopeSubscriptions = `${roleScopeSubscriptions}`; -export const apiRoleDescription = `api${roleDescription}`; -export const reservedWords = ['admin', 'administrator', 'system', 'user']; - -export const group = {}; -export const message = {}; -export const directMessage = {}; -export const integration = {}; -/** @type {{ 'X-Auth-Token': string | undefined; 'X-User-Id': string | undefined }} */ -export const credentials = { - 'X-Auth-Token': undefined, - 'X-User-Id': undefined, -}; -export const login = { - user: adminUsername, - password: adminPassword, -}; - -export function api(path) { - return prefix + path; -} - -export function methodCall(methodName) { - return api(`method.call/${methodName}`); -} - -export function log(res) { - console.log(res.req.path); - console.log({ - body: res.body, - headers: res.headers, - }); -} - -export function getCredentials(done = function () {}) { - request - .post(api('login')) - .send(login) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - credentials['X-Auth-Token'] = res.body.data.authToken; - credentials['X-User-Id'] = res.body.data.userId; - }) - .end(done); -} diff --git a/apps/meteor/tests/data/api-data.ts b/apps/meteor/tests/data/api-data.ts new file mode 100644 index 000000000000..f3186752a38f --- /dev/null +++ b/apps/meteor/tests/data/api-data.ts @@ -0,0 +1,76 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { Path } from '@rocket.chat/rest-typings'; +import type { CallbackHandler, Response } from 'supertest'; +import supertest from 'supertest'; + +import { adminUsername, adminPassword } from './user'; + +const apiUrl = process.env.TEST_API_URL || 'http://localhost:3000'; + +export const request = supertest(apiUrl); +const prefix = '/api/v1/'; + +export function wait(cb: () => void, time: number) { + return () => setTimeout(cb, time); +} + +const privateChannelName = `private-channel-test-${Date.now()}` as const; + +const username = 'user.test'; +const email = `${username}@rocket.chat`; + +export const apiUsername = `api${username}-${Date.now()}` as const; +export const apiEmail = `api${email}-${Date.now()}` as const; +export const apiPrivateChannelName = `api${privateChannelName}-${Date.now()}` as const; + +const roleNameUsers = `role-name-test-users-${Date.now()}` as const; +const roleNameSubscriptions = `role-name-test-subscriptions-${Date.now()}` as const; +const roleScopeUsers = 'Users' as const; +const roleScopeSubscriptions = 'Subscriptions' as const; +const roleDescription = `role-description-test-${Date.now()}` as const; + +export const apiRoleNameUsers = `api${roleNameUsers}` as const; +export const apiRoleNameSubscriptions = `api${roleNameSubscriptions}` as const; +export const apiRoleScopeUsers = `${roleScopeUsers}` as const; +export const apiRoleScopeSubscriptions = `${roleScopeSubscriptions}` as const; +export const apiRoleDescription = `api${roleDescription}` as const; +export const reservedWords = ['admin', 'administrator', 'system', 'user'] as const; + +export const credentials: Credentials = { + 'X-Auth-Token': undefined, + 'X-User-Id': undefined, +} as unknown as Credentials; // FIXME + +type PathWithoutPrefix = TPath extends `/v1/${infer U}` ? U : never; + +export function api>(path: TPath) { + return `${prefix}${path}` as const; +} + +export function methodCall(methodName: TMethodName) { + return api(`method.call/${methodName}`); +} + +export function log(res: Response) { + console.log((res as { req?: any }).req.path); // FIXME + console.log({ + body: res.body, + headers: res.headers, + }); +} + +export function getCredentials(done?: CallbackHandler) { + void request + .post(api('login')) + .send({ + user: adminUsername, + password: adminPassword, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + credentials['X-Auth-Token'] = res.body.data.authToken; + credentials['X-User-Id'] = res.body.data.userId; + }) + .end(done); +} diff --git a/apps/meteor/tests/data/apps/apps-data.js b/apps/meteor/tests/data/apps/apps-data.js deleted file mode 100644 index bf1e3c4422bd..000000000000 --- a/apps/meteor/tests/data/apps/apps-data.js +++ /dev/null @@ -1,4 +0,0 @@ -export const APP_URL = 'https://github.com/RocketChat/Apps.RocketChat.Tester/blob/master/dist/appsrocketchattester_0.0.5.zip?raw=true'; -export const APP_NAME = 'Apps.RocketChat.Tester'; -export const APP_USERNAME = 'appsrocketchattester.bot'; -export const apps = (path = '') => `/api/apps${path}`; diff --git a/apps/meteor/tests/data/apps/apps-data.ts b/apps/meteor/tests/data/apps/apps-data.ts new file mode 100644 index 000000000000..6c5117c2150e --- /dev/null +++ b/apps/meteor/tests/data/apps/apps-data.ts @@ -0,0 +1,12 @@ +import type { Path } from '@rocket.chat/rest-typings'; + +export const APP_URL = 'https://github.com/RocketChat/Apps.RocketChat.Tester/blob/master/dist/appsrocketchattester_0.0.5.zip?raw=true'; +export const APP_NAME = 'Apps.RocketChat.Tester'; + +type PathWithoutPrefix = TPath extends `/apps${infer U}` ? U : never; + +export function apps(path?: ''): `/api/apps`; +export function apps>(path: TPath): `/api/apps${TPath}`; +export function apps(path = '') { + return `/api/apps${path}` as const; +} diff --git a/apps/meteor/tests/data/apps/helper.js b/apps/meteor/tests/data/apps/helper.ts similarity index 68% rename from apps/meteor/tests/data/apps/helper.js rename to apps/meteor/tests/data/apps/helper.ts index 787846a1186f..3236b0652b86 100644 --- a/apps/meteor/tests/data/apps/helper.js +++ b/apps/meteor/tests/data/apps/helper.ts @@ -1,19 +1,21 @@ +import type { App } from '@rocket.chat/core-typings'; + import { request, credentials } from '../api-data'; import { apps, APP_URL, APP_NAME } from './apps-data'; -export const getApps = () => - new Promise((resolve) => { - request +const getApps = () => + new Promise((resolve) => { + void request .get(apps()) .set(credentials) - .end((err, res) => { + .end((_err, res) => { resolve(res.body.apps); }); }); -export const removeAppById = (id) => +const removeAppById = (id: App['id']) => new Promise((resolve) => { - request + void request .delete(apps(`/${id}`)) .set(credentials) .end(resolve); @@ -28,14 +30,14 @@ export const cleanupApps = async () => { }; export const installTestApp = () => - new Promise((resolve) => { - request + new Promise((resolve) => { + void request .post(apps()) .set(credentials) .send({ url: APP_URL, }) - .end((err, res) => { + .end((_err, res) => { resolve(res.body.app); }); }); diff --git a/apps/meteor/tests/data/channel.ts b/apps/meteor/tests/data/channel.ts deleted file mode 100644 index 1cd02fb09022..000000000000 --- a/apps/meteor/tests/data/channel.ts +++ /dev/null @@ -1 +0,0 @@ -export const privateChannelName = `private-channel-test-${Date.now()}`; diff --git a/apps/meteor/tests/data/chat.helper.js b/apps/meteor/tests/data/chat.helper.ts similarity index 54% rename from apps/meteor/tests/data/chat.helper.js rename to apps/meteor/tests/data/chat.helper.ts index 6e3a2d05a0cd..46514969bd82 100644 --- a/apps/meteor/tests/data/chat.helper.js +++ b/apps/meteor/tests/data/chat.helper.ts @@ -1,10 +1,24 @@ +import type { IRoom, IMessage } from '@rocket.chat/core-typings'; + import { api, credentials, request } from './api-data'; -export const sendSimpleMessage = ({ roomId, text = 'test message', tmid }) => { +export const sendSimpleMessage = ({ + roomId, + text = 'test message', + tmid, +}: { + roomId: IRoom['_id']; + text?: string; + tmid?: IMessage['_id']; +}) => { if (!roomId) { throw new Error('"roomId" is required in "sendSimpleMessage" test helper'); } - const message = { + const message: { + rid: IRoom['_id']; + text: string; + tmid?: IMessage['_id']; + } = { rid: roomId, text, }; @@ -15,17 +29,7 @@ export const sendSimpleMessage = ({ roomId, text = 'test message', tmid }) => { return request.post(api('chat.sendMessage')).set(credentials).send({ message }); }; -export const pinMessage = ({ msgId }) => { - if (!msgId) { - throw new Error('"msgId" is required in "pinMessage" test helper'); - } - - return request.post(api('chat.pinMessage')).set(credentials).send({ - messageId: msgId, - }); -}; - -export const deleteMessage = ({ roomId, msgId }) => { +export const deleteMessage = ({ roomId, msgId }: { roomId: IRoom['_id']; msgId: IMessage['_id'] }) => { if (!roomId) { throw new Error('"roomId" is required in "deleteMessage" test helper'); } @@ -39,16 +43,17 @@ export const deleteMessage = ({ roomId, msgId }) => { }); }; -export const getMessageById = ({ msgId }) => { +export const getMessageById = ({ msgId }: { msgId: IMessage['_id'] }) => { if (!msgId) { throw new Error('"msgId" is required in "getMessageById" test helper'); } - return new Promise((resolve) => { - request - .get(api(`chat.getMessage?msgId=${msgId}`)) + return new Promise((resolve) => { + void request + .get(api(`chat.getMessage`)) + .query({ msgId }) .set(credentials) - .end((err, res) => { + .end((_err, res) => { resolve(res.body.message); }); }); diff --git a/apps/meteor/tests/data/checks.js b/apps/meteor/tests/data/checks.js deleted file mode 100644 index abfe171915ab..000000000000 --- a/apps/meteor/tests/data/checks.js +++ /dev/null @@ -1,15 +0,0 @@ -export let publicChannelCreated = false; -export let privateChannelCreated = false; -export let directMessageCreated = false; - -export function setPublicChannelCreated(status) { - publicChannelCreated = status; -} - -export function setPrivateChannelCreated(status) { - privateChannelCreated = status; -} - -export function setDirectMessageCreated(status) { - directMessageCreated = status; -} diff --git a/apps/meteor/tests/data/constants.ts b/apps/meteor/tests/data/constants.ts index 7cf3c0ba901e..a7ebc76876db 100644 --- a/apps/meteor/tests/data/constants.ts +++ b/apps/meteor/tests/data/constants.ts @@ -1,3 +1 @@ export const CI_MAX_ROOMS_PER_GUEST = 10; -export const MAX_BIO_LENGTH = 260; -export const MAX_NICKNAME_LENGTH = 120; diff --git a/apps/meteor/tests/data/custom-fields.js b/apps/meteor/tests/data/custom-fields.js deleted file mode 100644 index e2e175429b4c..000000000000 --- a/apps/meteor/tests/data/custom-fields.js +++ /dev/null @@ -1,18 +0,0 @@ -import { credentials, request, api } from './api-data.js'; - -export const customFieldText = { - type: 'text', - required: true, - minLength: 2, - maxLength: 10, -}; - -export function setCustomFields(customFields) { - const stringified = customFields ? JSON.stringify(customFields) : ''; - - return request.post(api('settings/Accounts_CustomFields')).set(credentials).send({ value: stringified }).expect(200); -} - -export function clearCustomFields() { - return setCustomFields(null); -} diff --git a/apps/meteor/tests/data/integration.helper.js b/apps/meteor/tests/data/integration.helper.ts similarity index 54% rename from apps/meteor/tests/data/integration.helper.js rename to apps/meteor/tests/data/integration.helper.ts index 6a28643ffc7b..211de64b6e1a 100644 --- a/apps/meteor/tests/data/integration.helper.js +++ b/apps/meteor/tests/data/integration.helper.ts @@ -1,8 +1,12 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IIntegration } from '@rocket.chat/core-typings'; +import type { IntegrationsCreateProps } from '@rocket.chat/rest-typings'; + import { api, credentials, request } from './api-data'; -export const createIntegration = (integration, userCredentials) => - new Promise((resolve, reject) => { - request +export const createIntegration = (integration: IntegrationsCreateProps, userCredentials: Credentials) => + new Promise((resolve, reject) => { + void request .post(api('integrations.create')) .set(userCredentials) .send(integration) @@ -21,9 +25,9 @@ export const createIntegration = (integration, userCredentials) => }); }); -export const removeIntegration = (integrationId, type) => - new Promise((resolve, reject) => { - request +export const removeIntegration = (integrationId: IIntegration['_id'], type: 'incoming' | 'outgoing') => + new Promise((resolve) => { + void request .post(api('integrations.remove')) .set(credentials) .send({ diff --git a/apps/meteor/tests/data/interactions.ts b/apps/meteor/tests/data/interactions.ts index 085d97d4ece3..9d5a69ce9593 100644 --- a/apps/meteor/tests/data/interactions.ts +++ b/apps/meteor/tests/data/interactions.ts @@ -1,6 +1 @@ -export const targetUser = 'rocket.cat'; export const imgURL = './public/images/logo/1024x1024.png'; -export const lstURL = './tests/e2e/fixtures/files/lst-test.lst'; -export const drawioURL = './tests/e2e/fixtures/files/diagram.drawio'; -export const svgLogoURL = './public/images/logo/logo.svg'; -export const svgLogoFileName = 'logo.svg'; diff --git a/apps/meteor/tests/data/licenses.helper.ts b/apps/meteor/tests/data/licenses.helper.ts deleted file mode 100644 index 61177ee549d3..000000000000 --- a/apps/meteor/tests/data/licenses.helper.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { api, credentials, request } from "./api-data" - -export const getLicenseInfo = (loadValues = false) => { - return request.get(api('licenses.info')).set(credentials).query({ loadValues }).expect(200); -} \ No newline at end of file diff --git a/apps/meteor/tests/data/livechat/businessHours.ts b/apps/meteor/tests/data/livechat/businessHours.ts index 58d8affa3d2a..ad835b0cff25 100644 --- a/apps/meteor/tests/data/livechat/businessHours.ts +++ b/apps/meteor/tests/data/livechat/businessHours.ts @@ -1,48 +1,50 @@ -import { ILivechatBusinessHour, LivechatBusinessHourTypes } from "@rocket.chat/core-typings"; -import { api, credentials, methodCall, request } from "../api-data"; -import { updateEESetting, updateSetting } from "../permissions.helper" -import moment from "moment"; +import type { ILivechatBusinessHour } from '@rocket.chat/core-typings'; +import { LivechatBusinessHourTypes } from '@rocket.chat/core-typings'; +import moment from 'moment'; -type ISaveBhApiWorkHour = Omit & { workHours: { day: string, start: string, finish: string, open: boolean }[] } & { departmentsToApplyBusinessHour?: string } & { timezoneName: string }; +import { api, credentials, methodCall, request } from '../api-data'; +import { updateEESetting, updateSetting } from '../permissions.helper'; + +type ISaveBhApiWorkHour = Omit & { + workHours: { day: string; start: string; finish: string; open: boolean }[]; +} & { departmentsToApplyBusinessHour?: string } & { timezoneName: string }; // TODO: Migrate to an API call and return the business hour updated/created export const saveBusinessHour = async (businessHour: ISaveBhApiWorkHour) => { - const { body } = await request - .post(methodCall('livechat:saveBusinessHour')) - .set(credentials) - .send({ message: JSON.stringify({ params: [businessHour], msg: 'method', method: 'livechat:saveBusinessHour', id: '101' }) }) - .expect(200); + const { body } = await request + .post(methodCall('livechat:saveBusinessHour')) + .set(credentials) + .send({ message: JSON.stringify({ params: [businessHour], msg: 'method', method: 'livechat:saveBusinessHour', id: '101' }) }) + .expect(200); - return JSON.parse(body.message); + return JSON.parse(body.message); }; export const createCustomBusinessHour = async (departments: string[], open = true): Promise => { - const name = `business-hour-${Date.now()}`; - const businessHour: ISaveBhApiWorkHour = { - name, - active: true, - type: LivechatBusinessHourTypes.CUSTOM, - workHours: getWorkHours(open), - timezoneName: 'Asia/Calcutta', - departmentsToApplyBusinessHour: '', - }; - - if (departments.length) { - businessHour.departmentsToApplyBusinessHour = departments.join(','); - } - - await saveBusinessHour(businessHour); - - - const existingBusinessHours: ILivechatBusinessHour[] = await getAllCustomBusinessHours(); - const createdBusinessHour = existingBusinessHours.find((bh) => bh.name === name); - if (!createdBusinessHour) { - throw new Error('Could not create business hour'); - } - - return createdBusinessHour; -}; + const name = `business-hour-${Date.now()}`; + const businessHour: ISaveBhApiWorkHour = { + name, + active: true, + type: LivechatBusinessHourTypes.CUSTOM, + workHours: getWorkHours(open), + timezoneName: 'Asia/Calcutta', + departmentsToApplyBusinessHour: '', + }; + + if (departments.length) { + businessHour.departmentsToApplyBusinessHour = departments.join(','); + } + await saveBusinessHour(businessHour); + + const existingBusinessHours: ILivechatBusinessHour[] = await getAllCustomBusinessHours(); + const createdBusinessHour = existingBusinessHours.find((bh) => bh.name === name); + if (!createdBusinessHour) { + throw new Error('Could not create business hour'); + } + + return createdBusinessHour; +}; export const makeDefaultBusinessHourActiveAndClosed = async () => { // enable settings @@ -50,13 +52,12 @@ export const makeDefaultBusinessHourActiveAndClosed = async () => { await updateEESetting('Livechat_business_hour_type', 'Single'); // create business hours - const { body: { businessHour } } = await request - .get(api('livechat/business-hour?type=default')) - .set(credentials) - .send(); + const { + body: { businessHour }, + } = await request.get(api('livechat/business-hour')).query({ type: 'default' }).set(credentials).send(); - // TODO: Refactor this to use openOrCloseBusinessHour() instead - const workHours = businessHour.workHours as { start: string; finish: string; day: string, open: boolean }[]; + // TODO: Refactor this to use openOrCloseBusinessHour() instead + const workHours = businessHour.workHours as { start: string; finish: string; day: string; open: boolean }[]; const allEnabledWorkHours = workHours.map((workHour) => { workHour.open = true; workHour.start = '00:00'; @@ -67,9 +68,10 @@ export const makeDefaultBusinessHourActiveAndClosed = async () => { const enabledBusinessHour = { ...businessHour, workHours: allEnabledWorkHours, - } + }; - await request.post(methodCall('livechat:saveBusinessHour')) + await request + .post(methodCall('livechat:saveBusinessHour')) .set(credentials) .send({ message: JSON.stringify({ @@ -79,7 +81,7 @@ export const makeDefaultBusinessHourActiveAndClosed = async () => { msg: 'method', }), }); -} +}; export const disableDefaultBusinessHour = async () => { // disable settings @@ -87,13 +89,12 @@ export const disableDefaultBusinessHour = async () => { await updateEESetting('Livechat_business_hour_type', 'Single'); // create business hours - const { body: { businessHour } } = await request - .get(api('livechat/business-hour?type=default')) - .set(credentials) - .send(); + const { + body: { businessHour }, + } = await request.get(api('livechat/business-hour')).query({ type: 'default' }).set(credentials).send(); - // TODO: Refactor this to use openOrCloseBusinessHour() instead - const workHours = businessHour.workHours as { start: string; finish: string; day: string, open: boolean }[]; + // TODO: Refactor this to use openOrCloseBusinessHour() instead + const workHours = businessHour.workHours as { start: string; finish: string; day: string; open: boolean }[]; const allDisabledWorkHours = workHours.map((workHour) => { workHour.open = false; workHour.start = '00:00'; @@ -104,9 +105,10 @@ export const disableDefaultBusinessHour = async () => { const disabledBusinessHour = { ...businessHour, workHours: allDisabledWorkHours, - } + }; - await request.post(methodCall('livechat:saveBusinessHour')) + await request + .post(methodCall('livechat:saveBusinessHour')) .set(credentials) .send({ message: JSON.stringify({ @@ -116,67 +118,83 @@ export const disableDefaultBusinessHour = async () => { msg: 'method', }), }); -} - -export const removeCustomBusinessHour = async (businessHourId: string) => { - await request - .post(methodCall('livechat:removeBusinessHour')) - .set(credentials) - .send({ message: JSON.stringify({ params: [businessHourId, LivechatBusinessHourTypes.CUSTOM], msg: 'method', method: 'livechat:removeBusinessHour', id: '101' }) }) - .expect(200); }; -const getAllCustomBusinessHours = async (): Promise => { - const response = await request.get(api('livechat/business-hours')).set(credentials).expect(200); - return (response.body.businessHours || []).filter((businessHour: ILivechatBusinessHour) => businessHour.type === LivechatBusinessHourTypes.CUSTOM); +const removeCustomBusinessHour = async (businessHourId: string) => { + await request + .post(methodCall('livechat:removeBusinessHour')) + .set(credentials) + .send({ + message: JSON.stringify({ + params: [businessHourId, LivechatBusinessHourTypes.CUSTOM], + msg: 'method', + method: 'livechat:removeBusinessHour', + id: '101', + }), + }) + .expect(200); }; +const getAllCustomBusinessHours = async (): Promise => { + const response = await request.get(api('livechat/business-hours')).set(credentials).expect(200); + return (response.body.businessHours || []).filter( + (businessHour: ILivechatBusinessHour) => businessHour.type === LivechatBusinessHourTypes.CUSTOM, + ); +}; export const removeAllCustomBusinessHours = async () => { - const existingBusinessHours: ILivechatBusinessHour[] = await getAllCustomBusinessHours(); + const existingBusinessHours: ILivechatBusinessHour[] = await getAllCustomBusinessHours(); - const promises = existingBusinessHours.map((businessHour) => removeCustomBusinessHour(businessHour._id)); - await Promise.all(promises); + const promises = existingBusinessHours.map((businessHour) => removeCustomBusinessHour(businessHour._id)); + await Promise.all(promises); }; export const getDefaultBusinessHour = async (): Promise => { - const response = await request.get(api('livechat/business-hour')).set(credentials).query({ type: LivechatBusinessHourTypes.DEFAULT }).expect(200); - return response.body.businessHour; + const response = await request + .get(api('livechat/business-hour')) + .set(credentials) + .query({ type: LivechatBusinessHourTypes.DEFAULT }) + .expect(200); + return response.body.businessHour; }; export const getCustomBusinessHourById = async (businessHourId: string): Promise => { - const response = await request.get(api('livechat/business-hour')).set(credentials).query({ type: LivechatBusinessHourTypes.CUSTOM, _id: businessHourId }).expect(200); - return response.body.businessHour; + const response = await request + .get(api('livechat/business-hour')) + .set(credentials) + .query({ type: LivechatBusinessHourTypes.CUSTOM, _id: businessHourId }) + .expect(200); + return response.body.businessHour; }; export const openOrCloseBusinessHour = async (businessHour: ILivechatBusinessHour, open: boolean) => { - const enabledBusinessHour = { - ...businessHour, - timezoneName: businessHour.timezone.name, - workHours: getWorkHours().map((workHour) => { - return { - ...workHour, - open, - } - }), - departmentsToApplyBusinessHour: businessHour.departments?.map((department) => department._id).join(',') || '', - } - - await saveBusinessHour(enabledBusinessHour as any); -} + const enabledBusinessHour = { + ...businessHour, + timezoneName: businessHour.timezone.name, + workHours: getWorkHours().map((workHour) => { + return { + ...workHour, + open, + }; + }), + departmentsToApplyBusinessHour: businessHour.departments?.map((department) => department._id).join(',') || '', + }; + + await saveBusinessHour(enabledBusinessHour as any); +}; export const getWorkHours = (open = true): ISaveBhApiWorkHour['workHours'] => { - const workHours: ISaveBhApiWorkHour['workHours'] = []; + const workHours: ISaveBhApiWorkHour['workHours'] = []; - for (let i = 0; i < 7; i++) { - workHours.push({ - day: moment().day(i).format('dddd'), - start: '00:00', - finish: '23:59', + for (let i = 0; i < 7; i++) { + workHours.push({ + day: moment().day(i).format('dddd'), + start: '00:00', + finish: '23:59', - open, - }); - } + open, + }); + } - return workHours; -} + return workHours; +}; diff --git a/apps/meteor/tests/data/livechat/canned-responses.ts b/apps/meteor/tests/data/livechat/canned-responses.ts index 7d56e0957e9f..23cfac13e236 100644 --- a/apps/meteor/tests/data/livechat/canned-responses.ts +++ b/apps/meteor/tests/data/livechat/canned-responses.ts @@ -1,24 +1,25 @@ import { faker } from '@faker-js/faker'; import type { IOmnichannelCannedResponse } from '@rocket.chat/core-typings'; + import { api, credentials, request } from '../api-data'; import type { DummyResponse } from './utils'; export const createCannedResponse = (): Promise> => new Promise((resolve, reject) => { - const response = { - shortcut: `${faker.lorem.word()}-${Date.now()}`, - scope: 'user', - tags: [faker.lorem.word()], - text: faker.lorem.sentence(), - }; + const response = { + shortcut: `${faker.lorem.word()}-${Date.now()}`, + scope: 'user', + tags: [faker.lorem.word()], + text: faker.lorem.sentence(), + }; return request .post(api(`canned-responses`)) .set(credentials) - .send(response) + .send(response) .end((_err: Error, _res: DummyResponse) => { - if (_err) { - return reject(_err); - } - resolve(response); - }); + if (_err) { + return reject(_err); + } + resolve(response); + }); }); diff --git a/apps/meteor/tests/data/livechat/custom-fields.ts b/apps/meteor/tests/data/livechat/custom-fields.ts index f41fcf41115f..f4878f6f754d 100644 --- a/apps/meteor/tests/data/livechat/custom-fields.ts +++ b/apps/meteor/tests/data/livechat/custom-fields.ts @@ -1,60 +1,61 @@ -import type { Response } from 'supertest'; import type { ILivechatCustomField } from '@rocket.chat/core-typings'; -import { credentials, request, methodCall, api } from './../api-data'; - -type ExtendedCustomField = Omit & { field: string }; +import type { Response } from 'supertest'; -export const createCustomField = (customField: ExtendedCustomField): Promise => new Promise((resolve, reject) => { - request - .get(api(`livechat/custom-fields/${customField.label}`)) - .set(credentials) - .send() - .end((err: Error, res: Response) => { - if (err) { - return reject(err); - } - if (res.body.customField != null && res.body.customField != undefined) { - resolve(res.body.customField); - } else { - request - .post(methodCall('livechat:saveCustomField')) - .send({ - message: JSON.stringify({ - method: 'livechat:saveCustomField', - params: [null, customField], - id: 'id', - msg: 'method', - }), - }) - .set(credentials) - .end((err: Error, res: Response): void => { - if (err) { - return reject(err); - } - resolve(res.body); - }); - } - }); +import { credentials, request, methodCall, api } from '../api-data'; -}); +type ExtendedCustomField = Omit & { field: string }; -export const deleteCustomField = (customFieldID: string) => new Promise((resolve, reject) => { - request - .post(methodCall('livechat:removeCustomField')) - .send({ - message: JSON.stringify({ - method: 'livechat:removeCustomField', - params: [customFieldID], - id: 'id', - msg: 'method', - }), - }) - .set(credentials) - .end((err: Error, res: Response): void => { - if (err) { - return reject(err); - } - resolve(res.body); - }); -}); +export const createCustomField = (customField: ExtendedCustomField): Promise => + new Promise((resolve, reject) => { + void request + .get(api(`livechat/custom-fields/${customField.label}`)) + .set(credentials) + .send() + .end((err: Error, res: Response) => { + if (err) { + return reject(err); + } + if (res.body.customField !== null && res.body.customField !== undefined) { + resolve(res.body.customField); + } else { + void request + .post(methodCall('livechat:saveCustomField')) + .send({ + message: JSON.stringify({ + method: 'livechat:saveCustomField', + params: [null, customField], + id: 'id', + msg: 'method', + }), + }) + .set(credentials) + .end((err: Error, res: Response): void => { + if (err) { + return reject(err); + } + resolve(res.body); + }); + } + }); + }); +export const deleteCustomField = (customFieldID: string) => + new Promise((resolve, reject) => { + void request + .post(methodCall('livechat:removeCustomField')) + .send({ + message: JSON.stringify({ + method: 'livechat:removeCustomField', + params: [customFieldID], + id: 'id', + msg: 'method', + }), + }) + .set(credentials) + .end((err: Error, res: Response): void => { + if (err) { + return reject(err); + } + resolve(res.body); + }); + }); diff --git a/apps/meteor/tests/data/livechat/department.ts b/apps/meteor/tests/data/livechat/department.ts index ba0df137b567..47d0f7f2b468 100644 --- a/apps/meteor/tests/data/livechat/department.ts +++ b/apps/meteor/tests/data/livechat/department.ts @@ -1,78 +1,85 @@ import { faker } from '@faker-js/faker'; -import { expect } from 'chai'; +import type { Credentials } from '@rocket.chat/api-client'; import type { ILivechatDepartment, IUser, LivechatDepartmentDTO } from '@rocket.chat/core-typings'; +import { expect } from 'chai'; + import { api, credentials, methodCall, request } from '../api-data'; -import { IUserCredentialsHeader } from '../user'; import { createAnOnlineAgent, createAnOfflineAgent } from './users'; -import { WithRequiredProperty } from './utils'; - -export const NewDepartmentData = ((): Partial => ({ - enabled: true, - name: `new department ${Date.now()}`, - description: 'created from api', - showOnRegistration: true, - email: faker.internet.email(), - showOnOfflineForm: true, +import type { WithRequiredProperty } from './utils'; + +const NewDepartmentData = ((): Partial => ({ + enabled: true, + name: `new department ${Date.now()}`, + description: 'created from api', + showOnRegistration: true, + email: faker.internet.email(), + showOnOfflineForm: true, }))(); export const createDepartment = async (departmentData: Partial = NewDepartmentData): Promise => { - const response = await request.post(api('livechat/department')).set(credentials).send({ - department: departmentData, - }).expect(200); - return response.body.department; -}; - -export const updateDepartment = async (departmentId: string, departmentData: Partial): Promise => { - const response = await request.put(api(`livechat/department/${ departmentId }`)).set(credentials).send({ - department: departmentData, - }).expect(200); - return response.body.department; + const response = await request + .post(api('livechat/department')) + .set(credentials) + .send({ + department: departmentData, + }) + .expect(200); + return response.body.department; }; -export const createDepartmentWithMethod = ( - initialAgents: { agentId: string, username: string }[] = [], - allowReceiveForwardOffline = false) => -new Promise((resolve, reject) => { - request - .post(methodCall('livechat:saveDepartment')) +const updateDepartment = async (departmentId: string, departmentData: Partial): Promise => { + const response = await request + .put(api(`livechat/department/${departmentId}`)) .set(credentials) .send({ - message: JSON.stringify({ - method: 'livechat:saveDepartment', - params: [ - '', - { - enabled: true, - email: faker.internet.email(), - showOnRegistration: true, - showOnOfflineForm: true, - name: `new department ${Date.now()}`, - description: 'created from api', - allowReceiveForwardOffline, - }, - initialAgents, - ], - id: 'id', - msg: 'method', - }), + department: departmentData, }) - .end((err: any, res: any) => { - if (err) { - return reject(err); - } - resolve(JSON.parse(res.body.message).result); - }); -}); + .expect(200); + return response.body.department; +}; + +const createDepartmentWithMethod = (initialAgents: { agentId: string; username: string }[] = [], allowReceiveForwardOffline = false) => + new Promise((resolve, reject) => { + void request + .post(methodCall('livechat:saveDepartment')) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'livechat:saveDepartment', + params: [ + '', + { + enabled: true, + email: faker.internet.email(), + showOnRegistration: true, + showOnOfflineForm: true, + name: `new department ${Date.now()}`, + description: 'created from api', + allowReceiveForwardOffline, + }, + initialAgents, + ], + id: 'id', + msg: 'method', + }), + }) + .end((err: any, res: any) => { + if (err) { + return reject(err); + } + resolve(JSON.parse(res.body.message).result); + }); + }); type OnlineAgent = { user: WithRequiredProperty; - credentials: IUserCredentialsHeader; + credentials: Credentials; }; -export const createDepartmentWithAnOnlineAgent = async (): Promise<{department: ILivechatDepartment, agent: OnlineAgent }> => { - const { user, credentials } = await createAnOnlineAgent(); +export const createDepartmentWithAnOnlineAgent = async (): Promise<{ department: ILivechatDepartment; agent: OnlineAgent }> => { + const { user, credentials } = await createAnOnlineAgent(); - const department = await createDepartmentWithMethod() as ILivechatDepartment; + const department = (await createDepartmentWithMethod()) as ILivechatDepartment; await addOrRemoveAgentFromDepartment(department._id, { agentId: user._id, username: user.username }, true); @@ -81,13 +88,13 @@ export const createDepartmentWithAnOnlineAgent = async (): Promise<{department: agent: { credentials, user, - } + }, }; }; export const createDepartmentWithAgent = async (agent: OnlineAgent): Promise<{ department: ILivechatDepartment; agent: OnlineAgent }> => { const { user, credentials } = agent; - const department = await createDepartmentWithMethod() as ILivechatDepartment; + const department = (await createDepartmentWithMethod()) as ILivechatDepartment; await addOrRemoveAgentFromDepartment(department._id, { agentId: user._id, username: user.username }, true); @@ -96,19 +103,27 @@ export const createDepartmentWithAgent = async (agent: OnlineAgent): Promise<{ d agent: { credentials, user, - } + }, }; -} +}; -export const addOrRemoveAgentFromDepartment = async (departmentId: string, agent: { agentId: string; username: string; count?: number; order?: number }, add: boolean) => { - const response = await request.post(api('livechat/department/' + departmentId + '/agents')).set(credentials).send({ - ...add ? { upsert: [agent], remove: [] } : { remove: [agent], upsert: [] }, - }); +export const addOrRemoveAgentFromDepartment = async ( + departmentId: string, + agent: { agentId: string; username: string; count?: number; order?: number }, + add: boolean, +) => { + const response = await request + .post(api(`livechat/department/${departmentId}/agents`)) + .set(credentials) + .send({ + ...(add ? { upsert: [agent], remove: [] } : { remove: [agent], upsert: [] }), + }); if (response.status !== 200) { - throw new Error('Failed to add or remove agent from department. Status code: ' + response.status + '\n' + response.body); + throw new Error(`Failed to add or remove agent from department. Status code: ${response.status}\n${response.body}`); } -} +}; + export const createDepartmentWithAnOfflineAgent = async ({ allowReceiveForwardOffline = false, }: { @@ -116,7 +131,7 @@ export const createDepartmentWithAnOfflineAgent = async ({ }): Promise<{ department: ILivechatDepartment; agent: { - credentials: IUserCredentialsHeader; + credentials: Credentials; user: WithRequiredProperty; }; }> => { @@ -136,21 +151,30 @@ export const createDepartmentWithAnOfflineAgent = async ({ }; export const archiveDepartment = async (departmentId: string): Promise => { - await request.post(api(`livechat/department/${ departmentId }/archive`)).set(credentials).expect(200); -} + await request + .post(api(`livechat/department/${departmentId}/archive`)) + .set(credentials) + .expect(200); +}; export const disableDepartment = async (department: ILivechatDepartment): Promise => { - department.enabled = false; - delete department._updatedAt; - const updatedDepartment = await updateDepartment(department._id, department); - expect(updatedDepartment.enabled).to.be.false; -} + department.enabled = false; + delete department._updatedAt; + const updatedDepartment = await updateDepartment(department._id, department); + expect(updatedDepartment.enabled).to.be.false; +}; export const deleteDepartment = async (departmentId: string): Promise => { - await request.delete(api(`livechat/department/${ departmentId }`)).set(credentials).expect(200); -} + await request + .delete(api(`livechat/department/${departmentId}`)) + .set(credentials) + .expect(200); +}; export const getDepartmentById = async (departmentId: string): Promise => { - const response = await request.get(api(`livechat/department/${ departmentId }`)).set(credentials).expect(200); - return response.body.department; + const response = await request + .get(api(`livechat/department/${departmentId}`)) + .set(credentials) + .expect(200); + return response.body.department; }; diff --git a/apps/meteor/tests/data/livechat/inboxes.ts b/apps/meteor/tests/data/livechat/inboxes.ts index ccc7c742da1a..7def060d3cb3 100644 --- a/apps/meteor/tests/data/livechat/inboxes.ts +++ b/apps/meteor/tests/data/livechat/inboxes.ts @@ -1,31 +1,31 @@ import { getCredentials, api, request, credentials } from '../api-data'; export const createEmailInbox = async (): Promise<{ _id: string }> => { - await getCredentials() - const { body } = await request - .post(api('email-inbox')) - .set(credentials) - .send({ - name: 'test', - active: false, - email: `test${new Date().getTime()}@test.com`, - description: 'test', - senderInfo: 'test', - smtp: { - server: 'smtp.example.com', - port: 587, - username: 'xxxx', - password: 'xxxx', - secure: true, - }, - imap: { - server: 'imap.example.com', - port: 993, - username: 'xxxx', - password: 'xxxx', - secure: true, - maxRetries: 10, - }, - }); - return body; -} + await new Promise((resolve) => getCredentials(resolve)); + const { body } = await request + .post(api('email-inbox')) + .set(credentials) + .send({ + name: 'test', + active: false, + email: `test${new Date().getTime()}@test.com`, + description: 'test', + senderInfo: 'test', + smtp: { + server: 'smtp.example.com', + port: 587, + username: 'xxxx', + password: 'xxxx', + secure: true, + }, + imap: { + server: 'imap.example.com', + port: 993, + username: 'xxxx', + password: 'xxxx', + secure: true, + maxRetries: 10, + }, + }); + return body; +}; diff --git a/apps/meteor/tests/data/livechat/inquiries.ts b/apps/meteor/tests/data/livechat/inquiries.ts index b108e1d4d80e..94f4ce295556 100644 --- a/apps/meteor/tests/data/livechat/inquiries.ts +++ b/apps/meteor/tests/data/livechat/inquiries.ts @@ -1,9 +1,11 @@ +/* eslint-disable no-await-in-loop */ +import type { Credentials } from '@rocket.chat/api-client'; import type { ILivechatInquiryRecord } from '@rocket.chat/core-typings'; import type { PaginatedResult } from '@rocket.chat/rest-typings'; -import { api, request } from '../api-data'; +import { api, request } from '../api-data'; -export const fetchAllInquiries = async (credentials: { 'X-Auth-Token': string; 'X-User-Id': string; }, department?: string): Promise => { +export const fetchAllInquiries = async (credentials: Credentials, department?: string): Promise => { const inquiries: ILivechatInquiryRecord[] = []; let hasMore = true; @@ -26,6 +28,5 @@ export const fetchAllInquiries = async (credentials: { 'X-Auth-Token': string; ' offset += body.count; } - return inquiries; -} +}; diff --git a/apps/meteor/tests/data/livechat/priorities.ts b/apps/meteor/tests/data/livechat/priorities.ts index 32f8e5335234..e77845f614ec 100644 --- a/apps/meteor/tests/data/livechat/priorities.ts +++ b/apps/meteor/tests/data/livechat/priorities.ts @@ -1,12 +1,13 @@ -import { api, credentials, request } from '../api-data'; -import type { DummyResponse } from './utils'; +import type { ILivechatPriority, IOmnichannelServiceLevelAgreements } from '@rocket.chat/core-typings'; import { expect } from 'chai'; + import { generateRandomSLAData } from '../../e2e/utils/omnichannel/sla'; -import type { ILivechatPriority, IOmnichannelServiceLevelAgreements } from '@rocket.chat/core-typings'; +import { api, credentials, request } from '../api-data'; +import type { DummyResponse } from './utils'; export const createSLA = (): Promise> => { return new Promise((resolve, reject) => { - request + void request .post(api('livechat/sla')) .set(credentials) .send(generateRandomSLAData()) @@ -21,7 +22,7 @@ export const createSLA = (): Promise => { return new Promise((resolve, reject) => { - request + void request .delete(api(`livechat/sla/${id}`)) .set(credentials) .send() @@ -67,4 +68,4 @@ export const getRandomPriority = async (): Promise => { body: { priorities }, } = response as { body: { priorities: ILivechatPriority[] } }; return priorities[Math.floor(Math.random() * priorities.length)]; -} +}; diff --git a/apps/meteor/tests/data/livechat/rooms.ts b/apps/meteor/tests/data/livechat/rooms.ts index 921e7bb08582..e2084adda934 100644 --- a/apps/meteor/tests/data/livechat/rooms.ts +++ b/apps/meteor/tests/data/livechat/rooms.ts @@ -1,4 +1,6 @@ +/* eslint-disable no-await-in-loop */ import { faker } from '@faker-js/faker'; +import type { Credentials } from '@rocket.chat/api-client'; import type { ILivechatInquiryRecord, ILivechatAgent, @@ -7,13 +9,15 @@ import type { IMessage, IOmnichannelRoom, } from '@rocket.chat/core-typings'; +import type { Response } from 'supertest'; + import { api, credentials, methodCall, request } from '../api-data'; +import { imgURL } from '../interactions'; import { getSettingValueById, restorePermissionToRoles, updateSetting } from '../permissions.helper'; -import { IUserCredentialsHeader, adminUsername } from '../user'; +import { adminUsername } from '../user'; import { getRandomVisitorToken } from './users'; -import { DummyResponse, sleep } from './utils'; -import { Response } from 'supertest'; -import { imgURL } from '../interactions'; +import type { DummyResponse } from './utils'; +import { sleep } from './utils'; export const createLivechatRoom = async (visitorToken: string, extraRoomParams?: Record): Promise => { const urlParams = new URLSearchParams(); @@ -24,10 +28,7 @@ export const createLivechatRoom = async (visitorToken: string, extraRoomParams?: } } - const response = await request - .get(api(`livechat/room?${urlParams.toString()}`)) - .set(credentials) - .expect(200); + const response = await request.get(api('livechat/room')).query(urlParams.toString()).set(credentials).expect(200); return response.body.room; }; @@ -37,11 +38,11 @@ export const createVisitor = (department?: string, visitorName?: string): Promis const token = getRandomVisitorToken(); const email = `${token}@${token}.com`; const phone = `${Math.floor(Math.random() * 10000000000)}`; - request.get(api(`livechat/visitor/${token}`)).end((err: Error, res: DummyResponse) => { + void request.get(api(`livechat/visitor/${token}`)).end((err: Error, res: DummyResponse) => { if (!err && res && res.body && res.body.visitor) { return resolve(res.body.visitor); } - request + void request .post(api('livechat/visitor')) .set(credentials) .send({ @@ -65,18 +66,23 @@ export const createVisitor = (department?: string, visitorName?: string): Promis export const deleteVisitor = async (token: string): Promise => { await request.delete(api(`livechat/visitor/${token}`)); -} +}; -export const takeInquiry = async (inquiryId: string, agentCredentials?: IUserCredentialsHeader): Promise => { - const userId = agentCredentials ? agentCredentials['X-User-Id'] : credentials['X-User-Id']; +export const takeInquiry = async (inquiryId: string, agentCredentials?: Credentials): Promise => { + const userId = agentCredentials ? agentCredentials['X-User-Id'] : credentials['X-User-Id']; - await request.post(api('livechat/inquiries.take')).set(agentCredentials || credentials).send({ userId, inquiryId }).expect(200); + await request + .post(api('livechat/inquiries.take')) + .set(agentCredentials || credentials) + .send({ userId, inquiryId }) + .expect(200); }; export const fetchInquiry = (roomId: string): Promise => { return new Promise((resolve, reject) => { - request - .get(api(`livechat/inquiries.getOne?roomId=${roomId}`)) + void request + .get(api('livechat/inquiries.getOne')) + .query({ roomId }) .set(credentials) .end((err: Error, res: DummyResponse) => { if (err) { @@ -87,9 +93,14 @@ export const fetchInquiry = (roomId: string): Promise => }); }; -export const createDepartment = (agents?: { agentId: string }[], name?: string, enabled = true, opts: Record = {}): Promise => { +export const createDepartment = ( + agents?: { agentId: string }[], + name?: string, + enabled = true, + opts: Record = {}, +): Promise => { return new Promise((resolve, reject) => { - request + void request .post(api('livechat/department')) .set(credentials) .send({ @@ -114,7 +125,7 @@ export const createDepartment = (agents?: { agentId: string }[], name?: string, export const createAgent = (overrideUsername?: string): Promise => new Promise((resolve, reject) => { - request + void request .post(api('livechat/users/agent')) .set(credentials) .send({ @@ -130,7 +141,7 @@ export const createAgent = (overrideUsername?: string): Promise export const createManager = (overrideUsername?: string): Promise => new Promise((resolve, reject) => { - request + void request .post(api('livechat/users/manager')) .set(credentials) .send({ @@ -144,7 +155,7 @@ export const createManager = (overrideUsername?: string): Promise => { +export const makeAgentAvailable = async (overrideCredentials?: Credentials): Promise => { await restorePermissionToRoles('view-l-room'); await request .post(api('users.setStatus')) @@ -162,7 +173,7 @@ export const makeAgentAvailable = async (overrideCredentials?: { 'X-Auth-Token': }); }; -export const makeAgentUnavailable = async (overrideCredentials?: { 'X-Auth-Token': string; 'X-User-Id': string }): Promise => { +export const makeAgentUnavailable = async (overrideCredentials?: Credentials): Promise => { await request .post(api('users.setStatus')) .set(overrideCredentials || credentials) @@ -179,7 +190,7 @@ export const makeAgentUnavailable = async (overrideCredentials?: { 'X-Auth-Token export const getLivechatRoomInfo = (roomId: string): Promise => { return new Promise((resolve /* , reject*/) => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -193,10 +204,10 @@ export const getLivechatRoomInfo = (roomId: string): Promise = /** * @summary Sends message as visitor -*/ + */ export const sendMessage = (roomId: string, message: string, visitorToken: string): Promise => { return new Promise((resolve, reject) => { - request + void request .post(api('livechat/message')) .set(credentials) .send({ @@ -215,7 +226,7 @@ export const sendMessage = (roomId: string, message: string, visitorToken: strin export const uploadFile = (roomId: string, visitorToken: string): Promise => { return new Promise((resolve, reject) => { - request + void request .post(api(`livechat/upload/${roomId}`)) .set({ 'x-visitor-token': visitorToken, ...credentials }) .attach('file', imgURL) @@ -231,7 +242,7 @@ export const uploadFile = (roomId: string, visitorToken: string): Promise => { return new Promise((resolve, reject) => { - request + void request .post(methodCall('sendMessage')) .set(credentials) .send({ @@ -253,7 +264,7 @@ export const sendAgentMessage = (roomId: string, msg?: string): Promise => { return new Promise((resolve, reject) => { - request + void request .get(api(`livechat/messages.history/${roomId}`)) .set(credentials) .query({ @@ -275,7 +286,11 @@ export const fetchMessages = (roomId: string, visitorToken: string): Promise => { - await request.post(api('livechat/room.closeByUser')).set(credentials).send({ rid: roomId, ...tags && { tags }, comment: faker.lorem.sentence() }).expect(200); + await request + .post(api('livechat/room.closeByUser')) + .set(credentials) + .send({ rid: roomId, ...(tags && { tags }), comment: faker.lorem.sentence() }) + .expect(200); }; export const bulkCreateLivechatRooms = async ( @@ -298,22 +313,20 @@ export const bulkCreateLivechatRooms = async ( }; export const startANewLivechatRoomAndTakeIt = async ({ - departmentId, - agent + departmentId, + agent, }: { - departmentId?: string; - agent?: IUserCredentialsHeader; + departmentId?: string; + agent?: Credentials; } = {}): Promise<{ room: IOmnichannelRoom; visitor: ILivechatVisitor }> => { + const currentRoutingMethod = await getSettingValueById('Livechat_Routing_Method'); + const routingMethodChanged = false; + if (currentRoutingMethod !== 'Manual_Selection') { + await updateSetting('Livechat_Routing_Method', 'Manual_Selection'); - const currentRoutingMethod = await getSettingValueById('Livechat_Routing_Method'); - let routingMethodChanged = false; - if (currentRoutingMethod !== 'Manual_Selection') { - await updateSetting('Livechat_Routing_Method', 'Manual_Selection'); - - // wait for routing algorithm to stop - await sleep(1000); - } - + // wait for routing algorithm to stop + await sleep(1000); + } const visitor = await createVisitor(departmentId); const room = await createLivechatRoom(visitor.token); @@ -322,26 +335,21 @@ export const startANewLivechatRoomAndTakeIt = async ({ await takeInquiry(inq._id, agent); await sendMessage(roomId, 'test message', visitor.token); + if (routingMethodChanged) { + await updateSetting('Livechat_Routing_Method', currentRoutingMethod); - if (routingMethodChanged) { - await updateSetting('Livechat_Routing_Method', currentRoutingMethod); - - // wait for routing algorithm to start - await sleep(1000); - } + // wait for routing algorithm to start + await sleep(1000); + } return { room, visitor }; }; export const placeRoomOnHold = async (roomId: string): Promise => { - await request - .post(api('livechat/room.onHold')) - .set(credentials) - .send({ roomId }) - .expect(200); -} - -export const moveBackToQueue = async (roomId: string, overrideCredentials?: IUserCredentialsHeader): Promise => { + await request.post(api('livechat/room.onHold')).set(credentials).send({ roomId }).expect(200); +}; + +export const moveBackToQueue = async (roomId: string, overrideCredentials?: Credentials): Promise => { await request .post(methodCall('livechat:returnAsInquiry')) .set(overrideCredentials || credentials) diff --git a/apps/meteor/tests/data/livechat/tags.ts b/apps/meteor/tests/data/livechat/tags.ts index b12cca1f64ae..5f5cac0e4039 100644 --- a/apps/meteor/tests/data/livechat/tags.ts +++ b/apps/meteor/tests/data/livechat/tags.ts @@ -1,17 +1,18 @@ import { faker } from '@faker-js/faker'; import type { ILivechatTag } from '@rocket.chat/core-typings'; + import { credentials, methodCall, request } from '../api-data'; import type { DummyResponse } from './utils'; export const saveTags = (departments: string[] = []): Promise => { - return new Promise((resolve, reject) => { - request + return new Promise((resolve, reject) => { + void request .post(methodCall(`livechat:saveTag`)) .set(credentials) .send({ message: JSON.stringify({ method: 'livechat:saveTag', - params: [undefined, { name: faker.person.firstName(), description: faker.lorem.sentence() }, departments], + params: [undefined, { name: faker.person.firstName(), description: faker.lorem.sentence() }, departments], id: '101', msg: 'method', }), @@ -27,7 +28,7 @@ export const saveTags = (departments: string[] = []): Promise => { export const removeTag = (id: string): Promise => { return new Promise((resolve, reject) => { - request + void request .post(methodCall(`livechat:removeTag`)) .set(credentials) .send({ @@ -43,7 +44,6 @@ export const removeTag = (id: string): Promise => { return reject(err); } resolve(JSON.parse(res.body.message).result); - } - ); + }); }); -}; \ No newline at end of file +}; diff --git a/apps/meteor/tests/data/livechat/triggers.ts b/apps/meteor/tests/data/livechat/triggers.ts index d3886cb34de7..4c8905a50825 100644 --- a/apps/meteor/tests/data/livechat/triggers.ts +++ b/apps/meteor/tests/data/livechat/triggers.ts @@ -1,17 +1,36 @@ import { faker } from '@faker-js/faker'; import type { ILivechatTrigger } from '@rocket.chat/core-typings'; + import { api, credentials, methodCall, request } from '../api-data'; import type { DummyResponse } from './utils'; export const createTrigger = (name: string): Promise => { - return new Promise((resolve, reject) => { - request + return new Promise((resolve, reject) => { + void request .post(methodCall(`livechat:saveTrigger`)) .set(credentials) .send({ message: JSON.stringify({ method: 'livechat:saveTrigger', - params: [{ name, description: faker.lorem.sentence(), enabled: true, runOnce: faker.datatype.boolean(), actions: [{ name: 'send-message', params: { msg: faker.lorem.sentence(), name: faker.person.firstName(), sender: faker.helpers.arrayElement(['queue', 'custom']) } }], conditions: [{ name: faker.lorem.word(), value: faker.number.int() }] }], + params: [ + { + name, + description: faker.lorem.sentence(), + enabled: true, + runOnce: faker.datatype.boolean(), + actions: [ + { + name: 'send-message', + params: { + msg: faker.lorem.sentence(), + name: faker.person.firstName(), + sender: faker.helpers.arrayElement(['queue', 'custom']), + }, + }, + ], + conditions: [{ name: faker.lorem.word(), value: faker.number.int() }], + }, + ], id: '101', msg: 'method', }), @@ -26,15 +45,15 @@ export const createTrigger = (name: string): Promise => { }; export const fetchTriggers = (): Promise => { - return new Promise((resolve, reject) => { - request - .get(api('livechat/triggers')) - .set(credentials) - .end((err: Error, res: DummyResponse) => { - if (err) { - return reject(err); - } - resolve(res.body.triggers); - }); - }); + return new Promise((resolve, reject) => { + void request + .get(api('livechat/triggers')) + .set(credentials) + .end((err: Error, res: DummyResponse) => { + if (err) { + return reject(err); + } + resolve(res.body.triggers); + }); + }); }; diff --git a/apps/meteor/tests/data/livechat/units.ts b/apps/meteor/tests/data/livechat/units.ts index c42d7ad5b345..03ea578e654d 100644 --- a/apps/meteor/tests/data/livechat/units.ts +++ b/apps/meteor/tests/data/livechat/units.ts @@ -1,11 +1,12 @@ -import { faker } from "@faker-js/faker"; -import type { IOmnichannelBusinessUnit } from "@rocket.chat/core-typings"; -import { methodCall, credentials, request } from "../api-data"; -import type { DummyResponse } from "./utils"; +import { faker } from '@faker-js/faker'; +import type { IOmnichannelBusinessUnit } from '@rocket.chat/core-typings'; + +import { methodCall, credentials, request } from '../api-data'; +import type { DummyResponse } from './utils'; export const createMonitor = async (username: string): Promise<{ _id: string; username: string }> => { - return new Promise((resolve, reject) => { - request + return new Promise((resolve, reject) => { + void request .post(methodCall(`livechat:addMonitor`)) .set(credentials) .send({ @@ -25,24 +26,34 @@ export const createMonitor = async (username: string): Promise<{ _id: string; us }); }; -export const createUnit = async (monitorId: string, username: string, departmentIds: string[], name?: string): Promise => { - return new Promise((resolve, reject) => { - request - .post(methodCall(`livechat:saveUnit`)) - .set(credentials) - .send({ - message: JSON.stringify({ - method: 'livechat:saveUnit', - params: [null, { name: name || faker.person.firstName(), visibility: faker.helpers.arrayElement(['public', 'private']) }, [{ monitorId, username }], departmentIds.map((departmentId) => ({ departmentId }))], - id: '101', - msg: 'method', - }), - }) - .end((err: Error, res: DummyResponse) => { - if (err) { - return reject(err); - } - resolve(JSON.parse(res.body.message).result); - }); - }); +export const createUnit = async ( + monitorId: string, + username: string, + departmentIds: string[], + name?: string, +): Promise => { + return new Promise((resolve, reject) => { + void request + .post(methodCall(`livechat:saveUnit`)) + .set(credentials) + .send({ + message: JSON.stringify({ + method: 'livechat:saveUnit', + params: [ + null, + { name: name || faker.person.firstName(), visibility: faker.helpers.arrayElement(['public', 'private']) }, + [{ monitorId, username }], + departmentIds.map((departmentId) => ({ departmentId })), + ], + id: '101', + msg: 'method', + }), + }) + .end((err: Error, res: DummyResponse) => { + if (err) { + return reject(err); + } + resolve(JSON.parse(res.body.message).result); + }); + }); }; diff --git a/apps/meteor/tests/data/livechat/users.ts b/apps/meteor/tests/data/livechat/users.ts index 161c20749b6c..9d0bfd04f170 100644 --- a/apps/meteor/tests/data/livechat/users.ts +++ b/apps/meteor/tests/data/livechat/users.ts @@ -1,65 +1,66 @@ -import { faker } from "@faker-js/faker"; -import type { ILivechatAgent, IUser } from "@rocket.chat/core-typings"; -import { IUserCredentialsHeader, password } from "../user"; -import { createUser, login } from "../users.helper"; -import { createAgent, makeAgentAvailable, makeAgentUnavailable } from "./rooms"; -import { api, credentials, request } from "../api-data"; +import { faker } from '@faker-js/faker'; +import type { Credentials } from '@rocket.chat/api-client'; +import type { ILivechatAgent, IUser } from '@rocket.chat/core-typings'; + +import { api, credentials, request } from '../api-data'; +import { password } from '../user'; +import { createUser, login } from '../users.helper'; +import { createAgent, makeAgentAvailable, makeAgentUnavailable } from './rooms'; export const createBotAgent = async (): Promise<{ - credentials: { 'X-Auth-Token': string; 'X-User-Id': string; }; + credentials: Credentials; user: IUser; }> => { - const agent: IUser = await createUser({ - roles: ['bot'] - }); + const agent = await createUser({ + roles: ['bot'], + }); const createdUserCredentials = await login(agent.username, password); await createAgent(agent.username); await makeAgentAvailable(createdUserCredentials); - return { - credentials: createdUserCredentials, - user: agent, - }; -} + return { + credentials: createdUserCredentials, + user: agent, + }; +}; export const getRandomVisitorToken = (): string => faker.string.alphanumeric(17); export const getAgent = async (userId: string): Promise => { - const { body } = await request.get(api(`livechat/users/agent/${userId}`)) - .set(credentials) - .expect(200); - return body.user; -} + const { body } = await request + .get(api(`livechat/users/agent/${userId}`)) + .set(credentials) + .expect(200); + return body.user; +}; export const removeAgent = async (userId: string): Promise => { - await request.delete(api(`livechat/users/agent/${userId}`)) - .set(credentials) - .expect(200); -} + await request + .delete(api(`livechat/users/agent/${userId}`)) + .set(credentials) + .expect(200); +}; export const createAnOnlineAgent = async (): Promise<{ - credentials: IUserCredentialsHeader; - user: IUser & { username: string }; + credentials: Credentials; + user: IUser & { username: string }; }> => { - const username = `user.test.${Date.now()}`; - const email = `${username}@rocket.chat`; - const { body } = await request - .post(api('users.create')) - .set(credentials) - .send({ email, name: username, username, password }); - const agent = body.user; - const createdUserCredentials = await login(agent.username, password); - await createAgent(agent.username); - await makeAgentAvailable(createdUserCredentials); + const username = `user.test.${Date.now()}`; + const email = `${username}@rocket.chat`; + const { body } = await request.post(api('users.create')).set(credentials).send({ email, name: username, username, password }); + const agent = body.user; + const createdUserCredentials = await login(agent.username, password); + await createAgent(agent.username); + await makeAgentAvailable(createdUserCredentials); - return { - credentials: createdUserCredentials, - user: agent, - }; -} + return { + credentials: createdUserCredentials, + user: agent, + }; +}; export const createAnOfflineAgent = async (): Promise<{ - credentials: IUserCredentialsHeader; + credentials: Credentials; user: IUser & { username: string }; }> => { const username = `user.test.${Date.now()}.offline`; @@ -74,4 +75,4 @@ export const createAnOfflineAgent = async (): Promise<{ credentials: createdUserCredentials, user: agent, }; -}; \ No newline at end of file +}; diff --git a/apps/meteor/tests/data/livechat/utils.ts b/apps/meteor/tests/data/livechat/utils.ts index 3d82ecdd58f7..cf4b906c1878 100644 --- a/apps/meteor/tests/data/livechat/utils.ts +++ b/apps/meteor/tests/data/livechat/utils.ts @@ -1,5 +1,4 @@ -export type DummyResponse = - E extends 'wrapped' ? { body: { [k: string]: T } } : { body: T }; +export type DummyResponse = E extends 'wrapped' ? { body: { [k: string]: T } } : { body: T }; export type WithRequiredProperty = Type & { [Property in Key]-?: Type[Property]; @@ -7,7 +6,7 @@ export type WithRequiredProperty = Type & { export const sleep = (ms: number) => { return new Promise((resolve) => setTimeout(resolve, ms)); -} +}; export const parseMethodResponse = (response: any) => { if (response.message) { @@ -15,4 +14,4 @@ export const parseMethodResponse = (response: any) => { } return {}; -} \ No newline at end of file +}; diff --git a/apps/meteor/tests/data/livechat/visitor.ts b/apps/meteor/tests/data/livechat/visitor.ts index 86c1043fb05d..ed29296bd27d 100644 --- a/apps/meteor/tests/data/livechat/visitor.ts +++ b/apps/meteor/tests/data/livechat/visitor.ts @@ -1,9 +1,13 @@ -import { ILivechatVisitor } from '@rocket.chat/core-typings'; +import type { ILivechatVisitor } from '@rocket.chat/core-typings'; import { expect } from 'chai'; + import { api, credentials, request } from '../api-data'; export const getLivechatVisitorByToken = async (token: string): Promise => { - const response = await request.get(api(`livechat/visitor/${token}`)).set(credentials).expect(200); - expect(response.body).to.have.property('visitor'); - return response.body.visitor; -} + const response = await request + .get(api(`livechat/visitor/${token}`)) + .set(credentials) + .expect(200); + expect(response.body).to.have.property('visitor'); + return response.body.visitor; +}; diff --git a/apps/meteor/tests/data/moderation.helper.ts b/apps/meteor/tests/data/moderation.helper.ts deleted file mode 100644 index 459fb43bad96..000000000000 --- a/apps/meteor/tests/data/moderation.helper.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { api, credentials, request } from './api-data'; - -export const makeModerationApiRequest = async (url: string, method: 'get' | 'post', data?: any) => { - let res: any; - - if (method === 'get') { - res = await request.get(api(url)).set(credentials).query(data); - } else if (method === 'post') { - res = await request.post(api(url)).set(credentials).send(data); - } - - return res.body; -}; - -export const reportUser = (userId: string, reason: string) => makeModerationApiRequest('moderation.reportUser', 'post', { userId, reason }); - -export const getUsersReports = (userId: string) => makeModerationApiRequest('moderation.user.reportsByUserId', 'get', { userId }); diff --git a/apps/meteor/tests/data/permissions.helper.ts b/apps/meteor/tests/data/permissions.helper.ts index 471317601511..33e9af1693ad 100644 --- a/apps/meteor/tests/data/permissions.helper.ts +++ b/apps/meteor/tests/data/permissions.helper.ts @@ -1,43 +1,44 @@ import type { ISetting } from '@rocket.chat/core-typings'; -import { IS_EE } from '../e2e/config/constants'; -import { api, credentials, request } from './api-data'; + import { permissions } from '../../app/authorization/server/constant/permissions'; import { omnichannelEEPermissions } from '../../ee/app/livechat-enterprise/server/permissions'; +import { IS_EE } from '../e2e/config/constants'; +import { api, credentials, request } from './api-data'; -export const updatePermission = (permission:string, roles:string[]):Promise => - new Promise((resolve,reject) => { - request +export const updatePermission = (permission: string, roles: string[]): Promise => + new Promise((resolve, reject) => { + void request .post(api('permissions.update')) .set(credentials) .send({ permissions: [{ _id: permission, roles }] }) .expect('Content-Type', 'application/json') .expect(200) - .end((err?:Error) => setTimeout(() => !err && resolve() || reject(err), 100)); + .end((err?: Error) => setTimeout(() => (!err && resolve()) || reject(err), 100)); }); -export const updateEEPermission = (permission:string, roles:string[]):Promise => +export const updateEEPermission = (permission: string, roles: string[]): Promise => IS_EE ? updatePermission(permission, roles) : Promise.resolve(); -export const updateManyPermissions = (permissions: { [key: string]: string[] }):Promise => - new Promise((resolve,reject) => { - request +const updateManyPermissions = (permissions: { [key: string]: string[] }): Promise => + new Promise((resolve, reject) => { + void request .post(api('permissions.update')) .set(credentials) - .send({ permissions: Object.keys(permissions).map((k) => ({_id: k, roles: permissions[k] }))}) + .send({ permissions: Object.keys(permissions).map((k) => ({ _id: k, roles: permissions[k] })) }) .expect('Content-Type', 'application/json') .expect(200) - .end((err?:Error) => setTimeout(() => !err && resolve() || reject(err), 100)); + .end((err?: Error) => setTimeout(() => (!err && resolve()) || reject(err), 100)); }); -export const updateSetting = (setting:string, value:ISetting['value']):Promise => - new Promise((resolve,reject) => { - request +export const updateSetting = (setting: string, value: ISetting['value']): Promise => + new Promise((resolve, reject) => { + void request .post(`/api/v1/settings/${setting}`) .set(credentials) .send({ value }) .expect('Content-Type', 'application/json') .expect(200) - .end((err?:Error) => setTimeout(() => !err && resolve() || reject(err), 100)); + .end((err?: Error) => setTimeout(() => (!err && resolve()) || reject(err), 100)); }); export const getSettingValueById = async (setting: string): Promise => { @@ -46,17 +47,18 @@ export const getSettingValueById = async (setting: string): Promise => - IS_EE ? new Promise((resolve,reject) => { - request - .post(`/api/v1/settings/${setting}`) - .set(credentials) - .send({ value }) - .expect('Content-Type', 'application/json') - .expect(200) - .end((err?:Error) => setTimeout(() => !err && resolve() || reject(err), 100)); - }) : Promise.resolve(); +export const updateEESetting = (setting: string, value: ISetting['value']): Promise => + IS_EE + ? new Promise((resolve, reject) => { + void request + .post(`/api/v1/settings/${setting}`) + .set(credentials) + .send({ value }) + .expect('Content-Type', 'application/json') + .expect(200) + .end((err?: Error) => setTimeout(() => (!err && resolve()) || reject(err), 100)); + }) + : Promise.resolve(); export const removePermissions = async (perms: string[]) => { await updateManyPermissions(Object.fromEntries(perms.map((name) => [name, []]))); @@ -66,37 +68,37 @@ export const addPermissions = async (perms: { [key: string]: string[] }) => { await updateManyPermissions(perms); }; -type Permission = typeof permissions[number]['_id'] +type Permission = (typeof permissions)[number]['_id']; export const removePermissionFromAllRoles = async (permission: Permission) => { - await updatePermission(permission, []); + await updatePermission(permission, []); }; -export const restorePermissionToRoles = async (permission: Permission) => { - const defaultPermission = getPermissions().find((p) => p._id === permission); - if (!defaultPermission) { - throw new Error(`No default roles found for permission ${permission}`); - } - - const mutableDefaultRoles: string[] = defaultPermission.roles.map((r) => r); +const getPermissions = () => { + if (!IS_EE) { + return permissions; + } - if (!IS_EE) { - const eeOnlyRoles = ['livechat-monitor']; - eeOnlyRoles.forEach((role) => { - const index = mutableDefaultRoles.indexOf(role); - if (index !== -1) { - mutableDefaultRoles.splice(index, 1); - } - }); - } + return [...permissions, ...omnichannelEEPermissions]; +}; - await updatePermission(permission, mutableDefaultRoles); -} +export const restorePermissionToRoles = async (permission: Permission) => { + const defaultPermission = getPermissions().find((p) => p._id === permission); + if (!defaultPermission) { + throw new Error(`No default roles found for permission ${permission}`); + } -const getPermissions = () => { - if (!IS_EE) { - return permissions; - } + const mutableDefaultRoles: string[] = defaultPermission.roles.map((r) => r); - return [...permissions, ...omnichannelEEPermissions] -} + if (!IS_EE) { + const eeOnlyRoles = ['livechat-monitor']; + eeOnlyRoles.forEach((role) => { + const index = mutableDefaultRoles.indexOf(role); + if (index !== -1) { + mutableDefaultRoles.splice(index, 1); + } + }); + } + + await updatePermission(permission, mutableDefaultRoles); +}; diff --git a/apps/meteor/tests/data/role.ts b/apps/meteor/tests/data/role.ts deleted file mode 100644 index 2d68825f3a2e..000000000000 --- a/apps/meteor/tests/data/role.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const roleNameUsers = `role-name-test-users-${Date.now()}`; -export const roleNameSubscriptions = `role-name-test-subscriptions-${Date.now()}`; -export const roleScopeUsers = 'Users'; -export const roleScopeSubscriptions = 'Subscriptions'; -export const roleDescription = `role-description-test-${Date.now()}`; diff --git a/apps/meteor/tests/data/rooms.helper.ts b/apps/meteor/tests/data/rooms.helper.ts index 384ac5614e41..410e6e7ca48c 100644 --- a/apps/meteor/tests/data/rooms.helper.ts +++ b/apps/meteor/tests/data/rooms.helper.ts @@ -1,8 +1,7 @@ +import type { Credentials } from '@rocket.chat/api-client'; import type { IRoom } from '@rocket.chat/core-typings'; -import { api, credentials, request } from './api-data'; -import type { IUser } from '@rocket.chat/core-typings'; -type Credentials = { 'X-Auth-Token'?: string; 'X-User-Id'?: string }; +import { api, credentials, request } from './api-data'; type CreateRoomParams = { name?: IRoom['name']; @@ -38,7 +37,8 @@ export const createRoom = ({ * is handled separately here. */ return request - .get(api(`voip/room?token=${token}&agentId=${agentId}&direction=${voipCallDirection}`)) + .get(api('voip/room')) + .query({ token, agentId, direction: voipCallDirection }) .set(customCredentials || credentials) .send(); } @@ -51,7 +51,7 @@ export const createRoom = ({ c: 'channels.create', p: 'groups.create', d: 'im.create', - }; + } as const; const params = type === 'd' ? { username } : { name }; // Safe assertion because we already checked the type is not 'v' @@ -68,13 +68,8 @@ export const createRoom = ({ }); }; -export const asyncCreateRoom = ({ name, type, username, members = [] }: Pick) => - new Promise((resolve) => { - createRoom({ name, type, username, members }).end(resolve); - }); - type ActionType = 'delete' | 'close' | 'addOwner' | 'removeOwner'; -type ActionRoomParams = { +export type ActionRoomParams = { action: ActionType; type: Exclude; roomId: IRoom['_id']; @@ -82,7 +77,7 @@ type ActionRoomParams = { extraData?: Record; }; -function actionRoom({ action, type, roomId, overrideCredentials = credentials, extraData = {} }: ActionRoomParams) { +export function actionRoom({ action, type, roomId, overrideCredentials = credentials, extraData = {} }: ActionRoomParams) { if (!type) { throw new Error(`"type" is required in "${action}Room" test helper`); } @@ -93,10 +88,15 @@ function actionRoom({ action, type, roomId, overrideCredentials = credentials, e c: 'channels', p: 'groups', d: 'im', - }; + } as const; + + const path = `${endpoints[type]}.${action}` as const; + + if (path === 'im.addOwner' || path === 'im.removeOwner') throw new Error(`invalid path ("${path}")`); + return new Promise((resolve) => { - request - .post(api(`${endpoints[type]}.${action}`)) + void request + .post(api(path)) .set(overrideCredentials) .send({ roomId, @@ -108,60 +108,3 @@ function actionRoom({ action, type, roomId, overrideCredentials = credentials, e export const deleteRoom = ({ type, roomId }: { type: ActionRoomParams['type']; roomId: IRoom['_id'] }) => actionRoom({ action: 'delete', type, roomId, overrideCredentials: credentials }); - -export const closeRoom = ({ type, roomId }: { type: ActionRoomParams['type']; roomId: IRoom['_id'] }) => - actionRoom({ action: 'close', type, roomId }); - -export const joinChannel = ({ overrideCredentials = credentials, roomId }: { overrideCredentials: Credentials; roomId: IRoom['_id'] }) => - request.post(api('channels.join')).set(overrideCredentials).send({ - roomId, - }); - -export const inviteToChannel = ({ - overrideCredentials = credentials, - roomId, - userId, -}: { - overrideCredentials: Credentials; - roomId: IRoom['_id']; - userId: IUser['_id']; -}) => - request.post(api('channels.invite')).set(overrideCredentials).send({ - userId, - roomId, - }); - -export const addRoomOwner = ({ type, roomId, userId }: { type: ActionRoomParams['type']; roomId: IRoom['_id']; userId: IUser['_id'] }) => - actionRoom({ action: 'addOwner', type, roomId, extraData: { userId } }); - -export const removeRoomOwner = ({ type, roomId, userId }: { type: ActionRoomParams['type']; roomId: IRoom['_id']; userId: IUser['_id'] }) => - actionRoom({ action: 'removeOwner', type, roomId, extraData: { userId } }); - -export const getChannelRoles = async ({ - roomId, - overrideCredentials = credentials, -}: { - roomId: IRoom['_id']; - overrideCredentials: Credentials; -}) => - ( - await request.get(api('channels.roles')).set(overrideCredentials).query({ - roomId, - }) - ).body.roles; - -export const setRoomConfig = ({ roomId, favorite, isDefault }: { roomId: IRoom['_id']; favorite: boolean; isDefault: boolean }) => { - return request - .post(api('rooms.saveRoomSettings')) - .set(credentials) - .send({ - rid: roomId, - default: isDefault, - favorite: favorite - ? { - defaultValue: true, - favorite: false, - } - : undefined, - }); -}; diff --git a/apps/meteor/tests/data/subscriptions.ts b/apps/meteor/tests/data/subscriptions.ts deleted file mode 100644 index 04e0f48c98e4..000000000000 --- a/apps/meteor/tests/data/subscriptions.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ISubscription } from "@rocket.chat/core-typings"; -import { api, credentials, request } from "./api-data"; - -export const getSubscriptionForRoom = async (roomId: string, overrideCredential?: { 'X-Auth-Token': string; 'X-User-Id': string; }): Promise => { - const response = await request - .get(api('subscriptions.getOne')) - .set(overrideCredential || credentials) - .query({ roomId }) - .expect('Content-Type', 'application/json') - .expect(200); - - const { subscription } = response.body; - - return subscription; -} diff --git a/apps/meteor/tests/data/teams.helper.ts b/apps/meteor/tests/data/teams.helper.ts index 62da06eea71a..8fc60bd19fd4 100644 --- a/apps/meteor/tests/data/teams.helper.ts +++ b/apps/meteor/tests/data/teams.helper.ts @@ -1,28 +1,18 @@ -import { ITeam, TEAM_TYPE } from "@rocket.chat/core-typings" -import { api, request } from "./api-data" -import { IUser } from "@rocket.chat/apps-engine/definition/users"; +import type { ITeam, TEAM_TYPE } from '@rocket.chat/core-typings'; + +import { api, request } from './api-data'; export const createTeam = async (credentials: Record, teamName: string, type: TEAM_TYPE): Promise => { - const response = await request.post(api('teams.create')).set(credentials).send({ - name: teamName, - type, - }); + const response = await request.post(api('teams.create')).set(credentials).send({ + name: teamName, + type, + }); - return response.body.team; + return response.body.team; }; export const deleteTeam = async (credentials: Record, teamName: string): Promise => { - await request.post(api('teams.delete')).set(credentials).send({ - teamName, - }); -}; - -export const addMembers = async (credentials: Record, teamName: string, members: IUser['id'][]): Promise => { - await request - .post(api('teams.addMembers')) - .set(credentials) - .send({ - teamName: teamName, - members: members.map((userId) => ({ userId, roles: ['member'] })) - }); + await request.post(api('teams.delete')).set(credentials).send({ + teamName, + }); }; diff --git a/apps/meteor/tests/data/uploads.helper.ts b/apps/meteor/tests/data/uploads.helper.ts index 5f6e4924d9ff..ad95587527e3 100644 --- a/apps/meteor/tests/data/uploads.helper.ts +++ b/apps/meteor/tests/data/uploads.helper.ts @@ -1,15 +1,15 @@ -import type { Response } from 'supertest'; +import type { IRoom } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, it } from 'mocha'; +import type { Response } from 'supertest'; -import { api, request, credentials } from './api-data.js'; -import { password } from './user'; -import { createUser, login } from './users.helper'; +import { api, request, credentials } from './api-data'; import { imgURL } from './interactions'; +import { createVisitor } from './livechat/rooms'; import { updateSetting } from './permissions.helper'; import { createRoom, deleteRoom } from './rooms.helper'; -import { createVisitor } from './livechat/rooms'; -import { IRoom } from '@rocket.chat/core-typings'; +import { password } from './user'; +import { createUser, login } from './users.helper'; export async function testFileUploads( filesEndpoint: 'channels.files' | 'groups.files' | 'im.files', @@ -56,8 +56,8 @@ export async function testFileUploads( return roomResponse.body.room; }; - it('should fail if invalid channel', function (done) { - request + it('should fail if invalid channel', (done) => { + void request .get(api(filesEndpoint)) .set(credentials) .query({ @@ -65,16 +65,16 @@ export async function testFileUploads( }) .expect('Content-Type', 'application/json') .expect(400) - .expect(function (res: Response) { + .expect((res: Response) => { expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('errorType', invalidRoomError); }) .end(done); }); - it('should fail for room type v', async function () { + it('should fail for room type v', async () => { const { _id } = await createVoipRoom(); - request + void request .get(api(filesEndpoint)) .set(credentials) .query({ @@ -82,14 +82,14 @@ export async function testFileUploads( }) .expect('Content-Type', 'application/json') .expect(400) - .expect(function (res: Response) { + .expect((res: Response) => { expect(res.body).to.have.property('success', false); expect(res.body).to.have.property('errorType', 'error-room-not-found'); }); }); - it('should succeed when searching by roomId', function (done) { - request + it('should succeed when searching by roomId', (done) => { + void request .get(api(filesEndpoint)) .set(credentials) .query({ @@ -97,15 +97,15 @@ export async function testFileUploads( }) .expect('Content-Type', 'application/json') .expect(200) - .expect(function (res: Response) { + .expect((res: Response) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('files').and.to.be.an('array'); }) .end(done); }); - it('should succeed when searching by roomId even requested with count and offset params', function (done) { - request + it('should succeed when searching by roomId even requested with count and offset params', (done) => { + void request .get(api(filesEndpoint)) .set(credentials) .query({ @@ -115,7 +115,7 @@ export async function testFileUploads( }) .expect('Content-Type', 'application/json') .expect(200) - .expect(function (res: Response) { + .expect((res: Response) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('files').and.to.be.an('array'); }) @@ -126,7 +126,7 @@ export async function testFileUploads( if (!testRoom.name) { this.skip(); } - request + void request .get(api(filesEndpoint)) .set(credentials) .query({ @@ -134,7 +134,7 @@ export async function testFileUploads( }) .expect('Content-Type', 'application/json') .expect(200) - .expect(function (res: Response) { + .expect((res: Response) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('files').and.to.be.an('array'); }) @@ -145,7 +145,7 @@ export async function testFileUploads( if (!testRoom.name) { this.skip(); } - request + void request .get(api(filesEndpoint)) .set(credentials) .query({ @@ -155,21 +155,21 @@ export async function testFileUploads( }) .expect('Content-Type', 'application/json') .expect(200) - .expect(function (res: Response) { + .expect((res: Response) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('files').and.to.be.an('array'); }) .end(done); }); - it('should not return thumbnails', async function () { + it('should not return thumbnails', async () => { await request .post(api(`rooms.upload/${testRoom._id}`)) .set(credentials) .attach('file', imgURL) .expect('Content-Type', 'application/json') .expect(200) - .expect(function (res: Response) { + .expect((res: Response) => { expect(res.body).to.have.property('success', true); }); @@ -181,19 +181,19 @@ export async function testFileUploads( }) .expect('Content-Type', 'application/json') .expect(200) - .expect(function (res: Response) { + .expect((res: Response) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('files').and.to.be.an('array').with.lengthOf(1); const { files } = res.body; - files.forEach(function (file: unknown) { + files.forEach((file: unknown) => { expect(file).to.not.have.property('originalFileId'); }); }); }); - it('should not return hidden files', async function () { + it('should not return hidden files', async () => { let msgId; let fileId: string; @@ -203,7 +203,7 @@ export async function testFileUploads( .attach('file', imgURL) .expect('Content-Type', 'application/json') .expect(200) - .expect(function (res: Response) { + .expect((res: Response) => { expect(res.body).to.have.property('success', true); msgId = res.body.message._id; @@ -228,12 +228,12 @@ export async function testFileUploads( }) .expect('Content-Type', 'application/json') .expect(200) - .expect(function (res: Response) { + .expect((res: Response) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('files').and.to.be.an('array').with.lengthOf(1); const { files } = res.body; - files.forEach(function (file: unknown) { + files.forEach((file: unknown) => { expect(file).to.have.property('_id').to.not.be.equal(fileId); }); }); diff --git a/apps/meteor/tests/data/user.ts b/apps/meteor/tests/data/user.ts index f9086bd351bc..e7bbf03f83a2 100644 --- a/apps/meteor/tests/data/user.ts +++ b/apps/meteor/tests/data/user.ts @@ -1,45 +1,12 @@ -import { IUser } from "@rocket.chat/core-typings"; +import type { Credentials } from '@rocket.chat/api-client'; +import type { IUser } from '@rocket.chat/core-typings'; -export const username = 'user.test'; -export const email = `${username}@rocket.chat`; export const password = 'rocket.chat'; -export const reason = 'rocket.chat.reason'; export const adminUsername = 'rocketchat.internal.admin.test'; export const adminEmail = `${adminUsername}@rocket.chat`; export const adminPassword = adminUsername; -export const preferences = { - data: { - newRoomNotification: 'door', - newMessageNotification: 'chime', - muteFocusedConversations: true, - clockMode: 1, - useEmojis: true, - convertAsciiEmoji: true, - saveMobileBandwidth: true, - collapseMediaByDefault: false, - autoImageLoad: true, - emailNotificationMode: 'mentions', - unreadAlert: true, - notificationsSoundVolume: 100, - desktopNotifications: 'default', - pushNotifications: 'default', - enableAutoAway: true, - highlights: [], - desktopNotificationRequireInteraction: false, - hideUsernames: false, - hideRoles: false, - displayAvatars: true, - hideFlexTab: false, - sendOnEnter: 'normal', - idleTimeLimit: 3600, - notifyCalendarEvents: false, - enableMobileRinging: false, - }, -}; - -export type IUserCredentialsHeader = { 'X-Auth-Token': string; 'X-User-Id': string; }; export type IUserWithCredentials = { - user: IUser; - credentials: IUserCredentialsHeader; + user: IUser; + credentials: Credentials; }; diff --git a/apps/meteor/tests/data/users.helper.js b/apps/meteor/tests/data/users.helper.js deleted file mode 100644 index 5f4d93204886..000000000000 --- a/apps/meteor/tests/data/users.helper.js +++ /dev/null @@ -1,121 +0,0 @@ -import { UserStatus } from '@rocket.chat/core-typings'; -import { api, credentials, request } from './api-data'; -import { password } from './user'; -import { MongoClient } from 'mongodb'; -import { URL_MONGODB } from '../e2e/config/constants'; - -export const createUser = (userData = {}) => - new Promise((resolve, reject) => { - const username = userData.username || `user.test.${Date.now()}.${Math.random()}`; - const email = userData.email || `${username}@rocket.chat`; - request - .post(api('users.create')) - .set(credentials) - .send({ email, name: username, username, password, ...userData }) - .end((err, res) => { - if (err) { - return reject(err); - } - resolve(res.body.user); - }); - }); - -export const login = (username, password) => - new Promise((resolve) => { - request - .post(api('login')) - .send({ - user: username, - password, - }) - .end((err, res) => { - const userCredentials = {}; - userCredentials['X-Auth-Token'] = res.body.data.authToken; - userCredentials['X-User-Id'] = res.body.data.userId; - resolve(userCredentials); - }); - }); - -export const deleteUser = async (user, extraData = {}) => - request - .post(api('users.delete')) - .set(credentials) - .send({ - userId: user._id, - ...extraData, - }); - -export const getUserByUsername = (username) => - new Promise((resolve) => { - request - .get(api(`users.info?username=${username}`)) - .set(credentials) - .end((err, res) => { - resolve(res.body.user); - }); - }); - -export const getUserStatus = (userId) => - new Promise((resolve) => { - request - .get(api(`users.getStatus?userId=${userId}`)) - .set(credentials) - .expect('Content-Type', 'application/json') - .expect(200) - .end((end, res) => { - resolve(res.body); - }); - }); - -export const getMe = (overrideCredential = credentials) => - new Promise((resolve) => { - request - .get(api('me')) - .set(overrideCredential) - .expect('Content-Type', 'application/json') - .expect(200) - .end((end, res) => { - resolve(res.body); - }); - }); - -export const setUserActiveStatus = (userId, activeStatus = true) => - new Promise((resolve) => { - request - .post(api('users.setActiveStatus')) - .set(credentials) - .send({ - userId, - activeStatus, - }) - .end(resolve); - }); - -export const setUserStatus = (overrideCredentials = credentials, status = UserStatus.ONLINE) => - request.post(api('users.setStatus')).set(overrideCredentials).send({ - message: '', - status, - }); - -export const registerUser = async (userData = {}, overrideCredentials = credentials) => { - const username = userData.username || `user.test.${Date.now()}`; - const email = userData.email || `${username}@rocket.chat`; - const result = await request - .post(api('users.register')) - .set(overrideCredentials) - .send({ email, name: username, username, pass: password, ...userData }); - - return result.body.user; -}; - -// For changing user data when it's not possible to do so via API -export const updateUserInDb = async (userId, userData) => { - const connection = await MongoClient.connect(URL_MONGODB); - - await connection - .db() - .collection('users') - .updateOne({ _id: userId }, { $set: { ...userData } }); - - await connection.close(); -}; diff --git a/apps/meteor/tests/data/users.helper.ts b/apps/meteor/tests/data/users.helper.ts new file mode 100644 index 000000000000..ceeb671d3a4b --- /dev/null +++ b/apps/meteor/tests/data/users.helper.ts @@ -0,0 +1,102 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IUser } from '@rocket.chat/core-typings'; +import { UserStatus } from '@rocket.chat/core-typings'; + +import { api, credentials, request } from './api-data'; +import { password } from './user'; + +export type TestUser = TUser & { username: string; emails: string[] }; + +export const createUser = ( + userData: { + username?: string; + email?: string; + roles?: string[]; + active?: boolean; + joinDefaultChannels?: boolean; + verified?: boolean; + requirePasswordChange?: boolean; + name?: string; + password?: string; + } = {}, +) => + new Promise>((resolve, reject) => { + const username = userData.username || `user.test.${Date.now()}.${Math.random()}`; + const email = userData.email || `${username}@rocket.chat`; + void request + .post(api('users.create')) + .set(credentials) + .send({ email, name: username, username, password, ...userData }) + .end((err, res) => { + if (err) { + return reject(err); + } + resolve(res.body.user); + }); + }); + +export const login = (username: string | undefined, password: string): Promise => + new Promise((resolve) => { + void request + .post(api('login')) + .send({ + user: username, + password, + }) + .end((_err, res) => { + resolve({ + 'X-Auth-Token': res.body.data.authToken, + 'X-User-Id': res.body.data.userId, + }); + }); + }); + +export const deleteUser = async (user: Pick, extraData = {}) => + request + .post(api('users.delete')) + .set(credentials) + .send({ + userId: user._id, + ...extraData, + }); + +export const getUserByUsername = (username: string) => + new Promise>((resolve) => { + void request + .get(api('users.info')) + .query({ username }) + .set(credentials) + .end((_err, res) => { + resolve(res.body.user); + }); + }); + +export const getMe = (overrideCredential = credentials) => + new Promise>((resolve) => { + void request + .get(api('me')) + .set(overrideCredential) + .expect('Content-Type', 'application/json') + .expect(200) + .end((_end, res) => { + resolve(res.body); + }); + }); + +export const setUserActiveStatus = (userId: IUser['_id'], activeStatus = true) => + new Promise((resolve) => { + void request + .post(api('users.setActiveStatus')) + .set(credentials) + .send({ + userId, + activeStatus, + }) + .end(resolve); + }); + +export const setUserStatus = (overrideCredentials = credentials, status = UserStatus.ONLINE) => + request.post(api('users.setStatus')).set(overrideCredentials).send({ + message: '', + status, + }); diff --git a/apps/meteor/tests/e2e/config/constants.ts b/apps/meteor/tests/e2e/config/constants.ts index c938b693ff45..4c2a174e98aa 100644 --- a/apps/meteor/tests/e2e/config/constants.ts +++ b/apps/meteor/tests/e2e/config/constants.ts @@ -6,7 +6,7 @@ export const BASE_API_URL = BASE_URL + API_PREFIX; export const IS_LOCALHOST = BASE_URL.startsWith('http://localhost'); -export const IS_EE = Boolean(process.env.IS_EE); +export const IS_EE = process.env.IS_EE ? !!JSON.parse(process.env.IS_EE) : false; export const URL_MONGODB = process.env.MONGO_URL || 'mongodb://localhost:3001/meteor?retryWrites=false'; diff --git a/apps/meteor/tests/end-to-end/api/00-autotranslate.js b/apps/meteor/tests/end-to-end/api/00-autotranslate.ts similarity index 88% rename from apps/meteor/tests/end-to-end/api/00-autotranslate.js rename to apps/meteor/tests/end-to-end/api/00-autotranslate.ts index 7397df990849..3b5e03e8016f 100644 --- a/apps/meteor/tests/end-to-end/api/00-autotranslate.js +++ b/apps/meteor/tests/end-to-end/api/00-autotranslate.ts @@ -1,12 +1,15 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IMessage, IRoom, IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { before, describe, after, it } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { sendSimpleMessage } from '../../data/chat.helper'; import { updatePermission, updateSetting } from '../../data/permissions.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { password } from '../../data/user'; -import { createUser, deleteUser, login } from '../../data/users.helper.js'; +import type { TestUser } from '../../data/users.helper'; +import { createUser, deleteUser, login } from '../../data/users.helper'; const resetAutoTranslateDefaults = async () => { await Promise.all([ @@ -21,9 +24,7 @@ const resetE2EDefaults = async () => { await Promise.all([updateSetting('E2E_Enabled_Default_PrivateRooms', false), updateSetting('E2E_Enable', false)]); }; -describe('AutoTranslate', function () { - this.retries(0); - +describe('AutoTranslate', () => { before((done) => getCredentials(done)); describe('[AutoTranslate]', () => { @@ -32,7 +33,7 @@ describe('AutoTranslate', function () { after(() => resetAutoTranslateDefaults()); it('should throw an error when the "AutoTranslate_Enabled" setting is disabled', (done) => { - request + void request .get(api('autotranslate.getSupportedLanguages')) .set(credentials) .query({ @@ -47,9 +48,9 @@ describe('AutoTranslate', function () { .end(done); }); it('should throw an error when the user does not have the "auto-translate" permission', (done) => { - updateSetting('AutoTranslate_Enabled', true).then(() => { - updatePermission('auto-translate', []).then(() => { - request + void updateSetting('AutoTranslate_Enabled', true).then(() => { + void updatePermission('auto-translate', []).then(() => { + void request .get(api('autotranslate.getSupportedLanguages')) .set(credentials) .query({ @@ -66,28 +67,27 @@ describe('AutoTranslate', function () { }); }); }); - it('should return a list of languages', (done) => { - updatePermission('auto-translate', ['admin']).then(() => { - request - .get(api('autotranslate.getSupportedLanguages')) - .set(credentials) - .query({ - targetLanguage: 'en', - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.a.property('success', true); - expect(res.body.languages).to.be.an('array'); - }) - .end(done); - }); + + it('should return a list of languages', async () => { + await updatePermission('auto-translate', ['admin']); + await request + .get(api('autotranslate.getSupportedLanguages')) + .set(credentials) + .query({ + targetLanguage: 'en', + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((res) => { + expect(res.body).to.have.a.property('success', true); + expect(res.body.languages).to.be.an('array'); + }); }); }); describe('[/autotranslate.saveSettings', () => { - let testGroupId; - let testChannelId; + let testGroupId: IRoom['_id']; + let testChannelId: IRoom['_id']; before(async () => { await Promise.all([ @@ -110,7 +110,7 @@ describe('AutoTranslate', function () { }); it('should throw an error when the "AutoTranslate_Enabled" setting is disabled', (done) => { - request + void request .post(api('autotranslate.saveSettings')) .set(credentials) .send({ @@ -128,9 +128,9 @@ describe('AutoTranslate', function () { .end(done); }); it('should throw an error when the user does not have the "auto-translate" permission', (done) => { - updateSetting('AutoTranslate_Enabled', true).then(() => { - updatePermission('auto-translate', []).then(() => { - request + void updateSetting('AutoTranslate_Enabled', true).then(() => { + void updatePermission('auto-translate', []).then(() => { + void request .post(api('autotranslate.saveSettings')) .set(credentials) .send({ @@ -151,8 +151,8 @@ describe('AutoTranslate', function () { }); }); it('should throw an error when the bodyParam "roomId" is not provided', (done) => { - updatePermission('auto-translate', ['admin']).then(() => { - request + void updatePermission('auto-translate', ['admin']).then(() => { + void request .post(api('autotranslate.saveSettings')) .set(credentials) .send({}) @@ -165,7 +165,7 @@ describe('AutoTranslate', function () { }); }); it('should throw an error when the bodyParam "field" is not provided', (done) => { - request + void request .post(api('autotranslate.saveSettings')) .set(credentials) .send({ @@ -179,7 +179,7 @@ describe('AutoTranslate', function () { .end(done); }); it('should throw an error when the bodyParam "value" is not provided', (done) => { - request + void request .post(api('autotranslate.saveSettings')) .set(credentials) .send({ @@ -194,7 +194,7 @@ describe('AutoTranslate', function () { .end(done); }); it('should throw an error when the bodyParam "autoTranslate" is not a boolean', (done) => { - request + void request .post(api('autotranslate.saveSettings')) .set(credentials) .send({ @@ -210,7 +210,7 @@ describe('AutoTranslate', function () { .end(done); }); it('should throw an error when the bodyParam "autoTranslateLanguage" is not a string', (done) => { - request + void request .post(api('autotranslate.saveSettings')) .set(credentials) .send({ @@ -226,7 +226,7 @@ describe('AutoTranslate', function () { .end(done); }); it('should throw an error when the bodyParam "field" is invalid', (done) => { - request + void request .post(api('autotranslate.saveSettings')) .set(credentials) .send({ @@ -242,7 +242,7 @@ describe('AutoTranslate', function () { .end(done); }); it('should throw an error when the bodyParam "roomId" is invalid or the user is not subscribed', (done) => { - request + void request .post(api('autotranslate.saveSettings')) .set(credentials) .send({ @@ -277,7 +277,7 @@ describe('AutoTranslate', function () { }); }); it('should return success when the setting is saved correctly', (done) => { - request + void request .post(api('autotranslate.saveSettings')) .set(credentials) .send({ @@ -295,8 +295,8 @@ describe('AutoTranslate', function () { }); describe('[/autotranslate.translateMessage', () => { - let messageSent; - let testChannelId; + let messageSent: IMessage; + let testChannelId: IRoom['_id']; before(async () => { await resetAutoTranslateDefaults(); @@ -314,7 +314,7 @@ describe('AutoTranslate', function () { }); it('should throw an error when the "AutoTranslate_Enabled" setting is disabled', (done) => { - request + void request .post(api('autotranslate.translateMessage')) .set(credentials) .send({ @@ -330,9 +330,9 @@ describe('AutoTranslate', function () { .end(done); }); it('should throw an error when the bodyParam "messageId" is not provided', (done) => { - updateSetting('AutoTranslate_Enabled', true).then(() => { - updatePermission('auto-translate', ['admin']).then(() => { - request + void updateSetting('AutoTranslate_Enabled', true).then(() => { + void updatePermission('auto-translate', ['admin']).then(() => { + void request .post(api('autotranslate.translateMessage')) .set(credentials) .send({}) @@ -346,7 +346,7 @@ describe('AutoTranslate', function () { }); }); it('should throw an error when the bodyParam "messageId" is invalid', (done) => { - request + void request .post(api('autotranslate.translateMessage')) .set(credentials) .send({ @@ -361,7 +361,7 @@ describe('AutoTranslate', function () { .end(done); }); it('should return success when the translate is successful', (done) => { - request + void request .post(api('autotranslate.translateMessage')) .set(credentials) .send({ @@ -377,17 +377,17 @@ describe('AutoTranslate', function () { }); describe('Autoenable setting', () => { - let userA; - let userB; - let credA; - let credB; - let channel; - const channelsToRemove = []; - - const createChannel = async (members, cred) => + let userA: TestUser; + let userB: TestUser; + let credA: Credentials; + let credB: Credentials; + let channel: IRoom; + const channelsToRemove: IRoom[] = []; + + const createChannel = async (members: string[] | undefined, cred: Credentials) => (await createRoom({ type: 'c', members, name: `channel-test-${Date.now()}`, credentials: cred })).body.channel; - const setLanguagePref = async (language, cred) => { + const setLanguagePref = async (language: string, cred: Credentials) => { await request .post(api('users.setPreferences')) .set(cred) @@ -399,7 +399,7 @@ describe('AutoTranslate', function () { }); }; - const getSub = async (roomId, cred) => + const getSub = async (roomId: IRoom['_id'], cred: Credentials) => ( await request .get(api('subscriptions.getOne')) diff --git a/apps/meteor/tests/end-to-end/api/00-miscellaneous.js b/apps/meteor/tests/end-to-end/api/00-miscellaneous.ts similarity index 92% rename from apps/meteor/tests/end-to-end/api/00-miscellaneous.js rename to apps/meteor/tests/end-to-end/api/00-miscellaneous.ts index 1fe04b9b380a..6469ef051a24 100644 --- a/apps/meteor/tests/end-to-end/api/00-miscellaneous.js +++ b/apps/meteor/tests/end-to-end/api/00-miscellaneous.ts @@ -1,26 +1,28 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IInstanceStatus, IRoom, ITeam, IUser } from '@rocket.chat/core-typings'; import { TEAM_TYPE } from '@rocket.chat/core-typings'; -import { expect } from 'chai'; +import type { IInstance } from '@rocket.chat/rest-typings'; +import { AssertionError, expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { updatePermission, updateSetting } from '../../data/permissions.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { createTeam, deleteTeam } from '../../data/teams.helper'; import { adminEmail, adminUsername, adminPassword, password } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; import { createUser, deleteUser, login as doLogin } from '../../data/users.helper'; import { IS_EE } from '../../e2e/config/constants'; -describe('miscellaneous', function () { - this.retries(0); - +describe('miscellaneous', () => { before((done) => getCredentials(done)); describe('API default', () => { // Required by mobile apps describe('/info', () => { - let version; + let version: string; it('should return "version", "build", "commit" and "marketplaceApiVersion" when the user is logged in', (done) => { - request + void request .get('/api/info') .set(credentials) .expect('Content-Type', 'application/json') @@ -36,7 +38,7 @@ describe('miscellaneous', function () { .end(done); }); it('should return only "version" and the version should not have patch info when the user is not logged in', (done) => { - request + void request .get('/api/info') .expect('Content-Type', 'application/json') .expect(200) @@ -56,7 +58,7 @@ describe('miscellaneous', function () { }); it('/login (wrapper username)', (done) => { - request + void request .post(api('login')) .send({ user: { @@ -77,7 +79,7 @@ describe('miscellaneous', function () { }); it('/login (wrapper email)', (done) => { - request + void request .post(api('login')) .send({ user: { @@ -98,7 +100,7 @@ describe('miscellaneous', function () { }); it('/login by user', (done) => { - request + void request .post(api('login')) .send({ user: adminEmail, @@ -117,7 +119,7 @@ describe('miscellaneous', function () { }); it('/login by username', (done) => { - request + void request .post(api('login')) .send({ username: adminUsername, @@ -201,11 +203,11 @@ describe('miscellaneous', function () { }); describe('/directory', () => { - let user; - let testChannel; - let normalUserCredentials; - const teamName = `new-team-name-${Date.now()}`; - let teamCreated = {}; + let user: TestUser; + let testChannel: IRoom; + let normalUserCredentials: Credentials; + const teamName = `new-team-name-${Date.now()}` as const; + let teamCreated: ITeam; before(async () => { await updatePermission('create-team', ['admin', 'user']); @@ -225,7 +227,7 @@ describe('miscellaneous', function () { }); it('should return an array(result) when search by user and execute successfully', (done) => { - request + void request .get(api('directory')) .set(credentials) .query({ @@ -252,7 +254,7 @@ describe('miscellaneous', function () { }); it('should not return the emails field for non admins', (done) => { - request + void request .get(api('directory')) .set(normalUserCredentials) .query({ @@ -278,7 +280,7 @@ describe('miscellaneous', function () { .end(done); }); it('should return an array(result) when search by channel and execute successfully', (done) => { - request + void request .get(api('directory')) .set(credentials) .query({ @@ -303,7 +305,7 @@ describe('miscellaneous', function () { .end(done); }); it('should return an array(result) when search by channel with sort params correctly and execute successfully', (done) => { - request + void request .get(api('directory')) .set(credentials) .query({ @@ -331,7 +333,7 @@ describe('miscellaneous', function () { .end(done); }); it('should return an error when send invalid query', (done) => { - request + void request .get(api('directory')) .set(credentials) .query({ @@ -348,7 +350,7 @@ describe('miscellaneous', function () { .end(done); }); it('should return an error when have more than one sort parameter', (done) => { - request + void request .get(api('directory')) .set(credentials) .query({ @@ -370,7 +372,7 @@ describe('miscellaneous', function () { }); it('should return an object containing rooms and totalCount from teams', (done) => { - request + void request .get(api('directory')) .set(normalUserCredentials) .query({ @@ -405,11 +407,11 @@ describe('miscellaneous', function () { }); describe('[/spotlight]', () => { - let user; - let userCredentials; - let testChannel; - let testTeam; - let testChannelSpecialChars; + let user: TestUser; + let userCredentials: Credentials; + let testChannel: IRoom; + let testTeam: ITeam; + let testChannelSpecialChars: IRoom; const fnameSpecialCharsRoom = `test ГДΕληνικά-${Date.now()}`; const teamName = `team-test-${Date.now()}`; @@ -431,7 +433,7 @@ describe('miscellaneous', function () { }); it('should fail when does not have query param', (done) => { - request + void request .get(api('spotlight')) .set(credentials) .expect('Content-Type', 'application/json') @@ -443,7 +445,7 @@ describe('miscellaneous', function () { .end(done); }); it('should return object inside users array when search by a valid user', (done) => { - request + void request .get(api('spotlight')) .query({ query: `@${adminUsername}`, @@ -463,7 +465,7 @@ describe('miscellaneous', function () { .end(done); }); it('must return the object inside the room array when searching for a valid room and that user is not a member of it', (done) => { - request + void request .get(api('spotlight')) .query({ query: `#${testChannel.name}`, @@ -482,7 +484,7 @@ describe('miscellaneous', function () { .end(done); }); it('must return the teamMain property when searching for a valid team that the user is not a member of', (done) => { - request + void request .get(api('spotlight')) .query({ query: `${testTeam.name}`, @@ -502,7 +504,7 @@ describe('miscellaneous', function () { .end(done); }); it('must return rooms when searching for a valid fname', (done) => { - request + void request .get(api('spotlight')) .query({ query: `#${fnameSpecialCharsRoom}`, @@ -523,14 +525,14 @@ describe('miscellaneous', function () { }); describe('[/instances.get]', () => { - let unauthorizedUserCredentials; + let unauthorizedUserCredentials: Credentials; before(async () => { const createdUser = await createUser(); unauthorizedUserCredentials = await doLogin(createdUser.username, password); }); it('should fail if user is logged in but is unauthorized', (done) => { - request + void request .get(api('instances.get')) .set(unauthorizedUserCredentials) .expect('Content-Type', 'application/json') @@ -543,7 +545,7 @@ describe('miscellaneous', function () { }); it('should fail if not logged in', (done) => { - request + void request .get(api('instances.get')) .expect('Content-Type', 'application/json') .expect(401) @@ -555,7 +557,7 @@ describe('miscellaneous', function () { }); it('should return instances if user is logged in and is authorized', (done) => { - request + void request .get(api('instances.get')) .set(credentials) .expect(200) @@ -564,11 +566,15 @@ describe('miscellaneous', function () { expect(res.body).to.have.property('instances').and.to.be.an('array').with.lengthOf(1); - const { instances } = res.body; + const instances = res.body.instances as IInstance[]; const instanceName = IS_EE ? 'ddp-streamer' : 'rocket.chat'; - const instance = instances.filter((i) => i.instanceRecord.name === instanceName)[0]; + const instance = instances.find( + (i): i is IInstance & { instanceRecord: IInstanceStatus } => i.instanceRecord?.name === instanceName, + ); + + if (!instance) throw new AssertionError(`no instance named "${instanceName}"`); expect(instance).to.have.property('instanceRecord'); expect(instance).to.have.property('currentStatus'); @@ -604,7 +610,7 @@ describe('miscellaneous', function () { after(() => updateSetting('API_Enable_Shields', true)); it('should fail if API_Enable_Shields is disabled', (done) => { - request + void request .get(api('shield.svg')) .query({ type: 'online', @@ -622,8 +628,8 @@ describe('miscellaneous', function () { }); it('should succeed if API_Enable_Shields is enabled', (done) => { - updateSetting('API_Enable_Shields', true).then(() => { - request + void updateSetting('API_Enable_Shields', true).then(() => { + void request .get(api('shield.svg')) .query({ type: 'online', @@ -640,7 +646,7 @@ describe('miscellaneous', function () { describe('/pw.getPolicy', () => { it('should return policies', (done) => { - request + void request .get(api('pw.getPolicy')) .set(credentials) .expect('Content-Type', 'application/json') @@ -656,7 +662,7 @@ describe('miscellaneous', function () { describe('/pw.getPolicyReset', () => { it('should fail if no token provided', (done) => { - request + void request .get(api('pw.getPolicyReset')) .expect('Content-Type', 'application/json') .expect(400) @@ -668,8 +674,9 @@ describe('miscellaneous', function () { }); it('should fail if no token is invalid format', (done) => { - request - .get(api('pw.getPolicyReset?token=123')) + void request + .get(api('pw.getPolicyReset')) + .query({ token: '123' }) .expect('Content-Type', 'application/json') .expect(403) .expect((res) => { @@ -681,8 +688,9 @@ describe('miscellaneous', function () { // not sure we have a way to get the reset token, looks like it is only sent via email by Meteor it.skip('should return policies if correct token is provided', (done) => { - request - .get(api('pw.getPolicyReset?token')) + void request + .get(api('pw.getPolicyReset')) + .query({ token: '' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(403) diff --git a/apps/meteor/tests/end-to-end/api/01-users.js b/apps/meteor/tests/end-to-end/api/01-users.ts similarity index 88% rename from apps/meteor/tests/end-to-end/api/01-users.js rename to apps/meteor/tests/end-to-end/api/01-users.ts index ee53820daa2a..f34a424597af 100644 --- a/apps/meteor/tests/end-to-end/api/01-users.js +++ b/apps/meteor/tests/end-to-end/api/01-users.ts @@ -1,35 +1,186 @@ import crypto from 'crypto'; +import type { Credentials } from '@rocket.chat/api-client'; +import type { IGetRoomRoles, IRoom, ISubscription, ITeam, IUser } from '@rocket.chat/core-typings'; import { Random } from '@rocket.chat/random'; -import { expect } from 'chai'; +import type { PaginatedResult, DefaultUserInfo } from '@rocket.chat/rest-typings'; +import { assert, expect } from 'chai'; import { after, afterEach, before, beforeEach, describe, it } from 'mocha'; +import { MongoClient } from 'mongodb'; -import { getCredentials, api, request, credentials, apiEmail, apiUsername, log, wait, reservedWords } from '../../data/api-data.js'; -import { MAX_BIO_LENGTH, MAX_NICKNAME_LENGTH } from '../../data/constants.ts'; -import { customFieldText, clearCustomFields, setCustomFields } from '../../data/custom-fields.js'; +import { getCredentials, api, request, credentials, apiEmail, apiUsername, log, wait, reservedWords } from '../../data/api-data'; import { imgURL } from '../../data/interactions'; import { createAgent, makeAgentAvailable } from '../../data/livechat/rooms'; import { removeAgent, getAgent } from '../../data/livechat/users'; import { updatePermission, updateSetting } from '../../data/permissions.helper'; -import { - addRoomOwner, - createRoom, - deleteRoom, - getChannelRoles, - inviteToChannel, - joinChannel, - removeRoomOwner, - setRoomConfig, -} from '../../data/rooms.helper'; +import type { ActionRoomParams } from '../../data/rooms.helper'; +import { actionRoom, createRoom, deleteRoom } from '../../data/rooms.helper'; import { createTeam, deleteTeam } from '../../data/teams.helper'; -import { adminEmail, preferences, password, adminUsername } from '../../data/user'; -import { createUser, login, deleteUser, getUserStatus, getUserByUsername, registerUser, updateUserInDb } from '../../data/users.helper.js'; +import type { IUserWithCredentials } from '../../data/user'; +import { adminEmail, password, adminUsername } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; +import { createUser, login, deleteUser, getUserByUsername } from '../../data/users.helper'; +import { IS_EE, URL_MONGODB } from '../../e2e/config/constants'; + +const MAX_BIO_LENGTH = 260; +const MAX_NICKNAME_LENGTH = 120; + +const customFieldText = { + type: 'text', + required: true, + minLength: 2, + maxLength: 10, +}; + +function setCustomFields(customFields: unknown) { + const stringified = customFields ? JSON.stringify(customFields) : ''; + + return request.post(api('settings/Accounts_CustomFields')).set(credentials).send({ value: stringified }).expect(200); +} + +function clearCustomFields() { + return setCustomFields(null); +} + +const joinChannel = ({ overrideCredentials = credentials, roomId }: { overrideCredentials: Credentials; roomId: IRoom['_id'] }) => + request.post(api('channels.join')).set(overrideCredentials).send({ + roomId, + }); + +const inviteToChannel = ({ + overrideCredentials = credentials, + roomId, + userId, +}: { + overrideCredentials?: Credentials; + roomId: IRoom['_id']; + userId: IUser['_id']; +}) => + request.post(api('channels.invite')).set(overrideCredentials).send({ + userId, + roomId, + }); -const targetUser = {}; +const addRoomOwner = ({ type, roomId, userId }: { type: ActionRoomParams['type']; roomId: IRoom['_id']; userId: IUser['_id'] }) => + actionRoom({ action: 'addOwner', type, roomId, extraData: { userId } }); + +const removeRoomOwner = ({ type, roomId, userId }: { type: ActionRoomParams['type']; roomId: IRoom['_id']; userId: IUser['_id'] }) => + actionRoom({ action: 'removeOwner', type, roomId, extraData: { userId } }); + +const getChannelRoles = async ({ + roomId, + overrideCredentials = credentials, +}: { + roomId: IRoom['_id']; + overrideCredentials?: Credentials; +}) => + ( + await request.get(api('channels.roles')).set(overrideCredentials).query({ + roomId, + }) + ).body.roles as IGetRoomRoles[]; + +const setRoomConfig = ({ roomId, favorite, isDefault }: { roomId: IRoom['_id']; favorite?: boolean; isDefault: boolean }) => { + return request + .post(api('rooms.saveRoomSettings')) + .set(credentials) + .send({ + rid: roomId, + default: isDefault, + favorite: favorite + ? { + defaultValue: true, + favorite: false, + } + : undefined, + }); +}; + +const preferences = { + data: { + newRoomNotification: 'door', + newMessageNotification: 'chime', + muteFocusedConversations: true, + clockMode: 1, + useEmojis: true, + convertAsciiEmoji: true, + saveMobileBandwidth: true, + collapseMediaByDefault: false, + autoImageLoad: true, + emailNotificationMode: 'mentions', + unreadAlert: true, + notificationsSoundVolume: 100, + desktopNotifications: 'default', + pushNotifications: 'default', + enableAutoAway: true, + highlights: [], + desktopNotificationRequireInteraction: false, + hideUsernames: false, + hideRoles: false, + displayAvatars: true, + hideFlexTab: false, + sendOnEnter: 'normal', + idleTimeLimit: 3600, + notifyCalendarEvents: false, + enableMobileRinging: false, + ...(IS_EE && { + omnichannelTranscriptPDF: false, + }), + }, +}; + +const getUserStatus = (userId: IUser['_id']) => + new Promise<{ + status: 'online' | 'offline' | 'away' | 'busy'; + message?: string; + _id?: string; + connectionStatus?: 'online' | 'offline' | 'away' | 'busy'; + }>((resolve) => { + void request + .get(api('users.getStatus')) + .query({ userId }) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(200) + .end((_end, res) => { + resolve(res.body); + }); + }); -describe('[Users]', function () { - let userCredentials; - this.retries(0); +const registerUser = async ( + userData: { + username?: string; + email?: string; + name?: string; + pass?: string; + } = {}, + overrideCredentials = credentials, +) => { + const username = userData.username || `user.test.${Date.now()}`; + const email = userData.email || `${username}@rocket.chat`; + const result = await request + .post(api('users.register')) + .set(overrideCredentials) + .send({ email, name: username, username, pass: password, ...userData }); + + return result.body.user; +}; + +// For changing user data when it's not possible to do so via API +const updateUserInDb = async (userId: IUser['_id'], userData: Partial) => { + const connection = await MongoClient.connect(URL_MONGODB); + + await connection + .db() + .collection('users') + .updateOne({ _id: userId }, { $set: { ...userData } }); + + await connection.close(); +}; + +describe('[Users]', () => { + let targetUser: { _id: IUser['_id']; username: string }; + let userCredentials: Credentials; before((done) => getCredentials(done)); @@ -40,8 +191,10 @@ describe('[Users]', function () { joinDefaultChannels: true, verified: true, }); - targetUser._id = user._id; - targetUser.username = user.username; + targetUser = { + _id: user._id, + username: user.username, + }; userCredentials = await login(user.username, password); }); @@ -100,9 +253,7 @@ describe('[Users]', function () { const email = `customField_${apiEmail}`; const customFields = { customFieldText: 'success' }; - let user; - - await request + const res = await request .post(api('users.create')) .set(credentials) .send({ @@ -117,25 +268,24 @@ describe('[Users]', function () { customFields, }) .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.nested.property('user.username', username); - expect(res.body).to.have.nested.property('user.emails[0].address', email); - expect(res.body).to.have.nested.property('user.active', true); - expect(res.body).to.have.nested.property('user.name', username); - expect(res.body).to.have.nested.property('user.customFields.customFieldText', 'success'); - expect(res.body).to.not.have.nested.property('user.e2e'); + .expect(200); - user = res.body.user; - }); + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.nested.property('user.username', username); + expect(res.body).to.have.nested.property('user.emails[0].address', email); + expect(res.body).to.have.nested.property('user.active', true); + expect(res.body).to.have.nested.property('user.name', username); + expect(res.body).to.have.nested.property('user.customFields.customFieldText', 'success'); + expect(res.body).to.not.have.nested.property('user.e2e'); + + const { user } = res.body; await deleteUser(user); }); - function failCreateUser(name) { + function failCreateUser(name: string) { it(`should not create a new user if username is the reserved word ${name}`, (done) => { - request + void request .post(api('users.create')) .set(credentials) .send({ @@ -158,11 +308,11 @@ describe('[Users]', function () { }); } - function failUserWithCustomField(field) { + function failUserWithCustomField(field: { name: string; value: unknown; reason: string }) { it(`should not create a user if a custom field ${field.reason}`, async () => { await setCustomFields({ customFieldText }); - const customFields = {}; + const customFields: Record = {}; customFields[field.name] = field.value; await request @@ -201,7 +351,7 @@ describe('[Users]', function () { }); describe('users default roles configuration', () => { - const users = []; + const users: IUser[] = []; before(async () => { await updateSetting('Accounts_Registration_Users_Default_Roles', 'user,admin'); @@ -217,7 +367,7 @@ describe('[Users]', function () { const username = `defaultUserRole_${apiUsername}${Date.now()}`; const email = `defaultUserRole_${apiEmail}${Date.now()}`; - request + void request .post(api('users.create')) .set(credentials) .send({ @@ -245,7 +395,7 @@ describe('[Users]', function () { const username = `defaultUserRole_${apiUsername}${Date.now()}`; const email = `defaultUserRole_${apiEmail}${Date.now()}`; - request + void request .post(api('users.create')) .set(credentials) .send({ @@ -272,14 +422,14 @@ describe('[Users]', function () { }); describe('auto join default channels', () => { - let defaultTeamRoomId; - let defaultTeamId; - let group; - let user; - let userCredentials; - let user2; - let user3; - let userNoDefault; + let defaultTeamRoomId: IRoom['_id']; + let defaultTeamId: ITeam['_id']; + let group: IRoom; + let user: IUser; + let userCredentials: Credentials; + let user2: IUser; + let user3: IUser; + let userNoDefault: IUser; const teamName = `defaultTeam_${Date.now()}`; before(async () => { @@ -431,12 +581,12 @@ describe('[Users]', function () { describe('[/users.register]', () => { const email = `email@email${Date.now()}.com`; const username = `myusername${Date.now()}`; - let user; + let user: IUser; after(async () => deleteUser(user)); it('should register new user', (done) => { - request + void request .post(api('users.register')) .send({ email, @@ -456,7 +606,7 @@ describe('[Users]', function () { .end(done); }); it('should return an error when trying register new user with an existing username', (done) => { - request + void request .post(api('users.register')) .send({ email, @@ -475,7 +625,7 @@ describe('[Users]', function () { }); describe('[/users.info]', () => { - let infoRoom; + let infoRoom: IRoom; before(async () => { infoRoom = ( @@ -496,7 +646,7 @@ describe('[Users]', function () { ); it('should return an error when the user does not exist', (done) => { - request + void request .get(api('users.info')) .set(credentials) .query({ @@ -512,7 +662,7 @@ describe('[Users]', function () { }); it('should query information about a user by userId', (done) => { - request + void request .get(api('users.info')) .set(credentials) .query({ @@ -531,7 +681,7 @@ describe('[Users]', function () { }); it('should return "rooms" property when user request it and the user has the necessary permission (admin, "view-other-user-channels")', (done) => { - request + void request .get(api('users.info')) .set(credentials) .query({ @@ -543,14 +693,14 @@ describe('[Users]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('user.rooms').and.to.be.an('array'); - const createdRoom = res.body.user.rooms.find((room) => room.rid === infoRoom._id); + const createdRoom = (res.body.user.rooms as ISubscription[]).find((room) => room.rid === infoRoom._id); expect(createdRoom).to.have.property('unread'); }) .end(done); }); it('should NOT return "rooms" property when user NOT request it but the user has the necessary permission (admin, "view-other-user-channels")', (done) => { - request + void request .get(api('users.info')) .set(credentials) .query({ @@ -565,8 +715,8 @@ describe('[Users]', function () { .end(done); }); it('should return the rooms when the user request your own rooms but he does NOT have the necessary permission', (done) => { - updatePermission('view-other-user-channels', []).then(() => { - request + void updatePermission('view-other-user-channels', []).then(() => { + void request .get(api('users.info')) .set(credentials) .query({ @@ -585,8 +735,8 @@ describe('[Users]', function () { }); }); it("should NOT return the rooms when the user request another user's rooms and he does NOT have the necessary permission", (done) => { - updatePermission('view-other-user-channels', []).then(() => { - request + void updatePermission('view-other-user-channels', []).then(() => { + void request .get(api('users.info')) .set(credentials) .query({ @@ -603,8 +753,8 @@ describe('[Users]', function () { }); }); it("should NOT return any services fields when request to another user's info even if the user has the necessary permission", (done) => { - updatePermission('view-full-other-user-info', ['admin']).then(() => { - request + void updatePermission('view-full-other-user-info', ['admin']).then(() => { + void request .get(api('users.info')) .set(credentials) .query({ @@ -621,8 +771,8 @@ describe('[Users]', function () { }); }); it('should return all services fields when request for myself data even without privileged permission', (done) => { - updatePermission('view-full-other-user-info', []).then(() => { - request + void updatePermission('view-full-other-user-info', []).then(() => { + void request .get(api('users.info')) .set(credentials) .query({ @@ -670,7 +820,7 @@ describe('[Users]', function () { }); describe('[/users.getPresence]', () => { it("should query a user's presence by userId", (done) => { - request + void request .get(api('users.getPresence')) .set(credentials) .query({ @@ -686,8 +836,8 @@ describe('[Users]', function () { }); describe('Logging in with type: "resume"', () => { - let user; - let userCredentials; + let user: TestUser; + let userCredentials: Credentials; before(async () => { user = await createUser({ joinDefaultChannels: false }); @@ -724,7 +874,7 @@ describe('[Users]', function () { describe('[/users.presence]', () => { describe('Not logged in:', () => { it('should return 401 unauthorized', (done) => { - request + void request .get(api('users.presence')) .expect('Content-Type', 'application/json') .expect(401) @@ -736,7 +886,7 @@ describe('[Users]', function () { }); describe('Logged in:', () => { it('should return online users full list', (done) => { - request + void request .get(api('users.presence')) .set(credentials) .expect('Content-Type', 'application/json') @@ -745,7 +895,7 @@ describe('[Users]', function () { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('full', true); - const user = res.body.users.find((user) => user.username === 'rocket.cat'); + const user = (res.body.users as IUser[]).find((user) => user.username === 'rocket.cat'); expect(user).to.have.all.keys('_id', 'avatarETag', 'username', 'name', 'status', 'utcOffset'); }) @@ -753,8 +903,9 @@ describe('[Users]', function () { }); it('should return no online users updated after now', (done) => { - request - .get(api(`users.presence?from=${new Date().toISOString()}`)) + void request + .get(api('users.presence')) + .query({ from: new Date().toISOString() }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -770,8 +921,9 @@ describe('[Users]', function () { const date = new Date(); date.setMinutes(date.getMinutes() - 11); - request - .get(api(`users.presence?from=${date.toISOString()}`)) + void request + .get(api('users.presence')) + .query({ from: date.toISOString() }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -779,7 +931,7 @@ describe('[Users]', function () { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('full', true); - const user = res.body.users.find((user) => user.username === 'rocket.cat'); + const user = (res.body.users as IUser[]).find((user) => user.username === 'rocket.cat'); expect(user).to.have.all.keys('_id', 'avatarETag', 'username', 'name', 'status', 'utcOffset'); }) @@ -789,10 +941,10 @@ describe('[Users]', function () { }); describe('[/users.list]', () => { - let user; - let deactivatedUser; - let user2; - let user2Credentials; + let user: TestUser; + let deactivatedUser: TestUser; + let user2: TestUser; + let user2Credentials: Credentials; before(async () => { const username = `deactivated_${Date.now()}${apiUsername}`; @@ -863,7 +1015,7 @@ describe('[Users]', function () { ); it('should query all users in the system', (done) => { - request + void request .get(api('users.list')) .set(credentials) .expect('Content-Type', 'application/json') @@ -872,7 +1024,7 @@ describe('[Users]', function () { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('count'); expect(res.body).to.have.property('total'); - const myself = res.body.users.find((user) => user.username === adminUsername); + const myself = (res.body.users as IUser[]).find((user) => user.username === adminUsername); expect(myself).to.not.have.property('e2e'); }) .end(done); @@ -890,7 +1042,7 @@ describe('[Users]', function () { }), }; - request + void request .get(api('users.list')) .query(query) .set(credentials) @@ -901,7 +1053,8 @@ describe('[Users]', function () { expect(res.body).to.have.property('count'); expect(res.body).to.have.property('total'); expect(res.body).to.have.property('users'); - const queriedUser = res.body.users.find((u) => u._id === user._id); + const queriedUser = (res.body.users as IUser[]).find((u) => u._id === user._id); + assert.isDefined(queriedUser); expect(queriedUser).to.have.property('customFields'); expect(queriedUser.customFields).to.have.property('customFieldText', 'success'); }) @@ -921,7 +1074,7 @@ describe('[Users]', function () { }), }; - request + void request .get(api('users.list')) .query(query) .set(credentials) @@ -932,7 +1085,7 @@ describe('[Users]', function () { expect(res.body).to.have.property('count'); expect(res.body).to.have.property('total'); expect(res.body).to.have.property('users'); - const firstUser = res.body.users.find((u) => u._id === deactivatedUser._id); + const firstUser = (res.body.users as IUser[]).find((u) => u._id === deactivatedUser._id); expect(firstUser).to.have.property('active', false); }) .end(done); @@ -940,14 +1093,13 @@ describe('[Users]', function () { it.skip('should query all users in the system by name', (done) => { // filtering user list - request + void request .get(api('users.list')) .set(credentials) .query({ name: { $regex: 'g' }, }) .field('username', 1) - .sort('createdAt', -1) .expect(log) .expect('Content-Type', 'application/json') .expect(200) @@ -982,8 +1134,8 @@ describe('[Users]', function () { }); describe('Avatars', () => { - let user; - let userCredentials; + let user: TestUser; + let userCredentials: Credentials; before(async () => { user = await createUser(); @@ -1004,7 +1156,7 @@ describe('[Users]', function () { describe('[/users.setAvatar]', () => { it('should set the avatar of the logged user by a local image', (done) => { - request + void request .post(api('users.setAvatar')) .set(userCredentials) .attach('image', imgURL) @@ -1016,7 +1168,7 @@ describe('[Users]', function () { .end(done); }); it('should update the avatar of another user by userId when the logged user has the necessary permission (edit-other-user-avatar)', (done) => { - request + void request .post(api('users.setAvatar')) .set(userCredentials) .attach('image', imgURL) @@ -1029,7 +1181,7 @@ describe('[Users]', function () { .end(done); }); it('should set the avatar of another user by username and local image when the logged user has the necessary permission (edit-other-user-avatar)', (done) => { - request + void request .post(api('users.setAvatar')) .set(credentials) .attach('image', imgURL) @@ -1042,8 +1194,8 @@ describe('[Users]', function () { .end(done); }); it("should prevent from updating someone else's avatar when the logged user doesn't have the necessary permission(edit-other-user-avatar)", (done) => { - updatePermission('edit-other-user-avatar', []).then(() => { - request + void updatePermission('edit-other-user-avatar', []).then(() => { + void request .post(api('users.setAvatar')) .set(userCredentials) .attach('image', imgURL) @@ -1057,9 +1209,9 @@ describe('[Users]', function () { }); }); it('should allow users with the edit-other-user-avatar permission to update avatars when the Accounts_AllowUserAvatarChange setting is off', (done) => { - updateSetting('Accounts_AllowUserAvatarChange', false).then(() => { - updatePermission('edit-other-user-avatar', ['admin']).then(() => { - request + void updateSetting('Accounts_AllowUserAvatarChange', false).then(() => { + void updatePermission('edit-other-user-avatar', ['admin']).then(() => { + void request .post(api('users.setAvatar')) .set(credentials) .attach('image', imgURL) @@ -1084,7 +1236,7 @@ describe('[Users]', function () { }); it('should set the avatar of the logged user by a local image', (done) => { - request + void request .post(api('users.setAvatar')) .set(userCredentials) .attach('image', imgURL) @@ -1096,7 +1248,7 @@ describe('[Users]', function () { .end(done); }); it('should reset the avatar of the logged user', (done) => { - request + void request .post(api('users.resetAvatar')) .set(userCredentials) .expect('Content-Type', 'application/json') @@ -1110,7 +1262,7 @@ describe('[Users]', function () { .end(done); }); it('should reset the avatar of another user by userId when the logged user has the necessary permission (edit-other-user-avatar)', (done) => { - request + void request .post(api('users.resetAvatar')) .set(userCredentials) .send({ @@ -1124,7 +1276,7 @@ describe('[Users]', function () { .end(done); }); it('should reset the avatar of another user by username and local image when the logged user has the necessary permission (edit-other-user-avatar)', (done) => { - request + void request .post(api('users.resetAvatar')) .set(credentials) .send({ @@ -1138,8 +1290,8 @@ describe('[Users]', function () { .end(done); }); it("should prevent from resetting someone else's avatar when the logged user doesn't have the necessary permission(edit-other-user-avatar)", (done) => { - updatePermission('edit-other-user-avatar', []).then(() => { - request + void updatePermission('edit-other-user-avatar', []).then(() => { + void request .post(api('users.resetAvatar')) .set(userCredentials) .send({ @@ -1154,9 +1306,9 @@ describe('[Users]', function () { }); }); it('should allow users with the edit-other-user-avatar permission to reset avatars when the Accounts_AllowUserAvatarChange setting is off', (done) => { - updateSetting('Accounts_AllowUserAvatarChange', false).then(() => { - updatePermission('edit-other-user-avatar', ['admin']).then(() => { - request + void updateSetting('Accounts_AllowUserAvatarChange', false).then(() => { + void updatePermission('edit-other-user-avatar', ['admin']).then(() => { + void request .post(api('users.resetAvatar')) .set(credentials) .send({ @@ -1175,7 +1327,7 @@ describe('[Users]', function () { describe('[/users.getAvatar]', () => { it('should get the url of the avatar of the logged user via userId', (done) => { - request + void request .get(api('users.getAvatar')) .set(userCredentials) .query({ @@ -1185,7 +1337,7 @@ describe('[Users]', function () { .end(done); }); it('should get the url of the avatar of the logged user via username', (done) => { - request + void request .get(api('users.getAvatar')) .set(userCredentials) .query({ @@ -1198,11 +1350,11 @@ describe('[Users]', function () { describe('[/users.getAvatarSuggestion]', () => { it('should return 401 unauthorized when user is not logged in', (done) => { - request.get(api('users.getAvatarSuggestion')).expect('Content-Type', 'application/json').expect(401).end(done); + void request.get(api('users.getAvatarSuggestion')).expect('Content-Type', 'application/json').expect(401).end(done); }); it('should get avatar suggestion of the logged user via userId', (done) => { - request + void request .get(api('users.getAvatarSuggestion')) .set(userCredentials) .query({ @@ -1243,7 +1395,7 @@ describe('[Users]', function () { ); it("should update a user's info by userId", (done) => { - request + void request .post(api('users.update')) .set(credentials) .send({ @@ -1271,7 +1423,7 @@ describe('[Users]', function () { }); it("should update a user's email by userId", (done) => { - request + void request .post(api('users.update')) .set(credentials) .send({ @@ -1292,7 +1444,7 @@ describe('[Users]', function () { }); it("should update a user's bio by userId", (done) => { - request + void request .post(api('users.update')) .set(credentials) .send({ @@ -1312,7 +1464,7 @@ describe('[Users]', function () { }); it("should update a user's nickname by userId", (done) => { - request + void request .post(api('users.update')) .set(credentials) .send({ @@ -1332,7 +1484,7 @@ describe('[Users]', function () { }); it(`should return an error when trying to set a nickname longer than ${MAX_NICKNAME_LENGTH} characters`, (done) => { - request + void request .post(api('users.update')) .set(credentials) .send({ @@ -1354,7 +1506,7 @@ describe('[Users]', function () { }); it(`should return an error when trying to set a bio longer than ${MAX_BIO_LENGTH} characters`, (done) => { - request + void request .post(api('users.update')) .set(credentials) .send({ @@ -1373,7 +1525,7 @@ describe('[Users]', function () { }); it("should update a bot's email", (done) => { - request + void request .post(api('users.update')) .set(credentials) .send({ @@ -1389,7 +1541,7 @@ describe('[Users]', function () { }); it("should verify user's email by userId", (done) => { - request + void request .post(api('users.update')) .set(credentials) .send({ @@ -1409,9 +1561,9 @@ describe('[Users]', function () { }); it('should return an error when trying update username and it is not allowed', (done) => { - updatePermission('edit-other-user-info', ['user']).then(() => { - updateSetting('Accounts_AllowUsernameChange', false).then(() => { - request + void updatePermission('edit-other-user-info', ['user']).then(() => { + void updateSetting('Accounts_AllowUsernameChange', false).then(() => { + void request .post(api('users.update')) .set(credentials) .send({ @@ -1450,9 +1602,9 @@ describe('[Users]', function () { }); it('should return an error when trying update user real name and it is not allowed', (done) => { - updatePermission('edit-other-user-info', ['user']).then(() => { - updateSetting('Accounts_AllowRealNameChange', false).then(() => { - request + void updatePermission('edit-other-user-info', ['user']).then(() => { + void updateSetting('Accounts_AllowRealNameChange', false).then(() => { + void request .post(api('users.update')) .set(credentials) .send({ @@ -1472,9 +1624,9 @@ describe('[Users]', function () { }); it('should update user real name when the required permission is applied', (done) => { - updatePermission('edit-other-user-info', ['admin']).then(() => { - updateSetting('Accounts_AllowRealNameChange', false).then(() => { - request + void updatePermission('edit-other-user-info', ['admin']).then(() => { + void updateSetting('Accounts_AllowRealNameChange', false).then(() => { + void request .post(api('users.update')) .set(credentials) .send({ @@ -1494,9 +1646,9 @@ describe('[Users]', function () { }); it('should return an error when trying update user status message and it is not allowed', (done) => { - updatePermission('edit-other-user-info', ['user']).then(() => { - updateSetting('Accounts_AllowUserStatusMessageChange', false).then(() => { - request + void updatePermission('edit-other-user-info', ['user']).then(() => { + void updateSetting('Accounts_AllowUserStatusMessageChange', false).then(() => { + void request .post(api('users.update')) .set(credentials) .send({ @@ -1516,9 +1668,9 @@ describe('[Users]', function () { }); it('should update user status message when the required permission is applied', (done) => { - updatePermission('edit-other-user-info', ['admin']).then(() => { - updateSetting('Accounts_AllowUserStatusMessageChange', false).then(() => { - request + void updatePermission('edit-other-user-info', ['admin']).then(() => { + void updateSetting('Accounts_AllowUserStatusMessageChange', false).then(() => { + void request .post(api('users.update')) .set(credentials) .send({ @@ -1538,9 +1690,9 @@ describe('[Users]', function () { }); it('should return an error when trying update user email and it is not allowed', (done) => { - updatePermission('edit-other-user-info', ['user']).then(() => { - updateSetting('Accounts_AllowEmailChange', false).then(() => { - request + void updatePermission('edit-other-user-info', ['user']).then(() => { + void updateSetting('Accounts_AllowEmailChange', false).then(() => { + void request .post(api('users.update')) .set(credentials) .send({ @@ -1560,9 +1712,9 @@ describe('[Users]', function () { }); it('should update user email when the required permission is applied', (done) => { - updatePermission('edit-other-user-info', ['admin']).then(() => { - updateSetting('Accounts_AllowEmailChange', false).then(() => { - request + void updatePermission('edit-other-user-info', ['admin']).then(() => { + void updateSetting('Accounts_AllowEmailChange', false).then(() => { + void request .post(api('users.update')) .set(credentials) .send({ @@ -1582,9 +1734,9 @@ describe('[Users]', function () { }); it('should return an error when trying update user password and it is not allowed', (done) => { - updatePermission('edit-other-user-password', ['user']).then(() => { - updateSetting('Accounts_AllowPasswordChange', false).then(() => { - request + void updatePermission('edit-other-user-password', ['user']).then(() => { + void updateSetting('Accounts_AllowPasswordChange', false).then(() => { + void request .post(api('users.update')) .set(credentials) .send({ @@ -1604,9 +1756,9 @@ describe('[Users]', function () { }); it('should update user password when the required permission is applied', (done) => { - updatePermission('edit-other-user-password', ['admin']).then(() => { - updateSetting('Accounts_AllowPasswordChange', false).then(() => { - request + void updatePermission('edit-other-user-password', ['admin']).then(() => { + void updateSetting('Accounts_AllowPasswordChange', false).then(() => { + void request .post(api('users.update')) .set(credentials) .send({ @@ -1626,9 +1778,9 @@ describe('[Users]', function () { }); it('should return an error when trying update profile and it is not allowed', (done) => { - updatePermission('edit-other-user-info', ['user']).then(() => { - updateSetting('Accounts_AllowUserProfileChange', false).then(() => { - request + void updatePermission('edit-other-user-info', ['user']).then(() => { + void updateSetting('Accounts_AllowUserProfileChange', false).then(() => { + void request .post(api('users.update')) .set(credentials) .send({ @@ -1648,9 +1800,9 @@ describe('[Users]', function () { }); it('should update profile when the required permission is applied', (done) => { - updatePermission('edit-other-user-info', ['admin']).then(() => { - updateSetting('Accounts_AllowUserProfileChange', false).then(() => { - request + void updatePermission('edit-other-user-info', ['admin']).then(() => { + void updateSetting('Accounts_AllowUserProfileChange', false).then(() => { + void request .post(api('users.update')) .set(credentials) .send({ @@ -1697,9 +1849,9 @@ describe('[Users]', function () { await deleteUser(user); }); - function failUpdateUser(name) { + function failUpdateUser(name: string) { it(`should not update an user if the new username is the reserved word ${name}`, (done) => { - request + void request .post(api('users.update')) .set(credentials) .send({ @@ -1724,8 +1876,8 @@ describe('[Users]', function () { }); describe('[/users.updateOwnBasicInfo]', () => { - let user; - let userCredentials; + let user: TestUser; + let userCredentials: Credentials; before(async () => { user = await createUser(); @@ -1751,8 +1903,8 @@ describe('[Users]', function () { const editedEmail = `test${+new Date()}@mail.com`; it('enabling E2E in server and generating keys to user...', (done) => { - updateSetting('E2E_Enable', true).then(() => { - request + void updateSetting('E2E_Enable', true).then(() => { + void request .post(api('e2e.setUserPublicAndPrivateKeys')) .set(userCredentials) .send({ @@ -1769,7 +1921,7 @@ describe('[Users]', function () { }); it('should update the user own basic information', (done) => { - request + void request .post(api('users.updateOwnBasicInfo')) .set(userCredentials) .send({ @@ -1793,7 +1945,7 @@ describe('[Users]', function () { }); it('should update the user name only', (done) => { - request + void request .post(api('users.updateOwnBasicInfo')) .set(userCredentials) .send({ @@ -1813,7 +1965,7 @@ describe('[Users]', function () { }); it('should throw an error when user try change email without the password', (done) => { - request + void request .post(api('users.updateOwnBasicInfo')) .set(userCredentials) .send({ @@ -1827,7 +1979,7 @@ describe('[Users]', function () { }); it('should throw an error when user try change password without the actual password', (done) => { - request + void request .post(api('users.updateOwnBasicInfo')) .set(credentials) .send({ @@ -1841,7 +1993,7 @@ describe('[Users]', function () { }); it('should throw an error when the name is only whitespaces', (done) => { - request + void request .post(api('users.updateOwnBasicInfo')) .set(credentials) .send({ @@ -1858,7 +2010,7 @@ describe('[Users]', function () { }); it("should set new email as 'unverified'", (done) => { - request + void request .post(api('users.updateOwnBasicInfo')) .set(userCredentials) .send({ @@ -1879,9 +2031,9 @@ describe('[Users]', function () { .end(done); }); - function failUpdateUserOwnBasicInfo(name) { + function failUpdateUserOwnBasicInfo(name: string) { it(`should not update an user's basic info if the new username is the reserved word ${name}`, (done) => { - request + void request .post(api('users.updateOwnBasicInfo')) .set(credentials) .send({ @@ -2215,8 +2367,8 @@ describe('[Users]', function () { ...preferences.data, }, }; - updatePermission('edit-other-user-info', []).then(() => { - request + void updatePermission('edit-other-user-info', []).then(() => { + void request .post(api('users.setPreferences')) .set(credentials) .send(userPreferences) @@ -2237,8 +2389,8 @@ describe('[Users]', function () { ...preferences.data, }, }; - updatePermission('edit-other-user-info', ['admin', 'user']).then(() => { - request + void updatePermission('edit-other-user-info', ['admin', 'user']).then(() => { + void request .post(api('users.setPreferences')) .set(credentials) .send(userPreferences) @@ -2262,8 +2414,8 @@ describe('[Users]', function () { ...preferences.data, }, }; - updatePermission('edit-other-user-info', ['admin', 'user']).then(() => { - request + void updatePermission('edit-other-user-info', ['admin', 'user']).then(() => { + void request .post(api('users.setPreferences')) .set(credentials) .send(userPreferences) @@ -2285,7 +2437,7 @@ describe('[Users]', function () { ...preferences.data, }, }; - request + void request .post(api('users.setPreferences')) .set(credentials) .send(userPreferences) @@ -2306,7 +2458,7 @@ describe('[Users]', function () { language: 'en', }, }; - request + void request .post(api('users.setPreferences')) .set(credentials) .send(userPreferences) @@ -2326,7 +2478,7 @@ describe('[Users]', function () { ...preferences.data, language: 'en', }; - request + void request .get(api('users.getPreferences')) .set(credentials) .expect(200) @@ -2341,7 +2493,7 @@ describe('[Users]', function () { describe('[/users.forgotPassword]', () => { it('should send email to user (return success), when is a valid email', (done) => { - request + void request .post(api('users.forgotPassword')) .send({ email: adminEmail, @@ -2355,7 +2507,7 @@ describe('[Users]', function () { }); it('should not send email to user(return error), when is a invalid email', (done) => { - request + void request .post(api('users.forgotPassword')) .send({ email: 'invalidEmail', @@ -2371,7 +2523,7 @@ describe('[Users]', function () { describe('[/users.sendConfirmationEmail]', () => { it('should send email to user (return success), when is a valid email', (done) => { - request + void request .post(api('users.sendConfirmationEmail')) .set(credentials) .send({ @@ -2386,7 +2538,7 @@ describe('[Users]', function () { }); it('should not send email to user(return error), when is a invalid email', (done) => { - request + void request .post(api('users.sendConfirmationEmail')) .set(credentials) .send({ @@ -2403,8 +2555,8 @@ describe('[Users]', function () { describe('[/users.getUsernameSuggestion]', () => { const testUsername = `test${+new Date()}`; - let targetUser; - let userCredentials; + let targetUser: TestUser; + let userCredentials: Credentials; before(async () => { targetUser = await registerUser({ @@ -2419,7 +2571,7 @@ describe('[Users]', function () { after(() => deleteUser(targetUser)); it('should return an username suggestion', (done) => { - request + void request .get(api('users.getUsernameSuggestion')) .set(userCredentials) .expect('Content-Type', 'application/json') @@ -2433,8 +2585,8 @@ describe('[Users]', function () { }); describe('[/users.checkUsernameAvailability]', () => { - let targetUser; - let userCredentials; + let targetUser: TestUser; + let userCredentials: Credentials; before(async () => { targetUser = await registerUser(); @@ -2444,7 +2596,7 @@ describe('[Users]', function () { after(() => deleteUser(targetUser)); it('should return 401 unauthorized when user is not logged in', (done) => { - request + void request .get(api('users.checkUsernameAvailability')) .expect('Content-Type', 'application/json') .expect(401) @@ -2455,7 +2607,7 @@ describe('[Users]', function () { }); it('should return true if the username is the same user username set', (done) => { - request + void request .get(api('users.checkUsernameAvailability')) .set(userCredentials) .query({ @@ -2471,7 +2623,7 @@ describe('[Users]', function () { }); it('should return true if the username is available', (done) => { - request + void request .get(api('users.checkUsernameAvailability')) .set(userCredentials) .query({ @@ -2487,10 +2639,10 @@ describe('[Users]', function () { }); it('should return an error when the username is invalid', (done) => { - request + void request .get(api('users.checkUsernameAvailability')) .set(userCredentials) - .query() + .query({}) .expect('Content-Type', 'application/json') .expect(400) .expect((res) => { @@ -2501,8 +2653,8 @@ describe('[Users]', function () { }); describe('[/users.deleteOwnAccount]', () => { - let targetUser; - let userCredentials; + let targetUser: TestUser; + let userCredentials: Credentials; before(async () => { targetUser = await registerUser(); @@ -2512,7 +2664,7 @@ describe('[Users]', function () { after(async () => deleteUser(targetUser)); it('Enable "Accounts_AllowDeleteOwnAccount" setting...', (done) => { - request + void request .post('/api/v1/settings/Accounts_AllowDeleteOwnAccount') .set(credentials) .send({ value: true }) @@ -2525,7 +2677,7 @@ describe('[Users]', function () { }); it('should delete user own account', (done) => { - request + void request .post(api('users.deleteOwnAccount')) .set(userCredentials) .send({ @@ -2558,9 +2710,9 @@ describe('[Users]', function () { }); describe('last owner cases', () => { - let user; - let createdUserCredentials; - let room; + let user: TestUser; + let createdUserCredentials: Credentials; + let room: IRoom; beforeEach(async () => { user = await createUser(); @@ -2637,7 +2789,7 @@ describe('[Users]', function () { }); describe('[/users.delete]', () => { - let newUser; + let newUser: TestUser; before(async () => { newUser = await createUser(); @@ -2680,8 +2832,8 @@ describe('[Users]', function () { }); describe('last owner cases', () => { - let targetUser; - let room; + let targetUser: TestUser; + let room: IRoom; beforeEach(async () => { targetUser = await registerUser(); room = ( @@ -2763,7 +2915,7 @@ describe('[Users]', function () { describe('[/users.getPersonalAccessTokens]', () => { it('should return an array when the user does not have personal tokens configured', (done) => { - request + void request .get(api('users.getPersonalAccessTokens')) .set(credentials) .expect('Content-Type', 'application/json') @@ -2778,7 +2930,7 @@ describe('[Users]', function () { describe('[/users.generatePersonalAccessToken]', () => { it('should return a personal access token to user', (done) => { - request + void request .post(api('users.generatePersonalAccessToken')) .set(credentials) .send({ @@ -2793,7 +2945,7 @@ describe('[Users]', function () { .end(done); }); it('should throw an error when user tries generate a token with the same name', (done) => { - request + void request .post(api('users.generatePersonalAccessToken')) .set(credentials) .send({ @@ -2809,7 +2961,7 @@ describe('[Users]', function () { }); describe('[/users.regeneratePersonalAccessToken]', () => { it('should return a personal access token to user when user regenerates the token', (done) => { - request + void request .post(api('users.regeneratePersonalAccessToken')) .set(credentials) .send({ @@ -2824,7 +2976,7 @@ describe('[Users]', function () { .end(done); }); it('should throw an error when user tries regenerate a token that does not exist', (done) => { - request + void request .post(api('users.regeneratePersonalAccessToken')) .set(credentials) .send({ @@ -2840,7 +2992,7 @@ describe('[Users]', function () { }); describe('[/users.getPersonalAccessTokens]', () => { it('should return my personal access tokens', (done) => { - request + void request .get(api('users.getPersonalAccessTokens')) .set(credentials) .expect('Content-Type', 'application/json') @@ -2854,7 +3006,7 @@ describe('[Users]', function () { }); describe('[/users.removePersonalAccessToken]', () => { it('should return success when user remove a personal access token', (done) => { - request + void request .post(api('users.removePersonalAccessToken')) .set(credentials) .send({ @@ -2868,7 +3020,7 @@ describe('[Users]', function () { .end(done); }); it('should throw an error when user tries remove a token that does not exist', (done) => { - request + void request .post(api('users.removePersonalAccessToken')) .set(credentials) .send({ @@ -2889,7 +3041,7 @@ describe('[Users]', function () { describe('should return an error when the user dont have the necessary permission "create-personal-access-tokens"', () => { it('/users.generatePersonalAccessToken', (done) => { - request + void request .post(api('users.generatePersonalAccessToken')) .set(credentials) .send({ @@ -2904,7 +3056,7 @@ describe('[Users]', function () { .end(done); }); it('/users.regeneratePersonalAccessToken', (done) => { - request + void request .post(api('users.regeneratePersonalAccessToken')) .set(credentials) .send({ @@ -2919,7 +3071,7 @@ describe('[Users]', function () { .end(done); }); it('/users.getPersonalAccessTokens', (done) => { - request + void request .get(api('users.getPersonalAccessTokens')) .set(credentials) .expect('Content-Type', 'application/json') @@ -2931,7 +3083,7 @@ describe('[Users]', function () { .end(done); }); it('/users.removePersonalAccessToken', (done) => { - request + void request .post(api('users.removePersonalAccessToken')) .set(credentials) .send({ @@ -2946,7 +3098,7 @@ describe('[Users]', function () { .end(done); }); it('should throw an error when user tries remove a token that does not exist', (done) => { - request + void request .post(api('users.removePersonalAccessToken')) .set(credentials) .send({ @@ -2965,10 +3117,10 @@ describe('[Users]', function () { }); describe('[/users.setActiveStatus]', () => { - let user; - let agent; - let agentUser; - let userCredentials; + let user: TestUser; + let agent: IUserWithCredentials; + let agentUser: TestUser; + let userCredentials: Credentials; before(async () => { agentUser = await createUser(); @@ -3002,7 +3154,7 @@ describe('[Users]', function () { after(() => Promise.all([removeAgent(agent.user._id), deleteUser(agent.user)])); it('should set other user active status to false when the logged user has the necessary permission(edit-other-user-active-status)', (done) => { - request + void request .post(api('users.setActiveStatus')) .set(userCredentials) .send({ @@ -3018,7 +3170,7 @@ describe('[Users]', function () { .end(done); }); it('should set other user active status to true when the logged user has the necessary permission(edit-other-user-active-status)', (done) => { - request + void request .post(api('users.setActiveStatus')) .set(userCredentials) .send({ @@ -3035,8 +3187,8 @@ describe('[Users]', function () { }); it('should return an error when trying to set other user active status and has not the necessary permission(edit-other-user-active-status)', (done) => { - updatePermission('edit-other-user-active-status', []).then(() => { - request + void updatePermission('edit-other-user-active-status', []).then(() => { + void request .post(api('users.setActiveStatus')) .set(userCredentials) .send({ @@ -3052,7 +3204,7 @@ describe('[Users]', function () { }); }); it('should return an error when trying to set user own active status and has not the necessary permission(edit-other-user-active-status)', (done) => { - request + void request .post(api('users.setActiveStatus')) .set(userCredentials) .send({ @@ -3067,8 +3219,8 @@ describe('[Users]', function () { .end(done); }); it('should set user own active status to false when the user has the necessary permission(edit-other-user-active-status)', (done) => { - updatePermission('edit-other-user-active-status', ['admin']).then(() => { - request + void updatePermission('edit-other-user-active-status', ['admin']).then(() => { + void request .post(api('users.setActiveStatus')) .set(userCredentials) .send({ @@ -3139,7 +3291,7 @@ describe('[Users]', function () { }); describe('last owner cases', () => { - let room; + let room: IRoom; beforeEach(() => Promise.all([ @@ -3252,7 +3404,7 @@ describe('[Users]', function () { expect(roles).to.have.lengthOf(2); const originalCreator = roles.find((role) => role.u._id === credentials['X-User-Id']); - expect(originalCreator).to.not.be.undefined; + assert.isDefined(originalCreator); expect(originalCreator.roles).to.eql(['owner']); expect(originalCreator.u).to.have.property('_id', credentials['X-User-Id']); }); @@ -3260,7 +3412,7 @@ describe('[Users]', function () { }); describe('[/users.deactivateIdle]', () => { - let testUser; + let testUser: TestUser; const testRoleId = 'guest'; before('Create test user', async () => { @@ -3282,8 +3434,8 @@ describe('[Users]', function () { after(() => Promise.all([deleteUser(testUser), updatePermission('edit-other-user-active-status', ['admin'])])); it('should fail to deactivate if user doesnt have edit-other-user-active-status permission', (done) => { - updatePermission('edit-other-user-active-status', []).then(() => { - request + void updatePermission('edit-other-user-active-status', []).then(() => { + void request .post(api('users.deactivateIdle')) .set(credentials) .send({ @@ -3299,8 +3451,8 @@ describe('[Users]', function () { }); }); it('should deactivate no users when no users in time range', (done) => { - updatePermission('edit-other-user-active-status', ['admin']).then(() => { - request + void updatePermission('edit-other-user-active-status', ['admin']).then(() => { + void request .post(api('users.deactivateIdle')) .set(credentials) .send({ @@ -3316,8 +3468,8 @@ describe('[Users]', function () { }); }); it('should deactivate the test user when given its role and daysIdle = 0', (done) => { - updatePermission('edit-other-user-active-status', ['admin']).then(() => { - request + void updatePermission('edit-other-user-active-status', ['admin']).then(() => { + void request .post(api('users.deactivateIdle')) .set(credentials) .send({ @@ -3334,8 +3486,8 @@ describe('[Users]', function () { }); }); it('should not deactivate the test user again when given its role and daysIdle = 0', (done) => { - updatePermission('edit-other-user-active-status', ['admin']).then(() => { - request + void updatePermission('edit-other-user-active-status', ['admin']).then(() => { + void request .post(api('users.deactivateIdle')) .set(credentials) .send({ @@ -3355,7 +3507,7 @@ describe('[Users]', function () { describe('[/users.requestDataDownload]', () => { it('should return the request data with fullExport false when no query parameter was send', (done) => { - request + void request .get(api('users.requestDataDownload')) .set(credentials) .expect('Content-Type', 'application/json') @@ -3369,8 +3521,9 @@ describe('[Users]', function () { .end(done); }); it('should return the request data with fullExport false when the fullExport query parameter is false', (done) => { - request - .get(api('users.requestDataDownload?fullExport=false')) + void request + .get(api('users.requestDataDownload')) + .query({ fullExport: 'false' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -3383,8 +3536,9 @@ describe('[Users]', function () { .end(done); }); it('should return the request data with fullExport true when the fullExport query parameter is true', (done) => { - request - .get(api('users.requestDataDownload?fullExport=true')) + void request + .get(api('users.requestDataDownload')) + .query({ fullExport: 'true' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -3399,9 +3553,9 @@ describe('[Users]', function () { }); describe('[/users.logoutOtherClients]', function () { - let user; - let userCredentials; - let newCredentials; + let user: TestUser; + let userCredentials: Credentials; + let newCredentials: Credentials; this.timeout(20000); @@ -3434,7 +3588,7 @@ describe('[Users]', function () { } } - request + void request .post(api('users.logoutOtherClients')) .set(newCredentials) .expect(200) @@ -3451,11 +3605,11 @@ describe('[Users]', function () { after(() => updatePermission('view-outside-room', ['admin', 'owner', 'moderator', 'user'])); describe('[without permission]', function () { - let user; - let userCredentials; - let user2; - let user2Credentials; - let roomId; + let user: TestUser; + let userCredentials: Credentials; + let user2: TestUser; + let user2Credentials: Credentials; + let roomId: IRoom['_id']; this.timeout(20000); @@ -3478,8 +3632,9 @@ describe('[Users]', function () { }); it('should return an empty list when the user does not have any subscription', (done) => { - request - .get(api('users.autocomplete?selector={}')) + void request + .get(api('users.autocomplete')) + .query({ selector: '{}' }) .set(userCredentials) .expect('Content-Type', 'application/json') .expect(200) @@ -3493,8 +3648,9 @@ describe('[Users]', function () { it('should return users that are subscribed to the same rooms as the requester', async () => { await joinChannel({ overrideCredentials: user2Credentials, roomId }); - request - .get(api('users.autocomplete?selector={}')) + void request + .get(api('users.autocomplete')) + .query({ selector: '{}' }) .set(userCredentials) .expect('Content-Type', 'application/json') .expect(200) @@ -3509,10 +3665,10 @@ describe('[Users]', function () { before(() => updatePermission('view-outside-room', ['admin', 'user'])); it('should return an error when the required parameter "selector" is not provided', () => { - request + void request .get(api('users.autocomplete')) - .set(credentials) .query({}) + .set(credentials) .expect('Content-Type', 'application/json') .expect(400) .expect((res) => { @@ -3520,8 +3676,9 @@ describe('[Users]', function () { }); }); it('should return the users to fill auto complete', (done) => { - request - .get(api('users.autocomplete?selector={}')) + void request + .get(api('users.autocomplete')) + .query({ selector: '{}' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -3533,7 +3690,7 @@ describe('[Users]', function () { }); it('should filter results when using allowed operators', (done) => { - request + void request .get(api('users.autocomplete')) .set(credentials) .query({ @@ -3560,7 +3717,7 @@ describe('[Users]', function () { }); it('should return an error when using forbidden operators', (done) => { - request + void request .get(api('users.autocomplete')) .set(credentials) .query({ @@ -3593,7 +3750,7 @@ describe('[Users]', function () { describe('[/users.getStatus]', () => { it('should return my own status', (done) => { - request + void request .get(api('users.getStatus')) .set(credentials) .expect('Content-Type', 'application/json') @@ -3606,8 +3763,9 @@ describe('[Users]', function () { .end(done); }); it('should return other user status', (done) => { - request - .get(api('users.getStatus?userId=rocket.cat')) + void request + .get(api('users.getStatus')) + .query({ userId: 'rocket.cat' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -3621,7 +3779,7 @@ describe('[Users]', function () { }); describe('[/users.setStatus]', () => { - let user; + let user: TestUser; before(async () => { user = await createUser(); @@ -3629,8 +3787,8 @@ describe('[Users]', function () { after(() => Promise.all([deleteUser(user), updateSetting('Accounts_AllowUserStatusMessageChange', true)])); it('should return an error when the setting "Accounts_AllowUserStatusMessageChange" is disabled', (done) => { - updateSetting('Accounts_AllowUserStatusMessageChange', false).then(() => { - request + void updateSetting('Accounts_AllowUserStatusMessageChange', false).then(() => { + void request .post(api('users.setStatus')) .set(credentials) .send({ @@ -3648,8 +3806,8 @@ describe('[Users]', function () { }); }); it('should update my own status', (done) => { - updateSetting('Accounts_AllowUserStatusMessageChange', true).then(() => { - request + void updateSetting('Accounts_AllowUserStatusMessageChange', true).then(() => { + void request .post(api('users.setStatus')) .set(credentials) .send({ @@ -3660,14 +3818,14 @@ describe('[Users]', function () { .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - getUserStatus(credentials['X-User-Id']).then((status) => expect(status.status).to.be.equal('busy')); + void getUserStatus(credentials['X-User-Id']).then((status) => expect(status.status).to.be.equal('busy')); }) .end(done); }); }); it('should return an error when trying to update other user status without the required permission', (done) => { - updatePermission('edit-other-user-info', []).then(() => { - request + void updatePermission('edit-other-user-info', []).then(() => { + void request .post(api('users.setStatus')) .set(credentials) .send({ @@ -3685,8 +3843,8 @@ describe('[Users]', function () { }); }); it('should update another user status succesfully', (done) => { - updatePermission('edit-other-user-info', ['admin']).then(() => { - request + void updatePermission('edit-other-user-info', ['admin']).then(() => { + void request .post(api('users.setStatus')) .set(credentials) .send({ @@ -3698,7 +3856,7 @@ describe('[Users]', function () { .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - getUserStatus(credentials['X-User-Id']).then((status) => { + void getUserStatus(credentials['X-User-Id']).then((status) => { expect(status.status).to.be.equal('busy'); expect(status.message).to.be.equal('test'); }); @@ -3707,7 +3865,7 @@ describe('[Users]', function () { }); }); it('should return an error when the user try to update user status with an invalid status', (done) => { - request + void request .post(api('users.setStatus')) .set(credentials) .send({ @@ -3742,7 +3900,7 @@ describe('[Users]', function () { await updateSetting('Accounts_AllowInvisibleStatusOption', true); }); it('should return an error when the payload is missing all supported fields', (done) => { - request + void request .post(api('users.setStatus')) .set(credentials) .send({}) @@ -3757,9 +3915,9 @@ describe('[Users]', function () { }); describe('[/users.removeOtherTokens]', () => { - let user; - let userCredentials; - let newCredentials; + let user: TestUser; + let userCredentials: Credentials; + let newCredentials: Credentials; before(async () => { user = await createUser(); @@ -3790,17 +3948,17 @@ describe('[Users]', function () { } } - request.post(api('users.removeOtherTokens')).set(newCredentials).expect(200).then(tryAuthentication); + void request.post(api('users.removeOtherTokens')).set(newCredentials).expect(200).then(tryAuthentication); }); }); describe('[/users.listTeams]', () => { const teamName1 = `team-name-${Date.now()}`; const teamName2 = `team-name-2-${Date.now()}`; - let testUser; + let testUser: TestUser; before('create team 1', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ @@ -3818,7 +3976,7 @@ describe('[Users]', function () { }); before('create team 2', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ @@ -3840,7 +3998,7 @@ describe('[Users]', function () { }); before('add test user to team 1', (done) => { - request + void request .post(api('teams.addMembers')) .set(credentials) .send({ @@ -3861,7 +4019,7 @@ describe('[Users]', function () { }); before('add test user to team 2', (done) => { - request + void request .post(api('teams.addMembers')) .set(credentials) .send({ @@ -3884,7 +4042,7 @@ describe('[Users]', function () { after(() => Promise.all([...[teamName1, teamName2].map((team) => deleteTeam(credentials, team)), deleteUser(testUser)])); it('should list both channels', (done) => { - request + void request .get(api('users.listTeams')) .set(credentials) .query({ @@ -3906,9 +4064,9 @@ describe('[Users]', function () { }); describe('[/users.logout]', () => { - let user; - let otherUser; - let userCredentials; + let user: TestUser; + let otherUser: TestUser; + let userCredentials: Credentials; before(async () => { user = await createUser(); @@ -3919,8 +4077,8 @@ describe('[Users]', function () { after(() => Promise.all([deleteUser(user), deleteUser(otherUser), updatePermission('logout-other-user', ['admin'])])); it('should throw unauthorized error to user w/o "logout-other-user" permission', (done) => { - updatePermission('logout-other-user', []).then(() => { - request + void updatePermission('logout-other-user', []).then(() => { + void request .post(api('users.logout')) .set(credentials) .send({ userId: otherUser._id }) @@ -3931,8 +4089,8 @@ describe('[Users]', function () { }); it('should logout other user', (done) => { - updatePermission('logout-other-user', ['admin']).then(() => { - request + void updatePermission('logout-other-user', ['admin']).then(() => { + void request .post(api('users.logout')) .set(credentials) .send({ userId: otherUser._id }) @@ -3943,16 +4101,16 @@ describe('[Users]', function () { }); it('should logout the requester', (done) => { - updatePermission('logout-other-user', []).then(() => { - request.post(api('users.logout')).set(userCredentials).expect('Content-Type', 'application/json').expect(200).end(done); + void updatePermission('logout-other-user', []).then(() => { + void request.post(api('users.logout')).set(userCredentials).expect('Content-Type', 'application/json').expect(200).end(done); }); }); }); describe('[/users.listByStatus]', () => { - let user; - let otherUser; - let otherUserCredentials; + let user: TestUser; + let otherUser: TestUser; + let otherUserCredentials: Credentials; before(async () => { user = await createUser(); @@ -3977,7 +4135,9 @@ describe('[Users]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('users'); - const { users } = res.body; + const { users } = res.body as PaginatedResult<{ + users: DefaultUserInfo[]; + }>; const ids = users.map((user) => user._id); expect(ids).to.include(user._id); }); @@ -3992,7 +4152,9 @@ describe('[Users]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('users'); - const { users } = res.body; + const { users } = res.body as PaginatedResult<{ + users: DefaultUserInfo[]; + }>; const ids = users.map((user) => user._id); expect(ids).to.include(user._id); }); @@ -4009,7 +4171,9 @@ describe('[Users]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('users'); - const { users } = res.body; + const { users } = res.body as PaginatedResult<{ + users: DefaultUserInfo[]; + }>; const ids = users.map((user) => user._id); expect(ids).to.include(user._id); }); @@ -4026,7 +4190,9 @@ describe('[Users]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('users'); - const { users } = res.body; + const { users } = res.body as PaginatedResult<{ + users: DefaultUserInfo[]; + }>; const ids = users.map((user) => user._id); expect(ids).to.not.include(user._id); }); @@ -4047,7 +4213,9 @@ describe('[Users]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('users'); - const { users } = res.body; + const { users } = res.body as PaginatedResult<{ + users: DefaultUserInfo[]; + }>; const ids = users.map((user) => user._id); expect(ids).to.include(user._id); }); @@ -4063,7 +4231,9 @@ describe('[Users]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('users'); - const { users } = res.body; + const { users } = res.body as PaginatedResult<{ + users: DefaultUserInfo[]; + }>; const ids = users.map((user) => user._id); expect(ids).to.include(user._id); }); @@ -4113,8 +4283,8 @@ describe('[Users]', function () { }); describe('[/users.sendWelcomeEmail]', async () => { - let user; - let otherUser; + let user: TestUser; + let otherUser: TestUser; before(async () => { user = await createUser(); diff --git a/apps/meteor/tests/end-to-end/api/02-channels.js b/apps/meteor/tests/end-to-end/api/02-channels.ts similarity index 92% rename from apps/meteor/tests/end-to-end/api/02-channels.js rename to apps/meteor/tests/end-to-end/api/02-channels.ts index ded521f52509..193502195ef2 100644 --- a/apps/meteor/tests/end-to-end/api/02-channels.js +++ b/apps/meteor/tests/end-to-end/api/02-channels.ts @@ -1,7 +1,9 @@ -import { expect } from 'chai'; +import type { Credentials } from '@rocket.chat/api-client'; +import type { IIntegration, IMessage, IRoom, IUser } from '@rocket.chat/core-typings'; +import { expect, assert } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, api, request, credentials, reservedWords } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials, reservedWords } from '../../data/api-data'; import { CI_MAX_ROOMS_PER_GUEST as maxRoomsPerGuest } from '../../data/constants'; import { createIntegration, removeIntegration } from '../../data/integration.helper'; import { updatePermission, updateSetting } from '../../data/permissions.helper'; @@ -9,33 +11,31 @@ import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { deleteTeam } from '../../data/teams.helper'; import { testFileUploads } from '../../data/uploads.helper'; import { adminUsername, password } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; import { createUser, login, deleteUser } from '../../data/users.helper'; -function getRoomInfo(roomId) { - return new Promise((resolve /* , reject*/) => { - request +function getRoomInfo(roomId: IRoom['_id']) { + return new Promise<{ channel: IRoom }>((resolve) => { + void request .get(api('channels.info')) .set(credentials) .query({ roomId, }) - .end((err, req) => { + .end((_err, req) => { resolve(req.body); }); }); } -const channel = {}; - -describe('[Channels]', function () { +describe('[Channels]', () => { + let channel: Pick; const apiPublicChannelName = `api-channel-test-${Date.now()}`; - this.retries(0); - before((done) => getCredentials(done)); before('Creating channel', (done) => { - request + void request .post(api('channels.create')) .set(credentials) .send({ @@ -49,8 +49,10 @@ describe('[Channels]', function () { expect(res.body).to.have.nested.property('channel.name', apiPublicChannelName); expect(res.body).to.have.nested.property('channel.t', 'c'); expect(res.body).to.have.nested.property('channel.msgs', 0); - channel._id = res.body.channel._id; - channel.name = res.body.channel.name; + channel = { + _id: res.body.channel._id, + name: res.body.channel.name, + }; }) .end(done); }); @@ -81,7 +83,7 @@ describe('[Channels]', function () { }); it('/channels.addModerator', (done) => { - request + void request .post(api('channels.addModerator')) .set(credentials) .send({ @@ -97,7 +99,7 @@ describe('[Channels]', function () { }); it('/channels.addModerator should fail with missing room Id', (done) => { - request + void request .post(api('channels.addModerator')) .set(credentials) .send({ @@ -112,7 +114,7 @@ describe('[Channels]', function () { }); it('/channels.addModerator should fail with missing user Id', (done) => { - request + void request .post(api('channels.addModerator')) .set(credentials) .send({ @@ -127,7 +129,7 @@ describe('[Channels]', function () { }); it('/channels.removeModerator', (done) => { - request + void request .post(api('channels.removeModerator')) .set(credentials) .send({ @@ -143,7 +145,7 @@ describe('[Channels]', function () { }); it('/channels.removeModerator should fail on invalid room id', (done) => { - request + void request .post(api('channels.removeModerator')) .set(credentials) .send({ @@ -158,7 +160,7 @@ describe('[Channels]', function () { }); it('/channels.removeModerator should fail on invalid user id', (done) => { - request + void request .post(api('channels.removeModerator')) .set(credentials) .send({ @@ -173,7 +175,7 @@ describe('[Channels]', function () { }); it('/channels.addOwner', (done) => { - request + void request .post(api('channels.addOwner')) .set(credentials) .send({ @@ -189,7 +191,7 @@ describe('[Channels]', function () { }); it('/channels.removeOwner', (done) => { - request + void request .post(api('channels.removeOwner')) .set(credentials) .send({ @@ -247,7 +249,7 @@ describe('[Channels]', function () { }); it('/channels.addOwner', (done) => { - request + void request .post(api('channels.addOwner')) .set(credentials) .send({ @@ -263,7 +265,7 @@ describe('[Channels]', function () { }); it('/channels.archive', (done) => { - request + void request .post(api('channels.archive')) .set(credentials) .send({ @@ -278,7 +280,7 @@ describe('[Channels]', function () { }); it('/channels.unarchive', (done) => { - request + void request .post(api('channels.unarchive')) .set(credentials) .send({ @@ -293,7 +295,7 @@ describe('[Channels]', function () { }); it('/channels.close', (done) => { - request + void request .post(api('channels.close')) .set(credentials) .send({ @@ -308,7 +310,7 @@ describe('[Channels]', function () { }); it('/channels.close', (done) => { - request + void request .post(api('channels.close')) .set(credentials) .send({ @@ -324,7 +326,7 @@ describe('[Channels]', function () { }); it('/channels.open', (done) => { - request + void request .post(api('channels.open')) .set(credentials) .send({ @@ -339,7 +341,7 @@ describe('[Channels]', function () { }); it('/channels.list', (done) => { - request + void request .get(api('channels.list')) .set(credentials) .query({ @@ -356,7 +358,7 @@ describe('[Channels]', function () { }); it('/channels.list.joined', (done) => { - request + void request .get(api('channels.list.joined')) .set(credentials) .query({ @@ -372,7 +374,7 @@ describe('[Channels]', function () { .end(done); }); it('/channels.counters', (done) => { - request + void request .get(api('channels.counters')) .set(credentials) .query({ @@ -396,9 +398,9 @@ describe('[Channels]', function () { it('/channels.rename', async () => { const roomInfo = await getRoomInfo(channel._id); - function failRenameChannel(name) { + function failRenameChannel(name: string) { it(`should not rename a channel to the reserved name ${name}`, (done) => { - request + void request .post(api('channels.rename')) .set(credentials) .send({ @@ -438,7 +440,7 @@ describe('[Channels]', function () { }); it('/channels.addAll', (done) => { - request + void request .post(api('channels.addAll')) .set(credentials) .send({ @@ -456,7 +458,7 @@ describe('[Channels]', function () { }); it('/channels.addLeader', (done) => { - request + void request .post(api('channels.addLeader')) .set(credentials) .send({ @@ -471,7 +473,7 @@ describe('[Channels]', function () { .end(done); }); it('/channels.removeLeader', (done) => { - request + void request .post(api('channels.removeLeader')) .set(credentials) .send({ @@ -548,8 +550,8 @@ describe('[Channels]', function () { }); describe('[/channels.create]', () => { - let guestUser; - let room; + let guestUser: TestUser; + let room: IRoom; before(async () => { guestUser = await createUser({ roles: ['guest'] }); @@ -592,7 +594,7 @@ describe('[Channels]', function () { } const channelIds = (await Promise.all(promises)).map((r) => r.body.channel).map((channel) => channel._id); - request + void request .post(api('channels.create')) .set(credentials) .send({ @@ -606,7 +608,7 @@ describe('[Channels]', function () { room = res.body.group; }) .then(() => { - request + void request .get(api('channels.members')) .set(credentials) .query({ @@ -626,15 +628,14 @@ describe('[Channels]', function () { }); describe('[/channels.info]', () => { const testChannelName = `api-channel-test-${Date.now()}`; - let testChannel = {}; - let channelMessage = {}; + let testChannel: IRoom; after(async () => { await deleteRoom({ type: 'c', roomId: testChannel._id }); }); it('creating new channel...', (done) => { - request + void request .post(api('channels.create')) .set(credentials) .send({ @@ -648,7 +649,7 @@ describe('[Channels]', function () { .end(done); }); it('should fail to create the same channel twice', (done) => { - request + void request .post(api('channels.create')) .set(credentials) .send({ @@ -663,7 +664,7 @@ describe('[Channels]', function () { .end(done); }); it('should return channel basic structure', (done) => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -680,8 +681,11 @@ describe('[Channels]', function () { }) .end(done); }); + + let channelMessage: IMessage; + it('sending a message...', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -699,7 +703,7 @@ describe('[Channels]', function () { .end(done); }); it('REACTing with last message', (done) => { - request + void request .post(api('chat.react')) .set(credentials) .send({ @@ -714,7 +718,7 @@ describe('[Channels]', function () { .end(done); }); it('STARring last message', (done) => { - request + void request .post(api('chat.starMessage')) .set(credentials) .send({ @@ -728,7 +732,7 @@ describe('[Channels]', function () { .end(done); }); it('PINning last message', (done) => { - request + void request .post(api('chat.pinMessage')) .set(credentials) .send({ @@ -742,7 +746,7 @@ describe('[Channels]', function () { .end(done); }); it('should return channel structure with "lastMessage" object including pin, reactions and star(should be an array) infos', (done) => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -764,7 +768,7 @@ describe('[Channels]', function () { .end(done); }); it('should return all channels messages where the last message of array should have the "star" array with USERS star ONLY', (done) => { - request + void request .get(api('channels.messages')) .set(credentials) .query({ @@ -775,15 +779,15 @@ describe('[Channels]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('messages').and.to.be.an('array'); - const { messages } = res.body; + const messages = res.body.messages as IMessage[]; const lastMessage = messages.filter((message) => message._id === channelMessage._id)[0]; expect(lastMessage).to.have.property('starred').and.to.be.an('array'); - expect(lastMessage.starred[0]._id).to.be.equal(adminUsername); + expect(lastMessage.starred?.[0]._id).to.be.equal(adminUsername); }) .end(done); }); it('should return all channels messages where the last message of array should have the "star" array with USERS star ONLY even requested with count and offset params', (done) => { - request + void request .get(api('channels.messages')) .set(credentials) .query({ @@ -796,18 +800,18 @@ describe('[Channels]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('messages').and.to.be.an('array'); - const { messages } = res.body; + const messages = res.body.messages as IMessage[]; const lastMessage = messages.filter((message) => message._id === channelMessage._id)[0]; expect(lastMessage).to.have.property('starred').and.to.be.an('array'); - expect(lastMessage.starred[0]._id).to.be.equal(adminUsername); + expect(lastMessage.starred?.[0]._id).to.be.equal(adminUsername); }) .end(done); }); }); describe('[/channels.online]', () => { - const createdChannels = []; - const createdUsers = []; + const createdChannels: IRoom[] = []; + const createdUsers: TestUser[] = []; const createUserAndChannel = async () => { const testUser = await createUser(); @@ -843,7 +847,7 @@ describe('[Channels]', function () { }); it('should return an error if no query', () => - request + void request .get(api('channels.online')) .set(credentials) .expect('Content-Type', 'application/json') @@ -854,7 +858,7 @@ describe('[Channels]', function () { })); it('should return an error if passing an empty query', () => - request + void request .get(api('channels.online')) .set(credentials) .query('query={}') @@ -916,10 +920,10 @@ describe('[Channels]', function () { }); describe('[/channels.join]', () => { - let testChannelNoCode; - let testChannelWithCode; - let testUser; - let testUserCredentials; + let testChannelNoCode: IRoom; + let testChannelWithCode: IRoom; + let testUser: TestUser; + let testUserCredentials: Credentials; before('Create test user', async () => { testUser = await createUser(); @@ -943,7 +947,7 @@ describe('[Channels]', function () { }); before('Set code for channel', (done) => { - request + void request .post(api('channels.setJoinCode')) .set(testUserCredentials) .send({ @@ -959,7 +963,7 @@ describe('[Channels]', function () { }); it('should fail if invalid channel', (done) => { - request + void request .post(api('channels.join')) .set(credentials) .send({ @@ -976,7 +980,7 @@ describe('[Channels]', function () { describe('code-free channel', () => { it('should succeed when joining code-free channel without join code', (done) => { - request + void request .post(api('channels.join')) .set(credentials) .send({ @@ -999,7 +1003,7 @@ describe('[Channels]', function () { }); it('should fail when joining code-needed channel without join code and no join-without-join-code permission', (done) => { - request + void request .post(api('channels.join')) .set(credentials) .send({ @@ -1015,7 +1019,7 @@ describe('[Channels]', function () { }); it('should fail when joining code-needed channel with incorrect join code and no join-without-join-code permission', (done) => { - request + void request .post(api('channels.join')) .set(credentials) .send({ @@ -1032,7 +1036,7 @@ describe('[Channels]', function () { }); it('should succeed when joining code-needed channel with join code', (done) => { - request + void request .post(api('channels.join')) .set(credentials) .send({ @@ -1055,7 +1059,7 @@ describe('[Channels]', function () { }); before('leave channel', (done) => { - request + void request .post(api('channels.leave')) .set(credentials) .send({ @@ -1070,7 +1074,7 @@ describe('[Channels]', function () { }); it('should succeed when joining code-needed channel without join code and with join-without-join-code permission', (done) => { - request + void request .post(api('channels.join')) .set(credentials) .send({ @@ -1090,7 +1094,7 @@ describe('[Channels]', function () { describe('/channels.setDescription', () => { it('should set the description of the channel with a string', (done) => { - request + void request .post(api('channels.setDescription')) .set(credentials) .send({ @@ -1106,7 +1110,7 @@ describe('[Channels]', function () { .end(done); }); it('should set the description of the channel with an empty string(remove the description)', (done) => { - request + void request .post(api('channels.setDescription')) .set(credentials) .send({ @@ -1125,7 +1129,7 @@ describe('[Channels]', function () { describe('/channels.setTopic', () => { it('should set the topic of the channel with a string', (done) => { - request + void request .post(api('channels.setTopic')) .set(credentials) .send({ @@ -1141,7 +1145,7 @@ describe('[Channels]', function () { .end(done); }); it('should set the topic of the channel with an empty string(remove the topic)', (done) => { - request + void request .post(api('channels.setTopic')) .set(credentials) .send({ @@ -1160,7 +1164,7 @@ describe('[Channels]', function () { describe('/channels.setAnnouncement', () => { it('should set the announcement of the channel with a string', (done) => { - request + void request .post(api('channels.setAnnouncement')) .set(credentials) .send({ @@ -1176,7 +1180,7 @@ describe('[Channels]', function () { .end(done); }); it('should set the announcement of the channel with an empty string(remove the announcement)', (done) => { - request + void request .post(api('channels.setAnnouncement')) .set(credentials) .send({ @@ -1195,7 +1199,7 @@ describe('[Channels]', function () { describe('/channels.setPurpose', () => { it('should set the purpose of the channel with a string', (done) => { - request + void request .post(api('channels.setPurpose')) .set(credentials) .send({ @@ -1211,7 +1215,7 @@ describe('[Channels]', function () { .end(done); }); it('should set the announcement of channel with an empty string(remove the purpose)', (done) => { - request + void request .post(api('channels.setPurpose')) .set(credentials) .send({ @@ -1230,7 +1234,7 @@ describe('[Channels]', function () { describe('/channels.history', () => { it('should return an array of members by channel', (done) => { - request + void request .get(api('channels.history')) .set(credentials) .query({ @@ -1246,7 +1250,7 @@ describe('[Channels]', function () { }); it('should return an array of members by channel even requested with count and offset params', (done) => { - request + void request .get(api('channels.history')) .set(credentials) .query({ @@ -1265,7 +1269,7 @@ describe('[Channels]', function () { }); describe('/channels.members', () => { - let testUser; + let testUser: TestUser; before(async () => { testUser = await createUser(); @@ -1286,7 +1290,7 @@ describe('[Channels]', function () { }); it('should return an array of members by channel', (done) => { - request + void request .get(api('channels.members')) .set(credentials) .query({ @@ -1305,7 +1309,7 @@ describe('[Channels]', function () { }); it('should return an array of members by channel even requested with count and offset params', (done) => { - request + void request .get(api('channels.members')) .set(credentials) .query({ @@ -1326,7 +1330,7 @@ describe('[Channels]', function () { }); it('should return an filtered array of members by channel', (done) => { - request + void request .get(api('channels.members')) .set(credentials) .query({ @@ -1349,21 +1353,21 @@ describe('[Channels]', function () { }); describe('/channels.getIntegrations', () => { - let integrationCreatedByAnUser; - let userCredentials; - let createdChannel; - let user; + let integrationCreatedByAnUser: IIntegration; + let userCredentials: Credentials; + let createdChannel: IRoom; + let user: TestUser; before((done) => { - createRoom({ name: `test-integration-channel-${Date.now()}`, type: 'c' }).end((err, res) => { + void createRoom({ name: `test-integration-channel-${Date.now()}`, type: 'c' }).end((_err, res) => { createdChannel = res.body.channel; - createUser().then((createdUser) => { + void createUser().then((createdUser) => { user = createdUser; - login(user.username, password).then((credentials) => { + void login(user.username, password).then((credentials) => { userCredentials = credentials; - updatePermission('manage-incoming-integrations', ['user']).then(() => { - updatePermission('manage-own-incoming-integrations', ['user']).then(() => { - createIntegration( + void updatePermission('manage-incoming-integrations', ['user']).then(() => { + void updatePermission('manage-own-incoming-integrations', ['user']).then(() => { + void createIntegration( { type: 'webhook-incoming', name: 'Incoming test', @@ -1397,8 +1401,8 @@ describe('[Channels]', function () { }); it('should return the list of integrations of created channel and it should contain the integration created by user when the admin DOES have the permission', (done) => { - updatePermission('manage-incoming-integrations', ['admin']).then(() => { - request + void updatePermission('manage-incoming-integrations', ['admin']).then(() => { + void request .get(api('channels.getIntegrations')) .set(credentials) .query({ @@ -1408,9 +1412,10 @@ describe('[Channels]', function () { .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - const integrationCreated = res.body.integrations.find( + const integrationCreated = (res.body.integrations as IIntegration[]).find( (createdIntegration) => createdIntegration._id === integrationCreatedByAnUser._id, ); + assert.isDefined(integrationCreated); expect(integrationCreated).to.be.an('object'); expect(integrationCreated._id).to.be.equal(integrationCreatedByAnUser._id); expect(res.body).to.have.property('offset'); @@ -1421,9 +1426,9 @@ describe('[Channels]', function () { }); it('should return the list of integrations created by the user only', (done) => { - updatePermission('manage-own-incoming-integrations', ['admin']).then(() => { - updatePermission('manage-incoming-integrations', []).then(() => { - request + void updatePermission('manage-own-incoming-integrations', ['admin']).then(() => { + void updatePermission('manage-incoming-integrations', []).then(() => { + void request .get(api('channels.getIntegrations')) .set(credentials) .query({ @@ -1433,9 +1438,10 @@ describe('[Channels]', function () { .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - const integrationCreated = res.body.integrations.find( + const integrationCreated = (res.body.integrations as IIntegration[]).find( (createdIntegration) => createdIntegration._id === integrationCreatedByAnUser._id, ); + assert.isUndefined(integrationCreated); expect(integrationCreated).to.be.equal(undefined); expect(res.body).to.have.property('offset'); expect(res.body).to.have.property('total'); @@ -1446,11 +1452,11 @@ describe('[Channels]', function () { }); it('should return unauthorized error when the user does not have any integrations permissions', (done) => { - updatePermission('manage-incoming-integrations', []).then(() => { - updatePermission('manage-own-incoming-integrations', []).then(() => { - updatePermission('manage-outgoing-integrations', []).then(() => { - updatePermission('manage-own-outgoing-integrations', []).then(() => { - request + void updatePermission('manage-incoming-integrations', []).then(() => { + void updatePermission('manage-own-incoming-integrations', []).then(() => { + void updatePermission('manage-outgoing-integrations', []).then(() => { + void updatePermission('manage-own-outgoing-integrations', []).then(() => { + void request .get(api('channels.getIntegrations')) .set(credentials) .query({ @@ -1471,8 +1477,8 @@ describe('[Channels]', function () { }); describe('/channels.setCustomFields:', () => { - let withCFChannel; - let withoutCFChannel; + let withCFChannel: IRoom; + let withoutCFChannel: IRoom; after(async () => { await deleteRoom({ type: 'c', roomId: withCFChannel._id }); @@ -1480,20 +1486,20 @@ describe('[Channels]', function () { it('create channel with customFields', (done) => { const customFields = { field0: 'value0' }; - request + void request .post(api('channels.create')) .set(credentials) .send({ name: `channel.cf.${Date.now()}`, customFields, }) - .end((err, res) => { + .end((_err, res) => { withCFChannel = res.body.channel; done(); }); }); it('get customFields using channels.info', (done) => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -1528,7 +1534,7 @@ describe('[Channels]', function () { }); }); it('get customFields using channels.info', (done) => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -1543,7 +1549,7 @@ describe('[Channels]', function () { .end(done); }); it('delete channels with customFields', (done) => { - request + void request .post(api('channels.delete')) .set(credentials) .send({ @@ -1557,13 +1563,13 @@ describe('[Channels]', function () { .end(done); }); it('create channel without customFields', (done) => { - request + void request .post(api('channels.create')) .set(credentials) .send({ name: `channel.cf.${Date.now()}`, }) - .end((err, res) => { + .end((_err, res) => { withoutCFChannel = res.body.channel; done(); }); @@ -1613,7 +1619,7 @@ describe('[Channels]', function () { it('set customFields to empty object', (done) => { const customFields = {}; - request + void request .post(api('channels.setCustomFields')) .set(credentials) .send({ @@ -1636,7 +1642,7 @@ describe('[Channels]', function () { it('set customFields as a string -> should return 400', (done) => { const customFields = ''; - request + void request .post(api('channels.setCustomFields')) .set(credentials) .send({ @@ -1651,7 +1657,7 @@ describe('[Channels]', function () { .end(done); }); it('delete channel with empty customFields', (done) => { - request + void request .post(api('channels.delete')) .set(credentials) .send({ @@ -1667,7 +1673,7 @@ describe('[Channels]', function () { }); describe('/channels.setDefault', () => { - let testChannel; + let testChannel: IRoom; const name = `setDefault-${Date.now()}`; before(async () => { @@ -1723,7 +1729,7 @@ describe('[Channels]', function () { }); describe('/channels.setType', () => { - let testChannel; + let testChannel: IRoom; const name = `setType-${Date.now()}`; before(async () => { @@ -1737,7 +1743,7 @@ describe('[Channels]', function () { it('should change the type public channel to private', async () => { const roomInfo = await getRoomInfo(testChannel._id); - request + void request .post(api('channels.setType')) .set(credentials) .send({ @@ -1757,7 +1763,7 @@ describe('[Channels]', function () { }); describe('/channels.delete:', () => { - let testChannel; + let testChannel: IRoom; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.test.${Date.now()}` })).body.channel; @@ -1768,7 +1774,7 @@ describe('[Channels]', function () { }); it('/channels.delete', (done) => { - request + void request .post(api('channels.delete')) .set(credentials) .send({ @@ -1782,7 +1788,7 @@ describe('[Channels]', function () { .end(done); }); it('/channels.info', (done) => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -1800,7 +1806,7 @@ describe('[Channels]', function () { describe('/channels.getAllUserMentionsByChannel', () => { it('should return an array of mentions by channel', (done) => { - request + void request .get(api('channels.getAllUserMentionsByChannel')) .set(credentials) .query({ @@ -1818,7 +1824,7 @@ describe('[Channels]', function () { .end(done); }); it('should return an array of mentions by channel even requested with count and offset params', (done) => { - request + void request .get(api('channels.getAllUserMentionsByChannel')) .set(credentials) .query({ @@ -1840,7 +1846,7 @@ describe('[Channels]', function () { }); describe('/channels.roles', () => { - let testChannel; + let testChannel: IRoom; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.roles.test.${Date.now()}` })).body.channel; @@ -1851,7 +1857,7 @@ describe('[Channels]', function () { }); it('/channels.invite', (done) => { - request + void request .post(api('channels.invite')) .set(credentials) .send({ @@ -1861,7 +1867,7 @@ describe('[Channels]', function () { .end(done); }); it('/channels.addModerator', (done) => { - request + void request .post(api('channels.addModerator')) .set(credentials) .send({ @@ -1871,7 +1877,7 @@ describe('[Channels]', function () { .end(done); }); it('/channels.addLeader', (done) => { - request + void request .post(api('channels.addLeader')) .set(credentials) .send({ @@ -1881,7 +1887,7 @@ describe('[Channels]', function () { .end(done); }); it('should return an array of role <-> user relationships in a channel', (done) => { - request + void request .get(api('channels.roles')) .set(credentials) .query({ @@ -1912,7 +1918,7 @@ describe('[Channels]', function () { }); describe('/channels.moderators', () => { - let testChannel; + let testChannel: IRoom; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.moderators.test.${Date.now()}` })).body.channel; @@ -1923,7 +1929,7 @@ describe('[Channels]', function () { }); it('/channels.invite', (done) => { - request + void request .post(api('channels.invite')) .set(credentials) .send({ @@ -1933,7 +1939,7 @@ describe('[Channels]', function () { .end(done); }); it('/channels.addModerator', (done) => { - request + void request .post(api('channels.addModerator')) .set(credentials) .send({ @@ -1943,7 +1949,7 @@ describe('[Channels]', function () { .end(done); }); it('should return an array of moderators with rocket.cat as a moderator', (done) => { - request + void request .get(api('channels.moderators')) .set(credentials) .query({ @@ -1961,7 +1967,7 @@ describe('[Channels]', function () { }); describe('/channels.anonymousread', () => { - let testChannel; + let testChannel: IRoom; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.anonymousread.test.${Date.now()}` })).body.channel; @@ -1972,8 +1978,8 @@ describe('[Channels]', function () { }); it('should return an error when the setting "Accounts_AllowAnonymousRead" is disabled', (done) => { - updateSetting('Accounts_AllowAnonymousRead', false).then(() => { - request + void updateSetting('Accounts_AllowAnonymousRead', false).then(() => { + void request .get(api('channels.anonymousread')) .query({ roomId: testChannel._id, @@ -1991,8 +1997,8 @@ describe('[Channels]', function () { }); }); it('should return the messages list when the setting "Accounts_AllowAnonymousRead" is enabled', (done) => { - updateSetting('Accounts_AllowAnonymousRead', true).then(() => { - request + void updateSetting('Accounts_AllowAnonymousRead', true).then(() => { + void request .get(api('channels.anonymousread')) .query({ roomId: testChannel._id, @@ -2007,8 +2013,8 @@ describe('[Channels]', function () { }); }); it('should return the messages list when the setting "Accounts_AllowAnonymousRead" is enabled even requested with count and offset params', (done) => { - updateSetting('Accounts_AllowAnonymousRead', true).then(() => { - request + void updateSetting('Accounts_AllowAnonymousRead', true).then(() => { + void request .get(api('channels.anonymousread')) .query({ roomId: testChannel._id, @@ -2027,13 +2033,14 @@ describe('[Channels]', function () { }); describe('/channels.convertToTeam', () => { - let testChannel; + let testChannel: IRoom; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.convertToTeam.test.${Date.now()}` })).body.channel; }); after(async () => { + assert.isDefined(testChannel.name); await Promise.all([ updatePermission('create-team', ['admin', 'user']), updatePermission('edit-room', ['admin', 'owner', 'moderator']), @@ -2070,7 +2077,7 @@ describe('[Channels]', function () { }); it(`should return an error when the channel's name and id are sent as parameter`, (done) => { - request + void request .post(api('channels.convertToTeam')) .set(credentials) .send({ @@ -2120,11 +2127,11 @@ describe('[Channels]', function () { }); it('should fail to convert channel without the required parameters', (done) => { - request.post(api('channels.convertToTeam')).set(credentials).send({}).expect(400).end(done); + void request.post(api('channels.convertToTeam')).set(credentials).send({}).expect(400).end(done); }); it("should fail to convert channel if it's already taken", (done) => { - request + void request .post(api('channels.convertToTeam')) .set(credentials) .send({ channelId: testChannel._id }) @@ -2137,7 +2144,7 @@ describe('[Channels]', function () { }); describe("Setting: 'Use Real Name': true", () => { - let testChannel; + let testChannel: IRoom; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.anonymousread.test.${Date.now()}` })).body.channel; @@ -2183,7 +2190,7 @@ describe('[Channels]', function () { }); it('/channels.list', (done) => { - request + void request .get(api('channels.list')) .set(credentials) .expect('Content-Type', 'application/json') @@ -2194,7 +2201,7 @@ describe('[Channels]', function () { expect(res.body).to.have.property('total'); expect(res.body).to.have.property('channels').and.to.be.an('array'); - const retChannel = res.body.channels.find(({ _id }) => _id === testChannel._id); + const retChannel = (res.body.channels as IRoom[]).find(({ _id }) => _id === testChannel._id); expect(retChannel).to.have.nested.property('lastMessage.u.name', 'RocketChat Internal Admin Test'); }) @@ -2202,7 +2209,7 @@ describe('[Channels]', function () { }); it('/channels.list.joined', (done) => { - request + void request .get(api('channels.list.joined')) .set(credentials) .expect('Content-Type', 'application/json') @@ -2213,7 +2220,7 @@ describe('[Channels]', function () { expect(res.body).to.have.property('total'); expect(res.body).to.have.property('channels').and.to.be.an('array'); - const retChannel = res.body.channels.find(({ _id }) => _id === testChannel._id); + const retChannel = (res.body.channels as IRoom[]).find(({ _id }) => _id === testChannel._id); expect(retChannel).to.have.nested.property('lastMessage.u.name', 'RocketChat Internal Admin Test'); }) diff --git a/apps/meteor/tests/end-to-end/api/03-groups.js b/apps/meteor/tests/end-to-end/api/03-groups.ts similarity index 94% rename from apps/meteor/tests/end-to-end/api/03-groups.js rename to apps/meteor/tests/end-to-end/api/03-groups.ts index 2bf6bc774999..702a8bf5f840 100644 --- a/apps/meteor/tests/end-to-end/api/03-groups.js +++ b/apps/meteor/tests/end-to-end/api/03-groups.ts @@ -1,7 +1,9 @@ -import { expect } from 'chai'; +import type { Credentials } from '@rocket.chat/api-client'; +import type { IIntegration, IMessage, IRoom, IUser } from '@rocket.chat/core-typings'; +import { assert, expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, api, request, credentials, group, apiPrivateChannelName } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials, apiPrivateChannelName } from '../../data/api-data'; import { CI_MAX_ROOMS_PER_GUEST as maxRoomsPerGuest } from '../../data/constants'; import { createIntegration, removeIntegration } from '../../data/integration.helper'; import { updatePermission, updateSetting } from '../../data/permissions.helper'; @@ -9,24 +11,28 @@ import { createRoom } from '../../data/rooms.helper'; import { deleteTeam } from '../../data/teams.helper'; import { testFileUploads } from '../../data/uploads.helper'; import { adminUsername, password } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; import { createUser, login, deleteUser } from '../../data/users.helper'; -function getRoomInfo(roomId) { - return new Promise((resolve /* , reject*/) => { - request +function getRoomInfo(roomId: IRoom['_id']) { + return new Promise<{ group: IRoom }>((resolve) => { + void request .get(api('groups.info')) .set(credentials) .query({ roomId, }) - .end((err, req) => { + .end((_err, req) => { resolve(req.body); }); }); } -describe('[Groups]', function () { - this.retries(0); +describe('[Groups]', () => { + let group: { + _id: string; + name: string; + }; before((done) => getCredentials(done)); @@ -45,8 +51,10 @@ describe('[Groups]', function () { expect(res.body).to.have.nested.property('group.name', apiPrivateChannelName); expect(res.body).to.have.nested.property('group.t', 'p'); expect(res.body).to.have.nested.property('group.msgs', 0); - group._id = res.body.group._id; - group.name = res.body.group.name; + group = { + _id: res.body.group._id, + name: res.body.group.name, + }; }); }); @@ -62,12 +70,13 @@ describe('[Groups]', function () { }); describe('/groups.create', () => { - let guestUser; - let room; + let guestUser: TestUser; + let room: IRoom; before(async () => { guestUser = await createUser({ roles: ['guest'] }); }); + after(async () => { await deleteUser(guestUser); }); @@ -131,7 +140,7 @@ describe('[Groups]', function () { await Promise.all([updateSetting('E2E_Enable', false), updateSetting('E2E_Allow_Unencrypted_Messages', true)]); }); - let rid; + let rid: IRoom['_id']; it('should create a new encrypted group', async () => { await request @@ -262,8 +271,7 @@ describe('[Groups]', function () { }); describe('/groups.info', () => { - let testGroup = {}; - let groupMessage = {}; + let testGroup: IRoom; const newGroupInfoName = `info-private-channel-test-${Date.now()}`; @@ -310,6 +318,8 @@ describe('[Groups]', function () { }); }); + let groupMessage: IMessage; + it('sending a message...', async () => { await request .post(api('chat.sendMessage')) @@ -404,10 +414,10 @@ describe('[Groups]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('messages').and.to.be.an('array'); - const { messages } = res.body; + const messages = res.body.messages as IMessage[]; const lastMessage = messages.filter((message) => message._id === groupMessage._id)[0]; expect(lastMessage).to.have.property('starred').and.to.be.an('array'); - expect(lastMessage.starred[0]._id).to.be.equal(adminUsername); + expect(lastMessage.starred?.[0]._id).to.be.equal(adminUsername); }); }); @@ -425,16 +435,16 @@ describe('[Groups]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('messages').and.to.be.an('array'); - const { messages } = res.body; + const messages = res.body.messages as IMessage[]; const lastMessage = messages.filter((message) => message._id === groupMessage._id)[0]; expect(lastMessage).to.have.property('starred').and.to.be.an('array'); - expect(lastMessage.starred[0]._id).to.be.equal(adminUsername); + expect(lastMessage.starred?.[0]._id).to.be.equal(adminUsername); }); }); }); describe('/groups.invite', async () => { - let roomInfo = {}; + let roomInfo: { group: IRoom }; before(async () => { roomInfo = await getRoomInfo(group._id); @@ -462,7 +472,7 @@ describe('[Groups]', function () { describe('/groups.addModerator', () => { it('should make user a moderator', (done) => { - request + void request .post(api('groups.addModerator')) .set(credentials) .send({ @@ -480,7 +490,7 @@ describe('[Groups]', function () { describe('/groups.removeModerator', () => { it('should remove user from moderator', (done) => { - request + void request .post(api('groups.removeModerator')) .set(credentials) .send({ @@ -498,7 +508,7 @@ describe('[Groups]', function () { describe('/groups.addOwner', () => { it('should add user as owner', (done) => { - request + void request .post(api('groups.addOwner')) .set(credentials) .send({ @@ -516,7 +526,7 @@ describe('[Groups]', function () { describe('/groups.removeOwner', () => { it('should remove user from owner', (done) => { - request + void request .post(api('groups.removeOwner')) .set(credentials) .send({ @@ -534,7 +544,7 @@ describe('[Groups]', function () { describe('/groups.addLeader', () => { it('should add user as leader', (done) => { - request + void request .post(api('groups.addLeader')) .set(credentials) .send({ @@ -552,7 +562,7 @@ describe('[Groups]', function () { describe('/groups.removeLeader', () => { it('should remove user from leader', (done) => { - request + void request .post(api('groups.removeLeader')) .set(credentials) .send({ @@ -569,14 +579,14 @@ describe('[Groups]', function () { }); describe('/groups.kick', () => { - let testUserModerator; - let credsModerator; - let testUserOwner; - let credsOwner; - let testUserMember; - let groupTest; - - const inviteUser = async (userId) => { + let testUserModerator: TestUser; + let credsModerator: Credentials; + let testUserOwner: TestUser; + let credsOwner: Credentials; + let testUserMember: TestUser; + let groupTest: IRoom; + + const inviteUser = async (userId: IUser['_id']) => { await request .post(api('groups.invite')) .set(credsOwner) @@ -748,7 +758,7 @@ describe('[Groups]', function () { describe('/groups.setDescription', () => { it('should set the description of the group with a string', (done) => { - request + void request .post(api('groups.setDescription')) .set(credentials) .send({ @@ -764,7 +774,7 @@ describe('[Groups]', function () { .end(done); }); it('should set the description of the group with an empty string(remove the description)', (done) => { - request + void request .post(api('groups.setDescription')) .set(credentials) .send({ @@ -783,7 +793,7 @@ describe('[Groups]', function () { describe('/groups.setTopic', () => { it('should set the topic of the group with a string', (done) => { - request + void request .post(api('groups.setTopic')) .set(credentials) .send({ @@ -799,7 +809,7 @@ describe('[Groups]', function () { .end(done); }); it('should set the topic of the group with an empty string(remove the topic)', (done) => { - request + void request .post(api('groups.setTopic')) .set(credentials) .send({ @@ -818,7 +828,7 @@ describe('[Groups]', function () { describe('/groups.setPurpose', () => { it('should set the purpose of the group with a string', (done) => { - request + void request .post(api('groups.setPurpose')) .set(credentials) .send({ @@ -834,7 +844,7 @@ describe('[Groups]', function () { .end(done); }); it('should set the purpose of the group with an empty string(remove the purpose)', (done) => { - request + void request .post(api('groups.setPurpose')) .set(credentials) .send({ @@ -853,7 +863,7 @@ describe('[Groups]', function () { describe('/groups.history', () => { it('should return groups history when searching by roomId', (done) => { - request + void request .get(api('groups.history')) .set(credentials) .query({ @@ -868,7 +878,7 @@ describe('[Groups]', function () { .end(done); }); it('should return groups history when searching by roomId even requested with count and offset params', (done) => { - request + void request .get(api('groups.history')) .set(credentials) .query({ @@ -888,7 +898,7 @@ describe('[Groups]', function () { describe('/groups.archive', () => { it('should archive the group', (done) => { - request + void request .post(api('groups.archive')) .set(credentials) .send({ @@ -905,7 +915,7 @@ describe('[Groups]', function () { describe('/groups.unarchive', () => { it('should unarchive the group', (done) => { - request + void request .post(api('groups.unarchive')) .set(credentials) .send({ @@ -922,7 +932,7 @@ describe('[Groups]', function () { describe('/groups.close', () => { it('should close the group', (done) => { - request + void request .post(api('groups.close')) .set(credentials) .send({ @@ -937,7 +947,7 @@ describe('[Groups]', function () { }); it('should return an error when trying to close a private group that is already closed', (done) => { - request + void request .post(api('groups.close')) .set(credentials) .send({ @@ -955,7 +965,7 @@ describe('[Groups]', function () { describe('/groups.open', () => { it('should open the group', (done) => { - request + void request .post(api('groups.open')) .set(credentials) .send({ @@ -972,7 +982,7 @@ describe('[Groups]', function () { describe('/groups.list', () => { it('should list the groups the caller is part of', (done) => { - request + void request .get(api('groups.list')) .set(credentials) .expect('Content-Type', 'application/json') @@ -1099,7 +1109,7 @@ describe('[Groups]', function () { describe('/groups.members', () => { it('should return group members when searching by roomId', (done) => { - request + void request .get(api('groups.members')) .set(credentials) .query({ @@ -1117,7 +1127,7 @@ describe('[Groups]', function () { .end(done); }); it('should return group members when searching by roomId even requested with count and offset params', (done) => { - request + void request .get(api('groups.members')) .set(credentials) .query({ @@ -1144,8 +1154,8 @@ describe('[Groups]', function () { describe('/groups.listAll', () => { it('should fail if the user doesnt have view-room-administration permission', (done) => { - updatePermission('view-room-administration', []).then(() => { - request + void updatePermission('view-room-administration', []).then(() => { + void request .get(api('groups.listAll')) .set(credentials) .expect('Content-Type', 'application/json') @@ -1158,8 +1168,8 @@ describe('[Groups]', function () { }); }); it('should succeed if user has view-room-administration permission', (done) => { - updatePermission('view-room-administration', ['admin']).then(() => { - request + void updatePermission('view-room-administration', ['admin']).then(() => { + void request .get(api('groups.listAll')) .set(credentials) .expect('Content-Type', 'application/json') @@ -1175,7 +1185,7 @@ describe('[Groups]', function () { describe('/groups.counters', () => { it('should return group counters', (done) => { - request + void request .get(api('groups.counters')) .set(credentials) .query({ @@ -1198,7 +1208,7 @@ describe('[Groups]', function () { }); describe('/groups.rename', async () => { - let roomInfo; + let roomInfo: { group: IRoom }; before(async () => { roomInfo = await getRoomInfo(group._id); }); @@ -1224,8 +1234,8 @@ describe('[Groups]', function () { }); describe('/groups.getIntegrations', () => { - let integrationCreatedByAnUser; - let createdGroup; + let integrationCreatedByAnUser: IIntegration; + let createdGroup: IRoom; before(async () => { const resRoom = await createRoom({ name: `test-integration-group-${Date.now()}`, type: 'p' }); @@ -1280,9 +1290,10 @@ describe('[Groups]', function () { .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - const integrationCreated = res.body.integrations.find( + const integrationCreated = (res.body.integrations as IIntegration[]).find( (createdIntegration) => createdIntegration._id === integrationCreatedByAnUser._id, ); + assert.isDefined(integrationCreated); expect(integrationCreated).to.be.an('object'); expect(integrationCreated._id).to.be.equal(integrationCreatedByAnUser._id); expect(res.body).to.have.property('offset'); @@ -1306,7 +1317,7 @@ describe('[Groups]', function () { .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - const integrationCreated = res.body.integrations.find( + const integrationCreated = (res.body.integrations as IIntegration[]).find( (createdIntegration) => createdIntegration._id === integrationCreatedByAnUser._id, ); expect(integrationCreated).to.be.equal(undefined); @@ -1340,7 +1351,7 @@ describe('[Groups]', function () { describe('/groups.setReadOnly', () => { it('should set the group as read only', (done) => { - request + void request .post(api('groups.setReadOnly')) .set(credentials) .send({ @@ -1358,7 +1369,7 @@ describe('[Groups]', function () { describe.skip('/groups.leave', () => { it('should allow the user to leave the group', (done) => { - request + void request .post(api('groups.leave')) .set(credentials) .send({ @@ -1375,7 +1386,7 @@ describe('[Groups]', function () { describe('/groups.setAnnouncement', () => { it('should set the announcement of the group with a string', (done) => { - request + void request .post(api('groups.setAnnouncement')) .set(credentials) .send({ @@ -1391,7 +1402,7 @@ describe('[Groups]', function () { .end(done); }); it('should set the announcement of the group with an empty string(remove the announcement)', (done) => { - request + void request .post(api('groups.setAnnouncement')) .set(credentials) .send({ @@ -1409,7 +1420,7 @@ describe('[Groups]', function () { }); describe('/groups.setType', () => { - let roomTypeId; + let roomTypeId: IRoom['_id']; before(async () => { await request @@ -1456,8 +1467,8 @@ describe('[Groups]', function () { }); describe('/groups.setCustomFields', () => { - let cfchannel; - let groupWithoutCustomFields; + let cfchannel: IRoom; + let groupWithoutCustomFields: IRoom; before('create group with customFields', async () => { const customFields = { field0: 'value0' }; @@ -1505,7 +1516,7 @@ describe('[Groups]', function () { }); it('get customFields using groups.info', (done) => { - request + void request .get(api('groups.info')) .set(credentials) .query({ @@ -1540,7 +1551,7 @@ describe('[Groups]', function () { }); }); it('get customFields using groups.info', (done) => { - request + void request .get(api('groups.info')) .set(credentials) .query({ @@ -1622,7 +1633,7 @@ describe('[Groups]', function () { it('set customFields as a string -> should return 400', (done) => { const customFields = ''; - request + void request .post(api('groups.setCustomFields')) .set(credentials) .send({ @@ -1639,7 +1650,7 @@ describe('[Groups]', function () { }); describe('/groups.delete', () => { - let testGroup; + let testGroup: IRoom; before(async () => { await request .post(api('groups.create')) @@ -1655,7 +1666,7 @@ describe('[Groups]', function () { }); it('should delete group', (done) => { - request + void request .post(api('groups.delete')) .set(credentials) .send({ @@ -1670,7 +1681,7 @@ describe('[Groups]', function () { }); it('should return group not found', (done) => { - request + void request .get(api('groups.info')) .set(credentials) .query({ @@ -1687,7 +1698,7 @@ describe('[Groups]', function () { }); describe('/groups.roles', () => { - let testGroup; + let testGroup: IRoom; before(async () => { await request .post(api('groups.create')) @@ -1714,7 +1725,7 @@ describe('[Groups]', function () { }); it('/groups.invite', (done) => { - request + void request .post(api('groups.invite')) .set(credentials) .send({ @@ -1724,7 +1735,7 @@ describe('[Groups]', function () { .end(done); }); it('/groups.addModerator', (done) => { - request + void request .post(api('groups.addModerator')) .set(credentials) .send({ @@ -1734,7 +1745,7 @@ describe('[Groups]', function () { .end(done); }); it('/groups.addLeader', (done) => { - request + void request .post(api('groups.addLeader')) .set(credentials) .send({ @@ -1744,7 +1755,7 @@ describe('[Groups]', function () { .end(done); }); it('should return an array of roles <-> user relationships in a private group', (done) => { - request + void request .get(api('groups.roles')) .set(credentials) .query({ @@ -1775,7 +1786,7 @@ describe('[Groups]', function () { }); describe('/groups.moderators', () => { - let testGroup; + let testGroup: IRoom; before(async () => { await request .post(api('groups.create')) @@ -1802,7 +1813,7 @@ describe('[Groups]', function () { }); it('/groups.invite', (done) => { - request + void request .post(api('groups.invite')) .set(credentials) .send({ @@ -1812,7 +1823,7 @@ describe('[Groups]', function () { .end(done); }); it('/groups.addModerator', (done) => { - request + void request .post(api('groups.addModerator')) .set(credentials) .send({ @@ -1822,7 +1833,7 @@ describe('[Groups]', function () { .end(done); }); it('should return an array of moderators with rocket.cat as a moderator', (done) => { - request + void request .get(api('groups.moderators')) .set(credentials) .query({ @@ -1840,7 +1851,7 @@ describe('[Groups]', function () { }); describe('/groups.setEncrypted', () => { - let testGroup; + let testGroup: IRoom; before(async () => { await request @@ -1873,7 +1884,7 @@ describe('[Groups]', function () { }); it('should return an error when passing no boolean param', (done) => { - request + void request .post(api('groups.setEncrypted')) .set(credentials) .send({ @@ -1889,7 +1900,7 @@ describe('[Groups]', function () { }); it('should set group as encrypted correctly and return the new data', (done) => { - request + void request .post(api('groups.setEncrypted')) .set(credentials) .send({ @@ -1914,7 +1925,7 @@ describe('[Groups]', function () { }); it('should set group as unencrypted correctly and return the new data', (done) => { - request + void request .post(api('groups.setEncrypted')) .set(credentials) .send({ @@ -1940,7 +1951,7 @@ describe('[Groups]', function () { }); describe('/groups.convertToTeam', () => { - let newGroup; + let newGroup: IRoom; before(async () => { await request @@ -1953,12 +1964,15 @@ describe('[Groups]', function () { }); }); - after(() => Promise.all([deleteTeam(credentials, newGroup.name), updatePermission('create-team', ['admin', 'user'])])); + after(() => { + assert.isDefined(newGroup.name); + return Promise.all([deleteTeam(credentials, newGroup.name), updatePermission('create-team', ['admin', 'user'])]); + }); it('should fail to convert group if lacking edit-room permission', (done) => { - updatePermission('create-team', []).then(() => { - updatePermission('edit-room', ['admin']).then(() => { - request + void updatePermission('create-team', []).then(() => { + void updatePermission('edit-room', ['admin']).then(() => { + void request .post(api('groups.convertToTeam')) .set(credentials) .send({ roomId: newGroup._id }) @@ -1972,9 +1986,9 @@ describe('[Groups]', function () { }); it('should fail to convert group if lacking create-team permission', (done) => { - updatePermission('create-team', ['admin']).then(() => { - updatePermission('edit-room', []).then(() => { - request + void updatePermission('create-team', ['admin']).then(() => { + void updatePermission('edit-room', []).then(() => { + void request .post(api('groups.convertToTeam')) .set(credentials) .send({ roomId: newGroup._id }) @@ -1988,9 +2002,9 @@ describe('[Groups]', function () { }); it('should successfully convert a group to a team', (done) => { - updatePermission('create-team', ['admin']).then(() => { - updatePermission('edit-room', ['admin']).then(() => { - request + void updatePermission('create-team', ['admin']).then(() => { + void updatePermission('edit-room', ['admin']).then(() => { + void request .post(api('groups.convertToTeam')) .set(credentials) .send({ roomId: newGroup._id }) @@ -2004,11 +2018,11 @@ describe('[Groups]', function () { }); it('should fail to convert group without the required parameters', (done) => { - request.post(api('groups.convertToTeam')).set(credentials).send({}).expect(400).end(done); + void request.post(api('groups.convertToTeam')).set(credentials).send({}).expect(400).end(done); }); it("should fail to convert group if it's already taken", (done) => { - request + void request .post(api('groups.convertToTeam')) .set(credentials) .send({ roomId: newGroup._id }) @@ -2021,7 +2035,7 @@ describe('[Groups]', function () { }); describe("Setting: 'Use Real Name': true", () => { - let realNameGroup; + let realNameGroup: IRoom; before(async () => { await updateSetting('UI_Use_Real_Name', true); @@ -2067,7 +2081,7 @@ describe('[Groups]', function () { }); it('/groups.list', (done) => { - request + void request .get(api('groups.list')) .set(credentials) .expect('Content-Type', 'application/json') @@ -2078,7 +2092,7 @@ describe('[Groups]', function () { expect(res.body).to.have.property('total'); expect(res.body).to.have.property('groups').and.to.be.an('array'); - const retGroup = res.body.groups.find(({ _id }) => _id === realNameGroup._id); + const retGroup = (res.body.groups as IRoom[]).find(({ _id }) => _id === realNameGroup._id); expect(retGroup).to.have.nested.property('lastMessage.u.name', 'RocketChat Internal Admin Test'); }) @@ -2086,7 +2100,7 @@ describe('[Groups]', function () { }); it('/groups.listAll', (done) => { - request + void request .get(api('groups.listAll')) .set(credentials) .expect('Content-Type', 'application/json') @@ -2097,7 +2111,7 @@ describe('[Groups]', function () { expect(res.body).to.have.property('total'); expect(res.body).to.have.property('groups').and.to.be.an('array'); - const retGroup = res.body.groups.find(({ _id }) => _id === realNameGroup._id); + const retGroup = (res.body.groups as IRoom[]).find(({ _id }) => _id === realNameGroup._id); expect(retGroup).to.have.nested.property('lastMessage.u.name', 'RocketChat Internal Admin Test'); }) diff --git a/apps/meteor/tests/end-to-end/api/04-direct-message.js b/apps/meteor/tests/end-to-end/api/04-direct-message.ts similarity index 91% rename from apps/meteor/tests/end-to-end/api/04-direct-message.js rename to apps/meteor/tests/end-to-end/api/04-direct-message.ts index be8868ef6b48..b150c9f7669d 100644 --- a/apps/meteor/tests/end-to-end/api/04-direct-message.js +++ b/apps/meteor/tests/end-to-end/api/04-direct-message.ts @@ -1,20 +1,23 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IMessage, IRoom, IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, api, request, credentials, directMessage, apiUsername, apiEmail, methodCall } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials, apiUsername, apiEmail, methodCall } from '../../data/api-data'; import { updateSetting, updatePermission } from '../../data/permissions.helper'; import { deleteRoom } from '../../data/rooms.helper'; import { testFileUploads } from '../../data/uploads.helper'; import { password, adminUsername } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; import { createUser, deleteUser, login } from '../../data/users.helper'; -describe('[Direct Messages]', function () { - this.retries(0); +describe('[Direct Messages]', () => { + let directMessage: { _id: IRoom['_id'] }; before((done) => getCredentials(done)); before('/chat.postMessage', (done) => { - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -27,14 +30,14 @@ describe('[Direct Messages]', function () { expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('message.msg', 'This message was sent using the API'); expect(res.body).to.have.nested.property('message.rid'); - directMessage._id = res.body.message.rid; + directMessage = { _id: res.body.message.rid }; }) .end(done); }); describe('/im.setTopic', () => { it('should set the topic of the DM with a string', (done) => { - request + void request .post(api('im.setTopic')) .set(credentials) .send({ @@ -50,7 +53,7 @@ describe('[Direct Messages]', function () { .end(done); }); it('should set the topic of DM with an empty string(remove the topic)', (done) => { - request + void request .post(api('im.setTopic')) .set(credentials) .send({ @@ -68,10 +71,10 @@ describe('[Direct Messages]', function () { }); describe('Testing DM info', () => { - let testDM = {}; - let dmMessage = {}; + let testDM: IRoom; + let dmMessage: IMessage; it('creating new DM...', (done) => { - request + void request .post(api('im.create')) .set(credentials) .send({ @@ -85,7 +88,7 @@ describe('[Direct Messages]', function () { .end(done); }); it('sending a message...', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -103,7 +106,7 @@ describe('[Direct Messages]', function () { .end(done); }); it('REACTing with last message', (done) => { - request + void request .post(api('chat.react')) .set(credentials) .send({ @@ -118,7 +121,7 @@ describe('[Direct Messages]', function () { .end(done); }); it('STARring last message', (done) => { - request + void request .post(api('chat.starMessage')) .set(credentials) .send({ @@ -132,7 +135,7 @@ describe('[Direct Messages]', function () { .end(done); }); it('PINning last message', (done) => { - request + void request .post(api('chat.pinMessage')) .set(credentials) .send({ @@ -146,7 +149,7 @@ describe('[Direct Messages]', function () { .end(done); }); it('should return all DM messages where the last message of array should have the "star" array with USERS star ONLY', (done) => { - request + void request .get(api('im.messages')) .set(credentials) .query({ @@ -157,17 +160,17 @@ describe('[Direct Messages]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('messages').and.to.be.an('array'); - const { messages } = res.body; + const messages = res.body.messages as IMessage[]; const lastMessage = messages.filter((message) => message._id === dmMessage._id)[0]; expect(lastMessage).to.have.property('starred').and.to.be.an('array'); - expect(lastMessage.starred[0]._id).to.be.equal(adminUsername); + expect(lastMessage.starred?.[0]._id).to.be.equal(adminUsername); }) .end(done); }); }); it('/im.history', (done) => { - request + void request .get(api('im.history')) .set(credentials) .query({ @@ -183,7 +186,7 @@ describe('[Direct Messages]', function () { }); it('/im.list', (done) => { - request + void request .get(api('im.list')) .set(credentials) .expect('Content-Type', 'application/json') @@ -207,7 +210,7 @@ describe('[Direct Messages]', function () { }); it('/im.list.everyone', (done) => { - request + void request .get(api('im.list.everyone')) .set(credentials) .expect('Content-Type', 'application/json') @@ -236,7 +239,7 @@ describe('[Direct Messages]', function () { after(async () => updateSetting('UI_Use_Real_Name', false)); it('/im.list', (done) => { - request + void request .get(api('im.list')) .set(credentials) .expect('Content-Type', 'application/json') @@ -266,7 +269,7 @@ describe('[Direct Messages]', function () { }); it('/im.list.everyone', (done) => { - request + void request .get(api('im.list.everyone')) .set(credentials) .expect('Content-Type', 'application/json') @@ -296,7 +299,7 @@ describe('[Direct Messages]', function () { }); it('/im.open', (done) => { - request + void request .post(api('im.open')) .set(credentials) .send({ @@ -311,7 +314,7 @@ describe('[Direct Messages]', function () { }); it('/im.counters', (done) => { - request + void request .get(api('im.counters')) .set(credentials) .query({ @@ -338,7 +341,7 @@ describe('[Direct Messages]', function () { describe('/im.messages', () => { it('should return all DM messages that were sent to yourself using your username', (done) => { - request + void request .get(api('im.messages')) .set(credentials) .query({ @@ -356,8 +359,8 @@ describe('[Direct Messages]', function () { describe('/im.messages.others', () => { it('should fail when the endpoint is disabled', (done) => { - updateSetting('API_Enable_Direct_Message_History_EndPoint', false).then(() => { - request + void updateSetting('API_Enable_Direct_Message_History_EndPoint', false).then(() => { + void request .get(api('im.messages.others')) .set(credentials) .query({ @@ -373,9 +376,9 @@ describe('[Direct Messages]', function () { }); }); it('should fail when the endpoint is enabled but the user doesnt have permission', (done) => { - updateSetting('API_Enable_Direct_Message_History_EndPoint', true).then(() => { - updatePermission('view-room-administration', []).then(() => { - request + void updateSetting('API_Enable_Direct_Message_History_EndPoint', true).then(() => { + void updatePermission('view-room-administration', []).then(() => { + void request .get(api('im.messages.others')) .set(credentials) .query({ @@ -392,9 +395,9 @@ describe('[Direct Messages]', function () { }); }); it('should succeed when the endpoint is enabled and user has permission', (done) => { - updateSetting('API_Enable_Direct_Message_History_EndPoint', true).then(() => { - updatePermission('view-room-administration', ['admin']).then(() => { - request + void updateSetting('API_Enable_Direct_Message_History_EndPoint', true).then(() => { + void updatePermission('view-room-administration', ['admin']).then(() => { + void request .get(api('im.messages.others')) .set(credentials) .query({ @@ -416,7 +419,7 @@ describe('[Direct Messages]', function () { }); it('/im.close', (done) => { - request + void request .post(api('im.close')) .set(credentials) .send({ @@ -436,12 +439,12 @@ describe('[Direct Messages]', function () { const name = `Name fname_${apiUsername}`; const updatedName = `Updated Name fname_${apiUsername}`; const email = `fname_${apiEmail}`; - let userId; - let directMessageId; - let user; + let userId: IUser['_id']; + let directMessageId: IMessage['_id']; + let user: TestUser; before((done) => { - request + void request .post(api('users.create')) .set(credentials) .send({ @@ -462,7 +465,7 @@ describe('[Direct Messages]', function () { }); before((done) => { - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -483,7 +486,7 @@ describe('[Direct Messages]', function () { after(async () => deleteUser(user)); it('should have fname property', (done) => { - request + void request .get(api('subscriptions.getOne')) .set(credentials) .query({ @@ -500,7 +503,7 @@ describe('[Direct Messages]', function () { }); it("should update user's name", (done) => { - request + void request .post(api('users.update')) .set(credentials) .send({ @@ -516,7 +519,7 @@ describe('[Direct Messages]', function () { }); it('should have fname property updated', (done) => { - request + void request .get(api('subscriptions.getOne')) .set(credentials) .query({ @@ -535,7 +538,7 @@ describe('[Direct Messages]', function () { describe('/im.members', () => { it('should return and array with two members', (done) => { - request + void request .get(api('im.members')) .set(credentials) .query({ @@ -553,7 +556,7 @@ describe('[Direct Messages]', function () { .end(done); }); it('should return and array with one member', (done) => { - request + void request .get(api('im.members')) .set(credentials) .query({ @@ -571,7 +574,7 @@ describe('[Direct Messages]', function () { .end(done); }); it('should return and array with one member queried by status', (done) => { - request + void request .get(api('im.members')) .set(credentials) .query({ @@ -592,16 +595,16 @@ describe('[Direct Messages]', function () { }); describe('/im.create', () => { - let user; - let userCredentials; + let user: TestUser; + let userCredentials: Credentials; - let otherUser; - let otherUserCredentials; + let otherUser: TestUser; + let otherUserCredentials: Credentials; - let thirdUser; - let thirdUserCredentials; + let thirdUser: TestUser; + let thirdUserCredentials: Credentials; - let roomIds = {}; + let roomIds: Record = {}; // Names have to be in alfabetical order so we can test the room's fullname const userFullName = 'User A'; @@ -623,13 +626,10 @@ describe('[Direct Messages]', function () { await deleteUser(user); await deleteUser(otherUser); await deleteUser(thirdUser); - user = undefined; - otherUser = undefined; - thirdUser = undefined; }); it('creates a DM between two other parties (including self)', (done) => { - request + void request .post(api('im.create')) .set(userCredentials) .send({ @@ -647,7 +647,7 @@ describe('[Direct Messages]', function () { }); it('creates a DM between two other parties (excluding self)', (done) => { - request + void request .post(api('im.create')) .set(credentials) .send({ @@ -666,7 +666,7 @@ describe('[Direct Messages]', function () { }); it('should create a self-DM', (done) => { - request + void request .post(api('im.create')) .set(userCredentials) .send({ @@ -684,9 +684,9 @@ describe('[Direct Messages]', function () { }); describe('should create dm with correct notification preferences', () => { - let user; - let userCredentials; - let userPrefRoomId; + let user: TestUser; + let userCredentials: Credentials; + let userPrefRoomId: IRoom['_id']; before(async () => { user = await createUser(); @@ -698,7 +698,6 @@ describe('[Direct Messages]', function () { await deleteRoom({ type: 'd', roomId: userPrefRoomId }); } await deleteUser(user); - user = undefined; }); it('should save user preferences', async () => { @@ -717,7 +716,7 @@ describe('[Direct Messages]', function () { }); it('should create a DM', (done) => { - request + void request .post(api('im.create')) .set(userCredentials) .send({ @@ -735,7 +734,7 @@ describe('[Direct Messages]', function () { }); it('should return the right user notification preferences in the dm', (done) => { - request + void request .get(api('subscriptions.getOne')) .set(userCredentials) .query({ @@ -752,7 +751,7 @@ describe('[Direct Messages]', function () { }); }); - async function testRoomFNameForUser(testCredentials, roomId, fullName) { + async function testRoomFNameForUser(testCredentials: Credentials, roomId: IRoom['_id'], fullName: string) { return request .get(api('subscriptions.getOne')) .set(testCredentials) @@ -785,10 +784,10 @@ describe('[Direct Messages]', function () { }); describe('/im.delete', () => { - let testDM; + let testDM: IRoom; it('/im.create', (done) => { - request + void request .post(api('im.create')) .set(credentials) .send({ @@ -803,7 +802,7 @@ describe('[Direct Messages]', function () { }); it('/im.delete', (done) => { - request + void request .post(api('im.delete')) .set(credentials) .send({ @@ -818,7 +817,7 @@ describe('[Direct Messages]', function () { }); it('/im.open', (done) => { - request + void request .post(api('im.open')) .set(credentials) .send({ @@ -834,8 +833,8 @@ describe('[Direct Messages]', function () { }); describe('when authenticated as a non-admin user', () => { - let otherUser; - let otherCredentials; + let otherUser: TestUser; + let otherCredentials: Credentials; before(async () => { otherUser = await createUser(); @@ -844,11 +843,10 @@ describe('[Direct Messages]', function () { after(async () => { await deleteUser(otherUser); - otherUser = undefined; }); it('/im.create', (done) => { - request + void request .post(api('im.create')) .set(credentials) .send({ @@ -863,7 +861,7 @@ describe('[Direct Messages]', function () { }); it('/im.delete', (done) => { - request + void request .post(api('im.delete')) .set(otherCredentials) .send({ diff --git a/apps/meteor/tests/end-to-end/api/05-chat.js b/apps/meteor/tests/end-to-end/api/05-chat.ts similarity index 92% rename from apps/meteor/tests/end-to-end/api/05-chat.js rename to apps/meteor/tests/end-to-end/api/05-chat.ts index 96aa276e1a9c..6e2f004b47f0 100644 --- a/apps/meteor/tests/end-to-end/api/05-chat.js +++ b/apps/meteor/tests/end-to-end/api/05-chat.ts @@ -1,17 +1,31 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IMessage, IRoom, IThreadMessage, IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, beforeEach, describe, it } from 'mocha'; +import type { Response } from 'supertest'; -import { getCredentials, api, request, credentials, message } from '../../data/api-data.js'; -import { sendSimpleMessage, deleteMessage, pinMessage } from '../../data/chat.helper.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; +import { sendSimpleMessage, deleteMessage } from '../../data/chat.helper'; import { imgURL } from '../../data/interactions'; import { updatePermission, updateSetting } from '../../data/permissions.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { password } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; import { createUser, deleteUser, login } from '../../data/users.helper'; -describe('[Chat]', function () { - this.retries(0); - let testChannel; +const pinMessage = ({ msgId }: { msgId: IMessage['_id'] }) => { + if (!msgId) { + throw new Error('"msgId" is required in "pinMessage" test helper'); + } + + return request.post(api('chat.pinMessage')).set(credentials).send({ + messageId: msgId, + }); +}; + +describe('[Chat]', () => { + let testChannel: IRoom; + let message: { _id: IMessage['_id'] }; before((done) => getCredentials(done)); @@ -23,7 +37,7 @@ describe('[Chat]', function () { describe('/chat.postMessage', () => { it('should throw an error when at least one of required parameters(channel, roomId) is not sent', (done) => { - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -42,7 +56,7 @@ describe('[Chat]', function () { }); it('should throw an error when it has some properties with the wrong type(attachments.title_link_download, attachments.fields, message_link)', (done) => { - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -83,7 +97,7 @@ describe('[Chat]', function () { describe('should throw an error when the sensitive properties contain malicious XSS values', () => { it('attachment.message_link', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -110,7 +124,7 @@ describe('[Chat]', function () { })); it('attachment.author_link', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -137,7 +151,7 @@ describe('[Chat]', function () { })); it('attachment.title_link', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -164,7 +178,7 @@ describe('[Chat]', function () { })); it('attachment.action.url', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -198,7 +212,7 @@ describe('[Chat]', function () { })); it('message.avatar', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -232,7 +246,7 @@ describe('[Chat]', function () { })); it('attachment.action.image_url', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -267,7 +281,7 @@ describe('[Chat]', function () { })); it('attachment.thumb_url', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -295,7 +309,7 @@ describe('[Chat]', function () { })); it('attachment.author_icon', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -323,7 +337,7 @@ describe('[Chat]', function () { })); it('attachment.image_url', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -350,7 +364,7 @@ describe('[Chat]', function () { expect(res.body).to.have.property('error'); })); it('attachment.audio_url', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -377,7 +391,7 @@ describe('[Chat]', function () { expect(res.body).to.have.property('error'); })); it('attachment.video_url', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -406,7 +420,7 @@ describe('[Chat]', function () { }); it('should throw an error when the properties (attachments.fields.title, attachments.fields.value) are with the wrong type', (done) => { - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -452,7 +466,7 @@ describe('[Chat]', function () { }); it('should return statusCode 200 when postMessage successfully', (done) => { - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -496,7 +510,7 @@ describe('[Chat]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('message.msg', 'Sample message'); - message._id = res.body.message._id; + message = { _id: res.body.message._id }; }) .end(done); }); @@ -504,7 +518,7 @@ describe('[Chat]', function () { describe('/chat.getMessage', () => { it('should retrieve the message successfully', (done) => { - request + void request .get(api('chat.getMessage')) .set(credentials) .query({ @@ -522,7 +536,7 @@ describe('[Chat]', function () { describe('/chat.sendMessage', () => { it("should throw an error when the required param 'rid' is not sent", (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -544,7 +558,7 @@ describe('[Chat]', function () { describe('should throw an error when the sensitive properties contain malicious XSS values', () => { it('attachment.message_link', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -571,7 +585,7 @@ describe('[Chat]', function () { })); it('attachment.author_link', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -598,7 +612,7 @@ describe('[Chat]', function () { })); it('attachment.title_link', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -625,7 +639,7 @@ describe('[Chat]', function () { })); it('attachment.action.url', () => - request + void request .post(api('chat.postMessage')) .set(credentials) .send({ @@ -660,7 +674,7 @@ describe('[Chat]', function () { }); it('should throw an error when it has some properties with the wrong type(attachments.title_link_download, attachments.fields, message_link)', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -703,7 +717,7 @@ describe('[Chat]', function () { it('should send a message successfully', (done) => { message._id = `id-${Date.now()}`; - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -755,8 +769,8 @@ describe('[Chat]', function () { }); describe('oembed', () => { - let ytEmbedMsgId; - let imgUrlMsgId; + let ytEmbedMsgId: IMessage['_id']; + let imgUrlMsgId: IMessage['_id']; before(() => Promise.all([updateSetting('API_EmbedIgnoredHosts', ''), updateSetting('API_EmbedSafePorts', '80, 443, 3000')])); @@ -793,7 +807,7 @@ describe('[Chat]', function () { it('should have an iframe oembed with style max-width', (done) => { setTimeout(() => { - request + void request .get(api('chat.getMessage')) .set(credentials) .query({ @@ -815,7 +829,7 @@ describe('[Chat]', function () { it('should embed an image preview if message has an image url', (done) => { setTimeout(() => { - request + void request .get(api('chat.getMessage')) .set(credentials) .query({ @@ -945,7 +959,7 @@ describe('[Chat]', function () { .expect((res) => { expect(res.body).to.have.property('message').to.have.property('urls').to.be.an('array').that.has.lengthOf(urls.length); - res.body.message.urls.forEach((url) => { + (res.body.message as IMessage).urls?.forEach((url) => { expect(url).to.not.have.property('ignoreParse'); expect(url).to.have.property('meta').that.is.an('object').that.is.empty; }); @@ -954,9 +968,9 @@ describe('[Chat]', function () { }); describe('Read only channel', () => { - let readOnlyChannel; - let userCredentials; - let user; + let readOnlyChannel: IRoom; + let userCredentials: Credentials; + let user: TestUser; before(async () => { user = await createUser(); @@ -972,7 +986,7 @@ describe('[Chat]', function () { ); it('Creating a read-only channel', (done) => { - request + void request .post(api('channels.create')) .set(credentials) .send({ @@ -988,7 +1002,7 @@ describe('[Chat]', function () { .end(done); }); it('should send a message when the user is the owner of a readonly channel', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -1006,7 +1020,7 @@ describe('[Chat]', function () { .end(done); }); it('Inviting regular user to read-only channel', (done) => { - request + void request .post(api('channels.invite')) .set(credentials) .send({ @@ -1024,7 +1038,7 @@ describe('[Chat]', function () { }); it('should fail to send message when the user lacks permission', (done) => { - request + void request .post(api('chat.sendMessage')) .set(userCredentials) .send({ @@ -1064,7 +1078,7 @@ describe('[Chat]', function () { }); it('should fail if user does not have the message-impersonate permission and tries to send message with alias param', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -1084,7 +1098,7 @@ describe('[Chat]', function () { }); it('should fail if user does not have the message-impersonate permission and tries to send message with avatar param', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -1104,7 +1118,15 @@ describe('[Chat]', function () { }); describe('customFields', () => { - async function testMessageSending({ customFields, testCb, statusCode }) { + async function testMessageSending({ + customFields, + testCb, + statusCode, + }: { + customFields?: Record; + testCb: (res: Response) => any; + statusCode: number; + }) { await request .post(api('chat.sendMessage')) .set(credentials) @@ -1334,7 +1356,7 @@ describe('[Chat]', function () { describe('/chat.update', () => { const siteUrl = process.env.SITE_URL || process.env.TEST_API_URL || 'http://localhost:3000'; - let simpleMessageId; + let simpleMessageId: IMessage['_id']; before('should send simple message in room', async () => { const res = await sendSimpleMessage({ roomId: 'GENERAL' }); @@ -1342,7 +1364,7 @@ describe('[Chat]', function () { }); it('should update a message successfully', (done) => { - request + void request .post(api('chat.update')) .set(credentials) .send({ @@ -1361,7 +1383,7 @@ describe('[Chat]', function () { it('should add quote attachments to a message', async () => { const quotedMsgLink = `${siteUrl}/channel/general?msg=${message._id}`; - request + void request .post(api('chat.update')) .set(credentials) .send({ @@ -1381,7 +1403,7 @@ describe('[Chat]', function () { it('should replace a quote attachment in a message', async () => { const quotedMsgLink = `${siteUrl}/channel/general?msg=${simpleMessageId}`; - request + void request .post(api('chat.update')) .set(credentials) .send({ @@ -1402,7 +1424,7 @@ describe('[Chat]', function () { it('should add multiple quote attachments in a single message', async () => { const quotedMsgLink = `${siteUrl}/channel/general?msg=${simpleMessageId}`; const newQuotedMsgLink = `${siteUrl}/channel/general?msg=${message._id}`; - request + void request .post(api('chat.update')) .set(credentials) .send({ @@ -1441,9 +1463,9 @@ describe('[Chat]', function () { }); describe('[/chat.delete]', () => { - let msgId; - let user; - let userCredentials; + let msgId: IMessage['_id']; + let user: TestUser; + let userCredentials: Credentials; before(async () => { user = await createUser(); @@ -1453,7 +1475,7 @@ describe('[Chat]', function () { after(() => deleteUser(user)); beforeEach((done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -1471,7 +1493,7 @@ describe('[Chat]', function () { .end(done); }); it('should delete a message successfully', (done) => { - request + void request .post(api('chat.delete')) .set(credentials) .send({ @@ -1486,7 +1508,7 @@ describe('[Chat]', function () { .end(done); }); it('sending message as another user...', (done) => { - request + void request .post(api('chat.sendMessage')) .set(userCredentials) .send({ @@ -1504,7 +1526,7 @@ describe('[Chat]', function () { .end(done); }); it('should delete a message successfully when the user deletes a message send by another user', (done) => { - request + void request .post(api('chat.delete')) .set(credentials) .send({ @@ -1523,7 +1545,7 @@ describe('[Chat]', function () { describe('/chat.search', () => { before(async () => { - const sendMessage = (text) => + const sendMessage = (text: string) => request .post(api('chat.sendMessage')) .set(credentials) @@ -1542,7 +1564,7 @@ describe('[Chat]', function () { }); it('should return a list of messages when execute successfully', (done) => { - request + void request .get(api('chat.search')) .set(credentials) .query({ @@ -1558,7 +1580,7 @@ describe('[Chat]', function () { .end(done); }); it('should return a list of messages(length=1) when is provided "count" query parameter execute successfully', (done) => { - request + void request .get(api('chat.search')) .set(credentials) .query({ @@ -1576,7 +1598,7 @@ describe('[Chat]', function () { .end(done); }); it('should return a list of messages(length=3) when is provided "count" and "offset" query parameters are executed successfully', (done) => { - request + void request .get(api('chat.search')) .set(credentials) .query({ @@ -1596,7 +1618,7 @@ describe('[Chat]', function () { }); it('should return a empty list of messages when is provided a huge offset value', (done) => { - request + void request .get(api('chat.search')) .set(credentials) .query({ @@ -1618,7 +1640,7 @@ describe('[Chat]', function () { describe('[/chat.react]', () => { it("should return statusCode: 200 and success when try unreact a message that's no reacted yet", (done) => { - request + void request .post(api('chat.react')) .set(credentials) .send({ @@ -1634,7 +1656,7 @@ describe('[Chat]', function () { .end(done); }); it('should react a message successfully', (done) => { - request + void request .post(api('chat.react')) .set(credentials) .send({ @@ -1650,7 +1672,7 @@ describe('[Chat]', function () { }); it('should return statusCode: 200 when the emoji is valid', (done) => { - request + void request .post(api('chat.react')) .set(credentials) .send({ @@ -1665,7 +1687,7 @@ describe('[Chat]', function () { .end(done); }); it("should return statusCode: 200 and success when try react a message that's already reacted", (done) => { - request + void request .post(api('chat.react')) .set(credentials) .send({ @@ -1681,7 +1703,7 @@ describe('[Chat]', function () { .end(done); }); it('should return statusCode: 200 when unreact a message with flag, shouldReact: false', (done) => { - request + void request .post(api('chat.react')) .set(credentials) .send({ @@ -1697,7 +1719,7 @@ describe('[Chat]', function () { .end(done); }); it('should return statusCode: 200 when react a message with flag, shouldReact: true', (done) => { - request + void request .post(api('chat.react')) .set(credentials) .send({ @@ -1713,7 +1735,7 @@ describe('[Chat]', function () { .end(done); }); it('should return statusCode: 200 when the emoji is valid and has no colons', (done) => { - request + void request .post(api('chat.react')) .set(credentials) .send({ @@ -1728,7 +1750,7 @@ describe('[Chat]', function () { .end(done); }); it('should return statusCode: 200 for reaction property when the emoji is valid', (done) => { - request + void request .post(api('chat.react')) .set(credentials) .send({ @@ -1752,7 +1774,7 @@ describe('[Chat]', function () { this.skip(); } - request + void request .get(api(`chat.getMessageReadReceipts`)) .set(credentials) .query({ @@ -1775,7 +1797,7 @@ describe('[Chat]', function () { if (isEnterprise) { this.skip(); } - request + void request .get(api(`chat.getMessageReadReceipts`)) .set(credentials) .query({ @@ -1796,7 +1818,7 @@ describe('[Chat]', function () { this.skip(); } - request + void request .get(api('chat.getMessageReadReceipts')) .set(credentials) .expect('Content-Type', 'application/json') @@ -1814,7 +1836,7 @@ describe('[Chat]', function () { describe('[/chat.reportMessage]', () => { describe('when execute successfully', () => { it('should return the statusCode 200', (done) => { - request + void request .post(api('chat.reportMessage')) .set(credentials) .send({ @@ -1832,7 +1854,7 @@ describe('[Chat]', function () { describe('when an error occurs', () => { it('should return statusCode 400 and an error', (done) => { - request + void request .post(api('chat.reportMessage')) .set(credentials) .send({ @@ -1850,7 +1872,7 @@ describe('[Chat]', function () { }); describe('[/chat.getDeletedMessages]', () => { - let roomId; + let roomId: IRoom['_id']; before(async () => { roomId = ( @@ -1867,7 +1889,7 @@ describe('[Chat]', function () { describe('when execute successfully', () => { it('should return a list of deleted messages', (done) => { - request + void request .get(api('chat.getDeletedMessages')) .set(credentials) .query({ @@ -1884,7 +1906,7 @@ describe('[Chat]', function () { .end(done); }); it('should return a list of deleted messages when the user sets count query parameter', (done) => { - request + void request .get(api('chat.getDeletedMessages')) .set(credentials) .query({ @@ -1902,7 +1924,7 @@ describe('[Chat]', function () { .end(done); }); it('should return a list of deleted messages when the user sets count and offset query parameters', (done) => { - request + void request .get(api('chat.getDeletedMessages')) .set(credentials) .query({ @@ -1924,7 +1946,7 @@ describe('[Chat]', function () { describe('when an error occurs', () => { it('should return statusCode 400 and an error when "roomId" is not provided', (done) => { - request + void request .get(api('chat.getDeletedMessages')) .set(credentials) .query({ @@ -1941,7 +1963,7 @@ describe('[Chat]', function () { .end(done); }); it('should return statusCode 400 and an error when "since" is not provided', (done) => { - request + void request .get(api('chat.getDeletedMessages')) .set(credentials) .query({ @@ -1958,7 +1980,7 @@ describe('[Chat]', function () { .end(done); }); it('should return statusCode 400 and an error when "since" is provided but it is invalid ISODate', (done) => { - request + void request .get(api('chat.getDeletedMessages')) .set(credentials) .query({ @@ -1984,8 +2006,8 @@ describe('[Chat]', function () { ); it('should return an error when pinMessage is not allowed in this server', (done) => { - updateSetting('Message_AllowPinning', false).then(() => { - request + void updateSetting('Message_AllowPinning', false).then(() => { + void request .post(api('chat.pinMessage')) .set(credentials) .send({ @@ -2002,9 +2024,9 @@ describe('[Chat]', function () { }); it('should return an error when pinMessage is allowed in server but user dont have permission', (done) => { - updateSetting('Message_AllowPinning', true).then(() => { - updatePermission('pin-message', []).then(() => { - request + void updateSetting('Message_AllowPinning', true).then(() => { + void updatePermission('pin-message', []).then(() => { + void request .post(api('chat.pinMessage')) .set(credentials) .send({ @@ -2022,8 +2044,8 @@ describe('[Chat]', function () { }); it('should pin Message successfully', (done) => { - updatePermission('pin-message', ['admin']).then(() => { - request + void updatePermission('pin-message', ['admin']).then(() => { + void request .post(api('chat.pinMessage')) .set(credentials) .send({ @@ -2046,8 +2068,8 @@ describe('[Chat]', function () { ); it('should return an error when pinMessage is not allowed in this server', (done) => { - updateSetting('Message_AllowPinning', false).then(() => { - request + void updateSetting('Message_AllowPinning', false).then(() => { + void request .post(api('chat.unPinMessage')) .set(credentials) .send({ @@ -2064,9 +2086,9 @@ describe('[Chat]', function () { }); it('should return an error when pinMessage is allowed in server but users dont have permission', (done) => { - updateSetting('Message_AllowPinning', true).then(() => { - updatePermission('pin-message', []).then(() => { - request + void updateSetting('Message_AllowPinning', true).then(() => { + void updatePermission('pin-message', []).then(() => { + void request .post(api('chat.unPinMessage')) .set(credentials) .send({ @@ -2084,8 +2106,8 @@ describe('[Chat]', function () { }); it('should unpin Message successfully', (done) => { - updatePermission('pin-message', ['admin']).then(() => { - request + void updatePermission('pin-message', ['admin']).then(() => { + void request .post(api('chat.unPinMessage')) .set(credentials) .send({ @@ -2106,8 +2128,8 @@ describe('[Chat]', function () { after(() => updateSetting('Message_AllowStarring', true)); it('should return an error when starMessage is not allowed in this server', (done) => { - updateSetting('Message_AllowStarring', false).then(() => { - request + void updateSetting('Message_AllowStarring', false).then(() => { + void request .post(api('chat.unStarMessage')) .set(credentials) .send({ @@ -2124,8 +2146,8 @@ describe('[Chat]', function () { }); it('should unstar Message successfully', (done) => { - updateSetting('Message_AllowStarring', true).then(() => { - request + void updateSetting('Message_AllowStarring', true).then(() => { + void request .post(api('chat.unStarMessage')) .set(credentials) .send({ @@ -2146,8 +2168,8 @@ describe('[Chat]', function () { after(() => updateSetting('Message_AllowStarring', true)); it('should return an error when starMessage is not allowed in this server', (done) => { - updateSetting('Message_AllowStarring', false).then(() => { - request + void updateSetting('Message_AllowStarring', false).then(() => { + void request .post(api('chat.starMessage')) .set(credentials) .send({ @@ -2164,8 +2186,8 @@ describe('[Chat]', function () { }); it('should star Message successfully', (done) => { - updateSetting('Message_AllowStarring', true).then(() => { - request + void updateSetting('Message_AllowStarring', true).then(() => { + void request .post(api('chat.starMessage')) .set(credentials) .send({ @@ -2186,7 +2208,7 @@ describe('[Chat]', function () { after(() => deleteRoom({ type: 'd', roomId: 'rocket.catrocketchat.internal.admin.test' })); it('should fail if invalid roomId', (done) => { - request + void request .get(api('chat.ignoreUser')) .set(credentials) .query({ @@ -2204,7 +2226,7 @@ describe('[Chat]', function () { }); }); it('should fail if invalid userId', (done) => { - request + void request .get(api('chat.ignoreUser')) .set(credentials) .query({ @@ -2222,7 +2244,7 @@ describe('[Chat]', function () { }); }); it('should successfully ignore user', (done) => { - request + void request .get(api('chat.ignoreUser')) .set(credentials) .query({ @@ -2239,7 +2261,7 @@ describe('[Chat]', function () { }); }); it('should successfully unignore user', (done) => { - request + void request .get(api('chat.ignoreUser')) .set(credentials) .query({ @@ -2259,7 +2281,7 @@ describe('[Chat]', function () { }); describe('[/chat.getPinnedMessages]', () => { - let roomId; + let roomId: IRoom['_id']; before(async () => { roomId = ( @@ -2278,7 +2300,7 @@ describe('[Chat]', function () { describe('when execute successfully', () => { it('should return a list of pinned messages', (done) => { - request + void request .get(api('chat.getPinnedMessages')) .set(credentials) .query({ @@ -2294,7 +2316,7 @@ describe('[Chat]', function () { .end(done); }); it('should return a list of pinned messages when the user sets count query parameter', (done) => { - request + void request .get(api('chat.getPinnedMessages')) .set(credentials) .query({ @@ -2311,7 +2333,7 @@ describe('[Chat]', function () { .end(done); }); it('should return a list of pinned messages when the user sets count and offset query parameters', (done) => { - request + void request .get(api('chat.getPinnedMessages')) .set(credentials) .query({ @@ -2332,7 +2354,7 @@ describe('[Chat]', function () { describe('when an error occurs', () => { it('should return statusCode 400 and an error when "roomId" is not provided', (done) => { - request + void request .get(api('chat.getPinnedMessages')) .set(credentials) .query({ @@ -2351,7 +2373,7 @@ describe('[Chat]', function () { }); describe('[/chat.getMentionedMessages]', () => { - let testChannel; + let testChannel: IRoom; before(async () => { testChannel = ( @@ -2365,7 +2387,7 @@ describe('[Chat]', function () { after(() => deleteRoom({ type: 'c', roomId: testChannel._id })); it('should return an error when the required "roomId" parameter is not sent', (done) => { - request + void request .get(api('chat.getMentionedMessages')) .set(credentials) .expect('Content-Type', 'application/json') @@ -2378,8 +2400,9 @@ describe('[Chat]', function () { }); it('should return an error when the roomId is invalid', (done) => { - request - .get(api('chat.getMentionedMessages?roomId=invalid-room')) + void request + .get(api('chat.getMentionedMessages')) + .query({ roomId: 'invalid-room' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -2391,8 +2414,9 @@ describe('[Chat]', function () { }); it('should return the mentioned messages', (done) => { - request - .get(api(`chat.getMentionedMessages?roomId=${testChannel._id}`)) + void request + .get(api('chat.getMentionedMessages')) + .query({ roomId: testChannel._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -2408,7 +2432,7 @@ describe('[Chat]', function () { }); describe('[/chat.getStarredMessages]', () => { - let testChannel; + let testChannel: IRoom; before(async () => { testChannel = ( @@ -2422,7 +2446,7 @@ describe('[Chat]', function () { after(() => deleteRoom({ type: 'c', roomId: testChannel._id })); it('should return an error when the required "roomId" parameter is not sent', (done) => { - request + void request .get(api('chat.getStarredMessages')) .set(credentials) .expect('Content-Type', 'application/json') @@ -2435,8 +2459,9 @@ describe('[Chat]', function () { }); it('should return an error when the roomId is invalid', (done) => { - request - .get(api('chat.getStarredMessages?roomId=invalid-room')) + void request + .get(api('chat.getStarredMessages')) + .query({ roomId: 'invalid-room' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -2448,8 +2473,9 @@ describe('[Chat]', function () { }); it('should return the starred messages', (done) => { - request - .get(api(`chat.getStarredMessages?roomId=${testChannel._id}`)) + void request + .get(api('chat.getStarredMessages')) + .query({ roomId: testChannel._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -2466,8 +2492,8 @@ describe('[Chat]', function () { describe('[/chat.getDiscussions]', () => { const messageText = 'Message to create discussion'; - let testChannel; - let discussionRoom; + let testChannel: IRoom; + let discussionRoom: IRoom & { rid: IRoom['_id'] }; const messageWords = [ ...messageText.split(' '), ...messageText.toUpperCase().split(' '), @@ -2496,7 +2522,7 @@ describe('[Chat]', function () { after(() => deleteRoom({ type: 'c', roomId: testChannel._id })); it('should return an error when the required "roomId" parameter is not sent', (done) => { - request + void request .get(api('chat.getDiscussions')) .set(credentials) .expect('Content-Type', 'application/json') @@ -2509,8 +2535,9 @@ describe('[Chat]', function () { }); it('should return an error when the roomId is invalid', (done) => { - request - .get(api('chat.getDiscussions?roomId=invalid-room')) + void request + .get(api('chat.getDiscussions')) + .query({ roomId: 'invalid-room' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -2522,8 +2549,9 @@ describe('[Chat]', function () { }); it('should return the discussions of a room', (done) => { - request - .get(api(`chat.getDiscussions?roomId=${testChannel._id}`)) + void request + .get(api('chat.getDiscussions')) + .query({ roomId: testChannel._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -2537,7 +2565,7 @@ describe('[Chat]', function () { .end(done); }); it('should return the discussions of a room even requested with count and offset params', (done) => { - request + void request .get(api('chat.getDiscussions')) .set(credentials) .query({ @@ -2557,9 +2585,9 @@ describe('[Chat]', function () { .end(done); }); - function filterDiscussionsByText(text) { + function filterDiscussionsByText(text: string) { it(`should return the room's discussion list filtered by the text '${text}'`, (done) => { - request + void request .get(api('chat.getDiscussions')) .set(credentials) .query({ @@ -2581,7 +2609,7 @@ describe('[Chat]', function () { }); it(`should return the room's discussion list filtered by the text '${text}' even requested with count and offset params`, (done) => { - request + void request .get(api('chat.getDiscussions')) .set(credentials) .query({ @@ -2612,7 +2640,7 @@ describe('[Chat]', function () { }); describe('Threads', () => { - let testThreadChannel; + let testThreadChannel: IRoom; before((done) => getCredentials(done)); @@ -2632,9 +2660,9 @@ describe('Threads', () => { describe('[/chat.getThreadsList]', () => { const messageText = 'Message to create thread'; - let testChannel; - let threadMessage; - let user; + let testChannel: IRoom; + let threadMessage: IThreadMessage; + let user: TestUser; const messageWords = [ ...messageText.split(' '), ...messageText.toUpperCase().split(' '), @@ -2686,8 +2714,8 @@ describe('Threads', () => { ); it('should return an error for chat.getThreadsList when threads are not allowed in this server', (done) => { - updateSetting('Threads_enabled', false).then(() => { - request + void updateSetting('Threads_enabled', false).then(() => { + void request .get(api('chat.getThreadsList')) .set(credentials) .query({ @@ -2705,12 +2733,12 @@ describe('Threads', () => { }); it('should return an error when the user is not allowed access the room', (done) => { - createUser().then((createdUser) => { + void createUser().then((createdUser) => { user = createdUser; - login(createdUser.username, password).then((userCredentials) => { - updateSetting('Threads_enabled', true).then(() => { - updatePermission('view-c-room', []).then(() => { - request + void login(createdUser.username, password).then((userCredentials) => { + void updateSetting('Threads_enabled', true).then(() => { + void updatePermission('view-c-room', []).then(() => { + void request .get(api('chat.getThreadsList')) .set(userCredentials) .query({ @@ -2731,8 +2759,8 @@ describe('Threads', () => { }); it("should return the room's thread list", (done) => { - updatePermission('view-c-room', ['admin', 'user']).then(() => { - request + void updatePermission('view-c-room', ['admin', 'user']).then(() => { + void request .get(api('chat.getThreadsList')) .set(credentials) .query({ @@ -2754,8 +2782,8 @@ describe('Threads', () => { }); it("should return the room's thread list even requested with count and offset params", (done) => { - updatePermission('view-c-room', ['admin', 'user']).then(() => { - request + void updatePermission('view-c-room', ['admin', 'user']).then(() => { + void request .get(api('chat.getThreadsList')) .set(credentials) .query({ @@ -2778,9 +2806,9 @@ describe('Threads', () => { }); }); - function filterThreadsByText(text) { + function filterThreadsByText(text: string) { it(`should return the room's thread list filtered by the text '${text}'`, (done) => { - request + void request .get(api('chat.getThreadsList')) .set(credentials) .query({ @@ -2801,7 +2829,7 @@ describe('Threads', () => { .end(done); }); it(`should return the room's thread list filtered by the text '${text}' even requested with count and offset params`, (done) => { - request + void request .get(api('chat.getThreadsList')) .set(credentials) .query({ @@ -2830,8 +2858,8 @@ describe('Threads', () => { }); it('should return an empty thread list', (done) => { - updatePermission('view-c-room', ['admin', 'user']).then(() => { - request + void updatePermission('view-c-room', ['admin', 'user']).then(() => { + void request .get(api('chat.getThreadsList')) .set(credentials) .query({ @@ -2854,9 +2882,9 @@ describe('Threads', () => { }); describe('[/chat.syncThreadsList]', () => { - let testChannel; - let threadMessage; - let user; + let testChannel: IRoom; + let threadMessage: IThreadMessage; + let user: TestUser; before(async () => { testChannel = (await createRoom({ type: 'c', name: `.threads.sync.${Date.now()}` })).body.channel; @@ -2884,8 +2912,8 @@ describe('Threads', () => { ); it('should return an error for chat.getThreadsList when threads are not allowed in this server', (done) => { - updateSetting('Threads_enabled', false).then(() => { - request + void updateSetting('Threads_enabled', false).then(() => { + void request .get(api('chat.getThreadsList')) .set(credentials) .query({ @@ -2903,8 +2931,8 @@ describe('Threads', () => { }); it('should return an error when the required param "rid" is missing', (done) => { - updateSetting('Threads_enabled', true).then(() => { - request + void updateSetting('Threads_enabled', true).then(() => { + void request .get(api('chat.syncThreadsList')) .set(credentials) .query({}) @@ -2920,8 +2948,8 @@ describe('Threads', () => { }); it('should return an error when the required param "updatedSince" is missing', (done) => { - updateSetting('Threads_enabled', true).then(() => { - request + void updateSetting('Threads_enabled', true).then(() => { + void request .get(api('chat.syncThreadsList')) .set(credentials) .query({ @@ -2939,8 +2967,8 @@ describe('Threads', () => { }); it('should return an error when the param "updatedSince" is an invalid date', (done) => { - updateSetting('Threads_enabled', true).then(() => { - request + void updateSetting('Threads_enabled', true).then(() => { + void request .get(api('chat.syncThreadsList')) .set(credentials) .query({ @@ -2962,11 +2990,11 @@ describe('Threads', () => { }); it('should return an error when the user is not allowed access the room', (done) => { - createUser().then((createdUser) => { + void createUser().then((createdUser) => { user = createdUser; - login(createdUser.username, password).then((userCredentials) => { - updatePermission('view-c-room', []).then(() => { - request + void login(createdUser.username, password).then((userCredentials) => { + void updatePermission('view-c-room', []).then(() => { + void request .get(api('chat.syncThreadsList')) .set(userCredentials) .query({ @@ -2987,8 +3015,8 @@ describe('Threads', () => { }); it("should return the room's thread synced list", (done) => { - updatePermission('view-c-room', ['admin', 'user']).then(() => { - request + void updatePermission('view-c-room', ['admin', 'user']).then(() => { + void request .get(api('chat.syncThreadsList')) .set(credentials) .query({ @@ -3012,10 +3040,10 @@ describe('Threads', () => { }); describe('[/chat.getThreadMessages]', () => { - let testChannel; - let threadMessage; - let createdThreadMessage; - let user; + let testChannel: IRoom; + let threadMessage: IThreadMessage; + let createdThreadMessage: IThreadMessage; + let user: TestUser; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.test.threads.${Date.now()}` })).body.channel; @@ -3045,8 +3073,8 @@ describe('Threads', () => { ); it('should return an error for chat.getThreadMessages when threads are not allowed in this server', (done) => { - updateSetting('Threads_enabled', false).then(() => { - request + void updateSetting('Threads_enabled', false).then(() => { + void request .get(api('chat.getThreadMessages')) .set(credentials) .query({ @@ -3064,12 +3092,12 @@ describe('Threads', () => { }); it('should return an error when the user is not allowed access the room', (done) => { - createUser().then((createdUser) => { + void createUser().then((createdUser) => { user = createdUser; - login(createdUser.username, password).then((userCredentials) => { - updateSetting('Threads_enabled', true).then(() => { - updatePermission('view-c-room', []).then(() => { - request + void login(createdUser.username, password).then((userCredentials) => { + void updateSetting('Threads_enabled', true).then(() => { + void updatePermission('view-c-room', []).then(() => { + void request .get(api('chat.getThreadMessages')) .set(userCredentials) .query({ @@ -3090,8 +3118,8 @@ describe('Threads', () => { }); it("should return the thread's message list", (done) => { - updatePermission('view-c-room', ['admin', 'user']).then(() => { - request + void updatePermission('view-c-room', ['admin', 'user']).then(() => { + void request .get(api('chat.getThreadMessages')) .set(credentials) .query({ @@ -3114,10 +3142,10 @@ describe('Threads', () => { }); describe('[/chat.syncThreadMessages]', () => { - let testChannel; - let threadMessage; - let createdThreadMessage; - let user; + let testChannel: IRoom; + let threadMessage: IThreadMessage; + let createdThreadMessage: IThreadMessage; + let user: TestUser; before(async () => { testChannel = (await createRoom({ type: 'c', name: `message.threads.${Date.now()}` })).body.channel; @@ -3147,8 +3175,8 @@ describe('Threads', () => { ); it('should return an error for chat.syncThreadMessages when threads are not allowed in this server', (done) => { - updateSetting('Threads_enabled', false).then(() => { - request + void updateSetting('Threads_enabled', false).then(() => { + void request .get(api('chat.syncThreadMessages')) .set(credentials) .query({ @@ -3167,8 +3195,8 @@ describe('Threads', () => { }); it('should return an error when the required param "tmid" is missing', (done) => { - updateSetting('Threads_enabled', true).then(() => { - request + void updateSetting('Threads_enabled', true).then(() => { + void request .get(api('chat.syncThreadMessages')) .set(credentials) .query({}) @@ -3184,8 +3212,8 @@ describe('Threads', () => { }); it('should return an error when the required param "updatedSince" is missing', (done) => { - updateSetting('Threads_enabled', true).then(() => { - request + void updateSetting('Threads_enabled', true).then(() => { + void request .get(api('chat.syncThreadMessages')) .set(credentials) .query({ @@ -3203,8 +3231,8 @@ describe('Threads', () => { }); it('should return an error when the param "updatedSince" is an invalid date', (done) => { - updateSetting('Threads_enabled', true).then(() => { - request + void updateSetting('Threads_enabled', true).then(() => { + void request .get(api('chat.syncThreadMessages')) .set(credentials) .query({ @@ -3226,11 +3254,11 @@ describe('Threads', () => { }); it('should return an error when the user is not allowed access the room', (done) => { - createUser().then((createdUser) => { + void createUser().then((createdUser) => { user = createdUser; - login(createdUser.username, password).then((userCredentials) => { - updatePermission('view-c-room', []).then(() => { - request + void login(createdUser.username, password).then((userCredentials) => { + void updatePermission('view-c-room', []).then(() => { + void request .get(api('chat.syncThreadMessages')) .set(userCredentials) .query({ @@ -3251,8 +3279,8 @@ describe('Threads', () => { }); it("should return the thread's message list", (done) => { - updatePermission('view-c-room', ['admin', 'user']).then(() => { - request + void updatePermission('view-c-room', ['admin', 'user']).then(() => { + void request .get(api('chat.syncThreadMessages')) .set(credentials) .query({ @@ -3276,9 +3304,9 @@ describe('Threads', () => { }); describe('[/chat.followMessage]', () => { - let testChannel; - let threadMessage; - let user; + let testChannel: IRoom; + let threadMessage: IThreadMessage; + let user: TestUser; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.test.threads.follow${Date.now()}` })).body.channel; @@ -3306,8 +3334,8 @@ describe('Threads', () => { ); it('should return an error for chat.followMessage when threads are not allowed in this server', (done) => { - updateSetting('Threads_enabled', false).then(() => { - request + void updateSetting('Threads_enabled', false).then(() => { + void request .post(api('chat.followMessage')) .set(credentials) .send({ @@ -3325,8 +3353,8 @@ describe('Threads', () => { }); it('should return an error when the message does not exist', (done) => { - updateSetting('Threads_enabled', true).then(() => { - request + void updateSetting('Threads_enabled', true).then(() => { + void request .post(api('chat.followMessage')) .set(credentials) .send({ @@ -3344,11 +3372,11 @@ describe('Threads', () => { }); it('should return an error when the user is not allowed access the room', (done) => { - createUser().then((createdUser) => { + void createUser().then((createdUser) => { user = createdUser; - login(createdUser.username, password).then((userCredentials) => { - updatePermission('view-c-room', []).then(() => { - request + void login(createdUser.username, password).then((userCredentials) => { + void updatePermission('view-c-room', []).then(() => { + void request .post(api('chat.followMessage')) .set(userCredentials) .send({ @@ -3368,8 +3396,8 @@ describe('Threads', () => { }); it('should return success: true when it execute successfully', (done) => { - updatePermission('view-c-room', ['admin', 'user']).then(() => { - request + void updatePermission('view-c-room', ['admin', 'user']).then(() => { + void request .post(api('chat.followMessage')) .set(credentials) .send({ @@ -3386,9 +3414,9 @@ describe('Threads', () => { }); describe('[/chat.unfollowMessage]', () => { - let testChannel; - let threadMessage; - let user; + let testChannel: IRoom; + let threadMessage: IThreadMessage; + let user: TestUser; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.test.threads.unfollow.${Date.now()}` })).body.channel; @@ -3415,8 +3443,8 @@ describe('Threads', () => { ]), ); it('should return an error for chat.unfollowMessage when threads are not allowed in this server', (done) => { - updateSetting('Threads_enabled', false).then(() => { - request + void updateSetting('Threads_enabled', false).then(() => { + void request .post(api('chat.unfollowMessage')) .set(credentials) .send({ @@ -3434,8 +3462,8 @@ describe('Threads', () => { }); it('should return an error when the message does not exist', (done) => { - updateSetting('Threads_enabled', true).then(() => { - request + void updateSetting('Threads_enabled', true).then(() => { + void request .post(api('chat.unfollowMessage')) .set(credentials) .send({ @@ -3453,11 +3481,11 @@ describe('Threads', () => { }); it('should return an error when the user is not allowed access the room', (done) => { - createUser().then((createdUser) => { + void createUser().then((createdUser) => { user = createdUser; - login(createdUser.username, password).then((userCredentials) => { - updatePermission('view-c-room', []).then(() => { - request + void login(createdUser.username, password).then((userCredentials) => { + void updatePermission('view-c-room', []).then(() => { + void request .post(api('chat.unfollowMessage')) .set(userCredentials) .send({ @@ -3477,8 +3505,8 @@ describe('Threads', () => { }); it('should return success: true when it execute successfully', (done) => { - updatePermission('view-c-room', ['admin', 'user']).then(() => { - request + void updatePermission('view-c-room', ['admin', 'user']).then(() => { + void request .post(api('chat.unfollowMessage')) .set(credentials) .send({ diff --git a/apps/meteor/tests/end-to-end/api/06-outgoing-integrations.js b/apps/meteor/tests/end-to-end/api/06-outgoing-integrations.ts similarity index 82% rename from apps/meteor/tests/end-to-end/api/06-outgoing-integrations.js rename to apps/meteor/tests/end-to-end/api/06-outgoing-integrations.ts index 120b467ec1b8..5ed7f8604db1 100644 --- a/apps/meteor/tests/end-to-end/api/06-outgoing-integrations.js +++ b/apps/meteor/tests/end-to-end/api/06-outgoing-integrations.ts @@ -1,19 +1,19 @@ -import { expect } from 'chai'; +import type { Credentials } from '@rocket.chat/api-client'; +import type { IIntegration, IUser } from '@rocket.chat/core-typings'; +import { assert, expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { createIntegration, removeIntegration } from '../../data/integration.helper'; import { updatePermission } from '../../data/permissions.helper'; import { password } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; import { createUser, deleteUser, login } from '../../data/users.helper'; -describe('[Outgoing Integrations]', function () { - this.retries(0); - - let integration; - let integrationCreatedByAnUser; - let user; - let userCredentials; +describe('[Outgoing Integrations]', () => { + let integrationCreatedByAnUser: IIntegration; + let user: TestUser; + let userCredentials: Credentials; before((done) => getCredentials(done)); @@ -59,10 +59,12 @@ describe('[Outgoing Integrations]', function () { ]), ); + let integration: IIntegration; + describe('[/integrations.create]', () => { it('should return an error when the user DOES NOT have the permission "manage-outgoing-integrations" to add an outgoing integration', (done) => { - updatePermission('manage-outgoing-integrations', []).then(() => { - request + void updatePermission('manage-outgoing-integrations', []).then(() => { + void request .post(api('integrations.create')) .set(credentials) .send({ @@ -90,8 +92,8 @@ describe('[Outgoing Integrations]', function () { }); it('should return an error when the user DOES NOT have the permission "manage-own-outgoing-integrations" to add an outgoing integration', (done) => { - updatePermission('manage-own-outgoing-integrations', []).then(() => { - request + void updatePermission('manage-own-outgoing-integrations', []).then(() => { + void request .post(api('integrations.create')) .set(credentials) .send({ @@ -119,7 +121,7 @@ describe('[Outgoing Integrations]', function () { }); it('should return an error when the user sends an invalid type of integration', (done) => { - request + void request .post(api('integrations.create')) .set(credentials) .send({ @@ -146,9 +148,9 @@ describe('[Outgoing Integrations]', function () { }); it('should add the integration successfully when the user ONLY has the permission "manage-outgoing-integrations" to add an outgoing integration', (done) => { - let integrationId; - updatePermission('manage-outgoing-integrations', ['admin']).then(() => { - request + let integrationId: IIntegration['_id']; + void updatePermission('manage-outgoing-integrations', ['admin']).then(() => { + void request .post(api('integrations.create')) .set(credentials) .send({ @@ -177,9 +179,9 @@ describe('[Outgoing Integrations]', function () { }); it('should add the integration successfully when the user ONLY has the permission "manage-own-outgoing-integrations" to add an outgoing integration', (done) => { - updatePermission('manage-outgoing-integrations', []).then(() => { - updatePermission('manage-own-outgoing-integrations', ['admin']).then(() => { - request + void updatePermission('manage-outgoing-integrations', []).then(() => { + void updatePermission('manage-own-outgoing-integrations', ['admin']).then(() => { + void request .post(api('integrations.create')) .set(credentials) .send({ @@ -209,8 +211,8 @@ describe('[Outgoing Integrations]', function () { }); it('should create an outgoing integration successfully', (done) => { - let integrationId; - request + let integrationId: IIntegration['_id']; + void request .post(api('integrations.create')) .set(credentials) .send({ @@ -244,14 +246,17 @@ describe('[Outgoing Integrations]', function () { describe('[/integrations.list]', () => { it('should return the list of outgoing integrations', (done) => { - request + void request .get(api('integrations.list')) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - const integrationCreatedByAdmin = res.body.integrations.find((createdIntegration) => createdIntegration._id === integration._id); + const integrationCreatedByAdmin = (res.body.integrations as IIntegration[]).find( + (createdIntegration) => createdIntegration._id === integration._id, + ); + assert.isDefined(integrationCreatedByAdmin); expect(integrationCreatedByAdmin).to.be.an('object'); expect(integrationCreatedByAdmin._id).to.be.equal(integration._id); expect(res.body).to.have.property('offset'); @@ -262,16 +267,16 @@ describe('[Outgoing Integrations]', function () { }); it('should return the list create by the user only', (done) => { - updatePermission('manage-outgoing-integrations', []).then(() => { - updatePermission('manage-own-outgoing-integrations', ['user']).then(() => { - request + void updatePermission('manage-outgoing-integrations', []).then(() => { + void updatePermission('manage-own-outgoing-integrations', ['user']).then(() => { + void request .get(api('integrations.list')) .set(userCredentials) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - const integrationCreatedByAdmin = res.body.integrations.find( + const integrationCreatedByAdmin = (res.body.integrations as IIntegration[]).find( (createdIntegration) => createdIntegration._id === integration._id, ); expect(integrationCreatedByAdmin).to.be.equal(undefined); @@ -285,11 +290,11 @@ describe('[Outgoing Integrations]', function () { }); it('should return unauthorized error when the user does not have any integrations permissions', (done) => { - updatePermission('manage-incoming-integrations', []).then(() => { - updatePermission('manage-own-incoming-integrations', []).then(() => { - updatePermission('manage-outgoing-integrations', []).then(() => { - updatePermission('manage-outgoing-integrations', []).then(() => { - request + void updatePermission('manage-incoming-integrations', []).then(() => { + void updatePermission('manage-own-incoming-integrations', []).then(() => { + void updatePermission('manage-outgoing-integrations', []).then(() => { + void updatePermission('manage-outgoing-integrations', []).then(() => { + void request .get(api('integrations.list')) .set(credentials) .expect('Content-Type', 'application/json') @@ -308,9 +313,9 @@ describe('[Outgoing Integrations]', function () { describe('[/integrations.history]', () => { it('should return an error when the user DOES NOT the necessary permission', (done) => { - updatePermission('manage-outgoing-integrations', []).then(() => { - updatePermission('manage-own-outgoing-integrations', []).then(() => { - request + void updatePermission('manage-outgoing-integrations', []).then(() => { + void updatePermission('manage-own-outgoing-integrations', []).then(() => { + void request .get(api('integrations.history')) .set(credentials) .query({ @@ -328,8 +333,8 @@ describe('[Outgoing Integrations]', function () { }); it('should return the history of outgoing integrations', (done) => { - updatePermission('manage-outgoing-integrations', ['admin']).then(() => { - request + void updatePermission('manage-outgoing-integrations', ['admin']).then(() => { + void request .get(api('integrations.history')) .set(credentials) .query({ @@ -351,7 +356,7 @@ describe('[Outgoing Integrations]', function () { describe('[/integrations.get]', () => { it('should return an error when the required "integrationId" query parameters is not sent', (done) => { - request + void request .get(api('integrations.get')) .set(credentials) .expect('Content-Type', 'application/json') @@ -364,9 +369,10 @@ describe('[Outgoing Integrations]', function () { }); it('should return an error when the user DOES NOT have the permission "manage-outgoing-integrations" to get an outgoing integration', (done) => { - updatePermission('manage-outgoing-integrations', []).then(() => { - request - .get(api(`integrations.get?integrationId=${integration._id}`)) + void updatePermission('manage-outgoing-integrations', []).then(() => { + void request + .get(api('integrations.get')) + .query({ integrationId: integration._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -379,9 +385,10 @@ describe('[Outgoing Integrations]', function () { }); it('should return an error when the user DOES NOT have the permission "manage-outgoing-integrations" to get an outgoing integration created by another user', (done) => { - updatePermission('manage-outgoing-integrations', []).then(() => { - request - .get(api(`integrations.get?integrationId=${integrationCreatedByAnUser._id}`)) + void updatePermission('manage-outgoing-integrations', []).then(() => { + void request + .get(api('integrations.get')) + .query({ integrationId: integrationCreatedByAnUser._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -394,9 +401,10 @@ describe('[Outgoing Integrations]', function () { }); it('should return an error when the user sends an invalid integration', (done) => { - updatePermission('manage-outgoing-integrations', ['admin']).then(() => { - request - .get(api('integrations.get?integrationId=invalid')) + void updatePermission('manage-outgoing-integrations', ['admin']).then(() => { + void request + .get(api('integrations.get')) + .query({ integrationId: 'invalid' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -409,11 +417,12 @@ describe('[Outgoing Integrations]', function () { }); it('should return the integration successfully when the user is able to see only your own integrations', (done) => { - updatePermission('manage-outgoing-integrations', []) + void updatePermission('manage-outgoing-integrations', []) .then(() => updatePermission('manage-own-outgoing-integrations', ['user'])) .then(() => { - request - .get(api(`integrations.get?integrationId=${integrationCreatedByAnUser._id}`)) + void request + .get(api('integrations.get')) + .query({ integrationId: integrationCreatedByAnUser._id }) .set(userCredentials) .expect('Content-Type', 'application/json') .expect(200) @@ -427,9 +436,10 @@ describe('[Outgoing Integrations]', function () { }); it('should return the integration successfully', (done) => { - updatePermission('manage-outgoing-integrations', ['admin']).then(() => { - request - .get(api(`integrations.get?integrationId=${integration._id}`)) + void updatePermission('manage-outgoing-integrations', ['admin']).then(() => { + void request + .get(api('integrations.get')) + .query({ integrationId: integration._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -445,8 +455,8 @@ describe('[Outgoing Integrations]', function () { describe('[/integrations.remove]', () => { it('should return an error when the user DOES NOT have the permission "manage-outgoing-integrations" to remove an outgoing integration', (done) => { - updatePermission('manage-outgoing-integrations', []).then(() => { - request + void updatePermission('manage-outgoing-integrations', []).then(() => { + void request .post(api('integrations.remove')) .set(credentials) .send({ @@ -464,8 +474,8 @@ describe('[Outgoing Integrations]', function () { }); it('should return an error when the user DOES NOT have the permission "manage-own-outgoing-integrations" to remove an outgoing integration', (done) => { - updatePermission('manage-own-incoming-integrations', []).then(() => { - request + void updatePermission('manage-own-incoming-integrations', []).then(() => { + void request .post(api('integrations.remove')) .set(credentials) .send({ @@ -483,8 +493,8 @@ describe('[Outgoing Integrations]', function () { }); it('should return an error when the user sends an invalid type of integration', (done) => { - updatePermission('manage-own-outgoing-integrations', ['admin']).then(() => { - request + void updatePermission('manage-own-outgoing-integrations', ['admin']).then(() => { + void request .post(api('integrations.remove')) .set(credentials) .send({ @@ -502,8 +512,8 @@ describe('[Outgoing Integrations]', function () { }); it('should remove the integration successfully when the user at least one of the necessary permission to remove an outgoing integration', (done) => { - updatePermission('manage-outgoing-integrations', ['admin']).then(() => { - request + void updatePermission('manage-outgoing-integrations', ['admin']).then(() => { + void request .post(api('integrations.remove')) .set(credentials) .send({ @@ -520,8 +530,8 @@ describe('[Outgoing Integrations]', function () { }); it('the normal user should remove the integration successfully when the user have the "manage-own-outgoing-integrations" to remove an outgoing integration', (done) => { - updatePermission('manage-own-outgoing-integrations', ['user']).then(() => { - request + void updatePermission('manage-own-outgoing-integrations', ['user']).then(() => { + void request .post(api('integrations.remove')) .set(userCredentials) .send({ diff --git a/apps/meteor/tests/end-to-end/api/07-incoming-integrations.js b/apps/meteor/tests/end-to-end/api/07-incoming-integrations.ts similarity index 81% rename from apps/meteor/tests/end-to-end/api/07-incoming-integrations.js rename to apps/meteor/tests/end-to-end/api/07-incoming-integrations.ts index 7c325a9e3cd2..ff475945a9ac 100644 --- a/apps/meteor/tests/end-to-end/api/07-incoming-integrations.js +++ b/apps/meteor/tests/end-to-end/api/07-incoming-integrations.ts @@ -1,22 +1,23 @@ -import { expect } from 'chai'; +import type { Credentials } from '@rocket.chat/api-client'; +import type { IIntegration, IMessage, IRoom, IUser } from '@rocket.chat/core-typings'; +import { assert, expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { createIntegration, removeIntegration } from '../../data/integration.helper'; import { updatePermission } from '../../data/permissions.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { password } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; import { createUser, deleteUser, login } from '../../data/users.helper'; -describe('[Incoming Integrations]', function () { - this.retries(0); - - let integration; - let integrationCreatedByAnUser; - let user; - let userCredentials; - let channel; - let testChannelName; +describe('[Incoming Integrations]', () => { + let integration: IIntegration; + let integrationCreatedByAnUser: IIntegration; + let user: TestUser; + let userCredentials: Credentials; + let channel: IRoom; + let testChannelName: string; before((done) => getCredentials(done)); @@ -46,8 +47,8 @@ describe('[Incoming Integrations]', function () { describe('[/integrations.create]', () => { it('should return an error when the user DOES NOT have the permission "manage-incoming-integrations" to add an incoming integration', (done) => { - updatePermission('manage-incoming-integrations', []).then(() => { - request + void updatePermission('manage-incoming-integrations', []).then(() => { + void request .post(api('integrations.create')) .set(credentials) .send({ @@ -71,8 +72,8 @@ describe('[Incoming Integrations]', function () { }); it('should return an error when the user DOES NOT have the permission "manage-own-incoming-integrations" to add an incoming integration', (done) => { - updatePermission('manage-own-incoming-integrations', []).then(() => { - request + void updatePermission('manage-own-incoming-integrations', []).then(() => { + void request .post(api('integrations.create')) .set(credentials) .send({ @@ -96,7 +97,7 @@ describe('[Incoming Integrations]', function () { }); it('should return an error when the user sends an invalid type of integration', (done) => { - request + void request .post(api('integrations.create')) .set(credentials) .send({ @@ -119,9 +120,9 @@ describe('[Incoming Integrations]', function () { }); it('should add the integration successfully when the user ONLY has the permission "manage-incoming-integrations" to add an incoming integration', (done) => { - let integrationId; - updatePermission('manage-own-incoming-integrations', ['admin']).then(() => { - request + let integrationId: IIntegration['_id']; + void updatePermission('manage-own-incoming-integrations', ['admin']).then(() => { + void request .post(api('integrations.create')) .set(credentials) .send({ @@ -146,8 +147,7 @@ describe('[Incoming Integrations]', function () { }); it('should set overrideDestinationChannelEnabled setting to false when it is not provided', async () => { - let integrationId; - await request + const res = await request .post(api('integrations.create')) .set(credentials) .send({ @@ -160,20 +160,19 @@ describe('[Incoming Integrations]', function () { channel: '#general', }) .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('integration').and.to.be.an('object'); - expect(res.body.integration).to.have.property('overrideDestinationChannelEnabled', false); - integrationId = res.body.integration._id; - }); + .expect(200); + + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('integration').and.to.be.an('object'); + expect(res.body.integration).to.have.property('overrideDestinationChannelEnabled', false); + const integrationId = res.body.integration._id; await removeIntegration(integrationId, 'incoming'); }); it('should add the integration successfully when the user ONLY has the permission "manage-own-incoming-integrations" to add an incoming integration', (done) => { - updatePermission('manage-incoming-integrations', []).then(() => { - updatePermission('manage-own-incoming-integrations', ['admin']).then(() => { - request + void updatePermission('manage-incoming-integrations', []).then(() => { + void updatePermission('manage-own-incoming-integrations', ['admin']).then(() => { + void request .post(api('integrations.create')) .set(credentials) .send({ @@ -199,7 +198,7 @@ describe('[Incoming Integrations]', function () { }); it('should execute the incoming integration', (done) => { - request + void request .post(`/hooks/${integration._id}/${integration.token}`) .send({ text: 'Example message', @@ -209,7 +208,7 @@ describe('[Incoming Integrations]', function () { }); it("should return an error when sending 'channel' field telling its configuration is disabled", (done) => { - request + void request .post(`/hooks/${integration._id}/${integration.token}`) .send({ text: 'Example message', @@ -224,7 +223,7 @@ describe('[Incoming Integrations]', function () { }); it("should return an error when sending 'roomId' field telling its configuration is disabled", (done) => { - request + void request .post(`/hooks/${integration._id}/${integration.token}`) .send({ text: 'Example message', @@ -239,7 +238,7 @@ describe('[Incoming Integrations]', function () { }); it('should send a message for a channel that is specified in the webhooks configuration', (done) => { const successfulMesssage = `Message sent successfully at #${Date.now()}`; - request + void request .post(`/hooks/${integration._id}/${integration.token}`) .send({ text: successfulMesssage, @@ -257,7 +256,7 @@ describe('[Incoming Integrations]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('messages').and.to.be.an('array'); - expect(!!res.body.messages.find((m) => m.msg === successfulMesssage)).to.be.true; + expect(!!(res.body.messages as IMessage[]).find((m) => m.msg === successfulMesssage)).to.be.true; }) .end(done); }); @@ -303,14 +302,14 @@ describe('[Incoming Integrations]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('messages').and.to.be.an('array'); - expect(!!res.body.messages.find((m) => m.msg === successfulMesssage)).to.be.true; + expect(!!(res.body.messages as IMessage[]).find((m) => m.msg === successfulMesssage)).to.be.true; }); }); }); describe('[/integrations.history]', () => { it('should return an error when trying to get history of incoming integrations', (done) => { - request + void request .get(api('integrations.history')) .set(credentials) .query({ @@ -328,12 +327,12 @@ describe('[Incoming Integrations]', function () { describe('[/integrations.list]', () => { before((done) => { - createUser().then((createdUser) => { + void createUser().then((createdUser) => { user = createdUser; - login(user.username, password).then((credentials) => { + void login(user.username, password).then((credentials) => { userCredentials = credentials; - updatePermission('manage-incoming-integrations', ['user']).then(() => { - createIntegration( + void updatePermission('manage-incoming-integrations', ['user']).then(() => { + void createIntegration( { type: 'webhook-incoming', name: 'Incoming test', @@ -355,14 +354,17 @@ describe('[Incoming Integrations]', function () { }); it('should return the list of incoming integrations', (done) => { - request + void request .get(api('integrations.list')) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - const integrationCreatedByAdmin = res.body.integrations.find((createdIntegration) => createdIntegration._id === integration._id); + const integrationCreatedByAdmin = (res.body.integrations as IIntegration[]).find( + (createdIntegration) => createdIntegration._id === integration._id, + ); + assert.isDefined(integrationCreatedByAdmin); expect(integrationCreatedByAdmin).to.be.an('object'); expect(integrationCreatedByAdmin._id).to.be.equal(integration._id); expect(res.body).to.have.property('offset'); @@ -373,16 +375,16 @@ describe('[Incoming Integrations]', function () { }); it('should return the list of integrations created by the user only', (done) => { - updatePermission('manage-incoming-integrations', []).then(() => { - updatePermission('manage-own-incoming-integrations', ['user']).then(() => { - request + void updatePermission('manage-incoming-integrations', []).then(() => { + void updatePermission('manage-own-incoming-integrations', ['user']).then(() => { + void request .get(api('integrations.list')) .set(userCredentials) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { expect(res.body).to.have.property('success', true); - const integrationCreatedByAdmin = res.body.integrations.find( + const integrationCreatedByAdmin = (res.body.integrations as IIntegration[]).find( (createdIntegration) => createdIntegration._id === integration._id, ); expect(integrationCreatedByAdmin).to.be.equal(undefined); @@ -396,11 +398,11 @@ describe('[Incoming Integrations]', function () { }); it('should return unauthorized error when the user does not have any integrations permissions', (done) => { - updatePermission('manage-incoming-integrations', []).then(() => { - updatePermission('manage-own-incoming-integrations', []).then(() => { - updatePermission('manage-outgoing-integrations', []).then(() => { - updatePermission('manage-outgoing-integrations', []).then(() => { - request + void updatePermission('manage-incoming-integrations', []).then(() => { + void updatePermission('manage-own-incoming-integrations', []).then(() => { + void updatePermission('manage-outgoing-integrations', []).then(() => { + void updatePermission('manage-outgoing-integrations', []).then(() => { + void request .get(api('integrations.list')) .set(credentials) .expect('Content-Type', 'application/json') @@ -419,7 +421,7 @@ describe('[Incoming Integrations]', function () { describe('[/integrations.get]', () => { it('should return an error when the required "integrationId" query parameters is not sent', (done) => { - request + void request .get(api('integrations.get')) .set(credentials) .expect('Content-Type', 'application/json') @@ -432,9 +434,10 @@ describe('[Incoming Integrations]', function () { }); it('should return an error when the user DOES NOT have the permission "manage-incoming-integrations" to get an incoming integration', (done) => { - updatePermission('manage-incoming-integrations', []).then(() => { - request - .get(api(`integrations.get?integrationId=${integration._id}`)) + void updatePermission('manage-incoming-integrations', []).then(() => { + void request + .get(api('integrations.get')) + .query({ integrationId: integration._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -447,9 +450,10 @@ describe('[Incoming Integrations]', function () { }); it('should return an error when the user DOES NOT have the permission "manage-incoming-integrations" to get an incoming integration created by another user', (done) => { - updatePermission('manage-incoming-integrations', []).then(() => { - request - .get(api(`integrations.get?integrationId=${integrationCreatedByAnUser._id}`)) + void updatePermission('manage-incoming-integrations', []).then(() => { + void request + .get(api('integrations.get')) + .query({ integrationId: integrationCreatedByAnUser._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -462,9 +466,10 @@ describe('[Incoming Integrations]', function () { }); it('should return an error when the user sends an invalid integration', (done) => { - updatePermission('manage-incoming-integrations', ['admin']).then(() => { - request - .get(api('integrations.get?integrationId=invalid')) + void updatePermission('manage-incoming-integrations', ['admin']).then(() => { + void request + .get(api('integrations.get')) + .query({ integrationId: 'invalid' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -477,11 +482,12 @@ describe('[Incoming Integrations]', function () { }); it('should return the integration successfully when the user is able to see only your own integrations', (done) => { - updatePermission('manage-incoming-integrations', []) + void updatePermission('manage-incoming-integrations', []) .then(() => updatePermission('manage-own-incoming-integrations', ['user'])) .then(() => { - request - .get(api(`integrations.get?integrationId=${integrationCreatedByAnUser._id}`)) + void request + .get(api('integrations.get')) + .query({ integrationId: integrationCreatedByAnUser._id }) .set(userCredentials) .expect('Content-Type', 'application/json') .expect(200) @@ -495,9 +501,10 @@ describe('[Incoming Integrations]', function () { }); it('should return the integration successfully', (done) => { - updatePermission('manage-incoming-integrations', ['admin']).then(() => { - request - .get(api(`integrations.get?integrationId=${integration._id}`)) + void updatePermission('manage-incoming-integrations', ['admin']).then(() => { + void request + .get(api('integrations.get')) + .query({ integrationId: integration._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -513,7 +520,7 @@ describe('[Incoming Integrations]', function () { describe('[/integrations.update]', () => { it('should update an integration by id and return the new data', (done) => { - request + void request .put(api('integrations.update')) .set(credentials) .send({ @@ -540,8 +547,9 @@ describe('[Incoming Integrations]', function () { }); it('should have integration updated on subsequent gets', (done) => { - request - .get(api(`integrations.get?integrationId=${integration._id}`)) + void request + .get(api('integrations.get')) + .query({ integrationId: integration._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -558,8 +566,8 @@ describe('[Incoming Integrations]', function () { describe('[/integrations.remove]', () => { it('should return an error when the user DOES NOT have the permission "manage-incoming-integrations" to remove an incoming integration', (done) => { - updatePermission('manage-incoming-integrations', []).then(() => { - request + void updatePermission('manage-incoming-integrations', []).then(() => { + void request .post(api('integrations.remove')) .set(credentials) .send({ @@ -577,8 +585,8 @@ describe('[Incoming Integrations]', function () { }); it('should return an error when the user DOES NOT have the permission "manage-own-incoming-integrations" to remove an incoming integration', (done) => { - updatePermission('manage-own-incoming-integrations', []).then(() => { - request + void updatePermission('manage-own-incoming-integrations', []).then(() => { + void request .post(api('integrations.remove')) .set(credentials) .send({ @@ -596,8 +604,8 @@ describe('[Incoming Integrations]', function () { }); it('should return an error when the user sends an invalid type of integration', (done) => { - updatePermission('manage-own-incoming-integrations', ['admin']).then(() => { - request + void updatePermission('manage-own-incoming-integrations', ['admin']).then(() => { + void request .post(api('integrations.remove')) .set(credentials) .send({ @@ -615,8 +623,8 @@ describe('[Incoming Integrations]', function () { }); it('should remove the integration successfully when the user at least one of the necessary permission to remove an incoming integration', (done) => { - updatePermission('manage-incoming-integrations', ['admin']).then(() => { - request + void updatePermission('manage-incoming-integrations', ['admin']).then(() => { + void request .post(api('integrations.remove')) .set(credentials) .send({ @@ -633,8 +641,8 @@ describe('[Incoming Integrations]', function () { }); it('the normal user should remove the integration successfully when the user have the "manage-own-incoming-integrations" to remove an incoming integration', (done) => { - updatePermission('manage-own-incoming-integrations', ['user']).then(() => { - request + void updatePermission('manage-own-incoming-integrations', ['user']).then(() => { + void request .post(api('integrations.remove')) .set(userCredentials) .send({ diff --git a/apps/meteor/tests/end-to-end/api/08-settings.js b/apps/meteor/tests/end-to-end/api/08-settings.ts similarity index 89% rename from apps/meteor/tests/end-to-end/api/08-settings.js rename to apps/meteor/tests/end-to-end/api/08-settings.ts index 4ea6a6ae778e..3a03ecbe9226 100644 --- a/apps/meteor/tests/end-to-end/api/08-settings.js +++ b/apps/meteor/tests/end-to-end/api/08-settings.ts @@ -1,17 +1,16 @@ +import type { LoginServiceConfiguration } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { before, describe, it, after } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { updateSetting } from '../../data/permissions.helper'; -describe('[Settings]', function () { - this.retries(0); - +describe('[Settings]', () => { before((done) => getCredentials(done)); describe('[/settings.public]', () => { it('should return public settings', (done) => { - request + void request .get(api('settings.public')) .expect('Content-Type', 'application/json') .expect(200) @@ -23,7 +22,7 @@ describe('[Settings]', function () { .end(done); }); it('should return public settings even requested with count and offset params', (done) => { - request + void request .get(api('settings.public')) .query({ count: 5, @@ -42,7 +41,7 @@ describe('[Settings]', function () { describe('[/settings]', () => { it('should return private settings', (done) => { - request + void request .get(api('settings')) .set(credentials) .expect('Content-Type', 'application/json') @@ -58,7 +57,7 @@ describe('[Settings]', function () { describe('[/settings/:_id]', () => { it('should return one setting', (done) => { - request + void request .get(api('settings/Site_Url')) .set(credentials) .expect('Content-Type', 'application/json') @@ -74,7 +73,7 @@ describe('[Settings]', function () { describe('[/service.configurations]', () => { it('should return service configurations', (done) => { - request + void request .get(api('service.configurations')) .set(credentials) .expect('Content-Type', 'application/json') @@ -94,7 +93,7 @@ describe('[Settings]', function () { it('should include the OAuth service in the response', (done) => { // wait 3 seconds before getting the service list so the server has had time to update it setTimeout(() => { - request + void request .get(api('service.configurations')) .set(credentials) .expect('Content-Type', 'application/json') @@ -103,7 +102,7 @@ describe('[Settings]', function () { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('configurations'); - expect(res.body.configurations.find(({ service }) => service === 'google')).to.exist; + expect((res.body.configurations as LoginServiceConfiguration[]).find(({ service }) => service === 'google')).to.exist; }) .end(done); }, 3000); @@ -118,7 +117,7 @@ describe('[Settings]', function () { it('should not include the OAuth service in the response', (done) => { // wait 3 seconds before getting the service list so the server has had time to update it setTimeout(() => { - request + void request .get(api('service.configurations')) .set(credentials) .expect('Content-Type', 'application/json') @@ -127,7 +126,7 @@ describe('[Settings]', function () { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('configurations'); - expect(res.body.configurations.find(({ service }) => service === 'google')).to.not.exist; + expect((res.body.configurations as LoginServiceConfiguration[]).find(({ service }) => service === 'google')).to.not.exist; }) .end(done); }, 3000); @@ -137,7 +136,7 @@ describe('[Settings]', function () { describe('/settings.oauth', () => { it('should have return list of available oauth services when user is not logged', (done) => { - request + void request .get(api('settings.oauth')) .expect('Content-Type', 'application/json') .expect(200) @@ -149,7 +148,7 @@ describe('[Settings]', function () { }); it('should have return list of available oauth services when user is logged', (done) => { - request + void request .get(api('settings.oauth')) .set(credentials) .expect('Content-Type', 'application/json') diff --git a/apps/meteor/tests/end-to-end/api/09-rooms.js b/apps/meteor/tests/end-to-end/api/09-rooms.ts similarity index 91% rename from apps/meteor/tests/end-to-end/api/09-rooms.js rename to apps/meteor/tests/end-to-end/api/09-rooms.ts index de4668e86f48..03d33ecd3b8d 100644 --- a/apps/meteor/tests/end-to-end/api/09-rooms.js +++ b/apps/meteor/tests/end-to-end/api/09-rooms.ts @@ -1,27 +1,33 @@ import fs from 'fs'; import path from 'path'; -import { expect } from 'chai'; +import type { Credentials } from '@rocket.chat/api-client'; +import type { IMessage, IRoom, ITeam, IUpload, IUser, ImageAttachmentProps, SettingValue } from '@rocket.chat/core-typings'; +import { assert, expect } from 'chai'; import { after, afterEach, before, beforeEach, describe, it } from 'mocha'; import { sleep } from '../../../lib/utils/sleep'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { sendSimpleMessage, deleteMessage } from '../../data/chat.helper'; -import { drawioURL, imgURL, lstURL, svgLogoFileName, svgLogoURL } from '../../data/interactions'; +import { imgURL } from '../../data/interactions'; import { getSettingValueById, updateEEPermission, updatePermission, updateSetting } from '../../data/permissions.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { deleteTeam } from '../../data/teams.helper'; import { password } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; import { createUser, deleteUser, login } from '../../data/users.helper'; import { IS_EE } from '../../e2e/config/constants'; -describe('[Rooms]', function () { - this.retries(0); +const lstURL = './tests/e2e/fixtures/files/lst-test.lst'; +const drawioURL = './tests/e2e/fixtures/files/diagram.drawio'; +const svgLogoURL = './public/images/logo/logo.svg'; +const svgLogoFileName = 'logo.svg'; +describe('[Rooms]', () => { before((done) => getCredentials(done)); it('/rooms.get', (done) => { - request + void request .get(api('rooms.get')) .set(credentials) .expect(200) @@ -34,7 +40,7 @@ describe('[Rooms]', function () { }); it('/rooms.get?updatedSince', (done) => { - request + void request .get(api('rooms.get')) .set(credentials) .query({ @@ -50,7 +56,7 @@ describe('[Rooms]', function () { }); describe('/rooms.saveNotification:', () => { - let testChannel; + let testChannel: IRoom; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.test.${Date.now()}-${Math.random()}` })).body.channel; @@ -59,7 +65,7 @@ describe('[Rooms]', function () { after(() => deleteRoom({ type: 'c', roomId: testChannel._id })); it('/rooms.saveNotification:', (done) => { - request + void request .post(api('rooms.saveNotification')) .set(credentials) .send({ @@ -82,12 +88,12 @@ describe('[Rooms]', function () { }); describe('/rooms.upload', () => { - let testChannel; - let user; - let userCredentials; + let testChannel: IRoom; + let user: TestUser; + let userCredentials: Credentials; const testChannelName = `channel.test.upload.${Date.now()}-${Math.random()}`; - let blockedMediaTypes; - let testPrivateChannel; + let blockedMediaTypes: SettingValue; + let testPrivateChannel: IRoom; before(async () => { user = await createUser({ joinDefaultChannels: false }); @@ -95,7 +101,7 @@ describe('[Rooms]', function () { testChannel = (await createRoom({ type: 'c', name: testChannelName })).body.channel; testPrivateChannel = (await createRoom({ type: 'p', name: `channel.test.private.${Date.now()}-${Math.random()}` })).body.group; blockedMediaTypes = await getSettingValueById('FileUpload_MediaTypeBlackList'); - const newBlockedMediaTypes = blockedMediaTypes + const newBlockedMediaTypes = (blockedMediaTypes as string) .split(',') .filter((type) => type !== 'image/svg+xml') .join(','); @@ -115,7 +121,7 @@ describe('[Rooms]', function () { ); it("don't upload a file to room with file field other than file", (done) => { - request + void request .post(api(`rooms.upload/${testChannel._id}`)) .set(credentials) .attach('test', imgURL) @@ -129,7 +135,7 @@ describe('[Rooms]', function () { .end(done); }); it("don't upload a file to room with empty file", (done) => { - request + void request .post(api(`rooms.upload/${testChannel._id}`)) .set(credentials) .attach('file', '') @@ -142,7 +148,7 @@ describe('[Rooms]', function () { .end(done); }); it("don't upload a file to room with more than 1 file", (done) => { - request + void request .post(api(`rooms.upload/${testChannel._id}`)) .set(credentials) .attach('file', imgURL) @@ -156,8 +162,8 @@ describe('[Rooms]', function () { .end(done); }); - let fileNewUrl; - let fileOldUrl; + let fileNewUrl: string; + let fileOldUrl: string; it('should upload a PNG file to room', async () => { await request .post(api(`rooms.upload/${testChannel._id}`)) @@ -166,7 +172,7 @@ describe('[Rooms]', function () { .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { - const { message } = res.body; + const message = res.body.message as IMessage; expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('message'); expect(res.body.message).to.have.property('attachments'); @@ -178,6 +184,7 @@ describe('[Rooms]', function () { expect(res.body.message.files[0]).to.have.property('type', 'image/png'); expect(res.body.message.files[0]).to.have.property('name', '1024x1024.png'); + assert.isDefined(message.file); fileNewUrl = `/file-upload/${message.file._id}/${message.file.name}`; fileOldUrl = `/ufs/GridFS:Uploads/${message.file._id}/${message.file.name}`; }); @@ -319,52 +326,52 @@ describe('[Rooms]', function () { it('should generate thumbnail for SVG files correctly', async () => { const expectedFileName = `thumb-${svgLogoFileName}`; - let thumbUrl; - await request + + const res = await request .post(api(`rooms.upload/${testChannel._id}`)) .set(credentials) .attach('file', svgLogoURL) .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - const { message } = res.body; - const { files, attachments } = message; + .expect(200); - expect(files).to.be.an('array'); - const hasThumbFile = files.some((file) => file.type === 'image/png' && file.name === expectedFileName); - expect(hasThumbFile).to.be.true; + const message = res.body.message as IMessage; + const { files, attachments } = message; - expect(attachments).to.be.an('array'); - const thumbAttachment = attachments.find((attachment) => attachment.title === svgLogoFileName); - expect(thumbAttachment).to.be.an('object'); - thumbUrl = thumbAttachment.image_url; - }); + expect(files).to.be.an('array'); + const hasThumbFile = files?.some((file) => file.type === 'image/png' && file.name === expectedFileName); + expect(hasThumbFile).to.be.true; + + expect(attachments).to.be.an('array'); + const thumbAttachment = attachments?.find((attachment) => attachment.title === svgLogoFileName); + assert.isDefined(thumbAttachment); + expect(thumbAttachment).to.be.an('object'); + const thumbUrl = (thumbAttachment as ImageAttachmentProps).image_url; await request.get(thumbUrl).set(credentials).expect('Content-Type', 'image/png'); }); it('should generate thumbnail for JPEG files correctly', async () => { const expectedFileName = `thumb-sample-jpeg.jpg`; - let thumbUrl; - await request + const res = await request .post(api(`rooms.upload/${testChannel._id}`)) .set(credentials) .attach('file', fs.createReadStream(path.join(__dirname, '../../mocks/files/sample-jpeg.jpg'))) .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - const { message } = res.body; - const { files, attachments } = message; + .expect(200); - expect(files).to.be.an('array'); - const hasThumbFile = files.some((file) => file.type === 'image/jpeg' && file.name === expectedFileName); - expect(hasThumbFile).to.be.true; + const message = res.body.message as IMessage; + const { files, attachments } = message; - expect(attachments).to.be.an('array'); - const thumbAttachment = attachments.find((attachment) => attachment.title === `sample-jpeg.jpg`); - expect(thumbAttachment).to.be.an('object'); - thumbUrl = thumbAttachment.image_url; - }); + expect(files).to.be.an('array'); + assert.isDefined(files); + const hasThumbFile = files.some((file) => file.type === 'image/jpeg' && file.name === expectedFileName); + expect(hasThumbFile).to.be.true; + + expect(attachments).to.be.an('array'); + assert.isDefined(attachments); + const thumbAttachment = attachments.find((attachment) => attachment.title === `sample-jpeg.jpg`); + expect(thumbAttachment).to.be.an('object'); + const thumbUrl = (thumbAttachment as ImageAttachmentProps).image_url; await request.get(thumbUrl).set(credentials).expect('Content-Type', 'image/jpeg'); }); @@ -395,18 +402,18 @@ describe('[Rooms]', function () { }); describe('/rooms.media', () => { - let testChannel; - let user; - let userCredentials; + let testChannel: IRoom; + let user: TestUser; + let userCredentials: Credentials; const testChannelName = `channel.test.upload.${Date.now()}-${Math.random()}`; - let blockedMediaTypes; + let blockedMediaTypes: SettingValue; before(async () => { user = await createUser({ joinDefaultChannels: false }); userCredentials = await login(user.username, password); testChannel = (await createRoom({ type: 'c', name: testChannelName })).body.channel; blockedMediaTypes = await getSettingValueById('FileUpload_MediaTypeBlackList'); - const newBlockedMediaTypes = blockedMediaTypes + const newBlockedMediaTypes = (blockedMediaTypes as string) .split(',') .filter((type) => type !== 'image/svg+xml') .join(','); @@ -424,7 +431,7 @@ describe('[Rooms]', function () { ); it("don't upload a file to room with file field other than file", (done) => { - request + void request .post(api(`rooms.media/${testChannel._id}`)) .set(credentials) .attach('test', imgURL) @@ -438,7 +445,7 @@ describe('[Rooms]', function () { .end(done); }); it("don't upload a file to room with empty file", (done) => { - request + void request .post(api(`rooms.media/${testChannel._id}`)) .set(credentials) .attach('file', '') @@ -451,7 +458,7 @@ describe('[Rooms]', function () { .end(done); }); it("don't upload a file to room with more than 1 file", (done) => { - request + void request .post(api(`rooms.media/${testChannel._id}`)) .set(credentials) .attach('file', imgURL) @@ -465,9 +472,9 @@ describe('[Rooms]', function () { .end(done); }); - let fileNewUrl; - let fileOldUrl; - let fileId; + let fileNewUrl: string; + let fileOldUrl: string; + let fileId: string; it('should upload a PNG file to room', async () => { await request .post(api(`rooms.media/${testChannel._id}`)) @@ -592,82 +599,71 @@ describe('[Rooms]', function () { it('should generate thumbnail for SVG files correctly', async () => { const expectedFileName = `thumb-${svgLogoFileName}`; - let thumbUrl; - let fileId; - await request + let res = await request .post(api(`rooms.media/${testChannel._id}`)) .set(credentials) .attach('file', svgLogoURL) .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('file'); - expect(res.body.file).to.have.property('_id'); - expect(res.body.file).to.have.property('url'); + .expect(200); + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('file'); + expect(res.body.file).to.have.property('_id'); + expect(res.body.file).to.have.property('url'); - fileId = res.body.file._id; - }); + const fileId = res.body.file._id; - await request + res = await request .post(api(`rooms.mediaConfirm/${testChannel._id}/${fileId}`)) .set(credentials) .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - const { message } = res.body; - const { files, attachments } = message; + .expect(200); + const message = res.body.message as IMessage; + const { files, attachments } = message; - expect(files).to.be.an('array'); - const hasThumbFile = files.some((file) => file.type === 'image/png' && file.name === expectedFileName); - expect(hasThumbFile).to.be.true; + expect(files).to.be.an('array'); + const hasThumbFile = files?.some((file) => file.type === 'image/png' && file.name === expectedFileName); + expect(hasThumbFile).to.be.true; - expect(attachments).to.be.an('array'); - const thumbAttachment = attachments.find((attachment) => attachment.title === svgLogoFileName); - expect(thumbAttachment).to.be.an('object'); - thumbUrl = thumbAttachment.image_url; - }); + expect(attachments).to.be.an('array'); + const thumbAttachment = attachments?.find((attachment) => attachment.title === svgLogoFileName); + assert.isDefined(thumbAttachment); + expect(thumbAttachment).to.be.an('object'); + const thumbUrl = (thumbAttachment as ImageAttachmentProps).image_url; await request.get(thumbUrl).set(credentials).expect('Content-Type', 'image/png'); }); it('should generate thumbnail for JPEG files correctly', async () => { const expectedFileName = `thumb-sample-jpeg.jpg`; - let thumbUrl; - let fileId; - await request + let res = await request .post(api(`rooms.media/${testChannel._id}`)) .set(credentials) .attach('file', fs.createReadStream(path.join(__dirname, '../../mocks/files/sample-jpeg.jpg'))) .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - expect(res.body).to.have.property('success', true); - expect(res.body).to.have.property('file'); - expect(res.body.file).to.have.property('_id'); - expect(res.body.file).to.have.property('url'); + .expect(200); + expect(res.body).to.have.property('success', true); + expect(res.body).to.have.property('file'); + expect(res.body.file).to.have.property('_id'); + expect(res.body.file).to.have.property('url'); - fileId = res.body.file._id; - }); + const fileId = res.body.file._id; - await request + res = await request .post(api(`rooms.mediaConfirm/${testChannel._id}/${fileId}`)) .set(credentials) .expect('Content-Type', 'application/json') - .expect(200) - .expect((res) => { - const { message } = res.body; - const { files, attachments } = message; + .expect(200); + const message = res.body.message as IMessage; + const { files, attachments } = message; - expect(files).to.be.an('array'); - const hasThumbFile = files.some((file) => file.type === 'image/jpeg' && file.name === expectedFileName); - expect(hasThumbFile).to.be.true; + expect(files).to.be.an('array'); + const hasThumbFile = files?.some((file) => file.type === 'image/jpeg' && file.name === expectedFileName); + expect(hasThumbFile).to.be.true; - expect(attachments).to.be.an('array'); - const thumbAttachment = attachments.find((attachment) => attachment.title === `sample-jpeg.jpg`); - expect(thumbAttachment).to.be.an('object'); - thumbUrl = thumbAttachment.image_url; - }); + expect(attachments).to.be.an('array'); + const thumbAttachment = attachments?.find((attachment) => attachment.title === `sample-jpeg.jpg`); + expect(thumbAttachment).to.be.an('object'); + const thumbUrl = (thumbAttachment as ImageAttachmentProps).image_url; await request.get(thumbUrl).set(credentials).expect('Content-Type', 'image/jpeg'); }); @@ -715,7 +711,7 @@ describe('[Rooms]', function () { }); describe('/rooms.favorite', () => { - let testChannel; + let testChannel: IRoom; const testChannelName = `channel.test.${Date.now()}-${Math.random()}`; before(async () => { @@ -725,7 +721,7 @@ describe('[Rooms]', function () { after(() => deleteRoom({ type: 'c', roomId: testChannel._id })); it('should favorite the room when send favorite: true by roomName', (done) => { - request + void request .post(api('rooms.favorite')) .set(credentials) .send({ @@ -739,7 +735,7 @@ describe('[Rooms]', function () { .end(done); }); it('should unfavorite the room when send favorite: false by roomName', (done) => { - request + void request .post(api('rooms.favorite')) .set(credentials) .send({ @@ -753,7 +749,7 @@ describe('[Rooms]', function () { .end(done); }); it('should favorite the room when send favorite: true by roomId', (done) => { - request + void request .post(api('rooms.favorite')) .set(credentials) .send({ @@ -768,7 +764,7 @@ describe('[Rooms]', function () { }); it('should unfavorite room when send favorite: false by roomId', (done) => { - request + void request .post(api('rooms.favorite')) .set(credentials) .send({ @@ -783,7 +779,7 @@ describe('[Rooms]', function () { }); it('should return an error when send an invalid room', (done) => { - request + void request .post(api('rooms.favorite')) .set(credentials) .send({ @@ -800,7 +796,7 @@ describe('[Rooms]', function () { }); describe('/rooms.nameExists', () => { - let testChannel; + let testChannel: IRoom; const testChannelName = `channel.test.${Date.now()}-${Math.random()}`; before(async () => { @@ -810,7 +806,7 @@ describe('[Rooms]', function () { after(() => deleteRoom({ type: 'c', roomId: testChannel._id })); it('should return 401 unauthorized when user is not logged in', (done) => { - request + void request .get(api('rooms.nameExists')) .expect('Content-Type', 'application/json') .expect(401) @@ -821,7 +817,7 @@ describe('[Rooms]', function () { }); it('should return true if this room name exists', (done) => { - request + void request .get(api('rooms.nameExists')) .set(credentials) .query({ @@ -836,7 +832,7 @@ describe('[Rooms]', function () { }); it('should return an error when send an invalid room', (done) => { - request + void request .get(api('rooms.nameExists')) .set(credentials) .query({ @@ -852,11 +848,11 @@ describe('[Rooms]', function () { }); describe('[/rooms.cleanHistory]', () => { - let publicChannel; - let privateChannel; - let directMessageChannelId; - let user; - let userCredentials; + let publicChannel: IRoom; + let privateChannel: IRoom; + let directMessageChannelId: IRoom['_id']; + let user: TestUser; + let userCredentials: Credentials; beforeEach(async () => { user = await createUser(); @@ -880,7 +876,7 @@ describe('[Rooms]', function () { after(() => updateSetting('Message_ShowDeletedStatus', false)); it('should return success when send a valid public channel', (done) => { - request + void request .post(api('rooms.cleanHistory')) .set(credentials) .send({ @@ -933,22 +929,23 @@ describe('[Rooms]', function () { }); }); it('should successfully delete an image and thumbnail from public channel', (done) => { - request + void request .post(api(`rooms.upload/${publicChannel._id}`)) .set(credentials) .attach('file', imgURL) .expect('Content-Type', 'application/json') .expect(200) .expect((res) => { - const { message } = res.body; + const message = res.body.message as IMessage; expect(res.body).to.have.property('success', true); expect(res.body).to.have.nested.property('message._id', message._id); expect(res.body).to.have.nested.property('message.rid', publicChannel._id); + assert.isDefined(message.file); expect(res.body).to.have.nested.property('message.file._id', message.file._id); expect(res.body).to.have.nested.property('message.file.type', message.file.type); }); - request + void request .post(api('rooms.cleanHistory')) .set(credentials) .send({ @@ -962,7 +959,7 @@ describe('[Rooms]', function () { expect(res.body).to.have.property('success', true); }); - request + void request .get(api('channels.files')) .set(credentials) .query({ @@ -978,7 +975,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return success when send a valid private channel', (done) => { - request + void request .post(api('rooms.cleanHistory')) .set(credentials) .send({ @@ -994,7 +991,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return success when send a valid Direct Message channel', (done) => { - request + void request .post(api('rooms.cleanHistory')) .set(credentials) .send({ @@ -1010,7 +1007,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return not allowed error when try deleting messages with user without permission', (done) => { - request + void request .post(api('rooms.cleanHistory')) .set(userCredentials) .send({ @@ -1029,9 +1026,9 @@ describe('[Rooms]', function () { }); describe('[/rooms.info]', () => { - let testChannel; - let testGroup; - let testDM; + let testChannel: IRoom; + let testGroup: IRoom; + let testDM: IRoom; const expectedKeys = [ '_id', 'name', @@ -1065,7 +1062,7 @@ describe('[Rooms]', function () { ); it('should return the info about the created channel correctly searching by roomId', (done) => { - request + void request .get(api('rooms.info')) .set(credentials) .query({ @@ -1080,7 +1077,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return the info about the created channel correctly searching by roomName', (done) => { - request + void request .get(api('rooms.info')) .set(credentials) .query({ @@ -1095,7 +1092,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return the info about the created group correctly searching by roomId', (done) => { - request + void request .get(api('rooms.info')) .set(credentials) .query({ @@ -1110,7 +1107,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return the info about the created group correctly searching by roomName', (done) => { - request + void request .get(api('rooms.info')) .set(credentials) .query({ @@ -1125,7 +1122,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return the info about the created DM correctly searching by roomId', (done) => { - request + void request .get(api('rooms.info')) .set(credentials) .query({ @@ -1139,7 +1136,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return name and _id of public channel when it has the "fields" query parameter limiting by name', (done) => { - request + void request .get(api('rooms.info')) .set(credentials) .query({ @@ -1158,11 +1155,11 @@ describe('[Rooms]', function () { }); describe('[/rooms.leave]', () => { - let testChannel; - let testGroup; - let testDM; - let user2; - let user2Credentials; + let testChannel: IRoom; + let testGroup: IRoom; + let testDM: IRoom; + let user2: TestUser; + let user2Credentials: Credentials; const testChannelName = `channel.leave.${Date.now()}-${Math.random()}`; const testGroupName = `group.leave.${Date.now()}-${Math.random()}`; @@ -1186,7 +1183,7 @@ describe('[Rooms]', function () { ); it('should return an Error when trying leave a DM room', (done) => { - request + void request .post(api('rooms.leave')) .set(credentials) .send({ @@ -1200,7 +1197,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return an Error when trying to leave a public channel and you are the last owner', (done) => { - request + void request .post(api('rooms.leave')) .set(credentials) .send({ @@ -1214,7 +1211,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return an Error when trying to leave a private group and you are the last owner', (done) => { - request + void request .post(api('rooms.leave')) .set(credentials) .send({ @@ -1228,8 +1225,8 @@ describe('[Rooms]', function () { .end(done); }); it('should return an Error when trying to leave a public channel and not have the necessary permission(leave-c)', (done) => { - updatePermission('leave-c', []).then(() => { - request + void updatePermission('leave-c', []).then(() => { + void request .post(api('rooms.leave')) .set(credentials) .send({ @@ -1244,8 +1241,8 @@ describe('[Rooms]', function () { }); }); it('should return an Error when trying to leave a private group and not have the necessary permission(leave-p)', (done) => { - updatePermission('leave-p', []).then(() => { - request + void updatePermission('leave-p', []).then(() => { + void request .post(api('rooms.leave')) .set(credentials) .send({ @@ -1309,10 +1306,10 @@ describe('[Rooms]', function () { }); describe('/rooms.createDiscussion', () => { - let testChannel; + let testChannel: IRoom; const testChannelName = `channel.test.${Date.now()}-${Math.random()}`; - let messageSent; - let privateTeam; + let messageSent: IMessage; + let privateTeam: ITeam; before(async () => { testChannel = (await createRoom({ type: 'c', name: testChannelName })).body.channel; @@ -1334,8 +1331,8 @@ describe('[Rooms]', function () { ); it('should throw an error when the user tries to create a discussion and the feature is disabled', (done) => { - updateSetting('Discussion_enabled', false).then(() => { - request + void updateSetting('Discussion_enabled', false).then(() => { + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({ @@ -1351,9 +1348,9 @@ describe('[Rooms]', function () { }); }); it('should throw an error when the user tries to create a discussion and does not have at least one of the required permissions', (done) => { - updatePermission('start-discussion', []).then(() => { - updatePermission('start-discussion-other-user', []).then(() => { - request + void updatePermission('start-discussion', []).then(() => { + void updatePermission('start-discussion-other-user', []).then(() => { + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({ @@ -1366,7 +1363,7 @@ describe('[Rooms]', function () { expect(res.body).to.have.property('errorType', 'error-action-not-allowed'); }) .end(() => { - updatePermission('start-discussion', ['admin', 'user', 'guest']) + void updatePermission('start-discussion', ['admin', 'user', 'guest']) .then(() => updatePermission('start-discussion-other-user', ['admin', 'user', 'guest'])) .then(done); }); @@ -1374,7 +1371,7 @@ describe('[Rooms]', function () { }); }); it('should throw an error when the user tries to create a discussion without the required parameter "prid"', (done) => { - request + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({}) @@ -1386,7 +1383,7 @@ describe('[Rooms]', function () { .end(done); }); it('should throw an error when the user tries to create a discussion without the required parameter "t_name"', (done) => { - request + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({ @@ -1400,7 +1397,7 @@ describe('[Rooms]', function () { .end(done); }); it('should throw an error when the user tries to create a discussion with the required parameter invalid "users"(different from an array)', (done) => { - request + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({ @@ -1416,7 +1413,7 @@ describe('[Rooms]', function () { .end(done); }); it("should throw an error when the user tries to create a discussion with the channel's id invalid", (done) => { - request + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({ @@ -1431,7 +1428,7 @@ describe('[Rooms]', function () { .end(done); }); it("should throw an error when the user tries to create a discussion with the message's id invalid", (done) => { - request + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({ @@ -1447,7 +1444,7 @@ describe('[Rooms]', function () { .end(done); }); it('should create a discussion successfully when send only the required parameters', (done) => { - request + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({ @@ -1464,7 +1461,7 @@ describe('[Rooms]', function () { .end(done); }); it('should create a discussion successfully when send the required parameters plus the optional parameter "reply"', (done) => { - request + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({ @@ -1482,7 +1479,7 @@ describe('[Rooms]', function () { .end(done); }); it('should create a discussion successfully when send the required parameters plus the optional parameter "users"', (done) => { - request + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({ @@ -1501,7 +1498,7 @@ describe('[Rooms]', function () { .end(done); }); it('should create a discussion successfully when send the required parameters plus the optional parameter "pmid"', (done) => { - request + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({ @@ -1523,7 +1520,7 @@ describe('[Rooms]', function () { describe('it should create a *private* discussion if the parent channel is public and inside a private team', async () => { it('should create a team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ @@ -1542,7 +1539,7 @@ describe('[Rooms]', function () { }); it('should add the public channel to the team', (done) => { - request + void request .post(api('teams.addRooms')) .set(credentials) .send({ @@ -1558,7 +1555,7 @@ describe('[Rooms]', function () { }); it('should create a private discussion inside the public channel', (done) => { - request + void request .post(api('rooms.createDiscussion')) .set(credentials) .send({ @@ -1579,7 +1576,7 @@ describe('[Rooms]', function () { }); describe('/rooms.getDiscussions', () => { - let testChannel; + let testChannel: IRoom; const testChannelName = `channel.test.getDiscussions${Date.now()}-${Math.random()}`; before(async () => { @@ -1601,7 +1598,7 @@ describe('[Rooms]', function () { ); it('should throw an error when the user tries to gets a list of discussion without a required parameter "roomId"', (done) => { - request + void request .get(api('rooms.getDiscussions')) .set(credentials) .query({}) @@ -1613,8 +1610,8 @@ describe('[Rooms]', function () { .end(done); }); it('should throw an error when the user tries to gets a list of discussion and he cannot access the room', (done) => { - updatePermission('view-c-room', []).then(() => { - request + void updatePermission('view-c-room', []).then(() => { + void request .get(api('rooms.getDiscussions')) .set(credentials) .query({}) @@ -1627,7 +1624,7 @@ describe('[Rooms]', function () { }); }); it('should return a list of discussions with ONE discussion', (done) => { - request + void request .get(api('rooms.getDiscussions')) .set(credentials) .query({ @@ -1645,7 +1642,7 @@ describe('[Rooms]', function () { describe('[/rooms.autocomplete.channelAndPrivate]', () => { it('should return an error when the required parameter "selector" is not provided', (done) => { - request + void request .get(api('rooms.autocomplete.channelAndPrivate')) .set(credentials) .query({}) @@ -1658,8 +1655,9 @@ describe('[Rooms]', function () { .end(done); }); it('should return the rooms to fill auto complete', (done) => { - request - .get(api('rooms.autocomplete.channelAndPrivate?selector={}')) + void request + .get(api('rooms.autocomplete.channelAndPrivate')) + .query({ selector: '{}' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -1673,7 +1671,7 @@ describe('[Rooms]', function () { describe('[/rooms.autocomplete.channelAndPrivate.withPagination]', () => { it('should return an error when the required parameter "selector" is not provided', (done) => { - request + void request .get(api('rooms.autocomplete.channelAndPrivate.withPagination')) .set(credentials) .query({}) @@ -1686,8 +1684,9 @@ describe('[Rooms]', function () { .end(done); }); it('should return the rooms to fill auto complete', (done) => { - request - .get(api('rooms.autocomplete.channelAndPrivate.withPagination?selector={}')) + void request + .get(api('rooms.autocomplete.channelAndPrivate.withPagination')) + .query({ selector: '{}' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -1699,8 +1698,9 @@ describe('[Rooms]', function () { .end(done); }); it('should return the rooms to fill auto complete even requested with count and offset params', (done) => { - request - .get(api('rooms.autocomplete.channelAndPrivate.withPagination?selector={}')) + void request + .get(api('rooms.autocomplete.channelAndPrivate.withPagination')) + .query({ selector: '{}' }) .set(credentials) .query({ count: 5, @@ -1719,7 +1719,7 @@ describe('[Rooms]', function () { describe('[/rooms.autocomplete.availableForTeams]', () => { it('should return the rooms to fill auto complete', (done) => { - request + void request .get(api('rooms.autocomplete.availableForTeams')) .set(credentials) .expect('Content-Type', 'application/json') @@ -1731,8 +1731,9 @@ describe('[Rooms]', function () { .end(done); }); it('should return the filtered rooms to fill auto complete', (done) => { - request - .get(api('rooms.autocomplete.availableForTeams?name=group')) + void request + .get(api('rooms.autocomplete.availableForTeams')) + .query({ name: 'group' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -1745,7 +1746,7 @@ describe('[Rooms]', function () { }); describe('[/rooms.autocomplete.adminRooms]', () => { - let testGroup; + let testGroup: IRoom; const testGroupName = `channel.test.adminRoom${Date.now()}-${Math.random()}`; const name = { name: testGroupName, @@ -1765,8 +1766,8 @@ describe('[Rooms]', function () { after(() => Promise.all([deleteRoom({ type: 'p', roomId: testGroup._id }), updateEEPermission('can-audit', ['admin', 'auditor'])])); (IS_EE ? it : it.skip)('should return an error when the required parameter "selector" is not provided', (done) => { - updateEEPermission('can-audit', ['admin']).then(() => { - request + void updateEEPermission('can-audit', ['admin']).then(() => { + void request .get(api('rooms.autocomplete.adminRooms')) .set(credentials) .query({}) @@ -1780,8 +1781,9 @@ describe('[Rooms]', function () { }); }); it('should return the rooms to fill auto complete', (done) => { - request - .get(api('rooms.autocomplete.adminRooms?selector={}')) + void request + .get(api('rooms.autocomplete.adminRooms')) + .query({ selector: '{}' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -1792,8 +1794,8 @@ describe('[Rooms]', function () { .end(done); }); it('should return the rooms to fill auto complete', (done) => { - request - .get(api('rooms.autocomplete.adminRooms?')) + void request + .get(api('rooms.autocomplete.adminRooms')) .set(credentials) .query({ selector: JSON.stringify(name), @@ -1815,7 +1817,7 @@ describe('[Rooms]', function () { const nameRoom = `Ellinika-${suffix}`; const discussionRoomName = `${nameRoom}-discussion`; - let testGroup; + let testGroup: IRoom; before(async () => { await updateSetting('UI_Allow_room_names_with_special_chars', true); @@ -1835,8 +1837,8 @@ describe('[Rooms]', function () { ); it('should throw an error when the user tries to gets a list of discussion and he cannot access the room', (done) => { - updatePermission('view-room-administration', []).then(() => { - request + void updatePermission('view-room-administration', []).then(() => { + void request .get(api('rooms.adminRooms')) .set(credentials) .expect(400) @@ -1848,7 +1850,7 @@ describe('[Rooms]', function () { }); }); it('should return a list of admin rooms', (done) => { - request + void request .get(api('rooms.adminRooms')) .set(credentials) .expect(200) @@ -1862,7 +1864,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return a list of admin rooms even requested with count and offset params', (done) => { - request + void request .get(api('rooms.adminRooms')) .set(credentials) .query({ @@ -1880,8 +1882,8 @@ describe('[Rooms]', function () { .end(done); }); it('should search the list of admin rooms using non-latin characters when UI_Allow_room_names_with_special_chars setting is toggled', (done) => { - updateSetting('UI_Allow_room_names_with_special_chars', true).then(() => { - request + void updateSetting('UI_Allow_room_names_with_special_chars', true).then(() => { + void request .get(api('rooms.adminRooms')) .set(credentials) .query({ @@ -1901,8 +1903,8 @@ describe('[Rooms]', function () { }); }); it('should search the list of admin rooms using latin characters only when UI_Allow_room_names_with_special_chars setting is disabled', (done) => { - updateSetting('UI_Allow_room_names_with_special_chars', false).then(() => { - request + void updateSetting('UI_Allow_room_names_with_special_chars', false).then(() => { + void request .get(api('rooms.adminRooms')) .set(credentials) .query({ @@ -1922,7 +1924,7 @@ describe('[Rooms]', function () { }); }); it('should filter by only rooms types', (done) => { - request + void request .get(api('rooms.adminRooms')) .set(credentials) .query({ @@ -1934,13 +1936,13 @@ describe('[Rooms]', function () { expect(res.body).to.have.property('rooms').and.to.be.an('array'); expect(res.body.rooms).to.have.lengthOf.at.least(1); expect(res.body.rooms[0].t).to.be.equal('p'); - expect(res.body.rooms.find((room) => room.name === nameRoom)).to.exist; - expect(res.body.rooms.find((room) => room.name === discussionRoomName)).to.not.exist; + expect((res.body.rooms as IRoom[]).find((room) => room.name === nameRoom)).to.exist; + expect((res.body.rooms as IRoom[]).find((room) => room.name === discussionRoomName)).to.not.exist; }) .end(done); }); it('should filter by only name', (done) => { - request + void request .get(api('rooms.adminRooms')) .set(credentials) .query({ @@ -1956,7 +1958,7 @@ describe('[Rooms]', function () { .end(done); }); it('should filter by type and name at the same query', (done) => { - request + void request .get(api('rooms.adminRooms')) .set(credentials) .query({ @@ -1973,7 +1975,7 @@ describe('[Rooms]', function () { .end(done); }); it('should return an empty array when filter by wrong type and correct room name', (done) => { - request + void request .get(api('rooms.adminRooms')) .set(credentials) .query({ @@ -1991,8 +1993,8 @@ describe('[Rooms]', function () { }); describe('update group dms name', () => { - let testUser; - let roomId; + let testUser: TestUser; + let roomId: IRoom['_id']; before(async () => { testUser = await createUser(); @@ -2063,7 +2065,7 @@ describe('[Rooms]', function () { }); describe('/rooms.delete', () => { - let testChannel; + let testChannel: IRoom; before('create an channel', async () => { const result = await createRoom({ type: 'c', name: `channel.test.${Date.now()}-${Math.random()}` }); @@ -2073,7 +2075,7 @@ describe('[Rooms]', function () { after(() => deleteRoom({ type: 'c', roomId: testChannel._id })); it('should throw an error when roomId is not provided', (done) => { - request + void request .post(api('rooms.delete')) .set(credentials) .send({}) @@ -2086,7 +2088,7 @@ describe('[Rooms]', function () { .end(done); }); it('should delete a room when the request is correct', (done) => { - request + void request .post(api('rooms.delete')) .set(credentials) .send({ roomId: testChannel._id }) @@ -2098,7 +2100,7 @@ describe('[Rooms]', function () { .end(done); }); it('should throw an error when the room id doesn exist', (done) => { - request + void request .post(api('rooms.delete')) .set(credentials) .send({ roomId: 'invalid' }) @@ -2112,9 +2114,9 @@ describe('[Rooms]', function () { }); describe('rooms.saveRoomSettings', () => { - let testChannel; + let testChannel: IRoom; const randomString = `randomString${Date.now()}`; - let discussion; + let discussion: IRoom; before(async () => { const result = await createRoom({ type: 'c', name: `channel.test.${Date.now()}-${Math.random()}` }); @@ -2136,7 +2138,7 @@ describe('[Rooms]', function () { it('should update the room settings', (done) => { const imageDataUri = `data:image/png;base64,${fs.readFileSync(path.join(process.cwd(), imgURL)).toString('base64')}`; - request + void request .post(api('rooms.saveRoomSettings')) .set(credentials) .send({ @@ -2162,7 +2164,7 @@ describe('[Rooms]', function () { }); it('should have reflected on rooms.info', (done) => { - request + void request .get(api('rooms.info')) .set(credentials) .query({ @@ -2278,13 +2280,19 @@ describe('[Rooms]', function () { }); describe('rooms.images', () => { - let testUserCreds = null; + let testUserCreds: Credentials; before(async () => { const user = await createUser(); testUserCreds = await login(user.username, password); }); - const uploadFile = async ({ roomId, file }) => { + const uploadFile = async ({ + roomId, + file, + }: { + roomId: IRoom['_id']; + file: Blob | Buffer | fs.ReadStream | string | boolean | number; + }) => { const { body } = await request .post(api(`rooms.upload/${roomId}`)) .set(credentials) @@ -2295,7 +2303,7 @@ describe('[Rooms]', function () { return body.message.attachments[0]; }; - const getIdFromImgPath = (link) => { + const getIdFromImgPath = (link: string) => { return link.split('/')[2]; }; @@ -2319,7 +2327,7 @@ describe('[Rooms]', function () { await deleteRoom({ type: 'p', roomId }); }); it('should return an empty array when room is valid and user is part of it but there are no images', async () => { - const { body } = await createRoom({ type: 'p', usernames: [credentials.username], name: `test-${Date.now()}` }); + const { body } = await createRoom({ type: 'p', name: `test-${Date.now()}` }); const { group: { _id: roomId }, } = body; @@ -2336,7 +2344,7 @@ describe('[Rooms]', function () { await deleteRoom({ type: 'p', roomId }); }); it('should return an array of images when room is valid and user is part of it and there are images', async () => { - const { body } = await createRoom({ type: 'p', usernames: [credentials.username], name: `test-${Date.now()}` }); + const { body } = await createRoom({ type: 'p', name: `test-${Date.now()}` }); const { group: { _id: roomId }, } = body; @@ -2359,7 +2367,7 @@ describe('[Rooms]', function () { await deleteRoom({ type: 'p', roomId }); }); it('should return multiple images when room is valid and user is part of it and there are multiple images', async () => { - const { body } = await createRoom({ type: 'p', usernames: [credentials.username], name: `test-${Date.now()}` }); + const { body } = await createRoom({ type: 'p', name: `test-${Date.now()}` }); const { group: { _id: roomId }, } = body; @@ -2383,14 +2391,14 @@ describe('[Rooms]', function () { .expect((res) => { expect(res.body).to.have.property('success', true); expect(res.body).to.have.property('files').and.to.be.an('array').and.to.have.lengthOf(2); - expect(res.body.files.find((file) => file._id === fileId1)).to.exist; - expect(res.body.files.find((file) => file._id === fileId2)).to.exist; + expect((res.body.files as IUpload[]).find((file) => file._id === fileId1)).to.exist; + expect((res.body.files as IUpload[]).find((file) => file._id === fileId2)).to.exist; }); await deleteRoom({ type: 'p', roomId }); }); it('should allow to filter images passing the startingFromId parameter', async () => { - const { body } = await createRoom({ type: 'p', usernames: [credentials.username], name: `test-${Date.now()}` }); + const { body } = await createRoom({ type: 'p', name: `test-${Date.now()}` }); const { group: { _id: roomId }, } = body; @@ -2420,7 +2428,7 @@ describe('[Rooms]', function () { }); describe('/rooms.muteUser', () => { - let testChannel; + let testChannel: IRoom; before('create a channel', async () => { const result = await createRoom({ type: 'c', name: `channel.test.${Date.now()}-${Math.random()}` }); @@ -2482,7 +2490,7 @@ describe('[Rooms]', function () { }); describe('/rooms.unmuteUser', () => { - let testChannel; + let testChannel: IRoom; before('create a channel', async () => { const result = await createRoom({ type: 'c', name: `channel.test.${Date.now()}-${Math.random()}` }); @@ -2555,8 +2563,8 @@ describe('[Rooms]', function () { }); describe('/rooms.export', () => { - let testChannel; - let testMessageId; + let testChannel: IRoom; + let testMessageId: IMessage['_id']; before(async () => { const result = await createRoom({ type: 'c', name: `channel.export.test.${Date.now()}-${Math.random()}` }); diff --git a/apps/meteor/tests/end-to-end/api/10-subscriptions.js b/apps/meteor/tests/end-to-end/api/10-subscriptions.ts similarity index 92% rename from apps/meteor/tests/end-to-end/api/10-subscriptions.js rename to apps/meteor/tests/end-to-end/api/10-subscriptions.ts index e54102621690..da7319602271 100644 --- a/apps/meteor/tests/end-to-end/api/10-subscriptions.js +++ b/apps/meteor/tests/end-to-end/api/10-subscriptions.ts @@ -1,17 +1,18 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IRoom, IThreadMessage, IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { adminUsername } from '../../data/user'; -import { createUser, deleteUser, login } from '../../data/users.helper.js'; - -describe('[Subscriptions]', function () { - this.retries(0); +import type { TestUser } from '../../data/users.helper'; +import { createUser, deleteUser, login } from '../../data/users.helper'; +describe('[Subscriptions]', () => { before((done) => getCredentials(done)); - let testChannel; + let testChannel: IRoom; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.test.${Date.now()}` })).body.channel; @@ -20,7 +21,7 @@ describe('[Subscriptions]', function () { after(() => deleteRoom({ type: 'c', roomId: testChannel._id })); it('/subscriptions.get', (done) => { - request + void request .get(api('subscriptions.get')) .set(credentials) .expect('Content-Type', 'application/json') @@ -34,7 +35,7 @@ describe('[Subscriptions]', function () { }); it('/subscriptions.get?updatedSince', (done) => { - request + void request .get(api('subscriptions.get')) .set(credentials) .query({ @@ -51,7 +52,7 @@ describe('[Subscriptions]', function () { it('/subscriptions.getOne:', () => { it('subscriptions.getOne', (done) => { - request + void request .get(api('subscriptions.getOne')) .set(credentials) .query({ @@ -68,9 +69,9 @@ describe('[Subscriptions]', function () { }); describe('[/subscriptions.read]', () => { - let testChannel; - let testGroup; - let testDM; + let testChannel: IRoom; + let testGroup: IRoom; + let testDM: IRoom; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.test.${Date.now()}` })).body.channel; @@ -87,7 +88,7 @@ describe('[Subscriptions]', function () { ); it('should mark public channels as read', (done) => { - request + void request .post(api('subscriptions.read')) .set(credentials) .send({ @@ -101,7 +102,7 @@ describe('[Subscriptions]', function () { }); it('should mark groups as read', (done) => { - request + void request .post(api('subscriptions.read')) .set(credentials) .send({ @@ -115,7 +116,7 @@ describe('[Subscriptions]', function () { }); it('should mark DMs as read', (done) => { - request + void request .post(api('subscriptions.read')) .set(credentials) .send({ @@ -129,7 +130,7 @@ describe('[Subscriptions]', function () { }); it('should fail on two params with different ids', (done) => { - request + void request .post(api('subscriptions.read')) .set(credentials) .send({ @@ -145,7 +146,7 @@ describe('[Subscriptions]', function () { }); it('should fail on mark inexistent public channel as read', (done) => { - request + void request .post(api('subscriptions.read')) .set(credentials) .send({ @@ -160,7 +161,7 @@ describe('[Subscriptions]', function () { }); it('should fail on mark inexistent group as read', (done) => { - request + void request .post(api('subscriptions.read')) .set(credentials) .send({ @@ -175,7 +176,7 @@ describe('[Subscriptions]', function () { }); it('should fail on mark inexistent DM as read', (done) => { - request + void request .post(api('subscriptions.read')) .set(credentials) .send({ @@ -190,7 +191,7 @@ describe('[Subscriptions]', function () { }); it('should fail on invalid params', (done) => { - request + void request .post(api('subscriptions.read')) .set(credentials) .send({ @@ -205,7 +206,7 @@ describe('[Subscriptions]', function () { }); it('should fail on empty params', (done) => { - request + void request .post(api('subscriptions.read')) .set(credentials) .send({}) @@ -218,9 +219,9 @@ describe('[Subscriptions]', function () { }); describe('should handle threads correctly', () => { - let threadId; - let user; - let threadUserCredentials; + let threadId: IThreadMessage['_id']; + let user: TestUser; + let threadUserCredentials: Credentials; before(async () => { user = await createUser({ username: 'testthread123', password: 'testthread123' }); @@ -320,7 +321,7 @@ describe('[Subscriptions]', function () { }); describe('[/subscriptions.unread]', () => { - let testChannel; + let testChannel: IRoom; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.test.${Date.now()}` })).body.channel; @@ -329,7 +330,7 @@ describe('[Subscriptions]', function () { after(() => deleteRoom({ type: 'c', roomId: testChannel._id })); it('should fail when there are no messages on an channel', (done) => { - request + void request .post(api('subscriptions.unread')) .set(credentials) .send({ @@ -344,7 +345,7 @@ describe('[Subscriptions]', function () { .end(done); }); it('sending message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -362,7 +363,7 @@ describe('[Subscriptions]', function () { .end(done); }); it('should return success: true when make as unread successfully', (done) => { - request + void request .post(api('subscriptions.unread')) .set(credentials) .send({ @@ -376,7 +377,7 @@ describe('[Subscriptions]', function () { }); it('should fail on invalid params', (done) => { - request + void request .post(api('subscriptions.unread')) .set(credentials) .send({ @@ -391,7 +392,7 @@ describe('[Subscriptions]', function () { }); it('should fail on empty params', (done) => { - request + void request .post(api('subscriptions.unread')) .set(credentials) .send({}) diff --git a/apps/meteor/tests/end-to-end/api/11-permissions.js b/apps/meteor/tests/end-to-end/api/11-permissions.ts similarity index 91% rename from apps/meteor/tests/end-to-end/api/11-permissions.js rename to apps/meteor/tests/end-to-end/api/11-permissions.ts index 30db3b5b67e2..55bd724dad45 100644 --- a/apps/meteor/tests/end-to-end/api/11-permissions.js +++ b/apps/meteor/tests/end-to-end/api/11-permissions.ts @@ -1,19 +1,17 @@ import { expect } from 'chai'; import { before, describe, it, after } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { updatePermission } from '../../data/permissions.helper'; -describe('[Permissions]', function () { - this.retries(0); - +describe('[Permissions]', () => { before((done) => getCredentials(done)); after(() => updatePermission('add-oauth-service', ['admin'])); describe('[/permissions.listAll]', () => { it('should return an array with update and remove properties', (done) => { - request + void request .get(api('permissions.listAll')) .set(credentials) .expect('Content-Type', 'application/json') @@ -27,8 +25,9 @@ describe('[Permissions]', function () { }); it('should return an array with update and remov properties when search by "updatedSince" query parameter', (done) => { - request - .get(api('permissions.listAll?updatedSince=2018-11-27T13:52:01Z')) + void request + .get(api('permissions.listAll')) + .query({ updatedSince: '2018-11-27T13:52:01Z' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -41,8 +40,9 @@ describe('[Permissions]', function () { }); it('should return an error when updatedSince query parameter is not a valid ISODate string', (done) => { - request - .get(api('permissions.listAll?updatedSince=fsafdf')) + void request + .get(api('permissions.listAll')) + .query({ updatedSince: 'fsafdf' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -61,7 +61,7 @@ describe('[Permissions]', function () { roles: ['admin', 'user'], }, ]; - request + void request .post(api('permissions.update')) .set(credentials) .send({ permissions }) @@ -85,7 +85,7 @@ describe('[Permissions]', function () { roles: ['admin'], }, ]; - request + void request .post(api('permissions.update')) .set(credentials) .send({ permissions }) @@ -103,7 +103,7 @@ describe('[Permissions]', function () { roles: ['this-role-does-not-exist'], }, ]; - request + void request .post(api('permissions.update')) .set(credentials) .send({ permissions }) @@ -116,7 +116,7 @@ describe('[Permissions]', function () { }); it('should 400 when trying to set permissions to a string', (done) => { const permissions = ''; - request + void request .post(api('permissions.update')) .set(credentials) .send({ permissions }) diff --git a/apps/meteor/tests/end-to-end/api/12-emoji-custom.js b/apps/meteor/tests/end-to-end/api/12-emoji-custom.ts similarity index 87% rename from apps/meteor/tests/end-to-end/api/12-emoji-custom.js rename to apps/meteor/tests/end-to-end/api/12-emoji-custom.ts index 488be47852ca..31042363836e 100644 --- a/apps/meteor/tests/end-to-end/api/12-emoji-custom.js +++ b/apps/meteor/tests/end-to-end/api/12-emoji-custom.ts @@ -1,16 +1,14 @@ -import { expect } from 'chai'; +import type { ICustomEmojiDescriptor } from '@rocket.chat/core-typings'; +import { assert, expect } from 'chai'; import { before, describe, it, after } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { imgURL } from '../../data/interactions'; -const customEmojiName = `my-custom-emoji-${Date.now()}`; -let createdCustomEmoji; +describe('[EmojiCustom]', () => { + const customEmojiName = `my-custom-emoji-${Date.now()}`; -describe('[EmojiCustom]', function () { - let withoutAliases; - - this.retries(0); + let withoutAliases: ICustomEmojiDescriptor; before((done) => getCredentials(done)); @@ -22,7 +20,7 @@ describe('[EmojiCustom]', function () { describe('[/emoji-custom.create]', () => { it('should create new custom emoji', (done) => { - request + void request .post(api('emoji-custom.create')) .set(credentials) .attach('emoji', imgURL) @@ -38,7 +36,7 @@ describe('[EmojiCustom]', function () { .end(done); }); it('should create new custom emoji without optional parameter "aliases"', (done) => { - request + void request .post(api('emoji-custom.create')) .set(credentials) .attach('emoji', imgURL) @@ -53,7 +51,7 @@ describe('[EmojiCustom]', function () { .end(done); }); it('should throw an error when the filename is wrong', (done) => { - request + void request .post(api('emoji-custom.create')) .set(credentials) .attach('emojiwrong', imgURL) @@ -71,9 +69,11 @@ describe('[EmojiCustom]', function () { }); }); + let createdCustomEmoji: ICustomEmojiDescriptor; + describe('[/emoji-custom.update]', () => { before((done) => { - request + void request .get(api('emoji-custom.list')) .set(credentials) .expect(200) @@ -82,14 +82,22 @@ describe('[EmojiCustom]', function () { expect(res.body.emojis).to.have.property('update').and.to.be.a('array').and.to.not.have.lengthOf(0); expect(res.body.emojis).to.have.property('remove').and.to.be.a('array').and.to.have.lengthOf(0); - createdCustomEmoji = res.body.emojis.update.find((emoji) => emoji.name === customEmojiName); - withoutAliases = res.body.emojis.update.find((emoji) => emoji.name === `${customEmojiName}-without-aliases`); + const _createdCustomEmoji = (res.body.emojis.update as ICustomEmojiDescriptor[]).find((emoji) => emoji.name === customEmojiName); + const _withoutAliases = (res.body.emojis.update as ICustomEmojiDescriptor[]).find( + (emoji) => emoji.name === `${customEmojiName}-without-aliases`, + ); + + assert.isDefined(_createdCustomEmoji); + assert.isDefined(_withoutAliases); + + createdCustomEmoji = _createdCustomEmoji; + withoutAliases = _withoutAliases; }) .end(done); }); it('successfully:', () => { it('should update the custom emoji without a file', (done) => { - request + void request .post(api('emoji-custom.update')) .set(credentials) .field({ @@ -105,7 +113,7 @@ describe('[EmojiCustom]', function () { .end(done); }); it('should update the custom emoji without optional parameter "aliases"', (done) => { - request + void request .post(api('emoji-custom.update')) .set(credentials) .field({ @@ -120,7 +128,7 @@ describe('[EmojiCustom]', function () { .end(done); }); it('should update the custom emoji with all parameters and with a file', (done) => { - request + void request .post(api('emoji-custom.update')) .set(credentials) .attach('emoji', imgURL) @@ -138,7 +146,7 @@ describe('[EmojiCustom]', function () { }); it('should throw error when:', () => { it('the fields does not include "_id"', (done) => { - request + void request .post(api('emoji-custom.update')) .set(credentials) .attach('emoji', imgURL) @@ -154,7 +162,7 @@ describe('[EmojiCustom]', function () { .end(done); }); it('the custom emoji does not exists', (done) => { - request + void request .post(api('emoji-custom.update')) .set(credentials) .attach('emoji', imgURL) @@ -171,7 +179,7 @@ describe('[EmojiCustom]', function () { .end(done); }); it('the filename is wrong', (done) => { - request + void request .post(api('emoji-custom.update')) .set(credentials) .attach('emojiwrong', imgURL) @@ -192,7 +200,7 @@ describe('[EmojiCustom]', function () { describe('[/emoji-custom.list]', () => { it('should return emojis', (done) => { - request + void request .get(api('emoji-custom.list')) .set(credentials) .expect(200) @@ -204,8 +212,9 @@ describe('[EmojiCustom]', function () { .end(done); }); it('should return emojis when use "query" query parameter', (done) => { - request - .get(api(`emoji-custom.list?query={"_updatedAt": {"$gt": { "$date": "${new Date().toISOString()}" } } }`)) + void request + .get(api('emoji-custom.list')) + .query({ query: `{ "_updatedAt": { "$gt": { "$date": "${new Date().toISOString()}" } } }` }) .set(credentials) .expect(200) .expect((res) => { @@ -217,8 +226,9 @@ describe('[EmojiCustom]', function () { .end(done); }); it('should return emojis when use "updateSince" query parameter', (done) => { - request - .get(api(`emoji-custom.list?updatedSince=${new Date().toISOString()}`)) + void request + .get(api('emoji-custom.list')) + .query({ updatedSince: new Date().toISOString() }) .set(credentials) .expect(200) .expect((res) => { @@ -230,12 +240,9 @@ describe('[EmojiCustom]', function () { .end(done); }); it('should return emojis when use both, "updateSince" and "query" query parameter', (done) => { - request - .get( - api( - `emoji-custom.list?query={"_updatedAt": {"$gt": { "$date": "${new Date().toISOString()}" } }}&updatedSince=${new Date().toISOString()}`, - ), - ) + void request + .get(api('emoji-custom.list')) + .query({ query: `{"_updatedAt": {"$gt": { "$date": "${new Date().toISOString()}" } }}`, updatedSince: new Date().toISOString() }) .set(credentials) .expect(200) .expect((res) => { @@ -247,8 +254,9 @@ describe('[EmojiCustom]', function () { .end(done); }); it('should return an error when the "updateSince" query parameter is a invalid date', (done) => { - request - .get(api('emoji-custom.list?updatedSince=invalid-date')) + void request + .get(api('emoji-custom.list')) + .query({ updatedSince: 'invalid-date' }) .set(credentials) .expect(400) .expect((res) => { @@ -261,7 +269,7 @@ describe('[EmojiCustom]', function () { describe('[/emoji-custom.all]', () => { it('should return emojis', (done) => { - request + void request .get(api('emoji-custom.all')) .set(credentials) .expect(200) @@ -274,7 +282,7 @@ describe('[EmojiCustom]', function () { .end(done); }); it('should return emojis even requested with count and offset params', (done) => { - request + void request .get(api('emoji-custom.all')) .set(credentials) .query({ @@ -293,10 +301,10 @@ describe('[EmojiCustom]', function () { }); describe('Accessing custom emojis', () => { - let uploadDate; + let uploadDate: unknown; it('should return forbidden if the there is no fileId on the url', (done) => { - request + void request .get('/emoji-custom/') .set(credentials) .expect(403) @@ -307,7 +315,7 @@ describe('[EmojiCustom]', function () { }); it('should return success if the file does not exists with some specific headers', (done) => { - request + void request .get('/emoji-custom/invalid') .set(credentials) .expect(200) @@ -322,7 +330,7 @@ describe('[EmojiCustom]', function () { }); it('should return not modified if the file does not exists and if-modified-since is equal to the Thu, 01 Jan 2015 00:00:00 GMT', (done) => { - request + void request .get('/emoji-custom/invalid') .set(credentials) .set({ @@ -336,7 +344,7 @@ describe('[EmojiCustom]', function () { }); it('should return success if the the requested exists', (done) => { - request + void request .get(`/emoji-custom/${customEmojiName}.png`) .set(credentials) .expect(200) @@ -351,7 +359,7 @@ describe('[EmojiCustom]', function () { }); it('should return not modified if the the requested file contains a valid-since equal to the upload date', (done) => { - request + void request .get(`/emoji-custom/${customEmojiName}.png`) .set(credentials) .set({ @@ -370,7 +378,7 @@ describe('[EmojiCustom]', function () { describe('[/emoji-custom.delete]', () => { it('should throw an error when trying delete custom emoji without the required param "emojid"', (done) => { - request + void request .post(api('emoji-custom.delete')) .set(credentials) .send({}) @@ -383,7 +391,7 @@ describe('[EmojiCustom]', function () { .end(done); }); it('should throw an error when trying delete custom emoji that does not exists', (done) => { - request + void request .post(api('emoji-custom.delete')) .set(credentials) .send({ @@ -398,7 +406,7 @@ describe('[EmojiCustom]', function () { .end(done); }); it('should delete the custom emoji created before successfully', (done) => { - request + void request .post(api('emoji-custom.delete')) .set(credentials) .send({ diff --git a/apps/meteor/tests/end-to-end/api/14-assets.js b/apps/meteor/tests/end-to-end/api/14-assets.ts similarity index 94% rename from apps/meteor/tests/end-to-end/api/14-assets.js rename to apps/meteor/tests/end-to-end/api/14-assets.ts index 3bcc968e7ee7..ff9dbfa7a89f 100644 --- a/apps/meteor/tests/end-to-end/api/14-assets.js +++ b/apps/meteor/tests/end-to-end/api/14-assets.ts @@ -1,13 +1,11 @@ import { expect } from 'chai'; import { before, describe, it, after } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { imgURL } from '../../data/interactions'; import { updatePermission } from '../../data/permissions.helper'; -describe('[Assets]', function () { - this.retries(0); - +describe('[Assets]', () => { before((done) => getCredentials(done)); before(() => updatePermission('manage-assets', ['admin'])); @@ -16,7 +14,7 @@ describe('[Assets]', function () { describe('[/assets.setAsset]', () => { it('should set the "logo" asset', (done) => { - request + void request .post(api('assets.setAsset')) .set(credentials) .attach('asset', imgURL) @@ -31,7 +29,7 @@ describe('[Assets]', function () { .end(done); }); it('should throw an error when we try set an invalid asset', (done) => { - request + void request .post(api('assets.setAsset')) .set(credentials) .attach('invalidAsset', imgURL) @@ -46,7 +44,7 @@ describe('[Assets]', function () { describe('[/assets.unsetAsset]', () => { it('should unset the "logo" asset', (done) => { - request + void request .post(api('assets.unsetAsset')) .set(credentials) .send({ @@ -60,7 +58,7 @@ describe('[Assets]', function () { .end(done); }); it('should throw an error when we try set an invalid asset', (done) => { - request + void request .post(api('assets.unsetAsset')) .set(credentials) .send({ diff --git a/apps/meteor/tests/end-to-end/api/16-commands.js b/apps/meteor/tests/end-to-end/api/16-commands.ts similarity index 94% rename from apps/meteor/tests/end-to-end/api/16-commands.js rename to apps/meteor/tests/end-to-end/api/16-commands.ts index c0781167b67f..36a0842cc58f 100644 --- a/apps/meteor/tests/end-to-end/api/16-commands.js +++ b/apps/meteor/tests/end-to-end/api/16-commands.ts @@ -1,20 +1,21 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IRoom, IThreadMessage, IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { before, describe, it, after } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; -import { sendSimpleMessage } from '../../data/chat.helper.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; +import { sendSimpleMessage } from '../../data/chat.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { password } from '../../data/user'; -import { createUser, deleteUser, login } from '../../data/users.helper.js'; - -describe('[Commands]', function () { - this.retries(0); +import type { TestUser } from '../../data/users.helper'; +import { createUser, deleteUser, login } from '../../data/users.helper'; +describe('[Commands]', () => { before((done) => getCredentials(done)); describe('[/commands.get]', () => { it('should return an error when call the endpoint without "command" required parameter', (done) => { - request + void request .get(api('commands.get')) .set(credentials) .expect(400) @@ -25,7 +26,7 @@ describe('[Commands]', function () { .end(done); }); it('should return an error when call the endpoint with an invalid command', (done) => { - request + void request .get(api('commands.get')) .set(credentials) .query({ @@ -39,7 +40,7 @@ describe('[Commands]', function () { .end(done); }); it('should return success when parameters are correct', (done) => { - request + void request .get(api('commands.get')) .set(credentials) .query({ @@ -94,8 +95,8 @@ describe('[Commands]', function () { }); describe('[/commands.run]', () => { - let testChannel; - let threadMessage; + let testChannel: IRoom; + let threadMessage: IThreadMessage; before(async () => { testChannel = (await createRoom({ type: 'c', name: `channel.test.commands.${Date.now()}` })).body.channel; @@ -116,7 +117,7 @@ describe('[Commands]', function () { after(() => deleteRoom({ type: 'c', roomId: testChannel._id })); it('should return an error when call the endpoint without "command" required parameter', (done) => { - request + void request .post(api('commands.run')) .set(credentials) .expect(400) @@ -127,7 +128,7 @@ describe('[Commands]', function () { .end(done); }); it('should return an error when call the endpoint with the param "params" and it is not a string', (done) => { - request + void request .post(api('commands.run')) .set(credentials) .send({ @@ -142,7 +143,7 @@ describe('[Commands]', function () { .end(done); }); it('should return an error when call the endpoint without "roomId" required parameter', (done) => { - request + void request .post(api('commands.run')) .set(credentials) .send({ @@ -157,7 +158,7 @@ describe('[Commands]', function () { .end(done); }); it('should return an error when call the endpoint with the param "tmid" and it is not a string', (done) => { - request + void request .post(api('commands.run')) .set(credentials) .send({ @@ -174,7 +175,7 @@ describe('[Commands]', function () { .end(done); }); it('should return an error when call the endpoint with the invalid "command" param', (done) => { - request + void request .post(api('commands.run')) .set(credentials) .send({ @@ -190,7 +191,7 @@ describe('[Commands]', function () { .end(done); }); it('should return an error when call the endpoint with an invalid thread id', (done) => { - request + void request .post(api('commands.run')) .set(credentials) .send({ @@ -207,7 +208,7 @@ describe('[Commands]', function () { .end(done); }); it('should return an error when call the endpoint with a valid thread id of wrong channel', (done) => { - request + void request .post(api('commands.run')) .set(credentials) .send({ @@ -224,7 +225,7 @@ describe('[Commands]', function () { .end(done); }); it('should return success when parameters are correct', (done) => { - request + void request .post(api('commands.run')) .set(credentials) .send({ @@ -243,8 +244,8 @@ describe('[Commands]', function () { describe('Command archive', function () { describe('unauthorized cases', () => { - let user; - let credentials; + let user: TestUser; + let credentials: Credentials; this.beforeAll(async () => { user = await createUser({ @@ -319,8 +320,8 @@ describe('[Commands]', function () { describe('Command unarchive', function () { describe('unauthorized cases', () => { - let user; - let credentials; + let user: TestUser; + let credentials: Credentials; this.beforeAll(async () => { user = await createUser({ joinDefaultChannels: true, diff --git a/apps/meteor/tests/end-to-end/api/17-custom-sounds.js b/apps/meteor/tests/end-to-end/api/17-custom-sounds.ts similarity index 94% rename from apps/meteor/tests/end-to-end/api/17-custom-sounds.js rename to apps/meteor/tests/end-to-end/api/17-custom-sounds.ts index 006129a31d7c..11ba7622bfe0 100644 --- a/apps/meteor/tests/end-to-end/api/17-custom-sounds.js +++ b/apps/meteor/tests/end-to-end/api/17-custom-sounds.ts @@ -5,16 +5,14 @@ import path from 'path'; import { expect } from 'chai'; import { before, describe, it, after } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; - -describe('[CustomSounds]', function () { - this.retries(0); +import { getCredentials, api, request, credentials } from '../../data/api-data'; +describe('[CustomSounds]', () => { before((done) => getCredentials(done)); describe('[/custom-sounds.list]', () => { it('should return custom sounds', (done) => { - request + void request .get(api('custom-sounds.list')) .set(credentials) .expect(200) @@ -27,7 +25,7 @@ describe('[CustomSounds]', function () { .end(done); }); it('should return custom sounds even requested with count and offset params', (done) => { - request + void request .get(api('custom-sounds.list')) .set(credentials) .expect(200) @@ -46,13 +44,13 @@ describe('[CustomSounds]', function () { }); describe('Accessing custom sounds', () => { - let fileId; + let fileId: string; const fileName = `test-file-${randomUUID()}`; - let uploadDate; + let uploadDate: unknown; before(async () => { const data = readFileSync(path.resolve(__dirname, '../../mocks/files/audio_mock.wav')); - const binary = Buffer.from(data, 'base64').toString('binary'); + const binary = data.toString('binary'); await request .post(api('method.call/insertOrUpdateSound')) .set(credentials) @@ -97,7 +95,7 @@ describe('[CustomSounds]', function () { ); it('should return forbidden if the there is no fileId on the url', (done) => { - request + void request .get('/custom-sounds/') .set(credentials) .expect(403) @@ -108,7 +106,7 @@ describe('[CustomSounds]', function () { }); it('should return not found if the the requested file does not exists', (done) => { - request + void request .get('/custom-sounds/invalid.mp3') .set(credentials) .expect(404) @@ -119,7 +117,7 @@ describe('[CustomSounds]', function () { }); it('should return success if the the requested exists', (done) => { - request + void request .get(`/custom-sounds/${fileId}.wav`) .set(credentials) .expect(200) @@ -134,7 +132,7 @@ describe('[CustomSounds]', function () { }); it('should return not modified if the the requested file contains a valid-since equal to the upload date', (done) => { - request + void request .get(`/custom-sounds/${fileId}.wav`) .set(credentials) .set({ diff --git a/apps/meteor/tests/end-to-end/api/17-custom-user-status.js b/apps/meteor/tests/end-to-end/api/17-custom-user-status.ts similarity index 91% rename from apps/meteor/tests/end-to-end/api/17-custom-user-status.js rename to apps/meteor/tests/end-to-end/api/17-custom-user-status.ts index 711d037a9b98..c1ecd185dae8 100644 --- a/apps/meteor/tests/end-to-end/api/17-custom-user-status.js +++ b/apps/meteor/tests/end-to-end/api/17-custom-user-status.ts @@ -1,16 +1,14 @@ import { expect } from 'chai'; import { before, describe, it } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; - -describe('[CustomUserStatus]', function () { - this.retries(0); +import { getCredentials, api, request, credentials } from '../../data/api-data'; +describe('[CustomUserStatus]', () => { before((done) => getCredentials(done)); describe('[/custom-user-status.list]', () => { it('should return custom user status', (done) => { - request + void request .get(api('custom-user-status.list')) .set(credentials) .expect(200) @@ -23,7 +21,7 @@ describe('[CustomUserStatus]', function () { .end(done); }); it('should return custom user status even requested with count and offset params', (done) => { - request + void request .get(api('custom-user-status.list')) .set(credentials) .expect(200) diff --git a/apps/meteor/tests/end-to-end/api/17-webdav.js b/apps/meteor/tests/end-to-end/api/17-webdav.ts similarity index 92% rename from apps/meteor/tests/end-to-end/api/17-webdav.js rename to apps/meteor/tests/end-to-end/api/17-webdav.ts index c4348d6112f1..1dc2957fd6ba 100644 --- a/apps/meteor/tests/end-to-end/api/17-webdav.js +++ b/apps/meteor/tests/end-to-end/api/17-webdav.ts @@ -1,16 +1,14 @@ import { expect } from 'chai'; import { before, describe, it } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; - -describe('[Webdav]', function () { - this.retries(0); +import { getCredentials, api, request, credentials } from '../../data/api-data'; +describe('[Webdav]', () => { before((done) => getCredentials(done)); describe('/webdav.getMyAccounts', () => { it('should return my webdav accounts', (done) => { - request + void request .get(api('webdav.getMyAccounts')) .set(credentials) .expect(200) @@ -24,7 +22,7 @@ describe('[Webdav]', function () { describe('/webdav.removeWebdavAccount', () => { it('should return an error when send an invalid request', (done) => { - request + void request .post(api('webdav.removeWebdavAccount')) .set(credentials) .send({}) @@ -36,7 +34,7 @@ describe('[Webdav]', function () { .end(done); }); it('should return an error when using an invalid account id', (done) => { - request + void request .post(api('webdav.removeWebdavAccount')) .set(credentials) .send({ diff --git a/apps/meteor/tests/end-to-end/api/18-oauthapps.js b/apps/meteor/tests/end-to-end/api/18-oauthapps.ts similarity index 88% rename from apps/meteor/tests/end-to-end/api/18-oauthapps.js rename to apps/meteor/tests/end-to-end/api/18-oauthapps.ts index 4566dab47967..7bffa3297bfc 100644 --- a/apps/meteor/tests/end-to-end/api/18-oauthapps.js +++ b/apps/meteor/tests/end-to-end/api/18-oauthapps.ts @@ -1,12 +1,12 @@ +import type { IOAuthApps } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { before, describe, it, after } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { updatePermission } from '../../data/permissions.helper'; -describe('[OAuthApps]', function () { - const createdAppsIds = []; - this.retries(0); +describe('[OAuthApps]', () => { + const createdAppsIds: IOAuthApps['_id'][] = []; before((done) => getCredentials(done)); @@ -23,8 +23,8 @@ describe('[OAuthApps]', function () { describe('[/oauth-apps.list]', () => { it('should return an error when the user does not have the necessary permission', (done) => { - updatePermission('manage-oauth-apps', []).then(() => { - request + void updatePermission('manage-oauth-apps', []).then(() => { + void request .get(api('oauth-apps.list')) .set(credentials) .expect(400) @@ -36,8 +36,8 @@ describe('[OAuthApps]', function () { }); }); it('should return an array of oauth apps', (done) => { - updatePermission('manage-oauth-apps', ['admin']).then(() => { - request + void updatePermission('manage-oauth-apps', ['admin']).then(() => { + void request .get(api('oauth-apps.list')) .set(credentials) .expect(200) @@ -52,8 +52,9 @@ describe('[OAuthApps]', function () { describe('[/oauth-apps.get]', () => { it('should return a single oauthApp by id', (done) => { - request - .get(api('oauth-apps.get?appId=zapier')) + void request + .get(api('oauth-apps.get')) + .query({ appId: 'zapier' }) .set(credentials) .expect(200) .expect((res) => { @@ -64,8 +65,9 @@ describe('[OAuthApps]', function () { .end(done); }); it('should return a single oauthApp by client id', (done) => { - request - .get(api('oauth-apps.get?clientId=zapier')) + void request + .get(api('oauth-apps.get')) + .query({ clientId: 'zapier' }) .set(credentials) .expect(200) .expect((res) => { @@ -76,9 +78,10 @@ describe('[OAuthApps]', function () { .end(done); }); it('should return a 403 Forbidden error when the user does not have the necessary permission by client id', (done) => { - updatePermission('manage-oauth-apps', []).then(() => { - request - .get(api('oauth-apps.get?clientId=zapier')) + void updatePermission('manage-oauth-apps', []).then(() => { + void request + .get(api('oauth-apps.get')) + .query({ clientId: 'zapier' }) .set(credentials) .expect(403) .expect((res) => { @@ -89,9 +92,10 @@ describe('[OAuthApps]', function () { }); }); it('should return a 403 Forbidden error when the user does not have the necessary permission by app id', (done) => { - updatePermission('manage-oauth-apps', []).then(() => { - request - .get(api('oauth-apps.get?appId=zapier')) + void updatePermission('manage-oauth-apps', []).then(() => { + void request + .get(api('oauth-apps.get')) + .query({ appId: 'zapier' }) .set(credentials) .expect(403) .expect((res) => { @@ -197,13 +201,13 @@ describe('[OAuthApps]', function () { }); describe('[/oauth-apps.update]', () => { - let appId; + let appId: IOAuthApps['_id']; before((done) => { const name = 'test-oauth-app'; const redirectUri = 'https://test.com'; const active = true; - request + void request .post(api('oauth-apps.create')) .set(credentials) .send({ @@ -213,7 +217,7 @@ describe('[OAuthApps]', function () { }) .expect('Content-Type', 'application/json') .expect(200) - .end((err, res) => { + .end((_err, res) => { appId = res.body.application._id; createdAppsIds.push(appId); done(); @@ -246,13 +250,13 @@ describe('[OAuthApps]', function () { }); describe('[/oauth-apps.delete]', () => { - let appId; + let appId: IOAuthApps['_id']; before((done) => { const name = 'test-oauth-app'; const redirectUri = 'https://test.com'; const active = true; - request + void request .post(api('oauth-apps.create')) .set(credentials) .send({ @@ -262,7 +266,7 @@ describe('[OAuthApps]', function () { }) .expect('Content-Type', 'application/json') .expect(200) - .end((err, res) => { + .end((_err, res) => { appId = res.body.application._id; done(); }); diff --git a/apps/meteor/tests/end-to-end/api/19-statistics.js b/apps/meteor/tests/end-to-end/api/19-statistics.ts similarity index 84% rename from apps/meteor/tests/end-to-end/api/19-statistics.js rename to apps/meteor/tests/end-to-end/api/19-statistics.ts index 4e1f0d8b0148..c10eff929807 100644 --- a/apps/meteor/tests/end-to-end/api/19-statistics.js +++ b/apps/meteor/tests/end-to-end/api/19-statistics.ts @@ -1,21 +1,19 @@ import { expect } from 'chai'; import { before, describe, it, after } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { updatePermission } from '../../data/permissions.helper'; -describe('[Statistics]', function () { - this.retries(0); - +describe('[Statistics]', () => { before((done) => getCredentials(done)); after(() => updatePermission('view-statistics', ['admin'])); describe('[/statistics]', () => { - let lastUptime; + let lastUptime: unknown; it('should return an error when the user does not have the necessary permission', (done) => { - updatePermission('view-statistics', []).then(() => { - request + void updatePermission('view-statistics', []).then(() => { + void request .get(api('statistics')) .set(credentials) .expect(400) @@ -27,8 +25,8 @@ describe('[Statistics]', function () { }); }); it('should return an object with the statistics', (done) => { - updatePermission('view-statistics', ['admin']).then(() => { - request + void updatePermission('view-statistics', ['admin']).then(() => { + void request .get(api('statistics')) .set(credentials) .expect(200) @@ -42,8 +40,9 @@ describe('[Statistics]', function () { }); }); it('should update the statistics when is provided the "refresh:true" query parameter', (done) => { - request - .get(api('statistics?refresh=true')) + void request + .get(api('statistics')) + .query({ refresh: 'true' }) .set(credentials) .expect(200) .expect((res) => { @@ -58,8 +57,8 @@ describe('[Statistics]', function () { describe('[/statistics.list]', () => { it('should return an error when the user does not have the necessary permission', (done) => { - updatePermission('view-statistics', []).then(() => { - request + void updatePermission('view-statistics', []).then(() => { + void request .get(api('statistics.list')) .set(credentials) .expect(400) @@ -71,8 +70,8 @@ describe('[Statistics]', function () { }); }); it('should return an array with the statistics', (done) => { - updatePermission('view-statistics', ['admin']).then(() => { - request + void updatePermission('view-statistics', ['admin']).then(() => { + void request .get(api('statistics.list')) .set(credentials) .expect(200) @@ -87,8 +86,8 @@ describe('[Statistics]', function () { }); }); it('should return an array with the statistics even requested with count and offset params', (done) => { - updatePermission('view-statistics', ['admin']).then(() => { - request + void updatePermission('view-statistics', ['admin']).then(() => { + void request .get(api('statistics.list')) .set(credentials) .query({ diff --git a/apps/meteor/tests/end-to-end/api/20-licenses.js b/apps/meteor/tests/end-to-end/api/20-licenses.ts similarity index 91% rename from apps/meteor/tests/end-to-end/api/20-licenses.js rename to apps/meteor/tests/end-to-end/api/20-licenses.ts index 83867712a80d..7792d497fe1b 100644 --- a/apps/meteor/tests/end-to-end/api/20-licenses.js +++ b/apps/meteor/tests/end-to-end/api/20-licenses.ts @@ -1,16 +1,18 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { before, describe, it, after } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { password } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; import { createUser, deleteUser, login } from '../../data/users.helper'; -describe('licenses', function () { - let createdUser; - this.retries(0); +describe('licenses', () => { + let createdUser: TestUser; before((done) => getCredentials(done)); - let unauthorizedUserCredentials; + let unauthorizedUserCredentials: Credentials; before(async () => { createdUser = await createUser(); @@ -21,7 +23,7 @@ describe('licenses', function () { describe('[/licenses.add]', () => { it('should fail if not logged in', (done) => { - request + void request .post(api('licenses.add')) .send({ license: '', @@ -36,7 +38,7 @@ describe('licenses', function () { }); it('should fail if user is unauthorized', (done) => { - request + void request .post(api('licenses.add')) .set(unauthorizedUserCredentials) .send({ @@ -52,7 +54,7 @@ describe('licenses', function () { }); it('should fail if license is invalid', (done) => { - request + void request .post(api('licenses.add')) .set(credentials) .send({ @@ -70,7 +72,7 @@ describe('licenses', function () { describe('[/licenses.get]', () => { it('should fail if not logged in', (done) => { - request + void request .get(api('licenses.get')) .expect('Content-Type', 'application/json') .expect(401) @@ -82,7 +84,7 @@ describe('licenses', function () { }); it('should fail if user is unauthorized', (done) => { - request + void request .get(api('licenses.get')) .set(unauthorizedUserCredentials) .expect('Content-Type', 'application/json') @@ -95,7 +97,7 @@ describe('licenses', function () { }); it('should return licenses if user is logged in and is authorized', (done) => { - request + void request .get(api('licenses.get')) .set(credentials) .expect(200) @@ -110,7 +112,7 @@ describe('licenses', function () { describe('[/licenses.info]', () => { it('should fail if not logged in', (done) => { - request + void request .get(api('licenses.info')) .expect('Content-Type', 'application/json') .expect(401) @@ -122,7 +124,7 @@ describe('licenses', function () { }); it('should return limited information if user is unauthorized', (done) => { - request + void request .get(api('licenses.info')) .set(unauthorizedUserCredentials) .expect('Content-Type', 'application/json') @@ -137,7 +139,7 @@ describe('licenses', function () { }); it('should return unrestricted info if user is logged in and is authorized', (done) => { - request + void request .get(api('licenses.info')) .set(credentials) .expect(200) @@ -156,7 +158,7 @@ describe('licenses', function () { describe('[/licenses.isEnterprise]', () => { it('should fail if not logged in', (done) => { - request + void request .get(api('licenses.isEnterprise')) .expect('Content-Type', 'application/json') .expect(401) @@ -168,7 +170,7 @@ describe('licenses', function () { }); it('should pass if user has user role', (done) => { - request + void request .get(api('licenses.isEnterprise')) .set(unauthorizedUserCredentials) .expect('Content-Type', 'application/json') @@ -180,7 +182,7 @@ describe('licenses', function () { }); it('should pass if user has admin role', (done) => { - request + void request .get(api('licenses.isEnterprise')) .set(credentials) .expect('Content-Type', 'application/json') diff --git a/apps/meteor/tests/end-to-end/api/21-banners.js b/apps/meteor/tests/end-to-end/api/21-banners.ts similarity index 94% rename from apps/meteor/tests/end-to-end/api/21-banners.js rename to apps/meteor/tests/end-to-end/api/21-banners.ts index c206901d57eb..a4fd2638e7dd 100644 --- a/apps/meteor/tests/end-to-end/api/21-banners.js +++ b/apps/meteor/tests/end-to-end/api/21-banners.ts @@ -1,16 +1,14 @@ import { expect } from 'chai'; import { before, describe, it } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; - -describe('banners', function () { - this.retries(0); +import { getCredentials, api, request, credentials } from '../../data/api-data'; +describe('banners', () => { before((done) => getCredentials(done)); describe('[/banners.getNew]', () => { it('should fail if not logged in', (done) => { - request + void request .get(api('banners.getNew')) .query({ platform: 'web', @@ -24,7 +22,7 @@ describe('banners', function () { }); it('should fail if missing platform key', (done) => { - request + void request .get(api('banners.getNew')) .set(credentials) .expect(400) @@ -35,7 +33,7 @@ describe('banners', function () { }); it('should fail if platform param is unknown', (done) => { - request + void request .get(api('banners.getNew')) .set(credentials) .query({ @@ -49,7 +47,7 @@ describe('banners', function () { }); it('should fail if platform param is empty', (done) => { - request + void request .get(api('banners.getNew')) .set(credentials) .query({ @@ -63,7 +61,7 @@ describe('banners', function () { }); it('should return banners if platform param is valid', (done) => { - request + void request .get(api('banners.getNew')) .set(credentials) .query({ @@ -80,7 +78,7 @@ describe('banners', function () { describe('[/banners.dismiss]', () => { it('should fail if not logged in', (done) => { - request + void request .post(api('banners.dismiss')) .send({ bannerId: '123', @@ -94,7 +92,7 @@ describe('banners', function () { }); it('should fail if missing bannerId key', (done) => { - request + void request .post(api('banners.dismiss')) .set(credentials) .send({}) @@ -107,7 +105,7 @@ describe('banners', function () { }); it('should fail if missing bannerId is empty', (done) => { - request + void request .post(api('banners.dismiss')) .set(credentials) .send({ @@ -121,7 +119,7 @@ describe('banners', function () { }); it('should fail if missing bannerId is invalid', (done) => { - request + void request .post(api('banners.dismiss')) .set(credentials) .send({ diff --git a/apps/meteor/tests/end-to-end/api/22-push.ts b/apps/meteor/tests/end-to-end/api/22-push.ts index 7035260816d9..f496d0dfe9e9 100644 --- a/apps/meteor/tests/end-to-end/api/22-push.ts +++ b/apps/meteor/tests/end-to-end/api/22-push.ts @@ -1,12 +1,10 @@ import { expect } from 'chai'; import { before, describe, it, after } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { updateSetting } from '../../data/permissions.helper'; -describe('[Push]', function () { - this.retries(0); - +describe('[Push]', () => { before((done) => getCredentials(done)); describe('POST [/push.token]', () => { diff --git a/apps/meteor/tests/end-to-end/api/23-invites.js b/apps/meteor/tests/end-to-end/api/23-invites.ts similarity index 93% rename from apps/meteor/tests/end-to-end/api/23-invites.js rename to apps/meteor/tests/end-to-end/api/23-invites.ts index ef6238f4fc73..85f0771f67d1 100644 --- a/apps/meteor/tests/end-to-end/api/23-invites.js +++ b/apps/meteor/tests/end-to-end/api/23-invites.ts @@ -1,16 +1,16 @@ +import type { IInvite } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { before, describe, it } from 'mocha'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; -describe('Invites', function () { - let testInviteID; - this.retries(0); +describe('Invites', () => { + let testInviteID: IInvite['_id']; before((done) => getCredentials(done)); describe('POST [/findOrCreateInvite]', () => { it('should fail if not logged in', (done) => { - request + void request .post(api('findOrCreateInvite')) .send({ rid: 'GENERAL', @@ -26,7 +26,7 @@ describe('Invites', function () { }); it('should fail if invalid roomid', (done) => { - request + void request .post(api('findOrCreateInvite')) .set(credentials) .send({ @@ -43,7 +43,7 @@ describe('Invites', function () { }); it('should create an invite for GENERAL', (done) => { - request + void request .post(api('findOrCreateInvite')) .set(credentials) .send({ @@ -64,7 +64,7 @@ describe('Invites', function () { }); it('should return an existing invite for GENERAL', (done) => { - request + void request .post(api('findOrCreateInvite')) .set(credentials) .send({ @@ -86,7 +86,7 @@ describe('Invites', function () { describe('GET [/listInvites]', () => { it('should fail if not logged in', (done) => { - request + void request .get(api('listInvites')) .expect(401) .expect((res) => { @@ -97,7 +97,7 @@ describe('Invites', function () { }); it('should return the existing invite for GENERAL', (done) => { - request + void request .get(api('listInvites')) .set(credentials) .expect(200) @@ -110,7 +110,7 @@ describe('Invites', function () { describe('POST [/useInviteToken]', () => { it('should fail if not logged in', (done) => { - request + void request .post(api('useInviteToken')) .expect(401) .expect((res) => { @@ -121,7 +121,7 @@ describe('Invites', function () { }); it('should fail if invalid token', (done) => { - request + void request .post(api('useInviteToken')) .set(credentials) .send({ @@ -136,7 +136,7 @@ describe('Invites', function () { }); it('should fail if missing token', (done) => { - request + void request .post(api('useInviteToken')) .set(credentials) .send({}) @@ -149,7 +149,7 @@ describe('Invites', function () { }); it('should use the existing invite for GENERAL', (done) => { - request + void request .post(api('useInviteToken')) .set(credentials) .send({ @@ -165,7 +165,7 @@ describe('Invites', function () { describe('POST [/validateInviteToken]', () => { it('should warn if invalid token', (done) => { - request + void request .post(api('validateInviteToken')) .set(credentials) .send({ @@ -180,7 +180,7 @@ describe('Invites', function () { }); it('should succeed when valid token', (done) => { - request + void request .post(api('validateInviteToken')) .set(credentials) .send({ @@ -197,7 +197,7 @@ describe('Invites', function () { describe('DELETE [/removeInvite]', () => { it('should fail if not logged in', (done) => { - request + void request .delete(api(`removeInvite/${testInviteID}`)) .expect(401) .expect((res) => { @@ -208,7 +208,7 @@ describe('Invites', function () { }); it('should fail if invalid token', (done) => { - request + void request .delete(api('removeInvite/invalid')) .set(credentials) .expect(400) @@ -220,7 +220,7 @@ describe('Invites', function () { }); it('should succeed when valid token', (done) => { - request + void request .delete(api(`removeInvite/${testInviteID}`)) .set(credentials) .expect(200) @@ -231,7 +231,7 @@ describe('Invites', function () { }); it('should fail when deleting the same invite again', (done) => { - request + void request .delete(api(`removeInvite/${testInviteID}`)) .set(credentials) .expect(400) diff --git a/apps/meteor/tests/end-to-end/api/24-methods.js b/apps/meteor/tests/end-to-end/api/24-methods.ts similarity index 95% rename from apps/meteor/tests/end-to-end/api/24-methods.js rename to apps/meteor/tests/end-to-end/api/24-methods.ts index dc1d506f1317..d03b83854b28 100644 --- a/apps/meteor/tests/end-to-end/api/24-methods.js +++ b/apps/meteor/tests/end-to-end/api/24-methods.ts @@ -1,29 +1,30 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IMessage, IRoom, IThreadMessage, IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, beforeEach, describe, it } from 'mocha'; -import { api, credentials, getCredentials, methodCall, request } from '../../data/api-data.js'; -import { sendSimpleMessage } from '../../data/chat.helper.js'; +import { api, credentials, getCredentials, methodCall, request } from '../../data/api-data'; +import { sendSimpleMessage } from '../../data/chat.helper'; import { CI_MAX_ROOMS_PER_GUEST as maxRoomsPerGuest } from '../../data/constants'; import { updatePermission, updateSetting } from '../../data/permissions.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { password } from '../../data/user'; -import { createUser, deleteUser, login } from '../../data/users.helper.js'; +import type { TestUser } from '../../data/users.helper'; +import { createUser, deleteUser, login } from '../../data/users.helper'; import { IS_EE } from '../../e2e/config/constants'; -describe('Meteor.methods', function () { - this.retries(0); - +describe('Meteor.methods', () => { before((done) => getCredentials(done)); describe('[@getThreadMessages]', () => { - let rid = false; - let firstMessage = false; + let rid: IRoom['_id']; + let firstMessage: IMessage; - let channelName = false; + let channelName: string; before('create room', (done) => { channelName = `methods-test-channel-${Date.now()}`; - request + void request .post(api('groups.create')) .set(credentials) .send({ @@ -43,7 +44,7 @@ describe('Meteor.methods', function () { }); before('send sample message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -62,7 +63,7 @@ describe('Meteor.methods', function () { }); before('send sample message into thread', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -83,7 +84,7 @@ describe('Meteor.methods', function () { after(() => deleteRoom({ type: 'p', roomId: rid })); it('should fail if not logged in', (done) => { - request + void request .post(methodCall('getThreadMessages')) .send({ message: JSON.stringify({ @@ -103,7 +104,7 @@ describe('Meteor.methods', function () { }); it('should return message thread', (done) => { - request + void request .post(methodCall('getThreadMessages')) .set(credentials) .send({ @@ -174,11 +175,11 @@ describe('Meteor.methods', function () { }); (IS_EE ? describe : describe.skip)('[@getReadReceipts] EE', () => { - let user = null; - let userCredentials = null; - let room = null; - let firstMessage = null; - let firstThreadMessage = null; + let user: TestUser; + let userCredentials: Credentials; + let room: IRoom; + let firstMessage: IMessage; + let firstThreadMessage: IThreadMessage; const roomName = `methods-test-channel-${Date.now()}`; before(async () => { @@ -368,8 +369,8 @@ describe('Meteor.methods', function () { }); describe('simple message and thread marked as read by the invited user', () => { - let otherMessage = null; - let otherThreadMessage = null; + let otherMessage: IMessage; + let otherThreadMessage: IThreadMessage; before('should send another message and create a thread', async () => { otherMessage = (await sendSimpleMessage({ roomId: room._id })).body.message; @@ -448,15 +449,15 @@ describe('Meteor.methods', function () { }); describe('[@getMessages]', () => { - let rid = false; - let firstMessage = false; - let lastMessage = false; + let rid: IRoom['_id']; + let firstMessage: IMessage; + let lastMessage: IMessage; - let channelName = false; + let channelName: string; before('create room', (done) => { channelName = `methods-test-channel-${Date.now()}`; - request + void request .post(api('groups.create')) .set(credentials) .send({ @@ -476,7 +477,7 @@ describe('Meteor.methods', function () { }); before('send sample message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -495,7 +496,7 @@ describe('Meteor.methods', function () { }); before('send another sample message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -516,7 +517,7 @@ describe('Meteor.methods', function () { after(() => deleteRoom({ type: 'p', roomId: rid })); it('should fail if not logged in', (done) => { - request + void request .post(methodCall('getMessages')) .send({ message: JSON.stringify({ @@ -536,7 +537,7 @@ describe('Meteor.methods', function () { }); it('should fail if msgIds not specified', (done) => { - request + void request .post(methodCall('getMessages')) .set(credentials) .send({ @@ -562,7 +563,7 @@ describe('Meteor.methods', function () { }); it('should return the first message', (done) => { - request + void request .post(methodCall('getMessages')) .set(credentials) .send({ @@ -587,7 +588,7 @@ describe('Meteor.methods', function () { }); it('should return both messages', (done) => { - request + void request .post(methodCall('getMessages')) .set(credentials) .send({ @@ -613,13 +614,13 @@ describe('Meteor.methods', function () { }); describe('[@cleanRoomHistory]', () => { - let rid = false; + let rid: IRoom['_id']; - let channelName = false; + let channelName: string; before('create room', (done) => { channelName = `methods-test-channel-${Date.now()}`; - request + void request .post(api('groups.create')) .set(credentials) .send({ @@ -639,7 +640,7 @@ describe('Meteor.methods', function () { }); before('send sample message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -657,7 +658,7 @@ describe('Meteor.methods', function () { }); before('send another sample message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -736,15 +737,15 @@ describe('Meteor.methods', function () { }); describe('[@loadHistory]', () => { - let rid = false; - let postMessageDate = false; - let lastMessage = false; + let rid: IRoom['_id']; + let postMessageDate: unknown; + let lastMessage: IMessage; - let channelName = false; + let channelName: string; before('create room', (done) => { channelName = `methods-test-channel-${Date.now()}`; - request + void request .post(api('groups.create')) .set(credentials) .send({ @@ -764,7 +765,7 @@ describe('Meteor.methods', function () { }); before('send sample message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -783,7 +784,7 @@ describe('Meteor.methods', function () { }); before('send another sample message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -804,7 +805,7 @@ describe('Meteor.methods', function () { after(() => deleteRoom({ type: 'p', roomId: rid })); it('should fail if not logged in', (done) => { - request + void request .post(methodCall('loadHistory')) .send({ message: JSON.stringify({ @@ -824,7 +825,7 @@ describe('Meteor.methods', function () { }); it('should fail if roomId not specified', (done) => { - request + void request .post(methodCall('loadHistory')) .set(credentials) .send({ @@ -850,7 +851,7 @@ describe('Meteor.methods', function () { }); it('should return all messages for the specified room', (done) => { - request + void request .post(methodCall('loadHistory')) .set(credentials) .send({ @@ -876,7 +877,7 @@ describe('Meteor.methods', function () { }); it('should return only the first message', (done) => { - request + void request .post(methodCall('loadHistory')) .set(credentials) .send({ @@ -902,7 +903,7 @@ describe('Meteor.methods', function () { }); it('should return only one message when limit = 1', (done) => { - request + void request .post(methodCall('loadHistory')) .set(credentials) .send({ @@ -928,7 +929,7 @@ describe('Meteor.methods', function () { }); it('should return the messages since the last one', (done) => { - request + void request .post(methodCall('loadHistory')) .set(credentials) .send({ @@ -955,15 +956,15 @@ describe('Meteor.methods', function () { }); describe('[@loadNextMessages]', () => { - let rid = false; - let postMessageDate = false; + let rid: IRoom['_id']; + let postMessageDate: unknown; const startDate = { $date: new Date().getTime() }; - let channelName = false; + let channelName: string; before('create room', (done) => { channelName = `methods-test-channel-${Date.now()}`; - request + void request .post(api('groups.create')) .set(credentials) .send({ @@ -983,7 +984,7 @@ describe('Meteor.methods', function () { }); before('send sample message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -1002,7 +1003,7 @@ describe('Meteor.methods', function () { }); before('send another sample message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -1022,7 +1023,7 @@ describe('Meteor.methods', function () { after(() => deleteRoom({ type: 'p', roomId: rid })); it('should fail if not logged in', (done) => { - request + void request .post(methodCall('loadNextMessages')) .send({ message: JSON.stringify({ @@ -1042,7 +1043,7 @@ describe('Meteor.methods', function () { }); it('should fail if roomId not specified', (done) => { - request + void request .post(methodCall('loadNextMessages')) .set(credentials) .send({ @@ -1068,7 +1069,7 @@ describe('Meteor.methods', function () { }); it('should return all messages for the specified room', (done) => { - request + void request .post(methodCall('loadNextMessages')) .set(credentials) .send({ @@ -1094,7 +1095,7 @@ describe('Meteor.methods', function () { }); it('should return only the latest message', (done) => { - request + void request .post(methodCall('loadNextMessages')) .set(credentials) .send({ @@ -1120,7 +1121,7 @@ describe('Meteor.methods', function () { }); it('should return only one message when limit = 1', (done) => { - request + void request .post(methodCall('loadNextMessages')) .set(credentials) .send({ @@ -1147,14 +1148,14 @@ describe('Meteor.methods', function () { }); describe('[@getUsersOfRoom]', () => { - let testUser; - let rid = false; + let testUser: TestUser; + let rid: IRoom['_id']; - let channelName = false; + let channelName: string; before('create room', (done) => { channelName = `methods-test-channel-${Date.now()}`; - request + void request .post(api('groups.create')) .set(credentials) .send({ @@ -1176,18 +1177,18 @@ describe('Meteor.methods', function () { before('create test user', (done) => { const username = `user.test.${Date.now()}`; const email = `${username}@rocket.chat`; - request + void request .post(api('users.create')) .set(credentials) .send({ email, name: username, username, password: username }) - .end((err, res) => { + .end((_err, res) => { testUser = res.body.user; done(); }); }); before('add user to room', (done) => { - request + void request .post(api('groups.invite')) .set(credentials) .send({ @@ -1202,7 +1203,7 @@ describe('Meteor.methods', function () { after(() => Promise.all([deleteRoom({ type: 'p', roomId: rid }), deleteUser(testUser)])); it('should fail if not logged in', (done) => { - request + void request .post(methodCall('getUsersOfRoom')) .send({ message: JSON.stringify({ @@ -1222,7 +1223,7 @@ describe('Meteor.methods', function () { }); it('should fail if roomId not specified', (done) => { - request + void request .post(methodCall('getUsersOfRoom')) .set(credentials) .send({ @@ -1247,7 +1248,7 @@ describe('Meteor.methods', function () { }); it('should return the users for the specified room', (done) => { - request + void request .post(methodCall('getUsersOfRoom')) .set(credentials) .send({ @@ -1274,7 +1275,7 @@ describe('Meteor.methods', function () { describe('[@getUserRoles]', () => { it('should fail if not logged in', (done) => { - request + void request .post(methodCall('getUserRoles')) .send({ message: JSON.stringify({ @@ -1294,7 +1295,7 @@ describe('Meteor.methods', function () { }); it('should return the roles for the current user', (done) => { - request + void request .post(methodCall('getUserRoles')) .set(credentials) .send({ @@ -1320,7 +1321,7 @@ describe('Meteor.methods', function () { describe('[@listCustomUserStatus]', () => { it('should fail if not logged in', (done) => { - request + void request .post(methodCall('listCustomUserStatus')) .send({ message: JSON.stringify({ @@ -1340,7 +1341,7 @@ describe('Meteor.methods', function () { }); it('should return custom status for the current user', (done) => { - request + void request .post(methodCall('listCustomUserStatus')) .set(credentials) .send({ @@ -1370,7 +1371,7 @@ describe('Meteor.methods', function () { }; it('should fail if not logged in', (done) => { - request + void request .post(methodCall('permissions:get')) .send({ message: JSON.stringify({ @@ -1390,7 +1391,7 @@ describe('Meteor.methods', function () { }); it('should return all permissions', (done) => { - request + void request .post(methodCall('permissions:get')) .set(credentials) .send({ @@ -1415,7 +1416,7 @@ describe('Meteor.methods', function () { }); it('should return all permissions after the given date', (done) => { - request + void request .post(methodCall('permissions:get')) .set(credentials) .send({ @@ -1441,16 +1442,16 @@ describe('Meteor.methods', function () { }); describe('[@loadMissedMessages]', () => { - let rid = false; + let rid: IRoom['_id']; const date = { $date: new Date().getTime(), }; - let postMessageDate = false; + let postMessageDate: unknown; const channelName = `methods-test-channel-${Date.now()}`; before('create test group', (done) => { - request + void request .post(api('groups.create')) .set(credentials) .send({ @@ -1470,7 +1471,7 @@ describe('Meteor.methods', function () { }); before('send sample message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -1489,7 +1490,7 @@ describe('Meteor.methods', function () { }); before('send another sample message', (done) => { - request + void request .post(api('chat.sendMessage')) .set(credentials) .send({ @@ -1509,7 +1510,7 @@ describe('Meteor.methods', function () { after(() => deleteRoom({ type: 'p', roomId: rid })); it('should fail if not logged in', (done) => { - request + void request .post(methodCall('loadMissedMessages')) .send({ message: JSON.stringify({ @@ -1529,7 +1530,7 @@ describe('Meteor.methods', function () { }); it('should return an error if the rid param is empty', (done) => { - request + void request .post(methodCall('loadMissedMessages')) .set(credentials) .send({ @@ -1550,7 +1551,7 @@ describe('Meteor.methods', function () { }); it('should return an error if the start param is missing', (done) => { - request + void request .post(methodCall('loadMissedMessages')) .set(credentials) .send({ @@ -1571,7 +1572,7 @@ describe('Meteor.methods', function () { }); it('should return and empty list if using current time', (done) => { - request + void request .post(methodCall('loadMissedMessages')) .set(credentials) .send({ @@ -1596,7 +1597,7 @@ describe('Meteor.methods', function () { }); it('should return two messages if using a time from before the first msg was sent', (done) => { - request + void request .post(methodCall('loadMissedMessages')) .set(credentials) .send({ @@ -1621,7 +1622,7 @@ describe('Meteor.methods', function () { }); it('should return a single message if using a time from in between the messages', (done) => { - request + void request .post(methodCall('loadMissedMessages')) .set(credentials) .send({ @@ -1652,7 +1653,7 @@ describe('Meteor.methods', function () { }; it('should fail if not logged in', (done) => { - request + void request .post(methodCall('public-settings:get')) .send({ message: JSON.stringify({ @@ -1672,7 +1673,7 @@ describe('Meteor.methods', function () { }); it('should return the list of public settings', (done) => { - request + void request .post(methodCall('public-settings:get')) .set(credentials) .send({ @@ -1710,7 +1711,7 @@ describe('Meteor.methods', function () { ); it('should fail if not logged in', (done) => { - request + void request .post(methodCall('private-settings:get')) .send({ message: JSON.stringify({ @@ -1730,11 +1731,11 @@ describe('Meteor.methods', function () { }); it('should return nothing when user doesnt have any permission', (done) => { - updatePermission('view-privileged-setting', []) - .then(updatePermission('edit-privileged-setting', [])) - .then(updatePermission('manage-selected-settings', [])) + void updatePermission('view-privileged-setting', []) + .then(() => updatePermission('edit-privileged-setting', [])) + .then(() => updatePermission('manage-selected-settings', [])) .then(() => { - request + void request .post(methodCall('private-settings:get')) .set(credentials) .send({ @@ -1760,8 +1761,8 @@ describe('Meteor.methods', function () { }); it('should return properties when user has any related permissions', (done) => { - updatePermission('view-privileged-setting', ['admin']).then(() => { - request + void updatePermission('view-privileged-setting', ['admin']).then(() => { + void request .post(methodCall('private-settings:get')) .set(credentials) .send({ @@ -1788,11 +1789,11 @@ describe('Meteor.methods', function () { }); it('should return properties when user has all related permissions', (done) => { - updatePermission('view-privileged-setting', ['admin']) - .then(updatePermission('edit-privileged-setting', ['admin'])) - .then(updatePermission('manage-selected-settings', ['admin'])) + void updatePermission('view-privileged-setting', ['admin']) + .then(() => updatePermission('edit-privileged-setting', ['admin'])) + .then(() => updatePermission('manage-selected-settings', ['admin'])) .then(() => { - request + void request .post(methodCall('private-settings:get')) .set(credentials) .send({ @@ -1825,7 +1826,7 @@ describe('Meteor.methods', function () { }; it('should fail if not logged in', (done) => { - request + void request .post(methodCall('subscriptions:get')) .send({ message: JSON.stringify({ @@ -1845,7 +1846,7 @@ describe('Meteor.methods', function () { }); it('should return all subscriptions', (done) => { - request + void request .post(methodCall('subscriptions:get')) .set(credentials) .send({ @@ -1870,7 +1871,7 @@ describe('Meteor.methods', function () { }); it('should return all subscriptions after the given date', (done) => { - request + void request .post(methodCall('subscriptions:get')) .set(credentials) .send({ @@ -1896,12 +1897,12 @@ describe('Meteor.methods', function () { }); describe('[@sendMessage]', () => { - let rid = false; - let channelName = false; + let rid: IRoom['_id']; + let channelName: string; before('create room', (done) => { channelName = `methods-test-channel-${Date.now()}`; - request + void request .post(api('groups.create')) .set(credentials) .send({ @@ -1923,7 +1924,7 @@ describe('Meteor.methods', function () { after(() => deleteRoom({ type: 'p', roomId: rid })); it('should send a message', (done) => { - request + void request .post(methodCall('sendMessage')) .set(credentials) .send({ @@ -1948,7 +1949,7 @@ describe('Meteor.methods', function () { }); it('should parse correctly urls sent in message', (done) => { - request + void request .post(methodCall('sendMessage')) .set(credentials) .send({ @@ -1981,17 +1982,17 @@ describe('Meteor.methods', function () { }); describe('[@updateMessage]', () => { - let rid = false; - let roomName = false; - let messageId; - let simpleMessageId; - let messageWithMarkdownId; - let channelName = false; + let rid: IRoom['_id']; + let roomName: string; + let messageId: IMessage['_id']; + let simpleMessageId: IMessage['_id']; + let messageWithMarkdownId: IMessage['_id']; + let channelName: string; const siteUrl = process.env.SITE_URL || process.env.TEST_API_URL || 'http://localhost:3000'; before('create room', (done) => { channelName = `methods-test-channel-${Date.now()}`; - request + void request .post(api('groups.create')) .set(credentials) .send({ @@ -2017,7 +2018,7 @@ describe('Meteor.methods', function () { }); before('send message with URL', (done) => { - request + void request .post(methodCall('sendMessage')) .set(credentials) .send({ @@ -2050,7 +2051,7 @@ describe('Meteor.methods', function () { }); before('send message with URL inside markdown', (done) => { - request + void request .post(methodCall('sendMessage')) .set(credentials) .send({ @@ -2089,7 +2090,7 @@ describe('Meteor.methods', function () { ); it('should update a message with a URL', (done) => { - request + void request .post(methodCall('updateMessage')) .set(credentials) .send({ @@ -2132,7 +2133,8 @@ describe('Meteor.methods', function () { }); await request - .get(api(`chat.getMessage?msgId=${messageId}`)) + .get(api('chat.getMessage')) + .query({ msgId: messageId }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -2165,7 +2167,8 @@ describe('Meteor.methods', function () { }); await request - .get(api(`chat.getMessage?msgId=${messageId}`)) + .get(api('chat.getMessage')) + .query({ msgId: messageId }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -2199,7 +2202,8 @@ describe('Meteor.methods', function () { }); await request - .get(api(`chat.getMessage?msgId=${messageId}`)) + .get(api('chat.getMessage')) + .query({ msgId: messageId }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -2232,7 +2236,8 @@ describe('Meteor.methods', function () { }); await request - .get(api(`chat.getMessage?msgId=${messageId}`)) + .get(api('chat.getMessage')) + .query({ msgId: messageId }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -2268,7 +2273,8 @@ describe('Meteor.methods', function () { }); await request - .get(api(`chat.getMessage?msgId=${messageId}`)) + .get(api('chat.getMessage')) + .query({ msgId: messageId }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -2284,7 +2290,7 @@ describe('Meteor.methods', function () { }); it('should not parse URLs inside markdown on update', (done) => { - request + void request .post(methodCall('updateMessage')) .set(credentials) .send({ @@ -2311,8 +2317,9 @@ describe('Meteor.methods', function () { expect(data).to.have.a.property('msg').that.is.an('string'); }) .then(() => { - request - .get(api(`chat.getMessage?msgId=${messageWithMarkdownId}`)) + void request + .get(api('chat.getMessage')) + .query({ msgId: messageWithMarkdownId }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -2328,7 +2335,7 @@ describe('Meteor.methods', function () { ['tshow', 'alias', 'attachments', 'avatar', 'emoji', 'msg'].forEach((prop) => { it(`should allow to update a message changing property '${prop}'`, (done) => { - request + void request .post(methodCall('updateMessage')) .set(credentials) .send({ @@ -2353,7 +2360,7 @@ describe('Meteor.methods', function () { ['tmid', '_hidden', 'rid'].forEach((prop) => { it(`should fail to update a message changing invalid property '${prop}'`, (done) => { - request + void request .post(methodCall('updateMessage')) .set(credentials) .send({ @@ -2380,12 +2387,12 @@ describe('Meteor.methods', function () { }); describe('[@deleteMessage]', () => { - let rid = false; - let messageId; + let rid: IRoom['_id']; + let messageId: IMessage['_id']; before('create room', (done) => { const channelName = `methods-test-channel-${Date.now()}`; - request + void request .post(api('groups.create')) .set(credentials) .send({ @@ -2405,7 +2412,7 @@ describe('Meteor.methods', function () { }); beforeEach('send message with URL', (done) => { - request + void request .post(methodCall('sendMessage')) .set(credentials) .send({ @@ -2446,7 +2453,7 @@ describe('Meteor.methods', function () { ); it('should delete a message', (done) => { - request + void request .post(methodCall('deleteMessage')) .set(credentials) .send({ @@ -2504,11 +2511,11 @@ describe('Meteor.methods', function () { }); describe('[@setUserActiveStatus]', () => { - let testUser; - let testUser2; - let testUserCredentials; - let dmId; - let dmTestId; + let testUser: TestUser; + let testUser2: TestUser; + let testUserCredentials: Credentials; + let dmId: IRoom['_id']; + let dmTestId: IRoom['_id']; before(async () => { testUser = await createUser(); @@ -2517,7 +2524,7 @@ describe('Meteor.methods', function () { }); before('create direct conversation with user', (done) => { - request + void request .post(methodCall('createDirectMessage')) .set(credentials) .send({ @@ -2528,7 +2535,7 @@ describe('Meteor.methods', function () { msg: 'method', }), }) - .end((err, res) => { + .end((_err, res) => { const result = JSON.parse(res.body.message); expect(result.result).to.be.an('object'); expect(result.result).to.have.property('rid').that.is.an('string'); @@ -2539,7 +2546,7 @@ describe('Meteor.methods', function () { }); before('create direct conversation between both users', (done) => { - request + void request .post(methodCall('createDirectMessage')) .set(testUserCredentials) .send({ @@ -2550,7 +2557,7 @@ describe('Meteor.methods', function () { msg: 'method', }), }) - .end((err, res) => { + .end((_err, res) => { const result = JSON.parse(res.body.message); expect(result.result).to.be.an('object'); expect(result.result).to.have.property('rid').that.is.an('string'); @@ -2570,7 +2577,7 @@ describe('Meteor.methods', function () { ); it('should deactivate a user', (done) => { - request + void request .post(methodCall('setUserActiveStatus')) .set(credentials) .send({ @@ -2581,7 +2588,7 @@ describe('Meteor.methods', function () { msg: 'method', }), }) - .end((err, res) => { + .end((_err, res) => { expect(res.body).to.have.property('success').that.is.an('boolean'); const result = JSON.parse(res.body.message); expect(result.result).to.be.equal(true); @@ -2590,7 +2597,7 @@ describe('Meteor.methods', function () { }); it('should deactivate another user', (done) => { - request + void request .post(methodCall('setUserActiveStatus')) .set(credentials) .send({ @@ -2601,7 +2608,7 @@ describe('Meteor.methods', function () { msg: 'method', }), }) - .end((err, res) => { + .end((_err, res) => { expect(res.body).to.have.property('success').that.is.an('boolean'); const result = JSON.parse(res.body.message); expect(result.result).to.be.equal(true); @@ -2610,7 +2617,7 @@ describe('Meteor.methods', function () { }); it('should mark the direct conversation between admin=>testUser as readonly when user is deactivated', (done) => { - request + void request .post(methodCall('getRoomByTypeAndName')) .set(credentials) .send({ @@ -2621,7 +2628,7 @@ describe('Meteor.methods', function () { msg: 'method', }), }) - .end((err, res) => { + .end((_err, res) => { expect(res.body.success).to.equal(true); const result = JSON.parse(res.body.message); expect(result.result.ro).to.equal(true); @@ -2630,7 +2637,7 @@ describe('Meteor.methods', function () { }); it('should activate a user', (done) => { - request + void request .post(methodCall('setUserActiveStatus')) .set(credentials) .send({ @@ -2641,7 +2648,7 @@ describe('Meteor.methods', function () { msg: 'method', }), }) - .end((err, res) => { + .end((_err, res) => { expect(res.body).to.have.property('success').that.is.an('boolean'); const result = JSON.parse(res.body.message); expect(result.result).to.be.equal(true); @@ -2650,7 +2657,7 @@ describe('Meteor.methods', function () { }); it('should set readonly=false when user is activated (and the other side is also active)', (done) => { - request + void request .post(methodCall('getRoomByTypeAndName')) .set(credentials) .send({ @@ -2661,7 +2668,7 @@ describe('Meteor.methods', function () { msg: 'method', }), }) - .end((err, res) => { + .end((_err, res) => { expect(res.body.success).to.equal(true); const result = JSON.parse(res.body.message); expect(result.result.ro).to.equal(false); @@ -2670,7 +2677,7 @@ describe('Meteor.methods', function () { }); it('should keep the direct conversation between testUser=>testUser2 as readonly when one of them is deactivated', (done) => { - request + void request .post(api('login')) .send({ user: testUser.username, @@ -2683,7 +2690,7 @@ describe('Meteor.methods', function () { testUserCredentials['X-User-Id'] = res.body.data.userId; }) .then(() => { - request + void request .post(methodCall('getRoomByTypeAndName')) .set(testUserCredentials) .send({ @@ -2694,7 +2701,7 @@ describe('Meteor.methods', function () { msg: 'method', }), }) - .end((err, res) => { + .end((_err, res) => { expect(res.body.success).to.equal(true); const result = JSON.parse(res.body.message); expect(result.result.ro).to.equal(true); @@ -2705,7 +2712,7 @@ describe('Meteor.methods', function () { }); it('should activate another user', (done) => { - request + void request .post(methodCall('setUserActiveStatus')) .set(credentials) .send({ @@ -2716,7 +2723,7 @@ describe('Meteor.methods', function () { msg: 'method', }), }) - .end((err, res) => { + .end((_err, res) => { expect(res.body).to.have.property('success').that.is.an('boolean'); const result = JSON.parse(res.body.message); expect(result.result).to.be.equal(true); @@ -2725,7 +2732,7 @@ describe('Meteor.methods', function () { }); it('should set readonly=false when both users are activated', (done) => { - request + void request .post(methodCall('getRoomByTypeAndName')) .set(testUserCredentials) .send({ @@ -2736,7 +2743,7 @@ describe('Meteor.methods', function () { msg: 'method', }), }) - .end((err, res) => { + .end((_err, res) => { expect(res.body.success).to.equal(true); const result = JSON.parse(res.body.message); expect(result.result.ro).to.equal(false); @@ -2745,7 +2752,7 @@ describe('Meteor.methods', function () { }); it('should keep readonly=true when user is activated (and the other side is deactivated)', (done) => { - request + void request .post(methodCall('getRoomByTypeAndName')) .set(testUserCredentials) .send({ @@ -2756,7 +2763,7 @@ describe('Meteor.methods', function () { msg: 'method', }), }) - .end((err, res) => { + .end((_err, res) => { expect(res.body.success).to.equal(true); const result = JSON.parse(res.body.message); expect(result.result.ro).to.equal(false); @@ -2766,10 +2773,10 @@ describe('Meteor.methods', function () { }); describe('[@addUsersToRoom]', () => { - let guestUser; - let user; - let room; - let createdRooms = []; + let guestUser: TestUser; + let user: TestUser; + let room: IRoom; + let createdRooms: IRoom[] = []; before(async () => { guestUser = await createUser({ roles: ['guest'] }); @@ -2787,7 +2794,7 @@ describe('Meteor.methods', function () { ); it('should fail if not logged in', (done) => { - request + void request .post(methodCall('addUsersToRoom')) .expect('Content-Type', 'application/json') .expect(401) @@ -2799,7 +2806,7 @@ describe('Meteor.methods', function () { }); it('should add a single user to a room', (done) => { - request + void request .post(methodCall('addUsersToRoom')) .set(credentials) .send({ @@ -2816,7 +2823,7 @@ describe('Meteor.methods', function () { expect(res.body).to.have.property('success', true); }) .then(() => { - request + void request .get(api('channels.members')) .set(credentials) .query({ @@ -2852,7 +2859,7 @@ describe('Meteor.methods', function () { } createdRooms = [...createdRooms, ...(await Promise.all(promises)).map((res) => res.body.channel)]; - request + void request .post(methodCall('addUsersToRoom')) .set(credentials) .send({ @@ -2875,9 +2882,9 @@ describe('Meteor.methods', function () { }); describe('[@muteUserInRoom & @unmuteUserInRoom]', () => { - let rid = null; - let channelName = null; - let testUser = null; + let rid: IRoom['_id']; + let channelName: string; + let testUser: TestUser; let testUserCredentials = {}; before('create test user', async () => { @@ -3111,7 +3118,7 @@ describe('Meteor.methods', function () { describe('[@saveSettings]', () => { it('should return an error when trying to save a "NaN" value', () => { - request + void request .post(api('method.call/saveSettings')) .set(credentials) .send({ @@ -3132,7 +3139,7 @@ describe('Meteor.methods', function () { }); it('should return an error when trying to save a "Infinity" value', () => { - request + void request .post(api('method.call/saveSettings')) .set(credentials) .send({ @@ -3153,7 +3160,7 @@ describe('Meteor.methods', function () { }); it('should return an error when trying to save a "-Infinity" value', () => { - request + void request .post(api('method.call/saveSettings')) .set(credentials) .send({ diff --git a/apps/meteor/tests/end-to-end/api/25-teams.js b/apps/meteor/tests/end-to-end/api/25-teams.ts similarity index 85% rename from apps/meteor/tests/end-to-end/api/25-teams.js rename to apps/meteor/tests/end-to-end/api/25-teams.ts index 6fc9899e403b..751bb7168607 100644 --- a/apps/meteor/tests/end-to-end/api/25-teams.js +++ b/apps/meteor/tests/end-to-end/api/25-teams.ts @@ -1,3 +1,5 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IRole, IRoom, ITeam, IUser } from '@rocket.chat/core-typings'; import { TEAM_TYPE } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, afterEach, before, beforeEach, describe, it } from 'mocha'; @@ -5,17 +7,43 @@ import { after, afterEach, before, beforeEach, describe, it } from 'mocha'; import { getCredentials, api, request, credentials, methodCall } from '../../data/api-data'; import { updatePermission, updateSetting } from '../../data/permissions.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; -import { addMembers, createTeam, deleteTeam } from '../../data/teams.helper'; +import { createTeam, deleteTeam } from '../../data/teams.helper'; import { adminUsername, password } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; import { createUser, deleteUser, login } from '../../data/users.helper'; +interface IUserInfo { + _id: string; + username?: string; + name?: string; + status?: string; + settings?: Record; +} + +interface ITeamMemberInfo { + user: IUserInfo; + roles?: IRole['_id'][] | null; + createdBy: Omit; + createdAt: Date; +} + +const addMembers = async (credentials: Record, teamName: string, members: IUser['_id'][]): Promise => { + await request + .post(api('teams.addMembers')) + .set(credentials) + .send({ + teamName, + members: members.map((userId) => ({ userId, roles: ['member'] })), + }); +}; + describe('[Teams]', () => { before((done) => getCredentials(done)); describe('/teams.create', () => { const name = `test-team-create-${Date.now()}`; - const createdTeams = []; - let testUser; + const createdTeams: ITeam[] = []; + let testUser: TestUser; before(async () => { testUser = await createUser(); @@ -24,7 +52,7 @@ describe('[Teams]', () => { after(() => Promise.all([...createdTeams.map((team) => deleteTeam(credentials, team.name)), deleteUser(testUser)])); it('should create a public team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ @@ -43,7 +71,7 @@ describe('[Teams]', () => { }); it('should create a public team with a member', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ @@ -71,7 +99,7 @@ describe('[Teams]', () => { expect(response.body).to.have.property('members'); // remove admin user from members because it's added automatically as owner - const members = response.body.members.filter(({ user }) => user.username !== adminUsername); + const members = (response.body.members as ITeamMemberInfo[]).filter(({ user }) => user.username !== adminUsername); const [member] = members; expect(member.user.username).to.be.equal(testUser.username); @@ -82,7 +110,7 @@ describe('[Teams]', () => { }); it('should create private team with a defined owner', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ @@ -128,7 +156,7 @@ describe('[Teams]', () => { }); it('should throw an error if the team already exists', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ @@ -147,28 +175,28 @@ describe('[Teams]', () => { }); describe('/teams.convertToChannel', () => { - let testTeam; - let channelToEraseId; - let channelToKeepId; + let testTeam: ITeam; + let channelToEraseId: IRoom['_id']; + let channelToKeepId: IRoom['_id']; const teamName = `test-team-convert-to-channel-${Date.now()}`; const channelToEraseName = `${teamName}-channelToErase`; const channelToKeepName = `${teamName}-channelToKeep`; before('Create test team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 1, }) - .end((err, res) => { + .end((_err, res) => { testTeam = res.body.team; done(); }); }); before('create channel (to erase after its team is converted to a channel)', (done) => { - request + void request .post(api('channels.create')) .set(credentials) .send({ @@ -188,7 +216,7 @@ describe('[Teams]', () => { }); before('add first channel to team', (done) => { - request + void request .post(api('teams.addRooms')) .set(credentials) .send({ @@ -208,7 +236,7 @@ describe('[Teams]', () => { }); before('create channel (to keep after its team is converted to a channel)', (done) => { - request + void request .post(api('channels.create')) .set(credentials) .send({ @@ -228,7 +256,7 @@ describe('[Teams]', () => { }); before('add second channel to team', (done) => { - request + void request .post(api('teams.addRooms')) .set(credentials) .send({ @@ -255,7 +283,7 @@ describe('[Teams]', () => { ); it('should convert the team to a channel, delete the specified room and move the other back to the workspace', (done) => { - request + void request .post(api('teams.convertToChannel')) .set(credentials) .send({ @@ -268,7 +296,7 @@ describe('[Teams]', () => { expect(res.body).to.have.property('success', true); }) .then(() => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -283,7 +311,7 @@ describe('[Teams]', () => { }); }) .then(() => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -299,7 +327,7 @@ describe('[Teams]', () => { }); }) .then(() => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -321,10 +349,10 @@ describe('[Teams]', () => { }); describe('/teams.addMembers', () => { - let testTeam; + let testTeam: ITeam; const teamName = `test-team-add-members-${Date.now()}`; - let testUser; - let testUser2; + let testUser: TestUser; + let testUser2: TestUser; before(async () => { testUser = await createUser(); @@ -332,14 +360,14 @@ describe('[Teams]', () => { }); before('Create test team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) - .end((err, res) => { + .end((_err, res) => { testTeam = res.body.team; done(); }); @@ -348,7 +376,7 @@ describe('[Teams]', () => { after(() => Promise.all([deleteUser(testUser), deleteUser(testUser2), deleteTeam(credentials, teamName)])); it('should add members to a public team', (done) => { - request + void request .post(api('teams.addMembers')) .set(credentials) .send({ @@ -369,44 +397,45 @@ describe('[Teams]', () => { .expect((res) => { expect(res.body).to.have.property('success', true); }) - .then(() => - request - .get(api('teams.members')) - .set(credentials) - .query({ - teamName: testTeam.name, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((response) => { - expect(response.body).to.have.property('success', true); - expect(response.body).to.have.property('members'); - expect(response.body.members).to.have.length(3); - expect(response.body.members[1]).to.have.property('user'); - expect(response.body.members[1]).to.have.property('roles'); - expect(response.body.members[1]).to.have.property('createdBy'); - expect(response.body.members[1]).to.have.property('createdAt'); - - const members = response.body.members.map(({ user, roles }) => ({ - _id: user._id, - username: user.username, - name: user.name, - roles, - })); - - expect(members).to.own.deep.include({ - _id: testUser._id, - username: testUser.username, - name: testUser.name, - roles: ['member'], - }); - expect(members).to.own.deep.include({ - _id: testUser2._id, - username: testUser2.username, - name: testUser2.name, - roles: ['member'], - }); - }), + .then( + () => + void request + .get(api('teams.members')) + .set(credentials) + .query({ + teamName: testTeam.name, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((response) => { + expect(response.body).to.have.property('success', true); + expect(response.body).to.have.property('members'); + expect(response.body.members).to.have.length(3); + expect(response.body.members[1]).to.have.property('user'); + expect(response.body.members[1]).to.have.property('roles'); + expect(response.body.members[1]).to.have.property('createdBy'); + expect(response.body.members[1]).to.have.property('createdAt'); + + const members = (response.body.members as ITeamMemberInfo[]).map(({ user, roles }) => ({ + _id: user._id, + username: user.username, + name: user.name, + roles, + })); + + expect(members).to.deep.own.include({ + _id: testUser._id, + username: testUser.username, + name: testUser.name, + roles: ['member'], + }); + expect(members).to.deep.own.include({ + _id: testUser2._id, + username: testUser2.username, + name: testUser2.name, + roles: ['member'], + }); + }), ) .then(() => done()) .catch(done); @@ -414,10 +443,10 @@ describe('[Teams]', () => { }); describe('/teams.members', () => { - let testTeam; + let testTeam: ITeam; const teamName = `test-team-members-${Date.now()}`; - let testUser; - let testUser2; + let testUser: TestUser; + let testUser2: TestUser; before(async () => { testUser = await createUser(); @@ -425,21 +454,21 @@ describe('[Teams]', () => { }); before('Create test team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) - .end((err, res) => { + .end((_err, res) => { testTeam = res.body.team; done(); }); }); before('Add members to team', (done) => { - request + void request .post(api('teams.addMembers')) .set(credentials) .send({ @@ -461,7 +490,7 @@ describe('[Teams]', () => { after(() => Promise.all([deleteUser(testUser), deleteUser(testUser2), deleteTeam(credentials, teamName)])); it('should list all the members from a public team', (done) => { - request + void request .get(api('teams.members')) .set(credentials) .query({ @@ -494,7 +523,7 @@ describe('[Teams]', () => { describe('/teams.list', () => { const teamName = `test-team-list-${Date.now()}`; before('Create test team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ @@ -507,7 +536,7 @@ describe('[Teams]', () => { after(() => deleteTeam(credentials, teamName)); it('should list all teams', (done) => { - request + void request .get(api('teams.list')) .set(credentials) .expect('Content-Type', 'application/json') @@ -519,27 +548,27 @@ describe('[Teams]', () => { expect(res.body).to.have.property('total'); expect(res.body).to.have.property('teams'); expect(res.body.teams.length).equal(1); - expect(res.body.teams[0]).to.include.property('_id'); - expect(res.body.teams[0]).to.include.property('_updatedAt'); - expect(res.body.teams[0]).to.include.property('name'); - expect(res.body.teams[0]).to.include.property('type'); - expect(res.body.teams[0]).to.include.property('roomId'); - expect(res.body.teams[0]).to.include.property('createdBy'); - expect(res.body.teams[0].createdBy).to.include.property('_id'); - expect(res.body.teams[0].createdBy).to.include.property('username'); - expect(res.body.teams[0]).to.include.property('createdAt'); - expect(res.body.teams[0]).to.include.property('rooms'); - expect(res.body.teams[0]).to.include.property('numberOfUsers'); + expect(res.body.teams[0]).to.have.property('_id'); + expect(res.body.teams[0]).to.have.property('_updatedAt'); + expect(res.body.teams[0]).to.have.property('name'); + expect(res.body.teams[0]).to.have.property('type'); + expect(res.body.teams[0]).to.have.property('roomId'); + expect(res.body.teams[0]).to.have.property('createdBy'); + expect(res.body.teams[0].createdBy).to.have.property('_id'); + expect(res.body.teams[0].createdBy).to.have.property('username'); + expect(res.body.teams[0]).to.have.property('createdAt'); + expect(res.body.teams[0]).to.have.property('rooms'); + expect(res.body.teams[0]).to.have.property('numberOfUsers'); }) .end(done); }); }); describe('/teams.updateMember', () => { - let testTeam; + let testTeam: ITeam; const teamName = `test-team-update-member-${Date.now()}`; - let testUser; - let testUser2; + let testUser: TestUser; + let testUser2: TestUser; before(async () => { testUser = await createUser(); @@ -547,20 +576,20 @@ describe('[Teams]', () => { }); before('Create test team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) - .end((err, res) => { + .end((_err, res) => { testTeam = res.body.team; done(); }); }); before('Add members to team', (done) => { - request + void request .post(api('teams.addMembers')) .set(credentials) .send({ @@ -582,7 +611,7 @@ describe('[Teams]', () => { after(() => Promise.all([deleteUser(testUser), deleteUser(testUser2), deleteTeam(credentials, teamName)])); it("should update member's data in a public team", (done) => { - request + void request .post(api('teams.updateMember')) .set(credentials) .send({ @@ -597,34 +626,35 @@ describe('[Teams]', () => { .expect((res) => { expect(res.body).to.have.property('success', true); }) - .then(() => - request - .get(api('teams.members')) - .set(credentials) - .query({ - teamName: testTeam.name, - }) - .expect('Content-Type', 'application/json') - .expect(200) - .expect((response) => { - expect(response.body).to.have.property('success', true); - expect(response.body).to.have.property('members'); - expect(response.body.members).to.have.length(3); - - const members = response.body.members.map(({ user, roles }) => ({ - _id: user._id, - username: user.username, - name: user.name, - roles, - })); - - expect(members).to.own.deep.include({ - _id: testUser._id, - username: testUser.username, - name: testUser.name, - roles: ['member', 'owner'], - }); - }), + .then( + () => + void request + .get(api('teams.members')) + .set(credentials) + .query({ + teamName: testTeam.name, + }) + .expect('Content-Type', 'application/json') + .expect(200) + .expect((response) => { + expect(response.body).to.have.property('success', true); + expect(response.body).to.have.property('members'); + expect(response.body.members).to.have.length(3); + + const members = (response.body.members as ITeamMemberInfo[]).map(({ user, roles }) => ({ + _id: user._id, + username: user.username, + name: user.name, + roles, + })); + + expect(members).to.deep.own.include({ + _id: testUser._id, + username: testUser.username, + name: testUser.name, + roles: ['member', 'owner'], + }); + }), ) .then(() => done()) .catch(done); @@ -632,10 +662,10 @@ describe('[Teams]', () => { }); describe('/teams.removeMember', () => { - let testTeam; + let testTeam: ITeam; const teamName = `test-team-remove-member-${Date.now()}`; - let testUser; - let testUser2; + let testUser: TestUser; + let testUser2: TestUser; before(async () => { testUser = await createUser(); @@ -643,14 +673,14 @@ describe('[Teams]', () => { }); before('Create test team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) - .end((err, res) => { + .end((_err, res) => { testTeam = res.body.team; done(); }); @@ -659,7 +689,7 @@ describe('[Teams]', () => { after(() => Promise.all([deleteUser(testUser), deleteUser(testUser2), deleteTeam(credentials, teamName)])); it('should not be able to remove the last owner', (done) => { - request + void request .post(api('teams.removeMember')) .set(credentials) .send({ @@ -678,7 +708,7 @@ describe('[Teams]', () => { }); it('should not be able to remove if rooms is empty', (done) => { - request + void request .post(api('teams.removeMember')) .set(credentials) .send({ @@ -698,7 +728,7 @@ describe('[Teams]', () => { }); it('should remove one member from a public team', (done) => { - request + void request .post(api('teams.addMembers')) .set(credentials) .send({ @@ -749,10 +779,10 @@ describe('[Teams]', () => { }); describe('/teams.leave', () => { - let testTeam; + let testTeam: ITeam; const teamName = `test-team-leave-${Date.now()}`; - let testUser; - let testUser2; + let testUser: TestUser; + let testUser2: TestUser; before(async () => { testUser = await createUser(); @@ -760,14 +790,14 @@ describe('[Teams]', () => { }); before('Create test team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) - .end((err, res) => { + .end((_err, res) => { testTeam = res.body.team; done(); }); @@ -850,10 +880,10 @@ describe('[Teams]', () => { describe('/teams.info', () => { const teamName = `test-team-info-${Date.now()}`; - let testTeam; - let testTeam2; - let testUser; - let testUserCredentials; + let testTeam: ITeam; + let testTeam2: ITeam; + let testUser: TestUser; + let testUserCredentials: Credentials; before(async () => { testUser = await createUser(); @@ -936,11 +966,11 @@ describe('[Teams]', () => { describe('/teams.delete', () => { describe('deleting an empty team', () => { - let roomId; + let roomId: IRoom['_id']; const tempTeamName = `temporaryTeam-${Date.now()}`; before('create team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ @@ -976,7 +1006,7 @@ describe('[Teams]', () => { expect(res.body).to.have.property('success', true); }) .then(() => { - request + void request .get(api('teams.info')) .set(credentials) .query({ @@ -990,7 +1020,7 @@ describe('[Teams]', () => { expect(response.body.error).to.be.equal('Team not found'); }) .then(() => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -1014,12 +1044,12 @@ describe('[Teams]', () => { const tempTeamName = `temporaryTeam-${Date.now()}`; const channel1Name = `${tempTeamName}-channel1`; const channel2Name = `${tempTeamName}-channel2`; - let teamId; - let channel1Id; - let channel2Id; + let teamId: ITeam['_id']; + let channel1Id: IRoom['_id']; + let channel2Id: IRoom['_id']; before('create team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ @@ -1033,7 +1063,7 @@ describe('[Teams]', () => { }); before('create channel 1', (done) => { - request + void request .post(api('channels.create')) .set(credentials) .send({ @@ -1073,7 +1103,7 @@ describe('[Teams]', () => { }); before('create channel 2', (done) => { - request + void request .post(api('channels.create')) .set(credentials) .send({ @@ -1093,7 +1123,7 @@ describe('[Teams]', () => { }); before('add channel 2 to team', (done) => { - request + void request .post(api('teams.addRooms')) .set(credentials) .send({ @@ -1127,7 +1157,7 @@ describe('[Teams]', () => { expect(res.body).to.have.property('success', true); }) .then(() => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -1141,7 +1171,7 @@ describe('[Teams]', () => { expect(response.body.error).to.include('[error-room-not-found]'); }) .then(() => { - request + void request .get(api('channels.info')) .set(credentials) .query({ @@ -1164,15 +1194,15 @@ describe('[Teams]', () => { }); describe('/teams.addRooms', () => { - let privateRoom; - let privateRoom2; - let privateRoom3; - let publicRoom; - let publicRoom2; - let publicTeam; - let privateTeam; - let testUser; - let testUserCredentials; + let privateRoom: IRoom & { t: 'p' }; + let privateRoom2: IRoom & { t: 'p' }; + let privateRoom3: IRoom & { t: 'p' }; + let publicRoom: IRoom & { t: 'c' }; + let publicRoom2: IRoom & { t: 'c' }; + let publicTeam: ITeam; + let privateTeam: ITeam; + let testUser: TestUser; + let testUserCredentials: Credentials; before(async () => { testUser = await createUser(); @@ -1196,8 +1226,8 @@ describe('[Teams]', () => { }); it('should throw an error if no permission', (done) => { - updatePermission('add-team-channel', []).then(() => { - request + void updatePermission('add-team-channel', []).then(() => { + void request .post(api('teams.addRooms')) .set(credentials) .send({ @@ -1216,8 +1246,8 @@ describe('[Teams]', () => { }); it('should add public and private rooms to team', (done) => { - updatePermission('add-team-channel', ['admin']).then(() => { - request + void updatePermission('add-team-channel', ['admin']).then(() => { + void request .post(api('teams.addRooms')) .set(credentials) .send({ @@ -1235,7 +1265,7 @@ describe('[Teams]', () => { expect(res.body.rooms[1]).to.have.property('_id'); expect(res.body.rooms[1]).to.have.property('teamId', publicTeam._id); - const rids = res.body.rooms.map(({ _id }) => _id); + const rids = (res.body.rooms as IRoom[]).map(({ _id }) => _id); expect(rids).to.include(publicRoom._id); expect(rids).to.include(privateRoom._id); @@ -1245,8 +1275,8 @@ describe('[Teams]', () => { }); it('should add public room to private team', (done) => { - updatePermission('add-team-channel', ['admin']).then(() => { - request + void updatePermission('add-team-channel', ['admin']).then(() => { + void request .post(api('teams.addRooms')) .set(credentials) .send({ @@ -1266,8 +1296,8 @@ describe('[Teams]', () => { }); it('should add private room to team', (done) => { - updatePermission('add-team-channel', ['admin']).then(() => { - request + void updatePermission('add-team-channel', ['admin']).then(() => { + void request .post(api('teams.addRooms')) .set(credentials) .send({ @@ -1287,9 +1317,9 @@ describe('[Teams]', () => { }); it('should fail if the user cannot access the channel', (done) => { - updatePermission('add-team-channel', ['admin', 'user']) + void updatePermission('add-team-channel', ['admin', 'user']) .then(() => { - request + void request .post(api('teams.addRooms')) .set(testUserCredentials) .send({ @@ -1309,7 +1339,7 @@ describe('[Teams]', () => { }); it('should fail if the user is not the owner of the channel', (done) => { - request + void request .post(methodCall('addUsersToRoom')) .set(credentials) .send({ @@ -1326,7 +1356,7 @@ describe('[Teams]', () => { expect(res.body).to.have.property('success', true); }) .then(() => { - request + void request .post(api('teams.addRooms')) .set(testUserCredentials) .send({ @@ -1347,13 +1377,13 @@ describe('[Teams]', () => { }); describe('/teams.listRooms', () => { - let testUser; - let testUserCredentials; - let privateTeam; - let publicTeam; - let privateRoom; - let publicRoom; - let publicRoom2; + let testUser: TestUser; + let testUserCredentials: Credentials; + let privateTeam: ITeam; + let publicTeam: ITeam; + let privateRoom: IRoom; + let publicRoom: IRoom; + let publicRoom2: IRoom; before(async () => { testUser = await createUser(); @@ -1403,8 +1433,8 @@ describe('[Teams]', () => { ); it('should throw an error if team is private and no permission', (done) => { - updatePermission('view-all-teams', []).then(() => { - request + void updatePermission('view-all-teams', []).then(() => { + void request .get(api('teams.listRooms')) .set(testUserCredentials) .query({ @@ -1422,8 +1452,8 @@ describe('[Teams]', () => { }); it('should return only public rooms for public team', (done) => { - updatePermission('view-all-team-channels', []).then(() => { - request + void updatePermission('view-all-team-channels', []).then(() => { + void request .get(api('teams.listRooms')) .set(testUserCredentials) .query({ @@ -1443,8 +1473,8 @@ describe('[Teams]', () => { }); it('should return all rooms for public team', (done) => { - updatePermission('view-all-team-channels', ['user']).then(() => { - request + void updatePermission('view-all-team-channels', ['user']).then(() => { + void request .get(api('teams.listRooms')) .set(testUserCredentials) .query({ @@ -1462,8 +1492,8 @@ describe('[Teams]', () => { }); }); it('should return all rooms for public team even requested with count and offset params', (done) => { - updatePermission('view-all-team-channels', ['user']).then(() => { - request + void updatePermission('view-all-team-channels', ['user']).then(() => { + void request .get(api('teams.listRooms')) .set(testUserCredentials) .query({ @@ -1484,9 +1514,9 @@ describe('[Teams]', () => { }); it('should return public rooms for private team', (done) => { - updatePermission('view-all-team-channels', []).then(() => { - updatePermission('view-all-teams', ['admin']).then(() => { - request + void updatePermission('view-all-team-channels', []).then(() => { + void updatePermission('view-all-teams', ['admin']).then(() => { + void request .get(api('teams.listRooms')) .set(credentials) .query({ @@ -1505,9 +1535,9 @@ describe('[Teams]', () => { }); }); it('should return public rooms for private team even requested with count and offset params', (done) => { - updatePermission('view-all-team-channels', []).then(() => { - updatePermission('view-all-teams', ['admin']).then(() => { - request + void updatePermission('view-all-team-channels', []).then(() => { + void updatePermission('view-all-teams', ['admin']).then(() => { + void request .get(api('teams.listRooms')) .set(credentials) .query({ @@ -1530,8 +1560,8 @@ describe('[Teams]', () => { }); describe('/teams.updateRoom', () => { - let publicRoom; - let publicTeam; + let publicRoom: IRoom; + let publicTeam: ITeam; const name = `teamName-update-room-${Date.now()}`; before(async () => { @@ -1555,8 +1585,8 @@ describe('[Teams]', () => { }); it('should throw an error if no permission', (done) => { - updatePermission('edit-team-channel', []).then(() => { - request + void updatePermission('edit-team-channel', []).then(() => { + void request .post(api('teams.updateRoom')) .set(credentials) .send({ @@ -1575,8 +1605,8 @@ describe('[Teams]', () => { }); it('should set room to team default', (done) => { - updatePermission('edit-team-channel', ['admin']).then(() => { - request + void updatePermission('edit-team-channel', ['admin']).then(() => { + void request .post(api('teams.updateRoom')) .set(credentials) .send({ @@ -1596,10 +1626,10 @@ describe('[Teams]', () => { }); describe('team auto-join', () => { - let testTeam; - let createdRoom; - let testUser1; - let testUser2; + let testTeam: ITeam; + let createdRoom: IRoom; + let testUser1: TestUser; + let testUser2: TestUser; before(async () => { const [testUser1Result, testUser2Result] = await Promise.all([createUser(), createUser()]); @@ -1614,21 +1644,19 @@ describe('[Teams]', () => { const [testTeamCreationResult, testRoomCreationResult] = await Promise.all([createTeamPromise, createRoomPromise]); testTeam = testTeamCreationResult; - createdRoom = testRoomCreationResult; + createdRoom = testRoomCreationResult.body.channel; await request .post(api('teams.addRooms')) .set(credentials) .expect(200) .send({ - rooms: [createdRoom.body.channel._id], + rooms: [createdRoom._id], teamName: testTeam.name, }); }); - afterEach(() => - Promise.all([deleteTeam(credentials, testTeam.name), deleteRoom({ roomId: createdRoom.body.channel._id, type: 'c' })]), - ); + afterEach(() => Promise.all([deleteTeam(credentials, testTeam.name), deleteRoom({ roomId: createdRoom._id, type: 'c' })])); after(() => Promise.all([updateSetting('API_User_Limit', 500), deleteUser(testUser1), deleteUser(testUser2)])); @@ -1640,7 +1668,7 @@ describe('[Teams]', () => { .post(api('teams.updateRoom')) .set(credentials) .send({ - roomId: createdRoom.body.channel._id, + roomId: createdRoom._id, isDefault: true, }) .expect(200) @@ -1658,7 +1686,7 @@ describe('[Teams]', () => { .post(api('teams.updateRoom')) .set(credentials) .send({ - roomId: createdRoom.body.channel._id, + roomId: createdRoom._id, isDefault: true, }) .expect(200) @@ -1671,8 +1699,8 @@ describe('[Teams]', () => { }); describe('/teams.removeRoom', () => { - let publicRoom; - let publicTeam; + let publicRoom: IRoom; + let publicTeam: ITeam; const name = `teamName-remove-room-${Date.now()}`; before(async () => { @@ -1704,8 +1732,8 @@ describe('[Teams]', () => { ); it('should throw an error if no permission', (done) => { - updatePermission('remove-team-channel', []).then(() => { - request + void updatePermission('remove-team-channel', []).then(() => { + void request .post(api('teams.removeRoom')) .set(credentials) .send({ @@ -1724,8 +1752,8 @@ describe('[Teams]', () => { }); it('should remove room from team', (done) => { - updatePermission('remove-team-channel', ['admin']).then(() => { - request + void updatePermission('remove-team-channel', ['admin']).then(() => { + void request .post(api('teams.removeRoom')) .set(credentials) .send({ @@ -1746,53 +1774,53 @@ describe('[Teams]', () => { }); describe('/teams.update', () => { - let testTeam; - let testTeam2; - let testTeam3; + let testTeam: ITeam; + let testTeam2: ITeam; + let testTeam3: ITeam; const teamName = `test-team-name1${Date.now()}`; const teamName2 = `test-team-name2${Date.now()}`; const teamName3 = `test-team-name3${Date.now()}`; const testTeamName = `test-team-name-changed${Date.now()}-1`; const testTeamName2 = `test-team-name-changed${Date.now()}-2`; - let unauthorizedUser; + let unauthorizedUser: TestUser; before('Create test team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ name: teamName, type: 0, }) - .end((err, res) => { + .end((_err, res) => { testTeam = res.body.team; done(); }); }); before('Create test team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ name: teamName2, type: 0, }) - .end((err, res) => { + .end((_err, res) => { testTeam2 = res.body.team; done(); }); }); before('Create test team', (done) => { - request + void request .post(api('teams.create')) .set(credentials) .send({ name: teamName3, type: 0, }) - .end((err, res) => { + .end((_err, res) => { testTeam3 = res.body.team; done(); }); @@ -1889,9 +1917,9 @@ describe('[Teams]', () => { }); describe('should update team room to default and invite users with the right notification preferences', () => { - let userWithPrefs; - let userCredentials; - let createdRoom; + let userWithPrefs: TestUser; + let userCredentials: Credentials; + let createdRoom: IRoom; before(async () => { userWithPrefs = await createUser(); @@ -1926,7 +1954,7 @@ describe('[Teams]', () => { }); it('should add user with prefs to team', (done) => { - request + void request .post(api('teams.addMembers')) .set(credentials) .send({ @@ -1950,7 +1978,7 @@ describe('[Teams]', () => { }); it('should return the user subscription with the right notification preferences', (done) => { - request + void request .get(api('subscriptions.getOne')) .set(userCredentials) .query({ diff --git a/apps/meteor/tests/end-to-end/api/26-LDAP.ts b/apps/meteor/tests/end-to-end/api/26-LDAP.ts index b4bb796b1e52..fc5c9d127836 100644 --- a/apps/meteor/tests/end-to-end/api/26-LDAP.ts +++ b/apps/meteor/tests/end-to-end/api/26-LDAP.ts @@ -2,11 +2,9 @@ import { expect } from 'chai'; import { before, describe, it } from 'mocha'; import type { Response } from 'supertest'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; - -describe('LDAP', function () { - this.retries(0); +import { getCredentials, api, request, credentials } from '../../data/api-data'; +describe('LDAP', () => { before((done) => getCredentials(done)); describe('[/ldap.syncNow]', () => { diff --git a/apps/meteor/tests/end-to-end/api/27-moderation.ts b/apps/meteor/tests/end-to-end/api/27-moderation.ts index 42845c4181a8..162b4c65c4bc 100644 --- a/apps/meteor/tests/end-to-end/api/27-moderation.ts +++ b/apps/meteor/tests/end-to-end/api/27-moderation.ts @@ -4,14 +4,29 @@ import { after, before, describe, it } from 'mocha'; import type { Response } from 'supertest'; import { getCredentials, api, request, credentials } from '../../data/api-data'; -import { getUsersReports, reportUser } from '../../data/moderation.helper'; -import { createUser, deleteUser } from '../../data/users.helper.js'; +import { createUser, deleteUser } from '../../data/users.helper'; -// test for the /moderation.reportsByUsers endpoint +const makeModerationApiRequest = async ( + url: 'moderation.reportUser' | 'moderation.user.reportsByUserId', + method: 'get' | 'post', + data?: any, +) => { + let res: any; -describe('[Moderation]', function () { - this.retries(0); + if (method === 'get') { + res = await request.get(api(url)).set(credentials).query(data); + } else if (method === 'post') { + res = await request.post(api(url)).set(credentials).send(data); + } + return res.body; +}; + +const reportUser = (userId: string, reason: string) => makeModerationApiRequest('moderation.reportUser', 'post', { userId, reason }); + +const getUsersReports = (userId: string) => makeModerationApiRequest('moderation.user.reportsByUserId', 'get', { userId }); + +describe('[Moderation]', () => { before((done) => getCredentials(done)); describe('[/moderation.reportsByUsers]', () => { diff --git a/apps/meteor/tests/end-to-end/api/27-presence.ts b/apps/meteor/tests/end-to-end/api/27-presence.ts index 80a95e18e5b3..a622ddeddfe4 100644 --- a/apps/meteor/tests/end-to-end/api/27-presence.ts +++ b/apps/meteor/tests/end-to-end/api/27-presence.ts @@ -2,14 +2,13 @@ import { expect } from 'chai'; import { before, describe, it, after } from 'mocha'; import type { Response } from 'supertest'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { updatePermission } from '../../data/permissions.helper'; import { password } from '../../data/user'; import { createUser, deleteUser, login } from '../../data/users.helper'; -describe('[Presence]', function () { +describe('[Presence]', () => { let createdUser: any; - this.retries(0); before((done) => getCredentials(done)); diff --git a/apps/meteor/tests/end-to-end/api/28-roles.ts b/apps/meteor/tests/end-to-end/api/28-roles.ts index ad0e693bf2d8..91f7a30ef2f5 100644 --- a/apps/meteor/tests/end-to-end/api/28-roles.ts +++ b/apps/meteor/tests/end-to-end/api/28-roles.ts @@ -2,11 +2,9 @@ import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; import type { Response } from 'supertest'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; - -describe('[Roles]', function () { - this.retries(0); +import { getCredentials, api, request, credentials } from '../../data/api-data'; +describe('[Roles]', () => { const isEnterprise = Boolean(process.env.IS_EE); before((done) => getCredentials(done)); diff --git a/apps/meteor/tests/end-to-end/api/29-oauth-server.ts b/apps/meteor/tests/end-to-end/api/29-oauth-server.ts index 16bed108b341..fcae24a2068a 100644 --- a/apps/meteor/tests/end-to-end/api/29-oauth-server.ts +++ b/apps/meteor/tests/end-to-end/api/29-oauth-server.ts @@ -2,11 +2,9 @@ import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; import type { Response } from 'supertest'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; - -describe('[OAuth Server]', function () { - this.retries(0); +import { getCredentials, api, request, credentials } from '../../data/api-data'; +describe('[OAuth Server]', () => { let oAuthAppId: string; let clientId: string; let clientSecret: string; diff --git a/apps/meteor/tests/end-to-end/api/30-calendar.ts b/apps/meteor/tests/end-to-end/api/30-calendar.ts index 6ea4947fa9db..3ce9cb4159cb 100644 --- a/apps/meteor/tests/end-to-end/api/30-calendar.ts +++ b/apps/meteor/tests/end-to-end/api/30-calendar.ts @@ -1,16 +1,16 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; import type { Response } from 'supertest'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { password } from '../../data/user'; import { createUser, deleteUser, login } from '../../data/users.helper'; -describe('[Calendar Events]', function () { - this.retries(0); - - let user2: Awaited> | undefined; - let userCredentials: Awaited> | undefined; +describe('[Calendar Events]', () => { + let user2: IUser; + let userCredentials: Credentials; before((done) => getCredentials(done)); diff --git a/apps/meteor/tests/end-to-end/api/31-failed-login-attempts.ts b/apps/meteor/tests/end-to-end/api/31-failed-login-attempts.ts index 7e1019b60ecb..ee0236c591b6 100644 --- a/apps/meteor/tests/end-to-end/api/31-failed-login-attempts.ts +++ b/apps/meteor/tests/end-to-end/api/31-failed-login-attempts.ts @@ -1,15 +1,15 @@ +import type { IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, beforeEach, afterEach, describe, it } from 'mocha'; import { sleep } from '../../../lib/utils/sleep'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { updateSetting, updatePermission } from '../../data/permissions.helper'; import { password } from '../../data/user'; +import type { TestUser } from '../../data/users.helper'; import { createUser, deleteUser } from '../../data/users.helper'; -describe('[Failed Login Attempts]', function () { - this.retries(0); - +describe('[Failed Login Attempts]', () => { const maxAttemptsByUser = 2; const maxAttemptsByIp = 4; const userBlockSeconds = 3; @@ -103,7 +103,7 @@ describe('[Failed Login Attempts]', function () { } describe('[Block by User]', () => { - let user: Awaited> | undefined; + let user: TestUser; before(async () => { await updateSetting('Block_Multiple_Failed_Logins_By_Ip', false); @@ -159,9 +159,9 @@ describe('[Failed Login Attempts]', function () { }); describe('[Block by IP]', () => { - let user: Awaited> | undefined; - let user2: Awaited> | undefined; - let userLogin: Awaited> | undefined; + let user: TestUser; + let user2: TestUser; + let userLogin: TestUser; beforeEach(async () => { user = await createUser(); diff --git a/apps/meteor/tests/end-to-end/api/32-assets.ts b/apps/meteor/tests/end-to-end/api/32-assets.ts index 76c24a99765b..63de4dc955fa 100644 --- a/apps/meteor/tests/end-to-end/api/32-assets.ts +++ b/apps/meteor/tests/end-to-end/api/32-assets.ts @@ -1,10 +1,8 @@ import { describe, it } from 'mocha'; -import { request } from '../../data/api-data.js'; - -describe('assets', function () { - this.retries(0); +import { request } from '../../data/api-data'; +describe('assets', () => { it('should always have CORS headers for assets', async () => { await request.get('/assets/favicon.svg').expect('Content-Type', 'image/svg+xml').expect('Access-Control-Allow-Origin', '*').expect(200); diff --git a/apps/meteor/tests/end-to-end/api/33-federation.ts b/apps/meteor/tests/end-to-end/api/33-federation.ts index b44711d83291..9d832d9fc1ac 100644 --- a/apps/meteor/tests/end-to-end/api/33-federation.ts +++ b/apps/meteor/tests/end-to-end/api/33-federation.ts @@ -4,9 +4,7 @@ import { after, before, describe, it } from 'mocha'; import { getCredentials, request } from '../../data/api-data'; import { updateSetting } from '../../data/permissions.helper'; -describe('federation', function () { - this.retries(0); - +describe('federation', () => { before((done) => getCredentials(done)); describe('well-known', () => { diff --git a/apps/meteor/tests/end-to-end/api/import.spec.ts b/apps/meteor/tests/end-to-end/api/import.spec.ts index ba37465626d3..a3db33efff0d 100644 --- a/apps/meteor/tests/end-to-end/api/import.spec.ts +++ b/apps/meteor/tests/end-to-end/api/import.spec.ts @@ -2,13 +2,11 @@ import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; import type { Response } from 'supertest'; -import { getCredentials, api, request, credentials } from '../../data/api-data.js'; +import { getCredentials, api, request, credentials } from '../../data/api-data'; import { password } from '../../data/user'; -import { createUser, login, deleteUser } from '../../data/users.helper.js'; - -describe('Imports', function () { - this.retries(0); +import { createUser, login, deleteUser } from '../../data/users.helper'; +describe('Imports', () => { before((done) => getCredentials(done)); describe('[/getCurrentImportOperation]', () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts index b40ff1dce9c8..5c881b530d08 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/00-rooms.ts @@ -2,17 +2,18 @@ import fs from 'fs'; import path from 'path'; import { faker } from '@faker-js/faker'; +import type { Credentials } from '@rocket.chat/api-client'; import type { IOmnichannelRoom, ILivechatVisitor, - IUser, IOmnichannelSystemMessage, ILivechatPriority, ILivechatDepartment, + ISubscription, } from '@rocket.chat/core-typings'; import { LivechatPriorityWeight } from '@rocket.chat/core-typings'; import { expect } from 'chai'; -import { before, describe, it } from 'mocha'; +import { after, before, describe, it } from 'mocha'; import type { Response } from 'supertest'; import type { SuccessResult } from '../../../../app/api/server/definition'; @@ -46,13 +47,24 @@ import { updatePermission, updateSetting, } from '../../../data/permissions.helper'; -import { getSubscriptionForRoom } from '../../../data/subscriptions'; import { adminUsername, password } from '../../../data/user'; -import { createUser, deleteUser, login } from '../../../data/users.helper.js'; +import { createUser, deleteUser, login } from '../../../data/users.helper'; import { IS_EE } from '../../../e2e/config/constants'; -describe('LIVECHAT - rooms', function () { - this.retries(0); +const getSubscriptionForRoom = async (roomId: string, overrideCredential?: Credentials): Promise => { + const response = await request + .get(api('subscriptions.getOne')) + .set(overrideCredential || credentials) + .query({ roomId }) + .expect('Content-Type', 'application/json') + .expect(200); + + const { subscription } = response.body; + + return subscription; +}; + +describe('LIVECHAT - rooms', () => { let visitor: ILivechatVisitor; let room: IOmnichannelRoom; @@ -145,7 +157,8 @@ describe('LIVECHAT - rooms', function () { }); it('should return an error when the "agents" query parameter is not valid', async () => { await request - .get(api('livechat/rooms?agents=invalid')) + .get(api('livechat/rooms')) + .query({ agents: 'invalid' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -155,7 +168,8 @@ describe('LIVECHAT - rooms', function () { }); it('should return an error when the "roomName" query parameter is not valid', async () => { await request - .get(api('livechat/rooms?roomName[]=invalid')) + .get(api('livechat/rooms')) + .query({ 'roomName[]': 'invalid' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -165,7 +179,8 @@ describe('LIVECHAT - rooms', function () { }); it('should return an error when the "departmentId" query parameter is not valid', async () => { await request - .get(api('livechat/rooms?departmentId[]=marcos')) + .get(api('livechat/rooms')) + .query({ 'departmentId[]': 'marcos' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -175,7 +190,8 @@ describe('LIVECHAT - rooms', function () { }); it('should return an error when the "open" query parameter is not valid', async () => { await request - .get(api('livechat/rooms?open[]=true')) + .get(api('livechat/rooms')) + .query({ 'open[]': 'true' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -185,7 +201,8 @@ describe('LIVECHAT - rooms', function () { }); it('should return an error when the "tags" query parameter is not valid', async () => { await request - .get(api('livechat/rooms?tags=invalid')) + .get(api('livechat/rooms')) + .query({ tags: 'invalid' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -195,7 +212,8 @@ describe('LIVECHAT - rooms', function () { }); it('should return an error when the "createdAt" query parameter is not valid', async () => { await request - .get(api('livechat/rooms?createdAt=invalid')) + .get(api('livechat/rooms')) + .query({ createdAt: 'invalid' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -205,7 +223,8 @@ describe('LIVECHAT - rooms', function () { }); it('should return an error when the "closedAt" query parameter is not valid', async () => { await request - .get(api('livechat/rooms?closedAt=invalid')) + .get(api('livechat/rooms')) + .query({ closedAt: 'invalid' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -215,7 +234,8 @@ describe('LIVECHAT - rooms', function () { }); it('should return an error when the "customFields" query parameter is not valid', async () => { await request - .get(api('livechat/rooms?customFields=invalid')) + .get(api('livechat/rooms')) + .query({ customFields: 'invalid' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -372,10 +392,7 @@ describe('LIVECHAT - rooms', function () { agent: agent.credentials, }); - const { body } = await request - .get(api(`livechat/rooms?agents[]=${agent.user._id}`)) - .set(credentials) - .expect(200); + const { body } = await request.get(api('livechat/rooms')).query({ 'agents[]': agent.user._id }).set(credentials).expect(200); expect(body.rooms.length).to.be.equal(1); expect(body.rooms.some((room: IOmnichannelRoom) => room._id === expectedRoom._id)).to.be.true; @@ -386,10 +403,7 @@ describe('LIVECHAT - rooms', function () { const { room: expectedRoom } = await startANewLivechatRoomAndTakeIt(); await closeOmnichannelRoom(expectedRoom._id, [tag.name]); - const { body } = await request - .get(api(`livechat/rooms?tags[]=${tag.name}`)) - .set(credentials) - .expect(200); + const { body } = await request.get(api('livechat/rooms')).query({ 'tags[]': tag.name }).set(credentials).expect(200); expect(body.rooms.length).to.be.equal(1); expect(body.rooms.some((room: IOmnichannelRoom) => room._id === expectedRoom._id)).to.be.true; @@ -488,7 +502,7 @@ describe('LIVECHAT - rooms', function () { room: { _id: roomId }, } = await startANewLivechatRoomAndTakeIt(); - const manager: IUser = await createUser(); + const manager = await createUser(); const managerCredentials = await login(manager.username, password); await createManager(manager.username); @@ -659,7 +673,7 @@ describe('LIVECHAT - rooms', function () { }); it('should return a success message when transferred successfully to agent', async () => { - const initialAgentAssignedToChat: IUser = await createUser(); + const initialAgentAssignedToChat = await createUser(); const initialAgentCredentials = await login(initialAgentAssignedToChat.username, password); await createAgent(initialAgentAssignedToChat.username); await makeAgentAvailable(initialAgentCredentials); @@ -668,7 +682,7 @@ describe('LIVECHAT - rooms', function () { // at this point, the chat will get transferred to agent "user" const newRoom = await createLivechatRoom(newVisitor.token); - const forwardChatToUser: IUser = await createUser(); + const forwardChatToUser = await createUser(); const forwardChatToUserCredentials = await login(forwardChatToUser.username, password); await createAgent(forwardChatToUser.username); await makeAgentAvailable(forwardChatToUserCredentials); @@ -839,7 +853,7 @@ describe('LIVECHAT - rooms', function () { await makeAgentUnavailable(offlineAgent.credentials); - const manager: IUser = await createUser(); + const manager = await createUser(); const managerCredentials = await login(manager.username, password); await createManager(manager.username); @@ -1544,7 +1558,7 @@ describe('LIVECHAT - rooms', function () { }); it('should return the transfer history for a room', async () => { await updatePermission('view-l-room', ['admin', 'livechat-manager', 'livechat-agent']); - const initialAgentAssignedToChat: IUser = await createUser(); + const initialAgentAssignedToChat = await createUser(); const initialAgentCredentials = await login(initialAgentAssignedToChat.username, password); await createAgent(initialAgentAssignedToChat.username); await makeAgentAvailable(initialAgentCredentials); @@ -1553,7 +1567,7 @@ describe('LIVECHAT - rooms', function () { // at this point, the chat will get transferred to agent "user" const newRoom = await createLivechatRoom(newVisitor.token); - const forwardChatToUser: IUser = await createUser(); + const forwardChatToUser = await createUser(); const forwardChatToUserCredentials = await login(forwardChatToUser.username, password); await createAgent(forwardChatToUser.username); await makeAgentAvailable(forwardChatToUserCredentials); @@ -1980,7 +1994,7 @@ describe('LIVECHAT - rooms', function () { (IS_EE ? describe : describe.skip)('livechat/room/:rid/priority', async () => { let priorities: ILivechatPriority[]; let chosenPriority: ILivechatPriority; - this.afterAll(async () => { + after(async () => { await updateEEPermission('manage-livechat-priorities', ['admin', 'livechat-manager']); await updatePermission('view-l-room', ['admin', 'livechat-manager', 'livechat-agent']); }); diff --git a/apps/meteor/tests/end-to-end/api/livechat/01-agents.ts b/apps/meteor/tests/end-to-end/api/livechat/01-agents.ts index 141cfec1f73d..fc81488ac37d 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/01-agents.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/01-agents.ts @@ -1,3 +1,4 @@ +import type { Credentials } from '@rocket.chat/api-client'; import { UserStatus, type ILivechatAgent, type ILivechatDepartment, type IRoom, type IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; @@ -18,16 +19,14 @@ import { closeOmnichannelRoom, } from '../../../data/livechat/rooms'; import { updatePermission, updateSetting } from '../../../data/permissions.helper'; -import type { IUserCredentialsHeader } from '../../../data/user'; import { password } from '../../../data/user'; import { createUser, deleteUser, getMe, login, setUserStatus } from '../../../data/users.helper'; -describe('LIVECHAT - Agents', function () { - this.retries(0); +describe('LIVECHAT - Agents', () => { let agent: ILivechatAgent; let manager: ILivechatAgent; - let agent2: { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id': string } }; + let agent2: { user: IUser; credentials: Credentials }; before((done) => getCredentials(done)); @@ -39,7 +38,7 @@ describe('LIVECHAT - Agents', function () { }); before(async () => { - const user: IUser = await createUser(); + const user = await createUser(); const userCredentials = await login(user.username, password); await createAgent(user.username); @@ -243,7 +242,7 @@ describe('LIVECHAT - Agents', function () { it('should return a valid user when all goes fine', async () => { await updatePermission('view-livechat-manager', ['admin']); - const user: IUser = await createUser(); + const user = await createUser(); await request .post(api('livechat/users/agent')) .set(credentials) @@ -264,7 +263,7 @@ describe('LIVECHAT - Agents', function () { }); it('should properly create a manager', async () => { - const user: IUser = await createUser(); + const user = await createUser(); await request .post(api('livechat/users/manager')) .set(credentials) @@ -331,7 +330,7 @@ describe('LIVECHAT - Agents', function () { it('should return { user: null } when user is not an agent', async () => { await updatePermission('view-livechat-manager', ['admin']); - const user: IUser = await createUser(); + const user = await createUser(); await request .get(api(`livechat/users/agent/${user._id}`)) .set(credentials) @@ -482,7 +481,7 @@ describe('LIVECHAT - Agents', function () { await updatePermission('manage-livechat-agents', ['admin']); }); it('should return an error if user is not an agent', async () => { - const user: IUser = await createUser({ roles: ['livechat-manager'] }); + const user = await createUser({ roles: ['livechat-manager'] }); const userCredentials = await login(user.username, password); await request .post(api('livechat/agent.status')) @@ -520,7 +519,7 @@ describe('LIVECHAT - Agents', function () { }); }); it('should change logged in users status', async () => { - const currentUser: ILivechatAgent = await getMe(agent2.credentials as any); + const currentUser: ILivechatAgent = await getMe(agent2.credentials); const currentStatus = currentUser.statusLivechat; const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; @@ -537,7 +536,7 @@ describe('LIVECHAT - Agents', function () { it('should allow managers to change other agents status', async () => { await updatePermission('manage-livechat-agents', ['admin']); - const currentUser: ILivechatAgent = await getMe(agent2.credentials as any); + const currentUser: ILivechatAgent = await getMe(agent2.credentials); const currentStatus = currentUser.statusLivechat; const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; @@ -554,7 +553,7 @@ describe('LIVECHAT - Agents', function () { it('should throw an error if agent tries to make themselves available outside of Business hour', async () => { await makeDefaultBusinessHourActiveAndClosed(); - const currentUser: ILivechatAgent = await getMe(agent2.credentials as any); + const currentUser: ILivechatAgent = await getMe(agent2.credentials); const currentStatus = currentUser.statusLivechat; const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; @@ -571,7 +570,7 @@ describe('LIVECHAT - Agents', function () { it('should not allow managers to make other agents available outside business hour', async () => { await updatePermission('manage-livechat-agents', ['admin']); - const currentUser: ILivechatAgent = await getMe(agent2.credentials as any); + const currentUser: ILivechatAgent = await getMe(agent2.credentials); const currentStatus = currentUser.statusLivechat; const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; @@ -590,7 +589,7 @@ describe('LIVECHAT - Agents', function () { }); describe('Agent sidebar', () => { - let testUser: { user: IUser; credentials: IUserCredentialsHeader }; + let testUser: { user: IUser; credentials: Credentials }; before(async () => { const user = await createUser(); await createAgent(user.username); @@ -603,7 +602,7 @@ describe('LIVECHAT - Agents', function () { }; }); after(async () => { - await deleteUser(testUser.user._id); + await deleteUser(testUser.user); }); it('should return an empty list of rooms for a newly created agent', async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/02-appearance.ts b/apps/meteor/tests/end-to-end/api/livechat/02-appearance.ts index de2e81b370aa..030cdbd68f2d 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/02-appearance.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/02-appearance.ts @@ -7,9 +7,7 @@ import { sleep } from '../../../data/livechat/utils'; import { removePermissionFromAllRoles, restorePermissionToRoles, updatePermission, updateSetting } from '../../../data/permissions.helper'; import { IS_EE } from '../../../e2e/config/constants'; -describe('LIVECHAT - appearance', function () { - this.retries(0); - +describe('LIVECHAT - appearance', () => { before((done) => getCredentials(done)); before(async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/03-custom-fields.ts b/apps/meteor/tests/end-to-end/api/livechat/03-custom-fields.ts index 5645392b1adc..75c1eaa62290 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/03-custom-fields.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/03-custom-fields.ts @@ -7,9 +7,7 @@ import { createCustomField } from '../../../data/livechat/custom-fields'; import { createVisitor } from '../../../data/livechat/rooms'; import { updatePermission, updateSetting } from '../../../data/permissions.helper'; -describe('LIVECHAT - custom fields', function () { - this.retries(0); - +describe('LIVECHAT - custom fields', () => { before((done) => getCredentials(done)); before(async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/04-dashboards.ts b/apps/meteor/tests/end-to-end/api/livechat/04-dashboards.ts index bfe53d92dade..c0a559bbcba7 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/04-dashboards.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/04-dashboards.ts @@ -1,4 +1,5 @@ import { faker } from '@faker-js/faker'; +import type { Credentials } from '@rocket.chat/api-client'; import type { ILivechatDepartment, IUser } from '@rocket.chat/core-typings'; import { Random } from '@rocket.chat/random'; import { expect } from 'chai'; @@ -18,11 +19,9 @@ import { import { createAnOnlineAgent } from '../../../data/livechat/users'; import { sleep } from '../../../data/livechat/utils'; import { removePermissionFromAllRoles, restorePermissionToRoles, updateSetting } from '../../../data/permissions.helper'; -import type { IUserCredentialsHeader } from '../../../data/user'; import { IS_EE } from '../../../e2e/config/constants'; describe('LIVECHAT - dashboards', function () { - this.retries(0); // This test is expected to take more time since we're simulating real time conversations to verify analytics this.timeout(60000); @@ -34,7 +33,7 @@ describe('LIVECHAT - dashboards', function () { let department: ILivechatDepartment; const agents: { - credentials: IUserCredentialsHeader; + credentials: Credentials; user: IUser & { username: string }; }[] = []; let avgClosedRoomChatDuration = 0; @@ -143,7 +142,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an "unauthorized error" when the user does not have the necessary permission', async () => { await removePermissionFromAllRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/conversation-totalizers?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/conversation-totalizers')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(403); @@ -151,7 +154,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an array of conversation totalizers', async () => { await restorePermissionToRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/conversation-totalizers?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/conversation-totalizers')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -207,7 +214,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an "unauthorized error" when the user does not have the necessary permission', async () => { await removePermissionFromAllRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/productivity-totalizers?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/productivity-totalizers')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(403); @@ -215,7 +226,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an array of productivity totalizers', async () => { await restorePermissionToRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/productivity-totalizers?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/productivity-totalizers')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -263,7 +278,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an "unauthorized error" when the user does not have the necessary permission', async () => { await removePermissionFromAllRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/chats-totalizers?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/chats-totalizers')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(403); @@ -271,7 +290,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an array of chats totalizers', async () => { await restorePermissionToRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/chats-totalizers?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/chats-totalizers')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -323,9 +346,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an "unauthorized error" when the user does not have the necessary permission', async () => { await removePermissionFromAllRoles('view-livechat-manager'); await request - .get( - api('livechat/analytics/dashboards/agents-productivity-totalizers?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z'), - ) + .get(api('livechat/analytics/dashboards/agents-productivity-totalizers')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(403); @@ -333,9 +358,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an array of agents productivity totalizers', async () => { await restorePermissionToRoles('view-livechat-manager'); await request - .get( - api('livechat/analytics/dashboards/agents-productivity-totalizers?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z'), - ) + .get(api('livechat/analytics/dashboards/agents-productivity-totalizers')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -382,7 +409,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an "unauthorized error" when the user does not have the necessary permission', async () => { await removePermissionFromAllRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/charts/chats?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/charts/chats')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(403); @@ -390,7 +421,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an array of productivity totalizers', async () => { await restorePermissionToRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/charts/chats?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/charts/chats')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -431,7 +466,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an "unauthorized error" when the user does not have the necessary permission', async () => { await removePermissionFromAllRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/charts/chats-per-agent?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/charts/chats-per-agent')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(403); @@ -439,7 +478,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an object with open and closed chats by agent', async () => { await restorePermissionToRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/charts/chats-per-agent?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/charts/chats-per-agent')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -532,7 +575,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an "unauthorized error" when the user does not have the necessary permission', async () => { await removePermissionFromAllRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/charts/chats-per-department?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/charts/chats-per-department')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(403); @@ -540,7 +587,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an object with open and closed chats by department', async () => { await restorePermissionToRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/charts/chats-per-department?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/charts/chats-per-department')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -577,7 +628,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an "unauthorized error" when the user does not have the necessary permission', async () => { await removePermissionFromAllRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/charts/timings?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/charts/timings')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(403); @@ -585,7 +640,11 @@ describe('LIVECHAT - dashboards', function () { it('should return an object with open and closed chats by department', async () => { await restorePermissionToRoles('view-livechat-manager'); await request - .get(api('livechat/analytics/dashboards/charts/timings?start=2019-10-25T15:08:17.248Z&end=2019-12-08T15:08:17.248Z')) + .get(api('livechat/analytics/dashboards/charts/timings')) + .query({ + start: '2019-10-25T15:08:17.248Z', + end: '2019-12-08T15:08:17.248Z', + }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) diff --git a/apps/meteor/tests/end-to-end/api/livechat/05-inquiries.ts b/apps/meteor/tests/end-to-end/api/livechat/05-inquiries.ts index 06b54a4bf10c..8867d9c1b075 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/05-inquiries.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/05-inquiries.ts @@ -1,3 +1,4 @@ +import type { Credentials } from '@rocket.chat/api-client'; import type { ILivechatInquiryRecord, IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { before, describe, it, after } from 'mocha'; @@ -17,14 +18,11 @@ import { } from '../../../data/livechat/rooms'; import { parseMethodResponse } from '../../../data/livechat/utils'; import { removePermissionFromAllRoles, restorePermissionToRoles, updatePermission, updateSetting } from '../../../data/permissions.helper'; -import type { IUserCredentialsHeader } from '../../../data/user'; import { password } from '../../../data/user'; import { createUser, login, deleteUser } from '../../../data/users.helper'; import { IS_EE } from '../../../e2e/config/constants'; -describe('LIVECHAT - inquiries', function () { - this.retries(0); - +describe('LIVECHAT - inquiries', () => { before((done) => getCredentials(done)); before(async () => { @@ -80,7 +78,8 @@ describe('LIVECHAT - inquiries', function () { it('should return an "unauthorized error" when the user does not have the necessary permission', async () => { await updatePermission('view-l-room', []); await request - .get(api('livechat/inquiries.getOne?roomId=room-id')) + .get(api('livechat/inquiries.getOne')) + .query({ roomId: 'room-id' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(403); @@ -88,7 +87,8 @@ describe('LIVECHAT - inquiries', function () { it('should return a inquiry', async () => { await updatePermission('view-l-room', ['admin']); await request - .get(api('livechat/inquiries.getOne?roomId=room-id')) + .get(api('livechat/inquiries.getOne')) + .query({ roomId: 'room-id' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -105,7 +105,8 @@ describe('LIVECHAT - inquiries', function () { const room = await createLivechatRoom(visitor.token); const inquiry = await fetchInquiry(room._id); await request - .get(api(`livechat/inquiries.getOne?roomId=${room._id}`)) + .get(api(`livechat/inquiries.getOne`)) + .query({ roomId: room._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -231,7 +232,7 @@ describe('LIVECHAT - inquiries', function () { }); after(async () => { await updateSetting('Livechat_accept_chats_with_no_agents', false); - await deleteUser(testUser.user._id); + await deleteUser(testUser.user); }); it('should return an "unauthorized error" when the user does not have the necessary permission', async () => { await updatePermission('view-l-room', []); @@ -316,7 +317,7 @@ describe('LIVECHAT - inquiries', function () { }); describe('livechat:returnAsInquiry', () => { - let testUser: { user: IUser; credentials: IUserCredentialsHeader }; + let testUser: { user: IUser; credentials: Credentials }; before(async () => { const user = await createUser(); await createAgent(user.username); @@ -329,7 +330,7 @@ describe('LIVECHAT - inquiries', function () { }; }); after(async () => { - await deleteUser(testUser.user._id); + await deleteUser(testUser.user); }); it('should throw an error if user doesnt have view-l-room permission', async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/06-integrations.ts b/apps/meteor/tests/end-to-end/api/livechat/06-integrations.ts index 5d7165ff74b0..bc4d6fa04dc4 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/06-integrations.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/06-integrations.ts @@ -6,9 +6,7 @@ import type { Response } from 'supertest'; import { getCredentials, api, request, credentials } from '../../../data/api-data'; import { updatePermission, updateSetting } from '../../../data/permissions.helper'; -describe('LIVECHAT - Integrations', function () { - this.retries(0); - +describe('LIVECHAT - Integrations', () => { before((done) => getCredentials(done)); before(async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/07-queue.ts b/apps/meteor/tests/end-to-end/api/livechat/07-queue.ts index b0fc5e85b27e..1d5ef110d308 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/07-queue.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/07-queue.ts @@ -7,9 +7,7 @@ import type { Response } from 'supertest'; import { getCredentials, api, request, credentials } from '../../../data/api-data'; import { updatePermission, updateSetting } from '../../../data/permissions.helper'; -describe('LIVECHAT - Queue', function () { - this.retries(0); - +describe('LIVECHAT - Queue', () => { before((done) => getCredentials(done)); before(async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/08-triggers.ts b/apps/meteor/tests/end-to-end/api/livechat/08-triggers.ts index 92409c2c89d1..6168ed410f24 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/08-triggers.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/08-triggers.ts @@ -7,9 +7,7 @@ import { createTrigger, fetchTriggers } from '../../../data/livechat/triggers'; import { removePermissionFromAllRoles, restorePermissionToRoles, updatePermission, updateSetting } from '../../../data/permissions.helper'; import { IS_EE } from '../../../e2e/config/constants'; -describe('LIVECHAT - triggers', function () { - this.retries(0); - +describe('LIVECHAT - triggers', () => { before((done) => getCredentials(done)); before(async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/09-visitors.ts b/apps/meteor/tests/end-to-end/api/livechat/09-visitors.ts index 58484e857c40..5bc961087efc 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/09-visitors.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/09-visitors.ts @@ -6,7 +6,6 @@ import moment from 'moment'; import { type Response } from 'supertest'; import { getCredentials, api, request, credentials } from '../../../data/api-data'; -import { getLicenseInfo } from '../../../data/licenses.helper'; import { createCustomField, deleteCustomField } from '../../../data/livechat/custom-fields'; import { makeAgentAvailable, @@ -22,8 +21,11 @@ import { updatePermission, updateSetting, removePermissionFromAllRoles, restoreP import { adminUsername } from '../../../data/user'; import { IS_EE } from '../../../e2e/config/constants'; -describe('LIVECHAT - visitors', function () { - this.retries(0); +const getLicenseInfo = (loadValues = false) => { + return request.get(api('licenses.info')).set(credentials).query({ loadValues }).expect(200); +}; + +describe('LIVECHAT - visitors', () => { let visitor: ILivechatVisitor; before((done) => getCredentials(done)); @@ -221,7 +223,8 @@ describe('LIVECHAT - visitors', function () { await updatePermission('view-l-room', []); await request - .get(api('livechat/visitors.info?visitorId=invalid')) + .get(api('livechat/visitors.info')) + .query({ visitorId: 'invalid' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(403) @@ -234,7 +237,8 @@ describe('LIVECHAT - visitors', function () { await updatePermission('view-l-room', ['admin']); await request - .get(api('livechat/visitors.info?visitorId=invalid')) + .get(api('livechat/visitors.info')) + .query({ visitorId: 'invalid' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400) @@ -245,7 +249,8 @@ describe('LIVECHAT - visitors', function () { }); it('should return the visitor info', async () => { await request - .get(api(`livechat/visitors.info?visitorId=${visitor._id}`)) + .get(api('livechat/visitors.info')) + .query({ visitorId: visitor._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -803,18 +808,25 @@ describe('LIVECHAT - visitors', function () { await request.get(api('omnichannel/contact.search')).set(credentials).expect('Content-Type', 'application/json').expect(400); }); it('should fail if its trying to find by an empty string', async () => { - await request.get(api('omnichannel/contact.search?email=')).set(credentials).expect('Content-Type', 'application/json').expect(400); + await request + .get(api('omnichannel/contact.search')) + .query({ email: '' }) + .set(credentials) + .expect('Content-Type', 'application/json') + .expect(400); }); it('should fail if custom is passed but is not JSON serializable', async () => { await request - .get(api('omnichannel/contact.search?custom={a":1}')) + .get(api('omnichannel/contact.search')) + .query({ custom: '{a":1}' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400); }); it('should fail if custom is an empty object and no email|phone are provided', async () => { await request - .get(api('omnichannel/contact.search?custom={}')) + .get(api('omnichannel/contact.search')) + .query({ custom: '{}' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(400); @@ -822,7 +834,8 @@ describe('LIVECHAT - visitors', function () { it('should find a contact by email', async () => { const visitor = await createVisitor(); await request - .get(api(`omnichannel/contact.search?email=${visitor.visitorEmails?.[0].address}`)) + .get(api('omnichannel/contact.search')) + .query({ email: visitor.visitorEmails?.[0].address }) .set(credentials) .send() .expect('Content-Type', 'application/json') @@ -843,7 +856,8 @@ describe('LIVECHAT - visitors', function () { it('should find a contact by phone', async () => { const visitor = await createVisitor(); await request - .get(api(`omnichannel/contact.search?phone=${visitor.phone?.[0].phoneNumber}`)) + .get(api('omnichannel/contact.search')) + .query({ phone: visitor.phone?.[0].phoneNumber }) .set(credentials) .send() .expect('Content-Type', 'application/json') @@ -879,7 +893,8 @@ describe('LIVECHAT - visitors', function () { await createVisitor(); await request - .get(api(`omnichannel/contact.search?custom=${JSON.stringify({ address: 'Rocket.Chat' })}`)) + .get(api('omnichannel/contact.search')) + .query({ custom: JSON.stringify({ address: 'Rocket.Chat' }) }) .set(credentials) .send() .expect('Content-Type', 'application/json') @@ -898,7 +913,8 @@ describe('LIVECHAT - visitors', function () { it('should return null if an invalid set of custom fields is passed and no other params are sent', async () => { const res = await request - .get(api(`omnichannel/contact.search?custom=${JSON.stringify({ nope: 'nel' })}`)) + .get(api('omnichannel/contact.search')) + .query({ custom: JSON.stringify({ nope: 'nel' }) }) .set(credentials) .send(); expect(res.body).to.have.property('success', true); @@ -907,7 +923,8 @@ describe('LIVECHAT - visitors', function () { it('should not break if more than 1 custom field are passed', async () => { const res = await request - .get(api(`omnichannel/contact.search?custom=${JSON.stringify({ nope: 'nel', another: 'field' })}`)) + .get(api('omnichannel/contact.search')) + .query({ custom: JSON.stringify({ nope: 'nel', another: 'field' }) }) .set(credentials) .send(); expect(res.body).to.have.property('success', true); @@ -916,7 +933,8 @@ describe('LIVECHAT - visitors', function () { it('should not break if bad things are passed as custom field keys', async () => { const res = await request - .get(api(`omnichannel/contact.search?custom=${JSON.stringify({ $regex: 'nel' })}`)) + .get(api('omnichannel/contact.search')) + .query({ custom: JSON.stringify({ $regex: 'nel' }) }) .set(credentials) .send(); expect(res.body).to.have.property('success', true); @@ -925,7 +943,8 @@ describe('LIVECHAT - visitors', function () { it('should not break if bad things are passed as custom field keys 2', async () => { const res = await request - .get(api(`omnichannel/contact.search?custom=${JSON.stringify({ '$regex: { very-bad }': 'nel' })}`)) + .get(api('omnichannel/contact.search')) + .query({ custom: JSON.stringify({ '$regex: { very-bad }': 'nel' }) }) .set(credentials) .send(); expect(res.body).to.have.property('success', true); @@ -934,7 +953,8 @@ describe('LIVECHAT - visitors', function () { it('should not break if bad things are passed as custom field values', async () => { const res = await request - .get(api(`omnichannel/contact.search?custom=${JSON.stringify({ nope: '^((ab)*)+$' })}`)) + .get(api('omnichannel/contact.search')) + .query({ custom: JSON.stringify({ nope: '^((ab)*)+$' }) }) .set(credentials) .send(); expect(res.body).to.have.property('success', true); @@ -1004,7 +1024,7 @@ describe('LIVECHAT - visitors', function () { describe('livechat/visitors.search', () => { it('should fail if user doesnt have view-l-room permission', async () => { await updatePermission('view-l-room', []); - const res = await request.get(api(`livechat/visitors.search?text=nel`)).set(credentials).send(); + const res = await request.get(api('livechat/visitors.search')).query({ text: 'nel' }).set(credentials).send(); expect(res.body).to.have.property('success', false); }); it('should fail if term is not on query params', async () => { @@ -1013,16 +1033,13 @@ describe('LIVECHAT - visitors', function () { expect(res.body).to.have.property('success', false); }); it('should not fail when term is an evil regex string', async () => { - const res = await request.get(api(`livechat/visitors.search?term=^((ab)*)+$`)).set(credentials).send(); + const res = await request.get(api('livechat/visitors.search')).query({ term: '^((ab)*)+$' }).set(credentials).send(); expect(res.body).to.have.property('success', true); }); it('should return a list of visitors when term is a valid string', async () => { const visitor = await createVisitor(); - const res = await request - .get(api(`livechat/visitors.search?term=${visitor.name}`)) - .set(credentials) - .send(); + const res = await request.get(api('livechat/visitors.search')).query({ term: visitor.name }).set(credentials).send(); expect(res.body).to.have.property('success', true); expect(res.body.visitors).to.be.an('array'); expect(res.body.visitors).to.have.lengthOf.greaterThan(0); @@ -1033,7 +1050,7 @@ describe('LIVECHAT - visitors', function () { expect(res.body.visitors[0]).to.have.property('phone'); }); it('should return a list of visitors when term is an empty string', async () => { - const res = await request.get(api(`livechat/visitors.search?term=`)).set(credentials).send(); + const res = await request.get(api('livechat/visitors.search')).query({ term: '' }).set(credentials).send(); expect(res.body).to.have.property('success', true); expect(res.body.visitors).to.be.an('array'); expect(res.body.visitors).to.have.lengthOf.greaterThan(0); @@ -1048,7 +1065,7 @@ describe('LIVECHAT - visitors', function () { let contact: ILivechatVisitor; it('should fail if user doesnt have view-l-room permission', async () => { await removePermissionFromAllRoles('view-l-room'); - const res = await request.get(api(`omnichannel/contact?text=nel`)).set(credentials).send(); + const res = await request.get(api('omnichannel/contact')).query({ text: 'nel' }).set(credentials).send(); expect(res.body).to.have.property('success', false); await restorePermissionToRoles('view-l-room'); diff --git a/apps/meteor/tests/end-to-end/api/livechat/11-email-inbox.ts b/apps/meteor/tests/end-to-end/api/livechat/11-email-inbox.ts index 965e9b5ef58f..53367f2655e7 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/11-email-inbox.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/11-email-inbox.ts @@ -209,7 +209,7 @@ describe('Email inbox', () => { it('should return an email inbox matching email', async () => { await createEmailInbox(); await updatePermission('manage-email-inbox', ['admin']); - await request.get(api(`email-inbox.search?email=test`)).set(credentials).expect(200); + await request.get(api('email-inbox.search')).query({ email: 'test' }).set(credentials).expect(200); }); }); }); diff --git a/apps/meteor/tests/end-to-end/api/livechat/11-livechat.ts b/apps/meteor/tests/end-to-end/api/livechat/11-livechat.ts index 09d90b7da8d1..c07f7bcecc81 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/11-livechat.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/11-livechat.ts @@ -17,9 +17,7 @@ import { createBotAgent, getRandomVisitorToken } from '../../../data/livechat/us import { removePermissionFromAllRoles, restorePermissionToRoles, updatePermission, updateSetting } from '../../../data/permissions.helper'; import { IS_EE } from '../../../e2e/config/constants'; -describe('LIVECHAT - Utils', function () { - this.retries(0); - +describe('LIVECHAT - Utils', () => { before((done) => getCredentials(done)); after(async () => { @@ -116,7 +114,7 @@ describe('LIVECHAT - Utils', function () { (IS_EE ? it : it.skip)('should return online as true if there is at least one agent online', async () => { const { department } = await createDepartmentWithAnOnlineAgent(); - const { body } = await request.get(api(`livechat/config?department=${department._id}`)).set(credentials); + const { body } = await request.get(api('livechat/config')).query({ department: department._id }).set(credentials); expect(body).to.have.property('config'); expect(body.config).to.have.property('online', true); }); @@ -124,7 +122,7 @@ describe('LIVECHAT - Utils', function () { const { department, agent } = await createDepartmentWithAnOnlineAgent(); await makeAgentUnavailable(agent.credentials); - const { body } = await request.get(api(`livechat/config?department=${department._id}`)).set(credentials); + const { body } = await request.get(api('livechat/config')).query({ department: department._id }).set(credentials); expect(body).to.have.property('config'); expect(body.config).to.have.property('online', false); }); @@ -137,7 +135,7 @@ describe('LIVECHAT - Utils', function () { const botUser = await createBotAgent(); await addOrRemoveAgentFromDepartment(department._id, { agentId: botUser.user._id, username: botUser.user.username as string }, true); - const { body } = await request.get(api(`livechat/config?department=${department._id}`)).set(credentials); + const { body } = await request.get(api('livechat/config')).query({ department: department._id }).set(credentials); expect(body).to.have.property('config'); await updateSetting('Livechat_assign_new_conversation_to_bot', false); @@ -145,7 +143,7 @@ describe('LIVECHAT - Utils', function () { }); it('should return a guest if there exists a guest with the same token', async () => { const guest = await createVisitor(); - const { body } = await request.get(api(`livechat/config?token=${guest.token}`)).set(credentials); + const { body } = await request.get(api('livechat/config')).query({ token: guest.token }).set(credentials); expect(body).to.have.property('config'); expect(body.config).to.have.property('guest'); expect(body.config.guest).to.have.property('name', guest.name); @@ -153,13 +151,13 @@ describe('LIVECHAT - Utils', function () { it('should not return a guest if there exists a guest with the same token but the guest is not online', async () => { const token = getRandomVisitorToken(); - const { body } = await request.get(api(`livechat/config?token=${token}`)).set(credentials); + const { body } = await request.get(api('livechat/config')).query({ token }).set(credentials); expect(body).to.have.property('config'); expect(body.config).to.not.have.property('guest'); }); it('should return no online room if visitor is not chatting with an agent', async () => { const visitor = await createVisitor(); - const { body } = await request.get(api(`livechat/config?token=${visitor.token}`)).set(credentials); + const { body } = await request.get(api('livechat/config')).query({ token: visitor.token }).set(credentials); expect(body).to.have.property('config'); expect(body.config).to.not.have.property('room'); }); @@ -167,7 +165,7 @@ describe('LIVECHAT - Utils', function () { const newVisitor = await createVisitor(); const newRoom = await createLivechatRoom(newVisitor.token); - const { body } = await request.get(api(`livechat/config?token=${newVisitor.token}`)).set(credentials); + const { body } = await request.get(api('livechat/config')).query({ token: newVisitor.token }).set(credentials); expect(body).to.have.property('config'); expect(body.config).to.have.property('room'); @@ -470,7 +468,8 @@ describe('LIVECHAT - Utils', function () { const room2 = await createLivechatRoom(visitor2.token); const { body: result1 } = await request - .get(api('livechat/visitors.search?term=VisitorIn&sort={"lastChat.ts":1}')) + .get(api('livechat/visitors.search')) + .query({ term: 'VisitorIn', sort: '{"lastChat.ts":1}' }) .set(credentials) .send(); @@ -479,7 +478,8 @@ describe('LIVECHAT - Utils', function () { expect(result1.visitors[0].name).to.be.eq('VisitorInPast'); const { body: result2 } = await request - .get(api('livechat/visitors.search?term=VisitorIn&sort={"lastChat.ts":-1}')) + .get(api('livechat/visitors.search')) + .query({ term: 'VisitorIn', sort: '{"lastChat.ts":-1}' }) .set(credentials) .send(); diff --git a/apps/meteor/tests/end-to-end/api/livechat/12-priorites.ts b/apps/meteor/tests/end-to-end/api/livechat/12-priorites.ts index 3fb89278a7c1..7b80e2528629 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/12-priorites.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/12-priorites.ts @@ -7,7 +7,7 @@ import type { } from '@rocket.chat/core-typings'; import { OmnichannelSortingMechanismSettingType } from '@rocket.chat/core-typings'; import { expect } from 'chai'; -import { before, describe, it } from 'mocha'; +import { after, before, describe, it } from 'mocha'; import { getCredentials, api, request, credentials } from '../../../data/api-data'; import { createDepartmentWithAnOnlineAgent } from '../../../data/livechat/department'; @@ -32,9 +32,7 @@ import { import { IS_EE } from '../../../e2e/config/constants'; import { generateRandomSLAData } from '../../../e2e/utils/omnichannel/sla'; -(IS_EE ? describe : describe.skip)('[EE] LIVECHAT - Priorities & SLAs', function () { - this.retries(0); - +(IS_EE ? describe : describe.skip)('[EE] LIVECHAT - Priorities & SLAs', () => { before((done) => getCredentials(done)); before(async () => { @@ -42,7 +40,7 @@ import { generateRandomSLAData } from '../../../e2e/utils/omnichannel/sla'; await updateSetting('Livechat_Routing_Method', 'Manual_Selection'); }); - this.afterAll(async () => { + after(async () => { await addPermissions({ 'manage-livechat-priorities': ['admin', 'livechat-manager'], 'manage-livechat-sla': ['admin', 'livechat-manager'], diff --git a/apps/meteor/tests/end-to-end/api/livechat/13-tags.ts b/apps/meteor/tests/end-to-end/api/livechat/13-tags.ts index ff286250c5bb..7953e772c016 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/13-tags.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/13-tags.ts @@ -12,9 +12,7 @@ import { password } from '../../../data/user'; import { createUser, deleteUser, login } from '../../../data/users.helper'; import { IS_EE } from '../../../e2e/config/constants'; -(IS_EE ? describe : describe.skip)('[EE] Livechat - Tags', function () { - this.retries(0); - +(IS_EE ? describe : describe.skip)('[EE] Livechat - Tags', () => { before((done) => getCredentials(done)); before(async () => { @@ -68,7 +66,7 @@ import { IS_EE } from '../../../e2e/config/constants'; }); after(async () => { - await deleteUser(monitor); + await deleteUser(monitor.user); }); it('should throw unauthorized error when the user does not have the necessary permission', async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/14-units.ts b/apps/meteor/tests/end-to-end/api/livechat/14-units.ts index 3a03d9e93e2c..425c776fecdb 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/14-units.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/14-units.ts @@ -9,9 +9,7 @@ import { updatePermission, updateSetting } from '../../../data/permissions.helpe import { createUser, deleteUser } from '../../../data/users.helper'; import { IS_EE } from '../../../e2e/config/constants'; -(IS_EE ? describe : describe.skip)('[EE] LIVECHAT - Units', function () { - this.retries(0); - +(IS_EE ? describe : describe.skip)('[EE] LIVECHAT - Units', () => { before((done) => getCredentials(done)); before(async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/15-canned-responses.ts b/apps/meteor/tests/end-to-end/api/livechat/15-canned-responses.ts index d4c9c758e5a0..a71925531f4d 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/15-canned-responses.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/15-canned-responses.ts @@ -13,9 +13,7 @@ import { password } from '../../../data/user'; import { createUser, login } from '../../../data/users.helper'; import { IS_EE } from '../../../e2e/config/constants'; -(IS_EE ? describe : describe.skip)('[EE] LIVECHAT - Canned responses', function () { - this.retries(0); - +(IS_EE ? describe : describe.skip)('[EE] LIVECHAT - Canned responses', () => { before((done) => getCredentials(done)); before(async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/16-video-call.ts b/apps/meteor/tests/end-to-end/api/livechat/16-video-call.ts index 5f8d7492480f..4a3869aaed38 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/16-video-call.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/16-video-call.ts @@ -5,9 +5,7 @@ import { getCredentials, api, request, credentials } from '../../../data/api-dat import { createLivechatRoom, createVisitor, fetchMessages, sendMessage } from '../../../data/livechat/rooms'; import { updatePermission, updateSetting } from '../../../data/permissions.helper'; -describe('LIVECHAT - WebRTC video call', function () { - this.retries(0); - +describe('LIVECHAT - WebRTC video call', () => { before((done) => getCredentials(done)); before(async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/17-dashboards-ee.ts b/apps/meteor/tests/end-to-end/api/livechat/17-dashboards-ee.ts index 98c1bbe957a3..dc379eea9212 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/17-dashboards-ee.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/17-dashboards-ee.ts @@ -17,9 +17,7 @@ import { import { updatePermission, updateSetting } from '../../../data/permissions.helper'; import { IS_EE } from '../../../e2e/config/constants'; -(IS_EE ? describe : describe.skip)('[EE] LIVECHAT - dashboards', function () { - this.retries(0); - +(IS_EE ? describe : describe.skip)('[EE] LIVECHAT - dashboards', () => { before((done) => getCredentials(done)); before(async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/18-rooms-ee.ts b/apps/meteor/tests/end-to-end/api/livechat/18-rooms-ee.ts index e3117c3088a7..43282ef9c79b 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/18-rooms-ee.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/18-rooms-ee.ts @@ -1,3 +1,4 @@ +import type { Credentials } from '@rocket.chat/api-client'; import type { IOmnichannelRoom, IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; @@ -22,12 +23,10 @@ import { password } from '../../../data/user'; import { createUser, deleteUser, login } from '../../../data/users.helper'; import { IS_EE } from '../../../e2e/config/constants'; -(IS_EE ? describe : describe.skip)('[EE] LIVECHAT - rooms', function () { - this.retries(0); - +(IS_EE ? describe : describe.skip)('[EE] LIVECHAT - rooms', () => { before((done) => getCredentials(done)); - let agent2: { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id': string } }; + let agent2: { user: IUser; credentials: Credentials }; before(async () => { await updateSetting('Livechat_enabled', true); @@ -37,7 +36,7 @@ import { IS_EE } from '../../../e2e/config/constants'; }); before(async () => { - const user: IUser = await createUser(); + const user = await createUser(); const userCredentials = await login(user.username, password); await createAgent(user.username); await updateSetting('Livechat_allow_manual_on_hold', true); diff --git a/apps/meteor/tests/end-to-end/api/livechat/19-business-hours.ts b/apps/meteor/tests/end-to-end/api/livechat/19-business-hours.ts index 869f36fd9695..9a6543f06c72 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/19-business-hours.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/19-business-hours.ts @@ -1,3 +1,4 @@ +import type { Credentials } from '@rocket.chat/api-client'; import type { ILivechatAgent, ILivechatBusinessHour, ILivechatDepartment } from '@rocket.chat/core-typings'; import { LivechatBusinessHourBehaviors, LivechatBusinessHourTypes, ILivechatAgentStatus } from '@rocket.chat/core-typings'; import { expect } from 'chai'; @@ -26,14 +27,12 @@ import { import { createAgent, createManager, makeAgentAvailable } from '../../../data/livechat/rooms'; import { removeAgent } from '../../../data/livechat/users'; import { removePermissionFromAllRoles, restorePermissionToRoles, updateSetting, updateEESetting } from '../../../data/permissions.helper'; -import type { IUserCredentialsHeader } from '../../../data/user'; import { password } from '../../../data/user'; +import type { TestUser } from '../../../data/users.helper'; import { setUserActiveStatus, createUser, deleteUser, getMe, getUserByUsername, login } from '../../../data/users.helper'; import { IS_EE } from '../../../e2e/config/constants'; -describe('LIVECHAT - business hours', function () { - this.retries(0); - +describe('LIVECHAT - business hours', () => { before((done) => getCredentials(done)); before(async () => { @@ -317,7 +316,7 @@ describe('LIVECHAT - business hours', function () { const { department, agent } = await createDepartmentWithAnOnlineAgent(); await createCustomBusinessHour([department._id], false); - const latestAgent: ILivechatAgent = await getMe(agent.credentials as any); + const latestAgent = await getMe(agent.credentials); expect(latestAgent).to.be.an('object'); expect(latestAgent.openBusinessHours).to.be.an('array').of.length(0); expect(latestAgent.statusLivechat).to.be.equal(ILivechatAgentStatus.NOT_AVAILABLE); @@ -434,7 +433,7 @@ describe('LIVECHAT - business hours', function () { // archive department await archiveDepartment(deptLinkedToCustomBH._id); - const latestAgent: ILivechatAgent = await getMe(agentLinkedToDept.credentials as any); + const latestAgent: ILivechatAgent = await getMe(agentLinkedToDept.credentials); expect(latestAgent).to.be.an('object'); expect(latestAgent.openBusinessHours).to.be.an('array').of.length(1); expect(latestAgent?.openBusinessHours?.[0]).to.be.equal(defaultBusinessHour._id); @@ -479,7 +478,7 @@ describe('LIVECHAT - business hours', function () { expect(latestAgent?.openBusinessHours?.[0]).to.be.equal(customBusinessHour._id); // verify if other agent still has BH within his cache - const otherAgent: ILivechatAgent = await getMe(agent.credentials as any); + const otherAgent: ILivechatAgent = await getMe(agent.credentials); expect(otherAgent).to.be.an('object'); expect(otherAgent.openBusinessHours).to.be.an('array').of.length(1); expect(otherAgent?.openBusinessHours?.[0]).to.be.equal(customBusinessHour._id); @@ -579,7 +578,7 @@ describe('LIVECHAT - business hours', function () { // disable department await disableDepartment(deptLinkedToCustomBH); - const latestAgent: ILivechatAgent = await getMe(agentLinkedToDept.credentials as any); + const latestAgent: ILivechatAgent = await getMe(agentLinkedToDept.credentials); expect(latestAgent).to.be.an('object'); expect(latestAgent.openBusinessHours).to.be.an('array').of.length(1); expect(latestAgent?.openBusinessHours?.[0]).to.be.equal(defaultBusinessHour._id); @@ -617,13 +616,13 @@ describe('LIVECHAT - business hours', function () { expect(latestCustomBH?.departments?.[0]?._id).to.be.equal(department._id); // verify if overlapping agent still has BH within his cache - const latestAgent: ILivechatAgent = await getMe(agentLinkedToDept.credentials as any); + const latestAgent: ILivechatAgent = await getMe(agentLinkedToDept.credentials); expect(latestAgent).to.be.an('object'); expect(latestAgent.openBusinessHours).to.be.an('array').of.length(1); expect(latestAgent?.openBusinessHours?.[0]).to.be.equal(customBusinessHour._id); // verify if other agent still has BH within his cache - const otherAgent: ILivechatAgent = await getMe(agent.credentials as any); + const otherAgent: ILivechatAgent = await getMe(agent.credentials); expect(otherAgent).to.be.an('object'); expect(otherAgent.openBusinessHours).to.be.an('array').of.length(1); expect(otherAgent?.openBusinessHours?.[0]).to.be.equal(customBusinessHour._id); @@ -710,7 +709,7 @@ describe('LIVECHAT - business hours', function () { await deleteDepartment(deptLinkedToCustomBH._id); - const latestAgent: ILivechatAgent = await getMe(agentLinkedToDept.credentials as any); + const latestAgent: ILivechatAgent = await getMe(agentLinkedToDept.credentials); expect(latestAgent).to.be.an('object'); expect(latestAgent.openBusinessHours).to.be.an('array').of.length(1); expect(latestAgent?.openBusinessHours?.[0]).to.be.equal(defaultBusinessHour._id); @@ -742,13 +741,13 @@ describe('LIVECHAT - business hours', function () { expect(latestCustomBH?.departments?.[0]?._id).to.be.equal(department._id); // verify if overlapping agent still has BH within his cache - const latestAgent: ILivechatAgent = await getMe(agentLinkedToDept.credentials as any); + const latestAgent: ILivechatAgent = await getMe(agentLinkedToDept.credentials); expect(latestAgent).to.be.an('object'); expect(latestAgent.openBusinessHours).to.be.an('array').of.length(1); expect(latestAgent?.openBusinessHours?.[0]).to.be.equal(customBusinessHour._id); // verify if other agent still has BH within his cache - const otherAgent: ILivechatAgent = await getMe(agent.credentials as any); + const otherAgent: ILivechatAgent = await getMe(agent.credentials); expect(otherAgent).to.be.an('object'); expect(otherAgent.openBusinessHours).to.be.an('array').of.length(1); expect(otherAgent?.openBusinessHours?.[0]).to.be.equal(customBusinessHour._id); @@ -765,7 +764,7 @@ describe('LIVECHAT - business hours', function () { describe('[CE][BH] On Agent created/removed', () => { let defaultBH: ILivechatBusinessHour; let agent: ILivechatAgent; - let agentCredentials: IUserCredentialsHeader; + let agentCredentials: Credentials; before(async () => { await updateSetting('Livechat_enable_business_hours', true); @@ -787,7 +786,7 @@ describe('LIVECHAT - business hours', function () { it('should create a new agent and verify if it is assigned to the default business hour which is open', async () => { agent = await createAgent(agent.username); - const latestAgent: ILivechatAgent = await getMe(agentCredentials as any); + const latestAgent: ILivechatAgent = await getMe(agentCredentials); expect(latestAgent).to.be.an('object'); expect(latestAgent.openBusinessHours).to.be.an('array').of.length(1); expect(latestAgent?.openBusinessHours?.[0]).to.be.equal(defaultBH._id); @@ -811,7 +810,7 @@ describe('LIVECHAT - business hours', function () { it('should verify if agent is assigned to BH when it is opened', async () => { // first verify if agent is not assigned to any BH - let latestAgent: ILivechatAgent = await getMe(agentCredentials as any); + let latestAgent: ILivechatAgent = await getMe(agentCredentials); expect(latestAgent).to.be.an('object'); expect(latestAgent.openBusinessHours).to.be.an('array').of.length(0); expect(latestAgent.statusLivechat).to.be.equal(ILivechatAgentStatus.NOT_AVAILABLE); @@ -820,7 +819,7 @@ describe('LIVECHAT - business hours', function () { await openOrCloseBusinessHour(defaultBH, true); // verify if agent is assigned to BH - latestAgent = await getMe(agentCredentials as any); + latestAgent = await getMe(agentCredentials); expect(latestAgent).to.be.an('object'); expect(latestAgent.openBusinessHours).to.be.an('array').of.length(1); expect(latestAgent?.openBusinessHours?.[0]).to.be.equal(defaultBH._id); @@ -832,7 +831,7 @@ describe('LIVECHAT - business hours', function () { it('should verify if BH related props are cleared when an agent is deleted', async () => { await removeAgent(agent._id); - const latestAgent: ILivechatAgent = await getMe(agentCredentials as any); + const latestAgent: ILivechatAgent = await getMe(agentCredentials); expect(latestAgent).to.be.an('object'); expect(latestAgent.openBusinessHours).to.be.undefined; expect(latestAgent.statusLivechat).to.be.undefined; @@ -840,7 +839,7 @@ describe('LIVECHAT - business hours', function () { describe('Special Case - Agent created, BH already enabled', () => { let newAgent: ILivechatAgent; - let newAgentCredentials: IUserCredentialsHeader; + let newAgentCredentials: Credentials; before(async () => { newAgent = await createUser({ roles: ['user', 'livechat-agent'] }); newAgentCredentials = await login(newAgent.username, password); @@ -849,7 +848,7 @@ describe('LIVECHAT - business hours', function () { await deleteUser(newAgent); }); it('should verify a newly created agent to be assigned to the default business hour', async () => { - const latestAgent: ILivechatAgent = await getMe(newAgentCredentials as any); + const latestAgent: ILivechatAgent = await getMe(newAgentCredentials); expect(latestAgent).to.be.an('object'); expect(latestAgent.openBusinessHours).to.be.an('array').of.length(1); expect(latestAgent?.openBusinessHours?.[0]).to.be.equal(defaultBH._id); @@ -857,13 +856,13 @@ describe('LIVECHAT - business hours', function () { }); after(async () => { - await deleteUser(agent._id); + await deleteUser(agent); }); }); describe('[CE][BH] On Agent deactivated/activated', () => { let defaultBH: ILivechatBusinessHour; - let agent: ILivechatAgent; + let agent: TestUser; before(async () => { await updateSetting('Livechat_enable_business_hours', true); @@ -887,7 +886,7 @@ describe('LIVECHAT - business hours', function () { await makeAgentAvailable(await login(agent.username, password)); await setUserActiveStatus(agent._id, false); - const latestAgent = await getUserByUsername(agent.username); + const latestAgent = await getUserByUsername(agent.username); expect(latestAgent).to.be.an('object'); expect(latestAgent.statusLivechat).to.be.equal(ILivechatAgentStatus.NOT_AVAILABLE); @@ -898,7 +897,7 @@ describe('LIVECHAT - business hours', function () { await setUserActiveStatus(agent._id, true); - const latestAgent = await getUserByUsername(agent.username); + const latestAgent = await getUserByUsername(agent.username); expect(latestAgent).to.be.an('object'); expect(latestAgent.statusLivechat).to.be.equal(ILivechatAgentStatus.AVAILABLE); @@ -909,7 +908,7 @@ describe('LIVECHAT - business hours', function () { await setUserActiveStatus(agent._id, false); await setUserActiveStatus(agent._id, true); - const latestAgent = await getUserByUsername(agent.username); + const latestAgent = await getUserByUsername(agent.username); expect(latestAgent).to.be.an('object'); expect(latestAgent.statusLivechat).to.be.equal(ILivechatAgentStatus.NOT_AVAILABLE); diff --git a/apps/meteor/tests/end-to-end/api/livechat/21-reports.ts b/apps/meteor/tests/end-to-end/api/livechat/21-reports.ts index bc74905f92f6..2de552b7d8e1 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/21-reports.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/21-reports.ts @@ -1,3 +1,4 @@ +import type { Credentials } from '@rocket.chat/api-client'; import type { IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; @@ -14,11 +15,11 @@ import { IS_EE } from '../../../e2e/config/constants'; (IS_EE ? describe : describe.skip)('LIVECHAT - reports', () => { before((done) => getCredentials(done)); - let agent2: { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id': string } }; - let agent3: { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id': string } }; + let agent2: { user: IUser; credentials: Credentials }; + let agent3: { user: IUser; credentials: Credentials }; before(async () => { - const user: IUser = await createUser(); + const user = await createUser(); const userCredentials = await login(user.username, password); if (!user.username) { throw new Error('user not created'); @@ -32,7 +33,7 @@ import { IS_EE } from '../../../e2e/config/constants'; }); before(async () => { - const user: IUser = await createUser(); + const user = await createUser(); const userCredentials = await login(user.username, password); await createAgent(); if (!user.username) { diff --git a/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts index 31d5e04c4162..ad24fb0e1981 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/22-monitors.ts @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ +import type { Credentials } from '@rocket.chat/api-client'; import type { ILivechatDepartment, IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { before, it, describe, after } from 'mocha'; @@ -19,7 +20,7 @@ import { password } from '../../../data/user'; import { createUser, deleteUser, login, setUserActiveStatus } from '../../../data/users.helper'; import { IS_EE } from '../../../e2e/config/constants'; -type TestUser = { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id': string } }; +type TestUser = { user: IUser; credentials: Credentials }; (IS_EE ? describe : describe.skip)('Omnichannel - Monitors', () => { let manager: TestUser; @@ -35,7 +36,7 @@ type TestUser = { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id await makeAgentAvailable(); }); before(async () => { - const user: IUser = await createUser(); + const user = await createUser(); const userCredentials = await login(user.username, password); if (!user.username) { throw new Error('user not created'); @@ -48,7 +49,7 @@ type TestUser = { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id }; }); before(async () => { - const user: IUser = await createUser(); + const user = await createUser(); const userCredentials = await login(user.username, password); if (!user.username) { throw new Error('user not created'); diff --git a/apps/meteor/tests/end-to-end/api/livechat/23-mac.ts b/apps/meteor/tests/end-to-end/api/livechat/23-mac.ts index f8f23ca8fb30..033122c467da 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/23-mac.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/23-mac.ts @@ -78,7 +78,8 @@ describe('MAC', () => { it('visitor should be marked as active for period', async () => { const { body } = await request - .get(api(`livechat/visitors.info?visitorId=${visitor._id}`)) + .get(api('livechat/visitors.info')) + .query({ visitorId: visitor._id }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200); diff --git a/apps/meteor/tests/end-to-end/api/livechat/24-routing.ts b/apps/meteor/tests/end-to-end/api/livechat/24-routing.ts index 48d447b9923d..fb1301341069 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/24-routing.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/24-routing.ts @@ -1,3 +1,4 @@ +import type { Credentials } from '@rocket.chat/api-client'; import { UserStatus, type ILivechatDepartment, type IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; @@ -14,7 +15,6 @@ import { } from '../../../data/livechat/rooms'; import { sleep } from '../../../data/livechat/utils'; import { updateSetting } from '../../../data/permissions.helper'; -import type { IUserCredentialsHeader } from '../../../data/user'; import { password } from '../../../data/user'; import { createUser, deleteUser, login, setUserActiveStatus, setUserStatus } from '../../../data/users.helper'; import { IS_EE } from '../../../e2e/config/constants'; @@ -31,8 +31,8 @@ import { IS_EE } from '../../../e2e/config/constants'; await updateSetting('Livechat_Routing_Method', 'Auto_Selection'); }); - let testUser: { user: IUser; credentials: IUserCredentialsHeader }; - let testUser2: { user: IUser; credentials: IUserCredentialsHeader }; + let testUser: { user: IUser; credentials: Credentials }; + let testUser2: { user: IUser; credentials: Credentials }; let testDepartment: ILivechatDepartment; before(async () => { @@ -96,7 +96,7 @@ import { IS_EE } from '../../../e2e/config/constants'; await makeAgentUnavailable(testUser.credentials); const visitor = await createVisitor(testDepartment._id); - const { body } = await request.get(api(`livechat/room?token=${visitor.token}`)).expect(400); + const { body } = await request.get(api('livechat/room')).query({ token: visitor.token }).expect(400); expect(body.error).to.be.equal('Sorry, no online agents [no-agent-online]'); }); it('should accept a conversation but not route to anyone when Livechat_accept_chats_with_no_agents is true', async () => { @@ -153,8 +153,8 @@ import { IS_EE } from '../../../e2e/config/constants'; await updateSetting('Livechat_Routing_Method', 'Load_Balancing'); }); - let testUser: { user: IUser; credentials: IUserCredentialsHeader }; - let testUser2: { user: IUser; credentials: IUserCredentialsHeader }; + let testUser: { user: IUser; credentials: Credentials }; + let testUser2: { user: IUser; credentials: Credentials }; let testDepartment: ILivechatDepartment; before(async () => { @@ -242,8 +242,8 @@ import { IS_EE } from '../../../e2e/config/constants'; await updateSetting('Livechat_Routing_Method', 'Load_Rotation'); }); - let testUser: { user: IUser; credentials: IUserCredentialsHeader }; - let testUser2: { user: IUser; credentials: IUserCredentialsHeader }; + let testUser: { user: IUser; credentials: Credentials }; + let testUser2: { user: IUser; credentials: Credentials }; let testDepartment: ILivechatDepartment; before(async () => { diff --git a/apps/meteor/tests/end-to-end/api/livechat/methods/changeLivechatStatus.ts b/apps/meteor/tests/end-to-end/api/livechat/methods/changeLivechatStatus.ts index d299acb15764..9067965f4d18 100644 --- a/apps/meteor/tests/end-to-end/api/livechat/methods/changeLivechatStatus.ts +++ b/apps/meteor/tests/end-to-end/api/livechat/methods/changeLivechatStatus.ts @@ -1,3 +1,4 @@ +import type { Credentials } from '@rocket.chat/api-client'; import type { ILivechatAgent, IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; @@ -10,17 +11,15 @@ import { updatePermission, updateSetting } from '../../../../data/permissions.he import { password } from '../../../../data/user'; import { createUser, deleteUser, getMe, login } from '../../../../data/users.helper'; -describe('livechat:changeLivechatStatus', function () { - this.retries(0); - - let agent: { user: IUser; credentials: { 'X-Auth-Token': string; 'X-User-Id': string } }; +describe('livechat:changeLivechatStatus', () => { + let agent: { user: IUser; credentials: Credentials }; before((done) => getCredentials(done)); before(async () => { await updateSetting('Livechat_enabled', true); - const user: IUser = await createUser(); + const user = await createUser(); const userCredentials = await login(user.username, password); await createAgent(user.username); @@ -60,7 +59,7 @@ describe('livechat:changeLivechatStatus', function () { await updatePermission('manage-livechat-agents', ['admin']); }); it('should return an error if user is not an agent', async () => { - const user: IUser = await createUser(); + const user = await createUser(); const userCredentials = await login(user.username, password); await request .post(methodCall('livechat:changeLivechatStatus')) @@ -128,7 +127,7 @@ describe('livechat:changeLivechatStatus', function () { }); }); it('should change logged in users status', async () => { - const currentUser: ILivechatAgent = await getMe(agent.credentials as any); + const currentUser: ILivechatAgent = await getMe(agent.credentials); const currentStatus = currentUser.statusLivechat; const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; @@ -153,7 +152,7 @@ describe('livechat:changeLivechatStatus', function () { it('should allow managers to change other agents status', async () => { await updatePermission('manage-livechat-agents', ['admin']); - const currentUser: ILivechatAgent = await getMe(agent.credentials as any); + const currentUser: ILivechatAgent = await getMe(agent.credentials); const currentStatus = currentUser.statusLivechat; const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; @@ -178,7 +177,7 @@ describe('livechat:changeLivechatStatus', function () { it('should throw an error if agent tries to make themselves available outside of Business hour', async () => { await makeDefaultBusinessHourActiveAndClosed(); - const currentUser: ILivechatAgent = await getMe(agent.credentials as any); + const currentUser: ILivechatAgent = await getMe(agent.credentials); const currentStatus = currentUser.statusLivechat; const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; @@ -204,7 +203,7 @@ describe('livechat:changeLivechatStatus', function () { it('should allow managers to make other agents available outside business hour', async () => { await updatePermission('manage-livechat-agents', ['admin']); - const currentUser: ILivechatAgent = await getMe(agent.credentials as any); + const currentUser: ILivechatAgent = await getMe(agent.credentials); const currentStatus = currentUser.statusLivechat; const newStatus = currentStatus === 'available' ? 'not-available' : 'available'; diff --git a/apps/meteor/tests/end-to-end/apps/00-installation.js b/apps/meteor/tests/end-to-end/apps/00-installation.ts similarity index 82% rename from apps/meteor/tests/end-to-end/apps/00-installation.js rename to apps/meteor/tests/end-to-end/apps/00-installation.ts index f8633439a702..a3cfd3c17ce0 100644 --- a/apps/meteor/tests/end-to-end/apps/00-installation.js +++ b/apps/meteor/tests/end-to-end/apps/00-installation.ts @@ -1,15 +1,15 @@ import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, request, credentials, api } from '../../data/api-data.js'; -import { APP_URL, apps, APP_USERNAME } from '../../data/apps/apps-data.js'; -import { cleanupApps } from '../../data/apps/helper.js'; +import { getCredentials, request, credentials, api } from '../../data/api-data'; +import { APP_URL, apps } from '../../data/apps/apps-data'; +import { cleanupApps } from '../../data/apps/helper'; import { updatePermission } from '../../data/permissions.helper'; -import { getUserByUsername } from '../../data/users.helper.js'; +import { getUserByUsername } from '../../data/users.helper'; -describe('Apps - Installation', function () { - this.retries(0); +const APP_USERNAME = 'appsrocketchattester.bot'; +describe('Apps - Installation', () => { before((done) => getCredentials(done)); before(async () => cleanupApps()); @@ -18,8 +18,8 @@ describe('Apps - Installation', function () { describe('[Installation]', () => { it('should throw an error when trying to install an app and the apps framework is enabled but the user does not have the permission', (done) => { - updatePermission('manage-apps', []).then(() => { - request + void updatePermission('manage-apps', []).then(() => { + void request .post(apps()) .set(credentials) .send({ @@ -35,8 +35,8 @@ describe('Apps - Installation', function () { }); }); it('should install the app successfully from a URL', (done) => { - updatePermission('manage-apps', ['admin']).then(() => { - request + void updatePermission('manage-apps', ['admin']).then(() => { + void request .post(apps()) .set(credentials) .send({ @@ -55,7 +55,7 @@ describe('Apps - Installation', function () { }); }); it('should have created the app user successfully', (done) => { - getUserByUsername(APP_USERNAME) + void getUserByUsername(APP_USERNAME) .then((user) => { expect(user.username).to.be.equal(APP_USERNAME); }) @@ -63,8 +63,9 @@ describe('Apps - Installation', function () { }); describe('Slash commands registration', () => { it('should have created the "test-simple" slash command successfully', (done) => { - request - .get(api('commands.get?command=test-simple')) + void request + .get(api('commands.get')) + .query({ command: 'test-simple' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -76,8 +77,9 @@ describe('Apps - Installation', function () { .end(done); }); it('should have created the "test-with-arguments" slash command successfully', (done) => { - request - .get(api('commands.get?command=test-with-arguments')) + void request + .get(api('commands.get')) + .query({ command: 'test-with-arguments' }) .set(credentials) .expect('Content-Type', 'application/json') .expect(200) @@ -91,7 +93,7 @@ describe('Apps - Installation', function () { }); describe('Video Conf Provider registration', () => { it('should have created two video conf provider successfully', (done) => { - request + void request .get(api('video-conference.providers')) .set(credentials) .expect('Content-Type', 'application/json') diff --git a/apps/meteor/tests/end-to-end/apps/01-send-messages.js b/apps/meteor/tests/end-to-end/apps/01-send-messages.ts similarity index 82% rename from apps/meteor/tests/end-to-end/apps/01-send-messages.js rename to apps/meteor/tests/end-to-end/apps/01-send-messages.ts index 3f729715915f..9cfb9f2688d1 100644 --- a/apps/meteor/tests/end-to-end/apps/01-send-messages.js +++ b/apps/meteor/tests/end-to-end/apps/01-send-messages.ts @@ -1,15 +1,15 @@ +import type { App, IMessage, IRoom } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, request, credentials } from '../../data/api-data.js'; -import { apps } from '../../data/apps/apps-data.js'; -import { cleanupApps, installTestApp } from '../../data/apps/helper.js'; -import { getMessageById } from '../../data/chat.helper.js'; +import { getCredentials, request, credentials } from '../../data/api-data'; +import { apps } from '../../data/apps/apps-data'; +import { cleanupApps, installTestApp } from '../../data/apps/helper'; +import { getMessageById } from '../../data/chat.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; -describe('Apps - Send Messages As APP User', function () { - this.retries(0); - let app; +describe('Apps - Send Messages As APP User', () => { + let app: App; before((done) => getCredentials(done)); before(async () => { @@ -21,25 +21,25 @@ describe('Apps - Send Messages As APP User', function () { describe('[Send Message as app user]', () => { it('should return an error when the room is not found', (done) => { - request + void request .post(apps(`/public/${app.id}/send-message-as-app-user`)) .send({ roomId: 'invalid-room', }) .set(credentials) .expect(404) - .expect((err, res) => { + .expect((err: unknown, res: undefined) => { expect(err).to.have.a.property('error'); expect(res).to.be.equal(undefined); - expect(err.error).to.have.a.property('text'); - expect(err.error.text).to.be.equal('Room "invalid-room" could not be found'); + expect((err as { error?: any }).error).to.have.a.property('text'); + expect((err as { error?: any }).error.text).to.be.equal('Room "invalid-room" could not be found'); }) .end(done); }); describe('Send to a Public Channel', () => { - let publicMessageId; + let publicMessageId: IMessage['_id']; it('should send a message as app user', (done) => { - request + void request .post(apps(`/public/${app.id}/send-message-as-app-user`)) .set(credentials) .send({ @@ -59,8 +59,8 @@ describe('Apps - Send Messages As APP User', function () { }); }); describe('Send to a Private Channel', () => { - let privateMessageId; - let group; + let privateMessageId: IMessage['_id']; + let group: IRoom; before(async () => { group = ( @@ -74,7 +74,7 @@ describe('Apps - Send Messages As APP User', function () { after(() => deleteRoom({ type: 'p', roomId: group._id })); it('should send a message as app user', (done) => { - request + void request .post(apps(`/public/${app.id}/send-message-as-app-user`)) .set(credentials) .send({ @@ -94,8 +94,8 @@ describe('Apps - Send Messages As APP User', function () { }); }); describe('Send to a DM Channel', () => { - let DMMessageId; - let dmRoom; + let DMMessageId: IMessage['_id']; + let dmRoom: IRoom; before(async () => { dmRoom = ( @@ -109,7 +109,7 @@ describe('Apps - Send Messages As APP User', function () { after(() => deleteRoom({ type: 'd', roomId: dmRoom._id })); it('should send a message as app user', (done) => { - request + void request .post(apps(`/public/${app.id}/send-message-as-app-user`)) .set(credentials) .send({ diff --git a/apps/meteor/tests/end-to-end/apps/02-send-messages-as-user.js b/apps/meteor/tests/end-to-end/apps/02-send-messages-as-user.ts similarity index 78% rename from apps/meteor/tests/end-to-end/apps/02-send-messages-as-user.js rename to apps/meteor/tests/end-to-end/apps/02-send-messages-as-user.ts index 61d812571d7d..401a011cecea 100644 --- a/apps/meteor/tests/end-to-end/apps/02-send-messages-as-user.js +++ b/apps/meteor/tests/end-to-end/apps/02-send-messages-as-user.ts @@ -1,17 +1,19 @@ +import type { Credentials } from '@rocket.chat/api-client'; +import type { App, IMessage, IRoom, IUser } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, request, credentials } from '../../data/api-data.js'; -import { apps } from '../../data/apps/apps-data.js'; -import { cleanupApps, installTestApp } from '../../data/apps/helper.js'; -import { getMessageById } from '../../data/chat.helper.js'; +import { getCredentials, request, credentials } from '../../data/api-data'; +import { apps } from '../../data/apps/apps-data'; +import { cleanupApps, installTestApp } from '../../data/apps/helper'; +import { getMessageById } from '../../data/chat.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { adminUsername, password } from '../../data/user'; -import { createUser, deleteUser, login } from '../../data/users.helper.js'; +import type { TestUser } from '../../data/users.helper'; +import { createUser, deleteUser, login } from '../../data/users.helper'; -describe('Apps - Send Messages As User', function () { - this.retries(0); - let app; +describe('Apps - Send Messages As User', () => { + let app: App; before((done) => getCredentials(done)); before(async () => { @@ -23,41 +25,41 @@ describe('Apps - Send Messages As User', function () { describe('[Send Message as user]', () => { it('should return an error when the room is not found', (done) => { - request + void request .post(apps(`/public/${app.id}/send-message-as-user`)) .send({ roomId: 'invalid-room', }) .set(credentials) .expect(404) - .expect((err, res) => { + .expect((err: unknown, res: undefined) => { expect(err).to.have.a.property('error'); expect(res).to.be.equal(undefined); - expect(err.error).to.have.a.property('text'); - expect(err.error.text).to.be.equal('Room "invalid-room" could not be found'); + expect((err as { error?: any }).error).to.have.a.property('text'); + expect((err as { error?: any }).error.text).to.be.equal('Room "invalid-room" could not be found'); }) .end(done); }); it('should return an error when the user is not found', (done) => { - request + void request .post(apps(`/public/${app.id}/send-message-as-user?userId=invalid-user`)) .send({ roomId: 'GENERAL', }) .set(credentials) .expect(404) - .expect((err, res) => { + .expect((err: unknown, res: undefined) => { expect(err).to.have.a.property('error'); expect(res).to.be.equal(undefined); - expect(err.error).to.have.a.property('text'); - expect(err.error.text).to.be.equal('User with id "invalid-user" could not be found'); + expect((err as { error?: any }).error).to.have.a.property('text'); + expect((err as { error?: any }).error.text).to.be.equal('User with id "invalid-user" could not be found'); }) .end(done); }); describe('Send to a Public Channel', () => { - let publicMessageId; + let publicMessageId: IMessage['_id']; it('should send a message as app user', (done) => { - request + void request .post(apps(`/public/${app.id}/send-message-as-user?userId=${adminUsername}`)) .set(credentials) .send({ @@ -77,10 +79,10 @@ describe('Apps - Send Messages As User', function () { }); }); describe('Send to a Private Channel', () => { - let privateMessageId; - let group; - let user; - let userCredentials; + let privateMessageId: IMessage['_id']; + let group: IRoom; + let user: TestUser; + let userCredentials: Credentials; before(async () => { group = ( @@ -96,7 +98,7 @@ describe('Apps - Send Messages As User', function () { after(() => Promise.all([deleteRoom({ type: 'p', roomId: group._id }), deleteUser(user)])); it('should return 500 when sending a message as user that has no permissions', (done) => { - request + void request .post(apps(`/public/${app.id}/send-message-as-user?userId=${user._id}`)) .set(userCredentials) .send({ @@ -106,7 +108,7 @@ describe('Apps - Send Messages As User', function () { .end(done); }); it('should send a message as app user', (done) => { - request + void request .post(apps(`/public/${app.id}/send-message-as-user?userId=${adminUsername}`)) .set(credentials) .send({ @@ -126,8 +128,8 @@ describe('Apps - Send Messages As User', function () { }); }); describe('Send to a DM Channel', () => { - let DMMessageId; - let dmRoom; + let DMMessageId: IMessage['_id']; + let dmRoom: IRoom; before(async () => { dmRoom = ( @@ -141,7 +143,7 @@ describe('Apps - Send Messages As User', function () { after(() => deleteRoom({ type: 'd', roomId: dmRoom._id })); it('should send a message as app user', (done) => { - request + void request .post(apps(`/public/${app.id}/send-message-as-user?userId=${adminUsername}`)) .set(credentials) .send({ diff --git a/apps/meteor/tests/end-to-end/apps/03-slash-command-test-simple.js b/apps/meteor/tests/end-to-end/apps/03-slash-command-test-simple.ts similarity index 84% rename from apps/meteor/tests/end-to-end/apps/03-slash-command-test-simple.js rename to apps/meteor/tests/end-to-end/apps/03-slash-command-test-simple.ts index 64f25778fac2..c74bcffaa4a2 100644 --- a/apps/meteor/tests/end-to-end/apps/03-slash-command-test-simple.js +++ b/apps/meteor/tests/end-to-end/apps/03-slash-command-test-simple.ts @@ -1,12 +1,11 @@ +import type { IMessage } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, request, credentials, api } from '../../data/api-data.js'; -import { cleanupApps, installTestApp } from '../../data/apps/helper.js'; - -describe('Apps - Slash Command "test-simple"', function () { - this.retries(0); +import { getCredentials, request, credentials, api } from '../../data/api-data'; +import { cleanupApps, installTestApp } from '../../data/apps/helper'; +describe('Apps - Slash Command "test-simple"', () => { before((done) => getCredentials(done)); before(async () => { await cleanupApps(); @@ -17,7 +16,7 @@ describe('Apps - Slash Command "test-simple"', function () { describe('[Slash command "test-simple"]', () => { it('should return an error when no command is provided', (done) => { - request + void request .post(api('commands.run')) .send({ roomId: 'GENERAL', @@ -32,7 +31,7 @@ describe('Apps - Slash Command "test-simple"', function () { .end(done); }); it('should return an error when the command does not exist', (done) => { - request + void request .post(api('commands.run')) .send({ roomId: 'GENERAL', @@ -47,7 +46,7 @@ describe('Apps - Slash Command "test-simple"', function () { .end(done); }); it('should execute the slash command successfully', (done) => { - request + void request .post(api('commands.run')) .send({ roomId: 'GENERAL', @@ -61,7 +60,7 @@ describe('Apps - Slash Command "test-simple"', function () { .end(done); }); it('should have sent the message correctly', (done) => { - request + void request .get(api('chat.search')) .query({ roomId: 'GENERAL', @@ -70,7 +69,9 @@ describe('Apps - Slash Command "test-simple"', function () { .set(credentials) .expect(200) .expect((res) => { - const message = res.body.messages.find((message) => message.msg === "Slashcommand 'test-simple' successfully executed"); + const message = (res.body.messages as IMessage[]).find( + (message) => message.msg === "Slashcommand 'test-simple' successfully executed", + ); expect(message).to.not.be.equal(undefined); }) .end(done); diff --git a/apps/meteor/tests/end-to-end/apps/04-slash-command-test-with-arguments.js b/apps/meteor/tests/end-to-end/apps/04-slash-command-test-with-arguments.ts similarity index 81% rename from apps/meteor/tests/end-to-end/apps/04-slash-command-test-with-arguments.js rename to apps/meteor/tests/end-to-end/apps/04-slash-command-test-with-arguments.ts index 58ee4ab0d9c8..4701ed3c4c85 100644 --- a/apps/meteor/tests/end-to-end/apps/04-slash-command-test-with-arguments.js +++ b/apps/meteor/tests/end-to-end/apps/04-slash-command-test-with-arguments.ts @@ -1,12 +1,11 @@ +import type { IMessage } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, request, credentials, api } from '../../data/api-data.js'; -import { cleanupApps, installTestApp } from '../../data/apps/helper.js'; - -describe('Apps - Slash Command "test-with-arguments"', function () { - this.retries(0); +import { getCredentials, request, credentials, api } from '../../data/api-data'; +import { cleanupApps, installTestApp } from '../../data/apps/helper'; +describe('Apps - Slash Command "test-with-arguments"', () => { before((done) => getCredentials(done)); before(async () => { await cleanupApps(); @@ -18,7 +17,7 @@ describe('Apps - Slash Command "test-with-arguments"', function () { describe('[Slash command "test-with-arguments"]', () => { const params = 'argument'; it('should execute the slash command successfully', (done) => { - request + void request .post(api('commands.run')) .send({ roomId: 'GENERAL', @@ -34,7 +33,7 @@ describe('Apps - Slash Command "test-with-arguments"', function () { }); it('should have sent the message correctly', (done) => { const searchText = `Slashcommand \'test-with-arguments\' successfully executed with arguments: "${params}"`; - request + void request .get(api('chat.search')) .query({ roomId: 'GENERAL', @@ -43,7 +42,7 @@ describe('Apps - Slash Command "test-with-arguments"', function () { .set(credentials) .expect(200) .expect((res) => { - const message = res.body.messages.find((message) => message.msg === searchText); + const message = (res.body.messages as IMessage[]).find((message) => message.msg === searchText); expect(message).to.not.be.equal(undefined); }) .end(done); diff --git a/apps/meteor/tests/end-to-end/apps/05-video-conferences.ts b/apps/meteor/tests/end-to-end/apps/05-video-conferences.ts index d7772b7a233a..8d29eee97b7d 100644 --- a/apps/meteor/tests/end-to-end/apps/05-video-conferences.ts +++ b/apps/meteor/tests/end-to-end/apps/05-video-conferences.ts @@ -2,15 +2,13 @@ import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; import type { Response } from 'supertest'; -import { getCredentials, request, api, credentials } from '../../data/api-data.js'; -import { cleanupApps, installTestApp } from '../../data/apps/helper.js'; +import { getCredentials, request, api, credentials } from '../../data/api-data'; +import { cleanupApps, installTestApp } from '../../data/apps/helper'; import { updateSetting } from '../../data/permissions.helper'; import { createRoom, deleteRoom } from '../../data/rooms.helper'; import { adminUsername } from '../../data/user'; -describe('Apps - Video Conferences', function () { - this.retries(0); - +describe('Apps - Video Conferences', () => { before((done) => getCredentials(done)); const roomName = `apps-e2etest-room-${Date.now()}-videoconf`; diff --git a/apps/meteor/tests/end-to-end/apps/apps-uninstall.js b/apps/meteor/tests/end-to-end/apps/apps-uninstall.ts similarity index 85% rename from apps/meteor/tests/end-to-end/apps/apps-uninstall.js rename to apps/meteor/tests/end-to-end/apps/apps-uninstall.ts index 15130c79e129..e51bbb31bd96 100644 --- a/apps/meteor/tests/end-to-end/apps/apps-uninstall.js +++ b/apps/meteor/tests/end-to-end/apps/apps-uninstall.ts @@ -1,13 +1,13 @@ +import type { App } from '@rocket.chat/core-typings'; import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; -import { getCredentials, request, credentials } from '../../data/api-data.js'; -import { apps } from '../../data/apps/apps-data.js'; -import { installTestApp, cleanupApps } from '../../data/apps/helper.js'; +import { getCredentials, request, credentials } from '../../data/api-data'; +import { apps } from '../../data/apps/apps-data'; +import { installTestApp, cleanupApps } from '../../data/apps/helper'; -describe('Apps - Uninstall', function () { - this.retries(0); - let app; +describe('Apps - Uninstall', () => { + let app: App; before((done) => getCredentials(done)); @@ -20,7 +20,7 @@ describe('Apps - Uninstall', function () { describe('[Uninstall]', () => { it('should throw an error when trying to uninstall an invalid app', (done) => { - request + void request .delete(apps('/invalid-id')) .set(credentials) .expect('Content-Type', 'application/json') @@ -32,7 +32,7 @@ describe('Apps - Uninstall', function () { .end(done); }); it('should remove the app successfully', (done) => { - request + void request .delete(apps(`/${app.id}`)) .set(credentials) .expect('Content-Type', 'application/json') diff --git a/apps/meteor/tests/end-to-end/teardown.js b/apps/meteor/tests/end-to-end/teardown.ts similarity index 59% rename from apps/meteor/tests/end-to-end/teardown.js rename to apps/meteor/tests/end-to-end/teardown.ts index 0cf40a45e504..7ad3917a985c 100644 --- a/apps/meteor/tests/end-to-end/teardown.js +++ b/apps/meteor/tests/end-to-end/teardown.ts @@ -1,12 +1,13 @@ import { afterEach } from 'mocha'; +import type { Response } from 'supertest'; -import { request } from '../data/api-data.js'; +import { request } from '../data/api-data'; -const methods = ['get', 'post', 'put', 'del']; +const methods = ['get', 'post', 'put', 'del'] as const; -let lastUrl; -let lastMethod; -let lastResponse; +let lastUrl: string; +let lastMethod: string; +let lastResponse: Response; methods.forEach((method) => { const original = request[method]; @@ -20,7 +21,7 @@ methods.forEach((method) => { }); afterEach(async function () { - if (this.currentTest.state === 'failed') { + if (this.currentTest?.state === 'failed') { console.log({ lastUrl, lastMethod, diff --git a/apps/meteor/tests/unit/app/markdown/client.tests.js b/apps/meteor/tests/unit/app/markdown/client.tests.js index cf970b1822e6..7b32fae7e4bf 100644 --- a/apps/meteor/tests/unit/app/markdown/client.tests.js +++ b/apps/meteor/tests/unit/app/markdown/client.tests.js @@ -1,7 +1,7 @@ import { escapeHTML } from '@rocket.chat/string-helpers'; import { expect } from 'chai'; -import { Markdown, original, filtered } from './client.mocks.js'; +import { Markdown, original, filtered } from './client.mocks'; const wrapper = (text, tag) => `${tag}${text}${tag}`; const boldWrapper = (text) => wrapper(`${text}`, '*'); diff --git a/ee/packages/api-client/src/Credentials.ts b/ee/packages/api-client/src/Credentials.ts new file mode 100644 index 000000000000..721c9aa5a90c --- /dev/null +++ b/ee/packages/api-client/src/Credentials.ts @@ -0,0 +1,4 @@ +export type Credentials = { + 'X-User-Id': string; + 'X-Auth-Token': string; +}; diff --git a/ee/packages/api-client/src/index.ts b/ee/packages/api-client/src/index.ts index 7a664b9fcc8a..a11e032e91b2 100644 --- a/ee/packages/api-client/src/index.ts +++ b/ee/packages/api-client/src/index.ts @@ -9,10 +9,11 @@ import type { } from '@rocket.chat/rest-typings'; import { stringify } from 'query-string'; +import type { Credentials } from './Credentials'; import type { Middleware, RestClientInterface } from './RestClientInterface'; import { hasRequiredTwoFactorMethod, isTotpInvalidError, isTotpRequiredError } from './errors'; -export { RestClientInterface }; +export { RestClientInterface, Credentials }; const pipe = any>(fn: T) => @@ -60,25 +61,9 @@ export class RestClient implements RestClientInterface { private headers: Record = {}; - private credentials: - | { - 'X-User-Id': string; - 'X-Auth-Token': string; - } - | undefined; - - constructor({ - baseUrl, - credentials, - headers = {}, - }: { - baseUrl: string; - credentials?: { - 'X-User-Id': string; - 'X-Auth-Token': string; - }; - headers?: Record; - }) { + private credentials: Credentials | undefined; + + constructor({ baseUrl, credentials, headers = {} }: { baseUrl: string; credentials?: Credentials; headers?: Record }) { this.baseUrl = `${baseUrl}/api`; this.setCredentials(credentials); this.headers = headers; diff --git a/packages/core-typings/src/IRoom.ts b/packages/core-typings/src/IRoom.ts index 74d4ca2ef487..accc78585c29 100644 --- a/packages/core-typings/src/IRoom.ts +++ b/packages/core-typings/src/IRoom.ts @@ -94,8 +94,6 @@ export interface IRoom extends IRocketChatRecord { /* @deprecated */ customFields?: Record; - channel?: { _id: string }; - usersWaitingForE2EKeys?: { userId: IUser['_id']; ts: Date }[]; } diff --git a/packages/core-typings/src/IUser.ts b/packages/core-typings/src/IUser.ts index d7de094b90c1..136146e40a34 100644 --- a/packages/core-typings/src/IUser.ts +++ b/packages/core-typings/src/IUser.ts @@ -152,7 +152,6 @@ export interface IUser extends IRocketChatRecord { private_key: string; public_key: string; }; - requirePasswordChange?: boolean; customFields?: { [key: string]: any; }; @@ -184,6 +183,8 @@ export interface IUser extends IRocketChatRecord { }; importIds?: string[]; _pendingAvatarUrl?: string; + requirePasswordChange?: boolean; + requirePasswordChangeReason?: string; } export interface IRegisterUser extends IUser { diff --git a/packages/password-policies/package.json b/packages/password-policies/package.json index 920554bad203..4b2f0c76b7ae 100644 --- a/packages/password-policies/package.json +++ b/packages/password-policies/package.json @@ -3,7 +3,7 @@ "version": "0.0.2", "private": true, "devDependencies": { - "@types/chai": "^4.3.9", + "@types/chai": "~4.3.16", "@types/jest": "~29.5.7", "chai": "^4.3.10", "eslint": "~8.45.0", diff --git a/packages/rest-typings/src/v1/rooms.ts b/packages/rest-typings/src/v1/rooms.ts index ee05f10f2c14..1c0b6a360f7b 100644 --- a/packages/rest-typings/src/v1/rooms.ts +++ b/packages/rest-typings/src/v1/rooms.ts @@ -575,7 +575,7 @@ export type RoomsEndpoints = { '/v1/rooms.createDiscussion': { POST: (params: RoomsCreateDiscussionProps) => { - discussion: IRoom; + discussion: IRoom & { rid: IRoom['_id'] }; }; }; diff --git a/packages/web-ui-registration/src/ResetPassword/ResetPasswordPage.tsx b/packages/web-ui-registration/src/ResetPassword/ResetPasswordPage.tsx index 15290a823d4a..daf66606f98f 100644 --- a/packages/web-ui-registration/src/ResetPassword/ResetPasswordPage.tsx +++ b/packages/web-ui-registration/src/ResetPassword/ResetPasswordPage.tsx @@ -1,3 +1,4 @@ +import type { IUser } from '@rocket.chat/core-typings'; import { Button, FieldGroup, Field, FieldLabel, ButtonGroup, PasswordInput, FieldRow, FieldError } from '@rocket.chat/fuselage'; import { useUniqueId } from '@rocket.chat/fuselage-hooks'; import { Form } from '@rocket.chat/layout'; @@ -13,7 +14,7 @@ import HorizontalTemplate from '../template/HorizontalTemplate'; const getChangePasswordReason = ({ requirePasswordChange, requirePasswordChangeReason = requirePasswordChange ? 'You_need_to_change_your_password' : 'Please_enter_your_new_password_below', -}: { requirePasswordChange?: boolean; requirePasswordChangeReason?: TranslationKey } = {}): TranslationKey => requirePasswordChangeReason; +}: Pick = {}) => requirePasswordChangeReason as TranslationKey; const ResetPasswordPage = (): ReactElement => { const user = useUser(); diff --git a/yarn.lock b/yarn.lock index 97fe3c5151d5..116c715d3c60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9436,7 +9436,7 @@ __metadata: "@types/bcrypt": ^5.0.1 "@types/body-parser": ^1.19.4 "@types/busboy": ^1.5.2 - "@types/chai": ^4.3.9 + "@types/chai": ~4.3.16 "@types/chai-as-promised": ^7.1.7 "@types/chai-datetime": 0.0.38 "@types/chai-dom": 1.11.2 @@ -9870,7 +9870,7 @@ __metadata: version: 0.0.0-use.local resolution: "@rocket.chat/password-policies@workspace:packages/password-policies" dependencies: - "@types/chai": ^4.3.9 + "@types/chai": ~4.3.16 "@types/jest": ~29.5.7 chai: ^4.3.10 eslint: ~8.45.0 @@ -12994,10 +12994,10 @@ __metadata: languageName: node linkType: hard -"@types/chai@npm:*, @types/chai@npm:^4.3.9": - version: 4.3.9 - resolution: "@types/chai@npm:4.3.9" - checksum: 2300a2c7abd4cb590349927a759b3d0172211a69f363db06e585faf7874a47f125ef3b364cce4f6190e3668147587fc11164c791c9560cf9bce8478fb7019610 +"@types/chai@npm:*, @types/chai@npm:~4.3.16": + version: 4.3.16 + resolution: "@types/chai@npm:4.3.16" + checksum: bb5f52d1b70534ed8b4bf74bd248add003ffe1156303802ea367331607c06b494da885ffbc2b674a66b4f90c9ee88759790a5f243879f6759f124f22328f5e95 languageName: node linkType: hard @@ -18321,9 +18321,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001541": - version: 1.0.30001577 - resolution: "caniuse-lite@npm:1.0.30001577" - checksum: 26d2b4a498a2a6ad5a33c44c18a32497b59a3bb1963b8b9221ddcbfe166ed7f7a1f75a3de040870cdc2467ce35199c643cfe8c45e7208d8bc033e7877214b0f9 + version: 1.0.30001636 + resolution: "caniuse-lite@npm:1.0.30001636" + checksum: b0347fd2c8d346680a64d98b061c59cb8fbf149cdd03005a447fae4d21e6286d5bd161b43eefe3221c6624aacb3cda4e838ae83c95ff5313a547f84ca93bcc70 languageName: node linkType: hard