Files
gridpilot.gg/tests/unit/infrastructure/AutomationConfig.test.ts

407 lines
13 KiB
TypeScript

import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { loadAutomationConfig, getAutomationMode, AutomationMode } from '../../../packages/infrastructure/config/AutomationConfig';
describe('AutomationConfig', () => {
const originalEnv = process.env;
beforeEach(() => {
// Reset environment before each test
process.env = { ...originalEnv };
});
afterEach(() => {
// Restore original environment
process.env = originalEnv;
});
describe('getAutomationMode', () => {
describe('NODE_ENV-based mode detection', () => {
it('should return development mode when NODE_ENV=development', () => {
process.env.NODE_ENV = 'development';
delete process.env.AUTOMATION_MODE;
const mode = getAutomationMode();
expect(mode).toBe('development');
});
it('should return production mode when NODE_ENV=production', () => {
process.env.NODE_ENV = 'production';
delete process.env.AUTOMATION_MODE;
const mode = getAutomationMode();
expect(mode).toBe('production');
});
it('should return test mode when NODE_ENV=test', () => {
process.env.NODE_ENV = 'test';
delete process.env.AUTOMATION_MODE;
const mode = getAutomationMode();
expect(mode).toBe('test');
});
it('should return development mode when NODE_ENV is not set', () => {
delete process.env.NODE_ENV;
delete process.env.AUTOMATION_MODE;
const mode = getAutomationMode();
expect(mode).toBe('development');
});
it('should return development mode for unknown NODE_ENV values', () => {
process.env.NODE_ENV = 'staging';
delete process.env.AUTOMATION_MODE;
const mode = getAutomationMode();
expect(mode).toBe('development');
});
});
describe('legacy AUTOMATION_MODE support', () => {
it('should map legacy dev mode to development with deprecation warning', () => {
process.env.AUTOMATION_MODE = 'dev';
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
const mode = getAutomationMode();
expect(mode).toBe('development');
expect(consoleSpy).toHaveBeenCalledWith(
expect.stringContaining('[DEPRECATED] AUTOMATION_MODE')
);
consoleSpy.mockRestore();
});
it('should map legacy mock mode to test with deprecation warning', () => {
process.env.AUTOMATION_MODE = 'mock';
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
const mode = getAutomationMode();
expect(mode).toBe('test');
expect(consoleSpy).toHaveBeenCalledWith(
expect.stringContaining('[DEPRECATED] AUTOMATION_MODE')
);
consoleSpy.mockRestore();
});
it('should map legacy production mode to production with deprecation warning', () => {
process.env.AUTOMATION_MODE = 'production';
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
const mode = getAutomationMode();
expect(mode).toBe('production');
expect(consoleSpy).toHaveBeenCalledWith(
expect.stringContaining('[DEPRECATED] AUTOMATION_MODE')
);
consoleSpy.mockRestore();
});
it('should ignore invalid AUTOMATION_MODE and use NODE_ENV', () => {
process.env.AUTOMATION_MODE = 'invalid-mode';
process.env.NODE_ENV = 'production';
const mode = getAutomationMode();
expect(mode).toBe('production');
});
});
});
describe('loadAutomationConfig', () => {
describe('default configuration', () => {
it('should return development mode when NODE_ENV is not set', () => {
delete process.env.NODE_ENV;
delete process.env.AUTOMATION_MODE;
const config = loadAutomationConfig();
expect(config.mode).toBe('development');
});
it('should return default devTools configuration', () => {
const config = loadAutomationConfig();
expect(config.devTools?.debuggingPort).toBe(9222);
expect(config.devTools?.browserWSEndpoint).toBeUndefined();
});
it('should return default nutJs configuration', () => {
const config = loadAutomationConfig();
expect(config.nutJs?.windowTitle).toBe('iRacing');
expect(config.nutJs?.templatePath).toBe('./resources/templates');
expect(config.nutJs?.confidence).toBe(0.9);
});
it('should return default shared settings', () => {
const config = loadAutomationConfig();
expect(config.defaultTimeout).toBe(30000);
expect(config.retryAttempts).toBe(3);
expect(config.screenshotOnError).toBe(true);
});
it('should return default fixture server configuration', () => {
delete process.env.NODE_ENV;
delete process.env.AUTOMATION_MODE;
const config = loadAutomationConfig();
expect(config.fixtureServer?.port).toBe(3456);
expect(config.fixtureServer?.autoStart).toBe(true);
expect(config.fixtureServer?.fixturesPath).toBe('./resources/iracing-hosted-sessions');
});
});
describe('development mode configuration', () => {
it('should return development mode when NODE_ENV=development', () => {
process.env.NODE_ENV = 'development';
delete process.env.AUTOMATION_MODE;
const config = loadAutomationConfig();
expect(config.mode).toBe('development');
});
it('should parse CHROME_DEBUG_PORT', () => {
process.env.CHROME_DEBUG_PORT = '9333';
const config = loadAutomationConfig();
expect(config.devTools?.debuggingPort).toBe(9333);
});
it('should read CHROME_WS_ENDPOINT', () => {
process.env.CHROME_WS_ENDPOINT = 'ws://127.0.0.1:9222/devtools/browser/abc123';
const config = loadAutomationConfig();
expect(config.devTools?.browserWSEndpoint).toBe('ws://127.0.0.1:9222/devtools/browser/abc123');
});
});
describe('production mode configuration', () => {
it('should return production mode when NODE_ENV=production', () => {
process.env.NODE_ENV = 'production';
delete process.env.AUTOMATION_MODE;
const config = loadAutomationConfig();
expect(config.mode).toBe('production');
});
it('should parse IRACING_WINDOW_TITLE', () => {
process.env.IRACING_WINDOW_TITLE = 'iRacing Simulator';
const config = loadAutomationConfig();
expect(config.nutJs?.windowTitle).toBe('iRacing Simulator');
});
it('should parse TEMPLATE_PATH', () => {
process.env.TEMPLATE_PATH = '/custom/templates';
const config = loadAutomationConfig();
expect(config.nutJs?.templatePath).toBe('/custom/templates');
});
it('should parse OCR_CONFIDENCE', () => {
process.env.OCR_CONFIDENCE = '0.85';
const config = loadAutomationConfig();
expect(config.nutJs?.confidence).toBe(0.85);
});
});
describe('environment variable parsing', () => {
it('should parse AUTOMATION_TIMEOUT', () => {
process.env.AUTOMATION_TIMEOUT = '60000';
const config = loadAutomationConfig();
expect(config.defaultTimeout).toBe(60000);
});
it('should parse RETRY_ATTEMPTS', () => {
process.env.RETRY_ATTEMPTS = '5';
const config = loadAutomationConfig();
expect(config.retryAttempts).toBe(5);
});
it('should parse SCREENSHOT_ON_ERROR=false', () => {
process.env.SCREENSHOT_ON_ERROR = 'false';
const config = loadAutomationConfig();
expect(config.screenshotOnError).toBe(false);
});
it('should parse SCREENSHOT_ON_ERROR=true', () => {
process.env.SCREENSHOT_ON_ERROR = 'true';
const config = loadAutomationConfig();
expect(config.screenshotOnError).toBe(true);
});
it('should fallback to defaults for invalid integer values', () => {
process.env.CHROME_DEBUG_PORT = 'invalid';
process.env.AUTOMATION_TIMEOUT = 'not-a-number';
process.env.RETRY_ATTEMPTS = '';
const config = loadAutomationConfig();
expect(config.devTools?.debuggingPort).toBe(9222);
expect(config.defaultTimeout).toBe(30000);
expect(config.retryAttempts).toBe(3);
});
it('should fallback to defaults for invalid float values', () => {
process.env.OCR_CONFIDENCE = 'invalid';
const config = loadAutomationConfig();
expect(config.nutJs?.confidence).toBe(0.9);
});
it('should fallback to development mode for invalid NODE_ENV', () => {
process.env.NODE_ENV = 'invalid-env';
delete process.env.AUTOMATION_MODE;
const config = loadAutomationConfig();
expect(config.mode).toBe('development');
});
});
describe('fixture server configuration', () => {
it('should auto-start fixture server in development mode', () => {
process.env.NODE_ENV = 'development';
delete process.env.AUTOMATION_MODE;
const config = loadAutomationConfig();
expect(config.fixtureServer?.autoStart).toBe(true);
});
it('should not auto-start fixture server in production mode', () => {
process.env.NODE_ENV = 'production';
delete process.env.AUTOMATION_MODE;
const config = loadAutomationConfig();
expect(config.fixtureServer?.autoStart).toBe(false);
});
it('should not auto-start fixture server in test mode', () => {
process.env.NODE_ENV = 'test';
delete process.env.AUTOMATION_MODE;
const config = loadAutomationConfig();
expect(config.fixtureServer?.autoStart).toBe(false);
});
it('should parse FIXTURE_SERVER_PORT', () => {
process.env.FIXTURE_SERVER_PORT = '4567';
const config = loadAutomationConfig();
expect(config.fixtureServer?.port).toBe(4567);
});
it('should parse FIXTURE_SERVER_PATH', () => {
process.env.FIXTURE_SERVER_PATH = '/custom/fixtures';
const config = loadAutomationConfig();
expect(config.fixtureServer?.fixturesPath).toBe('/custom/fixtures');
});
it('should respect FIXTURE_SERVER_AUTO_START=false', () => {
process.env.NODE_ENV = 'development';
process.env.FIXTURE_SERVER_AUTO_START = 'false';
delete process.env.AUTOMATION_MODE;
const config = loadAutomationConfig();
expect(config.fixtureServer?.autoStart).toBe(false);
});
});
describe('full configuration scenario', () => {
it('should load complete development environment configuration', () => {
process.env.NODE_ENV = 'development';
delete process.env.AUTOMATION_MODE;
process.env.CHROME_DEBUG_PORT = '9222';
process.env.CHROME_WS_ENDPOINT = 'ws://localhost:9222/devtools/browser/test';
process.env.AUTOMATION_TIMEOUT = '45000';
process.env.RETRY_ATTEMPTS = '2';
process.env.SCREENSHOT_ON_ERROR = 'true';
process.env.FIXTURE_SERVER_PORT = '3456';
process.env.FIXTURE_SERVER_PATH = './resources/iracing-hosted-sessions';
const config = loadAutomationConfig();
expect(config).toEqual({
mode: 'development',
devTools: {
debuggingPort: 9222,
browserWSEndpoint: 'ws://localhost:9222/devtools/browser/test',
},
nutJs: {
mouseSpeed: 1000,
keyboardDelay: 50,
windowTitle: 'iRacing',
templatePath: './resources/templates',
confidence: 0.9,
},
fixtureServer: {
port: 3456,
autoStart: true,
fixturesPath: './resources/iracing-hosted-sessions',
},
defaultTimeout: 45000,
retryAttempts: 2,
screenshotOnError: true,
});
});
it('should load complete test environment configuration', () => {
process.env.NODE_ENV = 'test';
delete process.env.AUTOMATION_MODE;
const config = loadAutomationConfig();
expect(config.mode).toBe('test');
expect(config.devTools).toBeDefined();
expect(config.nutJs).toBeDefined();
expect(config.fixtureServer).toBeDefined();
expect(config.fixtureServer?.autoStart).toBe(false);
});
it('should load complete production environment configuration', () => {
process.env.NODE_ENV = 'production';
delete process.env.AUTOMATION_MODE;
const config = loadAutomationConfig();
expect(config.mode).toBe('production');
expect(config.devTools).toBeDefined();
expect(config.nutJs).toBeDefined();
expect(config.fixtureServer).toBeDefined();
expect(config.fixtureServer?.autoStart).toBe(false);
});
});
});
});