From c65ac7a60c86a1260cb7d9594510cdfe36804419 Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Fri, 13 Nov 2020 15:23:31 +0200 Subject: [PATCH 01/12] Add build upsert by ID https://github.com/Visual-Regression-Tracker/Visual-Regression-Tracker/issues/142 --- src/builds/builds.service.spec.ts | 26 ++++++++++++++++++-------- src/builds/builds.service.ts | 10 +++++++--- src/builds/dto/build-create.dto.ts | 7 ++++++- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/builds/builds.service.spec.ts b/src/builds/builds.service.spec.ts index d4b53a66..916296e1 100644 --- a/src/builds/builds.service.spec.ts +++ b/src/builds/builds.service.spec.ts @@ -17,6 +17,7 @@ const initService = async ({ buildUpdateMock = jest.fn(), buildFindOneMock = jest.fn(), buildDeleteMock = jest.fn(), + buildUpsertMock = jest.fn(), testRunDeleteMock = jest.fn(), eventsBuildCreatedMock = jest.fn(), eventsBuildFinishedMock = jest.fn(), @@ -39,6 +40,7 @@ const initService = async ({ update: buildUpdateMock, findOne: buildFindOneMock, delete: buildDeleteMock, + upsert: buildUpsertMock, }, }, }, @@ -150,12 +152,12 @@ describe('BuildsService', () => { updatedAt: new Date(), createdAt: new Date(), }; - const buildCreateMock = jest.fn().mockResolvedValueOnce(build); + const buildUpsertMock = jest.fn().mockResolvedValueOnce(build); const projectFindOneMock = jest.fn().mockResolvedValueOnce(project); const projectUpdateMock = jest.fn().mockResolvedValueOnce(project); const eventsBuildCreatedMock = jest.fn(); mocked(BuildDto).mockReturnValueOnce(buildDto); - service = await initService({ buildCreateMock, eventsBuildCreatedMock, projectFindOneMock, projectUpdateMock }); + service = await initService({ buildUpsertMock, eventsBuildCreatedMock, projectFindOneMock, projectUpdateMock }); const result = await service.create(createBuildDto); @@ -170,8 +172,8 @@ describe('BuildsService', () => { }, }, }); - expect(buildCreateMock).toHaveBeenCalledWith({ - data: { + expect(buildUpsertMock).toHaveBeenCalledWith({ + create: { branchName: createBuildDto.branchName, isRunning: true, number: project.buildsCounter, @@ -181,6 +183,10 @@ describe('BuildsService', () => { }, }, }, + update: {}, + where: { + id: '', + }, }); expect(eventsBuildCreatedMock).toHaveBeenCalledWith(buildDto); expect(result).toBe(buildDto); @@ -200,12 +206,12 @@ describe('BuildsService', () => { updatedAt: new Date(), createdAt: new Date(), }; - const buildCreateMock = jest.fn().mockResolvedValueOnce(build); + const buildUpsertMock = jest.fn().mockResolvedValueOnce(build); const projectFindOneMock = jest.fn().mockResolvedValueOnce(project); const projectUpdateMock = jest.fn().mockResolvedValueOnce(project); const eventsBuildCreatedMock = jest.fn(); mocked(BuildDto).mockReturnValueOnce(buildDto); - service = await initService({ buildCreateMock, eventsBuildCreatedMock, projectFindOneMock, projectUpdateMock }); + service = await initService({ buildUpsertMock, eventsBuildCreatedMock, projectFindOneMock, projectUpdateMock }); const result = await service.create(createBuildDto); @@ -220,8 +226,8 @@ describe('BuildsService', () => { }, }, }); - expect(buildCreateMock).toHaveBeenCalledWith({ - data: { + expect(buildUpsertMock).toHaveBeenCalledWith({ + create: { branchName: createBuildDto.branchName, isRunning: true, number: project.buildsCounter, @@ -231,6 +237,10 @@ describe('BuildsService', () => { }, }, }, + update: {}, + where: { + id: '', + }, }); expect(eventsBuildCreatedMock).toHaveBeenCalledWith(buildDto); expect(result).toBe(buildDto); diff --git a/src/builds/builds.service.ts b/src/builds/builds.service.ts index 28eb367d..a4b3d674 100644 --- a/src/builds/builds.service.ts +++ b/src/builds/builds.service.ts @@ -52,9 +52,9 @@ export class BuildsService { }, }); - // create build - const build = await this.prismaService.build.create({ - data: { + // get or create build + const build = await this.prismaService.build.upsert({ + create: { branchName: createBuildDto.branchName, isRunning: true, number: project.buildsCounter, @@ -64,6 +64,10 @@ export class BuildsService { }, }, }, + update: {}, + where: { + id: createBuildDto.id || '', + }, }); const buildDto = new BuildDto(build); this.eventsGateway.buildCreated(buildDto); diff --git a/src/builds/dto/build-create.dto.ts b/src/builds/dto/build-create.dto.ts index ae4e22c8..21a207ba 100644 --- a/src/builds/dto/build-create.dto.ts +++ b/src/builds/dto/build-create.dto.ts @@ -1,7 +1,12 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsUUID, IsOptional } from 'class-validator'; +import { IsString, IsUUID, IsOptional, isUUID } from 'class-validator'; export class CreateBuildDto { + @ApiProperty() + @IsOptional() + @IsUUID() + readonly id?: string; + @ApiProperty() @IsString() readonly branchName: string; From a518bb0a9cc0b76ec24cbcab6bedb5bb345d0b1e Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Fri, 13 Nov 2020 16:12:49 +0200 Subject: [PATCH 02/12] find project moved into project service --- src/builds/builds.service.spec.ts | 82 +++------------------------ src/builds/builds.service.ts | 23 +++----- src/projects/projects.service.spec.ts | 54 +++++++++++++----- src/projects/projects.service.ts | 22 ++++++- 4 files changed, 77 insertions(+), 104 deletions(-) diff --git a/src/builds/builds.service.spec.ts b/src/builds/builds.service.spec.ts index 916296e1..a87c1627 100644 --- a/src/builds/builds.service.spec.ts +++ b/src/builds/builds.service.spec.ts @@ -7,7 +7,7 @@ import { CreateBuildDto } from './dto/build-create.dto'; import { Build, TestRun, Project } from '@prisma/client'; import { mocked } from 'ts-jest/utils'; import { BuildDto } from './dto/build.dto'; -import { HttpException, HttpStatus } from '@nestjs/common'; +import { ProjectsService } from '../projects/projects.service'; jest.mock('./dto/build.dto'); @@ -31,7 +31,6 @@ const initService = async ({ provide: PrismaService, useValue: { project: { - findOne: projectFindOneMock, update: projectUpdateMock, }, build: { @@ -57,6 +56,12 @@ const initService = async ({ buildFinished: eventsBuildFinishedMock, }, }, + { + provide: ProjectsService, + useValue: { + findOne: projectFindOneMock, + }, + }, ], }).compile(); @@ -138,7 +143,7 @@ describe('BuildsService', () => { }); describe('create', () => { - it('should create by name', async () => { + it('should create', async () => { const createBuildDto: CreateBuildDto = { branchName: 'branchName', project: 'name', @@ -161,63 +166,7 @@ describe('BuildsService', () => { const result = await service.create(createBuildDto); - expect(projectFindOneMock).toHaveBeenCalledWith({ - where: { id: undefined, name: createBuildDto.project }, - }); - expect(projectUpdateMock).toHaveBeenCalledWith({ - where: { id: project.id }, - data: { - buildsCounter: { - increment: 1, - }, - }, - }); - expect(buildUpsertMock).toHaveBeenCalledWith({ - create: { - branchName: createBuildDto.branchName, - isRunning: true, - number: project.buildsCounter, - project: { - connect: { - id: project.id, - }, - }, - }, - update: {}, - where: { - id: '', - }, - }); - expect(eventsBuildCreatedMock).toHaveBeenCalledWith(buildDto); - expect(result).toBe(buildDto); - }); - - it('should create by UUID', async () => { - const createBuildDto: CreateBuildDto = { - branchName: 'branchName', - project: '6bdd3704-90af-4b1b-94cb-f183e500f5cb', - }; - - const project: Project = { - id: '6bdd3704-90af-4b1b-94cb-f183e500f5cb', - name: 'name', - buildsCounter: 1, - mainBranchName: 'master', - updatedAt: new Date(), - createdAt: new Date(), - }; - const buildUpsertMock = jest.fn().mockResolvedValueOnce(build); - const projectFindOneMock = jest.fn().mockResolvedValueOnce(project); - const projectUpdateMock = jest.fn().mockResolvedValueOnce(project); - const eventsBuildCreatedMock = jest.fn(); - mocked(BuildDto).mockReturnValueOnce(buildDto); - service = await initService({ buildUpsertMock, eventsBuildCreatedMock, projectFindOneMock, projectUpdateMock }); - - const result = await service.create(createBuildDto); - - expect(projectFindOneMock).toHaveBeenCalledWith({ - where: { id: createBuildDto.project, name: undefined }, - }); + expect(projectFindOneMock).toHaveBeenCalledWith(createBuildDto.project); expect(projectUpdateMock).toHaveBeenCalledWith({ where: { id: project.id }, data: { @@ -245,19 +194,6 @@ describe('BuildsService', () => { expect(eventsBuildCreatedMock).toHaveBeenCalledWith(buildDto); expect(result).toBe(buildDto); }); - - it('should throw exception if not found', async () => { - const createBuildDto: CreateBuildDto = { - branchName: 'branchName', - project: 'nonexisting', - }; - const projectFindOneMock = jest.fn().mockResolvedValueOnce(undefined); - service = await initService({ projectFindOneMock }); - - await expect(service.create(createBuildDto)).rejects.toThrowError( - new HttpException('Project not found', HttpStatus.NOT_FOUND) - ); - }); }); it('delete', async () => { diff --git a/src/builds/builds.service.ts b/src/builds/builds.service.ts index a4b3d674..0680b72c 100644 --- a/src/builds/builds.service.ts +++ b/src/builds/builds.service.ts @@ -1,18 +1,19 @@ -import { Injectable, HttpException, HttpStatus } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { CreateBuildDto } from './dto/build-create.dto'; import { PrismaService } from '../prisma/prisma.service'; -import { Build, Project } from '@prisma/client'; +import { Build } from '@prisma/client'; import { TestRunsService } from '../test-runs/test-runs.service'; import { EventsGateway } from '../shared/events/events.gateway'; import { BuildDto } from './dto/build.dto'; -import uuidAPIKey from 'uuid-apikey'; +import { ProjectsService } from '../projects/projects.service'; @Injectable() export class BuildsService { constructor( private prismaService: PrismaService, private testRunsService: TestRunsService, - private eventsGateway: EventsGateway + private eventsGateway: EventsGateway, + private projectService: ProjectsService ) {} async findMany(projectId: string): Promise { @@ -29,16 +30,7 @@ export class BuildsService { async create(createBuildDto: CreateBuildDto): Promise { // find project - const isUUID = uuidAPIKey.isUUID(createBuildDto.project); - let project: Project = await this.prismaService.project.findOne({ - where: { - id: isUUID ? createBuildDto.project : undefined, - name: !isUUID ? createBuildDto.project : undefined, - }, - }); - if (!project) { - throw new HttpException(`Project not found`, HttpStatus.NOT_FOUND); - } + let project = await this.projectService.findOne(createBuildDto.project); // increment build number project = await this.prismaService.project.update({ @@ -53,6 +45,7 @@ export class BuildsService { }); // get or create build + const buildId = createBuildDto.id || ''; const build = await this.prismaService.build.upsert({ create: { branchName: createBuildDto.branchName, @@ -66,7 +59,7 @@ export class BuildsService { }, update: {}, where: { - id: createBuildDto.id || '', + id: buildId, }, }); const buildDto = new BuildDto(build); diff --git a/src/projects/projects.service.spec.ts b/src/projects/projects.service.spec.ts index 58a847a8..281c5f93 100644 --- a/src/projects/projects.service.spec.ts +++ b/src/projects/projects.service.spec.ts @@ -3,24 +3,52 @@ import { ProjectsService } from './projects.service'; import { PrismaService } from '../prisma/prisma.service'; import { TestVariationsService } from '../test-variations/test-variations.service'; import { BuildsService } from '../builds/builds.service'; +import { HttpException, HttpStatus } from '@nestjs/common'; +const initService = async ({ projectFindOneMock = jest.fn() }) => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + ProjectsService, + { + provide: PrismaService, + useValue: { + project: { + findOne: projectFindOneMock, + }, + }, + }, + { provide: TestVariationsService, useValue: {} }, + { provide: BuildsService, useValue: {} }, + ], + }).compile(); + + return module.get(ProjectsService); +}; describe('ProjectsService', () => { let service: ProjectsService; - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ - ProjectsService, - { provide: PrismaService, useValue: {} }, - { provide: TestVariationsService, useValue: {} }, - { provide: BuildsService, useValue: {} }, - ], - }).compile(); + describe('findOne', () => { + it.each([ + ['name', 'someName', { id: undefined, name: 'someName' }], + ['id', 'a9385fc1-884d-4f9f-915e-40da0e7773d5', { id: 'a9385fc1-884d-4f9f-915e-40da0e7773d5', name: undefined }], + ])('should find by %s', async (_, query, expected) => { + const projectFindOneMock = jest.fn().mockResolvedValue({}); + service = await initService({ projectFindOneMock }); - service = module.get(ProjectsService); - }); + await service.findOne(query); + + expect(projectFindOneMock).toHaveBeenCalledWith({ + where: expected, + }); + }); + + it('should throw exception if not found', async () => { + const projectFindOneMock = jest.fn().mockResolvedValueOnce(undefined); + service = await initService({ projectFindOneMock }); - it('should be defined', () => { - expect(service).toBeDefined(); + await expect(service.findOne('foo')).rejects.toThrowError( + new HttpException('Project not found', HttpStatus.NOT_FOUND) + ); + }); }); }); diff --git a/src/projects/projects.service.ts b/src/projects/projects.service.ts index c87fee54..225744d2 100644 --- a/src/projects/projects.service.ts +++ b/src/projects/projects.service.ts @@ -1,10 +1,11 @@ -import { Injectable } from '@nestjs/common'; +import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; import { CreateProjectDto } from './dto/create-project.dto'; import { BuildsService } from '../builds/builds.service'; import { TestVariationsService } from '../test-variations/test-variations.service'; import { PrismaService } from '../prisma/prisma.service'; import { Project } from '@prisma/client'; import { ProjectDto } from './dto/project.dto'; +import uuidAPIKey from 'uuid-apikey'; @Injectable() export class ProjectsService { @@ -14,6 +15,21 @@ export class ProjectsService { private testVariationsService: TestVariationsService ) {} + async findOne(idOrName: string): Promise { + const isUUID = uuidAPIKey.isUUID(idOrName); + const project: Project = await this.prismaService.project.findOne({ + where: { + id: isUUID ? idOrName : undefined, + name: !isUUID ? idOrName : undefined, + }, + }); + + if (!project) { + throw new HttpException(`Project not found`, HttpStatus.NOT_FOUND); + } + return project; + } + async findAll(): Promise { return this.prismaService.project.findMany(); } @@ -47,9 +63,9 @@ export class ProjectsService { }); try { - await Promise.all(project.builds.map(build => this.buildsService.remove(build.id))); + await Promise.all(project.builds.map((build) => this.buildsService.remove(build.id))); await Promise.all( - project.testVariations.map(testVariation => this.testVariationsService.delete(testVariation.id)) + project.testVariations.map((testVariation) => this.testVariationsService.delete(testVariation.id)) ); } catch (err) { console.log(err); From 1114fa355332b480693eae227bb361f8a32f0eaf Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Sun, 15 Nov 2020 17:01:18 +0200 Subject: [PATCH 03/12] log error added --- src/http-exception.filter.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/http-exception.filter.ts b/src/http-exception.filter.ts index db7ec4d6..b04f5a1a 100644 --- a/src/http-exception.filter.ts +++ b/src/http-exception.filter.ts @@ -1,4 +1,4 @@ -import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus } from '@nestjs/common'; +import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus, Logger } from '@nestjs/common'; import { Request, Response } from 'express'; @Catch() @@ -14,6 +14,9 @@ export class HttpExceptionFilter implements ExceptionFilter { } catch { status = HttpStatus.INTERNAL_SERVER_ERROR; } + + Logger.error(exception, exception.stack); + response.status(status).json({ path: request.url, name: exception.name, From ee887b6bf9f55bdd5a48f99a261043a51b6145c9 Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Sun, 15 Nov 2020 17:49:30 +0200 Subject: [PATCH 04/12] circular dependency fixed --- src/builds/builds.module.ts | 5 +++-- src/builds/builds.service.ts | 6 ++++-- src/projects/projects.module.ts | 7 ++++--- src/projects/projects.service.ts | 4 +++- src/test-runs/test-runs.module.ts | 6 +++--- src/test-runs/test-runs.service.ts | 3 ++- src/test-variations/test-variations.module.ts | 10 ++++++---- src/test-variations/test-variations.service.ts | 18 +++++++++--------- 8 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/builds/builds.module.ts b/src/builds/builds.module.ts index 0a1cb790..cce932ba 100644 --- a/src/builds/builds.module.ts +++ b/src/builds/builds.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { forwardRef, Module } from '@nestjs/common'; import { BuildsService } from './builds.service'; import { BuildsController } from './builds.controller'; import { UsersModule } from '../users/users.module'; @@ -6,9 +6,10 @@ import { PrismaService } from '../prisma/prisma.service'; import { TestRunsModule } from '../test-runs/test-runs.module'; import { SharedModule } from '../shared/shared.module'; import { AuthModule } from '../auth/auth.module'; +import { ProjectsModule } from '../projects/projects.module'; @Module({ - imports: [SharedModule, UsersModule, TestRunsModule, AuthModule], + imports: [SharedModule, UsersModule, forwardRef(() => TestRunsModule), AuthModule, forwardRef(() => ProjectsModule)], providers: [BuildsService, PrismaService], controllers: [BuildsController], exports: [BuildsService], diff --git a/src/builds/builds.service.ts b/src/builds/builds.service.ts index 0680b72c..bf553550 100644 --- a/src/builds/builds.service.ts +++ b/src/builds/builds.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { forwardRef, Inject, Injectable } from '@nestjs/common'; import { CreateBuildDto } from './dto/build-create.dto'; import { PrismaService } from '../prisma/prisma.service'; import { Build } from '@prisma/client'; @@ -11,8 +11,10 @@ import { ProjectsService } from '../projects/projects.service'; export class BuildsService { constructor( private prismaService: PrismaService, - private testRunsService: TestRunsService, private eventsGateway: EventsGateway, + @Inject(forwardRef(() => TestRunsService)) + private testRunsService: TestRunsService, + @Inject(forwardRef(() => ProjectsService)) private projectService: ProjectsService ) {} diff --git a/src/projects/projects.module.ts b/src/projects/projects.module.ts index c47fe15e..1c97bb0d 100644 --- a/src/projects/projects.module.ts +++ b/src/projects/projects.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { forwardRef, Module } from '@nestjs/common'; import { ProjectsService } from './projects.service'; import { ProjectsController } from './projects.controller'; import { BuildsModule } from '../builds/builds.module'; @@ -6,8 +6,9 @@ import { TestVariationsModule } from '../test-variations/test-variations.module' import { PrismaService } from '../prisma/prisma.service'; @Module({ - imports: [BuildsModule, TestVariationsModule], + imports: [forwardRef(() => BuildsModule), forwardRef(() => TestVariationsModule)], providers: [ProjectsService, PrismaService], - controllers: [ProjectsController] + controllers: [ProjectsController], + exports: [ProjectsService], }) export class ProjectsModule {} diff --git a/src/projects/projects.service.ts b/src/projects/projects.service.ts index 225744d2..c05f7797 100644 --- a/src/projects/projects.service.ts +++ b/src/projects/projects.service.ts @@ -1,4 +1,4 @@ -import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; +import { forwardRef, HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; import { CreateProjectDto } from './dto/create-project.dto'; import { BuildsService } from '../builds/builds.service'; import { TestVariationsService } from '../test-variations/test-variations.service'; @@ -11,7 +11,9 @@ import uuidAPIKey from 'uuid-apikey'; export class ProjectsService { constructor( private prismaService: PrismaService, + @Inject(forwardRef(() => BuildsService)) private buildsService: BuildsService, + @Inject(forwardRef(() => TestVariationsService)) private testVariationsService: TestVariationsService ) {} diff --git a/src/test-runs/test-runs.module.ts b/src/test-runs/test-runs.module.ts index 579466d0..7673e7a2 100644 --- a/src/test-runs/test-runs.module.ts +++ b/src/test-runs/test-runs.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { forwardRef, Module } from '@nestjs/common'; import { TestRunsService } from './test-runs.service'; import { SharedModule } from '../shared/shared.module'; import { PrismaService } from '../prisma/prisma.service'; @@ -6,9 +6,9 @@ import { TestRunsController } from './test-runs.controller'; import { TestVariationsModule } from '../test-variations/test-variations.module'; @Module({ - imports: [SharedModule, TestVariationsModule], + imports: [SharedModule, forwardRef(() => TestVariationsModule)], providers: [TestRunsService, PrismaService], + controllers: [TestRunsController], exports: [TestRunsService], - controllers: [TestRunsController] }) export class TestRunsModule {} diff --git a/src/test-runs/test-runs.service.ts b/src/test-runs/test-runs.service.ts index 114473ca..b8baa9b7 100644 --- a/src/test-runs/test-runs.service.ts +++ b/src/test-runs/test-runs.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { forwardRef, Inject, Injectable } from '@nestjs/common'; import { PNG } from 'pngjs'; import Pixelmatch from 'pixelmatch'; import { CreateTestRequestDto } from './dto/create-test-request.dto'; @@ -17,6 +17,7 @@ import { convertBaselineDataToQuery } from '../shared/dto/baseline-data.dto'; @Injectable() export class TestRunsService { constructor( + @Inject(forwardRef(() => TestVariationsService)) private testVariationService: TestVariationsService, private prismaService: PrismaService, private staticService: StaticService, diff --git a/src/test-variations/test-variations.module.ts b/src/test-variations/test-variations.module.ts index 0e8c23f3..994230cd 100644 --- a/src/test-variations/test-variations.module.ts +++ b/src/test-variations/test-variations.module.ts @@ -1,12 +1,14 @@ -import { Module } from '@nestjs/common'; +import { forwardRef, Module } from '@nestjs/common'; import { TestVariationsService } from './test-variations.service'; import { TestVariationsController } from './test-variations.controller'; import { PrismaService } from '../prisma/prisma.service'; -import { TestRunsService } from '../test-runs/test-runs.service'; -import { BuildsService } from '../builds/builds.service'; +import { TestRunsModule } from '../test-runs/test-runs.module'; +import { BuildsModule } from '../builds/builds.module'; +import { SharedModule } from 'src/shared/shared.module'; @Module({ - providers: [TestVariationsService, PrismaService, TestRunsService, BuildsService], + imports: [forwardRef(() => TestRunsModule), forwardRef(() => BuildsModule)], + providers: [TestVariationsService, PrismaService], controllers: [TestVariationsController], exports: [TestVariationsService], }) diff --git a/src/test-variations/test-variations.service.ts b/src/test-variations/test-variations.service.ts index 276e725a..0ea425ac 100644 --- a/src/test-variations/test-variations.service.ts +++ b/src/test-variations/test-variations.service.ts @@ -16,10 +16,10 @@ export class TestVariationsService { constructor( private prismaService: PrismaService, private staticService: StaticService, - @Inject(forwardRef(() => BuildsService)) - private buildsService: BuildsService, @Inject(forwardRef(() => TestRunsService)) - private testRunsService: TestRunsService + private testRunsService: TestRunsService, + @Inject(forwardRef(() => BuildsService)) + private buildsService: BuildsService ) {} async getDetails(id: string): Promise { @@ -110,7 +110,7 @@ export class TestVariationsService { }); // compare to main branch variations - testVariations.map(async sideBranchTestVariation => { + testVariations.map(async (sideBranchTestVariation) => { const baseline = this.staticService.getImage(sideBranchTestVariation.baselineName); if (baseline) { try { @@ -130,7 +130,7 @@ export class TestVariationsService { imageBase64, diffTollerancePercent: 0, merge: true, - ignoreAreas: JSON.parse(sideBranchTestVariation.ignoreAreas) + ignoreAreas: JSON.parse(sideBranchTestVariation.ignoreAreas), }; return this.testRunsService.create(mainBranchTestVariation, createTestRequestDto); @@ -149,14 +149,14 @@ export class TestVariationsService { this.getDetails(id), this.prismaService.testRun.findMany({ where: { testVariationId: id }, - }) - ]) + }), + ]); // delete testRun - await Promise.all(testRuns.map(item => this.testRunsService.delete(item.id))); + await Promise.all(testRuns.map((item) => this.testRunsService.delete(item.id))); // delete baseline - await Promise.all(testVariation.baselines.map(baseline => this.deleteBaseline(baseline))); + await Promise.all(testVariation.baselines.map((baseline) => this.deleteBaseline(baseline))); // delete testVariation return this.prismaService.testVariation.delete({ From 9a4a60a63f57579e95a3f8114936aa3b28cc7c03 Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Sun, 15 Nov 2020 18:25:22 +0200 Subject: [PATCH 05/12] ciBuildId added --- .../README.md | 42 ++++++ .../schema.prisma | 120 ++++++++++++++++++ .../steps.json | 23 ++++ prisma/migrations/migrate.lock | 3 +- prisma/schema.prisma | 7 +- src/builds/builds.service.spec.ts | 74 ++++++++--- src/builds/builds.service.ts | 58 +++++---- src/builds/dto/build-create.dto.ts | 5 +- src/shared/static/static.service.ts | 2 +- src/test-variations/test-variations.module.ts | 1 - 10 files changed, 277 insertions(+), 58 deletions(-) create mode 100644 prisma/migrations/20201115155739-ci-build-id-added/README.md create mode 100644 prisma/migrations/20201115155739-ci-build-id-added/schema.prisma create mode 100644 prisma/migrations/20201115155739-ci-build-id-added/steps.json diff --git a/prisma/migrations/20201115155739-ci-build-id-added/README.md b/prisma/migrations/20201115155739-ci-build-id-added/README.md new file mode 100644 index 00000000..7e797dbc --- /dev/null +++ b/prisma/migrations/20201115155739-ci-build-id-added/README.md @@ -0,0 +1,42 @@ +# Migration `20201115155739-ci-build-id-added` + +This migration has been generated by Pavel Strunkin at 11/15/2020, 5:57:39 PM. +You can check out the [state of the schema](./schema.prisma) after the migration. + +## Database Steps + +```sql +ALTER TABLE "public"."Build" ADD COLUMN "ciBuildId" text + +CREATE UNIQUE INDEX "Build.ciBuildId_unique" ON "public"."Build"("ciBuildId") +``` + +## Changes + +```diff +diff --git schema.prisma schema.prisma +migration 20201007145002-builds-counter..20201115155739-ci-build-id-added +--- datamodel.dml ++++ datamodel.dml +@@ -1,16 +1,17 @@ + generator client { +- provider = "prisma-client-js" ++ provider = "prisma-client-js" + previewFeatures = ["atomicNumberOperations"] + } + datasource db { +- provider = "postgresql" +- url = "***" ++ provider = "postgresql" ++ url = "***" + } + model Build { + id String @id @default(uuid()) ++ ciBuildId String? @unique + number Int? + branchName String? + status String? + testRuns TestRun[] +``` + + diff --git a/prisma/migrations/20201115155739-ci-build-id-added/schema.prisma b/prisma/migrations/20201115155739-ci-build-id-added/schema.prisma new file mode 100644 index 00000000..01b6e22e --- /dev/null +++ b/prisma/migrations/20201115155739-ci-build-id-added/schema.prisma @@ -0,0 +1,120 @@ +generator client { + provider = "prisma-client-js" + previewFeatures = ["atomicNumberOperations"] +} + +datasource db { + provider = "postgresql" + url = "***" +} + +model Build { + id String @id @default(uuid()) + ciBuildId String? @unique + number Int? + branchName String? + status String? + testRuns TestRun[] + projectId String + project Project @relation(fields: [projectId], references: [id]) + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + user User? @relation(fields: [userId], references: [id]) + userId String? + isRunning Boolean? +} + +model Project { + id String @id @default(uuid()) + name String + mainBranchName String @default("master") + builds Build[] + buildsCounter Int @default(0) + testVariations TestVariation[] + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + + @@unique([name]) +} + +model TestRun { + id String @id @default(uuid()) + imageName String + diffName String? + diffPercent Float? + diffTollerancePercent Float @default(0) + pixelMisMatchCount Int? + status TestStatus + buildId String + build Build @relation(fields: [buildId], references: [id]) + testVariationId String + testVariation TestVariation @relation(fields: [testVariationId], references: [id]) + merge Boolean @default(false) + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + // Test variation data + name String @default("") + browser String? + device String? + os String? + viewport String? + baselineName String? + ignoreAreas String @default("[]") + comment String? + baseline Baseline? + branchName String @default("master") + baselineBranchName String? +} + +model TestVariation { + id String @id @default(uuid()) + name String + branchName String @default("master") + browser String? + device String? + os String? + viewport String? + baselineName String? + ignoreAreas String @default("[]") + projectId String + project Project @relation(fields: [projectId], references: [id]) + testRuns TestRun[] + baselines Baseline[] + comment String? + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + + @@unique([projectId, name, browser, device, os, viewport, branchName]) +} + +model Baseline { + id String @id @default(uuid()) + baselineName String + testVariationId String + testVariation TestVariation @relation(fields: [testVariationId], references: [id]) + testRunId String? + testRun TestRun? @relation(fields: [testRunId], references: [id]) + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) +} + +model User { + id String @id @default(uuid()) + email String @unique + password String + firstName String? + lastName String? + apiKey String @unique + isActive Boolean @default(true) + builds Build[] + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) +} + +enum TestStatus { + failed + new + ok + unresolved + approved +} diff --git a/prisma/migrations/20201115155739-ci-build-id-added/steps.json b/prisma/migrations/20201115155739-ci-build-id-added/steps.json new file mode 100644 index 00000000..83924d01 --- /dev/null +++ b/prisma/migrations/20201115155739-ci-build-id-added/steps.json @@ -0,0 +1,23 @@ +{ + "version": "0.3.14-fixed", + "steps": [ + { + "tag": "CreateField", + "model": "Build", + "field": "ciBuildId", + "type": "String", + "arity": "Optional" + }, + { + "tag": "CreateDirective", + "location": { + "path": { + "tag": "Field", + "model": "Build", + "field": "ciBuildId" + }, + "directive": "unique" + } + } + ] +} \ No newline at end of file diff --git a/prisma/migrations/migrate.lock b/prisma/migrations/migrate.lock index 6f8e22c5..b6cd57de 100644 --- a/prisma/migrations/migrate.lock +++ b/prisma/migrations/migrate.lock @@ -9,4 +9,5 @@ 20200728221159-zero-diff-tolerance 20200812213545-build-run-status 20200909223305-test-variation-project-id-added-into-unique-constraint -20201007145002-builds-counter \ No newline at end of file +20201007145002-builds-counter +20201115155739-ci-build-id-added \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index db598486..c817ccad 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,15 +1,16 @@ generator client { - provider = "prisma-client-js" + provider = "prisma-client-js" previewFeatures = ["atomicNumberOperations"] } datasource db { - provider = "postgresql" - url = env("DATABASE_URL") + provider = "postgresql" + url = env("DATABASE_URL") } model Build { id String @id @default(uuid()) + ciBuildId String? @unique number Int? branchName String? status String? diff --git a/src/builds/builds.service.spec.ts b/src/builds/builds.service.spec.ts index a87c1627..9bb99dfe 100644 --- a/src/builds/builds.service.spec.ts +++ b/src/builds/builds.service.spec.ts @@ -75,6 +75,7 @@ describe('BuildsService', () => { testRuns: TestRun[]; } = { id: 'a9385fc1-884d-4f9f-915e-40da0e7773d5', + ciBuildId: null, number: null, branchName: 'develop', status: null, @@ -143,30 +144,44 @@ describe('BuildsService', () => { }); describe('create', () => { + const createBuildDto: CreateBuildDto = { + ciBuildId: 'ciBuildId', + branchName: 'branchName', + project: 'name', + }; + + const project: Project = { + id: 'project id', + name: 'name', + mainBranchName: 'master', + buildsCounter: 1, + updatedAt: new Date(), + createdAt: new Date(), + }; + it('should create', async () => { - const createBuildDto: CreateBuildDto = { - branchName: 'branchName', - project: 'name', - }; - - const project: Project = { - id: 'project id', - name: 'name', - mainBranchName: 'master', - buildsCounter: 1, - updatedAt: new Date(), - createdAt: new Date(), - }; - const buildUpsertMock = jest.fn().mockResolvedValueOnce(build); + const buildFindOneMock = jest.fn().mockResolvedValueOnce(null); + const buildCreateMock = jest.fn().mockResolvedValueOnce(build); const projectFindOneMock = jest.fn().mockResolvedValueOnce(project); const projectUpdateMock = jest.fn().mockResolvedValueOnce(project); const eventsBuildCreatedMock = jest.fn(); - mocked(BuildDto).mockReturnValueOnce(buildDto); - service = await initService({ buildUpsertMock, eventsBuildCreatedMock, projectFindOneMock, projectUpdateMock }); + mocked(BuildDto).mockReturnValue(buildDto); + service = await initService({ + buildCreateMock, + buildFindOneMock, + eventsBuildCreatedMock, + projectFindOneMock, + projectUpdateMock, + }); const result = await service.create(createBuildDto); expect(projectFindOneMock).toHaveBeenCalledWith(createBuildDto.project); + expect(buildFindOneMock).toHaveBeenCalledWith({ + where: { + ciBuildId: createBuildDto.ciBuildId, + }, + }); expect(projectUpdateMock).toHaveBeenCalledWith({ where: { id: project.id }, data: { @@ -175,9 +190,10 @@ describe('BuildsService', () => { }, }, }); - expect(buildUpsertMock).toHaveBeenCalledWith({ - create: { + expect(buildCreateMock).toHaveBeenCalledWith({ + data: { branchName: createBuildDto.branchName, + ciBuildId: createBuildDto.ciBuildId, isRunning: true, number: project.buildsCounter, project: { @@ -186,12 +202,28 @@ describe('BuildsService', () => { }, }, }, - update: {}, + }); + expect(eventsBuildCreatedMock).toHaveBeenCalledWith(buildDto); + expect(result).toBe(buildDto); + }); + + it('should reuse by ciBuildId', async () => { + const buildFindOneMock = jest.fn().mockResolvedValueOnce(build); + const projectFindOneMock = jest.fn().mockResolvedValueOnce(project); + mocked(BuildDto).mockReturnValue(buildDto); + service = await initService({ + buildFindOneMock, + projectFindOneMock, + }); + + const result = await service.create(createBuildDto); + + expect(projectFindOneMock).toHaveBeenCalledWith(createBuildDto.project); + expect(buildFindOneMock).toHaveBeenCalledWith({ where: { - id: '', + ciBuildId: createBuildDto.ciBuildId, }, }); - expect(eventsBuildCreatedMock).toHaveBeenCalledWith(buildDto); expect(result).toBe(buildDto); }); }); diff --git a/src/builds/builds.service.ts b/src/builds/builds.service.ts index bf553550..8095f202 100644 --- a/src/builds/builds.service.ts +++ b/src/builds/builds.service.ts @@ -31,42 +31,44 @@ export class BuildsService { } async create(createBuildDto: CreateBuildDto): Promise { - // find project let project = await this.projectService.findOne(createBuildDto.project); - // increment build number - project = await this.prismaService.project.update({ + let build = await this.prismaService.build.findOne({ where: { - id: project.id, - }, - data: { - buildsCounter: { - increment: 1, - }, + ciBuildId: createBuildDto.ciBuildId, }, }); - // get or create build - const buildId = createBuildDto.id || ''; - const build = await this.prismaService.build.upsert({ - create: { - branchName: createBuildDto.branchName, - isRunning: true, - number: project.buildsCounter, - project: { - connect: { - id: project.id, + if (!build) { + // increment build number + project = await this.prismaService.project.update({ + where: { + id: project.id, + }, + data: { + buildsCounter: { + increment: 1, }, }, - }, - update: {}, - where: { - id: buildId, - }, - }); - const buildDto = new BuildDto(build); - this.eventsGateway.buildCreated(buildDto); - return buildDto; + }); + + build = await this.prismaService.build.create({ + data: { + ciBuildId: createBuildDto.ciBuildId, + branchName: createBuildDto.branchName, + isRunning: true, + number: project.buildsCounter, + project: { + connect: { + id: project.id, + }, + }, + }, + }); + + this.eventsGateway.buildCreated(new BuildDto(build)); + } + return new BuildDto(build); } async stop(id: string): Promise { diff --git a/src/builds/dto/build-create.dto.ts b/src/builds/dto/build-create.dto.ts index 21a207ba..d1c69185 100644 --- a/src/builds/dto/build-create.dto.ts +++ b/src/builds/dto/build-create.dto.ts @@ -1,11 +1,10 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsUUID, IsOptional, isUUID } from 'class-validator'; +import { IsString, IsOptional } from 'class-validator'; export class CreateBuildDto { @ApiProperty() @IsOptional() - @IsUUID() - readonly id?: string; + readonly ciBuildId?: string; @ApiProperty() @IsString() diff --git a/src/shared/static/static.service.ts b/src/shared/static/static.service.ts index a4eafda0..93c3521e 100644 --- a/src/shared/static/static.service.ts +++ b/src/shared/static/static.service.ts @@ -28,7 +28,7 @@ export class StaticService { async deleteImage(imageName: string): Promise { if (!imageName) return; return new Promise((resolvePromise, reject) => { - unlink(this.getImagePath(imageName), err => { + unlink(this.getImagePath(imageName), (err) => { if (err) { reject(err); } diff --git a/src/test-variations/test-variations.module.ts b/src/test-variations/test-variations.module.ts index 994230cd..4cc64701 100644 --- a/src/test-variations/test-variations.module.ts +++ b/src/test-variations/test-variations.module.ts @@ -4,7 +4,6 @@ import { TestVariationsController } from './test-variations.controller'; import { PrismaService } from '../prisma/prisma.service'; import { TestRunsModule } from '../test-runs/test-runs.module'; import { BuildsModule } from '../builds/builds.module'; -import { SharedModule } from 'src/shared/shared.module'; @Module({ imports: [forwardRef(() => TestRunsModule), forwardRef(() => BuildsModule)], From a44001639690d8bfafda2e6f0d8161517b4c68db Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Sun, 15 Nov 2020 18:34:30 +0200 Subject: [PATCH 06/12] Update test-runs.service.spec.ts --- src/test-runs/test-runs.service.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test-runs/test-runs.service.spec.ts b/src/test-runs/test-runs.service.spec.ts index b124039c..a8f91fd7 100644 --- a/src/test-runs/test-runs.service.spec.ts +++ b/src/test-runs/test-runs.service.spec.ts @@ -843,6 +843,7 @@ describe('TestRunsService', () => { testRuns: TestRun[]; } = { id: 'a9385fc1-884d-4f9f-915e-40da0e7773d5', + ciBuildId: null, number: null, branchName: 'develop', status: null, From 9f3225b1f20170e66abc17707d74f82329eeef90 Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Sun, 15 Nov 2020 18:41:41 +0200 Subject: [PATCH 07/12] ciBuildId: 'ciBuildId', --- src/builds/dto/build.dto.spec.ts | 9 +++++++++ src/builds/dto/build.dto.ts | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/builds/dto/build.dto.spec.ts b/src/builds/dto/build.dto.spec.ts index ec7c0d7d..aea1c66f 100644 --- a/src/builds/dto/build.dto.spec.ts +++ b/src/builds/dto/build.dto.spec.ts @@ -7,6 +7,7 @@ describe('BuildDto', () => { 'undefined testRuns', { id: 'a9385fc1-884d-4f9f-915e-40da0e7773d5', + ciBuildId: 'ciBuildId', number: null, branchName: 'develop', status: null, @@ -22,6 +23,7 @@ describe('BuildDto', () => { 'empty testRuns', { id: 'a9385fc1-884d-4f9f-915e-40da0e7773d5', + ciBuildId: 'ciBuildId', number: null, branchName: 'develop', status: null, @@ -36,6 +38,7 @@ describe('BuildDto', () => { ])('new with %s', (_, build) => { const buildDto: BuildDto = { id: build.id, + ciBuildId: build.ciBuildId, number: build.number, branchName: build.branchName, status: 'new', @@ -59,6 +62,7 @@ describe('BuildDto', () => { testRuns: TestRun[]; } = { id: 'a9385fc1-884d-4f9f-915e-40da0e7773d5', + ciBuildId: 'ciBuildId', number: null, branchName: 'develop', status: null, @@ -120,6 +124,7 @@ describe('BuildDto', () => { }; const buildDto: BuildDto = { id: build.id, + ciBuildId: build.ciBuildId, number: build.number, branchName: build.branchName, status: 'passed', @@ -141,6 +146,7 @@ describe('BuildDto', () => { it('failed', () => { const build: Build & { testRuns: TestRun[] } = { id: 'a9385fc1-884d-4f9f-915e-40da0e7773d5', + ciBuildId: 'ciBuildId', number: null, branchName: 'develop', status: null, @@ -226,6 +232,7 @@ describe('BuildDto', () => { }; const buildDto: BuildDto = { id: build.id, + ciBuildId: build.ciBuildId, number: build.number, branchName: build.branchName, status: 'failed', @@ -247,6 +254,7 @@ describe('BuildDto', () => { it('unresolved', () => { const build: Build & { testRuns: TestRun[] } = { id: 'a9385fc1-884d-4f9f-915e-40da0e7773d5', + ciBuildId: 'ciBuildId', number: null, branchName: 'develop', status: null, @@ -380,6 +388,7 @@ describe('BuildDto', () => { }; const buildDto: BuildDto = { id: build.id, + ciBuildId: build.ciBuildId, number: build.number, branchName: build.branchName, status: 'unresolved', diff --git a/src/builds/dto/build.dto.ts b/src/builds/dto/build.dto.ts index 7f62cc99..66e5220b 100644 --- a/src/builds/dto/build.dto.ts +++ b/src/builds/dto/build.dto.ts @@ -5,6 +5,9 @@ export class BuildDto { @ApiProperty() id: string; + @ApiProperty() + ciBuildId: string | null; + @ApiProperty() number: number | null; @@ -37,6 +40,7 @@ export class BuildDto { constructor(build: Build & { testRuns?: TestRun[] }) { this.id = build.id; + this.ciBuildId = build.ciBuildId; this.number = build.number; this.branchName = build.branchName; this.userId = build.userId; @@ -50,7 +54,7 @@ export class BuildDto { this.unresolvedCount = 0; this.failedCount = 0; - build.testRuns?.forEach(testRun => { + build.testRuns?.forEach((testRun) => { switch (testRun.status) { case TestStatus.approved: case TestStatus.ok: { From d4c2a307fa9c91999fe25f5405ac420387fe074f Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Sun, 15 Nov 2020 18:43:04 +0200 Subject: [PATCH 08/12] Update builds.service.spec.ts --- src/builds/builds.service.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/builds/builds.service.spec.ts b/src/builds/builds.service.spec.ts index 9bb99dfe..be4b9ef9 100644 --- a/src/builds/builds.service.spec.ts +++ b/src/builds/builds.service.spec.ts @@ -114,6 +114,7 @@ describe('BuildsService', () => { const buildDto: BuildDto = { id: 'a9385fc1-884d-4f9f-915e-40da0e7773d5', + ciBuildId: 'ciBuildId', number: null, branchName: 'develop', status: 'new', From 631920f2a511ad12f2ca48d876e84ec81c1eb00b Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Sun, 15 Nov 2020 18:47:45 +0200 Subject: [PATCH 09/12] Update test-variations.service.spec.ts --- src/test-variations/test-variations.service.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test-variations/test-variations.service.spec.ts b/src/test-variations/test-variations.service.spec.ts index 3849b8cc..417ea208 100644 --- a/src/test-variations/test-variations.service.spec.ts +++ b/src/test-variations/test-variations.service.spec.ts @@ -332,6 +332,7 @@ describe('TestVariationsService', () => { }; const build: Build = { id: 'a9385fc1-884d-4f9f-915e-40da0e7773d5', + ciBuildId: 'ciBuildId', number: null, branchName: project.mainBranchName, status: null, From 95b43f1169fdadec27aea0114a4bd51d41c3ff84 Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Sun, 15 Nov 2020 18:57:53 +0200 Subject: [PATCH 10/12] Update builds.service.ts --- src/builds/builds.service.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/builds/builds.service.ts b/src/builds/builds.service.ts index 8095f202..65f6a6de 100644 --- a/src/builds/builds.service.ts +++ b/src/builds/builds.service.ts @@ -33,11 +33,14 @@ export class BuildsService { async create(createBuildDto: CreateBuildDto): Promise { let project = await this.projectService.findOne(createBuildDto.project); - let build = await this.prismaService.build.findOne({ - where: { - ciBuildId: createBuildDto.ciBuildId, - }, - }); + let build: Build; + if (createBuildDto.ciBuildId) { + build = await this.prismaService.build.findOne({ + where: { + ciBuildId: createBuildDto.ciBuildId, + }, + }); + } if (!build) { // increment build number From 868fa70b8729978960474403999e20160a8aa2dc Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Sun, 15 Nov 2020 19:03:26 +0200 Subject: [PATCH 11/12] Update builds.e2e-spec.ts --- test/builds.e2e-spec.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/builds.e2e-spec.ts b/test/builds.e2e-spec.ts index 28dfe6bf..2e52c0cd 100644 --- a/test/builds.e2e-spec.ts +++ b/test/builds.e2e-spec.ts @@ -79,6 +79,28 @@ describe('Builds (e2e)', () => { }); }); + it('201 by ciBuildId', async () => { + const createBuildDto: CreateBuildDto = { + ciBuildId: 'ciBuildId', + branchName: 'branchName', + project: project.name, + }; + const build = await buildsService.create(createBuildDto) + + return requestWithApiKey(app, 'post', '/builds', createBuildDto, user.apiKey) + .expect(201) + .expect((res) => { + expect(res.body.id).toBe(build.id); + expect(res.body.ciBuildId).toBe("test"); + expect(res.body.projectId).toBe(project.id); + expect(res.body.branchName).toBe(createBuildDto.branchName); + expect(res.body.failedCount).toBe(0); + expect(res.body.passedCount).toBe(0); + expect(res.body.unresolvedCount).toBe(0); + expect(res.body.isRunning).toBe(true); + }); + }); + it('404', () => { const createBuildDto: CreateBuildDto = { branchName: 'branchName', From 5979f1bf0038baec50f52644ded6cab2200c95f6 Mon Sep 17 00:00:00 2001 From: Pavel Strunkin Date: Sun, 15 Nov 2020 19:11:39 +0200 Subject: [PATCH 12/12] Update builds.e2e-spec.ts --- test/builds.e2e-spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/builds.e2e-spec.ts b/test/builds.e2e-spec.ts index 2e52c0cd..c57cad1c 100644 --- a/test/builds.e2e-spec.ts +++ b/test/builds.e2e-spec.ts @@ -85,13 +85,13 @@ describe('Builds (e2e)', () => { branchName: 'branchName', project: project.name, }; - const build = await buildsService.create(createBuildDto) + const build = await buildsService.create(createBuildDto); return requestWithApiKey(app, 'post', '/builds', createBuildDto, user.apiKey) .expect(201) .expect((res) => { expect(res.body.id).toBe(build.id); - expect(res.body.ciBuildId).toBe("test"); + expect(res.body.ciBuildId).toBe(createBuildDto.ciBuildId); expect(res.body.projectId).toBe(project.id); expect(res.body.branchName).toBe(createBuildDto.branchName); expect(res.body.failedCount).toBe(0);