Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
107 changes: 107 additions & 0 deletions src/components/__tests__/SettingsTab.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// @vitest-environment jsdom
import { render, screen, fireEvent } from "@testing-library/react";
import { describe, expect, it, vi, beforeEach } from "vitest";
import { SettingsTab } from "../SettingsTab";
import { MAIN_BLOCKS, DETAIL_OPTIONS } from "@/lib/cardGeneratorConstants";
import type { CardDisplayOptions, CardBlockId } from "@/lib/types";
import "@testing-library/jest-dom";

describe("SettingsTab", () => {
const mockIsBlockVisible = vi.fn();
const mockToggleMainBlockVisibility = vi.fn();
const mockToggleDisplayOption = vi.fn();

const defaultProps = {
isBlockVisible: mockIsBlockVisible,
toggleMainBlockVisibility: mockToggleMainBlockVisibility,
displayOptions: {} as CardDisplayOptions,
toggleDisplayOption: mockToggleDisplayOption,
};

beforeEach(() => {
vi.resetAllMocks();
});

it("renders all MAIN_BLOCKS checkboxes", () => {
mockIsBlockVisible.mockReturnValue(false);
render(<SettingsTab {...defaultProps} />);

MAIN_BLOCKS.forEach(({ label }) => {
const checkbox = screen.getByLabelText(label);
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveAttribute("type", "checkbox");
expect(checkbox).not.toBeChecked();
});
});

it("renders all DETAIL_OPTIONS checkboxes", () => {
render(<SettingsTab {...defaultProps} />);

DETAIL_OPTIONS.forEach(({ label }) => {
const checkbox = screen.getByLabelText(label);
expect(checkbox).toBeInTheDocument();
expect(checkbox).toHaveAttribute("type", "checkbox");
expect(checkbox).not.toBeChecked();
});
});

Comment on lines +38 to +47

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 mockIsBlockVisible のセットアップが欠落している

renders all DETAIL_OPTIONS checkboxes テストでは beforeEach により vi.resetAllMocks() が実行されるため、mockIsBlockVisible はデフォルトで undefined を返します。その結果、MAIN_BLOCKS のチェックボックスが checked={undefined} でレンダリングされ、React が「制御→非制御コンポーネントへの切り替え」の警告を出力する可能性があります。他のテスト(例: renders all MAIN_BLOCKS checkboxes)と同様に mockIsBlockVisible.mockReturnValue(false) を先頭に追加すると、テストの一貫性が保たれます。

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/__tests__/SettingsTab.test.tsx
Line: 38-47

Comment:
**`mockIsBlockVisible` のセットアップが欠落している**

`renders all DETAIL_OPTIONS checkboxes` テストでは `beforeEach` により `vi.resetAllMocks()` が実行されるため、`mockIsBlockVisible` はデフォルトで `undefined` を返します。その結果、MAIN_BLOCKS のチェックボックスが `checked={undefined}` でレンダリングされ、React が「制御→非制御コンポーネントへの切り替え」の警告を出力する可能性があります。他のテスト(例: `renders all MAIN_BLOCKS checkboxes`)と同様に `mockIsBlockVisible.mockReturnValue(false)` を先頭に追加すると、テストの一貫性が保たれます。

How can I resolve this? If you propose a fix, please make it concise.

it("sets MAIN_BLOCKS checkbox checked state based on isBlockVisible prop", () => {
// Mock that 'profile' and 'skills' are visible, others are not
mockIsBlockVisible.mockImplementation((id: CardBlockId) => id === "profile" || id === "skills");

render(<SettingsTab {...defaultProps} />);

MAIN_BLOCKS.forEach(({ id, label }) => {
const checkbox = screen.getByLabelText(label);
if (id === "profile" || id === "skills") {
expect(checkbox).toBeChecked();
} else {
expect(checkbox).not.toBeChecked();
}
});
});

it("sets DETAIL_OPTIONS checkbox checked state based on displayOptions prop", () => {
const displayOptions: CardDisplayOptions = {
showAvatar: true,
showLocation: true,
// Others are implicitly false or undefined
};

render(<SettingsTab {...defaultProps} displayOptions={displayOptions} />);

DETAIL_OPTIONS.forEach(({ key, label }) => {
const checkbox = screen.getByLabelText(label);
if (key === "showAvatar" || key === "showLocation") {
expect(checkbox).toBeChecked();
} else {
expect(checkbox).not.toBeChecked();
}
});
});

it("calls toggleMainBlockVisibility with correct id when MAIN_BLOCKS checkbox is clicked", () => {
mockIsBlockVisible.mockReturnValue(false);
render(<SettingsTab {...defaultProps} />);

const firstMainBlock = MAIN_BLOCKS[0];
const checkbox = screen.getByLabelText(firstMainBlock.label);

fireEvent.click(checkbox);

expect(mockToggleMainBlockVisibility).toHaveBeenCalledTimes(1);
expect(mockToggleMainBlockVisibility).toHaveBeenCalledWith(firstMainBlock.id);
});

it("calls toggleDisplayOption with correct key when DETAIL_OPTIONS checkbox is clicked", () => {
render(<SettingsTab {...defaultProps} />);

const firstDetailOption = DETAIL_OPTIONS[0];
const checkbox = screen.getByLabelText(firstDetailOption.label);

fireEvent.click(checkbox);

expect(mockToggleDisplayOption).toHaveBeenCalledTimes(1);
expect(mockToggleDisplayOption).toHaveBeenCalledWith(firstDetailOption.key);
});
});
2 changes: 2 additions & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export default defineConfig({
"src/components/LanguageChart.tsx",
"src/components/SkillsCard.tsx",
"src/components/LayoutEditor.tsx",
"src/components/SettingsTab.tsx",
"src/lib/rateLimit.ts",

"src/app/api/og/[username]/route.tsx"
Comment on lines 25 to 27

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 カバレッジの include 配列の途中に不要な空行が入っています。配列要素のリスト内には空行を入れないのが一般的なスタイルです。

Suggested change
"src/lib/rateLimit.ts",
"src/app/api/og/[username]/route.tsx"
"src/lib/rateLimit.ts",
"src/app/api/og/[username]/route.tsx"
Prompt To Fix With AI
This is a comment left during a code review.
Path: vitest.config.ts
Line: 25-27

Comment:
カバレッジの `include` 配列の途中に不要な空行が入っています。配列要素のリスト内には空行を入れないのが一般的なスタイルです。

```suggestion
        "src/lib/rateLimit.ts",
        "src/app/api/og/[username]/route.tsx"
```

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

],
thresholds: {
Expand Down
Loading