learn and share notes on atproto (wip) 馃 malfestio.stormlightlabs.org/
readability solid axum atproto srs
at main 73 lines 2.6 kB view raw
1import type { Note } from "$lib/model"; 2import type { WikiLink } from "$lib/wikilink"; 3import { cleanup, render, screen } from "@solidjs/testing-library"; 4import { JSX } from "solid-js"; 5import { afterEach, describe, expect, it, vi } from "vitest"; 6import { WikilinksPanel } from "../WikilinksPanel"; 7 8vi.mock( 9 "@solidjs/router", 10 () => ({ A: (props: { href: string; children: JSX.Element }) => <a href={props.href}>{props.children}</a> }), 11); 12 13describe("WikilinksPanel", () => { 14 afterEach(() => { 15 cleanup(); 16 vi.clearAllMocks(); 17 }); 18 19 const mockNotes: Note[] = [{ 20 id: "note-1", 21 owner_did: "did:plc:test", 22 title: "Existing Note", 23 body: "Content", 24 tags: [], 25 visibility: { type: "Private" }, 26 created_at: "2026-01-01T00:00:00Z", 27 updated_at: "2026-01-01T00:00:00Z", 28 }]; 29 30 const mockLinks: WikiLink[] = [{ raw: "[[Existing Note]]", title: "Existing Note", start: 0, end: 17 }, { 31 raw: "[[Missing Note]]", 32 title: "Missing Note", 33 start: 20, 34 end: 36, 35 }, { raw: "[[Aliased|Display]]", title: "Aliased", alias: "Display", start: 40, end: 59 }]; 36 37 const resolveNote = (title: string) => mockNotes.find((n) => n.title === title) ?? null; 38 39 it("renders heading title", () => { 40 render(() => <WikilinksPanel links={[]} notes={[]} resolveNote={() => null} />); 41 expect(screen.getByText("Wikilinks")).toBeInTheDocument(); 42 }); 43 44 it("shows empty state when no links", () => { 45 render(() => <WikilinksPanel links={[]} notes={[]} resolveNote={() => null} />); 46 expect(screen.getByText("No outgoing links")).toBeInTheDocument(); 47 }); 48 49 it("renders resolved links as navigation links", () => { 50 render(() => <WikilinksPanel links={mockLinks} notes={mockNotes} resolveNote={resolveNote} />); 51 const existingLink = screen.getByRole("link", { name: /Existing Note/ }); 52 expect(existingLink).toHaveAttribute("href", "/notes/note-1"); 53 }); 54 55 it("renders unresolved links with strikethrough", () => { 56 render(() => <WikilinksPanel links={mockLinks} notes={mockNotes} resolveNote={resolveNote} />); 57 const missingLink = screen.getByText("Missing Note"); 58 expect(missingLink).toHaveClass("line-through"); 59 }); 60 61 it("deduplicates links by title", () => { 62 const duplicateLinks: WikiLink[] = [{ raw: "[[Same]]", title: "Same", start: 0, end: 8 }, { 63 raw: "[[Same]]", 64 title: "Same", 65 start: 10, 66 end: 18, 67 }]; 68 69 render(() => <WikilinksPanel links={duplicateLinks} notes={[]} resolveNote={() => null} />); 70 const sameLinks = screen.getAllByText("Same"); 71 expect(sameLinks).toHaveLength(1); 72 }); 73});