Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

배너 공지사항 조회 / 공지사항 목록 조회 / 공지사항 상세 조회 / 공지사항 수정 / 공지사항 삭제 / 공지사항 생성 api 구현 및 query hook 구현 #739

Merged
merged 32 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
823bf6f
feat: (#713) 이미지 모달 초기 셋팅
Gilpop8663 Oct 5, 2023
a174960
Merge branch 'feat/#713' of https://github.com/woowacourse-teams/2023…
Gilpop8663 Oct 6, 2023
b8bf29b
feat: (#713) 이미지 확대 모달 훅 구현 및 적용
Gilpop8663 Oct 6, 2023
be2314d
fix: (#723) Drawer 내부가 탭 기능이 안되던 버그 수정
Gilpop8663 Oct 6, 2023
4472e32
style: (#713) 이미지 확대 모달 CSS 속성 적용
Gilpop8663 Oct 6, 2023
0b634e7
style: (#713) 이미지 반응형 되도록 CSS 설정
Gilpop8663 Oct 6, 2023
2497e6d
feat: (#713) Post 컴포넌트에서 이미지 확대 모달 기능 적용
Gilpop8663 Oct 6, 2023
f6e43ea
fix: (#710) 선택지 사진이 정중앙 배치가 되도록 수정
Gilpop8663 Oct 6, 2023
eef1725
feat: (#732) 키보드 ctrl + enter을 눌렀을 때 댓글을 달 수 있도록 구현
Gilpop8663 Oct 11, 2023
73154a1
chore: (#732) 변수명 변경 및 개행 추가
Gilpop8663 Oct 11, 2023
f9df3ba
feat: (#732) Command 키 지원되도록 수정 및 댓글 저장 밑의 설명글 추가
Gilpop8663 Oct 12, 2023
e227674
style: (#732) 글자 크기 줄임
Gilpop8663 Oct 12, 2023
a773c2d
feat: (#737) 공지사항 모킹 데이터 생성
Gilpop8663 Oct 12, 2023
38b5e3c
feat: (#737) 공지사항 관련된 api 구현 및 테스트 코드 작성
Gilpop8663 Oct 12, 2023
518a59a
feat: (#737) 공지사항 관련 탄스텍 쿼리 훅 구현 및 테스트 코드 작성
Gilpop8663 Oct 12, 2023
fdf06a2
feat: (#737) 공지사항 목록 페이지네이션 구현 및 테스트 코드 작성
Gilpop8663 Oct 12, 2023
05fcb1b
feat: (#737) 공지사항 목록 페이지네이션 구현 및 테스트 코드 작성
Gilpop8663 Oct 12, 2023
662c7fb
chore: (#737) 중복되어 만든 훅 삭제
Gilpop8663 Oct 12, 2023
844a937
chore: (#737) 중복된 코드 삭제로 인한 테스트 코드 변경
Gilpop8663 Oct 12, 2023
a231c61
Merge branch 'feat/#713' of https://github.com/woowacourse-teams/2023…
Gilpop8663 Oct 13, 2023
fd0177f
chore: (#713) 스타일드 컴포넌트 코드 순서 변경
Gilpop8663 Oct 13, 2023
7b0230e
상세 게시글에서 이미지를 눌렀을 때 이미지가 확대되어져 보이는 모달이 보이도록 구현 (#713)
Gilpop8663 Oct 13, 2023
33f593f
style: (#732) 컨트롤 키 안내 문구 버튼 위로 이동
Gilpop8663 Oct 13, 2023
e6661b4
Cmd(Ctrl) + Enter를 입력했을 때 댓글이 작성되도록 구현 (#732)
Gilpop8663 Oct 13, 2023
2f051f9
feat: (#737) api에 현재 페이지, 전체 페이지 정보를 받도록 코드 업데이트
Gilpop8663 Oct 13, 2023
a714fc1
feat: (#737) 페이지네이션 방식의 공지사항 리스트 api 훅 구현
Gilpop8663 Oct 13, 2023
4f0dda5
feat: (#737) 사용자가 보게 될 데이터가 쌓이는 형태의 공지사항 목록 훅 구현 및 테스트 코드 추가 작성
Gilpop8663 Oct 13, 2023
814e3a2
Merge branch 'feat/#737' of https://github.com/woowacourse-teams/2023…
Gilpop8663 Oct 13, 2023
02364f6
chore: (#737) 어색한 한글 수정 및 사용하지 않는 코드 삭제
Gilpop8663 Oct 13, 2023
ccfda7f
chore: (#737) 어색하거나 불필요한 테스트 코드 문구 삭제
Gilpop8663 Oct 13, 2023
c016505
style: (#737) 1.2rem을 이미 존재하는 글로벌 스타일로 변경
Gilpop8663 Oct 16, 2023
1796d47
refactor: (#737) 유연한 타입 재사용을 위한 Omit 활용
Gilpop8663 Oct 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions frontend/__test__/api/notice.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import {
createNotice,
deleteNotice,
getBannerNotice,
getNoticeDetail,
getNoticeList,
modifyNotice,
} from '@api/notice';

import { MOCK_TRANSFORM_NOTICE, MOCK_TRANSFORM_NOTICE_LIST } from '@mocks/mockData/notice';
import { MOCK_NOTICE_TEST } from '@mocks/notice';

describe('서버와 통신하여 공지사항 관련된 api를 통신할 수 있어야 한다. ', () => {
test('공지사항을 생성한다.', async () => {
const data = {
title: '갤럭시',
content: '공지사항입니다',
deadline: '2023-10-12 15:13',
bannerTitle: '아이폰',
bannerSubtitle: '공지사항입니다',
};

await createNotice(data);

const result = MOCK_NOTICE_TEST;

expect(result).toBe(data.title);
});

test('배너 공지 사항을 조회한다.', async () => {
const result = await getBannerNotice();

expect(result).toEqual(MOCK_TRANSFORM_NOTICE);
});

test('공지 사항 목록을 조회한다.', async () => {
const result = await getNoticeList(0);

expect(result).toEqual(MOCK_TRANSFORM_NOTICE_LIST);
});

test('공지 사항의 상세 내용을 조회한다.', async () => {
const result = await getNoticeDetail(1);

expect(result).toEqual(MOCK_TRANSFORM_NOTICE);
});

test('공지 사항을 수정한다.', async () => {
const data = {
title: '아이폰입니다',
content: '공지사항입니다',
deadline: '2023-10-12 15:13',
bannerTitle: '아이폰',
bannerSubtitle: '공지사항입니다',
};

await modifyNotice({ noticeId: 0, notice: data });

const result = MOCK_NOTICE_TEST;

expect(result).toBe(data.title);
});

test('공지 사항을 삭제한다.', async () => {
await deleteNotice(1);

const result = MOCK_NOTICE_TEST;

expect(result).toBe('삭제된 공지사항');
});
});
24 changes: 24 additions & 0 deletions frontend/__test__/hooks/query/notice/useBannerNotice.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React, { ReactNode } from 'react';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { renderHook, waitFor } from '@testing-library/react';

import { useBannerNotice } from '@hooks';

import { MOCK_TRANSFORM_NOTICE } from '@mocks/mockData/notice';

const queryClient = new QueryClient();

const wrapper = ({ children }: { children: ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);

describe('배너 공지사항을 불러오는지 확인한다.', () => {
test('배너 공지사항을 확인한다', async () => {
const { result } = renderHook(() => useBannerNotice(), {
wrapper,
});

await waitFor(() => expect(result.current.data).toEqual(MOCK_TRANSFORM_NOTICE));
});
});
38 changes: 38 additions & 0 deletions frontend/__test__/hooks/query/notice/useCreateNotice.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { ReactNode } from 'react';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { renderHook, waitFor } from '@testing-library/react';

import { useCreateNotice } from '@hooks';

import { MOCK_NOTICE_TEST } from '@mocks/notice';

const queryClient = new QueryClient();

const wrapper = ({ children }: { children: ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);

describe('공지 사항을 생성하는 지 확인한다.', () => {
test('공지 사항을 생성한다.', async () => {
const data = {
title: '갤럭시',
content: '공지사항입니다',
deadline: '2023-10-12 15:13',
bannerTitle: '아이폰',
bannerSubtitle: '공지사항입니다',
};

const { result } = renderHook(() => useCreateNotice(), {
wrapper,
});

const { mutate } = result.current;

await waitFor(() => {
mutate(data);

expect(MOCK_NOTICE_TEST).toBe(data.title);
});
});
});
30 changes: 30 additions & 0 deletions frontend/__test__/hooks/query/notice/useDeleteNotice.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { ReactNode } from 'react';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { renderHook, waitFor } from '@testing-library/react';

import { useDeleteNotice } from '@hooks';

import { MOCK_NOTICE_TEST } from '@mocks/notice';

const queryClient = new QueryClient();

const wrapper = ({ children }: { children: ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);

describe('요청을 통해 공지 사항을 삭제하는 지 확인한다.', () => {
test('공지 사항을 삭제한다.', async () => {
const { result } = renderHook(() => useDeleteNotice(), {
wrapper,
});

const { mutate } = result.current;

await waitFor(() => {
mutate(1);

expect(MOCK_NOTICE_TEST).toBe('삭제된 공지사항');
});
});
});
38 changes: 38 additions & 0 deletions frontend/__test__/hooks/query/notice/useModifyNotice.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { ReactNode } from 'react';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { renderHook, waitFor } from '@testing-library/react';

import { useModifyNotice } from '@hooks';

import { MOCK_NOTICE_TEST } from '@mocks/notice';

const queryClient = new QueryClient();

const wrapper = ({ children }: { children: ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);

describe('요청을 통해 공지 사항을 수정하는 지 확인한다.', () => {
test('공지 사항을 생성한다.', async () => {
const data = {
title: '아이폰입니다',
content: '공지사항입니다',
deadline: '2023-10-12 15:13',
bannerTitle: '아이폰',
bannerSubtitle: '공지사항입니다',
};

const { result } = renderHook(() => useModifyNotice(), {
wrapper,
});

const { mutate } = result.current;

await waitFor(() => {
mutate({ notice: data, noticeId: 1 });

expect(MOCK_NOTICE_TEST).toEqual(data.title);
});
});
});
26 changes: 26 additions & 0 deletions frontend/__test__/hooks/query/notice/useNoticeDetail.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { ReactNode } from 'react';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { renderHook, waitFor } from '@testing-library/react';

import { useNoticeDetail } from '@hooks';

import { MOCK_TRANSFORM_NOTICE } from '@mocks/mockData/notice';

const queryClient = new QueryClient();

const wrapper = ({ children }: { children: ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);

describe('공지 사항 상세 정보를 불러오는 지 확인한다.', () => {
test('공지 사항 상세 정보를 불러온다.', async () => {
const { result } = renderHook(() => useNoticeDetail(1), {
wrapper,
});

await waitFor(() => {
expect(result.current.data).toEqual(MOCK_TRANSFORM_NOTICE);
});
});
});
139 changes: 139 additions & 0 deletions frontend/__test__/hooks/query/notice/usePagedNoticeList.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import React, { ReactNode } from 'react';

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { renderHook, waitFor } from '@testing-library/react';
import { act } from 'react-dom/test-utils';

import { usePagedNoticeList } from '@hooks';

import { MOCK_TRANSFORM_NOTICE_LIST } from '@mocks/mockData/notice';

const queryClient = new QueryClient();

const wrapper = ({ children }: { children: ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);

describe('페이지 버튼을 눌러 공지 사항 리스트를 불러오는 지 확인한다.', () => {
test('초기 설정으로는 0 페이지를 불러온다.', async () => {
const { result } = renderHook(() => usePagedNoticeList(), {
wrapper,
});

waitFor(() => {
expect(result.current.page).toEqual(0);
});
});

test('초기 페이지를 인자를 넣어 설정할 수 있다.', async () => {
const { result } = renderHook(() => usePagedNoticeList(5), {
wrapper,
});

waitFor(() => {
expect(result.current.page).toEqual(5);
});
});

test('현재 페이지를 3으로 설정했을 때 3페이지를 데이터만 불러온다. 클라이언트 측에서 3으로 설정했어도 서버로는 2를 보내야 하기 때문에 현재 페이지는 2로 설정된다.', async () => {
const { result } = renderHook(() => usePagedNoticeList(), {
wrapper,
});

act(() => {
result.current.setPage(3);
});

waitFor(() => {
expect(result.current.page).toEqual(2);
});
});

test('현재 페이지가 0이고, 다음 페이지를 불러올 때 현재 페이지 + 1을 하여 불러온다.', async () => {
const { result } = renderHook(() => usePagedNoticeList(), {
wrapper,
});

const currentPage = result.current.page;

act(() => {
result.current.fetchNextPage();
});

waitFor(() => {
expect(result.current.page).toEqual(currentPage + 1);
});
});

test('현재 페이지가 5이고, 이전의 페이지를 불러올 때 현재 페이지 - 1을 하여 불러온다.', async () => {
const { result } = renderHook(() => usePagedNoticeList(5), {
wrapper,
});

waitFor(() => {
result.current.fetchPrevPage();

expect(result.current.page).toEqual(3);
});
});

test('총 페이지보다 현재 페이지가 작다면 다음 페이지 여부를 반환하는 변수가 true로 동작한다.', async () => {
const { result } = renderHook(() => usePagedNoticeList(), {
wrapper,
});

const totalPage = MOCK_TRANSFORM_NOTICE_LIST.totalPageNumber;

const currentPage = result.current.page;

act(() => {
result.current.setPage(totalPage + 1);
});

waitFor(() => {
expect(totalPage > currentPage).toBe(true);
expect(result.current.hasNextPage).toBe(true);
});
});

test('총 페이지와 현재 페이지가 같다면 다음 페이지 여부를 반환하는 변수가 false로 동작한다.', async () => {
const { result } = renderHook(() => usePagedNoticeList(), {
wrapper,
});

const totalPage = MOCK_TRANSFORM_NOTICE_LIST.totalPageNumber;

const currentPage = result.current.page;

act(() => {
result.current.setPage(totalPage + 1);
});

waitFor(() => {
expect(totalPage === currentPage).toBe(true);
expect(result.current.hasNextPage).toBe(false);
});
});

test('공지 사항 목록 0 페이지를 불러온다.', async () => {
const { result } = renderHook(() => usePagedNoticeList(), {
wrapper,
});

await waitFor(() => {
expect(result.current.data).toEqual(MOCK_TRANSFORM_NOTICE_LIST);
});
});

test('공지 사항 목록 0 페이지를 불러오고 페이지 설정을 통해 3페이지를 불러온다. 페이지 설정 버튼을 누른다면 해당 페이지의 데이터 1개를 배열로 보내준다.', async () => {
const { result } = renderHook(() => usePagedNoticeList(), {
wrapper,
});

result.current.setPage(3);

act(() => {
expect(result.current.data).toEqual(MOCK_TRANSFORM_NOTICE_LIST);
});
});
});
Loading
Loading