import { getMailgunConfig, isMailgunConfigured, isDevelopmentMode, } from '../mailgun.config'; // Mock environment utilities jest.mock('../../utils/env', () => ({ getEnvVar: jest.fn(), isProduction: jest.fn(), })); describe('Mailgun Configuration', () => { let mockGetEnvVar: jest.MockedFunction; let mockIsProduction: jest.MockedFunction; beforeEach(() => { jest.clearAllMocks(); // Get mocked functions const envUtils = require('../../utils/env'); mockGetEnvVar = envUtils.getEnvVar; mockIsProduction = envUtils.isProduction; // Default mock implementations mockIsProduction.mockReturnValue(false); }); describe('getMailgunConfig', () => { test('should return config with all environment variables set', () => { mockGetEnvVar .mockReturnValueOnce('test-api-key') // VITE_MAILGUN_API_KEY .mockReturnValueOnce('test.domain.com') // VITE_MAILGUN_DOMAIN .mockReturnValueOnce('https://api.mailgun.net/v3') // VITE_MAILGUN_BASE_URL .mockReturnValueOnce('Test App') // VITE_MAILGUN_FROM_NAME .mockReturnValueOnce('noreply@test.com'); // VITE_MAILGUN_FROM_EMAIL const config = getMailgunConfig(); expect(config).toEqual({ apiKey: 'test-api-key', domain: 'test.domain.com', baseUrl: 'https://api.mailgun.net/v3', fromName: 'Test App', fromEmail: 'noreply@test.com', }); expect(mockGetEnvVar).toHaveBeenCalledTimes(5); expect(mockGetEnvVar).toHaveBeenNthCalledWith(1, 'VITE_MAILGUN_API_KEY'); expect(mockGetEnvVar).toHaveBeenNthCalledWith(2, 'VITE_MAILGUN_DOMAIN'); expect(mockGetEnvVar).toHaveBeenNthCalledWith( 3, 'VITE_MAILGUN_BASE_URL', 'https://api.mailgun.net/v3' ); expect(mockGetEnvVar).toHaveBeenNthCalledWith( 4, 'VITE_MAILGUN_FROM_NAME', 'Medication Reminder' ); expect(mockGetEnvVar).toHaveBeenNthCalledWith( 5, 'VITE_MAILGUN_FROM_EMAIL' ); }); test('should use default values for optional config', () => { mockGetEnvVar.mockImplementation((key: string, defaultValue?: string) => { if (key === 'VITE_MAILGUN_API_KEY') return 'test-api-key'; if (key === 'VITE_MAILGUN_DOMAIN') return 'test.domain.com'; if (key === 'VITE_MAILGUN_FROM_EMAIL') return 'noreply@test.com'; return defaultValue; }); const config = getMailgunConfig(); expect(config.baseUrl).toBe('https://api.mailgun.net/v3'); expect(config.fromName).toBe('Medication Reminder'); }); test('should handle missing environment variables gracefully', () => { mockGetEnvVar.mockImplementation( (_key: string, defaultValue?: string) => defaultValue ); const config = getMailgunConfig(); expect(config).toEqual({ apiKey: undefined, domain: undefined, baseUrl: 'https://api.mailgun.net/v3', fromName: 'Medication Reminder', fromEmail: undefined, }); }); }); describe('isMailgunConfigured', () => { test('should return true when all required config is present', () => { mockGetEnvVar.mockImplementation((key: string, defaultValue?: string) => { switch (key) { case 'VITE_MAILGUN_API_KEY': return 'test-api-key'; case 'VITE_MAILGUN_DOMAIN': return 'test.domain.com'; case 'VITE_MAILGUN_FROM_EMAIL': return 'noreply@test.com'; case 'VITE_MAILGUN_BASE_URL': return 'https://api.mailgun.net/v3'; case 'VITE_MAILGUN_FROM_NAME': return 'Test App'; default: return defaultValue; } }); expect(isMailgunConfigured()).toBe(true); }); test('should return false when apiKey is missing', () => { mockGetEnvVar.mockImplementation((key: string, defaultValue?: string) => { switch (key) { case 'VITE_MAILGUN_API_KEY': return undefined; case 'VITE_MAILGUN_DOMAIN': return 'test.domain.com'; case 'VITE_MAILGUN_FROM_EMAIL': return 'noreply@test.com'; case 'VITE_MAILGUN_BASE_URL': return 'https://api.mailgun.net/v3'; case 'VITE_MAILGUN_FROM_NAME': return 'Test App'; default: return defaultValue; } }); expect(isMailgunConfigured()).toBe(false); }); test('should return false when domain is missing', () => { mockGetEnvVar.mockImplementation((key: string, defaultValue?: string) => { switch (key) { case 'VITE_MAILGUN_API_KEY': return 'test-api-key'; case 'VITE_MAILGUN_DOMAIN': return undefined; case 'VITE_MAILGUN_FROM_EMAIL': return 'noreply@test.com'; case 'VITE_MAILGUN_BASE_URL': return 'https://api.mailgun.net/v3'; case 'VITE_MAILGUN_FROM_NAME': return 'Test App'; default: return defaultValue; } }); expect(isMailgunConfigured()).toBe(false); }); test('should return false when fromEmail is missing', () => { mockGetEnvVar.mockImplementation((key: string, defaultValue?: string) => { switch (key) { case 'VITE_MAILGUN_API_KEY': return 'test-api-key'; case 'VITE_MAILGUN_DOMAIN': return 'test.domain.com'; case 'VITE_MAILGUN_FROM_EMAIL': return undefined; case 'VITE_MAILGUN_BASE_URL': return 'https://api.mailgun.net/v3'; case 'VITE_MAILGUN_FROM_NAME': return 'Test App'; default: return defaultValue; } }); expect(isMailgunConfigured()).toBe(false); }); test('should return false when required fields are empty strings', () => { mockGetEnvVar.mockImplementation((key: string, defaultValue?: string) => { switch (key) { case 'VITE_MAILGUN_API_KEY': return ''; case 'VITE_MAILGUN_DOMAIN': return 'test.domain.com'; case 'VITE_MAILGUN_FROM_EMAIL': return 'noreply@test.com'; case 'VITE_MAILGUN_BASE_URL': return 'https://api.mailgun.net/v3'; case 'VITE_MAILGUN_FROM_NAME': return 'Test App'; default: return defaultValue; } }); expect(isMailgunConfigured()).toBe(false); }); test('should return true even when optional fields are missing', () => { // Provide only required fields (optional ones fall back to defaults) mockGetEnvVar.mockImplementation((key: string, defaultValue?: string) => { switch (key) { case 'VITE_MAILGUN_API_KEY': return 'test-api-key'; case 'VITE_MAILGUN_DOMAIN': return 'test.domain.com'; case 'VITE_MAILGUN_FROM_EMAIL': return 'noreply@test.com'; // baseUrl and fromName return undefined so defaults are applied default: return defaultValue; } }); expect(isMailgunConfigured()).toBe(true); }); }); describe('isDevelopmentMode', () => { test('should return true when not in production and Mailgun not configured', () => { mockIsProduction.mockReturnValue(false); mockGetEnvVar.mockReturnValue(undefined); expect(isDevelopmentMode()).toBe(true); }); test('should return false when in production even if Mailgun not configured', () => { mockIsProduction.mockReturnValue(true); expect(isDevelopmentMode()).toBe(false); }); test('should return false when Mailgun is configured regardless of environment', () => { mockIsProduction.mockReturnValue(false); mockGetEnvVar .mockReturnValueOnce('test-api-key') .mockReturnValueOnce('test.domain.com') .mockReturnValueOnce('https://api.mailgun.net/v3') .mockReturnValueOnce('Test App') .mockReturnValueOnce('noreply@test.com'); expect(isDevelopmentMode()).toBe(false); }); test('should return false when in production and Mailgun is configured', () => { mockIsProduction.mockReturnValue(true); mockGetEnvVar .mockReturnValueOnce('test-api-key') .mockReturnValueOnce('test.domain.com') .mockReturnValueOnce('https://api.mailgun.net/v3') .mockReturnValueOnce('Test App') .mockReturnValueOnce('noreply@test.com'); expect(isDevelopmentMode()).toBe(false); }); }); describe('integration scenarios', () => { test('should work with complete configuration', () => { mockGetEnvVar.mockImplementation((key: string, defaultValue?: string) => { switch (key) { case 'VITE_MAILGUN_API_KEY': return 'real-api-key'; case 'VITE_MAILGUN_DOMAIN': return 'mg.example.com'; case 'VITE_MAILGUN_FROM_EMAIL': return 'support@example.com'; default: return defaultValue; } }); expect(isMailgunConfigured()).toBe(true); expect(isDevelopmentMode()).toBe(false); }); test('should work in development mode', () => { mockGetEnvVar.mockReturnValue(undefined); mockIsProduction.mockReturnValue(false); expect(isMailgunConfigured()).toBe(false); expect(isDevelopmentMode()).toBe(true); }); }); });