From 143f39dfd2d413005ba8ad7d620cb7265c0593a3 Mon Sep 17 00:00:00 2001 From: J_Coder Date: Tue, 3 Dec 2024 03:27:14 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=E2=9C=85=20test:=20dto=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/test/rss/dto/rss-register.dto.spec.ts | 224 +++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 server/test/rss/dto/rss-register.dto.spec.ts diff --git a/server/test/rss/dto/rss-register.dto.spec.ts b/server/test/rss/dto/rss-register.dto.spec.ts new file mode 100644 index 00000000..51bffc2a --- /dev/null +++ b/server/test/rss/dto/rss-register.dto.spec.ts @@ -0,0 +1,224 @@ +import { validate } from 'class-validator'; +import { RssRegisterDto } from '../../../src/rss/dto/rss-register.dto'; + +describe('RssRegisterDto Test', () => { + let dto: RssRegisterDto; + + beforeEach(() => { + dto = new RssRegisterDto({ + blog: 'test', + name: 'test', + email: 'test@test.com', + rssUrl: 'https://test.com', + }); + }); + it('블로그 이름이 없다.', async () => { + // given + delete dto.blog; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isString', + '문자열로 입력해주세요.', + ); + }); + + it('블로그 이름이 빈 문자열이다.', async () => { + // given + dto.blog = ''; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isNotEmpty', + '블로그 이름이 없습니다.', + ); + }); + + it('블로그 이름이 문자열이 아니다.', async () => { + // given + dto.blog = 1 as unknown as string; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isString', + '문자열로 입력해주세요.', + ); + }); + + it('실명이 없다.', async () => { + // given + delete dto.name; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isString', + '문자열로 입력해주세요.', + ); + }); + + it('실명이 빈 문자열이다.', async () => { + // given + dto.name = ''; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isNotEmpty', + '실명이 없습니다.', + ); + }); + + it('실명이 문자열이 아니다.', async () => { + // given + dto.name = 1 as unknown as string; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isString', + '문자열로 입력해주세요.', + ); + }); + + it('실명의 길이가 2자리보다 작다.', async () => { + // given + dto.name = 'a'; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isLength', + '이름 길이가 올바르지 않습니다.', + ); + }); + + it('실명의 길이가 50자리보다 크다.', async () => { + // given + dto.name = 'a'.repeat(60); + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isLength', + '이름 길이가 올바르지 않습니다.', + ); + }); + + it('이메일이 없다.', async () => { + // given + delete dto.email; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isEmail', + '이메일 주소 형식에 맞춰서 작성해주세요.', + ); + }); + + it('이메일이 빈 문자열이다.', async () => { + // given + dto.email = ''; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isNotEmpty', + '이메일이 없습니다.', + ); + }); + + it('이메일 형식이 올바르지 않다.', async () => { + // given + dto.email = 'test'; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isEmail', + '이메일 주소 형식에 맞춰서 작성해주세요.', + ); + }); + + it('RSS URL이 없다.', async () => { + // given + delete dto.rssUrl; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isUrl', + 'http, https 프로토콜과 URL 형식을 맞춰주세요.', + ); + }); + + it('RSS URL이 빈 문자열이다.', async () => { + // given + dto.rssUrl = ''; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isNotEmpty', + 'RSS URL이 없습니다.', + ); + }); + + it('RSS URL 형식이 잘못되었다.', async () => { + // given + dto.rssUrl = 'http://test'; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isUrl', + 'http, https 프로토콜과 URL 형식을 맞춰주세요.', + ); + }); + + it('http, https 프로토콜을 제외한 다른 프로토콜을 입력한다.', async () => { + // given + dto.rssUrl = 'ftp://test.com'; + + // when + const errors = await validate(dto); + + // then + expect(errors[0].constraints).toHaveProperty( + 'isUrl', + 'http, https 프로토콜과 URL 형식을 맞춰주세요.', + ); + }); +}); From 00958e69fde03bbb46745875e4f25cf7ee531f58 Mon Sep 17 00:00:00 2001 From: J_Coder Date: Tue, 3 Dec 2024 03:30:43 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=E2=9C=85=20test:=20post=20rss=20API=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/test/rss/rss.e2e-spec.ts | 326 ++++---------------------------- 1 file changed, 37 insertions(+), 289 deletions(-) diff --git a/server/test/rss/rss.e2e-spec.ts b/server/test/rss/rss.e2e-spec.ts index 377c41fb..352ed286 100644 --- a/server/test/rss/rss.e2e-spec.ts +++ b/server/test/rss/rss.e2e-spec.ts @@ -1,6 +1,6 @@ import { INestApplication } from '@nestjs/common'; import { RssRegisterDto } from '../../src/rss/dto/rss-register.dto'; -import * as request from 'supertest'; +import * as supertest from 'supertest'; import { Repository } from 'typeorm'; import { Rss, RssAccept } from '../../src/rss/rss.entity'; import { RssFixture } from '../fixture/rss.fixture'; @@ -10,7 +10,7 @@ import { RssRepository, } from '../../src/rss/rss.repository'; -describe('Rss E2E Test', () => { +describe('/api/rss E2E Test', () => { let app: INestApplication; let rssRepository: Repository; let rssAcceptRepository: Repository; @@ -25,300 +25,48 @@ describe('Rss E2E Test', () => { await rssRepository.delete({}); }); - describe('POST /api/rss', () => { - describe('정상적인 요청을 한다.', () => { - it('정상적인 요청에 대한 응답을 한다.', async () => { - const requestDto = RssRegisterDto.from(RssFixture.createRssFixture()); - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - expect(response.status).toBe(201); - expect(response.body.message).toBe('신청이 완료되었습니다.'); - }); - - it('이미 신청했던 RSS를 또 신청한다.', async () => { - const requestDto = RssRegisterDto.from(RssFixture.createRssFixture()); - await request(app.getHttpServer()).post('/api/rss').send(requestDto); - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - expect(response.status).toBe(409); - expect(response.body.message).toBe('이미 신청된 RSS URL입니다.'); - }); - - it('이미 등록된 RSS를 또 신청한다.', async () => { - // given - const acceptedRss = await rssAcceptRepository.save( - RssAcceptFixture.createRssAcceptFixture(), - ); - const rssRegisterDto = RssRegisterDto.from(acceptedRss); + describe('POST /api/rss E2E Test', () => { + it('정상적인 요청이 들어왔다면 올바른 응답을 한다.', async () => { + // given + const requestDto = RssRegisterDto.from(RssFixture.createRssFixture()); - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(rssRegisterDto); + // when + const response = await supertest(app.getHttpServer()) + .post('/api/rss') + .send(requestDto); - // then - expect(response.status).toBe(409); - expect(response.body.message).toBe('이미 등록된 RSS URL입니다.'); - }); + // then + expect(response.status).toBe(201); }); - describe('비정상적인 요청을 한다.', () => { - describe('블로그 이름을 올바르게 입력하지 않는다.', () => { - it('블로그 이름이 없다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - delete rss.name; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('블로그 이름이 없습니다.'); - }); - - it('블로그 이름이 빈 문자열이다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - rss.name = ''; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('블로그 이름이 없습니다.'); - }); - - it('블로그 이름이 문자열이 아니다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - rss.name = 12345 as any; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('문자열로 입력해주세요.'); - }); - }); - - describe('실명을 올바르게 입력하지 않는다.', () => { - it('실명이 없다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - delete rss.userName; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('실명이 없습니다.'); - }); - - it('실명이 빈 문자열이다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - rss.userName = ''; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('실명이 없습니다.'); - }); - - it('실명이 문자열이 아니다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - rss.userName = 12345 as any; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('문자열로 입력해주세요.'); - }); + it('이미 신청한 RSS를 또 신청한다면 거부를 한다.', async () => { + // given + const requestDto = RssRegisterDto.from(RssFixture.createRssFixture()); + await supertest(app.getHttpServer()).post('/api/rss').send(requestDto); - it('실명의 길이가 2자리보다 작다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - rss.userName = 'A'; - const requestDto = RssRegisterDto.from(rss); + // when + const response = await supertest(app.getHttpServer()) + .post('/api/rss') + .send(requestDto); - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('이름 길이가 올바르지 않습니다.'); - }); - - it('실명의 길이가 50자리보다 크다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - rss.userName = 'A'.repeat(51); - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('이름 길이가 올바르지 않습니다.'); - }); - }); - - describe('이메일을 올바르게 입력하지 않는다.', () => { - it('이메일이 없다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - delete rss.email; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('이메일이 없습니다.'); - }); - - it('이메일이 빈 문자열이다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - rss.email = ''; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('이메일이 없습니다.'); - }); - - it('이메일 형식이 올바르지 않다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - rss.email = 'invalid-email'; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe( - '이메일 주소 형식에 맞춰서 작성해주세요.', - ); - }); - }); - - describe('RSS URL을 올바르게 입력하지 않는다.', () => { - it('RSS URL이 없다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - delete rss.rssUrl; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('RSS URL이 없습니다.'); - }); - - it('RSS URL이 빈 문자열이다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - rss.rssUrl = ''; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe('RSS URL이 없습니다.'); - }); - - it('RSS URL 형식이 잘못되었다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - rss.rssUrl = 'invalid-url'; - const requestDto = RssRegisterDto.from(rss); - - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); - - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe( - 'http, https 프로토콜과 URL 형식을 맞춰주세요.', - ); - }); + // then + expect(response.status).toBe(409); + }); - it('http, https 프로토콜을 제외한 다른 프로토콜을 입력한다.', async () => { - // given - const rss = RssFixture.createRssFixture(); - rss.rssUrl = 'ftp://example.com/rss'; - const requestDto = RssRegisterDto.from(rss); + it('이미 등록된 RSS를 또 신청한다면 거부를 한다.', async () => { + // given + const acceptedRss = await rssAcceptRepository.save( + RssAcceptFixture.createRssAcceptFixture(), + ); + const rssRegisterDto = RssRegisterDto.from(acceptedRss); - // when - const response = await request(app.getHttpServer()) - .post('/api/rss') - .send(requestDto); + // when + const response = await supertest(app.getHttpServer()) + .post('/api/rss') + .send(rssRegisterDto); - // then - expect(response.status).toBe(400); - expect(response.body.message).toBe( - 'http, https 프로토콜과 URL 형식을 맞춰주세요.', - ); - }); - }); + // then + expect(response.status).toBe(409); }); }); @@ -326,7 +74,7 @@ describe('Rss E2E Test', () => { describe('정상적인 요청을 한다.', () => { it('RSS가 등록되지 않은 경우 빈 리스트를 반환한다.', async () => { // when - then - const response = await request(app.getHttpServer()).get('/api/rss'); + const response = await supertest(app.getHttpServer()).get('/api/rss'); expect(response.status).toBe(200); expect(response.body.data).toEqual([]); }); @@ -337,7 +85,7 @@ describe('Rss E2E Test', () => { const expectedResult = await rssRepository.save(rss); // when - const response = await request(app.getHttpServer()).get('/api/rss'); + const response = await supertest(app.getHttpServer()).get('/api/rss'); //then expect(response.status).toBe(200); From 89a8c1de85f1b9732457ee5a4d1586ae720521ed Mon Sep 17 00:00:00 2001 From: J_Coder Date: Tue, 3 Dec 2024 03:39:25 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=A7=BC=20clean:=20supertest=20-\>=20r?= =?UTF-8?q?equest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/test/rss/rss.e2e-spec.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/server/test/rss/rss.e2e-spec.ts b/server/test/rss/rss.e2e-spec.ts index 352ed286..c5518532 100644 --- a/server/test/rss/rss.e2e-spec.ts +++ b/server/test/rss/rss.e2e-spec.ts @@ -1,6 +1,6 @@ import { INestApplication } from '@nestjs/common'; import { RssRegisterDto } from '../../src/rss/dto/rss-register.dto'; -import * as supertest from 'supertest'; +import * as request from 'supertest'; import { Repository } from 'typeorm'; import { Rss, RssAccept } from '../../src/rss/rss.entity'; import { RssFixture } from '../fixture/rss.fixture'; @@ -31,7 +31,7 @@ describe('/api/rss E2E Test', () => { const requestDto = RssRegisterDto.from(RssFixture.createRssFixture()); // when - const response = await supertest(app.getHttpServer()) + const response = await request(app.getHttpServer()) .post('/api/rss') .send(requestDto); @@ -42,10 +42,10 @@ describe('/api/rss E2E Test', () => { it('이미 신청한 RSS를 또 신청한다면 거부를 한다.', async () => { // given const requestDto = RssRegisterDto.from(RssFixture.createRssFixture()); - await supertest(app.getHttpServer()).post('/api/rss').send(requestDto); + await request(app.getHttpServer()).post('/api/rss').send(requestDto); // when - const response = await supertest(app.getHttpServer()) + const response = await request(app.getHttpServer()) .post('/api/rss') .send(requestDto); @@ -61,7 +61,7 @@ describe('/api/rss E2E Test', () => { const rssRegisterDto = RssRegisterDto.from(acceptedRss); // when - const response = await supertest(app.getHttpServer()) + const response = await request(app.getHttpServer()) .post('/api/rss') .send(rssRegisterDto); @@ -74,7 +74,7 @@ describe('/api/rss E2E Test', () => { describe('정상적인 요청을 한다.', () => { it('RSS가 등록되지 않은 경우 빈 리스트를 반환한다.', async () => { // when - then - const response = await supertest(app.getHttpServer()).get('/api/rss'); + const response = await request(app.getHttpServer()).get('/api/rss'); expect(response.status).toBe(200); expect(response.body.data).toEqual([]); }); @@ -85,7 +85,7 @@ describe('/api/rss E2E Test', () => { const expectedResult = await rssRepository.save(rss); // when - const response = await supertest(app.getHttpServer()).get('/api/rss'); + const response = await request(app.getHttpServer()).get('/api/rss'); //then expect(response.status).toBe(200); From 47238f899a2da88a84850ac932a1277b9a287228 Mon Sep 17 00:00:00 2001 From: J_Coder Date: Tue, 3 Dec 2024 04:01:13 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=A7=BC=20clean:=20=ED=95=84=EC=9A=94?= =?UTF-8?q?=EC=97=86=EB=8A=94=20async=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/test/rss/rss.e2e-spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/test/rss/rss.e2e-spec.ts b/server/test/rss/rss.e2e-spec.ts index c5518532..6ada1a4b 100644 --- a/server/test/rss/rss.e2e-spec.ts +++ b/server/test/rss/rss.e2e-spec.ts @@ -15,7 +15,7 @@ describe('/api/rss E2E Test', () => { let rssRepository: Repository; let rssAcceptRepository: Repository; - beforeAll(async () => { + beforeAll(() => { app = global.testApp; rssRepository = app.get(RssRepository); rssAcceptRepository = app.get(RssAcceptRepository);