/** * @file Tests Settings → About's Quit AgentHub button (issue #65): it asks * first, says when start-at-login will bring the dashboard back, and only a * confirmed ask reaches POST /api/settings/quit. Plus the status-area icon * switch, which goes straight to PUT /api/settings/tray, and Uninstall * AgentHub, which also asks first. * @author Nguyễn Ngọc Trí Vĩ */ import { describe, it, expect, vi, beforeEach } from "vitest"; import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import { AutostartSettings } from "../AutostartSettings"; import { api } from "../../../lib/api"; import * as confirm from "../../../lib/confirm"; vi.mock("../../../lib/api", () => ({ api: { settings: { autostart: { get: vi.fn(), set: vi.fn() }, tray: { get: vi.fn(), set: vi.fn() }, quit: vi.fn(), uninstall: vi.fn(), }, }, })); const status = { available: true, kind: "systemd", enabled: true, foreign: false }; const trayOff = { available: true, enabled: false, running: false }; describe("Quit AgentHub", () => { beforeEach(() => { vi.mocked(api.settings.autostart.get).mockResolvedValue(status as never); vi.mocked(api.settings.tray.get).mockResolvedValue(trayOff); vi.mocked(api.settings.quit).mockReset().mockResolvedValue({ ok: true, killed: 0 }); }); it("does nothing when the ask is cancelled", async () => { vi.spyOn(confirm, "confirmDialog").mockResolvedValue(false); render(); fireEvent.click(screen.getByTestId("quit-agenthub")); await waitFor(() => expect(confirm.confirmDialog).toHaveBeenCalled()); expect(api.settings.quit).not.toHaveBeenCalled(); }); it("quits once confirmed, warning that start-at-login brings it back", async () => { const ask = vi.spyOn(confirm, "confirmDialog").mockResolvedValue(true); render(); await waitFor(() => expect(api.settings.autostart.get).toHaveBeenCalled()); await screen.findByRole("switch", { checked: true }); fireEvent.click(screen.getByTestId("quit-agenthub")); await waitFor(() => expect(api.settings.quit).toHaveBeenCalledTimes(1)); expect(ask.mock.calls[0]![0].message).toMatch(/next boot\/login/); expect(screen.getByTestId("quit-agenthub")).toBeDisabled(); }); it("turns the status-area icon on from its switch", async () => { vi.mocked(api.settings.tray.set).mockResolvedValue({ ...trayOff, enabled: true, running: true, }); render(); await waitFor(() => expect(api.settings.tray.get).toHaveBeenCalled()); const icon = screen.getAllByRole("switch")[1]!; await waitFor(() => expect(icon).toBeEnabled()); fireEvent.click(icon); await waitFor(() => expect(api.settings.tray.set).toHaveBeenCalledWith(true)); await waitFor(() => expect(icon).toBeChecked()); }); }); describe("Uninstall AgentHub", () => { beforeEach(() => { vi.mocked(api.settings.autostart.get).mockResolvedValue(status as never); vi.mocked(api.settings.tray.get).mockResolvedValue(trayOff); vi.mocked(api.settings.uninstall) .mockReset() .mockResolvedValue({ ok: true, log: "/tmp/agenthub-uninstall-1.log" }); }); it("does nothing when the ask is cancelled", async () => { vi.spyOn(confirm, "confirmDialog").mockResolvedValue(false); render(); fireEvent.click(screen.getByTestId("uninstall-agenthub")); await waitFor(() => expect(confirm.confirmDialog).toHaveBeenCalled()); expect(api.settings.uninstall).not.toHaveBeenCalled(); }); it("uninstalls once confirmed, saying the database goes too", async () => { const ask = vi.spyOn(confirm, "confirmDialog").mockResolvedValue(true); render(); fireEvent.click(screen.getByTestId("uninstall-agenthub")); await waitFor(() => expect(api.settings.uninstall).toHaveBeenCalledTimes(1)); expect(ask.mock.calls[0]![0].message).toMatch(/database/); expect(screen.getByTestId("uninstall-agenthub")).toBeDisabled(); }); });