// Jest setup file - runs before all tests // Set NODE_ENV to test to prevent main application from starting process.env.NODE_ENV = 'test'; // Mock fs operations globally to prevent checkpoint.js errors const mockFn = () => { const fn = function(...args) { return fn.mockReturnValue; }; fn.mockReturnValue = undefined; fn.mockResolvedValue = (value) => { fn.mockReturnValue = Promise.resolve(value); return fn; }; return fn; }; global.fs = { readFileSync: () => 'mocked-file-content', writeFileSync: () => {}, mkdirSync: () => {}, existsSync: () => false, readdirSync: () => [], unlinkSync: () => {} }; // Mock fs/promises global.fsPromises = { readFile: () => Promise.resolve('mocked-content'), writeFile: () => Promise.resolve(undefined), mkdir: () => Promise.resolve(undefined) }; // Suppress console warnings and errors during tests for cleaner output const originalConsoleWarn = console.warn; const originalConsoleError = console.error; console.warn = () => {}; console.error = () => {}; // Track timers and intervals for cleanup const timers = new Set(); const immediates = new Set(); const originalSetTimeout = global.setTimeout; const originalSetInterval = global.setInterval; const originalSetImmediate = global.setImmediate; const originalClearTimeout = global.clearTimeout; const originalClearInterval = global.clearInterval; const originalClearImmediate = global.clearImmediate; global.setTimeout = (fn, delay, ...args) => { const id = originalSetTimeout(fn, delay, ...args); timers.add(id); return id; }; global.setInterval = (fn, delay, ...args) => { const id = originalSetInterval(fn, delay, ...args); timers.add(id); return id; }; global.setImmediate = (fn, ...args) => { const id = originalSetImmediate(fn, ...args); immediates.add(id); return id; }; global.clearTimeout = (id) => { timers.delete(id); return originalClearTimeout(id); }; global.clearInterval = (id) => { timers.delete(id); return originalClearInterval(id); }; global.clearImmediate = (id) => { immediates.delete(id); return originalClearImmediate(id); }; global.pendingImmediates = immediates; // Mock @iarna/toml to prevent async import after teardown // Note: This mock will be applied globally for all tests // Comprehensive behavioral detection mocking to prevent async operations global.mockBehavioralDetection = { config: { enabled: false }, isBlocked: () => Promise.resolve({ blocked: false }), getRateLimit: () => Promise.resolve(null), analyzeRequest: () => Promise.resolve({ totalScore: 0, patterns: [] }), loadRules: () => Promise.resolve(), init: () => Promise.resolve() }; // Mock the loadConfig function globally to prevent TOML imports global.mockLoadConfig = async (name, target) => { // Return immediately without trying to import TOML return Promise.resolve(); }; // Mock dynamic imports to prevent teardown issues const originalImport = global.import; if (originalImport) { global.import = (modulePath) => { if (modulePath === '@iarna/toml') { return Promise.resolve({ default: { parse: () => ({}) }, parse: () => ({}) }); } if (modulePath.includes('behavioral-detection')) { return Promise.resolve(global.mockBehavioralDetection); } return originalImport(modulePath); }; } // Function to clear all timers global.clearAllTimers = () => { timers.forEach(id => { originalClearTimeout(id); originalClearInterval(id); }); timers.clear(); immediates.forEach(id => { originalClearImmediate(id); }); immediates.clear(); }; // Clean up after all tests afterAll(() => { // Clear all remaining timers global.clearAllTimers(); // Restore original console methods console.warn = originalConsoleWarn; console.error = originalConsoleError; // Restore original import if it was mocked if (originalImport) { global.import = originalImport; } // Restore original timer functions global.setTimeout = originalSetTimeout; global.setInterval = originalSetInterval; global.setImmediate = originalSetImmediate; global.clearTimeout = originalClearTimeout; global.clearInterval = originalClearInterval; global.clearImmediate = originalClearImmediate; });