import { describe, it, expect, vi, afterEach } from "vitest"; import { render, screen, fireEvent, cleanup } from "@testing-library/react"; import { NotificationItem } from "./notification-item"; afterEach(() => { cleanup(); }); const makeNotification = (overrides?: Record) => ({ id: "1", user_id: "user-1", category: "instance", severity: "info" as const, title: "Container started", message: null, source_type: null, source_id: null, metadata: {}, read_at: null, dismissed_at: null, created_at: "2026-05-29T10:00:00Z", ...overrides, }); describe("NotificationItem", () => { it("displays title and relative time", () => { render( , ); expect(screen.getByText("Container started")).toBeInTheDocument(); expect(screen.getByText(/ago|just now/)).toBeInTheDocument(); }); it("applies unread styling when read_at is null", () => { render( , ); const row = screen.getByRole("listitem"); expect(row.className).toContain("notification-item--unread"); }); it("applies read styling when read_at is set", () => { render( , ); const row = screen.getByRole("listitem"); expect(row.className).toContain("notification-item--read"); }); it("calls onMarkRead when mark read clicked", () => { const onMarkRead = vi.fn(); render( , ); fireEvent.click(screen.getByRole("button", { name: /mark read/i })); expect(onMarkRead).toHaveBeenCalledWith("1"); }); it("calls onDismiss when dismiss clicked", () => { const onDismiss = vi.fn(); render( , ); fireEvent.click(screen.getByRole("button", { name: /dismiss/i })); expect(onDismiss).toHaveBeenCalledWith("1"); }); it("displays severity icon", () => { render( , ); expect(screen.getByRole("img", { hidden: true })).toBeInTheDocument(); }); });