import { describe, it, expect, vi } from "vitest"; import { render, screen } from "@testing-library/react"; import { QbittorrentSpeedWidget } from "../QbittorrentSpeedWidget"; import type { WidgetInstance } from "../../types"; import * as useWidgets from "../../hooks/useWidgets"; vi.mock("../../hooks/useWidgets", () => ({ useWidgetData: vi.fn(), })); const widget: WidgetInstance = { id: "w1", service_id: "s1", widget_kind: "speed", title: "Speed Chart", config: {}, enabled: true, sort_order: 0, created_at: 0, updated_at: 0, }; function mockData(data: unknown, error?: string) { vi.mocked(useWidgets.useWidgetData).mockReturnValue({ data: error ? { widget_id: "w1", error, fetched_at: 0 } : { widget_id: "w1", data, fetched_at: 0 }, isLoading: false, } as unknown as ReturnType); } describe("QbittorrentSpeedWidget", () => { it("renders skeleton while loading", () => { vi.mocked(useWidgets.useWidgetData).mockReturnValue({ data: undefined, isLoading: true, } as unknown as ReturnType); render(); expect( document.querySelector('[data-slot="skeleton"]'), ).toBeInTheDocument(); }); it("renders chart with series data", () => { mockData({ series: [ { label: "download", points: [{ t: 1000, v: 500000 }] }, { label: "upload", points: [{ t: 1000, v: 100000 }] }, ], }); const { container } = render( , ); expect(screen.getByText("Speed Chart")).toBeInTheDocument(); expect( screen.queryByRole("combobox", { name: "Chart range" }), ).not.toBeInTheDocument(); expect(container.firstChild).not.toBeNull(); }); it("shows empty state when no series", () => { mockData({ series: [] }); render(); expect(screen.getByText(/No speed data yet/i)).toBeInTheDocument(); }); it("shows error alert on error", () => { mockData(null, "qBittorrent fetch failed"); render(); expect(screen.getByText(/qBittorrent fetch failed/i)).toBeInTheDocument(); }); });