/** * @vitest-environment jsdom */ import "fake-indexeddb/auto"; import { cleanup, render, screen } from "@testing-library/react"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { SyncStatusIndicator } from "./SyncStatusIndicator"; // Mock the useSync hook const mockUseSync = vi.fn(); vi.mock("../stores", () => ({ useSync: () => mockUseSync(), })); // Mock the SyncStatus constant vi.mock("../sync", () => ({ SyncStatus: { Idle: "idle", Syncing: "syncing", Error: "error", }, })); describe("SyncStatusIndicator", () => { beforeEach(() => { vi.clearAllMocks(); }); afterEach(() => { cleanup(); }); it("displays 'Synced' when online with no pending changes", () => { mockUseSync.mockReturnValue({ isOnline: true, isSyncing: false, pendingCount: 0, lastError: null, status: "idle", }); render(); expect(screen.getByText("Synced")).toBeDefined(); expect(screen.getByTestId("sync-status-indicator")).toBeDefined(); }); it("displays 'Offline' when not online", () => { mockUseSync.mockReturnValue({ isOnline: false, isSyncing: false, pendingCount: 0, lastError: null, status: "idle", }); render(); expect(screen.getByText("Offline")).toBeDefined(); }); it("displays 'Syncing...' when syncing", () => { mockUseSync.mockReturnValue({ isOnline: true, isSyncing: true, pendingCount: 0, lastError: null, status: "syncing", }); render(); expect(screen.getByText("Syncing...")).toBeDefined(); }); it("displays pending count when there are pending changes", () => { mockUseSync.mockReturnValue({ isOnline: true, isSyncing: false, pendingCount: 5, lastError: null, status: "idle", }); render(); expect(screen.getByText("5 pending")).toBeDefined(); }); it("displays 'Sync error' when there is an error", () => { mockUseSync.mockReturnValue({ isOnline: true, isSyncing: false, pendingCount: 0, lastError: "Network error", status: "error", }); render(); expect(screen.getByText("Sync error")).toBeDefined(); }); it("shows error message in title when there is an error", () => { mockUseSync.mockReturnValue({ isOnline: true, isSyncing: false, pendingCount: 0, lastError: "Network error", status: "error", }); render(); const indicator = screen.getByTestId("sync-status-indicator"); expect(indicator.getAttribute("title")).toBe("Network error"); }); it("prioritizes offline status over other states", () => { mockUseSync.mockReturnValue({ isOnline: false, isSyncing: true, pendingCount: 5, lastError: "Error", status: "error", }); render(); expect(screen.getByText("Offline")).toBeDefined(); }); it("prioritizes syncing status over pending and error", () => { mockUseSync.mockReturnValue({ isOnline: true, isSyncing: true, pendingCount: 5, lastError: null, status: "syncing", }); render(); expect(screen.getByText("Syncing...")).toBeDefined(); }); it("prioritizes error status over pending", () => { mockUseSync.mockReturnValue({ isOnline: true, isSyncing: false, pendingCount: 5, lastError: "Network error", status: "error", }); render(); expect(screen.getByText("Sync error")).toBeDefined(); }); });