From 1581e09c191cd28539b2274d7de2e694c6fee0bc Mon Sep 17 00:00:00 2001 From: JoonSoo-Kim Date: Tue, 21 Nov 2023 23:08:42 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=EC=9D=BC=EA=B8=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=84=B1=EA=B3=B5=20=EC=9D=91=EB=8B=B5=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 일기 생성 성공 시 생성된 일기의 uuid를 응답하도록 변경 - 일기 생성 성공시 201 Created 코드를 응답하도록 변경 --- BE/src/diaries/diaries.controller.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/BE/src/diaries/diaries.controller.ts b/BE/src/diaries/diaries.controller.ts index 76a130d..5128ca8 100644 --- a/BE/src/diaries/diaries.controller.ts +++ b/BE/src/diaries/diaries.controller.ts @@ -3,6 +3,7 @@ import { Controller, Delete, Get, + HttpCode, Param, Post, Put, @@ -25,8 +26,13 @@ export class DiariesController { constructor(private diariesService: DiariesService) {} @Post() - async writeDiary(@Body() createDiaryDto: CreateDiaryDto): Promise { - return this.diariesService.writeDiary(createDiaryDto); + @HttpCode(201) + async writeDiary(@Body() createDiaryDto: CreateDiaryDto): Promise { + const diary: Diary = await this.diariesService.writeDiary(createDiaryDto); + const response = JSON.stringify({ + uuid: diary.uuid, + }); + return response; } @Get("/:uuid") From 5b2b238cfa62f23a2db297538cf9a6f63a939515 Mon Sep 17 00:00:00 2001 From: JoonSoo-Kim Date: Tue, 21 Nov 2023 23:10:00 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20DTO=EC=97=90=20=EC=A0=81=EC=A0=88?= =?UTF-8?q?=ED=95=9C=20class-validator=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - class-validator에서 검증 실패 시 사용할 메세지 추가 - 정규표현식 적절하게 수정 - Not Null 값의 경우 IsNotEmpty 추가 - main.ts에서 GlobalPipe를 사용하도록 추가 --- BE/src/diaries/diaries.dto.ts | 32 ++++++++++++++++++++++---------- BE/src/main.ts | 2 ++ 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/BE/src/diaries/diaries.dto.ts b/BE/src/diaries/diaries.dto.ts index 6cd5c32..3ff94b2 100644 --- a/BE/src/diaries/diaries.dto.ts +++ b/BE/src/diaries/diaries.dto.ts @@ -1,25 +1,37 @@ -import { IsString, IsDate, Matches, IsUUID, IsArray } from "class-validator"; +import { + IsString, + IsDate, + Matches, + IsUUID, + IsArray, + IsNotEmpty, + IsDateString, +} from "class-validator"; export class CreateDiaryDto { - @IsString() + @IsNotEmpty({ message: "제목은 비어있지 않아야 합니다." }) + @IsString({ message: "제목은 문자열이어야 합니다." }) title: string; - @IsString() + @IsString({ message: "내용은 문자열이어야 합니다." }) content: string; - @IsString() - @Matches(RegExp(/^-?d+(.d+)?,-?d+(.d+)?,-?d+(.d+)?$/), { - message: "적절하지 않은 포인트 양식입니다", + @IsNotEmpty({ message: "좌표는 비어있지 않아야 합니다." }) + @IsString({ message: "좌표는 문자열이어야 합니다." }) + @Matches(/^-?\d+(\.\d+)?,-?\d+(\.\d+)?,-?\d+(\.\d+)?$/, { + message: "적절하지 않은 좌표 양식입니다.", }) point: string; - @IsDate() + @IsDateString() + @IsNotEmpty({ message: "날짜는 비어있지 않아야 합니다." }) date: Date; - @IsArray() + @IsArray({ message: "태그는 배열의 형태여야 합니다." }) tags: string[]; - @IsUUID() + @IsUUID("4", { message: "모양 uuid 값이 uuid 양식이어야 합니다." }) + @IsNotEmpty({ message: "모양 uuid는 비어있지 않아야 합니다." }) shapeUuid: string; } @@ -39,7 +51,7 @@ export class UpdateDiaryDto { content: string; @IsString() - @Matches(RegExp("^-?d+(.d+)?,-?d+(.d+)?,-?d+(.d+)?$"), { + @Matches(/^-?\d+(\.\d+)?,-?\d+(\.\d+)?,-?\d+(\.\d+)?$/, { message: "적절하지 않은 포인트 양식입니다", }) point: string; diff --git a/BE/src/main.ts b/BE/src/main.ts index ad40d5b..9f367ab 100644 --- a/BE/src/main.ts +++ b/BE/src/main.ts @@ -1,9 +1,11 @@ import { NestFactory } from "@nestjs/core"; import { AppModule } from "./app.module"; +import { ValidationPipe } from "@nestjs/common"; async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableCors(); + app.useGlobalPipes(new ValidationPipe()); await app.listen(process.env.BE_PORT); } bootstrap(); From 9c5992fe8a501ef92ff1d059e059b54c9b556fd7 Mon Sep 17 00:00:00 2001 From: JoonSoo-Kim Date: Tue, 21 Nov 2023 23:10:44 +0900 Subject: [PATCH 3/8] =?UTF-8?q?fix:=20CreateUserDto=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=B6=80=EC=A0=81=EC=A0=88=ED=95=9C=20=EC=A0=95=EA=B7=9C?= =?UTF-8?q?=ED=91=9C=ED=98=84=EC=8B=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CreateUserDto의 email에 대한 부적절한 정규표현식 수정 --- BE/src/users/users.dto.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/BE/src/users/users.dto.ts b/BE/src/users/users.dto.ts index 0d819d6..7d1695a 100644 --- a/BE/src/users/users.dto.ts +++ b/BE/src/users/users.dto.ts @@ -3,16 +3,18 @@ import { IsString, Length, MaxLength, Matches } from "class-validator"; export class CreateUserDto { @IsString() @Length(4, 21) + @Matches(/^[A-Za-z0-9-]{5,20}$/) userId: string; @IsString() - @Matches(RegExp(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/), { + @Matches(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, { message: "적절하지 않은 이메일 양식입니다.", }) email: string; @IsString() @Length(4, 21) + @Matches(/^[A-Za-z0-9!@#$%^&*()+=-~]{5,20}$/) password: string; @IsString() From 53abab04a00f23fc9370950672491c59391ee2aa Mon Sep 17 00:00:00 2001 From: JoonSoo-Kim Date: Tue, 21 Nov 2023 23:12:54 +0900 Subject: [PATCH 4/8] =?UTF-8?q?test:=20=EC=9D=BC=EA=B8=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=A0=95=EC=83=81=20=EC=9A=94=EC=B2=AD=20e2e=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 일기 생성에 대한 정상 요청 시 201 Created를 응답하는 e2e 테스트 작성 - 기존의 app.e2e-spec.ts 삭제 --- BE/test/app.e2e-spec.ts | 114 ----------------------------- BE/test/diaries.create.e2e-spec.ts | 54 ++++++++++++++ 2 files changed, 54 insertions(+), 114 deletions(-) delete mode 100644 BE/test/app.e2e-spec.ts create mode 100644 BE/test/diaries.create.e2e-spec.ts diff --git a/BE/test/app.e2e-spec.ts b/BE/test/app.e2e-spec.ts deleted file mode 100644 index b64a1b9..0000000 --- a/BE/test/app.e2e-spec.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { Test, TestingModule } from "@nestjs/testing"; -import { INestApplication } from "@nestjs/common"; -import * as request from "supertest"; -import { AppModule } from "../src/app.module"; - -describe("AppController (e2e)", () => { - let app: INestApplication; - - beforeEach(async () => { - const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AppModule], - }).compile(); - - app = moduleFixture.createNestApplication(); - await app.init(); - }); - - afterEach(async () => { - await app.close(); - }); - - it("/diaries POST 201", async () => { - const postResponse = await request(app.getHttpServer()) - .post("/diaries") - .send({ - title: "title", - content: "this is content.", - point: "1.5,5.5,10.55", - date: "2023-11-14", - }) - .expect(201); - - const createdDiaryUuid = postResponse.body.uuid; - - await request(app.getHttpServer()) - .delete(`/diaries/${createdDiaryUuid}`) - .expect(200); - }); - - it("/diaries/:uuid GET 200", async () => { - const postResponse = await request(app.getHttpServer()) - .post("/diaries") - .send({ - title: "title", - content: "this is content.", - point: "1.5,5.5,10.55", - date: "2023-11-14", - }); - const createdDiaryUuid = postResponse.body.uuid; - - const getResponse = await request(app.getHttpServer()).get( - `/diaries/${createdDiaryUuid}`, - ); - const body = JSON.parse(getResponse.text); - - expect(body.userId).toBe("jeongmin"); - expect(body.title).toBe("title"); - expect(body.content).toBe("this is content."); - expect(body.date).toBe("2023-11-14T00:00:00.000Z"); - - await request(app.getHttpServer()) - .delete(`/diaries/${createdDiaryUuid}`) - .expect(200); - }); - - it("/diaries PUT 200", async () => { - const postResponse = await request(app.getHttpServer()) - .post("/diaries") - .send({ - title: "title", - content: "this is content.", - point: "1.5,5.5,10.55", - date: "2023-11-14", - }); - - const createdDiaryUuid = postResponse.body.uuid; - - const putResponse = await request(app.getHttpServer()) - .put("/diaries") - .send({ - uuid: createdDiaryUuid, - title: "업데이트 확인", - content: "this is content222.", - date: "2023-11-18", - shapeUuid: "test", - }); - const body = putResponse.body; - - expect(body.title).toBe("업데이트 확인"); - expect(atob(body.content)).toBe("this is content222."); - expect(body.date).toBe("2023-11-18"); - - await request(app.getHttpServer()) - .delete(`/diaries/${createdDiaryUuid}`) - .expect(200); - }); - - it("/diaries DELETE 200", async () => { - const postResponse = await request(app.getHttpServer()) - .post("/diaries") - .send({ - title: "title", - content: "this is content.", - point: "1.5,5.5,10.55", - date: "2023-11-14", - }); - - const createdDiaryUuid = postResponse.body.uuid; - - await request(app.getHttpServer()) - .delete(`/diaries/${createdDiaryUuid}`) - .expect(200); - }); -}); diff --git a/BE/test/diaries.create.e2e-spec.ts b/BE/test/diaries.create.e2e-spec.ts new file mode 100644 index 0000000..36b4315 --- /dev/null +++ b/BE/test/diaries.create.e2e-spec.ts @@ -0,0 +1,54 @@ +import { Test, TestingModule } from "@nestjs/testing"; +import { INestApplication } from "@nestjs/common"; +import * as request from "supertest"; +import { AppModule } from "../src/app.module"; +import { ValidationPipe } from "@nestjs/common"; + +describe("AppController (e2e)", () => { + let app: INestApplication; + let accessToken: string; + + beforeEach(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [AppModule], + }).compile(); + + app = moduleFixture.createNestApplication(); + app.enableCors(); + app.useGlobalPipes(new ValidationPipe()); + + await app.init(); + + const signInPost = await request(app.getHttpServer()) + .post("/auth/signin") + .send({ + userId: "commonUser", + password: process.env.COMMON_USER_PASS, + }); + + accessToken = signInPost.body.accessToken; + }); + + afterEach(async () => { + await app.close(); + }); + + it("정상 요청 시 201 Created 응답", async () => { + const postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: "title", + content: "this is content.", + point: "1.5,5.5,10.55", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", + }) + .expect(201); + + const body = JSON.parse(postResponse.text); + + expect(body.uuid.length).toBe(36); + }); +}); From d158fcd91c910d869b47ee089e97a94cb199b693 Mon Sep 17 00:00:00 2001 From: JoonSoo-Kim Date: Tue, 21 Nov 2023 23:13:51 +0900 Subject: [PATCH 5/8] =?UTF-8?q?test:=20=EC=9D=BC=EA=B8=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=8B=9C=20=EC=95=A1=EC=84=B8=EC=8A=A4=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=EC=97=86=EB=8A=94=20=EC=9A=94=EC=B2=AD=20e2e=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 일기 생성에 대해 액세스 토큰 없이 요청 시 401 Unauthorized를 응답하는 e2e 테스트 작성 --- BE/test/diaries.create.e2e-spec.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/BE/test/diaries.create.e2e-spec.ts b/BE/test/diaries.create.e2e-spec.ts index 36b4315..700d725 100644 --- a/BE/test/diaries.create.e2e-spec.ts +++ b/BE/test/diaries.create.e2e-spec.ts @@ -51,4 +51,22 @@ describe("AppController (e2e)", () => { expect(body.uuid.length).toBe(36); }); + + it("액세스 토큰 없이 요청 시 401 Unauthorized 응답", async () => { + const postResponse = await request(app.getHttpServer()) + .post("/diaries") + .send({ + title: "title", + content: "this is content.", + point: "1.5,5.5,10.55", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", + }) + .expect(401); + + const body = JSON.parse(postResponse.text); + + expect(body.message).toBe("Unauthorized"); + }); }); From cbd82ae089ad584d36abe5d9c199aa4e914634c1 Mon Sep 17 00:00:00 2001 From: JoonSoo-Kim Date: Tue, 21 Nov 2023 23:15:23 +0900 Subject: [PATCH 6/8] =?UTF-8?q?test:=20=EC=9D=BC=EA=B8=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=8B=9C=20=EB=B9=88=20=EA=B0=92=EC=9D=84=20?= =?UTF-8?q?=ED=8F=AC=ED=95=A8=ED=95=9C=20=EC=9A=94=EC=B2=AD=20e2e=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 일기 생성에 대해 빈 값을 포함하여 요청 시 400 Bad Request와 적절한 오류 메세지를 응답하는 e2e 테스트 작성 --- BE/test/diaries.create.e2e-spec.ts | 89 ++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/BE/test/diaries.create.e2e-spec.ts b/BE/test/diaries.create.e2e-spec.ts index 700d725..d1b7f05 100644 --- a/BE/test/diaries.create.e2e-spec.ts +++ b/BE/test/diaries.create.e2e-spec.ts @@ -69,4 +69,93 @@ describe("AppController (e2e)", () => { expect(body.message).toBe("Unauthorized"); }); + + it("빈 값을 포함한 요청 시 400 Bad Request 응답", async () => { + let postResponse; + let body; + // 제목이 없는 경우 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + content: "this is content.", + point: "1.5,5.5,10.55", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("제목은 비어있지 않아야 합니다."); + + // 좌표가 없는 경우 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: "title", + content: "this is content.", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("좌표는 비어있지 않아야 합니다."); + + // 날짜가 없는 경우 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: "title", + content: "this is content.", + point: "1.5,5.5,10.55", + tags: ["tagTest", "tagTest2"], + shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("날짜는 비어있지 않아야 합니다."); + + // 모양 uuid가 없는 경우 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: "title", + content: "this is content.", + point: "1.5,5.5,10.55", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("모양 uuid는 비어있지 않아야 합니다."); + + // 복수의 데이터가 없는 경우 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: "title", + content: "this is content.", + tags: ["tagTest", "tagTest2"], + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("날짜는 비어있지 않아야 합니다."); + expect(body.message).toContain("좌표는 비어있지 않아야 합니다."); + expect(body.message).toContain("모양 uuid는 비어있지 않아야 합니다."); + }); }); From 9003f17584fb835a57693a94781f834bb631b942 Mon Sep 17 00:00:00 2001 From: JoonSoo-Kim Date: Tue, 21 Nov 2023 23:16:19 +0900 Subject: [PATCH 7/8] =?UTF-8?q?test:=20=EC=9D=BC=EA=B8=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=8B=9C=20=EB=B6=80=EC=A0=81=EC=A0=88=ED=95=9C=20?= =?UTF-8?q?=EA=B0=92=EC=9C=BC=EB=A1=9C=20=EC=9A=94=EC=B2=AD=20e2e=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 일기 생성에 대해 부적절한 값을 포함하여 요청 시 400 Bad Request와 적절한 오류 메세지를 응답하는 e2e 테스트 작성 --- BE/test/diaries.create.e2e-spec.ts | 130 +++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/BE/test/diaries.create.e2e-spec.ts b/BE/test/diaries.create.e2e-spec.ts index d1b7f05..d7a1852 100644 --- a/BE/test/diaries.create.e2e-spec.ts +++ b/BE/test/diaries.create.e2e-spec.ts @@ -158,4 +158,134 @@ describe("AppController (e2e)", () => { expect(body.message).toContain("좌표는 비어있지 않아야 합니다."); expect(body.message).toContain("모양 uuid는 비어있지 않아야 합니다."); }); + + it("부적절한 값으로 요청 시 400 Bad Request 응답", async () => { + let postResponse; + let body; + // 문자열이 아닌 제목으로 요청 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: 35, + content: "this is content.", + point: "1.5,5.5,10.55", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("제목은 문자열이어야 합니다."); + + // 문자열이 아닌 내용으로 요청 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: "title", + content: 35, + point: "1.5,5.5,10.55", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("내용은 문자열이어야 합니다."); + + // 문자열이 아닌 좌표로 요청 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: "title", + content: "this is content.", + point: [], + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("좌표는 문자열이어야 합니다."); + + // 적절하지 않은 좌표 양식의 문자열로 요청 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: "title", + content: "this is content.", + point: "-1.5.5.5.10.55", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("적절하지 않은 좌표 양식입니다."); + + // 적절하지 않은 날짜 양식의 문자열로 요청 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: "title", + content: "this is content.", + point: "1.5,5.5,10.55", + date: "20231114019", + tags: ["tagTest", "tagTest2"], + shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("date must be a valid ISO 8601 date string"); + + // 배열 형태가 아닌 태그로 요청 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: "title", + content: "this is content.", + point: "1.5,5.5,10.55", + date: "2023-11-14", + tags: "tagTest2", + shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("태그는 배열의 형태여야 합니다."); + + // uuid 양식이 아닌 모양 uuid로 요청 + postResponse = await request(app.getHttpServer()) + .post("/diaries") + .set("Authorization", `Bearer ${accessToken}`) + .send({ + title: "title", + content: "this is content.", + point: "1.5,5.5,10.55", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + shapeUuid: "uuidTest", + }) + .expect(400); + + body = JSON.parse(postResponse.text); + + expect(body.message).toContain("모양 uuid 값이 uuid 양식이어야 합니다."); + }); }); From a153af5b54c1aa9dbab22002000c5996457b7f72 Mon Sep 17 00:00:00 2001 From: JoonSoo-Kim Date: Wed, 22 Nov 2023 00:04:28 +0900 Subject: [PATCH 8/8] =?UTF-8?q?Feat:=20=EC=9D=BC=EA=B8=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=9D=91=EB=8B=B5=EC=97=90=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EB=8A=94=20DiaryUuidDto=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 일기 생성 API의 응답 타입으로 사용할 DiaryUuidDto 생성 --- BE/src/diaries/diaries.controller.ts | 23 ++++++++++++----------- BE/src/diaries/diaries.dto.ts | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/BE/src/diaries/diaries.controller.ts b/BE/src/diaries/diaries.controller.ts index 5128ca8..b454c7a 100644 --- a/BE/src/diaries/diaries.controller.ts +++ b/BE/src/diaries/diaries.controller.ts @@ -13,6 +13,7 @@ import { DiariesService } from "./diaries.service"; import { CreateDiaryDto, DeleteDiaryDto, + DiaryUuidDto, ReadDiaryDto, UpdateDiaryDto, } from "./diaries.dto"; @@ -27,21 +28,21 @@ export class DiariesController { @Post() @HttpCode(201) - async writeDiary(@Body() createDiaryDto: CreateDiaryDto): Promise { + async writeDiary( + @Body() createDiaryDto: CreateDiaryDto, + ): Promise { const diary: Diary = await this.diariesService.writeDiary(createDiaryDto); - const response = JSON.stringify({ - uuid: diary.uuid, - }); - return response; + return { uuid: diary.uuid }; } @Get("/:uuid") @UseGuards(IdGuard) - async readDiary(@Param("uuid") uuid: string): Promise { + async readDiary(@Param("uuid") uuid: string): Promise { const readDiaryDto: ReadDiaryDto = { uuid }; const diary = await this.diariesService.readDiary(readDiaryDto); + const coordinateArray = diary.point.split(","); - const response = JSON.stringify({ + const response = { userId: diary.user.userId, title: diary.title, content: diary.content, @@ -54,12 +55,12 @@ export class DiariesController { sentiment: diary.sentiment, }, coordinate: { - x: diary.point.split(",")[0], - y: diary.point.split(",")[1], - z: diary.point.split(",")[2], + x: parseFloat(coordinateArray[0]), + y: parseFloat(coordinateArray[1]), + z: parseFloat(coordinateArray[2]), }, shape_uuid: diary.shape.uuid, - }); + }; return response; } diff --git a/BE/src/diaries/diaries.dto.ts b/BE/src/diaries/diaries.dto.ts index 3ff94b2..8cfc84c 100644 --- a/BE/src/diaries/diaries.dto.ts +++ b/BE/src/diaries/diaries.dto.ts @@ -7,6 +7,7 @@ import { IsNotEmpty, IsDateString, } from "class-validator"; +import { sentimentStatus } from "src/utils/enum"; export class CreateDiaryDto { @IsNotEmpty({ message: "제목은 비어있지 않아야 합니다." }) @@ -70,3 +71,27 @@ export class DeleteDiaryDto { @IsUUID() uuid: string; } + +export class DiaryUuidDto { + uuid: string; +} + +export class ReadDiaryResponseDto { + userId: string; + title: string; + content: string; + date: Date; + tags: string[]; + emotion: { + position: number; + neutral: number; + negative: number; + sentiment: sentimentStatus; + }; + coordinate: { + x: number; + y: number; + z: number; + }; + shape_uuid: string; +}