98 lines
3.6 KiB
JavaScript
98 lines
3.6 KiB
JavaScript
import { describe, expect, it, vi } from 'vitest';
|
|||
|
|
import { isValidOpenCodeHostname, resolveOpenCodeEnvConfig } from './env-config.js';
|
||
|
|
|
||
|
|
describe('isValidOpenCodeHostname', () => {
|
||
|
|
it('accepts IPv4 addresses', () => {
|
||
|
|
expect(isValidOpenCodeHostname('127.0.0.1')).toBe(true);
|
||
|
|
expect(isValidOpenCodeHostname('0.0.0.0')).toBe(true);
|
||
|
|
expect(isValidOpenCodeHostname('192.168.1.10')).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('accepts IPv6 addresses with and without brackets', () => {
|
||
|
|
expect(isValidOpenCodeHostname('::1')).toBe(true);
|
||
|
|
expect(isValidOpenCodeHostname('[::1]')).toBe(true);
|
||
|
|
expect(isValidOpenCodeHostname('::')).toBe(true);
|
||
|
|
expect(isValidOpenCodeHostname('[::]')).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('accepts DNS-style hostnames', () => {
|
||
|
|
expect(isValidOpenCodeHostname('localhost')).toBe(true);
|
||
|
|
expect(isValidOpenCodeHostname('tailscale-host')).toBe(true);
|
||
|
|
expect(isValidOpenCodeHostname('my.host.example')).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects malformed values', () => {
|
||
|
|
const invalid = [
|
||
|
|
'',
|
||
|
|
' ',
|
||
|
|
'http://localhost',
|
||
|
|
'https://host:4096',
|
||
|
|
'host:4096',
|
||
|
|
'host/path',
|
||
|
|
'bad host',
|
||
|
|
'bad_host',
|
||
|
|
'0.0.0.0.0',
|
||
|
|
'999.999.999.999',
|
||
|
|
'[::1',
|
||
|
|
'::1]',
|
||
|
|
'a'.repeat(254),
|
||
|
|
'1.2.3.4.5.6.7.8.9',
|
||
|
|
];
|
||
|
|
for (const value of invalid) {
|
||
|
|
expect(isValidOpenCodeHostname(value), JSON.stringify(value)).toBe(false);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects non-string values', () => {
|
||
|
|
expect(isValidOpenCodeHostname(undefined)).toBe(false);
|
||
|
|
expect(isValidOpenCodeHostname(null)).toBe(false);
|
||
|
|
expect(isValidOpenCodeHostname(42)).toBe(false);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('resolveOpenCodeEnvConfig hostname', () => {
|
||
|
|
it('defaults to loopback when the env var is absent', () => {
|
||
|
|
expect(resolveOpenCodeEnvConfig({ env: {} }).configuredOpenCodeHostname).toBe('127.0.0.1');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('reads OPENCHAMBER_OPENCODE_HOSTNAME', () => {
|
||
|
|
const result = resolveOpenCodeEnvConfig({ env: { OPENCHAMBER_OPENCODE_HOSTNAME: '0.0.0.0' } });
|
||
|
|
expect(result.configuredOpenCodeHostname).toBe('0.0.0.0');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('trims surrounding whitespace', () => {
|
||
|
|
const result = resolveOpenCodeEnvConfig({ env: { OPENCHAMBER_OPENCODE_HOSTNAME: ' tailscale-host ' } });
|
||
|
|
expect(result.configuredOpenCodeHostname).toBe('tailscale-host');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('warns and falls back for an empty value', () => {
|
||
|
|
const logger = { warn: vi.fn(), error: vi.fn() };
|
||
|
|
const result = resolveOpenCodeEnvConfig({ env: { OPENCHAMBER_OPENCODE_HOSTNAME: ' ' }, logger });
|
||
|
|
expect(result.configuredOpenCodeHostname).toBe('127.0.0.1');
|
||
|
|
expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('empty after trimming'));
|
||
|
|
expect(logger.error).not.toHaveBeenCalled();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects invalid values with a clear error and falls back to loopback', () => {
|
||
|
|
const logger = { warn: vi.fn(), error: vi.fn() };
|
||
|
|
const result = resolveOpenCodeEnvConfig({
|
||
|
|
env: { OPENCHAMBER_OPENCODE_HOSTNAME: 'http://nope:4096' },
|
||
|
|
logger,
|
||
|
|
});
|
||
|
|
expect(result.configuredOpenCodeHostname).toBe('127.0.0.1');
|
||
|
|
expect(logger.error).toHaveBeenCalledWith(
|
||
|
|
expect.stringContaining('Rejecting OPENCHAMBER_OPENCODE_HOSTNAME'),
|
||
|
|
);
|
||
|
|
expect(logger.error).toHaveBeenCalledWith(expect.stringContaining('127.0.0.1'));
|
||
|
|
});
|
||
|
|
|
||
|
|
it('keeps other env config intact when the hostname is validated', () => {
|
||
|
|
const result = resolveOpenCodeEnvConfig({
|
||
|
|
env: { OPENCHAMBER_OPENCODE_HOSTNAME: '0.0.0.0', OPENCODE_PORT: '4096' },
|
||
|
|
});
|
||
|
|
expect(result.configuredOpenCodeHostname).toBe('0.0.0.0');
|
||
|
|
expect(result.configuredOpenCodePort).toBe(4096);
|
||
|
|
expect(result.effectivePort).toBe(4096);
|
||
|
|
});
|
||
|
|
});
|