This repository has been archived by the owner on Jul 24, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #187 from ictsc/feature/add_scoring_index_page_uni…
…t_test add: ScoringIndexPage の 単体 テストを追加
- Loading branch information
Showing
3 changed files
with
316 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,311 @@ | ||
import "@testing-library/jest-dom"; | ||
|
||
import { act, render, screen } from "@testing-library/react"; | ||
import { Mock, vi } from "vitest"; | ||
|
||
import useAuth from "@/hooks/auth"; | ||
import useProblems from "@/hooks/problems"; | ||
import Index from "@/pages/scoring"; | ||
import { testProblem } from "@/types/Problem"; | ||
import { testAdminUser, testUser } from "@/types/User"; | ||
|
||
vi.mock("next/router", () => require("next-router-mock")); | ||
vi.mock("@/hooks/auth"); | ||
vi.mock("@/hooks/problems"); | ||
vi.mock("@/components/Navbar", () => ({ | ||
__esModule: true, | ||
default: () => <div data-testid="navbar" />, | ||
})); | ||
vi.mock("@/components/LoadingPage", () => ({ | ||
__esModule: true, | ||
default: () => <div data-testid="loading" />, | ||
})); | ||
beforeEach(() => { | ||
// toHaveBeenCalledTimes がテストごとにリセットされるようにする | ||
vi.clearAllMocks(); | ||
}); | ||
|
||
describe("Scoring", () => { | ||
test("未ログインで、NotFound が表示される", async () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: null, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
|
||
// when | ||
expect( | ||
screen.queryByText("This page could not be found.") | ||
).toBeInTheDocument(); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).not.toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(1); | ||
expect(useProblems).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
test("ログイン済みで問題が取得できない場合、NotFound が表示される", async () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testAdminUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
|
||
// when | ||
expect( | ||
screen.queryByText("This page could not be found.") | ||
).toBeInTheDocument(); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).not.toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(1); | ||
expect(useProblems).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
test("参加者でアクセスした場合、NotFound が表示される", async () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
|
||
// when | ||
expect( | ||
screen.queryByText("This page could not be found.") | ||
).toBeInTheDocument(); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).not.toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(1); | ||
expect(useProblems).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
test("問題を取得中の場合、ローディング画面が表示される", async () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testAdminUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [], | ||
isLoading: true, | ||
}); | ||
render(<Index />); | ||
|
||
// when | ||
expect(screen.queryByTestId("loading")).toBeInTheDocument(); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(1); | ||
expect(useProblems).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
test("問題一覧が表示される", async () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testAdminUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [testProblem], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
const tds = screen.queryAllByRole("cell"); | ||
|
||
// when | ||
expect(screen.queryByText("採点")).toBeInTheDocument(); | ||
expect(tds[1]).toHaveTextContent("/-/-"); | ||
expect(tds[2]).toHaveTextContent("id"); | ||
expect(tds[3]).toHaveTextContent("XYZ"); | ||
expect(tds[4]).toHaveTextContent("テスト問題タイトル"); | ||
expect(tds[5]).toHaveTextContent("--- title: テスト --- #..."); | ||
expect(tds[6]).toHaveTextContent("100"); | ||
expect(tds[7]).toHaveTextContent("150"); | ||
expect(tds[8]).toHaveTextContent(""); | ||
expect(tds[9]).toHaveTextContent("自分"); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(1); | ||
expect(useProblems).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
test("15分未満の問題がある場合、未採点の ~15分 に表示される", () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testAdminUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [{ ...testProblem, unchecked: 1 }], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
const tds = screen.queryAllByRole("cell"); | ||
|
||
// when | ||
expect(tds[1]).toHaveTextContent("1/-/-"); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(1); | ||
expect(useProblems).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
test("15分以上かつ19分以下の問題がある場合、未採点の 15~19分 に表示される", () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testAdminUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [{ ...testProblem, unchecked_near_overdue: 1 }], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
const tds = screen.queryAllByRole("cell"); | ||
|
||
// when | ||
expect(tds[1]).toHaveTextContent("/1/-"); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(1); | ||
expect(useProblems).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
test("20分以上の問題がある場合、未採点の 20分~ に表示される", () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testAdminUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [{ ...testProblem, unchecked_overdue: 1 }], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
const tds = screen.queryAllByRole("cell"); | ||
|
||
// when | ||
expect(tds[1]).toHaveTextContent("/-/1"); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(1); | ||
expect(useProblems).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
test("20文字未満の問題文は、20文字目以降が省略されない", () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testAdminUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [{ ...testProblem, body: "a".repeat(19) }], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
const tds = screen.queryAllByRole("cell"); | ||
|
||
// when | ||
expect(tds[5]).toHaveTextContent("a".repeat(19)); | ||
}); | ||
|
||
test("20文字以上の問題文は、20文字目以降が省略される", () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testAdminUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [{ ...testProblem, body: "a".repeat(20) }], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
const tds = screen.queryAllByRole("cell"); | ||
|
||
// when | ||
// aaa... となる | ||
expect(tds[5]).toHaveTextContent(`${"a".repeat(20)}...`); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(1); | ||
expect(useProblems).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
test("問題文が Null の場合、空文字が表示される", () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testAdminUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [{ ...testProblem, body: null }], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
const tds = screen.queryAllByRole("cell"); | ||
|
||
// when | ||
// aaa... となる | ||
expect(tds[5]).toHaveTextContent(""); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(1); | ||
expect(useProblems).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
test("問題作成者id が自分でない場合空文字が表示される", () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testAdminUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [{ ...testProblem, author_id: "other" }], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
const tds = screen.queryAllByRole("cell"); | ||
|
||
// when | ||
expect(tds[9]).toHaveTextContent(""); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(1); | ||
expect(useProblems).toHaveBeenCalledTimes(2); | ||
}); | ||
|
||
test("問題をクリックした場合、問題文が表示される", async () => { | ||
// setup | ||
(useAuth as Mock).mockReturnValue({ | ||
user: testAdminUser, | ||
}); | ||
(useProblems as Mock).mockReturnValue({ | ||
problems: [{ ...testProblem, author_id: "other" }], | ||
isLoading: false, | ||
}); | ||
render(<Index />); | ||
await act(async () => { | ||
await screen.queryAllByRole("row")[1].click(); | ||
}); | ||
|
||
// when | ||
expect(screen.queryByText("採点する")).toBeInTheDocument(); | ||
|
||
// then | ||
expect(screen.queryByTestId("navbar")).toBeInTheDocument(); | ||
expect(useAuth).toHaveBeenCalledTimes(2); | ||
expect(useProblems).toHaveBeenCalledTimes(4); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters