import { describe, expect, it, vi } from "vitest"; import type { RendererSettings, UiSnapshot } from "../src/shared/types"; import { activateDailyScheduleSettings, buildScheduleCancellationSettingsUpdate, buildDailyScheduleSettingsUpdate, persistDailyScheduleSettingsUpdate, resolveDailyScheduleInitialTime } from "../src/renderer/App"; describe("daily schedule settings form", () => { it("maps local time and the chosen start day to the recurring schedule settings", () => { const now = new Date(2026, 7, 22, 18, 30, 0, 0); expect(buildDailyScheduleSettingsUpdate("08:15", "today", now)).toEqual({ dailyStartEnabled: true, dailyStartMinuteOfDay: 8 * 60 + 15, dailyStartFirstLocalDate: "2026-08-22" }); expect(buildDailyScheduleSettingsUpdate("23:45", "tomorrow", now)).toEqual({ dailyStartEnabled: true, dailyStartMinuteOfDay: 23 * 60 + 45, dailyStartFirstLocalDate: "2026-08-23" }); }); it("prefills a previously saved disabled rule and uses local time only for the empty default", () => { const now = new Date(2026, 7, 22, 18, 30, 0, 0); const disabledSavedRule = { dailyStartEnabled: false, dailyStartMinuteOfDay: 8 * 60 + 15, dailyStartFirstLocalDate: "2026-08-21" }; expect(resolveDailyScheduleInitialTime(disabledSavedRule, now)).toBe("08:15"); expect(resolveDailyScheduleInitialTime({ dailyStartMinuteOfDay: 0, dailyStartFirstLocalDate: "" }, now)).toBe("18:30"); }); it.each(["", "8:15", "24:00", "12:60"])("reports the invalid time %j when activation is invoked directly", async (time) => { const persist = vi.fn(); const showError = vi.fn(); await expect(activateDailyScheduleSettings( time, "today", persist, showError, new Date(2026, 7, 22, 18, 30, 0, 0) )).resolves.toBe(false); expect(showError).toHaveBeenCalledWith("Bitte eine gültige Startzeit auswählen."); expect(persist).not.toHaveBeenCalled(); }); it("applies persisted settings after a successful activation", async () => { const persisted = { dailyStartEnabled: true } as RendererSettings; const updateSettings = vi.fn().mockResolvedValue(persisted); const applySettings = vi.fn(); const getSnapshot = vi.fn(); const applySnapshot = vi.fn(); const showError = vi.fn(); const update = { dailyStartEnabled: true, dailyStartMinuteOfDay: 495, dailyStartFirstLocalDate: "2026-08-23" }; await expect(persistDailyScheduleSettingsUpdate(update, "activate", { updateSettings, getSnapshot, applySettings, applySnapshot, showError })).resolves.toBe(true); expect(updateSettings).toHaveBeenCalledWith(update); expect(applySettings).toHaveBeenCalledWith(persisted); expect(getSnapshot).not.toHaveBeenCalled(); expect(showError).not.toHaveBeenCalled(); }); it("cancels the active schedule through its owning settings field", () => { expect(buildScheduleCancellationSettingsUpdate({ dailyStartEnabled: true, scheduledStartEpochMs: 1_800_000_000_000 })).toEqual({ dailyStartEnabled: false }); expect(buildScheduleCancellationSettingsUpdate({ dailyStartEnabled: false, scheduledStartEpochMs: 1_800_000_000_000 })).toEqual({ scheduledStartEpochMs: 0 }); }); it.each([ ["activate" as const, "Zeitplan konnte nicht aktiviert werden: Error: Speichern fehlgeschlagen"], ["cancel" as const, "Zeitplan konnte nicht abgebrochen werden: Error: Speichern fehlgeschlagen"] ])("shows %s failures before reconciling the authoritative snapshot", async (operation, expectedMessage) => { const authoritative = { settings: { dailyStartEnabled: false } } as UiSnapshot; const sequence: string[] = []; const updateSettings = vi.fn().mockRejectedValue(new Error("Speichern fehlgeschlagen")); const getSnapshot = vi.fn(async () => { sequence.push("snapshot"); return authoritative; }); const applySnapshot = vi.fn((snapshot: UiSnapshot) => { sequence.push(`apply:${String(snapshot.settings.dailyStartEnabled)}`); }); const showError = vi.fn((message: string) => { sequence.push(`error:${message}`); }); await expect(persistDailyScheduleSettingsUpdate({ dailyStartEnabled: false }, operation, { updateSettings, getSnapshot, applySettings: vi.fn(), applySnapshot, showError })).resolves.toBe(false); expect(showError).toHaveBeenCalledWith(expectedMessage); expect(getSnapshot).toHaveBeenCalledTimes(1); expect(applySnapshot).toHaveBeenCalledWith(authoritative); expect(sequence).toEqual([`error:${expectedMessage}`, "snapshot", "apply:false"]); }); });