diff --git a/twake/backend/node/test/e2e/channels/channels.realtime.spec.ts b/twake/backend/node/test/e2e/channels/channels.realtime.spec.ts deleted file mode 100644 index d66cefe6..00000000 --- a/twake/backend/node/test/e2e/channels/channels.realtime.spec.ts +++ /dev/null @@ -1,176 +0,0 @@ -import "reflect-metadata"; -import { afterEach, beforeEach, describe, expect, it } from "@jest/globals"; -import { ObjectId } from "mongodb"; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -import io from "socket.io-client"; -import { Channel } from "../../../src/services/channels/entities/channel"; -import { - getChannelPath, - getPublicRoomName, -} from "../../../src/services/channels/services/channel/realtime"; -import { WorkspaceExecutionContext } from "../../../src/services/channels/types"; -import { init, TestPlatform } from "../setup"; -import { ChannelUtils, get as getChannelUtils } from "./utils"; -import gr from "../../../src/services/global-resolver"; - -describe("The Channels Realtime feature", () => { - const url = "/internal/services/channels/v1"; - let platform: TestPlatform; - let socket: SocketIOClient.Socket; - let channelUtils: ChannelUtils; - - beforeEach(async () => { - platform = await init({ - services: [ - "webserver", - "database", - "search", - "storage", - "message-queue", - "user", - "search", - "websocket", - "applications", - "webserver", - "channels", - "auth", - "search", - "realtime", - "counter", - "statistics", - "platform-services", - ], - }); - channelUtils = getChannelUtils(platform); - }); - - afterEach(async () => { - await platform.tearDown(); - platform = null; - socket && socket.close(); - socket = null; - }); - - function connect() { - socket = io.connect("http://localhost:3000", { path: "/socket" }); - socket.connect(); - } - - describe("On channel creation", () => { - it("should notify the client", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const roomToken = "twake"; - const channelName = new ObjectId().toString(); - - connect(); - socket.on("connect", () => { - socket - .emit("authenticate", { token: jwtToken }) - .on("authenticated", () => { - socket.emit("realtime:join", { - name: getPublicRoomName(platform.workspace), - token: roomToken, - }); - socket.on("realtime:join:error", () => done(new Error("Should not occur"))); - socket.on("realtime:join:success", async () => { - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource: { - name: channelName, - }, - }, - }); - - expect(response.statusCode).toEqual(201); - }); - socket.on( - "realtime:resource", - (event: { type: any; action: any; resource: { name: any } }) => { - // we can also receive other types of events (channel_activity etc) - if (event.type === "channel") { - expect(event.type).toEqual("channel"); - expect(event.action).toEqual("saved"); - expect(event.resource.name).toEqual(channelName); - done(); - } - }, - ); - }) - .on("unauthorized", () => { - done(new Error("Should not occur")); - }); - }); - }); - }); - - describe("On channel removal", () => { - it("should notify the client", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const roomToken = "twake"; - const channelName = new ObjectId().toString(); - - const channel = channelUtils.getChannel(platform.currentUser.id); - channel.name = channelName; - - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - channelUtils.getContext({ id: channel.owner }), - ); - - connect(); - socket.on("connect", () => { - socket - .emit("authenticate", { token: jwtToken }) - .on("authenticated", () => { - socket.on( - "realtime:resource", - (event: { action: string; type: any; path: any; resource: { id: any } }) => { - if (event.action !== "deleted" || event.type !== "channel") { - // we can receive event when resource is created... - // we can also receive other types of events (channel_activity etc) - return; - } - - expect(event.type).toEqual("channel"); - expect(event.action).toEqual("deleted"); - expect(event.path).toEqual( - getChannelPath( - { id: creationResult.entity.id } as Channel, - { - workspace: platform.workspace, - } as WorkspaceExecutionContext, - ), - ); - expect(event.resource.id).toEqual(creationResult.entity.id); - done(); - }, - ); - socket.emit("realtime:join", { - name: getPublicRoomName(platform.workspace), - token: roomToken, - }); - socket.on("realtime:join:error", () => done(new Error("Should not occur"))); - socket.on("realtime:join:success", async () => { - await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${creationResult.entity.company_id}/workspaces/${creationResult.entity.workspace_id}/channels/${creationResult.entity.id}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - }); - }) - .on("unauthorized", () => { - done(new Error("Should not occur")); - }); - }); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/channels/channels.rest.spec.ts b/twake/backend/node/test/e2e/channels/channels.rest.spec.ts deleted file mode 100644 index 2bf97a75..00000000 --- a/twake/backend/node/test/e2e/channels/channels.rest.spec.ts +++ /dev/null @@ -1,1350 +0,0 @@ -import { afterEach, beforeAll, beforeEach, describe, expect, it } from "@jest/globals"; -import { v1 as uuidv1 } from "uuid"; -import { deserialize } from "class-transformer"; -import { init, TestPlatform } from "../setup"; -import { - ResourceGetResponse, - ResourceListResponse, - ResourceUpdateResponse, - User, - Workspace, -} from "../../../src/utils/types"; -import { Channel, ChannelMember } from "../../../src/services/channels/entities"; -import { - ChannelExecutionContext, - ChannelVisibility, - WorkspaceExecutionContext, -} from "../../../src/services/channels/types"; -import { - getPrivateRoomName, - getPublicRoomName, -} from "../../../src/services/channels/services/channel/realtime"; -import { ChannelUtils, get as getChannelUtils } from "./utils"; -import { TestDbService } from "../utils.prepare.db"; -import { ChannelObject } from "../../../src/services/channels/services/channel/types"; -import { Api } from "../utils.api"; -import gr from "../../../src/services/global-resolver"; -import { createMessage, e2e_createThread } from "../messages/utils"; - -describe("The /internal/services/channels/v1 API", () => { - const url = "/internal/services/channels/v1"; - let platform: TestPlatform; - let channelUtils: ChannelUtils; - let testDbService: TestDbService; - let api: Api; - - beforeAll(async end => { - // platform = await init(); - // await platform.database.getConnector().drop(); - end(); - }); - - beforeEach(async () => { - platform = await init(); - testDbService = new TestDbService(platform); - api = new Api(platform); - channelUtils = getChannelUtils(platform); - }); - - afterEach(async () => { - await platform?.tearDown(); - platform = null; - }); - - async function testAccess(url, method, done) { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method, - url, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - expect(response.statusCode).toBe(400); - done(); - } - - function getContext(user?: User): WorkspaceExecutionContext { - return { - workspace: platform.workspace, - user: user || platform.currentUser, - }; - } - - /** - * Get a new channel instance - * - * @param owner will be a random uuidv4 if not defined - */ - function getChannel(owner: string = uuidv1()): Channel { - const channel = new Channel(); - - channel.name = "Test Channel"; - channel.company_id = platform.workspace.company_id; - channel.workspace_id = platform.workspace.workspace_id; - channel.is_default = false; - channel.visibility = ChannelVisibility.PRIVATE; - channel.archived = false; - channel.owner = owner; - - return channel; - } - - async function getChannelREST(channelId: string): Promise { - const response = await api.get( - `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${channelId}`, - ); - - expect(response.statusCode).toEqual(200); - - const channelGetResult: ResourceGetResponse = deserialize( - ResourceGetResponse, - response.body, - ); - - return channelGetResult.resource; - } - - describe("The GET /companies/:companyId/workspaces/:workspaceId/channels route", () => { - it("should 400 when companyId is not valid", async done => { - testAccess( - `${url}/companies/123/workspaces/${platform.workspace.workspace_id}/channels`, - "GET", - done, - ); - }); - - it("should 400 when workspaceId is not valid", async done => { - testAccess( - `${url}/companies/${platform.workspace.company_id}/workspaces/123/channels`, - "GET", - done, - ); - }); - - it("should return empty list of channels", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(0); - - done(); - }); - - it("should return list of workspace channels", async done => { - const channel = new Channel(); - channel.name = "Test Channel"; - const creationResult = await gr.services.channels.channels.save(channel, {}, getContext()); - - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(1); - expect(result.resources[0]).toMatchObject({ - id: creationResult.entity.id, - name: channel.name, - }); - - result.resources.forEach(r => { - expect(r.stats).toMatchObject({ - members: 1, - messages: 0, - }); - }); - - done(); - }); - - it("should return list of channels the user is member of", async done => { - const ws0pk = { id: uuidv1(), company_id: platform.workspace.company_id }; - await testDbService.createWorkspace(ws0pk); - const newUser = await testDbService.createUser([ws0pk]); - - const channel1 = getChannel(); - const channel2 = getChannel(); - - channel1.name = "Test Channel1"; - channel2.name = "Test Channel2"; - - const creationResults = await Promise.all([ - gr.services.channels.channels.save(channel1, {}, getContext()), - gr.services.channels.channels.save(channel2, {}, getContext()), - ]); - - await gr.services.channels.members.save( - { - channel_id: channel1.id, - workspace_id: channel1.workspace_id, - company_id: channel1.company_id, - user_id: newUser.id, - } as ChannelMember, - channelUtils.getChannelContext(channel1, platform.currentUser), - ); - - const jwtToken = await platform.auth.getJWTToken({ sub: newUser.id }); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - query: { - mine: "true", - }, - }); - - console.log(response.body); - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(1); - expect(result.resources[0]).toMatchObject({ - id: creationResults[0].entity.id, - }); - - done(); - }); - - it("should return pagination information when not all channels are returned", async done => { - await Promise.all( - "0123456789".split("").map(name => { - const channel = new Channel(); - channel.name = name; - return gr.services.channels.channels.save(channel, {}, getContext()); - }), - ).catch(() => done(new Error("Failed on creation"))); - - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - query: { - limit: "5", - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(5); - expect(result.next_page_token).toBeDefined; - - done(); - }); - - it("should be able to paginate over channels from pagination information", async done => { - await platform.database.getConnector().drop(); - - await Promise.all( - "0123456789".split("").map(name => { - const channel = new Channel(); - channel.name = name; - return gr.services.channels.channels.save(channel, {}, getContext()); - }), - ).catch(() => done(new Error("Failed on creation"))); - - const jwtToken = await platform.auth.getJWTToken(); - const firstPage = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - query: { - limit: "5", - }, - }); - - const firstPageChannels: ResourceListResponse = deserialize( - ResourceListResponse, - firstPage.body, - ); - - expect(firstPage.statusCode).toBe(200); - expect(firstPageChannels.resources.length).toEqual(5); - expect(firstPageChannels.next_page_token).toBeDefined; - - const nextPage = firstPageChannels.next_page_token; - const secondPage = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - query: { - limit: "5", - page_token: nextPage, - }, - }); - - const secondPageChannels: ResourceListResponse = deserialize( - ResourceListResponse, - secondPage.body, - ); - - expect(secondPage.statusCode).toBe(200); - expect(secondPageChannels.resources.length).toEqual(5); - - expect( - new Set([ - ...firstPageChannels.resources.map(resource => resource.id), - ...secondPageChannels.resources.map(resource => resource.id), - ]).size, - ).toEqual(10); - - done(); - }); - - it("should not return pagination information when all channels are returned", async done => { - await Promise.all( - "0123456789".split("").map(name => { - const channel = new Channel(); - channel.name = name; - return gr.services.channels.channels.save(channel, {}, getContext()); - }), - ).catch(() => done(new Error("Failed on creation"))); - - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - query: { - limit: "11", - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(10); - expect(result.next_page_token).not.toBeDefined; - - done(); - }); - - it("should return websockets information", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - query: { - websockets: "true", - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.websockets).toMatchObject([ - { room: getPublicRoomName(platform.workspace) }, - // user id is randomly generated - { room: expect.stringContaining(getPrivateRoomName(platform.workspace, { id: "" })) }, - ]); - - done(); - }); - - it.skip("should return websockets and direct information", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - query: { - websockets: "true", - mine: "true", - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.websockets.length).toEqual(3); - - done(); - }); - }); - - describe("The GET /companies/:companyId/workspaces/:workspaceId/channels/:id route", () => { - it("should 400 when companyId is not valid", async done => { - const channelId = "1"; - - testAccess( - `${url}/companies/123/workspaces/${platform.workspace.workspace_id}/channels/${channelId}`, - "GET", - done, - ); - }); - - it("should 400 when workspaceId is not valid", async done => { - const channelId = "1"; - - testAccess( - `${url}/companies/${platform.workspace.company_id}/workspaces/123/channels/${channelId}`, - "GET", - done, - ); - }); - - it("should return the requested channel", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = new Channel(); - channel.name = "Test Channel"; - channel.company_id = platform.workspace.company_id; - channel.workspace_id = platform.workspace.workspace_id; - - const creationResult = await gr.services.channels.channels.save(channel, {}, getContext()); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${creationResult.entity.id}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - expect(response.statusCode).toEqual(200); - - const channelGetResult: ResourceGetResponse = deserialize( - ResourceGetResponse, - response.body, - ); - - expect(channelGetResult.resource).toBeDefined(); - expect(channelGetResult.resource).toMatchObject({ - id: String(creationResult.entity.id), - name: creationResult.entity.name, - }); - expect(channelGetResult.websocket).toBeDefined(); - expect(channelGetResult.websocket).toMatchObject({ - name: creationResult.entity.name, - room: `/channels/${creationResult.entity.id}`, - token: expect.any(String), - }); - - done(); - }); - - it("channel counters", async done => { - await platform.database.getConnector().drop(); - - await testDbService.createDefault(platform); - - const channel = new Channel(); - channel.name = "Test counters Channel"; - channel.company_id = platform.workspace.company_id; - channel.workspace_id = platform.workspace.workspace_id; - channel.is_default = true; - channel.visibility = ChannelVisibility.PUBLIC; - channel.description = "test counters"; - channel.channel_group = "my channel group"; - - const creationResult = await gr.services.channels.channels.save(channel, {}, getContext()); - - const channelId = creationResult.entity.id; - - let resource = await getChannelREST(channelId); - - expect(resource).toMatchObject({ - company_id: platform.workspace.company_id, - workspace_id: platform.workspace.workspace_id, - // type: expect.stringMatching(/workspace|direct/), // TODO - id: expect.any(String), - icon: expect.any(String), - name: channel.name, - description: channel.description, - channel_group: channel.channel_group, - visibility: channel.visibility, - default: channel.is_default, - owner: platform.currentUser.id, - last_activity: expect.any(Number), - archived: false, - archivation_date: 0, //Timestamp - user_member: expect.any(Object), - stats: expect.any(Object), - }); - - expect(resource.stats).toMatchObject({ - members: 1, - messages: 0, - }); - - expect(resource.user_member).toMatchObject({ - id: expect.any(String), - user_id: platform.currentUser.id, - type: expect.stringMatching(/member|guest|bot/), - last_access: 0, //Timestamp in seconds - last_increment: 0, //Number - favorite: false, - // notification_level: "all" | "none" | "group_mentions" | "user_mentions", // TODO - }); - - const anotherUserId = uuidv1(); - await gr.services.channels.members.addUsersToChannel( - [ - { id: anotherUserId }, - { id: uuidv1() }, - { id: uuidv1() }, - { id: uuidv1() }, - { id: uuidv1() }, - ], - creationResult.entity, - { - user: { id: platform.currentUser.id }, - }, - ); - - resource = await getChannelREST(channelId); - - expect(resource.stats).toMatchObject({ - members: 6, - messages: 0, - }); - - await gr.services.channels.members.delete( - { - ...platform.workspace, - channel_id: channelId, - user_id: anotherUserId, - }, - { channel: creationResult.entity, user: platform.currentUser } as ChannelExecutionContext, - ); - - resource = await getChannelREST(channelId); - - expect(resource.stats).toMatchObject({ - members: 5, - messages: 0, - }); - - done(); - }); - }); - - describe("The POST /companies/:companyId/workspaces/:workspaceId/channels route", () => { - it("should 400 when companyId is not valid", async done => { - testAccess( - `${url}/companies/123/workspaces/${platform.workspace.workspace_id}/channels`, - "POST", - done, - ); - }); - - it("should 400 when workspaceId is not valid", async done => { - testAccess( - `${url}/companies/${platform.workspace.company_id}/workspaces/123/channels`, - "POST", - done, - ); - }); - - it("should create a channel", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource: { - name: "Test channel", - }, - }, - }); - - expect(response.statusCode).toEqual(201); - - const channelCreateResult: ResourceGetResponse = deserialize( - ResourceGetResponse, - response.body, - ); - - expect(channelCreateResult.resource).toBeDefined(); - expect(channelCreateResult.websocket).toBeDefined(); - - const res = channelCreateResult.resource; - - const createdChannel = await gr.services.channels.channels.get({ - company_id: res.company_id, - workspace_id: res.workspace_id, - id: res.id, - }); - - expect(channelCreateResult.websocket).toMatchObject({ - room: `/channels/${createdChannel.id}`, - token: expect.any(String), - }); - expect(createdChannel).toBeDefined(); - done(); - }); - - it("should fail when channel name is not defined", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource: { - description: "The channel description", - }, - }, - }); - - expect(response.statusCode).toEqual(400); - done(); - }); - }); - - describe.skip("The POST /companies/:companyId/workspaces/:workspaceId/channels/:id route", () => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - async function updateChannel(jwtToken: string, id: string, resource: any): Promise { - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${id}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource, - }, - }); - - const channelUpdateResult: ResourceUpdateResponse = deserialize( - ResourceUpdateResponse, - response.body, - ); - - expect(channelUpdateResult.resource).toBeDefined(); - expect(channelUpdateResult.websocket).toBeDefined(); - - return await gr.services.channels.channels.get({ - id, - company_id: platform.workspace.company_id, - workspace_id: platform.workspace.workspace_id, - }); - } - - async function updateChannelFail( - jwtToken: string, - id: string, - resource: unknown, - expectedCode: number, - ): Promise { - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${id}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource, - }, - }); - - expect(response.statusCode).toEqual(expectedCode); - } - - it("should 400 when companyId is not valid", async done => { - testAccess( - `${url}/companies/123/workspaces/${platform.workspace.workspace_id}/channels/1`, - "POST", - done, - ); - }); - - it("should 400 when workspaceId is not valid", async done => { - testAccess( - `${url}/companies/${platform.workspace.company_id}/workspaces/123/channels/1`, - "POST", - done, - ); - }); - - describe("When user is workspace moderator and channel has been created by other user", () => { - beforeEach(() => { - platform.currentUser.isWorkspaceModerator = true; - }); - - it("should fail when resource is not defined", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - await updateChannelFail(jwtToken, creationResult.entity.id, {}, 400); - done(); - }); - - it("should be able to update the is_default field", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - const updatedChannel = await updateChannel(jwtToken, creationResult.entity.id, { - is_default: true, - }); - - expect(updatedChannel).toMatchObject({ - id: channel.id, - name: "Test Channel", - company_id: channel.company_id, - workspace_id: channel.workspace_id, - is_default: true, - visibility: channel.visibility, - archived: channel.archived, - owner: channel.owner, - }); - done(); - }); - - it("should be able to update the visibility field", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - const updatedChannel = await updateChannel(jwtToken, creationResult.entity.id, { - visibility: ChannelVisibility.PUBLIC, - }); - - expect(updatedChannel).toMatchObject({ - id: channel.id, - name: "Test Channel", - company_id: channel.company_id, - workspace_id: channel.workspace_id, - is_default: channel.is_default, - visibility: ChannelVisibility.PUBLIC, - archived: channel.archived, - owner: channel.owner, - }); - done(); - }); - - it("should be able to update the archived field", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - const updatedChannel = await updateChannel(jwtToken, creationResult.entity.id, { - archived: true, - }); - expect(updatedChannel).toMatchObject({ - id: channel.id, - name: "Test Channel", - company_id: channel.company_id, - workspace_id: channel.workspace_id, - is_default: channel.is_default, - visibility: channel.visibility, - archived: true, - owner: channel.owner, - }); - done(); - }); - - it("should be able to update all the fields at the same time", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - const updatedChannel = await updateChannel(jwtToken, creationResult.entity.id, { - visibility: ChannelVisibility.PUBLIC, - is_default: true, - archived: true, - }); - - expect(updatedChannel).toMatchObject({ - id: channel.id, - name: "Test Channel", - company_id: channel.company_id, - workspace_id: channel.workspace_id, - is_default: true, - visibility: ChannelVisibility.PUBLIC, - archived: true, - owner: channel.owner, - }); - - done(); - }); - }); - - describe("When user is channel owner", () => { - beforeEach(() => { - platform.currentUser.isWorkspaceModerator = false; - }); - - it("should be able to update the is_default field", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(platform.currentUser.id); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - const updatedChannel = await updateChannel(jwtToken, creationResult.entity.id, { - is_default: true, - }); - - expect(updatedChannel).toMatchObject({ - id: channel.id, - name: "Test Channel", - company_id: channel.company_id, - workspace_id: channel.workspace_id, - is_default: true, - visibility: channel.visibility, - archived: channel.archived, - owner: channel.owner, - }); - - done(); - }); - - it("should be able to update the visibility field", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(platform.currentUser.id); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - const updatedChannel = await updateChannel(jwtToken, creationResult.entity.id, { - visibility: ChannelVisibility.PUBLIC, - }); - - expect(updatedChannel).toMatchObject({ - id: channel.id, - name: "Test Channel", - company_id: channel.company_id, - workspace_id: channel.workspace_id, - is_default: channel.is_default, - visibility: ChannelVisibility.PUBLIC, - archived: channel.archived, - owner: channel.owner, - }); - - done(); - }); - - it("should be able to update the archived field", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(platform.currentUser.id); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - const updatedChannel = await updateChannel(jwtToken, creationResult.entity.id, { - archived: true, - }); - - expect(updatedChannel).toMatchObject({ - id: channel.id, - name: "Test Channel", - company_id: channel.company_id, - workspace_id: channel.workspace_id, - is_default: channel.is_default, - visibility: channel.visibility, - archived: true, - owner: channel.owner, - }); - done(); - }); - - it("should be able to update all the fields at the same time", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(platform.currentUser.id); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - const updatedChannel = await updateChannel(jwtToken, creationResult.entity.id, { - visibility: ChannelVisibility.PUBLIC, - is_default: true, - archived: true, - }); - - expect(updatedChannel).toMatchObject({ - id: channel.id, - name: "Test Channel", - company_id: channel.company_id, - workspace_id: channel.workspace_id, - is_default: true, - visibility: ChannelVisibility.PUBLIC, - archived: true, - owner: channel.owner, - }); - - done(); - }); - }); - - describe("When user is 'standard' user and is not channel owner", () => { - beforeEach(() => { - platform.currentUser.isWorkspaceModerator = false; - }); - - it("should not be able to update the is_default field", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - await updateChannelFail( - jwtToken, - creationResult.entity.id, - { - is_default: true, - }, - 400, - ); - - done(); - }); - - it("should not be able to update the visibility field", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - await updateChannelFail( - jwtToken, - creationResult.entity.id, - { - visibility: ChannelVisibility.PUBLIC, - }, - 400, - ); - - done(); - }); - - it("should not be able to update the archived field", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - await updateChannelFail( - jwtToken, - creationResult.entity.id, - { - archived: true, - }, - 400, - ); - - done(); - }); - - it("should be able to update the 'name', 'description', 'icon' fields", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - const updatedChannel = await updateChannel(jwtToken, creationResult.entity.id, { - name: "This is a new name", - description: "This is a new description", - icon: "This is a new icon", - }); - - expect(updatedChannel).toMatchObject({ - id: channel.id, - name: "This is a new name", - description: "This is a new description", - icon: "This is a new icon", - company_id: channel.company_id, - workspace_id: channel.workspace_id, - is_default: channel.is_default, - visibility: channel.visibility, - archived: channel.archived, - owner: channel.owner, - }); - - done(); - }); - }); - }); - - describe.skip("The DELETE /companies/:companyId/workspaces/:workspaceId/channels/:id route", () => { - async function expectDeleteResult( - jwtToken: string, - url: string, - status: number, - ): Promise { - const response = await platform.app.inject({ - method: "DELETE", - url, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - expect(response.statusCode).toEqual(status); - } - - it("should 400 when companyId is not valid", async done => { - testAccess( - `${url}/companies/123/workspaces/${platform.workspace.workspace_id}/channels/1`, - "DELETE", - done, - ); - }); - - it("should 400 when workspaceId is not valid", async done => { - testAccess( - `${url}/companies/${platform.workspace.company_id}/workspaces/123/channels/1`, - "DELETE", - done, - ); - }); - - describe("When user is workspace moderator", () => { - beforeEach(() => { - platform.currentUser.isWorkspaceModerator = true; - }); - - it("should not be able to delete a direct channel", async done => { - platform.workspace.workspace_id = "direct"; - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - await expectDeleteResult( - jwtToken, - `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${creationResult.entity.id}`, - 400, - ); - done(); - }); - - it("should be able to delete any channel of the workspace", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - await expectDeleteResult( - jwtToken, - `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${creationResult.entity.id}`, - 204, - ); - done(); - }); - }); - - describe("When user is channel owner", () => { - beforeEach(() => { - platform.currentUser.isWorkspaceModerator = false; - }); - - it("should not be able to delete a direct channel", async done => { - platform.workspace.workspace_id = "direct"; - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(platform.currentUser.id); - - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - await expectDeleteResult( - jwtToken, - `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${creationResult.entity.id}`, - 400, - ); - done(); - }); - - it("should be able to delete the channel", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(platform.currentUser.id); - - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - await expectDeleteResult( - jwtToken, - `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${creationResult.entity.id}`, - 204, - ); - done(); - }); - }); - - describe("When user is not creator nor workspace moderator", () => { - beforeEach(() => { - platform.currentUser.isWorkspaceModerator = false; - }); - - it("should not be able to delete the channel", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - await expectDeleteResult( - jwtToken, - `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${creationResult.entity.id}`, - 400, - ); - done(); - }); - - it("should not be able to delete a direct channel", async done => { - platform.workspace.workspace_id = "direct"; - const jwtToken = await platform.auth.getJWTToken(); - - const channel = getChannel(); - - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - getContext({ id: channel.owner }), - ); - - await expectDeleteResult( - jwtToken, - `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${creationResult.entity.id}`, - 400, - ); - done(); - }); - }); - }); - - describe("The GET /companies/:companyId/workspaces/:workspaceId/recent route", () => { - it("should return list of recent channels for workspace", async done => { - await testDbService.createDefault(platform); - - const channels = []; - - for (let i = 0; i < 5; i++) { - const channel = new Channel(); - channel.name = `Regular Channel ${i}`; - channel.visibility = ChannelVisibility.PUBLIC; - const creationResult = await gr.services.channels.channels.save(channel, {}, getContext()); - channels.push(creationResult.entity); - } - - for (let i = 0; i < 5; i++) { - // const channel = channelUtils.getChannel(); - const directChannelIn = channelUtils.getDirectChannel(); - - const nextUser = await testDbService.createUser( - [{ id: platform.workspace.workspace_id, company_id: platform.workspace.company_id }], - { firstName: "FirstName" + i, lastName: "LastName" + i }, - ); - - const members = [platform.currentUser.id, nextUser.id]; - const directWorkspace: Workspace = { - company_id: platform.workspace.company_id, - workspace_id: ChannelVisibility.DIRECT, - }; - await Promise.all([ - // gr.services.channels.channels.save(channel, {}, getContext()), - gr.services.channels.channels.save( - directChannelIn, - { - members, - }, - { ...getContext(), ...{ workspace: directWorkspace } }, - ), - ]); - channels.push(directChannelIn); - } - - await new Promise(resolve => setTimeout(resolve, 2000)); - - console.log("done awaiting"); - - await e2e_createThread( - platform, - [ - { - company_id: platform.workspace.company_id, - created_at: 0, - created_by: "", - id: channels[2].id, - type: "channel", - workspace_id: platform.workspace.workspace_id, - }, - ], - createMessage({ text: "Initial thread message for regular channel" }), - ); - - await e2e_createThread( - platform, - [ - { - company_id: platform.workspace.company_id, - created_at: 0, - created_by: "", - id: channels[7].id, - type: "channel", - workspace_id: "direct", - }, - ], - createMessage({ text: "Some message" }), - ); - - await gr.services.channels.channels.markAsRead(channels[2], { id: platform.currentUser.id }); - await gr.services.channels.channels.markAsRead(channels[7], { id: platform.currentUser.id }); - - await new Promise(resolve => setTimeout(resolve, 2000)); - - const jwtToken = await platform.auth.getJWTToken(); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/channels/recent`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - expect(response.statusCode).toBe(200); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - console.log(result.resources[0]); - console.log(result.resources.map(a => `${a.name} — ${a.last_activity}`)); - - expect(result.resources.length).toEqual(10); - - expect(result.resources[0].name).toEqual("FirstName2 LastName2"); - expect(result.resources[1].name).toEqual("Regular Channel 2"); - - done(); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/channels/channels.search.spec.ts b/twake/backend/node/test/e2e/channels/channels.search.spec.ts deleted file mode 100644 index bb1da691..00000000 --- a/twake/backend/node/test/e2e/channels/channels.search.spec.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it } from "@jest/globals"; -import { v1 as uuidv1 } from "uuid"; -import { deserialize } from "class-transformer"; -import { init, TestPlatform } from "../setup"; -import { ResourceGetResponse, ResourceListResponse, User } from "../../../src/utils/types"; -import { Channel } from "../../../src/services/channels/entities"; -import { ChannelVisibility, WorkspaceExecutionContext } from "../../../src/services/channels/types"; -import { ChannelMember } from "../../../src/services/channels/entities"; -import { ChannelUtils, get as getChannelUtils } from "./utils"; -import { TestDbService } from "../utils.prepare.db"; -import { ChannelObject } from "../../../src/services/channels/services/channel/types"; -import { Api } from "../utils.api"; -import gr from "../../../src/services/global-resolver"; - -describe("The /internal/services/channels/v1 API", () => { - const url = "/internal/services/channels/v1"; - let platform: TestPlatform; - let channelUtils: ChannelUtils; - let testDbService: TestDbService; - let api: Api; - - beforeEach(async () => { - platform = await init(); - testDbService = new TestDbService(platform); - api = new Api(platform); - channelUtils = getChannelUtils(platform); - }); - - afterEach(async () => { - await platform?.tearDown(); - platform = null; - }); - - async function testAccess(url, method, done) { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method, - url, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - expect(response.statusCode).toBe(400); - done(); - } - - function getContext(user?: User): WorkspaceExecutionContext { - return { - workspace: platform.workspace, - user: user || platform.currentUser, - }; - } - - /** - * Get a new channel instance - * - * @param owner will be a random uuidv4 if not defined - */ - function getChannel(owner: string = uuidv1()): Channel { - const channel = new Channel(); - - channel.name = "Test Channel"; - channel.company_id = platform.workspace.company_id; - channel.workspace_id = platform.workspace.workspace_id; - channel.is_default = false; - channel.visibility = ChannelVisibility.PRIVATE; - channel.archived = false; - channel.owner = owner; - - return channel; - } - - async function getChannelREST(channelId: string): Promise { - const response = await api.get( - `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${channelId}`, - ); - - expect(response.statusCode).toEqual(200); - - const channelGetResult: ResourceGetResponse = deserialize( - ResourceGetResponse, - response.body, - ); - - return channelGetResult.resource; - } - - describe("Channels search", () => { - it("Should find channels by name", async done => { - const ws0pk = { id: uuidv1(), company_id: platform.workspace.company_id }; - await testDbService.createWorkspace(ws0pk); - const newUser = await testDbService.createUser([ws0pk]); - - for (let i = 0; i < 10; i++) { - const channel = getChannel(); - channel.name = `test channel ${i}`; - await gr.services.channels.channels.save(channel, {}, getContext()); - - if (i == 0) continue; - await gr.services.channels.members.save( - { - channel_id: channel.id, - workspace_id: channel.workspace_id, - company_id: channel.company_id, - user_id: newUser.id, - } as ChannelMember, - channelUtils.getChannelContext(channel, platform.currentUser), - ); - } - - await new Promise(r => setTimeout(() => r(true), 1000)); - - const jwtToken = await platform.auth.getJWTToken({ sub: newUser.id }); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/search`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - query: { - q: "test", - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(9); - done(); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/channels/direct-channels.spec.ts b/twake/backend/node/test/e2e/channels/direct-channels.spec.ts deleted file mode 100644 index 8c49e156..00000000 --- a/twake/backend/node/test/e2e/channels/direct-channels.spec.ts +++ /dev/null @@ -1,420 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it } from "@jest/globals"; -import { v1 as uuidv1 } from "uuid"; -import { deserialize } from "class-transformer"; -import { init, TestPlatform } from "../setup"; -import { - ResourceCreateResponse, - ResourceListResponse, - User, - Workspace, -} from "../../../src/utils/types"; -import { Channel } from "../../../src/services/channels/entities"; -import { ChannelVisibility, WorkspaceExecutionContext } from "../../../src/services/channels/types"; -import { ChannelUtils, get as getChannelUtils } from "./utils"; -import { DirectChannel } from "../../../src/services/channels/entities/direct-channel"; -import gr from "../../../src/services/global-resolver"; - -describe("The direct channels API", () => { - const url = "/internal/services/channels/v1"; - let platform: TestPlatform; - let channelUtils: ChannelUtils; - - beforeEach(async () => { - platform = await init({ - services: [ - "webserver", - "database", - "search", - "storage", - "message-queue", - "user", - "applications", - "websocket", - "channels", - "auth", - "storage", - "counter", - "statistics", - ], - }); - channelUtils = getChannelUtils(platform); - }); - - afterEach(async () => { - await platform.tearDown(); - }); - - function getContext(user?: User): WorkspaceExecutionContext { - return { - workspace: platform.workspace, - user: user || platform.currentUser, - }; - } - - describe("Channel List - GET /channels", () => { - it("should return empty list of direct channels", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/direct/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(0); - - done(); - }); - - it("should return list of direct channels the user is member of", async done => { - const channel = channelUtils.getChannel(); - const directChannelIn = channelUtils.getDirectChannel(); - const directChannelNotIn = channelUtils.getDirectChannel(); - const members = [platform.currentUser.id, uuidv1()]; - const directWorkspace: Workspace = { - company_id: platform.workspace.company_id, - workspace_id: ChannelVisibility.DIRECT, - }; - - const creationResult = await Promise.all([ - gr.services.channels.channels.save(channel, {}, getContext()), - gr.services.channels.channels.save( - directChannelIn, - { - members, - }, - { ...getContext(), ...{ workspace: directWorkspace } }, - ), - gr.services.channels.channels.save( - directChannelNotIn, - { - members: [uuidv1(), uuidv1()], - }, - { ...getContext({ id: uuidv1() }), ...{ workspace: directWorkspace } }, - ), - ]); - - const jwtToken = await platform.auth.getJWTToken(); - const directResponse = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/direct/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - const directResult: ResourceListResponse = deserialize( - ResourceListResponse, - directResponse.body, - ); - - expect(directResponse.statusCode).toBe(200); - expect(directResult.resources.length).toEqual(1); - - expect(directResult.resources[0]).toMatchObject({ - id: creationResult[1].entity.id, - workspace_id: ChannelVisibility.DIRECT, - user_member: { - user_id: platform.currentUser.id, - }, - }); - - expect(directResult.resources[0].members).toContain(members[0]); - expect(directResult.resources[0].members).toContain(members[1]); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(1); - expect(result.resources[0]).toMatchObject({ - id: creationResult[0].entity.id, - }); - - done(); - }); - - it("should not return direct channels in workspace list", async done => { - const channel = channelUtils.getChannel(); - const directChannelIn = channelUtils.getDirectChannel(); - const directChannelIn2 = channelUtils.getDirectChannel(); - const directChannelNotIn = channelUtils.getDirectChannel(); - const members = [platform.currentUser.id, uuidv1()]; - const directWorkspace: Workspace = { - company_id: platform.workspace.company_id, - workspace_id: ChannelVisibility.DIRECT, - }; - - const creationResult = await Promise.all([ - //This channel will automatically contains the requester because it is added automatically in it - gr.services.channels.channels.save(channel, {}, getContext()), - - //It will contain the currentUser - gr.services.channels.channels.save( - directChannelIn, - { - members, - }, - { ...getContext({ id: uuidv1() }), ...{ workspace: directWorkspace } }, - ), - - //This channel will automatically contains the requester because it is added automatically in it - gr.services.channels.channels.save( - directChannelIn2, - { - members: [uuidv1(), uuidv1()], - }, - { ...getContext(), ...{ workspace: directWorkspace } }, - ), - - //This channel will not contain the currentUser - gr.services.channels.channels.save( - directChannelNotIn, - { - members: [uuidv1(), uuidv1()], - }, - { ...getContext({ id: uuidv1() }), ...{ workspace: directWorkspace } }, - ), - ]); - - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(1); - expect(result.resources[0]).toMatchObject({ - id: creationResult[0].entity.id, - }); - expect(result.resources[0].visibility).not.toEqual(ChannelVisibility.DIRECT); - - done(); - }); - - it("should not return direct channels in workspace list with mine parameter", async done => { - const channel = channelUtils.getChannel(); - const channel2 = channelUtils.getChannel(); - const directChannelIn = channelUtils.getDirectChannel(); - const directChannelNotIn = channelUtils.getDirectChannel(); - const members = [platform.currentUser.id, uuidv1()]; - const directWorkspace: Workspace = { - company_id: platform.workspace.company_id, - workspace_id: ChannelVisibility.DIRECT, - }; - - await Promise.all([ - //This channel will automatically contains the requester because it is added automatically in it - gr.services.channels.channels.save(channel, {}, getContext()), - - //This channel will not contain currentUser - gr.services.channels.channels.save(channel2, {}, getContext({ id: uuidv1() })), - - //This channel will automatically contains the requester because it is added automatically in it - gr.services.channels.channels.save( - directChannelIn, - { - members, - }, - { ...getContext(), ...{ workspace: directWorkspace } }, - ), - - gr.services.channels.channels.save( - directChannelNotIn, - { - members: [uuidv1(), uuidv1(), uuidv1()], - }, - { ...getContext(), ...{ workspace: directWorkspace } }, - ), - ]); - - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - query: { - mine: "true", - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(1); - - done(); - }); - }); - - describe("Create direct channel - POST /channels", () => { - it("should be able to create a direct channel with members", async done => { - const jwtToken = await platform.auth.getJWTToken(); - - const members = [uuidv1(), platform.currentUser.id]; - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/direct/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - options: { - members, - }, - resource: { - description: "A direct channel description", - visibility: "direct", - }, - }, - }); - - expect(response.statusCode).toEqual(201); - - const channelCreateResult: ResourceCreateResponse = deserialize( - ResourceCreateResponse, - response.body, - ); - - expect(channelCreateResult.resource).toBeDefined(); - - const createdChannel = await gr.services.channels.channels.get({ - id: channelCreateResult.resource.id, - company_id: channelCreateResult.resource.company_id, - workspace_id: ChannelVisibility.DIRECT, - }); - expect(createdChannel).toBeDefined(); - - const directChannelEntity = await gr.services.channels.channels.getDirectChannel({ - channel_id: createdChannel.id, - company_id: createdChannel.company_id, - users: DirectChannel.getUsersAsString(members), - }); - expect(directChannelEntity).toBeDefined(); - - const directChannelsInCompany = await gr.services.channels.channels.getDirectChannelInCompany( - createdChannel.company_id, - members, - ); - expect(directChannelsInCompany).toBeDefined(); - - done(); - }); - - it("should not be able to create the same direct channel twice (with same users)", async done => { - function createChannel(members: string[]) { - return platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/direct/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - options: { - members, - }, - resource: { - name: "Hello", - visibility: "direct", - }, - }, - }); - } - - const jwtToken = await platform.auth.getJWTToken(); - const members = [uuidv1(), platform.currentUser.id]; - const ids = new Set(); - - let response = await createChannel(members); - expect(response.statusCode).toEqual(201); - let channelCreateResult: ResourceCreateResponse = deserialize( - ResourceCreateResponse, - response.body, - ); - ids.add(channelCreateResult.resource.id); - - response = await createChannel(members); - expect(response.statusCode).toEqual(201); - channelCreateResult = deserialize(ResourceCreateResponse, response.body); - ids.add(channelCreateResult.resource.id); - - expect(ids.size).toEqual(1); - - done(); - }); - - it("should not be able to create the same direct channel twice (with same users not in the same order)", async done => { - function createChannel(members: string[]) { - return platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/direct/channels`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - options: { - members, - }, - resource: { - name: "Hello", - visibility: "direct", - }, - }, - }); - } - - const jwtToken = await platform.auth.getJWTToken(); - const members = [uuidv1(), platform.currentUser.id]; - const ids = new Set(); - - let response = await createChannel(members); - expect(response.statusCode).toEqual(201); - let channelCreateResult: ResourceCreateResponse = deserialize( - ResourceCreateResponse, - response.body, - ); - ids.add(channelCreateResult.resource.id); - - response = await createChannel(members.reverse()); - expect(response.statusCode).toEqual(201); - channelCreateResult = deserialize(ResourceCreateResponse, response.body); - ids.add(channelCreateResult.resource.id); - - expect(ids.size).toEqual(1); - - done(); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/channels/skip-channel-members.realtime.spec.ts b/twake/backend/node/test/e2e/channels/skip-channel-members.realtime.spec.ts deleted file mode 100644 index eede90a7..00000000 --- a/twake/backend/node/test/e2e/channels/skip-channel-members.realtime.spec.ts +++ /dev/null @@ -1,177 +0,0 @@ -import "reflect-metadata"; -import { afterEach, beforeEach, describe, expect, it } from "@jest/globals"; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -import io from "socket.io-client"; -import { Channel, ChannelMember } from "../../../src/services/channels/entities"; -import { init, TestPlatform } from "../setup"; -import { ChannelUtils, get as getChannelUtils } from "./utils"; -import { getPublicRoomName } from "../../../src/services/channels/services/member/realtime"; -import { SaveResult } from "../../../src/core/platform/framework/api/crud-service"; -import gr from "../../../src/services/global-resolver"; - -describe.skip("The Channels Members Realtime feature", () => { - const url = "/internal/services/channels/v1"; - let platform: TestPlatform; - let socket: SocketIOClient.Socket; - let channelUtils: ChannelUtils; - - beforeEach(async () => { - platform = await init({ - services: [ - "message-queue", - "user", - "search", - "websocket", - "webserver", - "channels", - "auth", - "database", - "search", - "realtime", - ], - }); - channelUtils = getChannelUtils(platform); - }); - - afterEach(async () => { - await platform.tearDown(); - platform = null; - socket && socket.close(); - socket = null; - }); - - function connect() { - socket = io.connect("http://localhost:3000", { path: "/socket.io" }); - socket.connect(); - } - - describe("On channel member creation", () => { - let channel; - let createdChannel: SaveResult; - - beforeEach(async () => { - channel = channelUtils.getChannel(); - createdChannel = await gr.services.channels.channels.save( - channel, - {}, - channelUtils.getContext({ id: channel.owner }), - ); - }); - - it("should notify the client", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const roomToken = "twake"; - - connect(); - socket.on("connect", () => { - socket - .emit("authenticate", { token: jwtToken }) - .on("authenticated", () => { - socket.emit("realtime:join", { - name: getPublicRoomName(createdChannel.entity), - token: roomToken, - }); - socket.on("realtime:join:error", () => done(new Error("Should not occur"))); - socket.on("realtime:join:success", async () => { - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${createdChannel.entity.id}/members`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource: { - user_id: platform.currentUser.id, - }, - }, - }); - - expect(response.statusCode).toEqual(201); - }); - socket.on("realtime:resource", event => { - expect(event.type).toEqual("channel_member"); - expect(event.action).toEqual("saved"); - expect(event.resource).toMatchObject({ - company_id: platform.workspace.company_id, - workspace_id: platform.workspace.workspace_id, - user_id: platform.currentUser.id, - channel_id: createdChannel.entity.id, - }); - done(); - }); - }) - .on("unauthorized", () => { - done(new Error("Should not occur")); - }); - }); - }); - }); - - describe("On channel member removal", () => { - it("should notify the client", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const roomToken = "twake"; - - const channel = channelUtils.getChannel(platform.currentUser.id); - - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - channelUtils.getContext({ id: channel.owner }), - ); - const member = { - channel_id: creationResult.entity.id, - workspace_id: platform.workspace.workspace_id, - company_id: platform.workspace.company_id, - user_id: platform.currentUser.id, - } as ChannelMember; - - await gr.services.channels.members.save(member, { - channel: creationResult.entity, - user: platform.currentUser, - }); - - connect(); - socket.on("connect", () => { - socket - .emit("authenticate", { token: jwtToken }) - .on("authenticated", () => { - socket.on("realtime:resource", event => { - if (event.action !== "deleted") { - // we can receive event when resource is created... - return; - } - - expect(event.type).toEqual("channel_member"); - expect(event.action).toEqual("deleted"); - expect(event.resource).toMatchObject({ - company_id: platform.workspace.company_id, - workspace_id: platform.workspace.workspace_id, - user_id: platform.currentUser.id, - channel_id: creationResult.entity.id, - }); - done(); - }); - socket.emit("realtime:join", { - name: getPublicRoomName(creationResult.entity), - token: roomToken, - }); - socket.on("realtime:join:error", () => done(new Error("Should not occur"))); - socket.on("realtime:join:success", async () => { - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${creationResult.entity.company_id}/workspaces/${creationResult.entity.workspace_id}/channels/${creationResult.entity.id}/members/${platform.currentUser.id}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - }); - }) - .on("unauthorized", () => { - done(new Error("Should not occur")); - }); - }); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/channels/skip-channel-members.rest.spec.ts b/twake/backend/node/test/e2e/channels/skip-channel-members.rest.spec.ts deleted file mode 100644 index 10e6ece9..00000000 --- a/twake/backend/node/test/e2e/channels/skip-channel-members.rest.spec.ts +++ /dev/null @@ -1,401 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it } from "@jest/globals"; -import { v1 as uuidv1, v4 as uuidv4 } from "uuid"; -import { deserialize } from "class-transformer"; -import { init, TestPlatform } from "../setup"; -import { Channel } from "../../../src/services/channels/entities/channel"; -import { ChannelMember } from "../../../src/services/channels/entities/channel-member"; -import { - ChannelExecutionContext, - ChannelVisibility, - WorkspaceExecutionContext, -} from "../../../src/services/channels/types"; -import { ResourceGetResponse, ResourceListResponse, User } from "../../../src/utils/types"; -import gr from "../../../src/services/global-resolver"; - -describe.skip("The ChannelMembers REST API", () => { - const url = "/internal/services/channels/v1"; - let platform: TestPlatform; - - beforeEach(async () => { - platform = await init({ - services: ["websocket", "webserver", "channels", "auth", "database"], - }); - }); - - afterEach(async () => { - await platform.tearDown(); - platform = null; - }); - - function getWorkspaceContext(user?: User): WorkspaceExecutionContext { - return { - workspace: platform.workspace, - user: user || platform.currentUser, - }; - } - - function getContext(channel: Channel, user?: User): ChannelExecutionContext { - return { - channel, - user, - }; - } - - /** - * Get a new channel instance - * - * @param owner will be a random uuidv4 if not defined - */ - function getChannel(owner: string = uuidv1()): Channel { - const channel = new Channel(); - - channel.name = "Test Channel"; - channel.company_id = platform.workspace.company_id; - channel.workspace_id = platform.workspace.workspace_id; - channel.is_default = false; - channel.visibility = ChannelVisibility.PRIVATE; - channel.archived = false; - channel.owner = owner; - - return channel; - } - - function getMember(channel: Channel, user: User): ChannelMember { - const member = new ChannelMember(); - - member.company_id = platform.workspace.company_id; - member.workspace_id = platform.workspace.workspace_id; - member.channel_id = channel?.id; - member.user_id = user?.id; - - return member; - } - - describe("The GET / - Get members list", () => { - let channel; - let createdChannel; - - beforeEach(async () => { - channel = getChannel(); - createdChannel = await gr.services.channels.channels.save(channel, {}, getWorkspaceContext()); - }); - - it("should 404 when channel does not exists", done => { - done(); - }); - - it("should return empty list of members", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${createdChannel.entity.id}/members`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(0); - - done(); - }); - - it("should return list of members the user has access to", async done => { - const member = getMember(createdChannel.entity, platform.currentUser); - const memberCreationResult = await gr.services.channels.members.save( - member, - getContext(channel), - ); - - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${createdChannel.entity.id}/members`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - const result: ResourceListResponse = deserialize( - ResourceListResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resources.length).toEqual(1); - expect(result.resources[0]).toMatchObject({ - channel_id: memberCreationResult.entity.channel_id, - workspace_id: memberCreationResult.entity.workspace_id, - company_id: memberCreationResult.entity.company_id, - user_id: memberCreationResult.entity.user_id, - }); - - done(); - }); - }); - - describe("The POST / - Add member", () => { - let channel; - let createdChannel; - - beforeEach(async () => { - channel = getChannel(); - createdChannel = await gr.services.channels.channels.save(channel, {}, getWorkspaceContext()); - }); - - it("should fail when user_id is not defined", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${createdChannel.entity.id}/members`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource: {}, - }, - }); - - expect(response.statusCode).toEqual(400); - - done(); - }); - - it("should be able to add current member", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${createdChannel.entity.id}/members`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource: { - user_id: platform.currentUser.id, - }, - }, - }); - - expect(response.statusCode).toEqual(201); - - done(); - }); - - it("should be able to add another member", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${createdChannel.entity.id}/members`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource: { - user_id: uuidv1(), - }, - }, - }); - - expect(response.statusCode).toEqual(201); - done(); - }); - }); - - describe("The GET /:member_id - Get a member", () => { - let channel; - let createdChannel; - - beforeEach(async () => { - channel = getChannel(); - createdChannel = await gr.services.channels.channels.save(channel, {}, getWorkspaceContext()); - }); - - it("should 404 when member does not exist", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${ - platform.workspace.workspace_id - }/channels/${createdChannel.entity.id}/members/${uuidv1()}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - expect(response.statusCode).toEqual(404); - done(); - }); - - it("should send back member", async done => { - const member = getMember(createdChannel.entity, platform.currentUser); - const memberCreationResult = await gr.services.channels.members.save( - member, - getContext(channel), - ); - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${createdChannel.entity.id}/members/${memberCreationResult.entity.user_id}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - expect(response.statusCode).toEqual(200); - const result: ResourceGetResponse = deserialize( - ResourceGetResponse, - response.body, - ); - - expect(response.statusCode).toBe(200); - expect(result.resource).toMatchObject({ - channel_id: memberCreationResult.entity.channel_id, - workspace_id: memberCreationResult.entity.workspace_id, - company_id: memberCreationResult.entity.company_id, - user_id: memberCreationResult.entity.user_id, - }); - - done(); - }); - }); - - describe("The POST /:member_id - Update a member", () => { - let channel; - let createdChannel; - - beforeEach(async () => { - channel = getChannel(); - createdChannel = await gr.services.channels.channels.save(channel, {}, getWorkspaceContext()); - }); - - it("should not be able to update a member when current user is not the member", async done => { - const member = getMember(createdChannel.entity, { id: uuidv4() }); - const memberCreationResult = await gr.services.channels.members.save( - member, - getContext(channel), - ); - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${createdChannel.entity.id}/members/${memberCreationResult.entity.user_id}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource: { - favorite: true, - }, - }, - }); - - expect(response.statusCode).toEqual(400); - done(); - }); - - it("should be able to update member when current user is the member", async done => { - const member = getMember(createdChannel.entity, platform.currentUser); - const memberCreationResult = await gr.services.channels.members.save( - member, - getContext(channel), - ); - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${createdChannel.entity.id}/members/${memberCreationResult.entity.user_id}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource: { - favorite: true, - }, - }, - }); - - expect(response.statusCode).toEqual(200); - - const channelMember: ChannelMember = await gr.services.channels.members.get(member); - - expect(channelMember).toMatchObject({ - channel_id: memberCreationResult.entity.channel_id, - workspace_id: memberCreationResult.entity.workspace_id, - company_id: memberCreationResult.entity.company_id, - user_id: memberCreationResult.entity.user_id, - favorite: true, - }); - - done(); - }); - }); - - describe("The DELETE /:member_id - Remove a member", () => { - let channel; - let createdChannel; - - beforeEach(async () => { - channel = getChannel(); - createdChannel = await gr.services.channels.channels.save(channel, {}, getWorkspaceContext()); - }); - - it("should 404 when member does not exist", async done => { - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${ - platform.workspace.workspace_id - }/channels/${createdChannel.entity.id}/members/${uuidv1()}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - payload: { - resource: { - favorite: true, - }, - }, - }); - - expect(response.statusCode).toEqual(404); - done(); - }); - - it("should not be able to remove the member when current user does not have enough rights", async done => { - // const member = getMember(createdChannel.entity, { id: uuidv4() }); - // const memberCreationResult = await gr.services.channels.members.save(member); - // const jwtToken = await platform.auth.getJWTToken(); - // const response = await platform.app.inject({ - // method: "DELETE", - // url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${createdChannel.entity.id}/members/${memberCreationResult.entity.user_id}`, - // headers: { - // authorization: `Bearer ${jwtToken}`, - // }, - // }); - // - // expect(response.statusCode).toEqual(400); - // done(); - }); - - it("should be able to remove the member when current user is the member", async done => { - const member = getMember(createdChannel.entity, platform.currentUser); - const memberCreationResult = await gr.services.channels.members.save( - member, - getContext(channel), - ); - const jwtToken = await platform.auth.getJWTToken(); - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${platform.workspace.company_id}/workspaces/${platform.workspace.workspace_id}/channels/${createdChannel.entity.id}/members/${memberCreationResult.entity.user_id}`, - headers: { - authorization: `Bearer ${jwtToken}`, - }, - }); - - expect(response.statusCode).toEqual(204); - done(); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/channels/utils.ts b/twake/backend/node/test/e2e/channels/utils.ts deleted file mode 100644 index b68024a6..00000000 --- a/twake/backend/node/test/e2e/channels/utils.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { v1 as uuidv1 } from "uuid"; -import { ChannelMember } from "../../../src/services/channels/entities"; -import { Channel } from "../../../src/services/channels/entities/channel"; -import { - ChannelExecutionContext, - ChannelVisibility, - WorkspaceExecutionContext, -} from "../../../src/services/channels/types"; -import { User } from "../../../src/utils/types"; -import { TestPlatform } from "../setup"; - -export interface ChannelUtils { - getContext(user?: User): WorkspaceExecutionContext; - getChannel(owner?: string): Channel; - getDirectChannel(owner?: string): Channel; - getChannelContext(channel: Channel, user: User): ChannelExecutionContext; -} - -export interface ChannelMemberUtils { - getMember(channel: Channel, user: User): ChannelMember; -} - -export function getMemberUtils(platform: TestPlatform): ChannelMemberUtils { - return { - getMember, - }; - - function getMember(channel: Channel, user: User): ChannelMember { - const member = new ChannelMember(); - - member.company_id = platform.workspace.company_id; - member.workspace_id = platform.workspace.workspace_id; - member.channel_id = channel?.id; - member.user_id = user?.id; - - return member; - } -} - -export function get(platform: TestPlatform): ChannelUtils { - return { - getContext, - getChannel, - getDirectChannel, - getChannelContext, - }; - - function getContext(user?: User): WorkspaceExecutionContext { - return { - workspace: platform.workspace, - user: user || platform.currentUser, - }; - } - - function getChannelContext(channel: Channel, user?: User): ChannelExecutionContext { - return { - channel, - user, - }; - } - - /** - * Get a new channel instance - * - * @param owner will be a random uuidv4 if not defined - */ - function getChannel(owner: string = uuidv1()): Channel { - const channel = new Channel(); - - channel.name = "Test Channel"; - channel.company_id = platform.workspace.company_id; - channel.workspace_id = platform.workspace.workspace_id; - channel.is_default = false; - channel.visibility = ChannelVisibility.PUBLIC; - channel.archived = false; - channel.owner = owner; - - return channel; - } - - function getDirectChannel(owner: string = uuidv1()): Channel { - const channel = getChannel(owner); - - channel.visibility = ChannelVisibility.DIRECT; - channel.workspace_id = ChannelVisibility.DIRECT; - channel.name = "A direct channel"; - - return channel; - } -} diff --git a/twake/backend/node/test/e2e/console/console-auth.spec.ts b/twake/backend/node/test/e2e/console/console-auth.spec.ts deleted file mode 100644 index f542f795..00000000 --- a/twake/backend/node/test/e2e/console/console-auth.spec.ts +++ /dev/null @@ -1,272 +0,0 @@ -import { afterAll, beforeAll, describe, expect, it as _it, it } from "@jest/globals"; -import { init, TestPlatform } from "../setup"; -import { TestDbService } from "../utils.prepare.db"; -import { v1 as uuidv1 } from "uuid"; -import gr from "../../../src/services/global-resolver"; - -export const itRemote = (name: string, cb: (a: any) => void) => { - _it(name, async done => { - if (gr.services.console.consoleType === "remote") { - cb(done); - } else { - console.warn(`[skipped]: ${name} (console-mode only)`); - done(); - } - }); -}; - -describe("The console API auth", () => { - const loginUrl = "/internal/services/console/v1/login"; - const tokenRefreshUrl = "/internal/services/console/v1/token"; - - let platform: TestPlatform; - - let testDbService: TestDbService; - const companyId = uuidv1(); - - const firstEmail = "superman@email.com"; - - const firstUserPassword = "superPassw0rd"; - - beforeAll(async ends => { - platform = await init({ - services: [ - "database", - "message-queue", - "search", - "applications", - "webserver", - "user", - "workspaces", - "auth", - "console", - "storage", - "counter", - "statistics", - "platform-services", - ], - }); - - await platform.database.getConnector().init(); - testDbService = await TestDbService.getInstance(platform); - await testDbService.createCompany(companyId); - const ws0pk = { id: uuidv1(), company_id: companyId }; - // const ws1pk = { id: uuidv1(), company_id: companyId }; - await testDbService.createWorkspace(ws0pk); - // await testDbService.createWorkspace(ws1pk); - await testDbService.createUser([ws0pk], { - companyRole: "member", - workspaceRole: "moderator", - email: firstEmail, - firstName: "superman", - password: firstUserPassword, - }); - // await testDbService.createUser([ws0pk], "member", "member"); - // await testDbService.createUser([ws1pk], "member", "member", emailForExistedUser); - - await new Promise(r => setTimeout(r, 1000)); - - ends(); - }); - - afterAll(async ends => { - await platform.tearDown(); - ends(); - }); - - describe("Common checks", () => { - it("should 400 when required params are missing ", async done => { - const response = await platform.app.inject({ - method: "POST", - url: `${loginUrl}`, - payload: { - email: "", - password: "", - remote_access_token: "", - }, - }); - expect(response.statusCode).toBe(400); - expect(response.json()).toMatchObject({ - statusCode: 400, - error: "Bad Request", - message: "remote_access_token or email+password are required", - }); - done(); - }); - }); - describe("Auth using token", () => { - itRemote("should 403 when token is invalid", async done => { - const response = await platform.app.inject({ - method: "POST", - url: `${loginUrl}`, - payload: { - remote_access_token: "12345", - }, - }); - expect(response.json()).toMatchObject({ - error: "Forbidden", - message: "Bad access token credentials", - statusCode: 403, - }); - expect(response.statusCode).toBe(403); - - done(); - }); - - itRemote("should 200 when token is valid", async done => { - const response = await platform.app.inject({ - method: "POST", - url: `${loginUrl}`, - payload: { - email: "", - password: "", - remote_access_token: "a550c8b8b942bd92e447271343ac6b29", - }, - }); - expect(response.json()).toMatchObject({ - access_token: { - time: expect.any(Number), - expiration: expect.any(Number), - refresh_expiration: expect.any(Number), - value: expect.any(String), - refresh: expect.any(String), - type: "Bearer", - }, - }); - expect(response.statusCode).toBe(200); - done(); - }); - }); - describe("Auth using email/password", () => { - it("should 403 when user doesn't exists", async done => { - const response = await platform.app.inject({ - method: "POST", - url: `${loginUrl}`, - payload: { - email: "randomEmail", - password: "randomPass", - }, - }); - expect(response.statusCode).toBe(403); - expect(response.json()).toMatchObject({ - error: "Forbidden", - message: "User doesn't exists", - statusCode: 403, - }); - done(); - }); - - it("should 403 when password doesn't match", async done => { - const user = testDbService.users[0]; - - const response = await platform.app.inject({ - method: "POST", - url: `${loginUrl}`, - payload: { - email: user.email_canonical, - password: "randomPass", - }, - }); - expect(response.statusCode).toBe(403); - expect(response.json()).toMatchObject({ - error: "Forbidden", - message: "Password doesn't match", - statusCode: 403, - }); - done(); - }); - - it("should 200 when credentials is valid", async done => { - const user = testDbService.users[0]; - - const response = await platform.app.inject({ - method: "POST", - url: `${loginUrl}`, - payload: { - email: user.email_canonical, - password: firstUserPassword, - }, - }); - expect(response.statusCode).toBe(200); - expect(response.json()).toMatchObject({ - access_token: { - time: expect.any(Number), - expiration: expect.any(Number), - refresh_expiration: expect.any(Number), - value: expect.any(String), - refresh: expect.any(String), - type: "Bearer", - }, - }); - - done(); - }); - }); - describe("Token renewal", () => { - it("should 200 when refresh from access_token", async done => { - const user = testDbService.users[0]; - - const firstResponse = await platform.app.inject({ - method: "POST", - url: `${loginUrl}`, - payload: { - email: user.email_canonical, - password: firstUserPassword, - }, - }); - - const firstRes = firstResponse.json().access_token; - expect(firstRes.value).toBeTruthy(); - - setTimeout(async () => { - const response = await platform.app.inject({ - method: "POST", - url: `${tokenRefreshUrl}`, - headers: { - authorization: `Bearer ${firstRes.value}`, - }, - }); - - const secondRes = response.json().access_token; - - expect(secondRes.expiration).toBeGreaterThan(firstRes.expiration); - expect(secondRes.refresh_expiration).toBeGreaterThan(firstRes.refresh_expiration); - - done(); - }, 2000); - }); - - it("should 200 when refresh from refresh_token", async done => { - const user = testDbService.users[0]; - - const firstResponse = await platform.app.inject({ - method: "POST", - url: `${loginUrl}`, - payload: { - email: user.email_canonical, - password: firstUserPassword, - }, - }); - - const firstRes = firstResponse.json().access_token; - expect(firstRes.refresh).toBeTruthy(); - - setTimeout(async () => { - const response = await platform.app.inject({ - method: "POST", - url: `${tokenRefreshUrl}`, - headers: { - authorization: `Bearer ${firstRes.refresh}`, - }, - }); - - const secondRes = response.json().access_token; - - expect(secondRes.expiration).toBeGreaterThan(firstRes.expiration); - expect(secondRes.refresh_expiration).toBeGreaterThan(firstRes.refresh_expiration); - - done(); - }, 2000); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/console/console-hooks.spec.ts b/twake/backend/node/test/e2e/console/console-hooks.spec.ts deleted file mode 100644 index fadbbec9..00000000 --- a/twake/backend/node/test/e2e/console/console-hooks.spec.ts +++ /dev/null @@ -1,545 +0,0 @@ -import { afterAll, beforeAll, describe, expect, it as _it } from "@jest/globals"; -import { init, TestPlatform } from "../setup"; -import { TestDbService } from "../utils.prepare.db"; -import { v1 as uuidv1 } from "uuid"; -import { sign as cryptoSign } from "crypto"; -import gr from "../../../src/services/global-resolver"; -import { ConsoleServiceImpl } from "../../../src/services/console/service"; -/* - THIS TESTS RUNS ONLY FOR THE CONSOLE-MODE (CONSOLE TYPE: REMOTE) -*/ - -export const it = (name: string, cb: (a: any) => void) => { - _it(name, async done => { - if (gr.services.console.consoleType === "remote") { - cb(done); - } else { - console.warn(`[skipped]: ${name} (console-mode only)`); - done(); - } - }); -}; - -describe("The console API hooks", () => { - const url = "/internal/services/console/v1/hook"; - - let platform: TestPlatform; - - let testDbService: TestDbService; - const companyId = uuidv1(); - - const firstEmail = "superman@email.com"; - const secondEmail = "C.o.n.sole_created-user@email.com"; - const thirdEmail = "superman@someogherservice.com"; - - const secret = "ohquoo1fohzeigitochaJeepoowug4Yuqueite6etojieg1oowaeraeshiW8ku8g"; - - beforeAll(async ends => { - platform = await init({ - services: [ - "database", - "message-queue", - "webserver", - "search", - "user", - "workspaces", - "auth", - "console", - "applications", - "storage", - "counter", - "statistics", - "platform-services", - ], - }); - - await platform.database.getConnector().init(); - testDbService = await TestDbService.getInstance(platform); - await testDbService.createCompany(companyId); - const ws0pk = { id: uuidv1(), company_id: companyId }; - - await testDbService.createWorkspace(ws0pk); - - await testDbService.createUser([ws0pk], { - companyRole: "member", - workspaceRole: "moderator", - username: "superman", - }); - - const console = platform.platform.getProvider("console"); - - ends(); - }); - - afterAll(async ends => { - await platform.tearDown(); - ends(); - }); - - const getPayload = (type: string, content: Record) => { - const data = { - content: content, - type: type, - } as any; - - const sign = cryptoSign( - "RSA-SHA512", - Buffer.from(JSON.stringify(data)), - "-----BEGIN PRIVATE KEY-----\nMIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQD15kALIEHoe1bt\nADG/oOqHLRgnzNoiGl8aQ6LD/9c4F5+IVP9gPxGm26haSMW2Z9doJeTucvV8syQV\nbdwc9z0NUhNhFG1RLsj0+ePgpuBfKv+uzEICrRedP7wsmWC37K1NmGZ+LzO21oeu\nLO0L39kNk+qspJnqqx8PIfUmeQ6DDkEKW/J0ISeOsBOetKiJC2n5F4Fkifh1Bq2T\nsFfW9Tz47hfLAKkNUyoulBbqX/xViUhlhFb59sxhoMesCL/VJf7OmTLvryXBW/TU\nCYFssAZXXSWOOzc2k+X2VX3QslKfCHsnCO75I+FPFd9YtFWKlaHeq36ZHlYxnYqp\nRcdixzhjAgMBAAECggEANtvoe9L1gUVLDlLVxnfC+udflTmJjMQvZW+jd3Czdisn\nB0ZXNwS7DmvA8mt72IbwMqcJnPz+sZRRv4oj6j5qW3dtJWJmRQ9X+/doFG2GbxTr\nt/aP34L4WremZpjNUBs4SrBuZUZolijkWkJhnB2Tkgjm+R87y3Pj2P9tbujhCPGM\nMQf+s5lOh/AXDyqYGyEJAZBJT3DevrB9Cl3uhYWZ0fFUz4hwATeB0Va8YT8ZJea2\nXwajg/NnOOpdSGVgv0+7zhPYvkvg8bMZeH24VxYkAfdww8vANPuk4wUwDvnh39+Q\nI4uHQGXgjf8SJ5Z7G7A5Q4r7Ma4drJDbCOfNTi84+QKBgQD+ar48b7c5ffMT/ta7\nGUfMiHCjLfauHt/1f1CkFN1OpJW2ZrS34jYusqBXos32X2gx+wsOGtzOrhkkpvgp\nL7jaZmUnQTwfn6Sx4Duq+LVVMH/uj+W/Zj24AKnoylzM9XC6D2kwKAfHs4Mg6+fe\no6VRBR/yw01ShR+YDVAEN0B7ZwKBgQD3bfCIlp1DpTjFKEBFaC4jRNJPaf8OLt/U\nYHOBwwltb406I4s13M3A1N74Btk5ycx6n/a6RHIGB6+E2xn9AnYI51M/+n9vBLPc\nnnqjOZP/7FdK7qL/g4JtXae/CyroXYaYXUNsdJttQC62QRW+xhp6fYxWt/nAcc9R\nvXmninx5pQJ/CPG3vmgvCNZktU9APVOmMoqZayMyiOyM8xSGwT36ick/eioiMFTD\nkuC0wl/23bJ890TcHqLTIHD+cUttbgU/em4fIEIq2vHB2H8JmfkkZtpNpRVp/lCZ\n2t4rGwQCPzJhxCjGiereWyb0dTPV8v3N0gtcFCzJix0i/zV4mq1WlwKBgGfV1F6N\nznun57YdmTNHcC1O4W+ATRA3rakjvPWU0u0BJmRirDYzbolhDB1MSncM7+n6HYG3\n3Z4YNZlslXBvSveblH1B8560e4K3Y0IClNCO72c71F2kY+Tfq9jpp90R+r0QTo5C\nNUPY7oF/uM9xtYT4ESAHXyFa4aUs/dPIs0odAoGBAKYqeAsbLIsb2ruMkeH5itbe\nxdgVHZ8d2Pxk1h+52SGyptuBzlt7c6Gb3KNxpIc61tZklOn5yj+QmJHN82rXGdIE\nCkdrkEmqZU52X2OInozV1Py8L7akH9wijzy5ULWqxapIE2ItnPkgcC7+x6vglkfd\nI0VcGHm8cgqCpzRaIZjH\n-----END PRIVATE KEY-----", - ); - - data.signature = sign.toString("base64"); - - return data; - }; - - describe("Common checks", () => { - it("should 404 when not POST ", async done => { - const response = await platform.app.inject({ - method: "GET", - url: `${url}`, - }); - expect(response.statusCode).toBe(404); - done(); - }); - - it("should 400 when secret key is missing", async done => { - const response = await platform.app.inject({ - method: "POST", - url: `${url}`, - payload: getPayload("a", {}), - }); - expect(response.statusCode).toBe(400); - expect(response.json()).toMatchObject({ - statusCode: 400, - error: "Bad Request", - message: "querystring should have required property 'secret_key'", - }); - done(); - }); - - it("should 403 when secret key is not valid ", async done => { - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=wrongOne`, - payload: getPayload("a", {}), - }); - expect(response.statusCode).toBe(403); - expect(response.json()).toMatchObject({ - statusCode: 403, - error: "Forbidden", - message: "Wrong secret", - }); - done(); - }); - - it("should 501 when type is not implemented", async done => { - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=${secret}`, - payload: getPayload("unknown_type", {}), - }); - expect(response.statusCode).toBe(501); - done(); - }); - }); - - describe("User related hooks", () => { - describe("User created/updated", () => { - it("should 200 when updated existing user", async done => { - const user = testDbService.users[0]; - - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=${secret}`, - payload: getPayload("user_updated", { - user: { - _id: user.identity_provider_id, - roles: [ - { targetCode: companyId, roleCode: "owner", applications: [{ code: "twake" }] }, - ], - email: firstEmail, - firstName: "firstName", - lastName: "lastName", - isVerified: true, - preference: { - locale: "en", - timeZone: 2, - }, - avatar: { - type: "unknown", - value: "123456.jpg", - }, - }, - }), - }); - - expect(response.statusCode).toBe(200); - - const updatedUser = await testDbService.getUserFromDb({ - id: user.id, - }); - - expect(updatedUser).toMatchObject({ - id: user.id, - email_canonical: firstEmail, - first_name: "firstName", - last_name: "lastName", - mail_verified: true, - timezone: 2, - language: "en", - picture: - gr.services.console.consoleOptions.url.replace(/\/$/, "") + "/avatars/123456.jpg", - }); - - const userRoles = await testDbService.getCompanyUser(companyId, updatedUser.id); - - expect(userRoles).toEqual( - expect.objectContaining({ - role: "owner", - }), - ); - - done(); - }); - - it("should 200 when creating new user", async done => { - const newUserConsoleId = String(testDbService.rand()); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=${secret}`, - payload: getPayload("user_updated", { - user: { - _id: newUserConsoleId, - roles: [ - { targetCode: companyId, roleCode: "admin", applications: [{ code: "twake" }] }, - ], - email: secondEmail, - firstName: "consoleFirst", - lastName: "consoleSecond", - isVerified: true, - preference: { - locale: "ru", - timeZone: 3, - }, - avatar: { - type: "unknown", - value: "5678.jpg", - }, - }, - }), - }); - - expect(response.statusCode).toBe(200); - - const updatedUser = await testDbService.getUserFromDb({ - identity_provider_id: newUserConsoleId, - }); - - expect(updatedUser).toMatchObject({ - first_name: "consoleFirst", - last_name: "consoleSecond", - mail_verified: true, - timezone: 3, - language: "ru", - creation_date: expect.any(String), - deleted: false, - email_canonical: secondEmail.toLocaleLowerCase(), - identity_provider: "console", - identity_provider_id: newUserConsoleId, - username_canonical: "consolecreateduser", - picture: gr.services.console.consoleOptions.url.replace(/\/$/, "") + "/avatars/5678.jpg", - }); - - const userRoles = await testDbService.getCompanyUser(companyId, updatedUser.id); - - expect(userRoles).toEqual( - expect.objectContaining({ - role: "moderator", - }), - ); - done(); - }); - - it("should 200 when creating new user with same username (generating new one)", async done => { - const newUserConsoleId = String(testDbService.rand()); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=${secret}`, - payload: getPayload("user_updated", { - user: { - _id: newUserConsoleId, - roles: [ - { targetCode: companyId, roleCode: "member", applications: [{ code: "twake" }] }, - ], - email: thirdEmail, - firstName: "superman", - lastName: "superman-lastname", - isVerified: true, - preference: { - locale: "ru", - timeZone: 3, - }, - avatar: { - type: "unknown", - value: "5679.jpg", - }, - }, - }), - }); - - expect(response.statusCode).toBe(200); - - const updatedUser = await testDbService.getUserFromDb({ - identity_provider_id: newUserConsoleId, - }); - - expect(updatedUser).toMatchObject({ - first_name: "superman", - last_name: "superman-lastname", - mail_verified: true, - timezone: 3, - language: "ru", - creation_date: expect.any(String), - deleted: false, - email_canonical: thirdEmail.toLocaleLowerCase(), - identity_provider: "console", - identity_provider_id: newUserConsoleId, - username_canonical: "superman1", - picture: gr.services.console.consoleOptions.url.replace(/\/$/, "") + "/avatars/5679.jpg", - }); - - const userRoles = await testDbService.getCompanyUser(companyId, updatedUser.id); - - expect(userRoles).toEqual( - expect.objectContaining({ - role: "member", - }), - ); - done(); - }); - - it("should 400 when creating user with email that already exists", async done => { - const newUserConsoleId = String(testDbService.rand()); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=${secret}`, - payload: getPayload("user_updated", { - user: { - _id: newUserConsoleId, - email: firstEmail, - }, - }), - }); - - expect(response.statusCode).toBe(400); - expect(response.json()).toMatchObject({ - error: "Console user not created because email already exists", - }); - done(); - }); - }); - describe("User removed", () => { - it("should 200 when deleting", async done => { - const company = testDbService.company; - let users = await testDbService.getCompanyUsers(company.id); - let user = users.find(a => a.username_canonical == "consolecreateduser"); - expect(user).toBeTruthy(); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=${secret}`, - payload: getPayload("company_user_deactivated", { - company: { code: company.identity_provider_id }, - user: { - _id: user.identity_provider_id, - }, - }), - }); - - expect(response.statusCode).toBe(200); - - users = await testDbService.getCompanyUsers(company.id); - user = users.find(a => a.username_canonical == "consolecreateduser"); - expect(user).toBeFalsy(); - - done(); - }); - - it("should 400 when user not found", async done => { - const company = testDbService.company; - - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=${secret}`, - payload: getPayload("company_user_deactivated", { - company: { code: company.identity_provider_id }, - user: { - _id: 123456789, - }, - }), - }); - - expect(response.statusCode).toBe(400); - - done(); - }); - }); - }); - - describe("Company related hooks", () => { - describe("Company added", () => { - it("should 200 when company created", async done => { - const newCompanyCode = String(testDbService.rand()); - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=${secret}`, - payload: getPayload("company_created", { - company: { - code: newCompanyCode, - stats: "stats", - plan: { name: "plan name", limits: {} }, - value: "value", - details: { - logo: "logo", - avatar: { - value: "avatar.jpg", - type: "type", - }, - name: "company name", - }, - }, - }), - }); - - expect(response.statusCode).toBe(200); - - const createdCompany = await testDbService.getCompanyFromDbByCode(newCompanyCode); - expect(createdCompany).toEqual( - expect.objectContaining({ - id: expect.any(String), - name: "company name", - plan: { name: "plan name", limits: {} }, - stats: "stats", - logo: "logo", - dateAdded: expect.any(Number), - identity_provider: "console", - identity_provider_id: newCompanyCode, - // details: - }), - ); - - done(); - }); - }); - describe("Company updated", () => { - it("should 200 when company updated", async done => { - const company = testDbService.company; - expect(company).toBeTruthy(); - expect(company.identity_provider_id).toBeTruthy(); - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=${secret}`, - payload: getPayload("company_updated", { - company: { - code: company.identity_provider_id, - stats: "stats", - plan: { name: "plan name", limits: {} }, - value: "value", - details: { - logo: "logo", - avatar: { - value: "avatar.jpg", - type: "type", - }, - name: "new company name", - }, - }, - }), - }); - - expect(response.statusCode).toBe(200); - - const createdCompany = await testDbService.getCompanyFromDb(company.id); - expect(createdCompany).toEqual( - expect.objectContaining({ - id: company.id, - name: "new company name", - plan: { name: "plan name", limits: {} }, - stats: "stats", - logo: "logo", - dateAdded: expect.any(Number), - identity_provider: "console", - identity_provider_id: company.identity_provider_id, - // details: - }), - ); - - done(); - }); - }); - describe("Plan updated", () => { - it("should 200 when plan updated", async done => { - const company = testDbService.company; - expect(company).toBeTruthy(); - expect(company.identity_provider_id).toBeTruthy(); - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=${secret}`, - payload: getPayload("plan_updated", { - company: { - code: company.identity_provider_id, - plan: { name: "another plan name", limits: {} }, - }, - }), - }); - - expect(response.statusCode).toBe(200); - - const createdCompany = await testDbService.getCompanyFromDb(company.id); - expect(createdCompany).toEqual( - expect.objectContaining({ - id: company.id, - name: "new company name", - plan: { name: "another plan name", limits: {} }, - stats: "stats", - logo: "logo", - dateAdded: expect.any(Number), - identity_provider: "console", - identity_provider_id: company.identity_provider_id, - // details: - }), - ); - - done(); - }); - }); - - describe("Company removed", () => { - it("should 200 when company removed", async done => { - const company = testDbService.company; - expect(company).toBeTruthy(); - expect(company.identity_provider_id).toBeTruthy(); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}?secret_key=${secret}`, - payload: getPayload("company_deleted", { - company: { - code: company.identity_provider_id, - }, - }), - }); - - expect(response.statusCode).toBe(200); - const deletedCompany = await testDbService.getCompanyFromDb(company.id); - expect(deletedCompany).toBeFalsy(); - - done(); - }); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/notifications/mention.spec.ts b/twake/backend/node/test/e2e/notifications/mention.spec.ts deleted file mode 100644 index bc3ae7d8..00000000 --- a/twake/backend/node/test/e2e/notifications/mention.spec.ts +++ /dev/null @@ -1,381 +0,0 @@ -import { afterAll, beforeAll, describe, expect, it } from "@jest/globals"; -import { v1 as uuidv1 } from "uuid"; -import { init, TestPlatform } from "../setup"; -import { Channel } from "../../../src/services/channels/entities/channel"; -import { ChannelMemberNotificationLevel } from "../../../src/services/channels/types"; -import { User } from "../../../src/utils/types"; -import { - ChannelMemberUtils, - ChannelUtils, - get as getChannelUtils, - getMemberUtils, -} from "../channels/utils"; -import { MessageNotification } from "../../../src/services/messages/types"; -import { - IncomingPubsubMessage, - MessageQueueServiceAPI, -} from "../../../src/core/platform/services/message-queue/api"; -import { ChannelMember } from "../../../src/services/channels/entities"; -import { MentionNotification } from "../../../src/services/notifications/types"; -import gr from "../../../src/services/global-resolver"; - -describe("The notification for user mentions", () => { - let platform: TestPlatform; - let channelUtils: ChannelUtils; - let channelMemberUtils: ChannelMemberUtils; - let pubsubService: MessageQueueServiceAPI; - // eslint-disable-next-line @typescript-eslint/no-empty-function - let pubsubHandler: (message: IncomingPubsubMessage) => void = _ => {}; - - beforeAll(async () => { - platform = await init({ - services: [ - "webserver", - "database", - "search", - "storage", - "message-queue", - "user", - "websocket", - "channels", - "auth", - "search", - "applications", - "files", - "push", - "notifications", - "counter", - "statistics", - "platform-services", - ], - }); - channelUtils = getChannelUtils(platform); - channelMemberUtils = getMemberUtils(platform); - pubsubService = platform.platform.getProvider("message-queue"); - pubsubService.subscribe("notification:mentions", message => { - pubsubHandler(message); - }); - }); - - afterAll(async () => { - await platform?.tearDown(); - platform = null; - }); - - async function createChannel(): Promise { - const channel = channelUtils.getChannel(platform.currentUser.id); - const creationResult = await gr.services.channels.channels.save( - channel, - {}, - channelUtils.getContext(), - ); - - return creationResult.entity; - } - - async function joinChannel( - userId: string, - channel: Channel, - notificationLevel?: ChannelMemberNotificationLevel, - ): Promise { - const user: User = { id: userId }; - const member = channelMemberUtils.getMember(channel, user); - - if (notificationLevel) member.notification_level = notificationLevel; - - const memberCreationResult = await gr.services.channels.members.save( - member, - channelUtils.getChannelContext(channel, user), - ); - return memberCreationResult.entity; - } - - async function updateNotificationLevel( - channel: Channel, - member: ChannelMember, - level: ChannelMemberNotificationLevel, - ): Promise { - member.notification_level = level; - await gr.services.channels.members.save( - member, - channelUtils.getChannelContext(channel, { id: member.user_id }), - ); - - return; - } - - function pushMessage(message: MessageNotification): Promise { - return pubsubService.publish("message:created", { - data: message, - }); - } - - it("should mention all users when preferences are MENTION", async done => { - const threadId = uuidv1(); - const messageId = uuidv1(); - const unknownUser = uuidv1(); - const channel = await createChannel(); - const member = await joinChannel( - platform.currentUser.id, - channel, - ChannelMemberNotificationLevel.MENTIONS, - ); - const member2 = await joinChannel(uuidv1(), channel, ChannelMemberNotificationLevel.MENTIONS); - const member3 = await joinChannel(uuidv1(), channel, ChannelMemberNotificationLevel.MENTIONS); - - pushMessage({ - channel_id: channel.id, - company_id: channel.company_id, - creation_date: Date.now(), - id: messageId, - sender: platform.currentUser.id, - thread_id: threadId, - workspace_id: channel.workspace_id, - mentions: { - users: [member.user_id, member2.user_id, unknownUser, member3.user_id], - }, - title: "test", - text: "should mention all users when preferences are MENTION ones", - }); - - const message = await new Promise>( - resolve => (pubsubHandler = resolve), - ); - expect(message.data.mentions.users).not.toContain(member.user_id); //The sender is not in the notified users - expect(message.data.mentions.users).toContain(member2.user_id); - expect(message.data.mentions.users).toContain(member3.user_id); - expect(message.data.mentions.users).not.toContain(unknownUser); - - done(); - }); - - it("should mention all users when preferences are default ones (ALL)", async done => { - const messageId = uuidv1(); - const unknownUser = uuidv1(); - const channel = await createChannel(); - const member = await joinChannel(platform.currentUser.id, channel); - const member2 = await joinChannel(uuidv1(), channel); - const member3 = await joinChannel(uuidv1(), channel); - - await new Promise(resolve => setTimeout(resolve, 500)); //Wait for the channel members to be created on all services - - pushMessage({ - channel_id: channel.id, - company_id: channel.company_id, - creation_date: Date.now(), - id: messageId, - sender: platform.currentUser.id, - thread_id: messageId, //Only thread initial messages generate notifications - workspace_id: channel.workspace_id, - title: "test", - text: "should mention all users when preferences are default ones (ALL)", - }); - - const message = await new Promise>( - resolve => (pubsubHandler = resolve), - ); - expect(message.data.mentions.users).not.toContain(member.user_id); //The sender is not in the notified users - expect(message.data.mentions.users).toContain(member2.user_id); - expect(message.data.mentions.users).toContain(member3.user_id); - expect(message.data.mentions.users).not.toContain(unknownUser); - - done(); - }); - - it("should not mention users with preferences ALL for replies of threads there are not member of", async done => { - const threadId = uuidv1(); - const messageId = uuidv1(); - const channel = await createChannel(); - const member = await joinChannel(platform.currentUser.id, channel); - const member2 = await joinChannel(uuidv1(), channel); - const member3 = await joinChannel(uuidv1(), channel); - - await new Promise(resolve => setTimeout(resolve, 500)); //Wait for the channel members to be created on all services - - pushMessage({ - channel_id: channel.id, - company_id: channel.company_id, - creation_date: Date.now(), - id: messageId, - sender: platform.currentUser.id, - thread_id: threadId, - workspace_id: channel.workspace_id, - mentions: { - users: [member.user_id, member2.user_id], - }, - title: "test", - text: "should mention all users when preferences are default ones (ALL)", - }); - - const message = await new Promise>( - resolve => (pubsubHandler = resolve), - ); - expect(message.data.mentions.users).not.toContain(member.user_id); //The sender is not in the notified users - expect(message.data.mentions.users).not.toContain(member3.user_id); - - done(); - }); - - it("should not mention user when notification level is set to NONE", async done => { - const threadId = uuidv1(); - const messageId = uuidv1(); - const unknownUser = uuidv1(); - const channel = await createChannel(); - const member = await joinChannel( - platform.currentUser.id, - channel, - ChannelMemberNotificationLevel.MENTIONS, - ); - const member2 = await joinChannel(uuidv1(), channel, ChannelMemberNotificationLevel.NONE); - const member3 = await joinChannel(uuidv1(), channel, ChannelMemberNotificationLevel.MENTIONS); - - await new Promise(resolve => setTimeout(resolve, 500)); //Wait for the channel members to be created on all services - - pushMessage({ - channel_id: channel.id, - company_id: channel.company_id, - creation_date: Date.now(), - id: messageId, - sender: platform.currentUser.id, - thread_id: threadId, - workspace_id: channel.workspace_id, - mentions: { - users: [member.user_id, member2.user_id, unknownUser, member3.user_id], - }, - title: "test", - text: "should not mention user when notification level is set to NONE", - }); - - const message = await new Promise>( - resolve => (pubsubHandler = resolve), - ); - expect(message.data.mentions.users).not.toContain(member.user_id); - expect(message.data.mentions.users).toContain(member3.user_id); - expect(message.data.mentions.users).not.toContain(member2.user_id); - - done(); - }); - - it("should mention user when notification level is set to channel mention and notification is for @all", async done => { - const threadId = uuidv1(); - const messageId = uuidv1(); - const channel = await createChannel(); - const member = await joinChannel( - platform.currentUser.id, - channel, - ChannelMemberNotificationLevel.MENTIONS, - ); - const member2 = await joinChannel(uuidv1(), channel, ChannelMemberNotificationLevel.MENTIONS); - const member3 = await joinChannel(uuidv1(), channel, ChannelMemberNotificationLevel.ME); - - await new Promise(resolve => setTimeout(resolve, 500)); //Wait for the channel members to be created on all services - - pushMessage({ - channel_id: channel.id, - company_id: channel.company_id, - creation_date: Date.now(), - id: messageId, - sender: platform.currentUser.id, - thread_id: threadId, - workspace_id: channel.workspace_id, - mentions: { - users: [], - specials: ["all"], - }, - title: "test", - text: "should mention user when notification level is set to channel mention and notification is for @all", - }); - - const message = await new Promise>( - resolve => (pubsubHandler = resolve), - ); - expect(message.data.mentions.users).not.toContain(member.user_id); - expect(message.data.mentions.users).toContain(member2.user_id); - expect(message.data.mentions.users).not.toContain(member3.user_id); - - done(); - }); - - it("should mention user when notification level is set to channel mention and notification is for @here", async done => { - const threadId = uuidv1(); - const messageId = uuidv1(); - const channel = await createChannel(); - const member = await joinChannel(platform.currentUser.id, channel); - const member2 = await joinChannel(uuidv1(), channel, ChannelMemberNotificationLevel.MENTIONS); - const member3 = await joinChannel(uuidv1(), channel, ChannelMemberNotificationLevel.ME); - - await new Promise(resolve => setTimeout(resolve, 500)); //Wait for the channel members to be created on all services - - pushMessage({ - channel_id: channel.id, - company_id: channel.company_id, - creation_date: Date.now(), - id: messageId, - sender: platform.currentUser.id, - thread_id: threadId, - workspace_id: channel.workspace_id, - mentions: { - users: [], - specials: ["here"], - }, - title: "test", - text: "should mention user when notification level is set to channel mention and notification is for @here", - }); - - const message = await new Promise>( - resolve => (pubsubHandler = resolve), - ); - - //Sender dont get notified - expect(message.data.mentions.users).not.toContain(member.user_id); - expect(message.data.mentions.users).toContain(member2.user_id); - expect(message.data.mentions.users).not.toContain(member3.user_id); - - done(); - }); - - it("should mention user when notification level is set to ME and updated notification later", async done => { - const threadId = uuidv1(); - const messageId = uuidv1(); - const channel = await createChannel(); - const member = await joinChannel( - platform.currentUser.id, - channel, - ChannelMemberNotificationLevel.NONE, - ); - const member2 = await joinChannel(uuidv1(), channel, ChannelMemberNotificationLevel.NONE); - const member3 = await joinChannel(uuidv1(), channel, ChannelMemberNotificationLevel.NONE); - - await new Promise(resolve => setTimeout(resolve, 1000)); //Wait for the channel members to be created - - await updateNotificationLevel(channel, member, ChannelMemberNotificationLevel.MENTIONS); - await updateNotificationLevel(channel, member2, ChannelMemberNotificationLevel.ME); - await updateNotificationLevel(channel, member3, ChannelMemberNotificationLevel.MENTIONS); - - await new Promise(resolve => setTimeout(resolve, 1000)); //Wait for the channel members to be created - - pushMessage({ - channel_id: channel.id, - company_id: channel.company_id, - creation_date: Date.now(), - id: messageId, - sender: platform.currentUser.id, - thread_id: threadId, - workspace_id: channel.workspace_id, - mentions: { - users: [member2.user_id], - }, - title: "test", - text: "should mention user when notification level is set to ME and updated notification later", - }); - - const message = await new Promise>( - resolve => (pubsubHandler = resolve), - ); - expect(message.data.mentions.users).not.toContain(member.user_id); - expect(message.data.mentions.users).not.toContain(member3.user_id); - expect(message.data.mentions.users).toContain(member2.user_id); - - done(); - }); -}); diff --git a/twake/backend/node/test/e2e/workspaces/workspace-pending-users.spec.ts b/twake/backend/node/test/e2e/workspaces/workspace-pending-users.spec.ts deleted file mode 100644 index cc021fcb..00000000 --- a/twake/backend/node/test/e2e/workspaces/workspace-pending-users.spec.ts +++ /dev/null @@ -1,437 +0,0 @@ -import { afterAll, beforeAll, describe, expect, it as _it } from "@jest/globals"; -import { init, TestPlatform } from "../setup"; -import { TestDbService } from "../utils.prepare.db"; -import { v1 as uuidv1 } from "uuid"; -import gr from "../../../src/services/global-resolver"; -/* - THIS TESTS RUNS ONLY FOR THE CONSOLE-MODE (CONSOLE TYPE: INTERNAL) -*/ - -export const it = (name: string, cb: (a: any) => void) => { - _it(name, async done => { - if (gr.services.console.consoleType === "internal") { - cb(done); - } else { - console.warn(`[skipped]: ${name} (no-console mode only)`); - done(); - } - }); -}; - -describe("The /workspace/pending users API", () => { - const url = "/internal/services/workspaces/v1"; - let platform: TestPlatform; - - let testDbService: TestDbService; - - const nonExistentId = uuidv1(); - const companyId = uuidv1(); - - const firstEmail = "first@test-user.com"; - const secondEmail = "second@test-user.com"; - const thirdEmail = "third@test-user.com"; - const fourthUser = "fourth@test-user.com"; - const emailForExistedUser = "exist@email.com"; - - async function doTheTest() { - return Promise.resolve(gr.services.console.consoleType === "remote"); - } - - beforeAll(async ends => { - platform = await init({ - services: [ - "user", - "database", - "message-queue", - "webserver", - "search", - "workspaces", - "applications", - "auth", - "console", - "storage", - "counter", - "statistics", - "platform-services", - ], - }); - - await platform.database.getConnector().drop(); - await platform.database.getConnector().init(); - testDbService = new TestDbService(platform); - await testDbService.createCompany(companyId); - const ws0pk = { id: uuidv1(), company_id: companyId }; - const ws1pk = { id: uuidv1(), company_id: companyId }; - const ws2pk = { id: uuidv1(), company_id: companyId }; - await testDbService.createWorkspace(ws0pk); - await testDbService.createWorkspace(ws1pk); - await testDbService.createWorkspace(ws2pk); - await testDbService.createUser([ws0pk], { companyRole: "member", workspaceRole: "moderator" }); - await testDbService.createUser([ws0pk], { companyRole: "member", workspaceRole: "member" }); - await testDbService.createUser([ws1pk], { - companyRole: "member", - workspaceRole: "member", - email: emailForExistedUser, - }); - await testDbService.createUser([ws2pk], { - companyRole: "guest", - workspaceRole: "member", - email: fourthUser, - }); - - ends(); - }); - - afterAll(async ends => { - await platform.tearDown(); - ends(); - }); - - describe("Invite users to a workspace by email", () => { - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users/invite`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 404 when workspace not found", async done => { - const userId = testDbService.users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users/invite`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - invitations: [ - { - email: firstEmail, - role: "member", - company_role: "member", - }, - ], - }, - }); - - expect(response.statusCode).toBe(404); - done(); - }); - - it("should 403 when requester is not at least workspace member", async done => { - const workspace_id = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspace_id}/users/invite`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - invitations: [ - { - email: firstEmail, - role: "member", - company_role: "member", - }, - ], - }, - }); - expect(response.statusCode).toBe(403); - done(); - }); - - it("should 200 when ok", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/invite`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - invitations: [ - { - email: firstEmail, - role: "member", - company_role: "member", - }, - { - email: secondEmail, - role: "member", - company_role: "member", - }, - { - email: "exist@email.com", - role: "member", - company_role: "member", - }, - ], - }, - }); - expect(response.statusCode).toBe(200); - - const resources = response.json()["resources"]; - - expect(resources.length).toBe(3); - - for (const item of resources) { - expect(item).toMatchObject({ - email: expect.stringMatching(/first@test-user.com|second@test-user.com|exist@email.com/), - status: "ok", - }); - } - - done(); - }); - - it("should fail in response with already added users", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/invite`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - invitations: [ - { - email: firstEmail, - role: "member", - company_role: "member", - }, - { - email: thirdEmail, - role: "member", - company_role: "member", - }, - ], - }, - }); - expect(response.statusCode).toBe(200); - - const resources = response.json()["resources"]; - - expect(resources.length).toBe(2); - - expect(resources[0]).toMatchObject({ - email: "first@test-user.com", - status: "error", - }); - - expect(resources[1]).toMatchObject({ - email: "third@test-user.com", - status: "ok", - }); - - done(); - }); - }); - - describe("Delete a pending user from a workspace", () => { - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - const email = "first@test-user.com"; - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/pending/${email}`, - }); - - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 404 when workspace not found", async done => { - const companyId = testDbService.company.id; - const email = "first@test-user.com"; - - const userId = testDbService.users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/pending/${email}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(404); - done(); - }); - - it("should 403 when requester is not at least workspace member", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[0].id; - const email = "first@test-user.com"; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/pending/${email}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(403); - done(); - }); - - it("should {status:error} when email is absent in pending list", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/pending/non-exist-email`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(200); - expect(response.json()).toMatchObject({ - status: "error", - }); - - done(); - }); - - it("should 200 when ok", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - const email = "first@test-user.com"; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/pending/${email}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(200); - expect(response.json()).toMatchObject({ - status: "success", - }); - - done(); - }); - }); - - describe("Get list of pending users in workspace", () => { - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - const email = "first@test-user.com"; - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/pending`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 404 when workspace not found", async done => { - const companyId = testDbService.company.id; - const email = "first@test-user.com"; - - const userId = testDbService.users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/pending`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(404); - done(); - }); - - it("should 403 when requester is not at least workspace member", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[0].id; - const email = "first@test-user.com"; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/pending`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(403); - done(); - }); - - it("should 200 when ok", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/pending`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(200); - - const resources = response.json()["resources"]; - console.log("resources A: ", resources); - expect(resources.length).toBe(2); - - expect(resources[0]).toMatchObject({ - email: "second@test-user.com", - role: "member", - company_role: "member", - }); - - expect(resources[1]).toMatchObject({ - email: "third@test-user.com", - role: "member", - company_role: "member", - }); - - done(); - }); - - it("existed user should be added instantly", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - const email = "first@test-user.com"; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(200); - - const resources = response.json()["resources"]; - - console.log("resources B: ", resources); - expect(resources.find((a: any) => a.user.email === emailForExistedUser)).toBeDefined(); - - done(); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/workspaces/workspace-users.spec.ts b/twake/backend/node/test/e2e/workspaces/workspace-users.spec.ts deleted file mode 100644 index c70f2e83..00000000 --- a/twake/backend/node/test/e2e/workspaces/workspace-users.spec.ts +++ /dev/null @@ -1,469 +0,0 @@ -import { afterAll, beforeAll, describe, expect, it } from "@jest/globals"; -import { init, TestPlatform } from "../setup"; -import { TestDbService, uuid } from "../utils.prepare.db"; -import { v1 as uuidv1 } from "uuid"; - -describe("The /workspace users API", () => { - const url = "/internal/services/workspaces/v1"; - let platform: TestPlatform; - - let testDbService: TestDbService; - - const nonExistentId = uuidv1(); - let companyId = ""; - - const checkUserObject = (resource: any) => { - expect(resource).toMatchObject({ - id: expect.any(String), - company_id: expect.any(String), - workspace_id: expect.any(String), - user_id: expect.any(String), - created_at: expect.any(Number), - role: expect.stringMatching(/moderator|member/), - user: { - id: expect.any(String), - provider: expect.any(String), - provider_id: expect.any(String), - email: expect.any(String), - is_verified: expect.any(Boolean), - picture: expect.any(String), - first_name: expect.any(String), - last_name: expect.any(String), - created_at: expect.any(Number), - deleted: expect.any(Boolean), - status: expect.any(String), - last_activity: expect.any(Number), - }, - }); - }; - - beforeAll(async ends => { - platform = await init({ - services: [ - "database", - "message-queue", - "search", - "webserver", - "user", - "workspaces", - "applications", - "auth", - "console", - "counter", - "storage", - "statistics", - "platform-services", - ], - }); - - companyId = platform.workspace.company_id; - - await platform.database.getConnector().init(); - testDbService = new TestDbService(platform); - await testDbService.createCompany(companyId); - const ws0pk = { id: uuidv1(), company_id: companyId }; - const ws1pk = { id: uuidv1(), company_id: companyId }; - const ws2pk = { id: uuidv1(), company_id: companyId }; - const ws3pk = { id: uuidv1(), company_id: companyId }; - await testDbService.createWorkspace(ws0pk); - await testDbService.createWorkspace(ws1pk); - await testDbService.createWorkspace(ws2pk); - await testDbService.createWorkspace(ws3pk); - await testDbService.createUser([ws0pk, ws1pk]); - await testDbService.createUser([ws2pk], { companyRole: "admin" }); - await testDbService.createUser([ws2pk], { workspaceRole: "moderator" }); - await testDbService.createUser([ws2pk], { workspaceRole: "member" }); - await testDbService.createUser([ws2pk], { workspaceRole: "member" }); - await testDbService.createUser([], { companyRole: "member" }); - await testDbService.createUser([ws3pk], { companyRole: "guest", workspaceRole: "member" }); - ends(); - }); - - afterAll(async ends => { - await platform.tearDown(); - ends(); - }); - - describe("The GET /workspaces/users route", () => { - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 404 when workspace not found", async done => { - const userId = testDbService.users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - expect(response.statusCode).toBe(404); - done(); - }); - - it("should 200 when ok", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - expect(response.statusCode).toBe(200); - - const resources = response.json()["resources"]; - - expect(resources.length).toBeGreaterThan(0); - - for (const resource of resources) { - checkUserObject(resource); - } - - done(); - }); - }); - - describe("The GET /workspaces/users/:user_id route", () => { - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - const userId = testDbService.users[0].id; - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users/${userId}`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 404 when workspace not found", async done => { - const userId = testDbService.users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users/${userId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - expect(response.statusCode).toBe(404); - done(); - }); - - it("should 200 when ok", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${userId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - expect(response.statusCode).toBe(200); - - const resource = response.json()["resource"]; - checkUserObject(resource); - done(); - }); - }); - - describe("The POST /workspaces/users route (add)", () => { - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 403 user is not workspace moderator", async done => { - const userId = testDbService.users[0].id; - const anotherUserId = testDbService.users[1].id; - const workspaceId = testDbService.workspaces[0].workspace.id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - resource: { - user_id: anotherUserId, - role: "moderator", - }, - }, - }); - expect(response.statusCode).toBe(403); - done(); - }); - - it("should 400 when requested user not in company", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[1].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - resource: { - user_id: nonExistentId, - role: "moderator", - }, - }, - }); - expect(response.statusCode).toBe(400); - done(); - }); - - it("should 201 when requested already in workspace (ignore)", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[1].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - resource: { - user_id: userId, - role: "moderator", - }, - }, - }); - expect(response.statusCode).toBe(201); - done(); - }); - - it("should 200 when ok", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[1].id; - const anotherUserId = testDbService.workspaces[0].users[0].id; - - let workspaceUsersCount = await testDbService.getWorkspaceUsersCountFromDb(workspaceId); - let companyUsersCount = await testDbService.getCompanyUsersCountFromDb(companyId); - - console.log(testDbService.workspaces[2].users); - console.log(workspaceUsersCount); - - expect(workspaceUsersCount).toBe(4); - // expect(companyUsersCount).toBe(6); - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - resource: { - user_id: anotherUserId, - role: "moderator", - }, - }, - }); - - expect(response.statusCode).toBe(201); - const resource = response.json()["resource"]; - checkUserObject(resource); - - workspaceUsersCount = await testDbService.getWorkspaceUsersCountFromDb(workspaceId); - companyUsersCount = await testDbService.getCompanyUsersCountFromDb(companyId); - expect(workspaceUsersCount).toBe(5); - // expect(companyUsersCount).toBe(6); - - done(); - }); - }); - - describe("The POST /workspaces/users/:user_id route (update)", () => { - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - const userId = testDbService.users[0].id; - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users/${userId}`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 403 user is not workspace moderator", async done => { - const userId = testDbService.users[0].id; - const anotherUserId = testDbService.users[1].id; - const workspaceId = testDbService.workspaces[0].workspace.id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${userId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - resource: { - user_id: anotherUserId, - role: "moderator", - }, - }, - }); - expect(response.statusCode).toBe(403); - done(); - }); - - it("should 404 when user not found in workspace", async done => { - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[1].id; - const anotherWorkspaceUserId = testDbService.workspaces[3].users[0].id; - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${anotherWorkspaceUserId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - resource: { - role: "moderator", - }, - }, - }); - - expect(response.statusCode).toBe(404); - done(); - }); - - it("should 200 when ok", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[1].id; - const anotherUserId = testDbService.workspaces[2].users[2].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${anotherUserId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - resource: { - role: "moderator", - }, - }, - }); - - expect(response.statusCode).toBe(201); - const resource = response.json()["resource"]; - checkUserObject(resource); - - expect(resource["role"]).toBe("moderator"); - - const usersCount = await testDbService.getWorkspaceUsersCountFromDb(workspaceId); - expect(usersCount).toBe(5); - - done(); - }); - }); - - describe("The DELETE /workspaces/users/:user_id route", () => { - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - const anotherUserId = testDbService.users[1].id; - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}/users/${anotherUserId}`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 403 user is not workspace moderator", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[3].id; - const anotherUserId = testDbService.workspaces[2].users[1].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${anotherUserId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - console.log(response.body); - - expect(response.statusCode).toBe(403); - done(); - }); - - it("should 404 when user not found in workspace", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[1].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${nonExistentId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(404); - - done(); - }); - - it("should 200 when ok", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[1].id; - const anotherUserId = testDbService.workspaces[2].users[2].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - let response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/${anotherUserId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(204); - - response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(200); - const resources = response.json()["resources"]; - expect(resources.find((a: { user_id: uuid }) => a.user_id === anotherUserId)).toBeUndefined(); - - const usersCount = await testDbService.getWorkspaceUsersCountFromDb(workspaceId); - expect(usersCount).toBe(4); - - done(); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/workspaces/workspaces.invite-tokens.spec.ts b/twake/backend/node/test/e2e/workspaces/workspaces.invite-tokens.spec.ts deleted file mode 100644 index 90853467..00000000 --- a/twake/backend/node/test/e2e/workspaces/workspaces.invite-tokens.spec.ts +++ /dev/null @@ -1,521 +0,0 @@ -import { afterAll, beforeAll, describe, expect, it } from "@jest/globals"; -import { init, TestPlatform } from "../setup"; -import { TestDbService } from "../utils.prepare.db"; -import { v1 as uuidv1 } from "uuid"; -import AuthService from "../../../src/core/platform/services/auth/provider"; -import { InviteTokenObject } from "../../../src/services/workspaces/web/types"; -import gr from "../../../src/services/global-resolver"; - -describe("The /workspaces API (invite tokens)", () => { - const url = "/internal/services/workspaces/v1"; - let platform: TestPlatform; - - let testDbService: TestDbService; - let authServiceApi: AuthService; - - let companyId = uuidv1(); - - const startup = async () => { - platform = await init({ - services: [ - "database", - "message-queue", - "webserver", - "user", - "search", - "workspaces", - "auth", - "console", - "counter", - "storage", - "applications", - "statistics", - "platform-services", - ], - }); - - companyId = platform.workspace.company_id; - - await platform.platform.getProvider("auth"); - testDbService = new TestDbService(platform); - await resetDatabase(); - }; - - const shutdown = async () => { - await platform.tearDown(); - }; - - const resetDatabase = async () => { - // await platform.database.getConnector().init(); - await platform.database.getConnector().drop(); - await testDbService.createCompany(companyId, "TestJoinCompany"); - const ws0pk = { id: uuidv1(), company_id: companyId }; - const ws1pk = { id: uuidv1(), company_id: companyId }; - const ws2pk = { id: uuidv1(), company_id: companyId }; - await testDbService.createWorkspace(ws0pk, "FirstWorkspace"); - await testDbService.createWorkspace(ws1pk, "SecondWorkspace"); - await testDbService.createWorkspace(ws2pk, "ThirdWorkspace"); - await testDbService.createUser([ws0pk, ws1pk]); - await testDbService.createUser([ws2pk], { companyRole: "admin" }); - await testDbService.createUser([ws2pk], { companyRole: undefined, workspaceRole: "moderator" }); - await testDbService.createUser([], { companyRole: "guest" }); - }; - - const decodeToken = (token: string): InviteTokenObject => { - return gr.services.workspaces.decodeInviteToken(token); - }; - - describe("The GET /tokens/ route", () => { - beforeAll(startup); - afterAll(shutdown); - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - - const workspaceId = testDbService.workspaces[0].workspace.id; - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 403 when user is not a workspace member", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - const userIdFromAnotherWorkspace = platform.currentUser.id; - const companyId = testDbService.company.id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userIdFromAnotherWorkspace }); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - expect(response.statusCode).toBe(403); - - done(); - }); - - it("should 404 when token doesn't exists yet", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - const companyId = testDbService.company.id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(404); - - done(); - }); - - it("should 200 when user is a workspace member", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - const companyId = testDbService.company.id; - - await gr.services.workspaces.createInviteToken(companyId, workspaceId, userId); - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(200); - - expect(response.json()).toMatchObject({ - resources: [ - { - token: expect.any(String), - }, - ], - }); - - done(); - }); - }); - - describe("The POST /tokens/ route", () => { - beforeAll(startup); - afterAll(shutdown); - - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - - const workspaceId = testDbService.workspaces[0].workspace.id; - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 403 when user is not a workspace member", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - const userIdFromAnotherWorkspace = platform.currentUser.id; - const companyId = testDbService.company.id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userIdFromAnotherWorkspace }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - channels: ["test"], - }, - }); - expect(response.statusCode).toBe(403); - - done(); - }); - - it("should 200 when user is a workspace member", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - const companyId = testDbService.company.id; - const channel = await testDbService.createChannel(userId); - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const beforeResponse = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(beforeResponse.statusCode).toBe(404); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - channels: [channel.id], - }, - }); - - expect(response.statusCode).toBe(200); - - expect(response.json()).toMatchObject({ - resource: { - token: expect.any(String), - }, - }); - - const createToken = decodeToken(response.json().resource.token); - - const afterResponse = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(afterResponse.statusCode).toBe(200); - - expect(afterResponse.json()).toMatchObject({ - resources: [ - { - token: expect.any(String), - }, - ], - }); - - const getToken = decodeToken(afterResponse.json().resources[0].token); - - expect(createToken.t).toEqual(getToken.t); - - done(); - }); - - it("should 200 when when recreate token", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - const companyId = testDbService.company.id; - const channel = await testDbService.createChannel(userId); - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const beforeResponse = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(beforeResponse.statusCode).toBe(200); - - const beforeResponseResource = beforeResponse.json()["resources"][0]; - - expect(beforeResponseResource).toMatchObject({ - token: expect.any(String), - }); - - const beforeResponseToken = decodeToken(beforeResponseResource.token).t; - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - channels: [channel.id], - }, - }); - - expect(response.statusCode).toBe(200); - - const responseResource = response.json()["resource"]; - - expect(responseResource).toMatchObject({ - token: expect.any(String), - }); - - const responseToken = decodeToken(responseResource.token).t; - - expect(responseToken).not.toEqual(beforeResponseToken); - - const afterResponse = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(afterResponse.statusCode).toBe(200); - - const afterResponseResource = afterResponse.json()["resources"][0]; - - expect(afterResponseResource).toMatchObject({ - token: expect.any(String), - }); - - const afterResponseToken = decodeToken(afterResponseResource.token).t; - - expect(responseToken).toEqual(afterResponseToken); - expect(afterResponseToken).not.toEqual(beforeResponseToken); - - done(); - }); - }); - - describe("The DELETE /tokens/ route", () => { - beforeAll(startup); - afterAll(shutdown); - - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - - const workspaceId = testDbService.workspaces[0].workspace.id; - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens/fake1-${new Date().getTime()}`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 403 when user is not a workspace member", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - const userIdFromAnotherWorkspace = platform.currentUser.id; - const companyId = testDbService.company.id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userIdFromAnotherWorkspace }); - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens/fake2-${new Date().getTime()}`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: {}, - }); - expect(response.statusCode).toBe(403); - - done(); - }); - - it("should 204 when user is a workspace member", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - const companyId = testDbService.company.id; - - await gr.services.workspaces.createInviteToken(companyId, workspaceId, userId); - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const beforeResponse = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(beforeResponse.statusCode).toBe(200); - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens/${ - beforeResponse.json().resources[0].token - }`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(204); - - const afterResponse = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(afterResponse.statusCode).toBe(404); - - done(); - }); - - it("should 404 when deleting token that doesn't exists", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - const companyId = testDbService.company.id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}/users/tokens/fake3-${new Date().getTime()}`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: {}, - }); - expect(response.statusCode).toBe(404); - - done(); - }); - }); - - describe("Join workspace using token", () => { - let workspaceId; - let userId; - let companyId; - let inviteToken; - - beforeAll(async () => { - await startup(); - companyId = testDbService.company.id; - workspaceId = testDbService.workspaces[0].workspace.id; - userId = testDbService.workspaces[2].users[0].id; - inviteToken = await gr.services.workspaces.createInviteToken(companyId, workspaceId, userId); - }); - afterAll(shutdown); - - it("should 404 when when token not found", async done => { - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/join`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - join: false, - token: "SOME FAKE TOKEN", - }, - }); - expect(response.statusCode).toBe(404); - done(); - }); - - it("should 200 when user is not authorized", async done => { - const response = await platform.app.inject({ - method: "POST", - url: `${url}/join`, - // headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - join: false, - token: inviteToken.token, - }, - }); - expect(response.statusCode).toBe(200); - - const resource = response.json()["resource"]; - - expect(resource).toMatchObject({ - company: { - name: "TestJoinCompany", - }, - workspace: { - name: "FirstWorkspace", - }, - auth_required: true, - }); - - done(); - }); - - it("should 200 when user is authorized and not joining", async done => { - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/join`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - join: false, - token: inviteToken.token, - }, - }); - expect(response.statusCode).toBe(200); - - const resource = response.json()["resource"]; - - expect(resource).toMatchObject({ - company: { - name: "TestJoinCompany", - }, - workspace: { - name: "FirstWorkspace", - }, - auth_required: false, - }); - - done(); - }); - - it("should 200 when user is authorized and joining", async done => { - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/join`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - join: true, - token: inviteToken.token, - }, - }); - expect(response.statusCode).toBe(200); - - const resource = response.json()["resource"]; - - expect(resource).toMatchObject({ - company: { - id: companyId, - name: "TestJoinCompany", - }, - workspace: { - id: workspaceId, - name: "FirstWorkspace", - }, - auth_required: false, - }); - - done(); - }); - }); -}); diff --git a/twake/backend/node/test/e2e/workspaces/workspaces.spec.ts b/twake/backend/node/test/e2e/workspaces/workspaces.spec.ts deleted file mode 100644 index d251e304..00000000 --- a/twake/backend/node/test/e2e/workspaces/workspaces.spec.ts +++ /dev/null @@ -1,513 +0,0 @@ -import { afterAll, beforeAll, describe, expect, it } from "@jest/globals"; -import { init, TestPlatform } from "../setup"; -import { TestDbService } from "../utils.prepare.db"; -import { v1 as uuidv1 } from "uuid"; - -describe("The /workspaces API", () => { - const url = "/internal/services/workspaces/v1"; - let platform: TestPlatform; - - let testDbService: TestDbService; - - const nonExistentId = uuidv1(); - let companyId = ""; - - beforeAll(async ends => { - platform = await init({ - services: [ - "database", - "message-queue", - "webserver", - "user", - "search", - "workspaces", - "auth", - "console", - "counter", - "storage", - "applications", - "statistics", - "platform-services", - ], - }); - - companyId = platform.workspace.company_id; - - await platform.database.getConnector().init(); - testDbService = new TestDbService(platform); - await testDbService.createCompany(companyId); - const ws0pk = { id: uuidv1(), company_id: companyId }; - const ws1pk = { id: uuidv1(), company_id: companyId }; - const ws2pk = { id: uuidv1(), company_id: companyId }; - await testDbService.createWorkspace(ws0pk); - await testDbService.createWorkspace(ws1pk); - await testDbService.createWorkspace(ws2pk); - await testDbService.createUser([ws0pk, ws1pk]); - await testDbService.createUser([ws2pk], { companyRole: "admin" }); - await testDbService.createUser([ws2pk], { companyRole: undefined, workspaceRole: "moderator" }); - await testDbService.createUser([], { companyRole: "guest" }); - ends(); - }); - - afterAll(async ends => { - await platform.tearDown(); - ends(); - }); - - describe("The GET /workspaces/ route", () => { - it("should 401 when not authenticated", async done => { - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${nonExistentId}/workspaces`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 404 when company not found", async done => { - const userId = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${nonExistentId}/workspaces`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - expect(response.statusCode).toBe(404); - done(); - }); - - it("should 200 when company belongs to user", async done => { - const userId = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const companyId = testDbService.company.id; - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - expect(response.statusCode).toBe(200); - - const resources = response.json()["resources"]; - - expect(resources.length).toBe(2); - - for (const resource of resources) { - expect(resource).toMatchObject({ - id: expect.any(String), - company_id: expect.any(String), - name: expect.any(String), - logo: expect.any(String), - default: expect.any(Boolean), - archived: expect.any(Boolean), - role: expect.stringMatching(/moderator|member/), - }); - - if (resource.stats) { - expect(resource.stats).toMatchObject({ - created_at: expect.any(Number), - total_members: 1, - }); - } - } - - done(); - }); - }); - - describe("The GET /workspaces/:workspace_id route", () => { - it("should 401 when not authenticated", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${nonExistentId}/workspaces/${workspaceId}`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 404 when workspace not found", async done => { - const userId = testDbService.workspaces[0].users[0].id; - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${uuidv1()}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - expect(response.statusCode).toBe(404); - done(); - }); - - it("should 403 when user not belong to workspace and not company_admin", async done => { - const workspaceId = testDbService.workspaces[2].workspace.id; - const userIdFromAnotherWorkspace = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userIdFromAnotherWorkspace }); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - expect(response.statusCode).toBe(403); - - expect(response.json()).toEqual({ - error: "Forbidden", - message: `You are not belong to workspace ${workspaceId}`, - statusCode: 403, - }); - - done(); - }); - - it("should 200 when user is company_admin", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - const userIdFromAnotherWorkspace = testDbService.workspaces[2].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userIdFromAnotherWorkspace }); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - expect(response.statusCode).toBe(200); - - const resource = response.json()["resource"]; - - expect(resource).toMatchObject({ - id: expect.any(String), - company_id: expect.any(String), - name: expect.any(String), - logo: expect.any(String), - default: expect.any(Boolean), - archived: expect.any(Boolean), - }); - - if (resource.stats) { - expect(resource.stats).toMatchObject({ - created_at: expect.any(Number), - total_members: 1, - }); - } - - done(); - }); - - it("should 200 when user is belong to workspace", async done => { - const workspaceId = testDbService.workspaces[0].workspace.id; - const userIdFromThisWorkspace = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userIdFromThisWorkspace }); - - const response = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - expect(response.statusCode).toBe(200); - - const resource = response.json()["resource"]; - - expect(resource).toMatchObject({ - id: expect.any(String), - company_id: expect.any(String), - name: expect.any(String), - logo: expect.any(String), - default: expect.any(Boolean), - archived: expect.any(Boolean), - role: expect.stringMatching(/moderator|member/), - }); - - if (resource.stats) { - expect(resource.stats).toMatchObject({ - created_at: expect.any(Number), - total_members: 1, - }); - } - - done(); - }); - }); - - // create - - describe("The POST /workspaces route (creating workspace)", () => { - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 403 when user is not (company member or company admin) ", async done => { - const companyId = testDbService.company.id; - const userId = testDbService.users[3].id; - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - resource: { - name: "Some channel name", - logo: "", - default: false, - }, - }, - }); - - expect(response.statusCode).toBe(403); - done(); - }); - - it("should 201 when workspace created well", async done => { - const companyId = testDbService.company.id; - const userId = testDbService.users[0].id; - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - resource: { - name: "Random channel name", - logo: "logo", - default: false, - }, - }, - }); - - expect(response.statusCode).toBe(201); - - const resource = response.json()["resource"]; - - expect(resource).toMatchObject({ - id: expect.any(String), - company_id: expect.any(String), - name: expect.any(String), - logo: expect.any(String), - default: expect.any(Boolean), - archived: expect.any(Boolean), - role: expect.stringMatching(/moderator/), - }); - - done(); - }); - }); - - // update - - describe("The POST /workspaces/:workspace_id route (updating workspace)", () => { - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}`, - payload: { resource: {} }, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 403 when not workspace not found", async done => { - const companyId = testDbService.company.id; - const userId = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { resource: {} }, - }); - - expect(response.statusCode).toBe(403); - - done(); - }); - - it("should 403 when not belong to workspace", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[1].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { resource: {} }, - }); - - expect(response.statusCode).toBe(403); - - done(); - }); - - it("should 403 when not workspace moderator", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[1].workspace.id; - const userId = testDbService.workspaces[0].users[0].id; - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { resource: {} }, - }); - - expect(response.statusCode).toBe(403); - - done(); - }); - - it("should 200 when admin of company (full update)", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[0].id; // company owner - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - resource: { - name: "Another workspace name", - logo: "logo", - default: false, - archived: false, - }, - }, - }); - - expect(response.statusCode).toBe(200); - - const resource = response.json()["resource"]; - - expect(resource).toMatchObject({ - id: workspaceId, - company_id: companyId, - name: "Another workspace name", - logo: expect.any(String), - default: false, - archived: false, - role: "moderator", //Company admin is a moderator - }); - - done(); - }); - - it("should 200 when moderator of workspace (partial update)", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[1].id; // workspace admin - - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "POST", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - payload: { - resource: { - name: "My awesome workspace", - default: true, - logo: "", - }, - }, - }); - - expect(response.statusCode).toBe(200); - - const resource = response.json()["resource"]; - - expect(resource).toMatchObject({ - id: workspaceId, - company_id: companyId, - name: "My awesome workspace", - logo: expect.any(String), - default: true, - archived: false, - role: "moderator", - }); - - done(); - }); - }); - - // delete - - describe("The DELETE /workspaces route", () => { - it("should 401 when not authenticated", async done => { - const companyId = testDbService.company.id; - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${nonExistentId}`, - }); - expect(response.statusCode).toBe(401); - done(); - }); - - it("should 403 when user is not (company member or company admin) ", async done => { - const companyId = testDbService.company.id; - const userId = testDbService.users[3].id; - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - const workspaceId = testDbService.workspaces[0].workspace.id; - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(403); - done(); - }); - - it("should 204 when workspace deleted", async done => { - const companyId = testDbService.company.id; - const workspaceId = testDbService.workspaces[2].workspace.id; - const userId = testDbService.workspaces[2].users[0].id; - const jwtToken = await platform.auth.getJWTToken({ sub: userId }); - - const response = await platform.app.inject({ - method: "DELETE", - url: `${url}/companies/${companyId}/workspaces/${workspaceId}`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - expect(response.statusCode).toBe(204); - - const checkResponse = await platform.app.inject({ - method: "GET", - url: `${url}/companies/${companyId}/workspaces`, - headers: { authorization: `Bearer ${jwtToken}` }, - }); - - const checkResponseJson = checkResponse.json(); - - expect(checkResponseJson.resources.find((a: any) => a.id === workspaceId)).toBe(undefined); - - done(); - }); - }); -});