Skip to content
Closed
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
52 changes: 24 additions & 28 deletions src/components/__tests__/LayoutEditor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import LayoutEditor from "../LayoutEditor";
import { CardLayout } from "@/lib/types";
import "@testing-library/jest-dom";

// Type definition for window mock variables used in DndKit tests
interface DndWindowMock extends Window {
triggerDragEnd?: (event: unknown) => void;
mockIsOverId?: string;
Comment on lines +9 to +10
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 triggerDragEndundefined のまま呼び出される可能性がある

DndWindowMocktriggerDragEndmockIsOverId は省略可能(?)な型として定義されているため、TypeScript の型は ((event: unknown) => void) | undefined になります。tsconfig.json"strict": truestrictNullChecks 含む)が有効になっているため、const triggerDragEnd = (window as unknown as DndWindowMock).triggerDragEnd の後に null チェックなしで triggerDragEnd({...}) を呼び出すコードは、TypeScript コンパイラ(tsc --noEmit)では型エラーになります。Vitest は esbuild でトランスパイルするため型チェックをスキップしてテスト自体は通りますが、エディタや CI の型チェックステップでは問題が検出されます。? を外して | undefined を明示するか、呼び出し箇所に非 null アサーション演算子(!)を追加することで解消できます。

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

Comment:
`triggerDragEnd``undefined` のまま呼び出される可能性がある

`DndWindowMock``triggerDragEnd``mockIsOverId` は省略可能(`?`)な型として定義されているため、TypeScript の型は `((event: unknown) => void) | undefined` になります。`tsconfig.json``"strict": true``strictNullChecks` 含む)が有効になっているため、`const triggerDragEnd = (window as unknown as DndWindowMock).triggerDragEnd` の後に null チェックなしで `triggerDragEnd({...})` を呼び出すコードは、TypeScript コンパイラ(`tsc --noEmit`)では型エラーになります。Vitest は esbuild でトランスパイルするため型チェックをスキップしてテスト自体は通りますが、エディタや CI の型チェックステップでは問題が検出されます。`?` を外して `| undefined` を明示するか、呼び出し箇所に非 null アサーション演算子(`!`)を追加することで解消できます。

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

}

// Mock dnd-kit components
vi.mock("@dnd-kit/core", async (importOriginal) => {
const actual = await importOriginal<typeof import("@dnd-kit/core")>();
Expand All @@ -13,7 +19,7 @@ vi.mock("@dnd-kit/core", async (importOriginal) => {
<div data-testid="dnd-context" onClick={() => {
// Expose a way to trigger onDragEnd via a synthetic event or global for testing
// We'll attach it to window for easy triggering
(window as unknown as { triggerDragEnd: (event: unknown) => void }).triggerDragEnd = onDragEnd;
(window as unknown as DndWindowMock).triggerDragEnd = onDragEnd;
}}>
{children}
</div>
Expand All @@ -22,8 +28,7 @@ vi.mock("@dnd-kit/core", async (importOriginal) => {
useSensor: vi.fn(() => ({})),
useDroppable: ({ id }: { id: string }) => ({
setNodeRef: vi.fn(),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
isOver: (window as any).mockIsOverId === id,
isOver: (window as unknown as DndWindowMock).mockIsOverId === id,
}),
PointerSensor: vi.fn(),
KeyboardSensor: vi.fn(),
Expand Down Expand Up @@ -64,10 +69,8 @@ describe("LayoutEditor", () => {
beforeEach(() => {
mockOnLayoutChange = vi.fn();
mockOnToggleVisibility = vi.fn();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).triggerDragEnd = undefined;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).mockIsOverId = undefined;
(window as unknown as DndWindowMock).triggerDragEnd = undefined;
(window as unknown as DndWindowMock).mockIsOverId = undefined;
});

it("renders blocks in their respective columns", () => {
Expand Down Expand Up @@ -119,12 +122,11 @@ describe("LayoutEditor", () => {
const dndContext = screen.getByTestId("dnd-context");
fireEvent.click(dndContext);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const triggerDragEnd = (window as any).triggerDragEnd;
const triggerDragEnd = (window as unknown as DndWindowMock).triggerDragEnd;
expect(triggerDragEnd).toBeDefined();

// Drag 'avatar' to 'right' column
triggerDragEnd({
triggerDragEnd!({
active: { id: "avatar" },
over: { id: "right" },
});
Expand All @@ -149,11 +151,10 @@ describe("LayoutEditor", () => {
const dndContext = screen.getByTestId("dnd-context");
fireEvent.click(dndContext);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const triggerDragEnd = (window as any).triggerDragEnd;
const triggerDragEnd = (window as unknown as DndWindowMock).triggerDragEnd;

// Drag 'avatar' over 'topLanguages'
triggerDragEnd({
triggerDragEnd!({
active: { id: "avatar" },
over: { id: "topLanguages" },
});
Expand All @@ -178,9 +179,8 @@ describe("LayoutEditor", () => {
const dndContext = screen.getByTestId("dnd-context");
fireEvent.click(dndContext);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const triggerDragEnd = (window as any).triggerDragEnd;
triggerDragEnd({
const triggerDragEnd = (window as unknown as DndWindowMock).triggerDragEnd;
triggerDragEnd!({
active: { id: "avatar" },
over: null,
});
Expand All @@ -200,9 +200,8 @@ describe("LayoutEditor", () => {
const dndContext = screen.getByTestId("dnd-context");
fireEvent.click(dndContext);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const triggerDragEnd = (window as any).triggerDragEnd;
triggerDragEnd({
const triggerDragEnd = (window as unknown as DndWindowMock).triggerDragEnd;
triggerDragEnd!({
active: { id: "avatar" },
over: { id: "avatar" },
});
Expand All @@ -222,9 +221,8 @@ describe("LayoutEditor", () => {
const dndContext = screen.getByTestId("dnd-context");
fireEvent.click(dndContext);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const triggerDragEnd = (window as any).triggerDragEnd;
triggerDragEnd({
const triggerDragEnd = (window as unknown as DndWindowMock).triggerDragEnd;
triggerDragEnd!({
active: { id: "avatar" },
over: { id: "non-existent-block" },
});
Expand All @@ -250,11 +248,10 @@ describe("LayoutEditor", () => {
const dndContext = screen.getByTestId("dnd-context");
fireEvent.click(dndContext);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const triggerDragEnd = (window as any).triggerDragEnd;
const triggerDragEnd = (window as unknown as DndWindowMock).triggerDragEnd;

// Drag 'avatar' over 'stats' (downwards)
triggerDragEnd({
triggerDragEnd!({
active: { id: "avatar" },
over: { id: "stats" },
});
Expand All @@ -278,11 +275,10 @@ describe("LayoutEditor", () => {
const dndContext = screen.getByTestId("dnd-context");
fireEvent.click(dndContext);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const triggerDragEnd = (window as any).triggerDragEnd;
const triggerDragEnd = (window as unknown as DndWindowMock).triggerDragEnd;

// Drag 'avatar' to empty column 'right'
triggerDragEnd({
triggerDragEnd!({
active: { id: "avatar" },
over: { id: "right" },
});
Expand Down
Loading