diff --git a/frontend/__test__/api/categoryList.test.ts b/frontend/__test__/api/categoryList.test.ts new file mode 100644 index 000000000..eaf34f352 --- /dev/null +++ b/frontend/__test__/api/categoryList.test.ts @@ -0,0 +1,55 @@ +import { + addFavoriteCategory, + getGuestCategoryList, + getUserCategoryList, + removeFavoriteCategory, + transformCategoryListResponse, +} from '@api/wus/categoryList'; + +import { MOCK_CATEGORY_LIST, MOCK_GUEST_CATEGORY_LIST } from '@mocks/mockData/categoryList'; + +describe('카테고리에 대한 통신(카테고리 목록 조회, 즐겨찾기 추가, 제거)이 올바르게 작동하는 지 확인한다.', () => { + test('회원의 카테고리 정보를 불러올 수 있다.', async () => { + const data = await getUserCategoryList(); + + const expectResult = transformCategoryListResponse(MOCK_CATEGORY_LIST); + + expect(data).toEqual(expectResult); + }); + + test('비회원의 카테고리 정보를 불러올 수 있다.', async () => { + const data = await getGuestCategoryList(); + + const expectResult = transformCategoryListResponse(MOCK_GUEST_CATEGORY_LIST); + + expect(data).toEqual(expectResult); + }); + + test('회원이 카테고리 즐겨찾기를 할 수 있다.', async () => { + MOCK_CATEGORY_LIST[1].favorite = false; + + await addFavoriteCategory(MOCK_CATEGORY_LIST[1].id); + + const data = await getUserCategoryList(); + + expect(data[1].isFavorite).toBe(true); + }); + + test('회원이 카테고리 즐겨찾기를 해제할 수 있다.', async () => { + MOCK_CATEGORY_LIST[0].favorite = true; + + await removeFavoriteCategory(MOCK_CATEGORY_LIST[0].id); + + const data = await getUserCategoryList(); + + expect(data[0].isFavorite).toBe(false); + }); + + test('클라이언트에서 사용하는 API 명세가 [id, name, isFavorite]으로 존재해야한다.', async () => { + const data = await getGuestCategoryList(); + + const categoryKeys = Object.keys(data[0]); + + expect(categoryKeys).toEqual(['id', 'name', 'isFavorite']); + }); +}); diff --git a/frontend/src/api/wus/categoryList.ts b/frontend/src/api/wus/categoryList.ts new file mode 100644 index 000000000..d899874af --- /dev/null +++ b/frontend/src/api/wus/categoryList.ts @@ -0,0 +1,31 @@ +import { CategoryResponse } from '@type/category'; + +import { deleteFetch, getFetch, postFetch } from '@utils/fetch'; + +export const transformCategoryListResponse = (categoryList: CategoryResponse[]) => { + return categoryList.map(category => ({ + id: category.id, + name: category.name, + isFavorite: category.favorite, + })); +}; + +export const getUserCategoryList = async () => { + const categoryList = await getFetch('/categories'); + + return transformCategoryListResponse(categoryList); +}; + +export const getGuestCategoryList = async () => { + const categoryList = await getFetch('/categories/guest'); + + return transformCategoryListResponse(categoryList); +}; + +export const addFavoriteCategory = async (categoryId: number) => { + await postFetch(`/categories/${categoryId}/like`, ''); +}; + +export const removeFavoriteCategory = async (categoryId: number) => { + await deleteFetch(`/categories/${categoryId}/like`); +}; diff --git a/frontend/src/mocks/mockData/categoryList.ts b/frontend/src/mocks/mockData/categoryList.ts new file mode 100644 index 000000000..b8633d038 --- /dev/null +++ b/frontend/src/mocks/mockData/categoryList.ts @@ -0,0 +1,27 @@ +import { CategoryResponse } from '@type/category'; + +export const MOCK_CATEGORY_LIST: CategoryResponse[] = [ + { id: 1, name: '음식', favorite: false }, + { id: 2, name: '연애', favorite: true }, + { id: 3, name: '패션', favorite: false }, + { id: 4, name: '금융', favorite: false }, + { id: 5, name: '여행', favorite: false }, + { id: 6, name: '게임', favorite: false }, + { id: 7, name: '재테크', favorite: false }, + { id: 8, name: '요리', favorite: true }, + { id: 9, name: '개발', favorite: true }, + { id: 10, name: '전자기기', favorite: true }, +]; + +export const MOCK_GUEST_CATEGORY_LIST: CategoryResponse[] = [ + { id: 1, name: '음식', favorite: false }, + { id: 2, name: '연애', favorite: false }, + { id: 3, name: '패션', favorite: false }, + { id: 4, name: '금융', favorite: false }, + { id: 5, name: '여행', favorite: false }, + { id: 6, name: '게임', favorite: false }, + { id: 7, name: '재테크', favorite: false }, + { id: 8, name: '요리', favorite: false }, + { id: 9, name: '개발', favorite: false }, + { id: 10, name: '전자기기', favorite: false }, +]; diff --git a/frontend/src/mocks/wus/categoryList.ts b/frontend/src/mocks/wus/categoryList.ts new file mode 100644 index 000000000..0ad9ae89a --- /dev/null +++ b/frontend/src/mocks/wus/categoryList.ts @@ -0,0 +1,25 @@ +import { rest } from 'msw'; + +import { MOCK_CATEGORY_LIST, MOCK_GUEST_CATEGORY_LIST } from '@mocks/mockData/categoryList'; + +export const mockCategoryHandlers = [ + rest.get('/categories', (req, res, ctx) => { + return res(ctx.status(200), ctx.json(MOCK_CATEGORY_LIST)); + }), + + rest.get('/categories/guest', (req, res, ctx) => { + return res(ctx.status(200), ctx.json(MOCK_GUEST_CATEGORY_LIST)); + }), + + rest.post('/categories/:categoryId/like', (req, res, ctx) => { + MOCK_CATEGORY_LIST[1].favorite = true; + + return res(ctx.status(201), ctx.json({ message: 'ok' })); + }), + + rest.delete('/categories/:categoryId/like', (req, res, ctx) => { + MOCK_CATEGORY_LIST[0].favorite = false; + + return res(ctx.status(204), ctx.json({ message: 'ok' })); + }), +]; diff --git a/frontend/src/types/category.ts b/frontend/src/types/category.ts index 774301439..417bf7633 100644 --- a/frontend/src/types/category.ts +++ b/frontend/src/types/category.ts @@ -3,3 +3,9 @@ export interface Category { name: string; isFavorite: boolean; } + +export interface CategoryResponse { + id: number; + name: string; + favorite: boolean; +}