diff --git a/prisma/migrations/20200627134248-comment-added/README.md b/prisma/migrations/20200627134248-comment-added/README.md new file mode 100644 index 00000000..f7244920 --- /dev/null +++ b/prisma/migrations/20200627134248-comment-added/README.md @@ -0,0 +1,58 @@ +# Migration `20200627134248-comment-added` + +This migration has been generated by Pavel Strunkin at 6/27/2020, 1:42:48 PM. +You can check out the [state of the schema](./schema.prisma) after the migration. + +## Database Steps + +```sql +ALTER TABLE "public"."TestRun" ADD COLUMN "comment" text ; + +ALTER TABLE "public"."TestVariation" ADD COLUMN "comment" text ; +``` + +## Changes + +```diff +diff --git schema.prisma schema.prisma +migration 20200526195312-approved-test-status-added..20200627134248-comment-added +--- datamodel.dml ++++ datamodel.dml +@@ -3,9 +3,9 @@ + } + datasource db { + provider = "postgresql" +- url = "***" ++ url = env("DATABASE_URL") + } + model Build { + id String @default(uuid()) @id +@@ -51,9 +51,9 @@ + os String? + viewport String? + baselineName String? + ignoreAreas String @default("[]") +- // Baseline ++ comment String? + baseline Baseline? + } + model TestVariation { +@@ -68,8 +68,9 @@ + projectId String + project Project @relation(fields: [projectId], references: [id]) + testRuns TestRun[] + baselines Baseline[] ++ comment String? + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) + } +@@ -102,5 +103,5 @@ + new + ok + unresolved + approved +-} ++} +``` + + diff --git a/prisma/migrations/20200627134248-comment-added/schema.prisma b/prisma/migrations/20200627134248-comment-added/schema.prisma new file mode 100644 index 00000000..bea33676 --- /dev/null +++ b/prisma/migrations/20200627134248-comment-added/schema.prisma @@ -0,0 +1,107 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = "***" +} + +model Build { + id String @default(uuid()) @id + 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? +} + +model Project { + id String @default(uuid()) @id + name String + builds Build[] + testVariations TestVariation[] + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) +} + +model TestRun { + id String @default(uuid()) @id + imageName String + diffName String? + diffPercent Float? + diffTollerancePercent Float @default(1.0) + pixelMisMatchCount Int? + status TestStatus + buildId String + build Build @relation(fields: [buildId], references: [id]) + testVariationId String + testVariation TestVariation @relation(fields: [testVariationId], references: [id]) + 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? +} + +model TestVariation { + id String @default(uuid()) @id + name String + 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()) +} + +model Baseline { + id String @default(uuid()) @id + 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 @default(uuid()) @id + 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/20200627134248-comment-added/steps.json b/prisma/migrations/20200627134248-comment-added/steps.json new file mode 100644 index 00000000..83e518f1 --- /dev/null +++ b/prisma/migrations/20200627134248-comment-added/steps.json @@ -0,0 +1,19 @@ +{ + "version": "0.3.14-fixed", + "steps": [ + { + "tag": "CreateField", + "model": "TestRun", + "field": "comment", + "type": "String", + "arity": "Optional" + }, + { + "tag": "CreateField", + "model": "TestVariation", + "field": "comment", + "type": "String", + "arity": "Optional" + } + ] +} \ No newline at end of file diff --git a/prisma/migrations/migrate.lock b/prisma/migrations/migrate.lock index aab02fd3..763eff37 100644 --- a/prisma/migrations/migrate.lock +++ b/prisma/migrations/migrate.lock @@ -1,8 +1,6 @@ -# IF THERE'S A GIT CONFLICT IN THIS FILE, DON'T SOLVE IT MANUALLY! -# INSTEAD EXECUTE `prisma migrate fix` # Prisma Migrate lockfile v1 -# Read more about conflict resolution here: TODO 20200503001556-init 20200524162125-baseline-history -20200526195312-approved-test-status-added \ No newline at end of file +20200526195312-approved-test-status-added +20200627134248-comment-added \ No newline at end of file diff --git a/prisma/package.json b/prisma/package.json index d9c7b7f7..a75bd155 100644 --- a/prisma/package.json +++ b/prisma/package.json @@ -1,6 +1,6 @@ { "name": "vrt-migration", - "version": "1.1.3", + "version": "1.2.0", "description": "", "author": "", "private": true, diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 51fd79bf..158328b4 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -52,7 +52,7 @@ model TestRun { viewport String? baselineName String? ignoreAreas String @default("[]") - // Baseline + comment String? baseline Baseline? } @@ -69,6 +69,7 @@ model TestVariation { project Project @relation(fields: [projectId], references: [id]) testRuns TestRun[] baselines Baseline[] + comment String? updatedAt DateTime @updatedAt createdAt DateTime @default(now()) } @@ -103,4 +104,4 @@ enum TestStatus { ok unresolved approved -} \ No newline at end of file +} diff --git a/src/builds/builds.service.spec.ts b/src/builds/builds.service.spec.ts index 117459da..a963f567 100644 --- a/src/builds/builds.service.spec.ts +++ b/src/builds/builds.service.spec.ts @@ -84,6 +84,7 @@ describe('BuildsService', () => { viewport: '1800x1600', baselineName: null, ignoreAreas: '[]', + comment: 'some comment', }, ], }; diff --git a/src/builds/dto/build.dto.spec.ts b/src/builds/dto/build.dto.spec.ts index 770aba69..8f632937 100644 --- a/src/builds/dto/build.dto.spec.ts +++ b/src/builds/dto/build.dto.spec.ts @@ -53,7 +53,9 @@ describe('BuildDto', () => { }); it('passed', () => { - const build = { + const build: Build & { + testRuns: TestRun[]; + } = { id: 'a9385fc1-884d-4f9f-915e-40da0e7773d5', number: null, branchName: 'develop', @@ -82,6 +84,7 @@ describe('BuildDto', () => { viewport: '1800x1600', baselineName: null, ignoreAreas: '[]', + comment: 'some comment1', }, { id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', @@ -102,6 +105,7 @@ describe('BuildDto', () => { viewport: '1800x1600', baselineName: null, ignoreAreas: '[]', + comment: 'some comment2', }, ], }; @@ -154,6 +158,7 @@ describe('BuildDto', () => { viewport: '1800x1600', baselineName: null, ignoreAreas: '[]', + comment: 'some comment', }, { id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', @@ -174,6 +179,7 @@ describe('BuildDto', () => { viewport: '1800x1600', baselineName: null, ignoreAreas: '[]', + comment: 'some comment1', }, { id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', @@ -194,6 +200,7 @@ describe('BuildDto', () => { viewport: '1800x1600', baselineName: null, ignoreAreas: '[]', + comment: 'some comment2', }, ], }; @@ -246,6 +253,7 @@ describe('BuildDto', () => { viewport: '1800x1600', baselineName: null, ignoreAreas: '[]', + comment: 'some comment1', }, { id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', @@ -266,6 +274,7 @@ describe('BuildDto', () => { viewport: '1800x1600', baselineName: null, ignoreAreas: '[]', + comment: 'some comment2', }, { id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', @@ -286,6 +295,7 @@ describe('BuildDto', () => { viewport: '1800x1600', baselineName: null, ignoreAreas: '[]', + comment: null, }, { id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', @@ -306,6 +316,7 @@ describe('BuildDto', () => { viewport: '1800x1600', baselineName: null, ignoreAreas: '[]', + comment: 'some comment', }, { id: '10fb5e02-64e0-4cf5-9f17-c00ab3c96658', @@ -326,6 +337,7 @@ describe('BuildDto', () => { viewport: '1800x1600', baselineName: null, ignoreAreas: '[]', + comment: 'some comment', }, ], }; diff --git a/src/shared/dto/comment.dto.ts b/src/shared/dto/comment.dto.ts new file mode 100644 index 00000000..fe0f9c65 --- /dev/null +++ b/src/shared/dto/comment.dto.ts @@ -0,0 +1,8 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsString } from 'class-validator'; + +export class CommentDto { + @ApiProperty() + @IsString() + comment: string; +} diff --git a/src/test-runs/test-runs.controller.ts b/src/test-runs/test-runs.controller.ts index 2fb3f539..02447bfa 100644 --- a/src/test-runs/test-runs.controller.ts +++ b/src/test-runs/test-runs.controller.ts @@ -4,60 +4,69 @@ import { JwtAuthGuard } from '../auth/guards/auth.guard'; import { TestRun } from '@prisma/client'; import { TestRunsService } from './test-runs.service'; import { IgnoreAreaDto } from '../test/dto/ignore-area.dto'; +import { CommentDto } from '../shared/dto/comment.dto'; @ApiTags('test-runs') @Controller('test-runs') export class TestRunsController { - constructor(private testRunsService: TestRunsService) { } - - @Get() - @ApiQuery({ name: 'buildId', required: true }) - @ApiBearerAuth() - @UseGuards(JwtAuthGuard) - get(@Query('buildId', new ParseUUIDPipe()) buildId: string): Promise { - return this.testRunsService.findMany(buildId); - } - - @Get('recalculateDiff/:id') - @ApiParam({ name: 'id', required: true }) - @ApiBearerAuth() - @UseGuards(JwtAuthGuard) - recalculateDiff(@Param('id', new ParseUUIDPipe()) id: string): Promise { - return this.testRunsService.recalculateDiff(id); - } - - @Get('approve/:id') - @ApiParam({ name: 'id', required: true }) - @ApiBearerAuth() - @UseGuards(JwtAuthGuard) - approveTestRun(@Param('id', new ParseUUIDPipe()) id: string): Promise { - return this.testRunsService.approve(id); - } - - @Get('reject/:id') - @ApiParam({ name: 'id', required: true }) - @ApiBearerAuth() - @UseGuards(JwtAuthGuard) - rejectTestRun(@Param('id', new ParseUUIDPipe()) id: string): Promise { - return this.testRunsService.reject(id); - } - - @Delete('/:id') - @ApiParam({ name: 'id', required: true }) - @ApiBearerAuth() - @UseGuards(JwtAuthGuard) - deleteTestRun(@Param('id', new ParseUUIDPipe()) id: string): Promise { - return this.testRunsService.delete(id); - } - - @Put('ignoreArea/:testRunId') - @ApiParam({ name: 'testRunId', required: true }) - @ApiBearerAuth() - @UseGuards(JwtAuthGuard) - updateIgnoreAreas( - @Param('testRunId', new ParseUUIDPipe()) testRunId: string, - @Body() ignoreAreas: IgnoreAreaDto[], - ): Promise { - return this.testRunsService.updateIgnoreAreas(testRunId, ignoreAreas); - } + constructor(private testRunsService: TestRunsService) {} + + @Get() + @ApiQuery({ name: 'buildId', required: true }) + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + get(@Query('buildId', new ParseUUIDPipe()) buildId: string): Promise { + return this.testRunsService.findMany(buildId); + } + + @Get('recalculateDiff/:id') + @ApiParam({ name: 'id', required: true }) + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + recalculateDiff(@Param('id', new ParseUUIDPipe()) id: string): Promise { + return this.testRunsService.recalculateDiff(id); + } + + @Get('approve/:id') + @ApiParam({ name: 'id', required: true }) + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + approveTestRun(@Param('id', new ParseUUIDPipe()) id: string): Promise { + return this.testRunsService.approve(id); + } + + @Get('reject/:id') + @ApiParam({ name: 'id', required: true }) + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + rejectTestRun(@Param('id', new ParseUUIDPipe()) id: string): Promise { + return this.testRunsService.reject(id); + } + + @Delete('/:id') + @ApiParam({ name: 'id', required: true }) + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + deleteTestRun(@Param('id', new ParseUUIDPipe()) id: string): Promise { + return this.testRunsService.delete(id); + } + + @Put('ignoreArea/:testRunId') + @ApiParam({ name: 'testRunId', required: true }) + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + updateIgnoreAreas( + @Param('testRunId', new ParseUUIDPipe()) testRunId: string, + @Body() ignoreAreas: IgnoreAreaDto[] + ): Promise { + return this.testRunsService.updateIgnoreAreas(testRunId, ignoreAreas); + } + + @Put('comment/:testRunId') + @ApiParam({ name: 'testRunId', required: true }) + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + updateComment(@Param('testRunId', new ParseUUIDPipe()) id: string, @Body() body: CommentDto): Promise { + return this.testRunsService.updateComment(id, body); + } } diff --git a/src/test-runs/test-runs.service.spec.ts b/src/test-runs/test-runs.service.spec.ts index 5fb67b5a..479e985f 100644 --- a/src/test-runs/test-runs.service.spec.ts +++ b/src/test-runs/test-runs.service.spec.ts @@ -10,6 +10,7 @@ import { CreateTestRequestDto } from '../test/dto/create-test-request.dto'; import { DiffResult } from './diffResult'; import { IgnoreAreaDto } from '../test/dto/ignore-area.dto'; import { EventsGateway } from '../events/events.gateway'; +import { CommentDto } from '../shared/dto/comment.dto'; jest.mock('pixelmatch'); @@ -195,6 +196,7 @@ describe('TestRunsService', () => { viewport: 'viewport', device: 'device', ignoreAreas: '[]', + comment: 'some comment', createdAt: new Date(), updatedAt: new Date(), }; @@ -253,6 +255,7 @@ describe('TestRunsService', () => { viewport: testVariation.viewport, baselineName: testVariation.baselineName, ignoreAreas: testVariation.ignoreAreas, + comment: testVariation.comment, diffTollerancePercent: createTestRequestDto.diffTollerancePercent, status: TestStatus.new, }, @@ -533,4 +536,24 @@ describe('TestRunsService', () => { }, }); }); + + it('updateComment', async () => { + const id = 'some id'; + const commentDto: CommentDto = { + comment: 'random comment', + }; + const testRunUpdateMock = jest.fn(); + service = await initService({ + testRunUpdateMock, + }); + + await service.updateComment(id, commentDto); + + expect(testRunUpdateMock).toHaveBeenCalledWith({ + where: { id }, + data: { + comment: commentDto.comment, + }, + }); + }); }); diff --git a/src/test-runs/test-runs.service.ts b/src/test-runs/test-runs.service.ts index 448e7456..092464b7 100644 --- a/src/test-runs/test-runs.service.ts +++ b/src/test-runs/test-runs.service.ts @@ -8,6 +8,7 @@ import { PrismaService } from '../prisma/prisma.service'; import { TestRun, TestStatus, TestVariation } from '@prisma/client'; import { DiffResult } from './diffResult'; import { EventsGateway } from '../events/events.gateway'; +import { CommentDto } from 'src/shared/dto/comment.dto'; @Injectable() export class TestRunsService { @@ -125,6 +126,7 @@ export class TestRunsService { viewport: testVariation.viewport, baselineName: testVariation.baselineName, ignoreAreas: testVariation.ignoreAreas, + comment: testVariation.comment, diffTollerancePercent: createTestRequestDto.diffTollerancePercent, status: TestStatus.new, }, @@ -133,12 +135,7 @@ export class TestRunsService { const baseline = this.staticService.getImage(testRun.baselineName); const image = this.staticService.getImage(imageName); - const diffResult = this.getDiff( - baseline, - image, - testRun.diffTollerancePercent, - testVariation.ignoreAreas - ); + const diffResult = this.getDiff(baseline, image, testRun.diffTollerancePercent, testVariation.ignoreAreas); const testRunWithResult = await this.saveDiffResult(testRun.id, diffResult); this.eventsGateway.newTestRun(testRunWithResult); @@ -164,6 +161,15 @@ export class TestRunsService { }); } + async updateComment(id: string, commentDto: CommentDto): Promise { + return this.prismaService.testRun.update({ + where: { id }, + data: { + comment: commentDto.comment, + }, + }); + } + getDiff(baseline: PNG, image: PNG, diffTollerancePercent: number, ignoreAreas: string): DiffResult { const result: DiffResult = { status: undefined, diff --git a/src/test-variations/test-variations.controller.ts b/src/test-variations/test-variations.controller.ts index d23e9622..9b2c9678 100644 --- a/src/test-variations/test-variations.controller.ts +++ b/src/test-variations/test-variations.controller.ts @@ -5,21 +5,20 @@ import { TestVariation, Baseline } from '@prisma/client'; import { JwtAuthGuard } from '../auth/guards/auth.guard'; import { PrismaService } from '../prisma/prisma.service'; import { IgnoreAreaDto } from '../test/dto/ignore-area.dto'; +import { CommentDto } from '../shared/dto/comment.dto'; @ApiTags('test-variations') @Controller('test-variations') export class TestVariationsController { - constructor(private testVariations: TestVariationsService, private prismaService: PrismaService) { } + constructor(private testVariations: TestVariationsService, private prismaService: PrismaService) {} @Get() @ApiQuery({ name: 'projectId', required: true }) @ApiBearerAuth() @UseGuards(JwtAuthGuard) - getList( - @Query('projectId', new ParseUUIDPipe()) projectId, - ): Promise { + getList(@Query('projectId', new ParseUUIDPipe()) projectId): Promise { return this.prismaService.testVariation.findMany({ - where: { projectId } + where: { projectId }, }); } @@ -27,9 +26,7 @@ export class TestVariationsController { @ApiQuery({ name: 'id', required: true }) @ApiBearerAuth() @UseGuards(JwtAuthGuard) - getDetails( - @Param('id', new ParseUUIDPipe()) id, - ): Promise { + getDetails(@Param('id', new ParseUUIDPipe()) id): Promise { return this.testVariations.getDetails(id); } @@ -39,8 +36,16 @@ export class TestVariationsController { @UseGuards(JwtAuthGuard) updateIgnoreAreas( @Param('variationId', new ParseUUIDPipe()) variationId: string, - @Body() ignoreAreas: IgnoreAreaDto[], + @Body() ignoreAreas: IgnoreAreaDto[] ): Promise { return this.testVariations.updateIgnoreAreas(variationId, ignoreAreas); } + + @Put('comment/:id') + @ApiParam({ name: 'id', required: true }) + @ApiBearerAuth() + @UseGuards(JwtAuthGuard) + updateComment(@Param('id', new ParseUUIDPipe()) id: string, @Body() body: CommentDto): Promise { + return this.testVariations.updateComment(id, body); + } } diff --git a/src/test-variations/test-variations.service.spec.ts b/src/test-variations/test-variations.service.spec.ts index 01cc9982..fb059f6b 100644 --- a/src/test-variations/test-variations.service.spec.ts +++ b/src/test-variations/test-variations.service.spec.ts @@ -5,6 +5,7 @@ import { CreateTestRequestDto } from '../test/dto/create-test-request.dto'; import { StaticService } from '../shared/static/static.service'; import { IgnoreAreaDto } from 'src/test/dto/ignore-area.dto'; import { TestVariation, Baseline } from '@prisma/client'; +import { CommentDto } from '../shared/dto/comment.dto'; const initModule = async ({ imageDeleteMock = jest.fn(), @@ -13,18 +14,20 @@ const initModule = async ({ variationCreateMock = jest.fn(), variationUpdateMock = jest.fn(), variationDeleteMock = jest.fn(), - baselineDeleteMock = jest.fn() + baselineDeleteMock = jest.fn(), }) => { const module: TestingModule = await Test.createTestingModule({ providers: [ TestVariationsService, { - provide: StaticService, useValue: { - deleteImage: imageDeleteMock - } + provide: StaticService, + useValue: { + deleteImage: imageDeleteMock, + }, }, { - provide: PrismaService, useValue: { + provide: PrismaService, + useValue: { testVariation: { findOne: variationFindOneMock, findMany: variationFindManyMock, @@ -33,22 +36,22 @@ const initModule = async ({ delete: variationDeleteMock, }, baseline: { - delete: baselineDeleteMock - } - } + delete: baselineDeleteMock, + }, + }, }, ], }).compile(); return module.get(TestVariationsService); -} +}; const dataRequiredFields: CreateTestRequestDto = { buildId: 'buildId', projectId: 'projectId', name: 'Test name', - imageBase64: 'Image' -} + imageBase64: 'Image', +}; const dataAllFields: CreateTestRequestDto = { buildId: 'buildId', @@ -59,18 +62,18 @@ const dataAllFields: CreateTestRequestDto = { browser: 'browser', viewport: 'viewport', device: 'device', -} +}; describe('TestVariationsService', () => { let service: TestVariationsService; describe('getDetails', () => { it('can find one', async () => { - const id = 'test id' - const variationFindOneMock = jest.fn() - service = await initModule({ variationFindOneMock }) + const id = 'test id'; + const variationFindOneMock = jest.fn(); + service = await initModule({ variationFindOneMock }); - await service.getDetails(id) + await service.getDetails(id); expect(variationFindOneMock).toHaveBeenCalledWith({ where: { id }, @@ -80,22 +83,21 @@ describe('TestVariationsService', () => { testRun: true, }, orderBy: { - createdAt: 'desc' - } + createdAt: 'desc', + }, }, - } - }) - }) - }) + }, + }); + }); + }); describe('findOrCreate', () => { - it('can find by required fields', async () => { - const data = dataRequiredFields - const variationFindManyMock = jest.fn() - service = await initModule({ variationFindManyMock: variationFindManyMock.mockResolvedValueOnce([data]) }) + const data = dataRequiredFields; + const variationFindManyMock = jest.fn(); + service = await initModule({ variationFindManyMock: variationFindManyMock.mockResolvedValueOnce([data]) }); - const result = await service.findOrCreate(data) + const result = await service.findOrCreate(data); expect(variationFindManyMock).toHaveBeenCalledWith({ where: { @@ -106,16 +108,16 @@ describe('TestVariationsService', () => { viewport: null, device: null, }, - }) - expect(result).toBe(data) - }) + }); + expect(result).toBe(data); + }); it('can find by all fields', async () => { - const data = dataAllFields - const variationFindManyMock = jest.fn() - service = await initModule({ variationFindManyMock: variationFindManyMock.mockResolvedValueOnce([data]) }) + const data = dataAllFields; + const variationFindManyMock = jest.fn(); + service = await initModule({ variationFindManyMock: variationFindManyMock.mockResolvedValueOnce([data]) }); - const result = await service.findOrCreate(data) + const result = await service.findOrCreate(data); expect(variationFindManyMock).toHaveBeenCalledWith({ where: { @@ -126,16 +128,16 @@ describe('TestVariationsService', () => { viewport: data.viewport, device: data.device, }, - }) - expect(result).toBe(data) - }) + }); + expect(result).toBe(data); + }); it('can create if not found', async () => { - const data = dataAllFields - const variationCreateMock = jest.fn() - service = await initModule({ variationCreateMock: variationCreateMock.mockResolvedValueOnce(data) }) + const data = dataAllFields; + const variationCreateMock = jest.fn(); + service = await initModule({ variationCreateMock: variationCreateMock.mockResolvedValueOnce(data) }); - const result = await service.findOrCreate(data) + const result = await service.findOrCreate(data); expect(variationCreateMock).toHaveBeenCalledWith({ data: { @@ -147,44 +149,44 @@ describe('TestVariationsService', () => { project: { connect: { id: data.projectId, - } - } + }, + }, }, - }) - expect(result).toBe(data) - }) - }) + }); + expect(result).toBe(data); + }); + }); describe('updateIgnoreAreas', () => { it('can update', async () => { - const id = 'test id' + const id = 'test id'; const ignoreAreas: IgnoreAreaDto[] = [ { x: 1, y: 2.3, width: 442.1, - height: 32.0 - } - ] - const variationUpdateMock = jest.fn() - service = await initModule({ variationUpdateMock }) + height: 32.0, + }, + ]; + const variationUpdateMock = jest.fn(); + service = await initModule({ variationUpdateMock }); - await service.updateIgnoreAreas(id, ignoreAreas) + await service.updateIgnoreAreas(id, ignoreAreas); expect(variationUpdateMock).toBeCalledWith({ where: { - id + id, }, data: { - ignoreAreas: JSON.stringify(ignoreAreas) - } - }) - }) - }) + ignoreAreas: JSON.stringify(ignoreAreas), + }, + }); + }); + }); describe('remove', () => { it('can remove', async () => { - const id = 'test id' + const id = 'test id'; const variation: TestVariation & { baselines: Baseline[]; } = { @@ -197,6 +199,7 @@ describe('TestVariationsService', () => { viewport: 'viewport', device: 'device', ignoreAreas: '[]', + comment: 'some comment', createdAt: new Date(), updatedAt: new Date(), baselines: [ @@ -208,31 +211,48 @@ describe('TestVariationsService', () => { createdAt: new Date(), updatedAt: new Date(), }, - ] - } - const variationFindOneMock = jest.fn() - const variationDeleteMock = jest.fn() - const imageDeleteMock = jest.fn() - const baselineDeleteMock = jest.fn() - service = await initModule( - { - variationFindOneMock: variationFindOneMock.mockResolvedValueOnce(variation), - variationDeleteMock, - imageDeleteMock, - baselineDeleteMock - }) + ], + }; + const variationFindOneMock = jest.fn(); + const variationDeleteMock = jest.fn(); + const imageDeleteMock = jest.fn(); + const baselineDeleteMock = jest.fn(); + service = await initModule({ + variationFindOneMock: variationFindOneMock.mockResolvedValueOnce(variation), + variationDeleteMock, + imageDeleteMock, + baselineDeleteMock, + }); - await service.remove(id) + await service.remove(id); - expect(imageDeleteMock).toHaveBeenCalledWith( - variation.baselines[0].baselineName - ) + expect(imageDeleteMock).toHaveBeenCalledWith(variation.baselines[0].baselineName); expect(baselineDeleteMock).toHaveBeenCalledWith({ - where: { id: variation.baselines[0].id } - }) + where: { id: variation.baselines[0].id }, + }); expect(variationDeleteMock).toHaveBeenCalledWith({ - where: { id: variation.id } - }) - }) - }) + where: { id: variation.id }, + }); + }); + }); + + it('updateComment', async () => { + const id = 'some id'; + const commentDto: CommentDto = { + comment: 'random comment', + }; + const variationUpdateMock = jest.fn(); + service = await initModule({ + variationUpdateMock, + }); + + await service.updateComment(id, commentDto); + + expect(variationUpdateMock).toHaveBeenCalledWith({ + where: { id }, + data: { + comment: commentDto.comment, + }, + }); + }); }); diff --git a/src/test-variations/test-variations.service.ts b/src/test-variations/test-variations.service.ts index 0e698f02..24a71842 100644 --- a/src/test-variations/test-variations.service.ts +++ b/src/test-variations/test-variations.service.ts @@ -4,13 +4,11 @@ import { IgnoreAreaDto } from '../test/dto/ignore-area.dto'; import { PrismaService } from '../prisma/prisma.service'; import { TestVariation, Baseline } from '@prisma/client'; import { StaticService } from '../shared/static/static.service'; +import { CommentDto } from '../shared/dto/comment.dto'; @Injectable() export class TestVariationsService { - constructor( - private prismaService: PrismaService, - private staticService: StaticService, - ) { } + constructor(private prismaService: PrismaService, private staticService: StaticService) {} async getDetails(id: string): Promise { return this.prismaService.testVariation.findOne({ @@ -21,8 +19,8 @@ export class TestVariationsService { testRun: true, }, orderBy: { - createdAt: 'desc' - } + createdAt: 'desc', + }, }, }, }); @@ -56,30 +54,40 @@ export class TestVariationsService { } async updateIgnoreAreas(id: string, ignoreAreas: IgnoreAreaDto[]): Promise { - return this.prismaService.testVariation - .update({ - where: { id }, - data: { - ignoreAreas: JSON.stringify(ignoreAreas), - }, - }); + return this.prismaService.testVariation.update({ + where: { id }, + data: { + ignoreAreas: JSON.stringify(ignoreAreas), + }, + }); + } + + async updateComment(id: string, commentDto: CommentDto): Promise { + return this.prismaService.testVariation.update({ + where: { id }, + data: { + comment: commentDto.comment, + }, + }); } async remove(id: string): Promise { - const variation = await this.getDetails(id) + const variation = await this.getDetails(id); // clear history try { await Promise.all( - variation.baselines.map(baseline => Promise.all([ - this.staticService.deleteImage(baseline.baselineName), - this.prismaService.baseline.delete({ - where: { id: baseline.id } - }) - ])) - ) + variation.baselines.map(baseline => + Promise.all([ + this.staticService.deleteImage(baseline.baselineName), + this.prismaService.baseline.delete({ + where: { id: baseline.id }, + }), + ]) + ) + ); } catch (err) { - console.log(err) + console.log(err); } return this.prismaService.testVariation.delete({