Skip to content

Commit 7db3a10

Browse files
authored
Merge pull request #14 from Visual-Regression-Tracker/54-project-name
Allow to use project name for build creation
2 parents d51ec9b + 250201e commit 7db3a10

File tree

5 files changed

+94
-29
lines changed

5 files changed

+94
-29
lines changed

src/builds/builds.service.spec.ts

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import { PrismaService } from '../prisma/prisma.service';
44
import { TestRunsService } from '../test-runs/test-runs.service';
55
import { EventsGateway } from '../events/events.gateway';
66
import { CreateBuildDto } from './dto/build-create.dto';
7-
import { Build, TestRun } from '@prisma/client';
7+
import { Build, TestRun, Project } from '@prisma/client';
88
import { mocked } from 'ts-jest/utils';
99
import { BuildDto } from './dto/build.dto';
10+
import { HttpException, HttpStatus } from '@nestjs/common';
1011

1112
jest.mock('./dto/build.dto');
1213

@@ -17,13 +18,17 @@ const initService = async ({
1718
buildDeleteMock = jest.fn(),
1819
testRunDeleteMock = jest.fn(),
1920
eventsBuildCreatedMock = jest.fn(),
21+
projectFindManyMock = jest.fn(),
2022
}) => {
2123
const module: TestingModule = await Test.createTestingModule({
2224
providers: [
2325
BuildsService,
2426
{
2527
provide: PrismaService,
2628
useValue: {
29+
project: {
30+
findMany: projectFindManyMock,
31+
},
2732
build: {
2833
findMany: buildFindManyMock,
2934
create: buildCreateMock,
@@ -119,30 +124,54 @@ describe('BuildsService', () => {
119124
expect(result).toEqual([buildDto]);
120125
});
121126

122-
it('create', async () => {
127+
describe('create', () => {
123128
const createBuildDto: CreateBuildDto = {
124129
branchName: 'branchName',
125-
projectId: 'projectId',
130+
project: 'project id or name',
126131
};
127-
const buildCreateMock = jest.fn().mockResolvedValueOnce(build);
128-
const eventsBuildCreatedMock = jest.fn();
129-
mocked(BuildDto).mockReturnValueOnce(buildDto);
130-
service = await initService({ buildCreateMock, eventsBuildCreatedMock });
131132

132-
const result = await service.create(createBuildDto);
133+
it('should create', async () => {
134+
const project: Project = {
135+
id: 'project id',
136+
name: 'name',
137+
updatedAt: new Date(),
138+
createdAt: new Date(),
139+
};
140+
const buildCreateMock = jest.fn().mockResolvedValueOnce(build);
141+
const projectFindManyMock = jest.fn().mockResolvedValueOnce([project]);
142+
const eventsBuildCreatedMock = jest.fn();
143+
mocked(BuildDto).mockReturnValueOnce(buildDto);
144+
service = await initService({ buildCreateMock, eventsBuildCreatedMock, projectFindManyMock });
145+
146+
const result = await service.create(createBuildDto);
133147

134-
expect(buildCreateMock).toHaveBeenCalledWith({
135-
data: {
136-
branchName: createBuildDto.branchName,
137-
project: {
138-
connect: {
139-
id: createBuildDto.projectId,
148+
expect(projectFindManyMock).toHaveBeenCalledWith({
149+
where: {
150+
OR: [{ id: createBuildDto.project }, { name: createBuildDto.project }],
151+
},
152+
});
153+
expect(buildCreateMock).toHaveBeenCalledWith({
154+
data: {
155+
branchName: createBuildDto.branchName,
156+
project: {
157+
connect: {
158+
id: project.id,
159+
},
140160
},
141161
},
142-
},
162+
});
163+
expect(eventsBuildCreatedMock).toHaveBeenCalledWith(buildDto);
164+
expect(result).toBe(buildDto);
165+
});
166+
167+
it('should throw exception if not found', async () => {
168+
const projectFindManyMock = jest.fn().mockResolvedValueOnce([]);
169+
service = await initService({ projectFindManyMock });
170+
171+
await expect(service.create(createBuildDto)).rejects.toThrowError(
172+
new HttpException('Project not found', HttpStatus.NOT_FOUND)
173+
);
143174
});
144-
expect(eventsBuildCreatedMock).toHaveBeenCalledWith(buildDto);
145-
expect(result).toBe(buildDto);
146175
});
147176

148177
it('delete', async () => {

src/builds/builds.service.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Injectable } from '@nestjs/common';
1+
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
22
import { CreateBuildDto } from './dto/build-create.dto';
33
import { PrismaService } from '../prisma/prisma.service';
44
import { Build } from '@prisma/client';
@@ -27,12 +27,22 @@ export class BuildsService {
2727
}
2828

2929
async create(createBuildDto: CreateBuildDto): Promise<BuildDto> {
30+
const projects = await this.prismaService.project.findMany({
31+
where: {
32+
OR: [{ id: createBuildDto.project }, { name: createBuildDto.project }],
33+
},
34+
});
35+
36+
if (projects.length <= 0) {
37+
throw new HttpException(`Project not found`, HttpStatus.NOT_FOUND);
38+
}
39+
3040
const build = await this.prismaService.build.create({
3141
data: {
3242
branchName: createBuildDto.branchName,
3343
project: {
3444
connect: {
35-
id: createBuildDto.projectId,
45+
id: projects[0].id,
3646
},
3747
},
3848
},

src/builds/dto/build-create.dto.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { ApiProperty } from '@nestjs/swagger';
2-
import { IsString, IsUUID } from 'class-validator';
2+
import { IsString, IsUUID, IsOptional } from 'class-validator';
33

44
export class CreateBuildDto {
55
@ApiProperty()
66
@IsString()
77
readonly branchName: string;
88

99
@ApiProperty()
10-
@IsUUID()
11-
readonly projectId: string;
10+
@IsString()
11+
readonly project: string;
1212
}

src/prisma/prisma.service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import { PrismaClient } from '@prisma/client';
44
@Injectable()
55
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
66
constructor() {
7-
super();
7+
super({
8+
// log: [{ emit: 'stdout', level: 'query' }],
9+
});
810
}
911
async onModuleInit() {
1012
await this.connect();

test/builds.e2e-spec.ts

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ describe('Builds (e2e)', () => {
4545
});
4646

4747
describe('POST /', () => {
48-
it('201', () => {
48+
it('201 by id', () => {
4949
const createBuildDto: CreateBuildDto = {
5050
branchName: 'branchName',
51-
projectId: project.id,
51+
project: project.id,
5252
};
5353
return requestWithApiKey(app, 'post', '/builds', createBuildDto, user.apiKey)
5454
.expect(201)
@@ -61,18 +61,42 @@ describe('Builds (e2e)', () => {
6161
});
6262
});
6363

64+
it('201 by name', () => {
65+
const createBuildDto: CreateBuildDto = {
66+
branchName: 'branchName',
67+
project: project.name,
68+
};
69+
return requestWithApiKey(app, 'post', '/builds', createBuildDto, user.apiKey)
70+
.expect(201)
71+
.expect(res => {
72+
expect(res.body.projectId).toBe(project.id);
73+
expect(res.body.branchName).toBe(createBuildDto.branchName);
74+
expect(res.body.failedCount).toBe(0);
75+
expect(res.body.passedCount).toBe(0);
76+
expect(res.body.unresolvedCount).toBe(0);
77+
});
78+
});
79+
80+
it('404', () => {
81+
const createBuildDto: CreateBuildDto = {
82+
branchName: 'branchName',
83+
project: 'random',
84+
};
85+
return requestWithApiKey(app, 'post', '/builds', createBuildDto, user.apiKey).expect(404);
86+
});
87+
6488
it('403', () => {
6589
const createBuildDto: CreateBuildDto = {
6690
branchName: 'branchName',
67-
projectId: project.id,
91+
project: project.id,
6892
};
6993
return requestWithApiKey(app, 'post', '/builds', createBuildDto, '').expect(403);
7094
});
7195
});
7296

7397
describe('GET /', () => {
7498
it('200', async () => {
75-
const build = await buildsService.create({ projectId: project.id, branchName: 'develop' });
99+
const build = await buildsService.create({ project: project.id, branchName: 'develop' });
76100

77101
return requestWithAuth(app, 'get', `/builds?projectId=${project.id}`, {}, user.token)
78102
.expect(200)
@@ -88,13 +112,13 @@ describe('Builds (e2e)', () => {
88112

89113
describe('DELETE /', () => {
90114
it('200', async () => {
91-
const build = await buildsService.create({ projectId: project.id, branchName: 'develop' });
115+
const build = await buildsService.create({ project: project.id, branchName: 'develop' });
92116

93117
return requestWithAuth(app, 'delete', `/builds/${build.id}`, {}, user.token).expect(200);
94118
});
95119

96120
it('401', async () => {
97-
const build = await buildsService.create({ projectId: project.id, branchName: 'develop' });
121+
const build = await buildsService.create({ project: project.id, branchName: 'develop' });
98122

99123
return requestWithAuth(app, 'delete', `/builds/${build.id}`, {}, '').expect(401);
100124
});

0 commit comments

Comments
 (0)