diff --git a/BE/src/auth/guard/auth.diary-guard.ts b/BE/src/auth/guard/auth.diary-guard.ts index 445fa90..f68b028 100644 --- a/BE/src/auth/guard/auth.diary-guard.ts +++ b/BE/src/auth/guard/auth.diary-guard.ts @@ -1,4 +1,5 @@ import { + BadRequestException, ExecutionContext, Injectable, NotFoundException, @@ -24,11 +25,17 @@ export class PrivateDiaryGuard extends JwtAuthGuard { } const request = context.switchToHttp().getRequest(); + // GET, DELETE 요청인 경우 params.uuid를 사용 // PUT 요청인 경우 body.uuid를 사용 const requestUuid = request.params.uuid ? request.params.uuid : request.body.uuid; + + if (requestUuid === undefined) { + throw new BadRequestException("일기 uuid는 비어있지 않아야 합니다."); + } + const requestDiary = await this.diariesRepository.getDiaryByUuid(requestUuid); diff --git a/BE/src/purchase/purchase.controller.ts b/BE/src/purchase/purchase.controller.ts index c08a289..1f316ed 100644 --- a/BE/src/purchase/purchase.controller.ts +++ b/BE/src/purchase/purchase.controller.ts @@ -20,11 +20,13 @@ export class PurchaseController { constructor(private purchaseService: PurchaseService) {} @Get("/credit") + @HttpCode(200) async getCreditBalanceByUser(@GetUser() user: User): Promise { return new CreditDto(user.credit); } @Post("/design") + @HttpCode(200) async purchaseDesign( @GetUser() user: User, @Body() purchaseDesignDto: PurchaseDesignDto, @@ -39,11 +41,13 @@ export class PurchaseController { } @Post("/premium") + @HttpCode(200) async purchasePremium(@GetUser() user: User): Promise { return this.purchaseService.purchasePremium(user); } @Get("/premium") + @HttpCode(200) async getPremiumStatus(@GetUser() user: User): Promise { return this.purchaseService.getPremiumStatus(user); } diff --git a/BE/src/purchase/purchase.service.ts b/BE/src/purchase/purchase.service.ts index 71ad334..60e973c 100644 --- a/BE/src/purchase/purchase.service.ts +++ b/BE/src/purchase/purchase.service.ts @@ -19,7 +19,7 @@ export class PurchaseService { const domain = domainEnum[purchaseDesignDto.domain]; const design = designEnum[purchaseDesignDto.design]; - if (await this.isDesignAlreadyPurchased(user.userId, design, design)) { + if (await this.isDesignAlreadyPurchased(user.userId, domain, design)) { throw new BadRequestException(`이미 구매한 디자인입니다.`); } diff --git a/BE/src/utils/clearDb.ts b/BE/src/utils/clearDb.ts deleted file mode 100644 index 6368990..0000000 --- a/BE/src/utils/clearDb.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { TestingModule } from "@nestjs/testing"; -import { CreateUserDto } from "src/auth/dto/users.dto"; -import { User } from "src/auth/users.entity"; -import { UsersRepository } from "src/auth/users.repository"; -import { DataSource } from "typeorm"; - -export async function clearUserDb( - moduleFixture: TestingModule, - usersRepository: UsersRepository, -) { - // user 데이터베이스 초기화 시작 - const queryRunner = await moduleFixture - .get(DataSource) - .createQueryRunner(); - - await queryRunner.startTransaction(); - - try { - // 외래 키 제약 조건을 비활성화합니다. - await queryRunner.query("SET FOREIGN_KEY_CHECKS=0"); - - await moduleFixture.get(DataSource).getRepository(User).clear(); - - // 외래 키 제약 조건을 다시 활성화합니다. - await queryRunner.query("SET FOREIGN_KEY_CHECKS=1"); - - await queryRunner.commitTransaction(); - } catch (error) { - await queryRunner.rollbackTransaction(); - } finally { - await queryRunner.release(); - } - // user 데이터베이스 초기화 종료 - - // 삭제된 commonUser 재생성 - await moduleFixture.get(DataSource).getRepository(User).clear(); - - const createUserDto = new CreateUserDto(); - createUserDto.userId = "commonUser"; - createUserDto.email = "byeolsoop08@naver.com"; - createUserDto.password = process.env.COMMON_USER_PASS; - createUserDto.nickname = "commonUser"; - - await usersRepository.createUser(createUserDto); -} diff --git a/BE/test/e2e/auth.reissue.e2e-spec.ts b/BE/test/e2e/auth.reissue.e2e-spec.ts index ae00442..4177f80 100644 --- a/BE/test/e2e/auth.reissue.e2e-spec.ts +++ b/BE/test/e2e/auth.reissue.e2e-spec.ts @@ -5,12 +5,15 @@ import { ValidationPipe } from "@nestjs/common"; import { AuthModule } from "src/auth/auth.module"; import { TypeOrmModule } from "@nestjs/typeorm"; import { typeORMTestConfig } from "src/configs/typeorm.test.config"; -import { User } from "src/auth/users.entity"; import { UsersRepository } from "src/auth/users.repository"; import { RedisModule } from "@liaoliaots/nestjs-redis"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; describe("[액세스 토큰 재발급] /auth/reissue POST e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ @@ -34,6 +37,10 @@ describe("[액세스 토큰 재발급] /auth/reissue POST e2e 테스트", () => await app.init(); + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); + await request(app.getHttpServer()) .post("/auth/signup") .send({ @@ -46,13 +53,7 @@ describe("[액세스 토큰 재발급] /auth/reissue POST e2e 테스트", () => }); afterAll(async () => { - const usersRepository = new UsersRepository(); - - const testUser = await usersRepository.getUserByUserId("SignoutTestUserId"); - if (testUser) { - await User.remove(testUser); - } - + await transactionalContext.finish(); await app.close(); }); diff --git a/BE/test/e2e/auth.signin.e2e-spec.ts b/BE/test/e2e/auth.signin.e2e-spec.ts index b0099b8..759056b 100644 --- a/BE/test/e2e/auth.signin.e2e-spec.ts +++ b/BE/test/e2e/auth.signin.e2e-spec.ts @@ -6,9 +6,13 @@ import { AuthModule } from "src/auth/auth.module"; import { TypeOrmModule } from "@nestjs/typeorm"; import { typeORMTestConfig } from "src/configs/typeorm.test.config"; import { RedisModule } from "@liaoliaots/nestjs-redis"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; describe("[로그인] /auth/signin POST e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ @@ -30,9 +34,14 @@ describe("[로그인] /auth/signin POST e2e 테스트", () => { app.useGlobalPipes(new ValidationPipe()); await app.init(); + + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); }); afterAll(async () => { + await transactionalContext.finish(); await app.close(); }); diff --git a/BE/test/e2e/auth.signout.e2e-spec.ts b/BE/test/e2e/auth.signout.e2e-spec.ts index 6d9f140..e029d88 100644 --- a/BE/test/e2e/auth.signout.e2e-spec.ts +++ b/BE/test/e2e/auth.signout.e2e-spec.ts @@ -5,12 +5,15 @@ import { ValidationPipe } from "@nestjs/common"; import { AuthModule } from "src/auth/auth.module"; import { TypeOrmModule } from "@nestjs/typeorm"; import { typeORMTestConfig } from "src/configs/typeorm.test.config"; -import { User } from "src/auth/users.entity"; import { UsersRepository } from "src/auth/users.repository"; import { RedisModule } from "@liaoliaots/nestjs-redis"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; describe("[로그아웃] /auth/signout POST e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ @@ -34,6 +37,10 @@ describe("[로그아웃] /auth/signout POST e2e 테스트", () => { await app.init(); + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); + await request(app.getHttpServer()) .post("/auth/signup") .send({ @@ -46,13 +53,7 @@ describe("[로그아웃] /auth/signout POST e2e 테스트", () => { }); afterAll(async () => { - const usersRepository = new UsersRepository(); - - const testUser = await usersRepository.getUserByUserId("SignoutTestUserId"); - if (testUser) { - await User.remove(testUser); - } - + await transactionalContext.finish(); await app.close(); }); diff --git a/BE/test/e2e/auth.signup.e2e-spec.ts b/BE/test/e2e/auth.signup.e2e-spec.ts index b70644b..62b391f 100644 --- a/BE/test/e2e/auth.signup.e2e-spec.ts +++ b/BE/test/e2e/auth.signup.e2e-spec.ts @@ -5,11 +5,14 @@ import { ValidationPipe } from "@nestjs/common"; import { AuthModule } from "src/auth/auth.module"; import { TypeOrmModule } from "@nestjs/typeorm"; import { typeORMTestConfig } from "src/configs/typeorm.test.config"; -import { User } from "src/auth/users.entity"; import { RedisModule } from "@liaoliaots/nestjs-redis"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; describe("[회원가입] /auth/signup POST e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ @@ -31,14 +34,19 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { app.useGlobalPipes(new ValidationPipe()); await app.init(); + + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); }); afterAll(async () => { + await transactionalContext.finish(); await app.close(); }); it("정상 요청 시 204 Created 응답", async () => { - const postResponse = await request(app.getHttpServer()) + await request(app.getHttpServer()) .post("/auth/signup") .send({ userId: "TestUserId", @@ -47,11 +55,6 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { nickname: "TestUser", }) .expect(204); - - const testUser = await User.findOne({ where: { userId: "TestUserId" } }); - if (testUser) { - await User.remove(testUser); - } }); it("중복된 아이디에 대한 요청 시 409 Conflict 응답", async () => { @@ -65,7 +68,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(204); - const postResponse = await request(app.getHttpServer()) + await request(app.getHttpServer()) .post("/auth/signup") .send({ userId: "TestUserId2", @@ -74,11 +77,6 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { nickname: "TestUser3", }) .expect(409); - - const testUser = await User.findOne({ where: { userId: "TestUserId2" } }); - if (testUser) { - await User.remove(testUser); - } }); it("중복된 이메일에 대한 요청 시 409 Conflict 응답", async () => { @@ -92,7 +90,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(204); - const postResponse = await request(app.getHttpServer()) + await request(app.getHttpServer()) .post("/auth/signup") .send({ userId: "TestUserId5", @@ -101,11 +99,6 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { nickname: "TestUser5", }) .expect(409); - - const testUser = await User.findOne({ where: { userId: "TestUserId4" } }); - if (testUser) { - await User.remove(testUser); - } }); it("생성 규칙을 지키지 않는 아이디 요청 시 400 Bad Request 응답", async () => { @@ -119,7 +112,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("생성 규칙에 맞지 않는 아이디입니다."); }); @@ -135,7 +128,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("생성 규칙에 맞지 않는 비밀번호 입니다."); }); @@ -151,7 +144,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("적절하지 않은 이메일 양식입니다."); }); @@ -166,7 +159,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("아이디는 비어있지 않아야 합니다."); }); @@ -181,7 +174,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("비밀번호는 비어있지 않아야 합니다."); }); @@ -196,7 +189,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("이메일은 비어있지 않아야 합니다."); }); @@ -211,7 +204,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("닉네임은 비어있지 않아야 합니다."); }); @@ -227,7 +220,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("아이디는 문자열이어야 합니다."); }); @@ -243,7 +236,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("비밀번호는 문자열이어야 합니다."); }); @@ -259,7 +252,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("이메일은 문자열이어야 합니다."); }); @@ -275,7 +268,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("닉네임은 문자열이어야 합니다."); }); @@ -291,7 +284,7 @@ describe("[회원가입] /auth/signup POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("닉네임은 20자 이하여야 합니다."); }); diff --git a/BE/test/e2e/diaries.create.e2e-spec.ts b/BE/test/e2e/diaries.create.e2e-spec.ts index 9ea0eff..e6ff59a 100644 --- a/BE/test/e2e/diaries.create.e2e-spec.ts +++ b/BE/test/e2e/diaries.create.e2e-spec.ts @@ -6,10 +6,15 @@ import { DiariesModule } from "src/diaries/diaries.module"; import { typeORMTestConfig } from "src/configs/typeorm.test.config"; import { TypeOrmModule } from "@nestjs/typeorm"; import { RedisModule } from "@liaoliaots/nestjs-redis"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; describe("[일기 작성] /diaries POST e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; let accessToken: string; + let shapeUuid: string; beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ @@ -32,6 +37,10 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { await app.init(); + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); + const signInPost = await request(app.getHttpServer()) .post("/auth/signin") .send({ @@ -40,9 +49,15 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { }); accessToken = signInPost.body.accessToken; + + const defaultShapes = await request(app.getHttpServer()) + .get("/shapes/default") + .set("Authorization", `Bearer ${accessToken}`); + shapeUuid = defaultShapes.body[0]["uuid"]; }); afterAll(async () => { + await transactionalContext.finish(); await app.close(); }); @@ -51,16 +66,16 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { .post("/diaries") .set("Authorization", `Bearer ${accessToken}`) .send({ + shapeUuid, 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); + const body = postResponse.body; expect(body.uuid.length).toBe(36); }); @@ -69,12 +84,12 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { const postResponse = await request(app.getHttpServer()) .post("/diaries") .send({ + shapeUuid, 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); @@ -86,15 +101,15 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { .post("/diaries") .set("Authorization", `Bearer ${accessToken}`) .send({ + shapeUuid, 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); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("제목은 비어있지 않아야 합니다."); }); @@ -104,15 +119,15 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { .post("/diaries") .set("Authorization", `Bearer ${accessToken}`) .send({ + shapeUuid, title: "title", content: "this is content.", date: "2023-11-14", tags: ["tagTest", "tagTest2"], - shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("좌표는 비어있지 않아야 합니다."); }); @@ -122,15 +137,15 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { .post("/diaries") .set("Authorization", `Bearer ${accessToken}`) .send({ + shapeUuid, title: "title", content: "this is content.", point: "1.5,5.5,10.55", tags: ["tagTest", "tagTest2"], - shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("날짜는 비어있지 않아야 합니다."); }); @@ -148,7 +163,7 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("모양 uuid는 비어있지 않아야 합니다."); }); @@ -164,7 +179,7 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("날짜는 비어있지 않아야 합니다."); expect(body.message).toContain("좌표는 비어있지 않아야 합니다."); @@ -176,16 +191,16 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { .post("/diaries") .set("Authorization", `Bearer ${accessToken}`) .send({ + shapeUuid, 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); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("제목은 문자열이어야 합니다."); }); @@ -195,16 +210,16 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { .post("/diaries") .set("Authorization", `Bearer ${accessToken}`) .send({ + shapeUuid, 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); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("내용은 문자열이어야 합니다."); }); @@ -214,16 +229,16 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { .post("/diaries") .set("Authorization", `Bearer ${accessToken}`) .send({ + shapeUuid, title: "title", content: "this is content.", point: [], date: "2023-11-14", tags: ["tagTest", "tagTest2"], - shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("좌표는 문자열이어야 합니다."); }); @@ -233,16 +248,16 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { .post("/diaries") .set("Authorization", `Bearer ${accessToken}`) .send({ + shapeUuid, 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); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("적절하지 않은 좌표 양식입니다."); }); @@ -252,16 +267,16 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { .post("/diaries") .set("Authorization", `Bearer ${accessToken}`) .send({ + shapeUuid, 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); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("date must be a valid ISO 8601 date string"); }); @@ -271,16 +286,16 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { .post("/diaries") .set("Authorization", `Bearer ${accessToken}`) .send({ + shapeUuid, 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); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("태그는 배열의 형태여야 합니다."); }); @@ -299,7 +314,7 @@ describe("[일기 작성] /diaries POST e2e 테스트", () => { }) .expect(400); - const body = JSON.parse(postResponse.text); + const body = postResponse.body; expect(body.message).toContain("모양 uuid 값이 uuid 양식이어야 합니다."); }); diff --git a/BE/test/e2e/diaries.delete.e2e-spec.ts b/BE/test/e2e/diaries.delete.e2e-spec.ts index c2a28de..ed49b1d 100644 --- a/BE/test/e2e/diaries.delete.e2e-spec.ts +++ b/BE/test/e2e/diaries.delete.e2e-spec.ts @@ -6,9 +6,13 @@ import { DiariesModule } from "src/diaries/diaries.module"; import { typeORMTestConfig } from "src/configs/typeorm.test.config"; import { TypeOrmModule } from "@nestjs/typeorm"; import { RedisModule } from "@liaoliaots/nestjs-redis"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; describe("[일기 삭제] /diaries/:uuid DELETE e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; let accessToken: string; let diaryUuid: string; @@ -33,6 +37,10 @@ describe("[일기 삭제] /diaries/:uuid DELETE e2e 테스트", () => { await app.init(); + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); + const signInPost = await request(app.getHttpServer()) .post("/auth/signin") .send({ @@ -42,27 +50,33 @@ describe("[일기 삭제] /diaries/:uuid DELETE e2e 테스트", () => { accessToken = signInPost.body.accessToken; + const defaultShapes = await request(app.getHttpServer()) + .get("/shapes/default") + .set("Authorization", `Bearer ${accessToken}`); + const shapeUuid = defaultShapes.body[0]["uuid"]; + const createDiaryPost = await request(app.getHttpServer()) .post("/diaries") .set("Authorization", `Bearer ${accessToken}`) .send({ + shapeUuid, 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", }); diaryUuid = createDiaryPost.body.uuid; }); afterAll(async () => { + await transactionalContext.finish(); await app.close(); }); it("정상 요청 시 200 OK 응답", async () => { - const postResponse = await request(app.getHttpServer()) + await request(app.getHttpServer()) .delete(`/diaries/${diaryUuid}`) .set("Authorization", `Bearer ${accessToken}`) .expect(204); @@ -73,9 +87,7 @@ describe("[일기 삭제] /diaries/:uuid DELETE e2e 테스트", () => { .delete(`/diaries/${diaryUuid}`) .expect(401); - const body = JSON.parse(postResponse.text); - - expect(body.message).toBe("비로그인 상태의 요청입니다."); + expect(postResponse.body.message).toBe("비로그인 상태의 요청입니다."); }); it("존재하지 않는 일기에 대한 요청 시 404 Not Found 응답", async () => { @@ -84,20 +96,16 @@ describe("[일기 삭제] /diaries/:uuid DELETE e2e 테스트", () => { .set("Authorization", `Bearer ${accessToken}`) .expect(404); - const body = JSON.parse(postResponse.text); - - expect(body.message).toContain("존재하지 않는 일기입니다."); + expect(postResponse.body.message).toContain("존재하지 않는 일기입니다."); }); - // 유저 회원가입 및 로그인 후 글 생성하고 commonUser에서 해당 글에 대해 삭제 요청 보내기 - // it("타인의 일기에 대한 요청 시 404 Not Found 응답", async () => { - // const postResponse = await request(app.getHttpServer()) - // .delete(`/diaries/${diaryUuid}`) - // .set("Authorization", `Bearer ${accessToken}`) - // .expect(204); - - // const body = JSON.parse(postResponse.text); + it("타인의 일기에 대한 요청 시 404 Not Found 응답", async () => { + const unauthorizedDiaryUuid = "aaaf869f-a822-48dd-8306-be4bac319f75"; + const postResponse = await request(app.getHttpServer()) + .delete(`/diaries/${unauthorizedDiaryUuid}`) + .set("Authorization", `Bearer ${accessToken}`) + .expect(404); - // expect(body.message).toContain("존재하지 않는 일기입니다."); - // }); + expect(postResponse.body.message).toContain("존재하지 않는 일기입니다."); + }); }); diff --git a/BE/test/e2e/diaries.read-list.e2e-spec.ts b/BE/test/e2e/diaries.read-list.e2e-spec.ts index 9e0a007..a9a9dfd 100644 --- a/BE/test/e2e/diaries.read-list.e2e-spec.ts +++ b/BE/test/e2e/diaries.read-list.e2e-spec.ts @@ -6,9 +6,13 @@ import { DiariesModule } from "src/diaries/diaries.module"; import { typeORMTestConfig } from "src/configs/typeorm.test.config"; import { TypeOrmModule } from "@nestjs/typeorm"; import { RedisModule } from "@liaoliaots/nestjs-redis"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; describe("[전체 일기 조회] /diaries GET e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; let accessToken: string; beforeAll(async () => { @@ -32,6 +36,10 @@ describe("[전체 일기 조회] /diaries GET e2e 테스트", () => { await app.init(); + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); + const signInPost = await request(app.getHttpServer()) .post("/auth/signin") .send({ @@ -43,19 +51,18 @@ describe("[전체 일기 조회] /diaries GET e2e 테스트", () => { }); afterAll(async () => { + await transactionalContext.finish(); await app.close(); }); it("정상 요청 시 200 OK 응답", async () => { - const postResponse = await request(app.getHttpServer()) + await request(app.getHttpServer()) .get("/diaries") .set("Authorization", `Bearer ${accessToken}`) .expect(200); }); it("액세스 토큰 없이 요청 시 401 Unauthorized 응답", async () => { - const postResponse = await request(app.getHttpServer()) - .get("/diaries") - .expect(401); + await request(app.getHttpServer()).get("/diaries").expect(401); }); }); diff --git a/BE/test/e2e/diaries.read.e2e-spec.ts b/BE/test/e2e/diaries.read.e2e-spec.ts index bfa2bd4..276ed93 100644 --- a/BE/test/e2e/diaries.read.e2e-spec.ts +++ b/BE/test/e2e/diaries.read.e2e-spec.ts @@ -8,9 +8,13 @@ import { typeORMTestConfig } from "src/configs/typeorm.test.config"; import { TypeOrmModule } from "@nestjs/typeorm"; import { ShapesModule } from "src/shapes/shapes.module"; import { RedisModule } from "@liaoliaots/nestjs-redis"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; describe("[일기 조회] /diaries/:uuid GET e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; let accessToken: string; let diaryUuid: string; let shapeUuid: string; @@ -39,6 +43,10 @@ describe("[일기 조회] /diaries/:uuid GET e2e 테스트", () => { await app.init(); + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); + const signInPost = await request(app.getHttpServer()) .post("/auth/signin") .send({ @@ -69,6 +77,7 @@ describe("[일기 조회] /diaries/:uuid GET e2e 테스트", () => { }); afterAll(async () => { + await transactionalContext.finish(); await app.close(); }); @@ -110,9 +119,7 @@ describe("[일기 조회] /diaries/:uuid GET e2e 테스트", () => { .get(`/diaries/${diaryUuid}`) .expect(401); - const body = postResponse.body; - - expect(body.message).toBe("비로그인 상태의 요청입니다."); + expect(postResponse.body.message).toBe("비로그인 상태의 요청입니다."); }); it("만료된 토큰 요청 시 401 Unauthorized 응답", async () => { @@ -125,8 +132,8 @@ describe("[일기 조회] /diaries/:uuid GET e2e 테스트", () => { const body = postResponse.body; expect( - postResponse.body.message === "토큰이 만료되었습니다." || - postResponse.body.message === "유효하지 않은 토큰입니다.", + body.message === "토큰이 만료되었습니다." || + body.message === "유효하지 않은 토큰입니다.", ).toBeTruthy(); }); @@ -142,4 +149,18 @@ describe("[일기 조회] /diaries/:uuid GET e2e 테스트", () => { statusCode: 404, }); }); + + it("타인의 일기에 대한 요청 시 404 Not Found 응답", async () => { + const unauthorizedDiaryUuid = "aaaf869f-a822-48dd-8306-be4bac319f75"; + const postResponse = await request(app.getHttpServer()) + .delete(`/diaries/${unauthorizedDiaryUuid}`) + .set("Authorization", `Bearer ${accessToken}`) + .expect(404); + + expect(postResponse.body).toEqual({ + error: "Not Found", + message: "존재하지 않는 일기입니다.", + statusCode: 404, + }); + }); }); diff --git a/BE/test/e2e/diaries.update.e2e-spec.ts b/BE/test/e2e/diaries.update.e2e-spec.ts index ff05bd7..5f54c93 100644 --- a/BE/test/e2e/diaries.update.e2e-spec.ts +++ b/BE/test/e2e/diaries.update.e2e-spec.ts @@ -8,9 +8,13 @@ import { typeORMTestConfig } from "src/configs/typeorm.test.config"; import { TypeOrmModule } from "@nestjs/typeorm"; import { ShapesModule } from "src/shapes/shapes.module"; import { RedisModule } from "@liaoliaots/nestjs-redis"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; describe("[일기 수정] /diaries PUT e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; let accessToken: string; let diaryUuid: string; let shapeUuid: string; @@ -66,9 +70,14 @@ describe("[일기 수정] /diaries PUT e2e 테스트", () => { }); diaryUuid = createResponse.body.uuid; + + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); }); afterAll(async () => { + await transactionalContext.finish(); await app.close(); }); @@ -213,132 +222,142 @@ describe("[일기 수정] /diaries PUT e2e 테스트", () => { }); it("빈 값을 포함한 요청 시 400 Bad Request 응답", async () => { - let postResponse; - - // uuid가 없는 경우 - postResponse = await request(app.getHttpServer()) - .put("/diaries") - .send({ - shapeUuid, - title: "title", - content: "this is content.", - date: "2023-11-14", - point: "1.5,5.5,10.55", - tags: ["tagTest", "tagTest2"], - }) - .set("Authorization", `Bearer ${accessToken}`) - .expect(400); - - expect(postResponse.body.message).toContain( - "일기 uuid는 비어있지 않아야 합니다.", - ); - - // 제목이 없는 경우 - postResponse = await request(app.getHttpServer()) - .put("/diaries") - .send({ - uuid: diaryUuid, - shapeUuid, - content: "this is content.", - point: "1.5,5.5,10.55", - date: "2023-11-14", - tags: ["tagTest", "tagTest2"], - }) - .set("Authorization", `Bearer ${accessToken}`) - .expect(400); - - expect(postResponse.body.message).toContain( - "제목은 비어있지 않아야 합니다.", - ); - - // 좌표가 없는 경우 - postResponse = await request(app.getHttpServer()) - .put("/diaries") - .send({ - uuid: diaryUuid, - shapeUuid, - title: "title", - content: "this is content.", - date: "2023-11-14", - tags: ["tagTest", "tagTest2"], - }) - .set("Authorization", `Bearer ${accessToken}`) - .expect(400); - - expect(postResponse.body.message).toContain( - "좌표는 비어있지 않아야 합니다.", - ); - - // 날짜가 없는 경우 - postResponse = await request(app.getHttpServer()) - .put("/diaries") - .send({ - uuid: diaryUuid, - shapeUuid, - title: "title", - content: "this is content.", - point: "1.5,5.5,10.55", - tags: ["tagTest", "tagTest2"], - }) - .set("Authorization", `Bearer ${accessToken}`) - .expect(400); - - expect(postResponse.body.message).toContain( - "날짜는 비어있지 않아야 합니다.", - ); + { + // uuid가 없는 경우 + const postResponse = await request(app.getHttpServer()) + .put("/diaries") + .send({ + shapeUuid, + title: "title", + content: "this is content.", + date: "2023-11-14", + point: "1.5,5.5,10.55", + tags: ["tagTest", "tagTest2"], + }) + .set("Authorization", `Bearer ${accessToken}`) + .expect(400); + + expect(postResponse.body.message).toContain( + "일기 uuid는 비어있지 않아야 합니다.", + ); + } + + { + // 제목이 없는 경우 + const postResponse = await request(app.getHttpServer()) + .put("/diaries") + .send({ + uuid: diaryUuid, + shapeUuid, + content: "this is content.", + point: "1.5,5.5,10.55", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + }) + .set("Authorization", `Bearer ${accessToken}`) + .expect(400); + + expect(postResponse.body.message).toContain( + "제목은 비어있지 않아야 합니다.", + ); + } + + { + // 좌표가 없는 경우 + const postResponse = await request(app.getHttpServer()) + .put("/diaries") + .send({ + uuid: diaryUuid, + shapeUuid, + title: "title", + content: "this is content.", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + }) + .set("Authorization", `Bearer ${accessToken}`) + .expect(400); + + expect(postResponse.body.message).toContain( + "좌표는 비어있지 않아야 합니다.", + ); + } + + { + // 날짜가 없는 경우 + const postResponse = await request(app.getHttpServer()) + .put("/diaries") + .send({ + uuid: diaryUuid, + shapeUuid, + title: "title", + content: "this is content.", + point: "1.5,5.5,10.55", + tags: ["tagTest", "tagTest2"], + }) + .set("Authorization", `Bearer ${accessToken}`) + .expect(400); + + expect(postResponse.body.message).toContain( + "날짜는 비어있지 않아야 합니다.", + ); + } + + { + // 모양 uuid가 없는 경우 + const postResponse = await request(app.getHttpServer()) + .put("/diaries") + .send({ + uuid: diaryUuid, + title: "title", + content: "this is content.", + point: "1.5,5.5,10.55", + date: "2023-11-14", + tags: ["tagTest", "tagTest2"], + }) + .set("Authorization", `Bearer ${accessToken}`) + .expect(400); + + expect(postResponse.body.message).toContain( + "모양 uuid는 비어있지 않아야 합니다.", + ); + } + + { + // 복수의 데이터가 없는 경우 + const postResponse = await request(app.getHttpServer()) + .put("/diaries") + .send({ + uuid: diaryUuid, + title: "title", + content: "this is content.", + tags: ["tagTest", "tagTest2"], + }) + .set("Authorization", `Bearer ${accessToken}`) + .expect(400); + + expect(postResponse.body.message).toContain( + "날짜는 비어있지 않아야 합니다.", + ); + expect(postResponse.body.message).toContain( + "좌표는 비어있지 않아야 합니다.", + ); + expect(postResponse.body.message).toContain( + "모양 uuid는 비어있지 않아야 합니다.", + ); + } + }); - // 모양 uuid가 없는 경우 - postResponse = await request(app.getHttpServer()) - .put("/diaries") - .send({ - uuid: diaryUuid, - title: "title", - content: "this is content.", - point: "1.5,5.5,10.55", - date: "2023-11-14", - tags: ["tagTest", "tagTest2"], - }) + it("타인의 일기에 대한 요청 시 404 Not Found 응답", async () => { + const unauthorizedDiaryUuid = "aaaf869f-a822-48dd-8306-be4bac319f75"; + const postResponse = await request(app.getHttpServer()) + .get(`/diaries/${unauthorizedDiaryUuid}`) .set("Authorization", `Bearer ${accessToken}`) - .expect(400); - - expect(postResponse.body.message).toContain( - "모양 uuid는 비어있지 않아야 합니다.", - ); + .expect(404); - // 복수의 데이터가 없는 경우 - postResponse = await request(app.getHttpServer()) - .put("/diaries") - .send({ - title: "title", - content: "this is content.", - tags: ["tagTest", "tagTest2"], - }) - .set("Authorization", `Bearer ${accessToken}`) - .expect(400); - - expect(postResponse.body.message).toContain( - "날짜는 비어있지 않아야 합니다.", - ); - expect(postResponse.body.message).toContain( - "좌표는 비어있지 않아야 합니다.", - ); - expect(postResponse.body.message).toContain( - "모양 uuid는 비어있지 않아야 합니다.", - ); + expect(postResponse.body).toEqual({ + error: "Not Found", + message: "존재하지 않는 일기입니다.", + statusCode: 404, + }); }); }); -// 유저 회원가입 및 로그인 후 글 생성하고 commonUser에서 해당 글에 대해 조회 요청 보내기 -// it("타인의 일기에 대한 요청 시 404 Not Found 응답", async () => { -// const postResponse = await request(app.getHttpServer()) -// .get(`/diaries/${unauthorizedDiaryUuid}`) -// .set("Authorization", `Bearer ${accessToken}`) -// .expect(404); - -// co - -// expect(postResponse.body).toEqual({ -// error: "Not Found", -// message: "존재하지 않는 일기입니다.", -// statusCode: 404, -// }); -// }); diff --git a/BE/test/e2e/purchase.design-list.e2e-spec.ts b/BE/test/e2e/purchase.design-list.e2e-spec.ts index d649535..640e4cf 100644 --- a/BE/test/e2e/purchase.design-list.e2e-spec.ts +++ b/BE/test/e2e/purchase.design-list.e2e-spec.ts @@ -5,14 +5,16 @@ import { ValidationPipe } from "@nestjs/common"; import { typeORMTestConfig } from "src/configs/typeorm.test.config"; import { TypeOrmModule } from "@nestjs/typeorm"; import { RedisModule } from "@liaoliaots/nestjs-redis"; -import { clearUserDb } from "src/utils/clearDb"; import { UsersRepository } from "src/auth/users.repository"; import { AuthModule } from "src/auth/auth.module"; import { PurchaseModule } from "src/purchase/purchase.module"; -import { User } from "src/auth/users.entity"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; -describe("[디자인 구매 내역 조회] /purchase/design GET e2e 테스트", () => { +describe("[별숲 상점] /purchase e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; let accessToken: string; beforeAll(async () => { @@ -32,67 +34,172 @@ describe("[디자인 구매 내역 조회] /purchase/design GET e2e 테스트", providers: [UsersRepository], }).compile(); - let usersRepository = moduleFixture.get(UsersRepository); - - await clearUserDb(moduleFixture, usersRepository); - app = moduleFixture.createNestApplication(); app.enableCors(); app.useGlobalPipes(new ValidationPipe()); await app.init(); + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); + const signInPost = await request(app.getHttpServer()) .post("/auth/signin") .send({ - userId: "commonUser", - password: process.env.COMMON_USER_PASS, + userId: "oldUser", + password: process.env.OLD_USER_PASS, }); accessToken = signInPost.body.accessToken; + }); - // 1000 별가루 충전 - const user = await User.findOne({ where: { userId: "commonUser" } }); - user.credit = 1000; - await user.save(); + afterAll(async () => { + await transactionalContext.finish(); + await app.close(); + }); - // 디자인 구매 - await request(app.getHttpServer()) - .post("/purchase/design") - .set("Authorization", `Bearer ${accessToken}`) - .send({ - domain: "GROUND", - design: "GROUND_GREEN", - }); + describe("[별숲 상점] /purchase/design GET e2e 테스트", () => { + it("정상 요청 시 200 OK 응답", async () => { + const getResponse = await request(app.getHttpServer()) + .get("/purchase/design") + .set("Authorization", `Bearer ${accessToken}`) + .expect(200); - await request(app.getHttpServer()) - .post("/purchase/design") - .set("Authorization", `Bearer ${accessToken}`) - .send({ - domain: "GROUND", - design: "GROUND_MOCHA", + expect(getResponse.body).toStrictEqual({ + ground: ["ground_2d"], }); - }); + }); - afterAll(async () => { - await app.close(); + it("유효하지 않은 토큰 요청 시 401 Unauthorized 응답", async () => { + const getResponse = await request(app.getHttpServer()) + .get("/purchase/design") + .expect(401); + }); + + it("중복 구매 시 401 Unauthorized 응답", async () => { + const postResponse = await request(app.getHttpServer()) + .post("/purchase/design") + .send({ + domain: "GROUND", + design: "GROUND_2D", + }) + .set("Authorization", `Bearer ${accessToken}`) + .expect(400); + + expect(postResponse.body.message).toBe("이미 구매한 디자인입니다."); + }); }); - it("정상 요청 시 200 OK 응답", async () => { - const getResponse = await request(app.getHttpServer()) - .get("/purchase/design") - .set("Authorization", `Bearer ${accessToken}`) - .expect(200); + describe("[별숲 상점] /purchase/premium GET e2e 테스트", () => { + it("정상 요청 시 200 OK 응답", async () => { + const getResponse = await request(app.getHttpServer()) + .get("/purchase/premium") + .set("Authorization", `Bearer ${accessToken}`) + .expect(200); + + expect(getResponse.body).toStrictEqual({ + premium: "TRUE", + }); + }); + + it("유효하지 않은 토큰 요청 시 401 Unauthorized 응답", async () => { + const getResponse = await request(app.getHttpServer()) + .get("/purchase/premium") + .expect(401); + }); + + it("중복 구매 시 401 Unauthorized 응답", async () => { + const postResponse = await request(app.getHttpServer()) + .post("/purchase/premium") + .set("Authorization", `Bearer ${accessToken}`) + .expect(400); - expect(getResponse.body).toStrictEqual({ - ground: ["#254117", "#493D26"], - sky: [], + expect(postResponse.body.message).toBe("이미 프리미엄 사용자입니다."); }); }); - it("유효하지 않은 토큰 요청 시 401 Unauthorized 응답", async () => { - const getResponse = await request(app.getHttpServer()) - .get("/purchase/design") - .expect(401); + describe("[별숲 상점] /purchase POST e2e 테스트", () => { + it("디자인 구매 정상 요청 201 Created 응답", async () => { + const kakaoUser = await request(app.getHttpServer()) + .post("/auth/signin") + .send({ + userId: "kakaoUser", + password: process.env.OLD_USER_PASS, + }); + + const kakaoUserAccessToken = kakaoUser.body.accessToken; + + const postResponse = await request(app.getHttpServer()) + .post("/purchase/design") + .send({ + domain: "GROUND", + design: "GROUND_2D", + }) + .set("Authorization", `Bearer ${kakaoUserAccessToken}`) + .expect(200); + + expect(postResponse.body).toStrictEqual({ + credit: 500, + }); + }); + + it("프리미엄 구매 정상 요청 201 Created 응답", async () => { + const naverUser = await request(app.getHttpServer()) + .post("/auth/signin") + .send({ + userId: "naverUser", + password: process.env.OLD_USER_PASS, + }); + + const naverUserAccessToken = naverUser.body.accessToken; + + const postResponse = await request(app.getHttpServer()) + .post("/purchase/premium") + .send({}) + .set("Authorization", `Bearer ${naverUserAccessToken}`) + .expect(200); + + expect(postResponse.body).toStrictEqual({ + credit: 150, + }); + }); + + it("별가루 부족한 경우 400 Bad Request 응답", async () => { + const newUser = await request(app.getHttpServer()) + .post("/auth/signin") + .send({ + userId: "newUser", + password: process.env.OLD_USER_PASS, + }); + + const newUserAccessToken = newUser.body.accessToken; + + { + const postResponse = await request(app.getHttpServer()) + .post("/purchase/design") + .send({ + domain: "GROUND", + design: "GROUND_2D", + }) + .set("Authorization", `Bearer ${newUserAccessToken}`) + .expect(400); + + expect(postResponse.body.message).toBe( + "보유한 별가루가 부족합니다. 현재 0 별가루", + ); + } + + { + const postResponse = await request(app.getHttpServer()) + .post("/purchase/premium") + .set("Authorization", `Bearer ${newUserAccessToken}`) + .expect(400); + + expect(postResponse.body.message).toBe( + "보유한 별가루가 부족합니다. 현재 0 별가루", + ); + } + }); }); }); diff --git a/BE/test/e2e/shape.read-list.e2e-spec.ts b/BE/test/e2e/shape.read-list.e2e-spec.ts index 46db604..3b346bb 100644 --- a/BE/test/e2e/shape.read-list.e2e-spec.ts +++ b/BE/test/e2e/shape.read-list.e2e-spec.ts @@ -6,12 +6,15 @@ import { typeORMTestConfig } from "src/configs/typeorm.test.config"; import { TypeOrmModule } from "@nestjs/typeorm"; import { RedisModule } from "@liaoliaots/nestjs-redis"; import { ShapesModule } from "src/shapes/shapes.module"; -import { clearUserDb } from "src/utils/clearDb"; import { UsersRepository } from "src/auth/users.repository"; import { AuthModule } from "src/auth/auth.module"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; describe("[전체 모양 조회] /shapes GET e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; let accessToken: string; beforeAll(async () => { @@ -31,16 +34,16 @@ describe("[전체 모양 조회] /shapes GET e2e 테스트", () => { providers: [UsersRepository], }).compile(); - let usersRepository = moduleFixture.get(UsersRepository); - - await clearUserDb(moduleFixture, usersRepository); - app = moduleFixture.createNestApplication(); app.enableCors(); app.useGlobalPipes(new ValidationPipe()); await app.init(); + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); + const signInPost = await request(app.getHttpServer()) .post("/auth/signin") .send({ @@ -52,6 +55,7 @@ describe("[전체 모양 조회] /shapes GET e2e 테스트", () => { }); afterAll(async () => { + await transactionalContext.finish(); await app.close(); }); @@ -64,19 +68,12 @@ describe("[전체 모양 조회] /shapes GET e2e 테스트", () => { expect(Object.keys(postResponse.body).length).toEqual(15); }); - it("일반 유저 정상 요청 시 200 OK 응답", async () => { - await request(app.getHttpServer()).post("/auth/signup").send({ - userId: "userId", - password: "password", - email: "email@email.com", - nickname: "nickname", - }); - + it("기존 유저 정상 요청 시 200 OK 응답", async () => { const signInPost = await request(app.getHttpServer()) .post("/auth/signin") .send({ - userId: "userId", - password: "password", + userId: "oldUser", + password: process.env.OLD_USER_PASS, }); accessToken = signInPost.body.accessToken; diff --git a/BE/test/e2e/stat.diaries.e2e-spec.ts b/BE/test/e2e/stat.diaries.e2e-spec.ts index a47ff14..d8f0a8f 100644 --- a/BE/test/e2e/stat.diaries.e2e-spec.ts +++ b/BE/test/e2e/stat.diaries.e2e-spec.ts @@ -8,9 +8,13 @@ import { RedisModule } from "@liaoliaots/nestjs-redis"; import { AuthModule } from "src/auth/auth.module"; import { StatModule } from "src/stat/stat.module"; import { DiariesModule } from "src/diaries/diaries.module"; +import { DataSource } from "typeorm"; +import { TransactionalTestContext } from "typeorm-transactional-tests"; describe("[연도별, 날짜별 일기 작성 조회] /stat/diaries/:year GET e2e 테스트", () => { let app: INestApplication; + let dataSource: DataSource; + let transactionalContext: TransactionalTestContext; let accessToken: string; beforeAll(async () => { @@ -36,54 +40,133 @@ describe("[연도별, 날짜별 일기 작성 조회] /stat/diaries/:year GET e2 await app.init(); + dataSource = moduleFixture.get(DataSource); + transactionalContext = new TransactionalTestContext(dataSource); + await transactionalContext.start(); + const signInPost = await request(app.getHttpServer()) .post("/auth/signin") .send({ - userId: "commonUser", - password: process.env.COMMON_USER_PASS, + userId: "oldUser", + password: process.env.OLD_USER_PASS, }); accessToken = signInPost.body.accessToken; - - for (let i = 1; i <= 3; i++) { - await request(app.getHttpServer()) - .post("/diaries") - .set("Authorization", `Bearer ${accessToken}`) - .send({ - title: "stat test", - content: "나는 행복해.", - point: "1.5,5.5,10.55", - date: `2023-08-0${i}`, - tags: ["tagTest"], - shapeUuid: "0c99bbc6-e404-464b-a310-5bf0fa0f0fa7", - }); - } }); afterAll(async () => { + await transactionalContext.finish(); await app.close(); }); - it("정상 요청 시 200 OK 응답", async () => { - const postResponse = await request(app.getHttpServer()) - .get("/stat/diaries/2023") - .set("Authorization", `Bearer ${accessToken}`) - .expect(200); + describe("[별숲 현황] /stat/diaries/:year GET e2e 테스트", () => { + it("정상 요청 시 200 OK 응답", async () => { + const postResponse = await request(app.getHttpServer()) + .get("/stat/diaries/2023") + .set("Authorization", `Bearer ${accessToken}`) + .expect(200); + + const expectedResult = { + "2023-01-03": { sentiment: "positive", count: 1 }, + "2023-01-06": { sentiment: "neutral", count: 1 }, + "2023-02-22": { sentiment: "neutral", count: 1 }, + "2023-03-03": { sentiment: "negative", count: 1 }, + "2023-03-17": { sentiment: "positive", count: 1 }, + "2023-05-20": { sentiment: "negative", count: 1 }, + "2023-06-06": { sentiment: "negative", count: 1 }, + "2023-08-01": { sentiment: "positive", count: 1 }, + "2023-09-04": { sentiment: "neutral", count: 1 }, + "2023-09-23": { sentiment: "positive", count: 1 }, + "2023-10-01": { sentiment: "negative", count: 1 }, + "2023-10-10": { sentiment: "negative", count: 1 }, + "2023-10-29": { sentiment: "positive", count: 1 }, + "2023-11-01": { sentiment: "neutral", count: 1 }, + "2023-12-25": { sentiment: "neutral", count: 1 }, + }; + + expect(postResponse.body).toEqual(expectedResult); + }); + + it("액세스 토큰 없이 요청 시 401 Unauthorized 응답", async () => { + const postResponse = await request(app.getHttpServer()) + .get("/stat/diaries/2023") + .expect(401); + + expect(postResponse.body).toEqual({ + error: "Unauthorized", + message: "비로그인 상태의 요청입니다.", + statusCode: 401, + }); + }); + }); + + describe("[별숲 현황] /stat/tags-rank/:year GET e2e 테스트", () => { + it("정상 요청 시 200 OK 응답", async () => { + const postResponse = await request(app.getHttpServer()) + .get("/stat/tags-rank/2023") + .set("Authorization", `Bearer ${accessToken}`) + .expect(200); + + const expectedResult = { + first: { rank: 1, tag: "Old", id: 1, count: 15 }, + second: { rank: 2, tag: "중립", id: 8, count: 6 }, + third: { rank: 3, tag: "긍정", id: 3, count: 5 }, + }; + + expect(postResponse.body).toEqual(expectedResult); + }); - expect(Object.keys(postResponse.body).includes("2023-08-01")).toEqual(true); - expect(Object.keys(postResponse.body).includes("2023-08-02")).toEqual(true); - expect(Object.keys(postResponse.body).includes("2023-08-03")).toEqual(true); + it("액세스 토큰 없이 요청 시 401 Unauthorized 응답", async () => { + const postResponse = await request(app.getHttpServer()) + .get("/stat/tags-rank/2023") + .expect(401); + + expect(postResponse.body).toEqual({ + error: "Unauthorized", + message: "비로그인 상태의 요청입니다.", + statusCode: 401, + }); + }); }); - it("액세스 토큰 없이 요청 시 401 Unauthorized 응답", async () => { - const postResponse = await request(app.getHttpServer()) - .get("/stat/diaries/2023") - .expect(401); + describe("[별숲 현황] /stat/shapes-rank/:year GET e2e 테스트", () => { + it("정상 요청 시 200 OK 응답", async () => { + const postResponse = await request(app.getHttpServer()) + .get("/stat/shapes-rank/2023") + .set("Authorization", `Bearer ${accessToken}`) + .expect(200); + + const expectedResult = { + first: { + rank: 1, + uuid: "eaa0f81e-c6a8-4446-8c5a-44ea1a50bee8", + count: 6, + }, + second: { + rank: 2, + uuid: "43cb83db-8089-447c-a146-bfa07336528b", + count: 6, + }, + third: { + rank: 3, + uuid: "7774e2c6-f5b4-47f6-887d-63a6230b4a30", + count: 3, + }, + }; + + expect(postResponse.body).toEqual(expectedResult); + }); + + it("액세스 토큰 없이 요청 시 401 Unauthorized 응답", async () => { + const postResponse = await request(app.getHttpServer()) + .get("/stat/shapes-rank/2023") + .expect(401); - expect(postResponse.body).toEqual({ - error: "Unauthorized", - message: "비로그인 상태의 요청입니다.", - statusCode: 401, + expect(postResponse.body).toEqual({ + error: "Unauthorized", + message: "비로그인 상태의 요청입니다.", + statusCode: 401, + }); }); }); }); diff --git a/BE/test/int/auth.service.int-spec.ts b/BE/test/int/auth.service.int-spec.ts index f871f86..3fa60b4 100644 --- a/BE/test/int/auth.service.int-spec.ts +++ b/BE/test/int/auth.service.int-spec.ts @@ -105,7 +105,7 @@ describe("AuthService 통합 테스트", () => { it("메서드 정상 요청", async () => { const authCredentialsDto: AuthCredentialsDto = { userId: "oldUser", - password: "oldUser", + password: process.env.OLD_USER_PASS, }; const result = await authService.signIn(authCredentialsDto, request); @@ -145,7 +145,7 @@ describe("AuthService 통합 테스트", () => { it("메서드 정상 요청", async () => { const authCredentialsDto: AuthCredentialsDto = { userId: "oldUser", - password: "oldUser", + password: process.env.OLD_USER_PASS, }; await authService.signIn(authCredentialsDto, request); @@ -170,7 +170,7 @@ describe("AuthService 통합 테스트", () => { it("메서드 정상 요청", async () => { const authCredentialsDto: AuthCredentialsDto = { userId: "oldUser", - password: "oldUser", + password: process.env.OLD_USER_PASS, }; const { accessToken } = await authService.signIn( diff --git a/BE/test/int/shapes.repository.int-spec.ts b/BE/test/int/shapes.repository.int-spec.ts index 56b84f0..8a3781b 100644 --- a/BE/test/int/shapes.repository.int-spec.ts +++ b/BE/test/int/shapes.repository.int-spec.ts @@ -1,4 +1,3 @@ -import { NotFoundException } from "@nestjs/common"; import { Test, TestingModule } from "@nestjs/testing"; import { TypeOrmModule } from "@nestjs/typeorm"; import { User } from "src/auth/users.entity"; diff --git a/BE/test/int/shapes.service.int-spec.ts b/BE/test/int/shapes.service.int-spec.ts index 452e7de..85f46b3 100644 --- a/BE/test/int/shapes.service.int-spec.ts +++ b/BE/test/int/shapes.service.int-spec.ts @@ -51,8 +51,8 @@ describe("ShapesService 통합 테스트", () => { expect(shapes).toHaveLength(defaultShapes.length); expect(shapes.every((shape) => shape instanceof Shape)).toBe(true); - expect(shapes.map((shape) => shape.shapePath).sort()).toEqual( - defaultShapes.map((shape) => shape.shapePath).sort(), + expect(shapes.map((shape) => shape.shapePath)).toEqual( + expect.arrayContaining(defaultShapes.map((shape) => shape.shapePath)), ); }); }); diff --git a/BE/test/int/user.repository.int-spec.ts b/BE/test/int/user.repository.int-spec.ts index ac53df1..1168b22 100644 --- a/BE/test/int/user.repository.int-spec.ts +++ b/BE/test/int/user.repository.int-spec.ts @@ -1,8 +1,6 @@ -import { RedisModule } from "@liaoliaots/nestjs-redis"; import { Test, TestingModule } from "@nestjs/testing"; import { TypeOrmModule } from "@nestjs/typeorm"; import { typeORMTestConfig } from "src/configs/typeorm.test.config"; -import { AuthModule } from "src/auth/auth.module"; import { UsersRepository } from "src/auth/users.repository"; import { CreateUserDto } from "src/auth/dto/users.dto"; import { ConflictException } from "@nestjs/common";