Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[기능] interview get #11

Merged
merged 10 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
"testEnvironment": "node",
"workerThreads": true
}
}
4 changes: 4 additions & 0 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export class AuthService {
async createInterviewer(createDTO: CreateInterviewerDTO) {
const interviewer = await this.interviewerRepository.create(createDTO);

await this.interviewerRepository
.getEntityManager()
.persistAndFlush(interviewer);

return InterviewerDTO.fromEntity(interviewer);
}
}
15 changes: 15 additions & 0 deletions src/interview/dto/createInterview.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
export class CreateInterviewDTO {
interviewerId: bigint;
reviewerId: bigint;

static from({
interviewerId,
reviewerId,
}: {
interviewerId: bigint;
reviewerId: bigint;
}) {
const interviewDTO = new CreateInterviewDTO();

interviewDTO.interviewerId = interviewerId;
interviewDTO.reviewerId = reviewerId;

return interviewDTO;
}
}
6 changes: 6 additions & 0 deletions src/interview/interview.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,10 @@ describe('InterviewController', () => {
expect(response.interviewer.id).toBe(interviewerList[0].id);
expect(response.reviewer.id).toBe(reviewerList[0].id);
});

it('interview 조회', async () => {
const response = await controller.findAll();

expect(response.length).toBe(1);
});
});
7 changes: 6 additions & 1 deletion src/interview/interview.controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Body, Controller, Post } from '@nestjs/common';
import { Body, Controller, Get, Post } from '@nestjs/common';
import { InterviewService } from './interview.service';
import { CreateInterviewDTO } from './dto/createInterview.dto';

Expand All @@ -10,4 +10,9 @@ export class InterviewController {
create(@Body() createDTO: CreateInterviewDTO) {
return this.interviewService.create(createDTO);
}

@Get()
findAll() {
return this.interviewService.findAll();
}
}
85 changes: 76 additions & 9 deletions src/interview/interview.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getRepositoryToken, MikroOrmModule } from '@mikro-orm/nestjs';
import { Reviewer } from '../entities/reviewer';
import { testConfig } from '../mikro-orm.config';
import { Interview } from '../entities/interview';
import { EntityRepository, MikroORM } from '@mikro-orm/sqlite';
import { EntityRepository, MikroORM, NotFoundError } from '@mikro-orm/sqlite';
import { plainToInstance } from 'class-transformer';
import { Interviewer } from '../entities/interviewer';
import { REVIEWER_LIST } from '../../test/fixture/reviewers.common';
Expand Down Expand Up @@ -62,16 +62,83 @@ describe('InterviewService', () => {
expect(service).toBeDefined();
});

it('interviewer 생성', async () => {
const createDTO = plainToInstance(CreateInterviewDTO, {
reviewerId: reviewerList[0].id,
interviewerId: interviewerList[0].id,
describe('interview 생성', () => {
it('정상 요청에 대해서 생성', async () => {
const createDTO = plainToInstance(CreateInterviewDTO, {
reviewerId: reviewerList[0].id,
interviewerId: interviewerList[0].id,
});

const response = await service.create(createDTO);

expect(response).toBeInstanceOf(Interview);
expect(response.interviewer.id).toBe(interviewerList[0].id);
expect(response.reviewer.id).toBe(reviewerList[0].id);
});

it('reviewerId가 유효하지 않으면 에러 발생', async () => {
const createDTO = plainToInstance(CreateInterviewDTO, {
reviewerId: null,
interviewerId: interviewerList[0].id,
});

await expect(async () => await service.create(createDTO)).rejects.toThrow(
NotFoundError,
);
});

it('interviewerId가 유효하지 않으면 에러 발생', async () => {
const createDTO = plainToInstance(CreateInterviewDTO, {
reviewerId: reviewerList[0].id,
interviewerId: null,
});

await expect(async () => await service.create(createDTO)).rejects.toThrow(
NotFoundError,
);
});
});

describe('interview 조회', () => {
it('0개일 경우 빈 array 조회', async () => {
const response = await service.findAll();

expect(response.length).toBe(0);
});

const response = await service.create(createDTO);
it('1개일 경우 조회 가능', async () => {
const interview = await service.create(
CreateInterviewDTO.from({
reviewerId: reviewerList[0].id,
interviewerId: interviewerList[0].id,
}),
);

expect(response).toBeInstanceOf(Interview);
expect(response.interviewer.id).toBe(interviewerList[0].id);
expect(response.reviewer.id).toBe(reviewerList[0].id);
const response = await service.findAll();

expect(response.length).toBe(1);
expect(response.map((item) => item.id)).toContain(interview.id);
});

it('interviewer에 관계없이 전체가 조회된다.', async () => {
await Promise.all([
service.create(
CreateInterviewDTO.from({
reviewerId: reviewerList[0].id,
interviewerId: interviewerList[0].id,
}),
),
service.create(
CreateInterviewDTO.from({
reviewerId: reviewerList[0].id,
interviewerId: interviewerList[1].id,
}),
),
]);

const response = await service.findAll();

expect(response.length).toBe(2);
});
});
});
13 changes: 12 additions & 1 deletion src/interview/interview.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,21 @@ export class InterviewService {
}),
]);

return this.interviewRepository.create({
const newEntity = this.interviewRepository.create({
title: 'test',
status: 'created',
interviewer,
reviewer,
});

await this.interviewerRepository
.getEntityManager()
.persistAndFlush(newEntity);

return newEntity;
}

findAll() {
return this.interviewRepository.findAll();
}
}
18 changes: 18 additions & 0 deletions test/fixture/interview.common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { INestApplication } from '@nestjs/common';
import { CreateInterviewDTO } from '../../src/interview/dto/createInterview.dto';
import * as request from 'supertest';

export class InterviewFixture {
constructor(private readonly app: INestApplication) {}

create(dto: CreateInterviewDTO) {
return request(this.app.getHttpServer())
.post('/interview')
.send(dto)
.expect(201);
}

getAll() {
return request(this.app.getHttpServer()).get('/interview').expect(200);
}
}
34 changes: 27 additions & 7 deletions test/interview.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { REVIEWER_LIST } from './fixture/reviewers.common';
import { MikroORM } from '@mikro-orm/sqlite';
import { Interviewer } from '../src/entities/interviewer';
import { INTERVIEWER_LIST } from './fixture/interviewer.common';
import { InterviewFixture } from './fixture/interview.common';
import { CreateInterviewDTO } from '../src/interview/dto/createInterview.dto';

describe('ReviewerController (e2e)', () => {
let app: INestApplication;
Expand All @@ -19,6 +21,8 @@ describe('ReviewerController (e2e)', () => {
let reviewerList: Reviewer[];
let interviewerList: Interviewer[];

let interviewFixture: InterviewFixture;

beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
Expand All @@ -40,6 +44,8 @@ describe('ReviewerController (e2e)', () => {
interviewerRepository = moduleFixture.get<EntityRepository<Interviewer>>(
getRepositoryToken(Interviewer),
);

interviewFixture = new InterviewFixture(app);
});

beforeEach(async () => {
Expand All @@ -61,18 +67,32 @@ describe('ReviewerController (e2e)', () => {

describe('/interviewer (POST)', () => {
it('interview 생성에 성공한다.', async () => {
const response = await request(app.getHttpServer())
.post('/interview')
.send({
const response = await interviewFixture.create(
CreateInterviewDTO.from({
interviewerId: interviewerList[0].id,
reviewerId: reviewerList[0].id,
})
.expect(201);
}),
);

expect(response.body.reviewer).toEqual(reviewerList[0].id.toString());
expect(response.body.interviewer).toEqual(
expect(response.body.reviewer.id).toEqual(reviewerList[0].id.toString());
expect(response.body.interviewer.id).toEqual(
interviewerList[0].id.toString(),
);
});
});

describe('/interviewer (GET)', () => {
it('interview 조회에 성공한다.', async () => {
await interviewFixture.create(
CreateInterviewDTO.from({
interviewerId: interviewerList[0].id,
reviewerId: reviewerList[0].id,
}),
);

const response = await interviewFixture.getAll();

expect(response.body.length).toEqual(1);
});
});
});