Skip to content

Commit

Permalink
[FE] 24시간 이하로 남으면 디데이 말고 시간 보여주기(#598) (#609)
Browse files Browse the repository at this point in the history
* fix: 디데이가 1일 남은경우에도 24시간 미만 남은경우 남은 dday로 반환하도록 변경

* refactor: areDatesEqual 함수를 dateFormatter 유틸 함수로 이동

* fix: 중복된 함수 제거

* test: 데이터 포메팅 유틸 함수 테스트코드 추가

* test: 테스트 시 이미지 모듈은 mock string 값이 반환되도록 모킹

* test: 룸 카드의 남은 기간 정보 UI 렌더링 테스트 추가

* fix: 진행중인 방의 D-Day 가 잘못 표기되는 문제 해결

* test: 테스트 명세 오타 수정

* test: 방 상세정보의 모집/리뷰 마감까지 남은 시간 렌더링 테스트 추가

* test: jest 환경에서 시간대를 한국 시간대를 사용하도록 변경

* feat: SEO 최적화를 위해 html에 메타태그 추가

---------

Co-authored-by: Lee sang Yeop <[email protected]>
  • Loading branch information
github-actions[bot] and pp449 authored Oct 17, 2024
1 parent 48256cd commit 2390af5
Show file tree
Hide file tree
Showing 11 changed files with 619 additions and 29 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/frontend-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Set timezone to Asia/Seoul
run: sudo timedatectl set-timezone Asia/Seoul

# 노드 설치
- name: Install Nodejs
uses: actions/setup-node@v4
Expand Down
3 changes: 3 additions & 0 deletions frontend/jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
const { server } = require("@/mocks/server");

jest.mock("@/assets", () => "");
process.env.TZ = "Asia/Seoul";

// 모든 테스트 전에 MSW 서버를 시작합니다.
beforeAll(() => server.listen());

Expand Down
6 changes: 4 additions & 2 deletions frontend/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,18 @@
name="description"
content="주니어 개발자들이 서로 코드리뷰하고 피드백 받을 수 있는 플랫폼"
/>
<title>CoReA</title>
<title>CoReA(Code Review Area) - 코드리뷰 매칭 플랫폼</title>
<link rel="stylesheet" href="./fonts.css" />
<link rel="icon" href="./favicon.ico" />
<meta property="og:title" content="CoReA" />
<meta property="og:title" content="CoReA - 코드리뷰 매칭 플랫폼" />
<meta
property="og:description"
content="주니어 개발자들이 서로 코드리뷰하고 피드백 받을 수 있는 플랫폼"
/>
<meta property="og:image" content="./logo.webp" />
<meta property="og:url" content="https://code-review-area.com" />
<meta property="og:type" content="website" />
<meta property="og:locale" content="ko_KR" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/common/calendar/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as S from "./Calendar.style";
import useCalendar from "@/hooks/common/useCalendar";
import Icon from "@/components/common/icon/Icon";
import DAYS from "@/constants/days";
import areDatesEqual from "@/utils/areDatesEqual";
import { areDatesEqual } from "@/utils/dateFormatter";

export interface CalendarProps {
selectedDate: Date;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import { ThemeProvider } from "styled-components";
import RoomInfoCard from "@/components/roomDetailPage/roomInfoCard/RoomInfoCard";
import { RoomInfo } from "@/@types/roomInfo";
import { theme } from "@/styles/theme";

const mockBaseRoomInfo: RoomInfo = {
id: 1,
manager: "darr",
currentParticipants: 5,
roomStatus: "OPEN",
participationStatus: "PARTICIPATED",
memberRole: "BOTH",
title: "테스트 제목",
content: "테스트 본문",
repositoryLink: "테스트 링크",
thumbnailLink: "테스트 썸네일",
matchingSize: 5,
keywords: ["테스트"],
limitedParticipants: 10,
recruitmentDeadline: "2024-10-05T10:30:00+09:00",
reviewDeadline: "2024-10-08T10:30:00+09:00",
};

describe("RoomInfoCard 컴포넌트 테스트", () => {
beforeAll(() => {
const mockDate = new Date("2024-10-02T10:30:00+09:00");
const OriginalDate = Date;

jest.spyOn(global, "Date").mockImplementation((value) => {
return value ? new OriginalDate(value) : new OriginalDate(mockDate);
});
});

it("'모집'중인 방에 2일 이상 남으면 '리뷰 마감까지 남은 일', '모집 마감까지 남은 일'이 보인다", async () => {
render(
<ThemeProvider theme={theme}>
<RoomInfoCard roomInfo={mockBaseRoomInfo} />
</ThemeProvider>,
);

const recruitLeftDay = screen.getByTestId("recruitLeftTime");
const reviewLeftDay = screen.getByTestId("reviewLeftTime");

expect(recruitLeftDay).toHaveTextContent("D-3");
expect(reviewLeftDay).toHaveTextContent("D-6");
});

it("'모집'이 24시간 미만, '리뷰'가 24시간 이상 남은 경우 '모집 마감까지 남은 시간', '리뷰 마감까지 남은 일'이 보인다", async () => {
const mockRoomInfo: RoomInfo = {
...mockBaseRoomInfo,
recruitmentDeadline: "2024-10-03T00:30:00+09:00",
reviewDeadline: "2024-10-05T00:30:00+09:00",
};

render(
<ThemeProvider theme={theme}>
<RoomInfoCard roomInfo={mockRoomInfo} />
</ThemeProvider>,
);

const recruitLeftDay = screen.getByTestId("recruitLeftTime");
const reviewLeftDay = screen.getByTestId("reviewLeftTime");

expect(recruitLeftDay).toHaveTextContent("14시간 0분 전");
expect(reviewLeftDay).toHaveTextContent("D-2");
});

it("'모집'이 24시간 미만, '리뷰'가 24시간 미만인 경우 '모집 마감까지 남은 시간', '리뷰 마감까지 남은 시간'이 보인다", async () => {
const mockRoomInfo: RoomInfo = {
...mockBaseRoomInfo,
recruitmentDeadline: "2024-10-02T12:30:00+09:00",
reviewDeadline: "2024-10-03T00:30:00+09:00",
};

render(
<ThemeProvider theme={theme}>
<RoomInfoCard roomInfo={mockRoomInfo} />
</ThemeProvider>,
);

const recruitLeftDay = screen.getByTestId("recruitLeftTime");
const reviewLeftDay = screen.getByTestId("reviewLeftTime");

expect(recruitLeftDay).toHaveTextContent("2시간 0분 전");
expect(reviewLeftDay).toHaveTextContent("14시간 0분 전");
});

it("'모집'완료 후 '진행 중'으로 바뀌었을 때 '리뷰'가 24시간 이상인 경우 '리뷰 마감까지 남은 일'이 보인다", async () => {
const mockRoomInfo: RoomInfo = {
...mockBaseRoomInfo,
recruitmentDeadline: "2024-10-01T12:30:00+09:00",
reviewDeadline: "2024-10-04T00:30:00+09:00",
};

render(
<ThemeProvider theme={theme}>
<RoomInfoCard roomInfo={mockRoomInfo} />
</ThemeProvider>,
);

const recruitLeftDay = screen.getByTestId("recruitLeftTime");
const reviewLeftDay = screen.getByTestId("reviewLeftTime");

expect(recruitLeftDay).toHaveTextContent("");
expect(reviewLeftDay).toHaveTextContent("D-1");
});

it("'모집'완료 후 '진행 중'으로 바뀌었을 때 '리뷰'가 24시간 미만인 경우 '리뷰 마감까지 남은 시간'이 보인다", async () => {
const mockRoomInfo: RoomInfo = {
...mockBaseRoomInfo,
recruitmentDeadline: "2024-10-01T12:30:00+09:00",
reviewDeadline: "2024-10-03T00:30:00+09:00",
};

render(
<ThemeProvider theme={theme}>
<RoomInfoCard roomInfo={mockRoomInfo} />
</ThemeProvider>,
);

const recruitLeftDay = screen.getByTestId("recruitLeftTime");
const reviewLeftDay = screen.getByTestId("reviewLeftTime");

expect(recruitLeftDay).toHaveTextContent("");
expect(reviewLeftDay).toHaveTextContent("14시간 0분 전");
});

it("'종료됨' 상태인 방에서는 남은 기간이 보이지 않는다", async () => {
const mockRoomInfo: RoomInfo = {
...mockBaseRoomInfo,
roomStatus: "CLOSE",
recruitmentDeadline: "2024-10-01T12:30:00+09:00",
reviewDeadline: "2024-10-03T00:30:00+09:00",
};

render(
<ThemeProvider theme={theme}>
<RoomInfoCard roomInfo={mockRoomInfo} />
</ThemeProvider>,
);

const recruitLeftDay = screen.getByTestId("recruitLeftTime");
const reviewLeftDay = screen.getByTestId("reviewLeftTime");

expect(recruitLeftDay).toHaveTextContent("");
expect(reviewLeftDay).toHaveTextContent("");
});

it("'실패' 상태인 방에서는 남은 기간이 보이지 않는다", async () => {
const mockRoomInfo: RoomInfo = {
...mockBaseRoomInfo,
roomStatus: "FAIL",
recruitmentDeadline: "2024-10-01T12:30:00+09:00",
reviewDeadline: "2024-10-03T00:30:00+09:00",
};

render(
<ThemeProvider theme={theme}>
<RoomInfoCard roomInfo={mockRoomInfo} />
</ThemeProvider>,
);

const recruitLeftDay = screen.getByTestId("recruitLeftTime");
const reviewLeftDay = screen.getByTestId("reviewLeftTime");

expect(recruitLeftDay).toHaveTextContent("");
expect(reviewLeftDay).toHaveTextContent("");
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const RoomInfoCard = ({ roomInfo }: { roomInfo: RoomInfo }) => {
<S.DateTimeText>
{formatDateTimeString(roomInfo.recruitmentDeadline)}
</S.DateTimeText>
<S.StyledDday>
<S.StyledDday data-testid="recruitLeftTime">
{roomInfo.roomStatus === "OPEN" &&
formatDday(roomInfo.recruitmentDeadline) !== "종료됨" &&
displayLeftTime(roomInfo.recruitmentDeadline)}
Expand All @@ -84,8 +84,9 @@ const RoomInfoCard = ({ roomInfo }: { roomInfo: RoomInfo }) => {
</S.RoomContentSmall>
<div>
<S.DateTimeText>{formatDateTimeString(roomInfo.reviewDeadline)}</S.DateTimeText>
<S.StyledDday>
{formatDday(roomInfo.reviewDeadline) !== "종료됨" &&
<S.StyledDday data-testid="reviewLeftTime">
{(roomInfo.roomStatus === "OPEN" || roomInfo.roomStatus === "PROGRESS") &&
formatDday(roomInfo.reviewDeadline) !== "종료됨" &&
displayLeftTime(roomInfo.reviewDeadline)}
</S.StyledDday>
</div>
Expand Down
Loading

0 comments on commit 2390af5

Please sign in to comment.