diff --git a/prisma/migrations/20210709133029-275-project-to-testrun-relation/README.md b/prisma/migrations/20210709133029-275-project-to-testrun-relation/README.md new file mode 100644 index 00000000..6d56845b --- /dev/null +++ b/prisma/migrations/20210709133029-275-project-to-testrun-relation/README.md @@ -0,0 +1,51 @@ +# Migration `20210709133029-275-project-to-testrun-relation` + +This migration has been generated by Pavel Strunkin at 7/9/2021, 4:30:29 PM. +You can check out the [state of the schema](./schema.prisma) after the migration. + +## Database Steps + +```sql +ALTER TABLE "TestRun" ADD COLUMN "projectId" TEXT + +ALTER TABLE "TestRun" ADD FOREIGN KEY("projectId")REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE +``` + +## Changes + +```diff +diff --git schema.prisma schema.prisma +migration 20210709115233-gh-275-max-branch-lifetime..20210709133029-275-project-to-testrun-relation +--- datamodel.dml ++++ datamodel.dml +@@ -3,9 +3,9 @@ + } + datasource db { + provider = "postgresql" +- url = "***" ++ url = "***" + } + model Build { + id String @id @default(uuid()) +@@ -40,8 +40,9 @@ + autoApproveFeature Boolean @default(false) + imageComparison ImageComparison @default(pixelmatch) + imageComparisonConfig String @default("{ \"threshold\": 0.1, \"ignoreAntialiasing\": true, \"allowDiffDimensions\": false }") ++ TestRun TestRun[] + @@unique([name]) + } + model TestRun { +@@ -55,8 +56,10 @@ + buildId String + build Build @relation(fields: [buildId], references: [id]) + testVariationId String? + testVariation TestVariation? @relation(fields: [testVariationId], references: [id]) ++ projectId String? ++ project Project? @relation(fields: [projectId], references: [id]) + merge Boolean @default(false) + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + // Test variation data +``` + + diff --git a/prisma/migrations/20210709133029-275-project-to-testrun-relation/schema.prisma b/prisma/migrations/20210709133029-275-project-to-testrun-relation/schema.prisma new file mode 100644 index 00000000..a91c3cbf --- /dev/null +++ b/prisma/migrations/20210709133029-275-project-to-testrun-relation/schema.prisma @@ -0,0 +1,143 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = "***" +} + +model Build { + id String @id @default(uuid()) + ciBuildId String? + 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? + + @@unique([projectId, ciBuildId]) +} + +model Project { + id String @id @default(uuid()) + name String + mainBranchName String @default("master") + builds Build[] + buildsCounter Int @default(0) + maxBuildAllowed Int @default(100) + maxBranchLifetime Int @default(30) + testVariations TestVariation[] + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + // config + autoApproveFeature Boolean @default(false) + imageComparison ImageComparison @default(pixelmatch) + imageComparisonConfig String @default("{ \"threshold\": 0.1, \"ignoreAntialiasing\": true, \"allowDiffDimensions\": false }") + + TestRun TestRun[] + @@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]) + projectId String? + project Project? @relation(fields: [projectId], 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? + customTags String? @default("") + baselineName String? + comment String? + baseline Baseline? + branchName String @default("master") + baselineBranchName String? + ignoreAreas String @default("[]") + tempIgnoreAreas String @default("[]") +} + +model TestVariation { + id String @id @default(uuid()) + name String + branchName String @default("master") + browser String @default("") + device String @default("") + os String @default("") + viewport String @default("") + customTags String @default("") + 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, customTags, 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]) + userId String? + user User? @relation(fields: [userId], 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[] + baselines Baseline[] + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) +} + +enum TestStatus { + failed + new + ok + unresolved + approved + autoApproved +} + +enum ImageComparison { + pixelmatch + lookSame + odiff +} diff --git a/prisma/migrations/20210709133029-275-project-to-testrun-relation/steps.json b/prisma/migrations/20210709133029-275-project-to-testrun-relation/steps.json new file mode 100644 index 00000000..177b6a06 --- /dev/null +++ b/prisma/migrations/20210709133029-275-project-to-testrun-relation/steps.json @@ -0,0 +1,65 @@ +{ + "version": "0.3.14-fixed", + "steps": [ + { + "tag": "CreateField", + "model": "Project", + "field": "TestRun", + "type": "TestRun", + "arity": "List" + }, + { + "tag": "CreateField", + "model": "TestRun", + "field": "projectId", + "type": "String", + "arity": "Optional" + }, + { + "tag": "CreateField", + "model": "TestRun", + "field": "project", + "type": "Project", + "arity": "Optional" + }, + { + "tag": "CreateDirective", + "location": { + "path": { + "tag": "Field", + "model": "TestRun", + "field": "project" + }, + "directive": "relation" + } + }, + { + "tag": "CreateArgument", + "location": { + "tag": "Directive", + "path": { + "tag": "Field", + "model": "TestRun", + "field": "project" + }, + "directive": "relation" + }, + "argument": "fields", + "value": "[projectId]" + }, + { + "tag": "CreateArgument", + "location": { + "tag": "Directive", + "path": { + "tag": "Field", + "model": "TestRun", + "field": "project" + }, + "directive": "relation" + }, + "argument": "references", + "value": "[id]" + } + ] +} \ No newline at end of file diff --git a/prisma/migrations/migrate.lock b/prisma/migrations/migrate.lock index 42b0eea1..73c4928c 100644 --- a/prisma/migrations/migrate.lock +++ b/prisma/migrations/migrate.lock @@ -21,4 +21,5 @@ 20210605124856-image-compare-config-as-json 20210612140950-limit-build-number 20210705154453-baseline-author -20210709115233-gh-275-max-branch-lifetime \ No newline at end of file +20210709115233-gh-275-max-branch-lifetime +20210709133029-275-project-to-testrun-relation diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 00a8d5d3..dd691e92 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -41,6 +41,7 @@ model Project { imageComparison ImageComparison @default(pixelmatch) imageComparisonConfig String @default("{ \"threshold\": 0.1, \"ignoreAntialiasing\": true, \"allowDiffDimensions\": false }") + TestRun TestRun[] @@unique([name]) } @@ -56,6 +57,8 @@ model TestRun { build Build @relation(fields: [buildId], references: [id]) testVariationId String? testVariation TestVariation? @relation(fields: [testVariationId], references: [id]) + projectId String? + project Project? @relation(fields: [projectId], references: [id]) merge Boolean @default(false) updatedAt DateTime @updatedAt createdAt DateTime @default(now()) diff --git a/src/_data_/index.ts b/src/_data_/index.ts index af90a3cd..b5af4e12 100644 --- a/src/_data_/index.ts +++ b/src/_data_/index.ts @@ -76,6 +76,7 @@ export const generateTestRun = (testRun?: Partial): TestRun => { status: 'new', buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', + projectId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fcc', updatedAt: new Date(), createdAt: new Date(), name: 'ss2f77', diff --git a/src/builds/builds.service.spec.ts b/src/builds/builds.service.spec.ts index 7abcb31e..871a75a4 100644 --- a/src/builds/builds.service.spec.ts +++ b/src/builds/builds.service.spec.ts @@ -7,6 +7,7 @@ import { Build, TestRun, TestStatus } from '@prisma/client'; import { mocked } from 'ts-jest/utils'; import { BuildDto } from './dto/build.dto'; import { ProjectsService } from '../projects/projects.service'; +import { generateTestRun } from '../_data_'; jest.mock('./dto/build.dto'); @@ -91,34 +92,7 @@ describe('BuildsService', () => { createdAt: new Date(), userId: null, isRunning: true, - testRuns: [ - { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: null, - diffPercent: null, - diffTollerancePercent: 1, - pixelMisMatchCount: null, - status: 'new', - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment', - branchName: 'develop', - baselineBranchName: 'master', - merge: false, - }, - ], + testRuns: [generateTestRun()], }; const buildDto: BuildDto = { @@ -182,7 +156,13 @@ describe('BuildsService', () => { const buildDeleteMock = jest.fn().mockImplementation(() => Promise.resolve(build)); const testRunDeleteMock = jest.fn(); const eventBuildDeletedMock = jest.fn(); - service = await initService({ buildFindUniqueMock, buildDeleteMock, testRunDeleteMock, eventBuildDeletedMock, buildFindManyMock }); + service = await initService({ + buildFindUniqueMock, + buildDeleteMock, + testRunDeleteMock, + eventBuildDeletedMock, + buildFindManyMock, + }); await service.remove(build.id); diff --git a/src/builds/builds.service.ts b/src/builds/builds.service.ts index 86a803ad..5e0d6270 100644 --- a/src/builds/builds.service.ts +++ b/src/builds/builds.service.ts @@ -9,7 +9,6 @@ import { ModifyBuildDto } from './dto/build-modify.dto'; @Injectable() export class BuildsService { - private readonly logger: Logger = new Logger(BuildsService.name); constructor( @@ -17,7 +16,7 @@ export class BuildsService { private eventsGateway: EventsGateway, @Inject(forwardRef(() => TestRunsService)) private testRunsService: TestRunsService - ) { } + ) {} async findOne(id: string): Promise { const [build, testRuns] = await Promise.all([ @@ -61,6 +60,8 @@ export class BuildsService { } async remove(id: string): Promise { + this.logger.debug(`Going to remove Build ${id}`); + const build = await this.prismaService.build.findUnique({ where: { id }, include: { @@ -70,14 +71,15 @@ export class BuildsService { await Promise.all(build.testRuns.map((testRun) => this.testRunsService.delete(testRun.id))); - let promise = this.prismaService.build.delete({ - where: { id }, - }) + let promise = this.prismaService.build + .delete({ + where: { id }, + }) .then((build) => { - this.logger.log("Deleted build:" + JSON.stringify(build.id)); + this.logger.log('Deleted build:' + JSON.stringify(build.id)); this.eventsGateway.buildDeleted( new BuildDto({ - ...build + ...build, }) ); return build; @@ -86,15 +88,12 @@ export class BuildsService { } async deleteOldBuilds(projectId: string, keepBuilds: number) { - keepBuilds = (keepBuilds < 2) ? keepBuilds : (keepBuilds - 1); - this.findMany(projectId, undefined, keepBuilds) - .then( - buildList => { - buildList.data.forEach(eachBuild => { - this.remove(eachBuild.id); - }); - } - ); + keepBuilds = keepBuilds < 2 ? keepBuilds : keepBuilds - 1; + this.findMany(projectId, undefined, keepBuilds).then((buildList) => { + buildList.data.forEach((eachBuild) => { + this.remove(eachBuild.id); + }); + }); } async approve(id: string, merge: boolean): Promise { @@ -127,11 +126,11 @@ export class BuildsService { }) { const where: Prisma.BuildWhereUniqueInput = ciBuildId ? { - projectId_ciBuildId: { - projectId, - ciBuildId, - }, - } + projectId_ciBuildId: { + projectId, + ciBuildId, + }, + } : { id: projectId }; return this.prismaService.build.upsert({ where, diff --git a/src/builds/dto/build.dto.spec.ts b/src/builds/dto/build.dto.spec.ts index 172d1a86..1aef6e0b 100644 --- a/src/builds/dto/build.dto.spec.ts +++ b/src/builds/dto/build.dto.spec.ts @@ -1,4 +1,5 @@ import { Build, TestRun, TestStatus } from '@prisma/client'; +import { generateTestRun } from '../../_data_'; import { BuildDto } from './build.dto'; describe('BuildDto', () => { @@ -75,58 +76,8 @@ describe('BuildDto', () => { userId: null, isRunning: true, testRuns: [ - { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: null, - diffPercent: null, - diffTollerancePercent: 1, - pixelMisMatchCount: null, - status: TestStatus.ok, - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment1', - branchName: 'develop', - baselineBranchName: 'master', - merge: true, - }, - { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: null, - diffPercent: null, - diffTollerancePercent: 1, - pixelMisMatchCount: null, - status: TestStatus.approved, - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment2', - branchName: 'develop', - baselineBranchName: 'master', - merge: false, - }, + generateTestRun({ status: TestStatus.ok, merge: true }), + generateTestRun({ status: TestStatus.approved, merge: true }), ], }; const buildDto: BuildDto = { @@ -164,84 +115,9 @@ describe('BuildDto', () => { userId: null, isRunning: true, testRuns: [ - { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: null, - diffPercent: null, - diffTollerancePercent: 1, - pixelMisMatchCount: null, - status: TestStatus.ok, - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment', - branchName: 'develop', - baselineBranchName: 'master', - merge: false, - }, - { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: null, - diffPercent: null, - diffTollerancePercent: 1, - pixelMisMatchCount: null, - status: TestStatus.approved, - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment1', - branchName: 'develop', - baselineBranchName: 'master', - merge: false, - }, - { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: null, - diffPercent: null, - diffTollerancePercent: 1, - pixelMisMatchCount: null, - status: TestStatus.failed, - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment2', - branchName: 'develop', - baselineBranchName: 'master', - merge: false, - }, + generateTestRun({ status: TestStatus.ok }), + generateTestRun({ status: TestStatus.approved }), + generateTestRun({ status: TestStatus.failed }), ], }; const buildDto: BuildDto = { @@ -279,136 +155,11 @@ describe('BuildDto', () => { userId: null, isRunning: true, testRuns: [ - { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: null, - diffPercent: null, - diffTollerancePercent: 1, - pixelMisMatchCount: null, - status: TestStatus.ok, - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment1', - branchName: 'develop', - baselineBranchName: 'master', - merge: false, - }, - { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: null, - diffPercent: null, - diffTollerancePercent: 1, - pixelMisMatchCount: null, - status: TestStatus.approved, - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment2', - branchName: 'develop', - baselineBranchName: 'master', - merge: false, - }, - { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: null, - diffPercent: null, - diffTollerancePercent: 1, - pixelMisMatchCount: null, - status: TestStatus.failed, - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: null, - branchName: 'develop', - baselineBranchName: 'master', - merge: false, - }, - { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: null, - diffPercent: null, - diffTollerancePercent: 1, - pixelMisMatchCount: null, - status: TestStatus.new, - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment', - branchName: 'develop', - baselineBranchName: 'master', - merge: false, - }, - { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: null, - diffPercent: null, - diffTollerancePercent: 1, - pixelMisMatchCount: null, - status: TestStatus.unresolved, - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment', - branchName: 'develop', - baselineBranchName: 'master', - merge: false, - }, + generateTestRun({ status: TestStatus.ok }), + generateTestRun({ status: TestStatus.approved }), + generateTestRun({ status: TestStatus.failed }), + generateTestRun({ status: TestStatus.new }), + generateTestRun({ status: TestStatus.unresolved }), ], }; const buildDto: BuildDto = { diff --git a/src/projects/projects.service.ts b/src/projects/projects.service.ts index cb6b8b4e..539a54c3 100644 --- a/src/projects/projects.service.ts +++ b/src/projects/projects.service.ts @@ -1,4 +1,4 @@ -import { forwardRef, HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; +import { forwardRef, HttpException, HttpStatus, Inject, Injectable, Logger } from '@nestjs/common'; import { CreateProjectDto } from './dto/create-project.dto'; import { BuildsService } from '../builds/builds.service'; import { TestVariationsService } from '../test-variations/test-variations.service'; @@ -9,13 +9,15 @@ import { UpdateProjectDto } from './dto/update-project.dto'; @Injectable() export class ProjectsService { + private readonly logger = new Logger(ProjectsService.name); + constructor( private prismaService: PrismaService, @Inject(forwardRef(() => BuildsService)) private buildsService: BuildsService, @Inject(forwardRef(() => TestVariationsService)) private testVariationsService: TestVariationsService - ) { } + ) {} async findOne(idOrName: string): Promise { const isUUID = uuidAPIKey.isUUID(idOrName); @@ -64,6 +66,7 @@ export class ProjectsService { } async remove(id: string): Promise { + this.logger.debug(`Going to remove Project ${id}`); const project = await this.prismaService.project.findUnique({ where: { id }, include: { @@ -72,10 +75,12 @@ export class ProjectsService { }, }); - await Promise.all(project.builds.map((build) => this.buildsService.remove(build.id))); - await Promise.all( - project.testVariations.map((testVariation) => this.testVariationsService.delete(testVariation.id)) - ); + for (const build of project.builds) { + await this.buildsService.remove(build.id); + } + for (const testVariation of project.testVariations) { + await this.testVariationsService.delete(testVariation.id); + } return this.prismaService.project.delete({ where: { id }, diff --git a/src/test-runs/test-runs.service.spec.ts b/src/test-runs/test-runs.service.spec.ts index 8cee93d6..e3dcccc2 100644 --- a/src/test-runs/test-runs.service.spec.ts +++ b/src/test-runs/test-runs.service.spec.ts @@ -270,6 +270,11 @@ describe('TestRunsService', () => { id: createTestRequestDto.buildId, }, }, + project: { + connect: { + id: createTestRequestDto.projectId, + }, + }, name: testVariation.name, browser: testVariation.browser, device: testVariation.device, @@ -291,32 +296,7 @@ describe('TestRunsService', () => { }); it('calculateDiff', async () => { - const testRun: TestRun = { - id: 'id', - buildId: 'buildId', - imageName: 'imageName', - baselineName: 'baselineName', - diffName: 'diffName', - diffTollerancePercent: 12, - diffPercent: 12, - pixelMisMatchCount: 123, - status: 'new', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - ignoreAreas: JSON.stringify(ignoreAreas), - tempIgnoreAreas: JSON.stringify(tempIgnoreAreas), - comment: 'some comment', - baselineBranchName: 'master', - branchName: 'develop', - merge: false, - }; + const testRun: TestRun = generateTestRun(); const testRunUpdateMock = jest.fn(); const baselineMock = 'baseline image'; const imageeMock = 'image'; @@ -349,32 +329,7 @@ describe('TestRunsService', () => { }); describe('saveDiffResult', () => { - const testRun: TestRun = { - id: 'id', - buildId: 'buildId', - imageName: 'imageName', - baselineName: 'baselineName', - diffName: 'diffName', - diffTollerancePercent: 12, - diffPercent: 12, - pixelMisMatchCount: 123, - status: 'new', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - ignoreAreas: JSON.stringify(ignoreAreas), - tempIgnoreAreas: JSON.stringify(tempIgnoreAreas), - comment: 'some comment', - baselineBranchName: 'master', - branchName: 'develop', - merge: false, - }; + const testRun: TestRun = generateTestRun(); it('no results', async () => { const id = 'some id'; const testRunUpdateMock = jest.fn().mockResolvedValueOnce(testRun); @@ -431,32 +386,7 @@ describe('TestRunsService', () => { it('findMany', async () => { const buildId = 'some id'; - const testRun: TestRun = { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: 'diffName', - diffPercent: 12, - diffTollerancePercent: 1, - pixelMisMatchCount: 123, - status: 'new', - buildId: buildId, - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - os: null, - viewport: '1800x1600', - customTags: '', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment', - baselineBranchName: 'master', - branchName: 'develop', - merge: false, - }; + const testRun: TestRun = generateTestRun(); const testRunFindManyMock = jest.fn().mockResolvedValueOnce([testRun]); service = await initService({ testRunFindManyMock, @@ -591,32 +521,7 @@ describe('TestRunsService', () => { updatedAt: new Date(), branchName: 'master', }; - const testRun: TestRun = { - id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', - imageName: '1592423768112.screenshot.png', - diffName: 'diffName', - diffPercent: 12, - diffTollerancePercent: 1, - pixelMisMatchCount: 123, - status: 'new', - buildId: '146e7a8d-89f0-4565-aa2c-e61efabb0afd', - testVariationId: '3bc4a5bc-006e-4d43-8e4e-eaa132627fca', - updatedAt: new Date(), - createdAt: new Date(), - name: 'ss2f77', - browser: 'chromium', - device: null, - customTags: '', - os: null, - viewport: '1800x1600', - baselineName: null, - ignoreAreas: '[]', - tempIgnoreAreas: '[]', - comment: 'some comment', - baselineBranchName: 'master', - branchName: 'develop', - merge: false, - }; + const testRun: TestRun = generateTestRun(); const projectFindUniqueMock = jest.fn().mockResolvedValueOnce(TEST_PROJECT); const testVariationFindMock = jest.fn().mockResolvedValueOnce(testVariation); const testRunFindManyMock = jest.fn().mockResolvedValueOnce([testRun]); diff --git a/src/test-runs/test-runs.service.ts b/src/test-runs/test-runs.service.ts index 29c2af0b..85f3a6b8 100644 --- a/src/test-runs/test-runs.service.ts +++ b/src/test-runs/test-runs.service.ts @@ -38,7 +38,7 @@ export class TestRunsService { id: string ): Promise< TestRun & { - testVariation: TestVariation; + testVariation?: TestVariation; } > { return this.prismaService.testRun.findUnique({ @@ -100,7 +100,9 @@ export class TestRunsService { this.logger.log(`Approving testRun: ${id} merge: ${merge} autoApprove: ${autoApprove}`); const testRun = await this.findOne(id); let { testVariation } = testRun; - const { projectId } = testVariation; + if (!testVariation) { + throw new Error('No test variation found. Re-create test run'); + } // save new baseline const baseline = this.staticService.getImage(testRun.imageName); @@ -109,7 +111,6 @@ export class TestRunsService { if (testRun.baselineBranchName !== testRun.branchName && !merge && !autoApprove) { // replace main branch with feature branch test variation const featureBranchTestVariation = await this.testVariationService.findUnique({ - projectId, ...testRun, }); @@ -117,7 +118,7 @@ export class TestRunsService { testVariation = await this.testVariationService.create({ testRunId: id, createTestRequestDto: { - projectId, + projectId: testRun.projectId, branchName: testRun.branchName, ...getTestVariationUniqueData(testRun), }, @@ -222,6 +223,11 @@ export class TestRunsService { id: createTestRequestDto.buildId, }, }, + project: { + connect: { + id: createTestRequestDto.projectId, + }, + }, ...getTestVariationUniqueData(testVariation), baselineName: testVariation.baselineName, baselineBranchName: testVariation.branchName, diff --git a/src/test-variations/test-variations.service.ts b/src/test-variations/test-variations.service.ts index 206d1247..d74954c1 100644 --- a/src/test-variations/test-variations.service.ts +++ b/src/test-variations/test-variations.service.ts @@ -224,7 +224,9 @@ export class TestVariationsService { const testVariation = await this.getDetails(id); // delete Baselines - await Promise.all(testVariation.baselines.map((baseline) => this.deleteBaseline(baseline))); + for (const baseline of testVariation.baselines) { + await this.deleteBaseline(baseline); + } // disconnect TestRuns // workaround due to https://github.com/prisma/prisma/issues/2810 @@ -238,6 +240,8 @@ export class TestVariationsService { } async deleteBaseline(baseline: Baseline): Promise { + this.logger.debug(`Going to remove Baseline ${baseline.id}`); + this.staticService.deleteImage(baseline.baselineName); return this.prismaService.baseline.delete({ where: { id: baseline.id },