Yaltopia-Ticket-Email/tests/unit/config.test.ts

168 lines
5.9 KiB
TypeScript

import { config, validateConfig } from '../../src/lib/config';
describe('Config Module', () => {
const originalEnv = process.env;
beforeEach(() => {
// Reset environment variables
jest.resetModules();
process.env = { ...originalEnv };
});
afterAll(() => {
process.env = originalEnv;
});
describe('Configuration Loading', () => {
it('should load configuration from environment variables', () => {
expect(config.email.resendApiKey).toBe('test-api-key');
expect(config.email.fromDomain).toBe('test.com');
expect(config.app.nodeEnv).toBe('test');
});
it('should use default values for optional variables', () => {
expect(config.email.fromEmail).toBe('noreply@test.com');
expect(config.app.port).toBe(3001);
expect(config.app.logLevel).toBe('error'); // Set in test setup
});
it('should apply feature flags based on NODE_ENV', () => {
expect(config.features.enableEmailSender).toBe(false); // test env
expect(config.features.enableDetailedErrors).toBe(false); // test env
});
});
describe('Required Environment Variables', () => {
it('should validate required environment variables exist', () => {
// Test that the required variables are set in our test environment
expect(process.env.RESEND_API_KEY).toBeDefined()
expect(process.env.FROM_DOMAIN).toBeDefined()
});
});
describe('Configuration Structure', () => {
it('should have email configuration', () => {
expect(config.email).toHaveProperty('resendApiKey');
expect(config.email).toHaveProperty('fromDomain');
expect(config.email).toHaveProperty('fromEmail');
});
it('should have security configuration', () => {
expect(config.security).toHaveProperty('rateLimit');
expect(config.security).toHaveProperty('corsOrigin');
expect(config.security.rateLimit).toHaveProperty('max');
expect(config.security.rateLimit).toHaveProperty('windowMs');
});
it('should have app configuration', () => {
expect(config.app).toHaveProperty('nodeEnv');
expect(config.app).toHaveProperty('port');
expect(config.app).toHaveProperty('logLevel');
});
it('should have default company configuration', () => {
expect(config.defaults.company).toHaveProperty('name');
expect(config.defaults.company).toHaveProperty('logoUrl');
expect(config.defaults.company).toHaveProperty('primaryColor');
});
it('should have feature flags', () => {
expect(config.features).toHaveProperty('enableEmailSender');
expect(config.features).toHaveProperty('enableDetailedErrors');
});
});
describe('Type Safety', () => {
it('should have immutable configuration structure', () => {
// Configuration should be readonly (TypeScript enforces this at compile time)
expect(typeof config.email.resendApiKey).toBe('string');
expect(typeof config.app.port).toBe('number');
});
it('should parse numeric values correctly', () => {
expect(typeof config.app.port).toBe('number');
expect(typeof config.security.rateLimit.max).toBe('number');
expect(typeof config.security.rateLimit.windowMs).toBe('number');
});
});
describe('Configuration Validation', () => {
it('should validate valid configuration', () => {
expect(() => validateConfig()).not.toThrow();
});
it('should validate domain format logic', () => {
// Test the validation logic directly
const validDomain = 'test.com'
const invalidDomain = 'invalid-domain'
expect(validDomain.includes('.')).toBe(true)
expect(invalidDomain.includes('.')).toBe(false)
});
it('should validate rate limit ranges', () => {
// Test rate limit validation logic
const validMax = 10
const invalidMaxLow = 0
const invalidMaxHigh = 2000
expect(validMax >= 1 && validMax <= 1000).toBe(true)
expect(invalidMaxLow >= 1 && invalidMaxLow <= 1000).toBe(false)
expect(invalidMaxHigh >= 1 && invalidMaxHigh <= 1000).toBe(false)
});
it('should validate port ranges', () => {
// Test port validation logic
const validPort = 3001
const invalidPortLow = 0
const invalidPortHigh = 70000
expect(validPort >= 1 && validPort <= 65535).toBe(true)
expect(invalidPortLow >= 1 && invalidPortLow <= 65535).toBe(false)
expect(invalidPortHigh >= 1 && invalidPortHigh <= 65535).toBe(false)
});
});
describe('Environment-Specific Behavior', () => {
it('should enable features in development', () => {
// Test the logic directly rather than reloading modules
const nodeEnv: string = 'development'
const isDevelopment = nodeEnv === 'development'
expect(isDevelopment).toBe(true)
});
it('should disable features in production', () => {
// Test the logic directly rather than reloading modules
const nodeEnv: string = 'production'
const isProduction = nodeEnv !== 'development'
expect(isProduction).toBe(true)
});
});
describe('Default Values', () => {
it('should use default FROM_EMAIL when not provided', () => {
// Test the default logic
const fromDomain = 'test.com'
const defaultFromEmail = `noreply@${fromDomain}`
expect(defaultFromEmail).toBe('noreply@test.com')
});
it('should use custom FROM_EMAIL when provided', () => {
// Test custom email logic
const customEmail = 'custom@test.com'
expect(customEmail).toBe('custom@test.com')
});
it('should use default CORS origin', () => {
// Test default CORS origin
const defaultCorsOrigin = 'http://localhost:3000'
expect(defaultCorsOrigin).toBe('http://localhost:3000')
});
it('should use default company settings', () => {
expect(config.defaults.company.name).toBe('Your Company');
expect(config.defaults.company.logoUrl).toBe('');
expect(config.defaults.company.primaryColor).toBe('#f97316');
});
});
});