import { afterEach, describe, expect, it, vi } from 'vitest'; import { BackgroundLifecycleController } from '../../electron/main/background-lifecycle'; describe('BackgroundLifecycleController', () => { afterEach(() => { vi.useRealTimers(); }); it('stops an idle hidden/inactive desktop after the grace period', async () => { vi.useFakeTimers(); const onSleep = vi.fn().mockResolvedValue(undefined); const onStopRuntime = vi.fn().mockResolvedValue(undefined); const controller = new BackgroundLifecycleController({ idleStopMs: 60_000, onSleep, onStopRuntime, }); controller.setActivity({ visible: false, module: 'painting' }); await vi.advanceTimersByTimeAsync(59_999); expect(onSleep).not.toHaveBeenCalled(); expect(onStopRuntime).not.toHaveBeenCalled(); await vi.advanceTimersByTimeAsync(1); expect(onSleep).toHaveBeenCalledTimes(1); expect(onStopRuntime).toHaveBeenCalledTimes(1); controller.dispose(); }); it('keeps the runtime alive while an active task lease exists', async () => { vi.useFakeTimers(); const onSleep = vi.fn().mockResolvedValue(undefined); const onStopRuntime = vi.fn().mockResolvedValue(undefined); const controller = new BackgroundLifecycleController({ idleStopMs: 60_000, onSleep, onStopRuntime, }); const release = controller.acquireLease({ id: 'release:1', kind: 'publish' }); controller.setActivity({ visible: false, module: 'programming' }); await vi.advanceTimersByTimeAsync(60_000); expect(controller.getLeaseCount()).toBe(1); expect(onStopRuntime).not.toHaveBeenCalled(); release(); await vi.advanceTimersByTimeAsync(60_000); expect(onSleep).toHaveBeenCalledTimes(1); expect(onStopRuntime).toHaveBeenCalledTimes(1); controller.dispose(); }); it('cancels the idle stop when programming becomes visible again', async () => { vi.useFakeTimers(); const onSleep = vi.fn(); const onStopRuntime = vi.fn(); const controller = new BackgroundLifecycleController({ idleStopMs: 60_000, onSleep, onStopRuntime, }); controller.setActivity({ visible: false, module: 'learning' }); await vi.advanceTimersByTimeAsync(30_000); controller.setActivity({ visible: true, module: 'programming' }); await vi.advanceTimersByTimeAsync(90_000); expect(onSleep).not.toHaveBeenCalled(); expect(onStopRuntime).not.toHaveBeenCalled(); controller.dispose(); }); });