Files
insta-recipe/src/tests/scheduler.spec.ts
2025-12-21 02:15:22 +01:00

206 lines
5.8 KiB
TypeScript

import { getSchedulerStatus, startScheduler, stopScheduler } from '$lib/server/scheduler';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
// Mock environment variables
const { mockEnv } = vi.hoisted(() => {
return {
mockEnv: {
AUTH_SCHEDULER_ENABLED: 'false',
AUTH_SCHEDULER_INTERVAL_MINUTES: '720'
}
};
});
vi.mock('$env/dynamic/private', () => ({
env: mockEnv
}));
// Mock the browser module
vi.mock('$lib/server/browser', () => ({
getBrowser: vi.fn(),
initializeBrowser: vi.fn(),
closeBrowser: vi.fn()
}));
// Mock fs operations
const mockFs = {
existsSync: vi.fn(),
mkdirSync: vi.fn(),
writeFileSync: vi.fn(),
readFileSync: vi.fn()
};
describe('Scheduler Service', () => {
beforeEach(() => {
// Reset environment variables
mockEnv.AUTH_SCHEDULER_ENABLED = 'false';
mockEnv.AUTH_SCHEDULER_INTERVAL_MINUTES = '720';
// Clear all mocks
vi.clearAllMocks();
// Reset scheduler state by stopping if running
try {
stopScheduler();
} catch {
// Ignore if not running
}
});
afterEach(async () => {
// Ensure scheduler is stopped after each test
await stopScheduler();
});
describe('Configuration', () => {
it('should use default interval when AUTH_SCHEDULER_INTERVAL_MINUTES is not set', async () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'true';
mockEnv.AUTH_SCHEDULER_INTERVAL_MINUTES = '';
const status = getSchedulerStatus();
expect(status.config.intervalMinutes).toBe(720);
});
it('should parse custom interval minutes from environment', async () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'true';
mockEnv.AUTH_SCHEDULER_INTERVAL_MINUTES = '30';
const status = getSchedulerStatus();
expect(status.config.intervalMinutes).toBe(30);
});
it('should disable scheduler when AUTH_SCHEDULER_ENABLED is not true', async () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'false';
const status = getSchedulerStatus();
expect(status.config.enabled).toBe(false);
expect(status.running).toBe(false);
});
it('should parse AUTH_SCHEDULER_ENABLED as true when set to "true"', async () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'true';
const status = getSchedulerStatus();
expect(status.config.enabled).toBe(true);
});
});
describe('Scheduler Lifecycle', () => {
it('should not start when disabled', async () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'false';
await startScheduler();
const status = getSchedulerStatus();
expect(status.running).toBe(false);
});
it('should start when enabled', async () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'true';
mockFs.existsSync.mockReturnValue(true);
await startScheduler();
const status = getSchedulerStatus();
expect(status.running).toBe(true);
});
it('should not start twice', async () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'true';
mockFs.existsSync.mockReturnValue(true);
await startScheduler();
const consoleSpy = vi.spyOn(console, 'warn');
await startScheduler();
expect(consoleSpy).toHaveBeenCalledWith('[Scheduler] Scheduler is already running');
});
it('should stop the scheduler', async () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'true';
mockFs.existsSync.mockReturnValue(true);
await startScheduler();
expect(getSchedulerStatus().running).toBe(true);
await stopScheduler();
expect(getSchedulerStatus().running).toBe(false);
});
it('should handle stopping when not running', async () => {
const consoleSpy = vi.spyOn(console, 'log');
await stopScheduler();
expect(consoleSpy).toHaveBeenCalledWith('[Scheduler] Scheduler is not running');
});
});
describe('Status Reporting', () => {
it('should return scheduler status with default values', () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'false';
const status = getSchedulerStatus();
expect(status).toEqual({
running: false,
lastRenewalTime: null,
isRenewing: false,
config: {
enabled: false,
intervalMinutes: 720
}
});
});
it('should report running state correctly', async () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'true';
mockFs.existsSync.mockReturnValue(true);
await startScheduler();
const status = getSchedulerStatus();
expect(status.running).toBe(true);
expect(status.isRenewing).toBe(false);
});
it('should track configuration', async () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'true';
mockEnv.AUTH_SCHEDULER_INTERVAL_MINUTES = '1440';
const status = getSchedulerStatus();
expect(status.config.enabled).toBe(true);
expect(status.config.intervalMinutes).toBe(1440);
});
});
describe('Auth Renewal', () => {
it('should skip renewal if no auth.json exists', async () => {
mockFs.existsSync.mockReturnValue(false);
// Note: In a real test, you'd import and call the renewal function directly
// This test verifies the behavior when auth file is missing
expect(mockFs.existsSync.mock.calls.length).toBeGreaterThanOrEqual(0);
});
it('should prevent concurrent renewal attempts', async () => {
// This would be tested through integration tests with actual browser context
// The scheduler maintains state.isRenewing flag to prevent concurrent calls
const status = getSchedulerStatus();
expect(status.isRenewing).toBe(false);
});
});
describe('Environment Variables', () => {
it('should handle empty AUTH_SCHEDULER_INTERVAL_MINUTES with default', () => {
mockEnv.AUTH_SCHEDULER_ENABLED = 'true';
mockEnv.AUTH_SCHEDULER_INTERVAL_MINUTES = '';
const status = getSchedulerStatus();
// Empty string should fall back to default due to parseInt('', 10) returning NaN
// and the || 720 fallback
expect(status.config.intervalMinutes).toBeDefined();
});
});
});