import { loadEnv } from './env'; describe('loadEnv', () => { const valid = { DATABASE_URL: 'postgresql://user:pass@localhost:5432/tracking', JWT_ACCESS_SECRET: 'test-secret-at-least-32-chars-long!!', }; it('loads required values with defaults', () => { const env = loadEnv(valid); expect(env.DATABASE_URL).toBe(valid.DATABASE_URL); expect(env.JWT_ACCESS_SECRET).toBe(valid.JWT_ACCESS_SECRET); expect(env.PORT).toBe(3000); expect(env.JWT_ACCESS_EXPIRES_IN).toBe('15m'); expect(env.JWT_ACCESS_EXPIRES_IN_MS).toBe(15 * 60 * 1000); expect(env.REFRESH_TOKEN_EXPIRES_IN_MS).toBe(7 * 24 * 60 * 60 * 1000); expect(env.BCRYPT_SALT_ROUNDS).toBe(10); expect(env.DEFAULT_TIMEZONE).toBe('GMT+7'); expect(env.SKIP_GPS_VALIDATION).toBe(false); }); it('throws when DATABASE_URL is missing', () => { expect(() => loadEnv({ JWT_ACCESS_SECRET: valid.JWT_ACCESS_SECRET }), ).toThrow('DATABASE_URL is not configured'); }); it('throws when JWT_ACCESS_SECRET is missing', () => { expect(() => loadEnv({ DATABASE_URL: valid.DATABASE_URL })).toThrow( 'JWT_ACCESS_SECRET is not configured', ); }); it('throws when JWT_ACCESS_SECRET is a placeholder', () => { expect(() => loadEnv({ DATABASE_URL: valid.DATABASE_URL, JWT_ACCESS_SECRET: 'change-me-to-a-long-random-secret', }), ).toThrow('known placeholder'); }); it('throws when JWT_ACCESS_SECRET is too short', () => { expect(() => loadEnv({ DATABASE_URL: valid.DATABASE_URL, JWT_ACCESS_SECRET: 'short-secret', }), ).toThrow('at least 32 characters'); }); it('parses optional numeric overrides', () => { const env = loadEnv({ ...valid, PORT: '4000', BCRYPT_SALT_ROUNDS: '12', REFRESH_TOKEN_EXPIRES_IN_MS: '3600000', JWT_ACCESS_EXPIRES_IN: '5m', DEFAULT_TIMEZONE: 'GMT+0', }); expect(env.PORT).toBe(4000); expect(env.BCRYPT_SALT_ROUNDS).toBe(12); expect(env.REFRESH_TOKEN_EXPIRES_IN_MS).toBe(3_600_000); expect(env.JWT_ACCESS_EXPIRES_IN).toBe('5m'); expect(env.JWT_ACCESS_EXPIRES_IN_MS).toBe(5 * 60 * 1000); expect(env.DEFAULT_TIMEZONE).toBe('GMT+0'); }); it('rejects invalid JWT_ACCESS_EXPIRES_IN format', () => { expect(() => loadEnv({ ...valid, JWT_ACCESS_EXPIRES_IN: '900', }), ).toThrow('must match'); }); it('enables SKIP_GPS_VALIDATION outside production', () => { const env = loadEnv({ ...valid, SKIP_GPS_VALIDATION: 'true', NODE_ENV: 'development', }); expect(env.SKIP_GPS_VALIDATION).toBe(true); }); it('rejects SKIP_GPS_VALIDATION in production', () => { expect(() => loadEnv({ ...valid, SKIP_GPS_VALIDATION: 'true', NODE_ENV: 'production', }), ).toThrow('cannot be enabled in production'); }); it('rejects invalid SKIP_GPS_VALIDATION values', () => { expect(() => loadEnv({ ...valid, SKIP_GPS_VALIDATION: 'yes', }), ).toThrow('must be true or false'); }); });