import type { Note } from "$lib/model"; import { cleanup, fireEvent, render, screen } from "@solidjs/testing-library"; import type { JSX } from "solid-js"; import { afterEach, describe, expect, it, vi } from "vitest"; import { NotesSidebar } from "../NotesSidebar"; vi.mock( "@solidjs/router", () => ({ A: (props: { href: string; class: string; children: JSX.Element; "data-testid"?: string }) => ( {props.children} ), }), ); const mockNotes: Note[] = [{ id: "note-1", owner_did: "did:plc:test", title: "First Note", body: "Content with [[Second Note]] link", tags: ["rust", "learning"], visibility: { type: "Private" }, created_at: "2026-01-01T00:00:00Z", updated_at: "2026-01-03T00:00:00Z", }, { id: "note-2", owner_did: "did:plc:test", title: "Second Note", body: "This links to [[First Note]]", tags: ["rust", "advanced"], visibility: { type: "Private" }, created_at: "2026-01-01T00:00:00Z", updated_at: "2026-01-02T00:00:00Z", }, { id: "note-3", owner_did: "did:plc:test", title: "Orphan Note", body: "No wikilinks here", tags: ["learning"], visibility: { type: "Private" }, created_at: "2026-01-01T00:00:00Z", updated_at: "2026-01-01T00:00:00Z", }]; describe("NotesSidebar", () => { afterEach(cleanup); it("renders the sidebar", () => { render(() => ); expect(screen.getByTestId("notes-sidebar")).toBeInTheDocument(); }); it("displays filter buttons with counts", () => { render(() => ); expect(screen.getByTestId("filter-all")).toHaveTextContent("All (3)"); expect(screen.getByTestId("filter-linked")).toHaveTextContent("Linked (2)"); expect(screen.getByTestId("filter-orphaned")).toHaveTextContent("Orphaned (1)"); }); it("displays unique tags with correct counts", () => { render(() => ); expect(screen.getByTestId("tag-rust")).toHaveTextContent("#rust"); expect(screen.getByTestId("tag-rust")).toHaveTextContent("2"); expect(screen.getByTestId("tag-learning")).toHaveTextContent("#learning"); expect(screen.getByTestId("tag-learning")).toHaveTextContent("2"); expect(screen.getByTestId("tag-advanced")).toHaveTextContent("#advanced"); expect(screen.getByTestId("tag-advanced")).toHaveTextContent("1"); }); it("displays recent notes sorted by update date", () => { render(() => ); const recentLinks = screen.getAllByTestId(/^recent-/); expect(recentLinks[0]).toHaveAttribute("href", "/notes/note-1"); expect(recentLinks[1]).toHaveAttribute("href", "/notes/note-2"); expect(recentLinks[2]).toHaveAttribute("href", "/notes/note-3"); }); it("calls onFilterSelect when filter clicked", async () => { const onFilterSelect = vi.fn(); render(() => ); await fireEvent.click(screen.getByTestId("filter-linked")); expect(onFilterSelect).toHaveBeenCalledWith("linked"); await fireEvent.click(screen.getByTestId("filter-orphaned")); expect(onFilterSelect).toHaveBeenCalledWith("orphaned"); }); it("calls onTagSelect when tag clicked", async () => { const onTagSelect = vi.fn(); render(() => ); await fireEvent.click(screen.getByTestId("tag-rust")); expect(onTagSelect).toHaveBeenCalledWith("rust"); }); it("toggles tag selection off when same tag clicked", async () => { const onTagSelect = vi.fn(); render(() => ); await fireEvent.click(screen.getByTestId("tag-rust")); expect(onTagSelect).toHaveBeenCalledWith(undefined); }); it("handles empty notes array", () => { render(() => ); expect(screen.getByTestId("notes-sidebar")).toBeInTheDocument(); expect(screen.getByTestId("filter-all")).toHaveTextContent("All (0)"); }); });