Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,28 @@ describe('deploymentDatastoreService', () => {
service = module.get(DeploymentDatastoreService)
})

const deploymentRelations = {
environment: true,
deploymentSources: {
include: {
repository: true,
internalValueSources: { orderBy: { order: 'asc' } },
externalValueSource: true,
},
},
}

describe('getDeploymentById', () => {
it('should return a deployment with sources and repository', async () => {
it('should return a deployment with sources and value sources', async () => {
const deployment = { ...mockDeployment }

prisma.deployment.findUnique.mockResolvedValue(deployment)
prisma.deployment.findUniqueOrThrow.mockResolvedValue(deployment)

const result = await service.getDeploymentById('dep1')

expect(prisma.deployment.findUnique).toHaveBeenCalledWith({
expect(prisma.deployment.findUniqueOrThrow).toHaveBeenCalledWith({
where: { id: 'dep1' },
include: {
environment: true,
deploymentSources: {
include: { repository: true },
},
},
include: deploymentRelations,
})
expect(result).toEqual(deployment)
})
Expand All @@ -68,12 +74,7 @@ describe('deploymentDatastoreService', () => {

expect(prisma.deployment.findMany).toHaveBeenCalledWith({
where: { projectId: 'project1' },
include: {
environment: true,
deploymentSources: {
include: { repository: true },
},
},
include: deploymentRelations,
orderBy: { createdAt: 'asc' },
})
expect(result).toEqual(deployments)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,68 @@
import type { Prisma } from '@prisma/client'
import type { Deployment, Prisma } from '@prisma/client'
import { Inject, Injectable } from '@nestjs/common'
import { PrismaService } from '../infrastructure/database/prisma.service'

export type DeploymentWithRelations = Prisma.DeploymentGetPayload<{
include: {
environment: true
deploymentSources: {
include: {
repository: true
internalValueSources: true
externalValueSource: true
}
}
}
}>

const deploymentRelations = {
environment: true,
deploymentSources: {
include: {
repository: true,
internalValueSources: { orderBy: { order: 'asc' } },
externalValueSource: true,
},
},
} satisfies Prisma.DeploymentInclude

@Injectable()
export class DeploymentDatastoreService {
constructor(@Inject(PrismaService) private readonly prisma: PrismaService) {}

getDeploymentById(deploymentId: string) {
return this.prisma.deployment.findUnique({
getDeploymentById(deploymentId: string): Promise<DeploymentWithRelations> {
return this.prisma.deployment.findUniqueOrThrow({
where: { id: deploymentId },
include: {
environment: true,
deploymentSources: {
include: { repository: true },
},
},
include: deploymentRelations,
})
}

getDeploymentsByProjectId(projectId: string) {
getDeploymentsByProjectId(projectId: string): Promise<DeploymentWithRelations[]> {
return this.prisma.deployment.findMany({
where: { projectId },
include: {
environment: true,
deploymentSources: {
include: { repository: true },
},
},
include: deploymentRelations,
orderBy: { createdAt: 'asc' },
})
}

createDeployment(data: Prisma.DeploymentCreateInput) {
createDeployment(data: Prisma.DeploymentCreateInput): Promise<Deployment> {
return this.prisma.deployment.create({ data })
}

updateDeployment(deploymentId: string, data: Prisma.DeploymentUpdateInput) {
updateDeployment(deploymentId: string, data: Prisma.DeploymentUpdateInput): Promise<Deployment> {
return this.prisma.deployment.update({
where: { id: deploymentId },
data,
})
}

deleteDeployment(deploymentId: string) {
deleteDeployment(deploymentId: string): Promise<Deployment> {
return this.prisma.deployment.delete({
where: { id: deploymentId },
})
}

deleteAllDeploymentsByProjectId(projectId: string) {
deleteAllDeploymentsByProjectId(projectId: string): Promise<Prisma.BatchPayload> {
return this.prisma.deployment.deleteMany({
where: { projectId },
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import type { Deployment, DeploymentSource, Environment, Prisma, Repository } from '@prisma/client'
import type {
Deployment,
DeploymentExternalValueSource,
DeploymentInternalValueSource,
DeploymentSource,
Environment,
Prisma,
Repository,
} from '@prisma/client'
import { faker } from '@faker-js/faker'

export function makeDeployment(overrides: Partial<Deployment> = {}): Deployment {
Expand Down Expand Up @@ -49,7 +57,38 @@ export function makeRepository(overrides: Partial<Repository> = {}): Repository
}
}

type DeploymentSourceWithRepository = DeploymentSource & { repository: Repository }
type DeploymentSourceWithRepository = DeploymentSource & {
repository: Repository
internalValueSources: DeploymentInternalValueSource[]
externalValueSource: DeploymentExternalValueSource | null
}

export function makeDeploymentInternalValueSource(overrides: Partial<DeploymentInternalValueSource> = {}): DeploymentInternalValueSource {
return {
id: faker.string.uuid(),
createdAt: faker.date.past(),
updatedAt: faker.date.past(),
deploymentSourceId: faker.string.uuid(),
order: 0,
path: 'values.yaml',
...overrides,
}
}

export function makeDeploymentExternalValueSource(overrides: Partial<DeploymentExternalValueSource> = {}): DeploymentExternalValueSource {
return {
id: faker.string.uuid(),
createdAt: faker.date.past(),
updatedAt: faker.date.past(),
deploymentSourceId: faker.string.uuid(),
order: 0,
path: 'values.yaml',
ref: 'main',
targetRevision: '',
repositoryId: faker.string.uuid(),
...overrides,
}
}

export function makeDeploymentSource(overrides: Partial<DeploymentSourceWithRepository> = {}): DeploymentSourceWithRepository {
const repositoryId = overrides.repositoryId ?? faker.string.uuid()
Expand All @@ -64,14 +103,22 @@ export function makeDeploymentSource(overrides: Partial<DeploymentSourceWithRepo
path: '/app',
helmValuesFiles: '',
repository: makeRepository({ id: repositoryId }),
internalValueSources: [],
externalValueSource: null,
...overrides,
}
}

export type DeploymentWithRelations = Prisma.DeploymentGetPayload<{
include: {
environment: true
deploymentSources: { include: { repository: true } }
deploymentSources: {
include: {
repository: true
internalValueSources: true
externalValueSource: true
}
}
}
}>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ProjectGuard } from '../infrastructure/permission/project/project.guard
import { makeDeployment, makeDeploymentWithRelations } from './deployment-testing.utils'
import { DeploymentController } from './deployment.controller'
import { DeploymentService } from './deployment.service'
import { serializeDeployment } from './deployment.utils'

describe('deploymentController', () => {
let module: TestingModule
Expand All @@ -36,6 +37,7 @@ describe('deploymentController', () => {
type: 'git',
targetRevision: 'main',
path: '/app',
valueSources: [],
},
],
} satisfies CreateDeployment
Expand All @@ -49,6 +51,7 @@ describe('deploymentController', () => {
type: 'git',
targetRevision: 'develop',
path: '/updated-app',
valueSources: [],
},
],
} satisfies UpdateDeployment
Expand All @@ -75,7 +78,7 @@ describe('deploymentController', () => {

describe('list', () => {
it('should call deploymentService.listByProjectId with projectId', async () => {
const expectedResult = [makeDeploymentWithRelations({ projectId })]
const expectedResult = [makeDeploymentWithRelations({ projectId })].map(serializeDeployment)

service.listByProjectId.mockResolvedValue(expectedResult)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { CreateDeployment, UpdateDeployment } from '@cpn-console/shared'
import type { Deployment } from '@prisma/client'
import type { FastifyRequest } from 'fastify'
import type { UserContext } from '../infrastructure/auth/auth-user.decorator'
import type { ProjectContext } from '../infrastructure/permission/project/project.guard'
import type { SerializedDeployment } from './deployment.utils'
import { CreateDeploymentSchema, UpdateDeploymentSchema } from '@cpn-console/shared'
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Inject, Param, Post, Put, Req, UseGuards } from '@nestjs/common'
import { AuthUser } from '../infrastructure/auth/auth-user.decorator'
Expand All @@ -20,7 +22,7 @@ export class DeploymentController {
@Get('')
@RequireAdminPermission('ListProjects')
@RequireProjectPermission('ListDeployments')
list(@Project() project: ProjectContext) {
list(@Project() project: ProjectContext): Promise<SerializedDeployment[]> {
return this.deploymentService.listByProjectId(project.id)
}

Expand All @@ -32,7 +34,7 @@ export class DeploymentController {
@Project() project: ProjectContext,
@AuthUser() user: UserContext,
@Req() request: FastifyRequest,
) {
): Promise<Deployment> {
return this.deploymentService.createDeployment(project.id, data, user.userId, request.id)
}

Expand All @@ -45,7 +47,7 @@ export class DeploymentController {
@Project() project: ProjectContext,
@AuthUser() user: UserContext,
@Req() request: FastifyRequest,
) {
): Promise<Deployment> {
return this.deploymentService.updateDeployment(project.id, deploymentId, data, user.userId, request.id)
}

Expand All @@ -57,7 +59,7 @@ export class DeploymentController {
@Project() project: ProjectContext,
@AuthUser() user: UserContext,
@Req() request: FastifyRequest,
) {
): Promise<void> {
return this.deploymentService.deleteDeployment(project.id, deploymentId, user.userId, request.id)
}
}
Loading