Skip to content

Commit

Permalink
test(api): Refactor project e2e tests to be more readable
Browse files Browse the repository at this point in the history
  • Loading branch information
rajdip-b committed May 13, 2024
1 parent ae1efd8 commit 4f8c178
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 114 deletions.
1 change: 0 additions & 1 deletion apps/api/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import { FeedbackModule } from '../feedback/feedback.module'
imports: [
ConfigModule.forRoot({
isGlobal: true,
// For some reason config module is looking for .env in the api directory so defining custom path
envFilePath: '../../.env',
validate: EnvSchema.parse,
validationOptions: {
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { GitlabStrategy } from '../config/oauth-strategy/gitlab/gitlab.strategy'
imports: [
JwtModule.register({
global: true,
secret: process.env.JWT_SECRET,
secret: process.env.JWT_SECRET ?? 'secret',
signOptions: {
expiresIn: '1d',
issuer: 'keyshade.xyz',
Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/project/controller/project.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class ProjectController {
@CurrentUser() user: User,
@Param('projectId') projectId: Project['id']
) {
return await this.service.getProjectByUserAndId(user, projectId)
return await this.service.getProjectById(user, projectId)
}

@Get('/all/:workspaceId')
Expand Down
188 changes: 82 additions & 106 deletions apps/api/src/project/project.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { MAIL_SERVICE } from '../mail/services/interface.service'
import { MockMailService } from '../mail/services/mock.service'
import cleanUp from '../common/cleanup'
import {
Authority,
EventSeverity,
EventSource,
EventTriggerer,
Expand All @@ -19,23 +18,36 @@ import {
User,
Workspace
} from '@prisma/client'
import { v4 } from 'uuid'
import fetchEvents from '../common/fetch-events'
import { EventService } from '../event/service/event.service'
import { EventModule } from '../event/event.module'
import { ProjectService } from './service/project.service'
import { WorkspaceService } from '../workspace/service/workspace.service'
import { UserService } from '../user/service/user.service'
import { WorkspaceModule } from '../workspace/workspace.module'
import { UserModule } from '../user/user.module'

describe('Project Controller Tests', () => {
let app: NestFastifyApplication
let prisma: PrismaService
let eventService: EventService
let projectService: ProjectService
let workspaceService: WorkspaceService
let userService: UserService

let user1: User, user2: User
let workspace1: Workspace
let project1: Project, project2: Project, otherProject: Project
let workspace1: Workspace, workspace2: Workspace
let project1: Project, project2: Project

beforeAll(async () => {
const moduleRef = await Test.createTestingModule({
imports: [AppModule, ProjectModule, EventModule]
imports: [
AppModule,
ProjectModule,
EventModule,
WorkspaceModule,
UserModule
]
})
.overrideProvider(MAIL_SERVICE)
.useClass(MockMailService)
Expand All @@ -46,120 +58,76 @@ describe('Project Controller Tests', () => {
)
prisma = moduleRef.get(PrismaService)
eventService = moduleRef.get(EventService)
projectService = moduleRef.get(ProjectService)
workspaceService = moduleRef.get(WorkspaceService)
userService = moduleRef.get(UserService)

await app.init()
await app.getHttpAdapter().getInstance().ready()

await cleanUp(prisma)
})

const workspace1Id = v4()
const workspace2Id = v4()
const workspace1AdminRoleId = v4()
const user1Id = v4(),
user2Id = v4()

const createUser1 = prisma.user.create({
data: {
id: user1Id,
email: 'johndoe@keyshade.xyz',
name: 'John Doe',
isOnboardingFinished: true
}
})

const createUser2 = prisma.user.create({
data: {
id: user2Id,
email: 'jane@keyshade.xyz',
name: 'Jane Doe',
isOnboardingFinished: true
}
})

const createWorkspace1 = prisma.workspace.create({
data: {
id: workspace1Id,
name: 'Workspace 1',
ownerId: user1Id
}
})

const createWorkspace1AdminRole = prisma.workspaceRole.create({
data: {
id: workspace1AdminRoleId,
name: 'Admin',
hasAdminAuthority: true,
authorities: [Authority.WORKSPACE_ADMIN],
workspaceId: workspace1Id
}
})

const createWorkspace1Membership1 = prisma.workspaceMember.create({
data: {
userId: user1Id,
workspaceId: workspace1Id,
invitationAccepted: true,
roles: {
create: {
roleId: workspace1AdminRoleId
}
}
}
beforeEach(async () => {
const createUser1 = await userService.createUser({
name: 'John Doe',
email: 'johndoe@keyshade.xyz',
isOnboardingFinished: true,
isActive: true,
isAdmin: false
})

const createWorkspace2 = prisma.workspace.create({
data: {
id: workspace2Id,
name: 'Workspace 2',
ownerId: user2Id
}
const createUser2 = await userService.createUser({
name: 'Jane Doe',
email: 'janedoe@keyshade.xyz',
isOnboardingFinished: true,
isActive: true,
isAdmin: false
})

const createOtherProject = prisma.project.create({
data: {
name: 'Other Project',
description: 'Other Project description',
publicKey: '',
privateKey: '',
isPublic: false,
workspace: {
connect: {
id: workspace2Id
}
}
}
})
workspace1 = createUser1.defaultWorkspace as Workspace
workspace2 = createUser2.defaultWorkspace as Workspace

const result = await prisma.$transaction([
createUser1,
createUser2,
createWorkspace1,
createWorkspace1AdminRole,
createWorkspace1Membership1,
createWorkspace2,
createOtherProject
])
delete createUser1.defaultWorkspace
delete createUser2.defaultWorkspace

user1 = result[0]
user2 = result[1]
user1 = createUser1
user2 = createUser2

workspace1 = result[2]
project1 = (await projectService.createProject(user1, workspace1.id, {
name: 'Project 1',
description: 'Project 1 description',
storePrivateKey: true
})) as Project

project2 = (await projectService.createProject(user2, workspace2.id, {
name: 'Project 2',
description: 'Project 2 description',
storePrivateKey: false
})) as Project
})

otherProject = result[6]
afterEach(async () => {
await prisma.user.deleteMany()
await prisma.workspace.deleteMany()
})

it('should be defined', async () => {
expect(app).toBeDefined()
expect(prisma).toBeDefined()
expect(eventService).toBeDefined()
expect(projectService).toBeDefined()
expect(workspaceService).toBeDefined()
expect(userService).toBeDefined()
})

it('should allow workspace member to create a project', async () => {
const response = await app.inject({
method: 'POST',
url: `/project/${workspace1.id}`,
payload: {
name: 'Project 1',
description: 'Project 1 description',
name: 'Project 3',
description: 'Project 3 description',
storePrivateKey: true
},
headers: {
Expand All @@ -170,8 +138,8 @@ describe('Project Controller Tests', () => {
expect(response.statusCode).toBe(201)
expect(response.json()).toEqual({
id: expect.any(String),
name: 'Project 1',
description: 'Project 1 description',
name: 'Project 3',
description: 'Project 3 description',
storePrivateKey: true,
workspaceId: workspace1.id,
lastUpdatedById: user1.id,
Expand All @@ -183,8 +151,6 @@ describe('Project Controller Tests', () => {
updatedAt: expect.any(String),
pendingCreation: false
})

project1 = response.json()
})

it('should have created a default environment', async () => {
Expand Down Expand Up @@ -340,8 +306,7 @@ describe('Project Controller Tests', () => {
method: 'PUT',
url: `/project/${project1.id}`,
payload: {
name: 'Project 1 Updated',
description: 'Project 1 description updated'
name: 'Project 1'
},
headers: {
'x-e2e-user-email': user1.email
Expand All @@ -352,7 +317,7 @@ describe('Project Controller Tests', () => {
expect(response.json()).toEqual({
statusCode: 409,
error: 'Conflict',
message: `Project with this name **Project 1 Updated** already exists`
message: `Project with this name **Project 1** already exists`
})
})

Expand Down Expand Up @@ -399,6 +364,11 @@ describe('Project Controller Tests', () => {
})

it('should have created a PROJECT_UPDATED event', async () => {
await projectService.updateProject(user1, project1.id, {
name: 'Project 1 Updated',
description: 'Project 1 description'
})

const response = await fetchEvents(
eventService,
user1,
Expand Down Expand Up @@ -431,7 +401,6 @@ describe('Project Controller Tests', () => {
lastUpdatedById: user1.id,
createdAt: expect.any(String),
updatedAt: expect.any(String),
privateKey: null,
secrets: []
})
})
Expand Down Expand Up @@ -486,7 +455,8 @@ describe('Project Controller Tests', () => {
lastUpdatedById: user1.id,
createdAt: expect.any(String),
updatedAt: expect.any(String),
publicKey: undefined
publicKey: undefined,
privateKey: undefined
}
])
})
Expand Down Expand Up @@ -626,7 +596,7 @@ describe('Project Controller Tests', () => {
regenerateKeyPair: true
},
headers: {
'x-e2e-user-email': user1.email
'x-e2e-user-email': user2.email
}
})

Expand All @@ -648,6 +618,8 @@ describe('Project Controller Tests', () => {
})

it('should have created a PROJECT_DELETED event', async () => {
await projectService.deleteProject(user1, project1.id)

const response = await fetchEvents(
eventService,
user1,
Expand All @@ -666,6 +638,8 @@ describe('Project Controller Tests', () => {
})

it('should have removed all environments of the project', async () => {
await projectService.deleteProject(user1, project1.id)

const environments = await prisma.environment.findMany({
where: {
projectId: project1.id
Expand All @@ -676,6 +650,8 @@ describe('Project Controller Tests', () => {
})

it('should have removed the project from the admin role of the workspace', async () => {
await projectService.deleteProject(user1, project1.id)

const adminRole = await prisma.workspaceRole.findUnique({
where: {
workspaceId_name: {
Expand All @@ -689,7 +665,7 @@ describe('Project Controller Tests', () => {
})

expect(adminRole).toBeDefined()
expect(adminRole.projects).toHaveLength(2)
expect(adminRole.projects).toHaveLength(0)
})

it('should not be able to delete a non existing project', async () => {
Expand All @@ -712,7 +688,7 @@ describe('Project Controller Tests', () => {
it('should not be able to delete a project if the user is not a member of the workspace', async () => {
const response = await app.inject({
method: 'DELETE',
url: `/project/${otherProject.id}`,
url: `/project/${project2.id}`,
headers: {
'x-e2e-user-email': user1.email
}
Expand All @@ -722,7 +698,7 @@ describe('Project Controller Tests', () => {
expect(response.json()).toEqual({
statusCode: 401,
error: 'Unauthorized',
message: `User with id ${user1.id} does not have the authority in the project with id ${otherProject.id}`
message: `User with id ${user1.id} does not have the authority in the project with id ${project2.id}`
})
})

Expand Down
2 changes: 1 addition & 1 deletion apps/api/src/project/service/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ export class ProjectService {
}
}

async getProjectByUserAndId(user: User, projectId: Project['id']) {
async getProjectById(user: User, projectId: Project['id']) {
const project =
await this.authorityCheckerService.checkAuthorityOverProject({
userId: user.id,
Expand Down
Loading

0 comments on commit 4f8c178

Please sign in to comment.