Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
d7c1fd9
Add unit tests for WhiteboardsPage component
tomastiminskas Mar 10, 2026
603d0b3
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 10, 2026
3fad1bb
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 10, 2026
ab99d8a
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 11, 2026
91ec0fa
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 11, 2026
d60b33d
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 11, 2026
221871c
fix: use --legacy-peer-deps in CI build workflow
tomsmith8 Mar 11, 2026
4bb2957
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 11, 2026
2a89abe
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 11, 2026
7b65c1c
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 11, 2026
34c8251
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 11, 2026
92ef72e
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 11, 2026
859b0f8
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
8567fc8
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
e38972f
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
7fd106d
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
507f301
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
7c9f3ba
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
ab4d95a
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
988952d
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
2fd5896
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
d124779
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
41bf27b
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
a415e44
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
ee8d013
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
0c37a03
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
f64b630
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 12, 2026
5a9926f
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 13, 2026
3646745
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 13, 2026
fa738a1
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 13, 2026
a2f0888
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 13, 2026
cc68e3e
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 13, 2026
d2d4a7a
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 13, 2026
d38ce5e
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Mar 13, 2026
c951c41
Merge branch 'master' into feature/add-whiteboards-page-tests
gonzaloaune Apr 1, 2026
9b33e0b
Generated with Hive: Fix WhiteboardsPage unit tests by mocking next-a…
tomsmith8 Apr 1, 2026
ab70130
Merge remote-tracking branch 'origin/master' into feature/add-whitebo…
tomsmith8 Apr 1, 2026
5855f22
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
72c0c2a
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
2effa35
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
8de2162
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
d16301d
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
1563e49
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
4b2597c
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
2662b6a
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
de41ebb
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
16c4b61
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
fb14c60
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
1412632
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
1a64e2b
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
6f60e37
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 1, 2026
aba652f
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 2, 2026
1e35b53
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 2, 2026
b3bfabb
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 2, 2026
cdaf0eb
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 2, 2026
3885590
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 2, 2026
331b62b
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 2, 2026
82e4221
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 2, 2026
64e2f23
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 2, 2026
e959676
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 2, 2026
75ca3de
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 2, 2026
be85af4
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 2, 2026
78368fa
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 3, 2026
4f141ee
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 3, 2026
f51a9d5
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 3, 2026
512b348
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 3, 2026
baac915
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 3, 2026
766a349
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 3, 2026
9cb15d8
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 3, 2026
80c8370
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 3, 2026
cfed522
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 3, 2026
1cebdb9
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 4, 2026
1a940e6
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 4, 2026
84c7359
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 4, 2026
58b0a80
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 4, 2026
66b663f
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 4, 2026
569c0de
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 5, 2026
e96485f
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 5, 2026
a1fa32e
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 5, 2026
7fcdfec
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 5, 2026
6c519c2
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 6, 2026
931bb03
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 6, 2026
50988b4
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 6, 2026
f79fafe
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 6, 2026
cd12f67
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 6, 2026
705d7c6
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 6, 2026
2509574
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 6, 2026
6e2d411
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 6, 2026
66c0e7c
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 6, 2026
dedbe28
Merge branch 'master' into feature/add-whiteboards-page-tests
tomsmith8 Apr 6, 2026
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
5 changes: 4 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@ jobs:

- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci
run: npm ci --legacy-peer-deps
env:
DATABASE_URL: "postgresql://dummy:dummy@localhost:5432/dummy"

- name: Generate Prisma client
run: npx prisma generate

- name: Cache Next.js build
uses: actions/cache@v4
with:
Expand Down
195 changes: 195 additions & 0 deletions src/__tests__/unit/components/whiteboard/WhiteboardsPage.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/**
* @vitest-environment jsdom
*/
import React from "react";
import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen, fireEvent, waitFor, act } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

globalThis.React = React;

// Mock next-auth/react
vi.mock("next-auth/react", () => ({
useSession: () => ({ data: { user: { id: "user-1", name: "Test User" } }, status: "authenticated" }),
}));

// Mock Next.js navigation
const mockRouterPush = vi.fn();
vi.mock("next/navigation", () => ({
useRouter: () => ({ push: mockRouterPush }),
}));

// Mock Next.js Link — renders as <a> so click events behave like real anchors
vi.mock("next/link", () => ({
default: ({ href, children, className, onClick }: any) => (
<a href={href} className={className} onClick={onClick}>
{children}
</a>
),
}));

// Mock workspace hook
vi.mock("@/hooks/useWorkspace", () => ({
useWorkspace: () => ({
id: "workspace-1",
slug: "test-workspace",
role: "OWNER",
workspaces: [],
}),
}));

// Mock PageHeader
vi.mock("@/components/ui/page-header", () => ({
PageHeader: ({ title, actions }: any) => (
<div>
<h1>{title}</h1>
{actions}
</div>
),
}));

// Mock fetch
const mockFetch = vi.fn();
globalThis.fetch = mockFetch;

import WhiteboardsPage from "@/app/w/[slug]/whiteboards/page";

const mockWhiteboards = [
{
id: "wb-1",
name: "Whiteboard One",
featureId: null,
feature: null,
createdAt: "2024-01-01T00:00:00Z",
updatedAt: "2024-01-02T00:00:00Z",
},
{
id: "wb-2",
name: "Whiteboard Two",
featureId: "feat-1",
feature: { id: "feat-1", title: "Feature Alpha" },
createdAt: "2024-01-03T00:00:00Z",
updatedAt: "2024-01-04T00:00:00Z",
},
];

/** Open a Radix UI DropdownMenu trigger in jsdom. */
async function openDropdown(trigger: Element) {
await act(async () => {
trigger.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true }));
fireEvent.click(trigger);
});
}

describe("WhiteboardsPage — delete button", () => {
beforeEach(() => {
vi.clearAllMocks();
mockFetch.mockResolvedValue({
ok: true,
json: async () => ({ success: true, data: mockWhiteboards }),
});
});

async function renderAndWait() {
const result = render(<WhiteboardsPage />);
// Wait for whiteboards to load
await waitFor(() => {
expect(screen.getByText("Whiteboard One")).toBeInTheDocument();
});
return result;
}

/** Open the dropdown for the first whiteboard card and click "Delete". */
async function openDeleteDialogForFirstCard() {
// Find the MoreHorizontal dropdown trigger (aria-haspopup="menu") for the first card
const menuTriggers = screen.getAllByRole("button").filter(
(btn) => btn.getAttribute("aria-haspopup") === "menu"
);
const firstMoreBtn = menuTriggers[0];
await openDropdown(firstMoreBtn);

// Click the Delete menu item
await waitFor(() => {
expect(screen.getByRole("menuitem", { name: /delete/i })).toBeInTheDocument();
});
fireEvent.click(screen.getByRole("menuitem", { name: /delete/i }));
}

it("calls e.preventDefault() and e.stopPropagation() and sets deleteId when delete button is clicked", async () => {
await renderAndWait();
await openDeleteDialogForFirstCard();

// After clicking Delete in the dropdown, the confirmation dialog should appear
await waitFor(() => {
expect(screen.getByText("Delete whiteboard?")).toBeInTheDocument();
});
});

it("opens delete dialog without navigating when delete button is clicked", async () => {
await renderAndWait();
await openDeleteDialogForFirstCard();

// Dialog should open
await waitFor(() => {
expect(screen.getByText("Delete whiteboard?")).toBeInTheDocument();
});

// Router should NOT have been called (no navigation)
expect(mockRouterPush).not.toHaveBeenCalled();
});

it("does not open delete dialog when clicking the card body link", async () => {
await renderAndWait();

// Click the card title text (part of the Link body, not the delete button)
const cardTitle = screen.getByText("Whiteboard One");
fireEvent.click(cardTitle);

// Dialog should NOT open
expect(screen.queryByText("Delete whiteboard?")).not.toBeInTheDocument();
});

it("removes the whiteboard from the list after confirming deletion", async () => {
await renderAndWait();

// Setup DELETE response
mockFetch.mockResolvedValueOnce({ ok: true, json: async () => ({}) });

await openDeleteDialogForFirstCard();

await waitFor(() => {
expect(screen.getByText("Delete whiteboard?")).toBeInTheDocument();
});

// Click the Delete confirm button
const confirmBtn = screen.getByRole("button", { name: /^Delete$/ });
fireEvent.click(confirmBtn);

await waitFor(() => {
expect(screen.queryByText("Whiteboard One")).not.toBeInTheDocument();
});

// Other whiteboard should still be there
expect(screen.getByText("Whiteboard Two")).toBeInTheDocument();
});

it("keeps the whiteboard list intact and closes dialog on cancel", async () => {
await renderAndWait();

await openDeleteDialogForFirstCard();

await waitFor(() => {
expect(screen.getByText("Delete whiteboard?")).toBeInTheDocument();
});

const cancelBtn = screen.getByRole("button", { name: /cancel/i });
fireEvent.click(cancelBtn);

await waitFor(() => {
expect(screen.queryByText("Delete whiteboard?")).not.toBeInTheDocument();
});

// Whiteboard should still be in the list
expect(screen.getByText("Whiteboard One")).toBeInTheDocument();
});
});
Loading