diff --git a/apps/api/src/project/project.e2e.spec.ts b/apps/api/src/project/project.e2e.spec.ts index 8aa49e30..68e96acb 100644 --- a/apps/api/src/project/project.e2e.spec.ts +++ b/apps/api/src/project/project.e2e.spec.ts @@ -57,7 +57,7 @@ describe('Project Controller Tests', () => { let user1: User, user2: User let workspace1: Workspace, workspace2: Workspace - let project1: Project, project2: Project, project3: Project + let project1: Project, project2: Project, project3: Project, project4: Project beforeAll(async () => { const moduleRef = await Test.createTestingModule({ @@ -142,6 +142,13 @@ describe('Project Controller Tests', () => { storePrivateKey: true, accessLevel: ProjectAccessLevel.GLOBAL })) as Project + + project4 = (await projectService.createProject(user2, workspace2.slug, { + name: 'Project4', + description: + 'Project for testing if all environments,secrets and keys are being fetched or not', + storePrivateKey: true + })) as Project }) afterEach(async () => { @@ -519,6 +526,89 @@ describe('Project Controller Tests', () => { expect(response.statusCode).toBe(401) }) + + it('should be able fetch all environments,variables,secrets of all projects of a workspace', async () => { + // Add an environment to the project + const environment = (await environmentService.createEnvironment( + user2, + { + name: 'Dev' + }, + project4.slug + )) as Environment + + // Add two secrets + ;(await secretService.createSecret( + user2, + { + name: 'API_KEY', + entries: [ + { + value: 'some_key', + environmentSlug: environment.slug + } + ] + }, + project4.slug + )) as Secret + ;(await secretService.createSecret( + user2, + { + name: 'DB_PASSWORD', + entries: [ + { + value: 'password', + environmentSlug: environment.slug + } + ] + }, + project4.slug + )) as Secret + + // Add two variables + ;(await variableService.createVariable( + user2, + { + name: 'PORT', + entries: [ + { + value: '8080', + environmentSlug: environment.slug + } + ] + }, + project4.slug + )) as Variable + ;(await variableService.createVariable( + user2, + { + name: 'EXPIRY', + entries: [ + { + value: '3600', + environmentSlug: environment.slug + } + ] + }, + project4.slug + )) as Variable + + const response = await app.inject({ + method: 'GET', + url: `/project/all/${workspace2.slug}?page=0&limit=10&search=Project4`, + headers: { + 'x-e2e-user-email': user2.email + } + }) + + expect(response.statusCode).toBe(200) + expect(response.json().items.length).toEqual(1) + //One environment is added by default + expect(response.json().items[0].totalEnvironmentsOfProject).toEqual(2) + + expect(response.json().items[0].totalVariablesOfProject).toEqual(2) + expect(response.json().items[0].totalSecretsOfProject).toEqual(2) + }) }) it('should create environments if provided', async () => { diff --git a/apps/api/src/project/service/project.service.ts b/apps/api/src/project/service/project.service.ts index 421d2832..f017c7db 100644 --- a/apps/api/src/project/service/project.service.ts +++ b/apps/api/src/project/service/project.service.ts @@ -777,7 +777,7 @@ export class ProjectService { const workspaceId = workspace.id //fetch projects with required properties - const items = ( + const projects = ( await this.prisma.project.findMany({ skip: page * limit, take: limitMaxItemsPerPage(limit), @@ -809,6 +809,59 @@ export class ProjectService { }) ).map((project) => excludeFields(project, 'privateKey', 'publicKey')) + const items = await Promise.all( + projects.map(async (project) => { + let totalEnvironmentsOfProject = 0 + let totalVariablesOfProject = 0 + let totalSecretsOfProject = 0 + + const allEnvs = await this.prisma.environment.findMany({ + where: { projectId: project.id } + }) + + const envPromises = allEnvs.map(async (env) => { + const hasRequiredPermission = + await this.authorityCheckerService.checkAuthorityOverEnvironment({ + userId: user.id, + entity: { slug: env.slug }, + authorities: [Authority.READ_ENVIRONMENT], + prisma: this.prisma + }) + + if (hasRequiredPermission) { + totalEnvironmentsOfProject += 1 + + const [secretCount, variableCount] = await Promise.all([ + this.prisma.secret.count({ + where: { + projectId: project.id, + versions: { some: { environmentId: env.id } } + } + }), + this.prisma.variable.count({ + where: { + projectId: project.id, + versions: { some: { environmentId: env.id } } + } + }) + ]) + + totalSecretsOfProject += secretCount + totalVariablesOfProject += variableCount + } + }) + + await Promise.all(envPromises) + + return { + ...project, + totalEnvironmentsOfProject, + totalVariablesOfProject, + totalSecretsOfProject + } + }) + ) + //calculate metadata const totalCount = await this.prisma.project.count({ where: {