From d3bd851e2690b9936e36c689e11ea4419a85e179 Mon Sep 17 00:00:00 2001 From: rajdip-b Date: Mon, 12 Feb 2024 23:58:32 +0530 Subject: [PATCH] test: Add event E2E tests --- apps/api/src/api-key/api-key.e2e.spec.ts | 7 +- apps/api/src/common/cleanup.ts | 16 + apps/api/src/common/create-event.ts | 127 ++----- .../src/event/controller/event.controller.ts | 6 +- apps/api/src/event/event.e2e.spec.ts | 352 ++++++++++++++++++ apps/api/src/event/service/event.service.ts | 21 +- .../20240212183333_update_event/migration.sql | 14 + apps/api/src/prisma/schema.prisma | 1 - .../workspace-role/workspace-role.e2e.spec.ts | 20 +- .../controller/workspace.controller.ts | 8 +- .../workspace/service/workspace.service.ts | 48 ++- apps/api/tsconfig.app.json | 2 +- apps/api/tsconfig.spec.json | 3 +- package.json | 2 +- 14 files changed, 470 insertions(+), 157 deletions(-) create mode 100644 apps/api/src/common/cleanup.ts create mode 100644 apps/api/src/event/event.e2e.spec.ts create mode 100644 apps/api/src/prisma/migrations/20240212183333_update_event/migration.sql diff --git a/apps/api/src/api-key/api-key.e2e.spec.ts b/apps/api/src/api-key/api-key.e2e.spec.ts index f15bc63b..fbffbbac 100644 --- a/apps/api/src/api-key/api-key.e2e.spec.ts +++ b/apps/api/src/api-key/api-key.e2e.spec.ts @@ -9,6 +9,7 @@ import { MockMailService } from '../mail/services/mock.service' import { AppModule } from '../app/app.module' import { Test } from '@nestjs/testing' import { ApiKey, User } from '@prisma/client' +import cleanUp from '../common/cleanup' describe('Api Key Role Controller Tests', () => { let app: NestFastifyApplication @@ -194,10 +195,6 @@ describe('Api Key Role Controller Tests', () => { }) afterAll(async () => { - await prisma.apiKey.deleteMany() - await prisma.user.deleteMany() - - await prisma.$disconnect() - await app.close() + await cleanUp(prisma) }) }) diff --git a/apps/api/src/common/cleanup.ts b/apps/api/src/common/cleanup.ts new file mode 100644 index 00000000..eed8ca87 --- /dev/null +++ b/apps/api/src/common/cleanup.ts @@ -0,0 +1,16 @@ +import { PrismaClient } from '@prisma/client' + +export default async function cleanUp(prisma: PrismaClient) { + await prisma.$transaction([ + prisma.workspaceMemberRoleAssociation.deleteMany(), + prisma.workspaceMember.deleteMany(), + prisma.workspaceRole.deleteMany(), + prisma.workspace.deleteMany(), + prisma.secret.deleteMany(), + prisma.environment.deleteMany(), + prisma.project.deleteMany(), + prisma.user.deleteMany(), + prisma.event.deleteMany(), + prisma.apiKey.deleteMany() + ]) +} diff --git a/apps/api/src/common/create-event.ts b/apps/api/src/common/create-event.ts index 2e622954..bdb7b795 100644 --- a/apps/api/src/common/create-event.ts +++ b/apps/api/src/common/create-event.ts @@ -10,7 +10,6 @@ import { Secret, User, Workspace, - WorkspaceMember, WorkspaceRole } from '@prisma/client' import { JsonObject } from '@prisma/client/runtime/library' @@ -20,14 +19,7 @@ export default async function createEvent( triggerer?: EventTriggerer severity?: EventSeverity triggeredBy?: User - entity?: - | Workspace - | Project - | Environment - | WorkspaceRole - | WorkspaceMember - | ApiKey - | Secret + entity?: Workspace | Project | Environment | WorkspaceRole | ApiKey | Secret type: EventType source: EventSource title: string @@ -40,119 +32,60 @@ export default async function createEvent( throw new Error('User must be provided for non-system events') } - const baseData = { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const baseData: any = { triggerer: data.triggerer ?? EventTriggerer.USER, severity: data.severity ?? EventSeverity.INFO, type: data.type, source: data.source, title: data.title, - description: data.description, - metadata: data.metadata, - sourceUser: data.triggeredBy.id - ? { - connect: { - id: data.triggeredBy.id - } - } - : undefined + description: data.description ?? '', + metadata: data.metadata + } + + if (data.triggeredBy) { + baseData.sourceUserId = data.triggeredBy.id } try { switch (data.source) { case EventSource.WORKSPACE: { - const entity = data.entity as Workspace - await prisma.event.create({ - data: { - ...baseData, - sourceWorkspace: data.entity - ? { - connect: { - id: entity.id - } - } - : undefined - } - }) + if (data.entity) { + baseData.sourceWorkspaceId = data.entity.id + } break } case EventSource.PROJECT: { - const entity = data.entity as Project - await prisma.event.create({ - data: { - ...baseData, - sourceProject: data.entity - ? { connect: { id: entity.id } } - : undefined - } - }) + if (data.entity) { + baseData.sourceProjectId = data.entity.id + } break } case EventSource.ENVIRONMENT: { - const entity = data.entity as Environment - await prisma.event.create({ - data: { - ...baseData, - sourceEnvironment: data.entity - ? { connect: { id: entity.id } } - : undefined - } - }) + if (data.entity) { + baseData.sourceEnvironmentId = data.entity.id + } break } case EventSource.WORKSPACE_ROLE: { - const entity = data.entity as WorkspaceRole - await prisma.event.create({ - data: { - ...baseData, - sourceWorkspaceRole: data.entity - ? { connect: { id: entity.id } } - : undefined - } - }) - break - } - case EventSource.WORKSPACE_MEMBER: { - const entity = data.entity as WorkspaceMember - await prisma.event.create({ - data: { - ...baseData, - sourceWorkspaceMembership: data.entity - ? { connect: { id: entity.id } } - : undefined - } - }) + if (data.entity) { + baseData.sourceWorkspaceRoleId = data.entity.id + } break } case EventSource.API_KEY: { - const entity = data.entity as ApiKey - await prisma.event.create({ - data: { - ...baseData, - sourceApiKey: data.entity - ? { connect: { id: entity.id } } - : undefined - } - }) + if (data.entity) { + baseData.sourceApiKeyId = data.entity.id + } break } case EventSource.SECRET: { - const entity = data.entity as Secret - await prisma.event.create({ - data: { - ...baseData, - sourceSecret: data.entity - ? { connect: { id: entity.id } } - : undefined - } - }) + if (data.entity) { + baseData.sourceSecretId = data.entity.id + } break } case EventSource.USER: { - await prisma.event.create({ - data: { - ...baseData - } - }) break } default: { @@ -160,6 +93,10 @@ export default async function createEvent( } } } catch (error) { - console.error('Error creating event', error) + console.error('Error creating event', data, error) } + + await prisma.event.create({ + data: baseData + }) } diff --git a/apps/api/src/event/controller/event.controller.ts b/apps/api/src/event/controller/event.controller.ts index 48a82594..c47f3433 100644 --- a/apps/api/src/event/controller/event.controller.ts +++ b/apps/api/src/event/controller/event.controller.ts @@ -23,8 +23,7 @@ export class EventController { @Query('environmentId') environmentId: string, @Query('secretId') secretId: string, @Query('apiKeyId') apiKeyId: string, - @Query('workspaceRoleId') workspaceRoleId: string, - @Query('workspaceMemberId') workspaceMemberId: string + @Query('workspaceRoleId') workspaceRoleId: string ) { return this.eventService.getEvents( user, @@ -34,8 +33,7 @@ export class EventController { environmentId, secretId, apiKeyId, - workspaceRoleId, - workspaceMemberId + workspaceRoleId }, page, limit, diff --git a/apps/api/src/event/event.e2e.spec.ts b/apps/api/src/event/event.e2e.spec.ts new file mode 100644 index 00000000..d1ebbf3a --- /dev/null +++ b/apps/api/src/event/event.e2e.spec.ts @@ -0,0 +1,352 @@ +import { + FastifyAdapter, + NestFastifyApplication +} from '@nestjs/platform-fastify' +import { + Authority, + Environment, + EventSeverity, + EventSource, + EventTriggerer, + EventType, + Project, + User, + Workspace +} from '@prisma/client' +import { PrismaService } from '../prisma/prisma.service' +import { Test } from '@nestjs/testing' +import { WorkspaceRoleModule } from '../workspace-role/workspace-role.module' +import { AppModule } from '../app/app.module' +import { MAIL_SERVICE } from '../mail/services/interface.service' +import { MockMailService } from '../mail/services/mock.service' +import { EventModule } from './event.module' +import { UserModule } from '../user/user.module' +import { UserService } from '../user/service/user.service' +import cleanUp from '../common/cleanup' +import { WorkspaceService } from '../workspace/service/workspace.service' +import { WorkspaceModule } from '../workspace/workspace.module' +import { ApiKeyService } from '../api-key/service/api-key.service' +import { EnvironmentService } from '../environment/service/environment.service' +import { WorkspaceRoleService } from '../workspace-role/service/workspace-role.service' +import { ProjectService } from '../project/service/project.service' +import { SecretService } from '../secret/service/secret.service' +import { SecretModule } from '../secret/secret.module' +import { ProjectModule } from '../project/project.module' +import { EnvironmentModule } from '../environment/environment.module' +import { ApiKeyModule } from '../api-key/api-key.module' + +const makeRequest = async ( + app: NestFastifyApplication, + user: User, + query?: string +) => + await app.inject({ + method: 'GET', + headers: { + 'x-e2e-user-email': user.email + }, + url: `/event${query ? '?' + query : ''}` + }) + +describe('Event Controller Tests', () => { + let app: NestFastifyApplication + let prisma: PrismaService + + let userService: UserService + let workspaceService: WorkspaceService + let apiKeyService: ApiKeyService + let environmentService: EnvironmentService + let workspaceRoleService: WorkspaceRoleService + let projectService: ProjectService + let secretService: SecretService + + let user: User + let workspace: Workspace + let project: Project + let environment: Environment + + const totalEvents = [] + + beforeAll(async () => { + const moduleRef = await Test.createTestingModule({ + imports: [ + AppModule, + EventModule, + UserModule, + WorkspaceModule, + WorkspaceRoleModule, + SecretModule, + ProjectModule, + EnvironmentModule, + ApiKeyModule + ] + }) + .overrideProvider(MAIL_SERVICE) + .useClass(MockMailService) + .compile() + + app = moduleRef.createNestApplication( + new FastifyAdapter() + ) + prisma = moduleRef.get(PrismaService) + userService = moduleRef.get(UserService) + workspaceService = moduleRef.get(WorkspaceService) + apiKeyService = moduleRef.get(ApiKeyService) + environmentService = moduleRef.get(EnvironmentService) + workspaceRoleService = moduleRef.get(WorkspaceRoleService) + projectService = moduleRef.get(ProjectService) + secretService = moduleRef.get(SecretService) + + await app.init() + await app.getHttpAdapter().getInstance().ready() + + await cleanUp(prisma) + + user = await prisma.user.create({ + data: { + email: 'johndoe@keyshade.xyz', + name: 'John Doe' + } + }) + }) + + it('should be able to fetch a user event', async () => { + const updatedUser = await userService.updateSelf(user, { + isOnboardingFinished: true + }) + user = updatedUser + + expect(updatedUser).toBeDefined() + + const response = await makeRequest(app, user) + + totalEvents.push({ + id: expect.any(String), + title: expect.any(String), + description: expect.any(String), + source: EventSource.USER, + triggerer: EventTriggerer.USER, + severity: EventSeverity.INFO, + type: EventType.USER_UPDATED, + timestamp: expect.any(String), + metadata: expect.any(Object) + }) + + expect(response.statusCode).toBe(200) + expect(response.json()).toEqual(totalEvents) + }) + + it('should be able to fetch API key event', async () => { + const newApiKey = await apiKeyService.createApiKey(user, { + name: 'My API key', + authorities: [Authority.READ_API_KEY] + }) + + expect(newApiKey).toBeDefined() + + const response = await makeRequest(app, user, `apiKeyId=${newApiKey.id}`) + + const event = { + id: expect.any(String), + title: expect.any(String), + description: expect.any(String), + source: EventSource.API_KEY, + triggerer: EventTriggerer.USER, + severity: EventSeverity.INFO, + type: EventType.API_KEY_ADDED, + timestamp: expect.any(String), + metadata: expect.any(Object) + } + + totalEvents.push(event) + + expect(response.statusCode).toBe(200) + expect(response.json()).toEqual([event]) + }) + + it('should be able to fetch a workspace event', async () => { + const newWorkspace = await workspaceService.createWorkspace(user, { + name: 'My workspace', + description: 'Some description' + }) + workspace = newWorkspace + + expect(newWorkspace).toBeDefined() + + const response = await makeRequest( + app, + user, + `workspaceId=${newWorkspace.id}` + ) + + const event = { + id: expect.any(String), + title: expect.any(String), + description: expect.any(String), + source: EventSource.WORKSPACE, + triggerer: EventTriggerer.USER, + severity: EventSeverity.INFO, + type: EventType.WORKSPACE_CREATED, + timestamp: expect.any(String), + metadata: expect.any(Object) + } + + totalEvents.push(event) + + expect(response.statusCode).toBe(200) + expect(response.json()).toEqual([event]) + }) + + it('should be able to fetch a project event', async () => { + const newProject = await projectService.createProject(user, workspace.id, { + name: 'My project', + description: 'Some description', + environments: [], + storePrivateKey: false + }) + project = newProject + + expect(newProject).toBeDefined() + + const response = await makeRequest(app, user, `projectId=${newProject.id}`) + + const event = { + id: expect.any(String), + title: expect.any(String), + description: expect.any(String), + source: EventSource.PROJECT, + triggerer: EventTriggerer.USER, + severity: EventSeverity.INFO, + type: EventType.PROJECT_CREATED, + timestamp: expect.any(String), + metadata: expect.any(Object) + } + + totalEvents.push(event) + + expect(response.statusCode).toBe(200) + expect(response.json()).toEqual([event]) + }) + + it('should be able to fetch an environment event', async () => { + const newEnvironment = await environmentService.createEnvironment( + user, + { + name: 'My environment', + description: 'Some description', + isDefault: false + }, + project.id + ) + environment = newEnvironment + + expect(newEnvironment).toBeDefined() + + const response = await makeRequest( + app, + user, + `environmentId=${newEnvironment.id}` + ) + + const event = { + id: expect.any(String), + title: expect.any(String), + description: expect.any(String), + source: EventSource.ENVIRONMENT, + triggerer: EventTriggerer.USER, + severity: EventSeverity.INFO, + type: EventType.ENVIRONMENT_ADDED, + timestamp: expect.any(String), + metadata: expect.any(Object) + } + + totalEvents.push(event) + + expect(response.statusCode).toBe(200) + expect(response.json()).toEqual([event]) + }) + + it('should be able to fetch a secret event', async () => { + const newSecret = await secretService.createSecret( + user, + { + name: 'My secret', + value: 'My value', + environmentId: environment.id, + rotateAfter: '720' + }, + project.id + ) + + expect(newSecret).toBeDefined() + + const response = await makeRequest(app, user, `secretId=${newSecret.id}`) + + const event = { + id: expect.any(String), + title: expect.any(String), + description: expect.any(String), + source: EventSource.SECRET, + triggerer: EventTriggerer.USER, + severity: EventSeverity.INFO, + type: EventType.SECRET_ADDED, + timestamp: expect.any(String), + metadata: expect.any(Object) + } + + totalEvents.push(event) + + expect(response.statusCode).toBe(200) + expect(response.json()).toEqual([event]) + }) + + it('should be able to fetch a workspace role event', async () => { + const newWorkspaceRole = await workspaceRoleService.createWorkspaceRole( + user, + workspace.id, + { + name: 'My role', + description: 'Some description', + colorCode: '#000000', + authorities: [], + projectIds: [project.id] + } + ) + + expect(newWorkspaceRole).toBeDefined() + + const response = await makeRequest( + app, + user, + `workspaceRoleId=${newWorkspaceRole.id}` + ) + + const event = { + id: expect.any(String), + title: expect.any(String), + description: expect.any(String), + source: EventSource.WORKSPACE_ROLE, + triggerer: EventTriggerer.USER, + severity: EventSeverity.INFO, + type: EventType.WORKSPACE_ROLE_CREATED, + timestamp: expect.any(String), + metadata: expect.any(Object) + } + + totalEvents.push(event) + + expect(response.statusCode).toBe(200) + expect(response.json()).toEqual([event]) + }) + + it('should be able to fetch all events', async () => { + const response = await makeRequest(app, user) + + expect(response.statusCode).toBe(200) + expect(response.json()).toEqual(totalEvents) + }) + + afterAll(async () => { + await cleanUp(prisma) + }) +}) diff --git a/apps/api/src/event/service/event.service.ts b/apps/api/src/event/service/event.service.ts index d83a0dbc..800cf35a 100644 --- a/apps/api/src/event/service/event.service.ts +++ b/apps/api/src/event/service/event.service.ts @@ -19,7 +19,6 @@ export class EventService { secretId?: string apiKeyId?: string workspaceRoleId?: string - workspaceMemberId?: string }, page: number, limit: number, @@ -73,21 +72,23 @@ export class EventService { } else if (context.apiKeyId) { whereCondition['sourceApiKeyId'] = context.apiKeyId } else if (context.workspaceRoleId) { + const workspaceRole = await this.prisma.workspaceRole.findUnique({ + where: { + id: context.workspaceRoleId + }, + include: { + workspace: true + } + }) await getWorkspaceWithAuthority( user.id, - context.workspaceRoleId, + workspaceRole.workspace.id, Authority.READ_WORKSPACE_ROLE, this.prisma ) whereCondition['sourceWorkspaceRoleId'] = context.workspaceRoleId - } else if (context.workspaceMemberId) { - await getWorkspaceWithAuthority( - user.id, - context.workspaceMemberId, - Authority.READ_USERS, - this.prisma - ) - whereCondition['sourceWorkspaceMembershipId'] = context.workspaceMemberId + } else { + whereCondition['sourceUserId'] = user.id } // Get the events diff --git a/apps/api/src/prisma/migrations/20240212183333_update_event/migration.sql b/apps/api/src/prisma/migrations/20240212183333_update_event/migration.sql new file mode 100644 index 00000000..a9559c74 --- /dev/null +++ b/apps/api/src/prisma/migrations/20240212183333_update_event/migration.sql @@ -0,0 +1,14 @@ +/* + Warnings: + + - The values [WORKSPACE_MEMBER] on the enum `EventSource` will be removed. If these variants are still used in the database, this will fail. + +*/ +-- AlterEnum +BEGIN; +CREATE TYPE "EventSource_new" AS ENUM ('SECRET', 'API_KEY', 'ENVIRONMENT', 'PROJECT', 'WORKSPACE', 'WORKSPACE_ROLE', 'USER'); +ALTER TABLE "Event" ALTER COLUMN "source" TYPE "EventSource_new" USING ("source"::text::"EventSource_new"); +ALTER TYPE "EventSource" RENAME TO "EventSource_old"; +ALTER TYPE "EventSource_new" RENAME TO "EventSource"; +DROP TYPE "EventSource_old"; +COMMIT; diff --git a/apps/api/src/prisma/schema.prisma b/apps/api/src/prisma/schema.prisma index 29ffb65e..1b01c797 100644 --- a/apps/api/src/prisma/schema.prisma +++ b/apps/api/src/prisma/schema.prisma @@ -15,7 +15,6 @@ enum EventSource { WORKSPACE WORKSPACE_ROLE USER - WORKSPACE_MEMBER } enum EventTriggerer { diff --git a/apps/api/src/workspace-role/workspace-role.e2e.spec.ts b/apps/api/src/workspace-role/workspace-role.e2e.spec.ts index c0d71668..36b198bd 100644 --- a/apps/api/src/workspace-role/workspace-role.e2e.spec.ts +++ b/apps/api/src/workspace-role/workspace-role.e2e.spec.ts @@ -16,6 +16,7 @@ import { MAIL_SERVICE } from '../mail/services/interface.service' import { MockMailService } from '../mail/services/mock.service' import { Test } from '@nestjs/testing' import { v4 } from 'uuid' +import cleanUp from '../common/cleanup' describe('Workspace Role Controller Tests', () => { let app: NestFastifyApplication @@ -45,13 +46,7 @@ describe('Workspace Role Controller Tests', () => { await app.init() await app.getHttpAdapter().getInstance().ready() - await prisma.$transaction([ - prisma.user.deleteMany(), - prisma.project.deleteMany(), - prisma.workspace.deleteMany(), - prisma.workspaceRole.deleteMany(), - prisma.workspaceMember.deleteMany() - ]) + await cleanUp(prisma) const aliceId = v4() const bobId = v4() @@ -906,15 +901,6 @@ describe('Workspace Role Controller Tests', () => { }) afterAll(async () => { - await prisma.$transaction([ - prisma.user.deleteMany(), - prisma.project.deleteMany(), - prisma.workspace.deleteMany(), - prisma.workspaceRole.deleteMany(), - prisma.workspaceMember.deleteMany() - ]) - - await prisma.$disconnect() - await app.close() + await cleanUp(prisma) }) }) diff --git a/apps/api/src/workspace/controller/workspace.controller.ts b/apps/api/src/workspace/controller/workspace.controller.ts index c3e05274..762ed1ac 100644 --- a/apps/api/src/workspace/controller/workspace.controller.ts +++ b/apps/api/src/workspace/controller/workspace.controller.ts @@ -59,14 +59,18 @@ export class WorkspaceController { return this.workspaceService.deleteWorkspace(user, workspaceId) } - @Post(':workspaceId/add-users') + @Post(':workspaceId/invite-users') @RequiredApiKeyAuthorities(Authority.ADD_USER) async addUsers( @CurrentUser() user: User, @Param('workspaceId') workspaceId: Workspace['id'], @Body() members: WorkspaceMemberDTO[] ) { - return this.workspaceService.addUsersToWorkspace(user, workspaceId, members) + return this.workspaceService.inviteUsersToWorkspace( + user, + workspaceId, + members + ) } @Delete(':workspaceId/remove-users') diff --git a/apps/api/src/workspace/service/workspace.service.ts b/apps/api/src/workspace/service/workspace.service.ts index 60193474..3968c4f1 100644 --- a/apps/api/src/workspace/service/workspace.service.ts +++ b/apps/api/src/workspace/service/workspace.service.ts @@ -305,7 +305,6 @@ export class WorkspaceService { createEvent( { triggeredBy: user, - entity: workspace, type: EventType.WORKSPACE_DELETED, source: EventSource.WORKSPACE, title: `Workspace deleted`, @@ -320,7 +319,7 @@ export class WorkspaceService { this.log.debug(`Deleted workspace ${workspace.name} (${workspace.id})`) } - async addUsersToWorkspace( + async inviteUsersToWorkspace( user: User, workspaceId: Workspace['id'], members: WorkspaceMemberDTO[] @@ -679,7 +678,8 @@ export class WorkspaceService { // Get all the memberships of this workspace const memberships = await this.prisma.workspaceMember.findMany({ where: { - workspaceId + workspaceId, + invitationAccepted: true } }) @@ -913,30 +913,42 @@ export class WorkspaceService { } }) + const userId = memberUser?.id ?? v4() + // Check if the user is already a member of the workspace if ( memberUser && - (await this.memberExistsInWorkspace(workspace.id, memberUser.id)) - ) - throw new ConflictException( - `User ${memberUser.name} (${memberUser.id}) is already a member of workspace ${workspace.name} (${workspace.id})` + (await this.memberExistsInWorkspace(workspace.id, userId)) + ) { + this.log.warn( + `User ${ + memberUser.name ?? 'NO_NAME_YET' + } (${userId}) is already a member of workspace ${workspace.name} (${ + workspace.id + }). Skipping.` ) + return + } // Create the workspace membership const createMembership = this.prisma.workspaceMember.create({ data: { workspaceId: workspace.id, - userId: memberUser.id, + userId, roles: { - connect: member.roleIds.map((r) => ({ id: r })) + create: member.roleIds.map((id) => ({ + role: { + connect: { + id + } + } + })) } } }) - let txResult - if (memberUser) { - txResult = await this.prisma.$transaction([createMembership]) + await this.prisma.$transaction([createMembership]) this.mailService.workspaceInvitationMailForUsers( member.email, @@ -952,14 +964,12 @@ export class WorkspaceService { } else { const createMember = this.prisma.user.create({ data: { + id: userId, email: member.email } }) - txResult = await this.prisma.$transaction([ - createMember, - createMembership - ]) + await this.prisma.$transaction([createMember, createMembership]) this.log.debug(`Created non-registered user ${memberUser}`) @@ -969,7 +979,7 @@ export class WorkspaceService { `${process.env.WORKSPACE_FRONTEND_URL}/workspace/${ workspace.id }/join?token=${await this.jwt.signAsync({ - id: memberUser.id + id: userId })}`, currentUser.name, false @@ -980,9 +990,7 @@ export class WorkspaceService { ) } - this.log.debug( - `Added user ${memberUser} to workspace ${workspace.name}. Membership: ${txResult[0].membership.id}` - ) + this.log.debug(`Added user ${memberUser} to workspace ${workspace.name}.`) } } diff --git a/apps/api/tsconfig.app.json b/apps/api/tsconfig.app.json index a2ce7652..8e277f05 100644 --- a/apps/api/tsconfig.app.json +++ b/apps/api/tsconfig.app.json @@ -8,5 +8,5 @@ "target": "es2021" }, "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], - "include": ["src/**/*.ts"] + "include": ["src/**/*.ts", "src/event/event.e2e.spec.ts"] } diff --git a/apps/api/tsconfig.spec.json b/apps/api/tsconfig.spec.json index 9b2a121d..02deb734 100644 --- a/apps/api/tsconfig.spec.json +++ b/apps/api/tsconfig.spec.json @@ -9,6 +9,7 @@ "jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", - "src/**/*.d.ts" + "src/**/*.d.ts", + "src/event/event.e2e.spec.ts" ] } diff --git a/package.json b/package.json index 94f593e4..7e09f8d2 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "test": "nx run-many -t test --parallel", "test:api": "nx run api:test", "e2e:api:prepare": "docker compose down && docker compose -f docker-compose-test.yml up -d && NODE_ENV='e2e' DATABASE_URL='postgresql://prisma:prisma@localhost:5432/tests' pnpm run db:deploy-migrations", - "e2e:api": "pnpm run e2e:api:prepare && NODE_ENV='e2e' DATABASE_URL='postgresql://prisma:prisma@localhost:5432/tests' nx run api:test:e2e -- --coverage --coverageDirectory=coverage-e2e/api --coverageReporters=json && pnpm run e2e:api:teardown", + "e2e:api": "pnpm run e2e:api:prepare && NODE_ENV='e2e' DATABASE_URL='postgresql://prisma:prisma@localhost:5432/tests' nx run api:test:e2e --skip-nx-cache -- --coverage --coverageDirectory=coverage-e2e/api --coverageReporters=json && pnpm run e2e:api:teardown", "e2e:api:teardown": "docker compose -f docker-compose-test.yml down", "test:web": "nx run web:test", "test:workspace": "nx run workspace:test",