import { assertEquals, cleanup, fireEvent, render, screen } from "./setup.ts"; import PostList from "../../islands/PostList.tsx"; const mockPosts = [ { id: "1", title: "First Post", content: "Hello world", shared: false, hasPassword: false, }, { id: "2", title: "Second Post", content: "Another post", shared: true, hasPassword: false, }, { id: "3", title: "", content: "", shared: false, hasPassword: false }, ]; const mockPostWithPassword = [ { id: "4", title: "Protected Post", content: "Secret", shared: true, hasPassword: true, }, ]; Deno.test({ name: "PostList - renders correct number of post cards", fn() { const { container } = render(); const cards = container.querySelectorAll(".grid > div"); assertEquals(cards.length, 3); cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - displays post title", fn() { render(); assertEquals(screen.getByText("First Post") !== null, true); assertEquals(screen.getByText("Second Post") !== null, true); cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - shows Untitled for empty title", fn() { render(); assertEquals(screen.getByText("Untitled") !== null, true); cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - displays post content snippet", fn() { render(); assertEquals(screen.getByText("Hello world") !== null, true); assertEquals(screen.getByText("Another post") !== null, true); cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - shows No content for empty content", fn() { render(); assertEquals(screen.getByText("No content") !== null, true); cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - each card has an Edit button", fn() { render(); const editButtons = screen.getAllByText("Edit"); assertEquals(editButtons.length, 3); cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - each card has a Delete button", fn() { render(); const deleteButtons = screen.getAllByText("Delete"); assertEquals(deleteButtons.length, 3); cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - Delete button triggers $modal.show", fn() { let modalTitle = ""; let modalContent = ""; globalThis.$modal = { show: (title: string, content: string | preact.JSX.Element) => { modalTitle = title; modalContent = content as string; }, hide: () => {}, }; render(); const deleteButton = screen.getByText("Delete"); fireEvent.click(deleteButton); assertEquals(modalTitle, "Confirm delete"); assertEquals(modalContent.includes("First Post"), true); delete globalThis.$modal; cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - shows shared icon for shared posts", fn() { const { container } = render(); const sharedIcons = container.querySelectorAll(".bi-share-fill"); assertEquals(sharedIcons.length, 1); cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - shows lock icon for password-protected posts", fn() { const { container } = render(); const lockIcons = container.querySelectorAll(".bi-lock-fill"); assertEquals(lockIcons.length, 1); cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - hides shared icon in readOnly mode", fn() { const { container } = render(); const sharedIcons = container.querySelectorAll(".bi-share-fill"); assertEquals(sharedIcons.length, 0); cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - hides Edit and Delete buttons in readOnly mode", fn() { render(); assertEquals(screen.queryByText("Edit"), null); assertEquals(screen.queryByText("Delete"), null); cleanup(); }, sanitizeResources: false, sanitizeOps: false, }); Deno.test({ name: "PostList - renders empty grid with no posts", fn() { const { container } = render(); const cards = container.querySelectorAll(".grid > div"); assertEquals(cards.length, 0); cleanup(); }, sanitizeResources: false, sanitizeOps: false, });