From 2c902bb28b4906061821db543b33131a220ecba5 Mon Sep 17 00:00:00 2001 From: jihwooon Date: Sat, 16 Mar 2024 17:34:07 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EC=9E=A5=EB=B0=94=EA=B5=AC=EB=8B=88=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=B0=8F=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 장바구니 추가 서비스 (server/src/cartItems/application/cartItem-save.service.ts)를 업데이트했습니다. - 사용자 인증을 위해 JWT 토큰 검증 로직(src/users/jwt/jwt.provider.ts)을 추가했습니다. - 서비스 함수 시그니처를 addToCart(userId: number, bookId: number, count: number)에서 addToCart(bookId: number, count: number, accessToken: any)으로 변경했습니다. - 테스트 코드 (server/src/cartItems/application/cartItem-save.service.test.ts)를 업데이트하여 변경된 서비스 로직을 검증합니다. - 모의 JWT 토큰을 테스트 케이스에 추가했습니다. - 유효하지 않은 토큰을 사용하는 경우 서비스가 예외를 발생시키는지 테스트합니다. - 장바구니 추가 컨트롤러 (server/src/cartItems/web/cartItem-save.controller.ts)를 업데이트했습니다. - 요청 헤더에서 JWT 토큰을 추출하여 서비스 함수에 전달합니다. --- .../application/cartItem-save.service.test.ts | 14 ++++++++++---- .../cartItems/application/cartItem-save.service.ts | 5 ++++- .../src/cartItems/web/cartItem-save.controller.ts | 5 +++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/server/src/cartItems/application/cartItem-save.service.test.ts b/server/src/cartItems/application/cartItem-save.service.test.ts index 1b59734..f802ffd 100644 --- a/server/src/cartItems/application/cartItem-save.service.test.ts +++ b/server/src/cartItems/application/cartItem-save.service.test.ts @@ -4,19 +4,25 @@ import HttpException from 'src/utils/httpException'; import { StatusCodes } from 'http-status-codes'; +import { validateToken } from 'src/users/jwt/jwt.provider'; + +import { ACCESS_TOKEN } from 'src/fixture/jwt.fixture'; + import { save } from '../domain/cartItem.repository'; import { addToCart } from './cartItem-save.service'; jest.mock('../domain/cartItem.repository.ts'); +jest.mock('../../users/jwt/jwt.provider.ts'); describe('cartItem Service', () => { beforeEach(() => { + (validateToken as jest.Mock).mockResolvedValue({ userId: existingCartItem.userId }); (save as jest.Mock).mockResolvedValue(true); }); context('사용자 id와 도서 정보 id가 주어지고 수량을 추가하면', () => { it('true를 반환한다.', async () => { - const savedCartItems = await addToCart(existingCartItem.userId, existingCartItem.bookId, existingCartItem.count); + const savedCartItems = await addToCart(existingCartItem.bookId, existingCartItem.count, ACCESS_TOKEN); expect(savedCartItems).toBe(true); }); @@ -28,9 +34,9 @@ describe('cartItem Service', () => { }); it('error를 반환한다.', async () => { - await expect( - addToCart(nonExistingCartItem.userId, nonExistingCartItem.bookId, nonExistingCartItem.count), - ).rejects.toThrow(new HttpException('장바구니 추가에 실패했습니다.', StatusCodes.BAD_REQUEST)); + await expect(addToCart(nonExistingCartItem.bookId, nonExistingCartItem.count, ACCESS_TOKEN)).rejects.toThrow( + new HttpException('장바구니 추가에 실패했습니다.', StatusCodes.BAD_REQUEST), + ); }); }); }); diff --git a/server/src/cartItems/application/cartItem-save.service.ts b/server/src/cartItems/application/cartItem-save.service.ts index 5410cf8..bd5aa6b 100644 --- a/server/src/cartItems/application/cartItem-save.service.ts +++ b/server/src/cartItems/application/cartItem-save.service.ts @@ -1,10 +1,13 @@ import { StatusCodes } from 'http-status-codes'; import HttpException from 'src/utils/httpException'; +import { validateToken } from 'src/users/jwt/jwt.provider'; + import CartItem from '../domain/cartItem'; import { save } from '../domain/cartItem.repository'; -export const addToCart = async (userId: number, bookId: number, count: number): Promise => { +export const addToCart = async (bookId: number, count: number, accessToken: any): Promise => { + const { userId } = validateToken(accessToken); const cartItems = CartItem.createCartItems(userId, bookId, count); const savedCartItems = await save(cartItems); diff --git a/server/src/cartItems/web/cartItem-save.controller.ts b/server/src/cartItems/web/cartItem-save.controller.ts index 4bea887..219c923 100644 --- a/server/src/cartItems/web/cartItem-save.controller.ts +++ b/server/src/cartItems/web/cartItem-save.controller.ts @@ -5,8 +5,9 @@ import { ResponseHandler } from 'src/utils/responseHandler'; import { addToCart } from '../application/cartItem-save.service'; -const addCartHandler = async ({ body: { userId, bookId, count } }: Request, res: Response) => { - ResponseHandler(() => addToCart(Number(userId), Number(bookId), Number(count)), StatusCodes.CREATED, res); +const addCartHandler = async ({ body: { bookId, count }, headers }: Request, res: Response) => { + const accessToken = headers.authorization; + ResponseHandler(() => addToCart(Number(bookId), Number(count), accessToken), StatusCodes.CREATED, res); }; export default addCartHandler; From 7d8484675471f24aabc2c8631a10f5ff2e32a114 Mon Sep 17 00:00:00 2001 From: jihwooon Date: Sat, 16 Mar 2024 17:59:42 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EC=9E=A5=EB=B0=94=EA=B5=AC=EB=8B=88=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EB=B0=8F=20=EB=AA=A9=EB=A1=9D=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4,=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 장바구니 조회 및 목록 서비스 (server/src/cartItems/application/cartItem-list.service.ts)를 업데이트했습니다. - 사용자 인증을 위해 JWT 토큰 검증 로직(src/users/jwt/jwt.provider.ts)을 추가했습니다. - 서비스 함수 시그니처를 getCartItems(userId: number, selectedId: number[])에서 getCartItems(accessToken: any, selectedId: number[])으로 변경했습니다. - 테스트 코드 (server/src/cartItems/application/cartItem-list.service.test.ts)를 업데이트하여 변경된 서비스 로직을 검증합니다. - 모의 JWT 토큰을 테스트 케이스에 추가했습니다. - 장바구니 조회 컨트롤러 (server/src/cartItems/web/cartItem-list.controller.ts)를 업데이트했습니다. - 요청 헤더에서 JWT 토큰을 추출하여 서비스 함수에 전달합니다. --- .../application/cartItem-list.service.test.ts | 16 +++++++++++----- .../application/cartItem-list.service.ts | 5 ++++- .../application/cartItem-remove.service.ts | 4 ++-- .../cartItems/web/cartItem-list.controller.ts | 5 +++-- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/server/src/cartItems/application/cartItem-list.service.test.ts b/server/src/cartItems/application/cartItem-list.service.test.ts index 3aee876..06a478d 100644 --- a/server/src/cartItems/application/cartItem-list.service.test.ts +++ b/server/src/cartItems/application/cartItem-list.service.test.ts @@ -1,4 +1,4 @@ -import { existingCartItem, existingCartItems, nonExistingCartItem } from 'src/fixture/cartItem.fixture'; +import { existingCartItems, nonExistingCartItem } from 'src/fixture/cartItem.fixture'; import { when } from 'jest-when'; @@ -6,24 +6,30 @@ import HttpException from 'src/utils/httpException'; import { StatusCodes } from 'http-status-codes'; +import { existingLike } from 'src/fixture/likes.fixture'; + +import { validateToken } from 'src/users/jwt/jwt.provider'; + +import { ACCESS_TOKEN } from 'src/fixture/jwt.fixture'; + import { findCartItemWithBook } from '../domain/cartItem.repository'; import { getCartItems } from './cartItem-list.service'; jest.mock('../domain/cartItem.repository.ts'); +jest.mock('../../users/jwt/jwt.provider.ts'); describe('cartItem Service', () => { const SelectedCartItem = [1, 4]; const notSelectedCartItem = [9999, 9999]; beforeEach(() => { - when(findCartItemWithBook as jest.Mock) - .calledWith(existingCartItem.userId, SelectedCartItem) - .mockResolvedValue(existingCartItems); + when(validateToken as jest.Mock).mockResolvedValue({ userId: existingLike.userId }); + when(findCartItemWithBook as jest.Mock).mockResolvedValue(existingCartItems); }); context('사용자 정보 id와 장바구니 상품을 선택하면', () => { it('장바구니 도서 목록을 반환한다.', async () => { - const cartItems = await getCartItems(existingCartItem.userId, SelectedCartItem); + const cartItems = await getCartItems(ACCESS_TOKEN, SelectedCartItem); expect(cartItems).toStrictEqual([ { diff --git a/server/src/cartItems/application/cartItem-list.service.ts b/server/src/cartItems/application/cartItem-list.service.ts index ddbce10..fa1816d 100644 --- a/server/src/cartItems/application/cartItem-list.service.ts +++ b/server/src/cartItems/application/cartItem-list.service.ts @@ -3,10 +3,13 @@ import HttpException from 'src/utils/httpException'; import { StatusCodes } from 'http-status-codes'; +import { validateToken } from 'src/users/jwt/jwt.provider'; + import type CartItem from '../domain/cartItem'; import { findCartItemWithBook } from '../domain/cartItem.repository'; -export const getCartItems = async (userId: number, selectedId: number[]) => { +export const getCartItems = async (accessToken: any, selectedId: number[]) => { + const { userId } = validateToken(accessToken); const cartItems = await findCartItemWithBook(userId, selectedId); if (cartItems.length === 0) { throw new HttpException('장바구니가 내 도서 정보가 존재하지 않습니다.', StatusCodes.NOT_FOUND); diff --git a/server/src/cartItems/application/cartItem-remove.service.ts b/server/src/cartItems/application/cartItem-remove.service.ts index d147b8e..abbb221 100644 --- a/server/src/cartItems/application/cartItem-remove.service.ts +++ b/server/src/cartItems/application/cartItem-remove.service.ts @@ -3,8 +3,8 @@ import HttpException from 'src/utils/httpException'; import { deleteById } from '../domain/cartItem.repository'; -export const removeToCart = async (id: number) => { - const removedCart = await deleteById(id); +export const removeToCart = async (cartItemId: number) => { + const removedCart = await deleteById(cartItemId); if (!removedCart) { throw new HttpException('장바구니 제거에 실패했습니다.', StatusCodes.BAD_REQUEST); } diff --git a/server/src/cartItems/web/cartItem-list.controller.ts b/server/src/cartItems/web/cartItem-list.controller.ts index d142283..9ddcb61 100644 --- a/server/src/cartItems/web/cartItem-list.controller.ts +++ b/server/src/cartItems/web/cartItem-list.controller.ts @@ -5,8 +5,9 @@ import { ResponseHandler } from 'src/utils/responseHandler'; import { getCartItems } from '../application/cartItem-list.service'; -const getCartHandler = async ({ body: { userId, selectedId } }: Request, res: Response) => { - ResponseHandler(() => getCartItems(Number(userId), selectedId), StatusCodes.OK, res); +const getCartHandler = async ({ body: { selectedId }, headers }: Request, res: Response) => { + const accessToken = headers.authorization; + ResponseHandler(() => getCartItems(accessToken, selectedId), StatusCodes.OK, res); }; export default getCartHandler;