Files
dockhand-upstream/tests/caddy-urls.test.ts
T

109 lines
3.6 KiB
TypeScript

import { describe, test, expect } from 'bun:test';
import { extractCaddyUrls } from '../src/lib/utils/caddy-urls';
describe('extractCaddyUrls', () => {
test('returns empty for no labels / null / undefined / empty', () => {
expect(extractCaddyUrls(null)).toEqual([]);
expect(extractCaddyUrls(undefined)).toEqual([]);
expect(extractCaddyUrls({})).toEqual([]);
});
test('ignores containers with no caddy labels', () => {
expect(extractCaddyUrls({ 'com.docker.compose.project': 'foo' })).toEqual([]);
});
test('bare caddy address defaults to https (Caddy auto-HTTPS)', () => {
expect(extractCaddyUrls({ caddy: 'whoami.example.com' })).toEqual([
{ url: 'https://whoami.example.com', group: 'caddy' }
]);
});
test('directive labels are ignored - only the bare site key is an address', () => {
const out = extractCaddyUrls({
caddy: 'app.example.com',
'caddy.reverse_proxy': '{{upstreams 3001}}',
'caddy.tls': 'internal'
});
expect(out).toEqual([{ url: 'https://app.example.com', group: 'caddy' }]);
});
test('caddy_N groups each yield their own URL (containers behind vpn)', () => {
const out = extractCaddyUrls({
caddy_0: 'prefix2.example.com',
'caddy_0.reverse_proxy': '{{upstreams 8080}}',
caddy_1: 'prefix3.example.com',
'caddy_1.reverse_proxy': '{{upstreams 5055}}'
});
expect(out).toEqual([
{ url: 'https://prefix2.example.com', group: 'caddy_0' },
{ url: 'https://prefix3.example.com', group: 'caddy_1' }
]);
});
test('comma-separated addresses in one value yield multiple URLs', () => {
const out = extractCaddyUrls({ caddy: 'example.com, example.org, www.example.com' });
expect(out.map((u) => u.url)).toEqual([
'https://example.com',
'https://example.org',
'https://www.example.com'
]);
});
test('explicit http:// scheme is preserved', () => {
expect(extractCaddyUrls({ caddy: 'http://insecure.example.com' })).toEqual([
{ url: 'http://insecure.example.com', group: 'caddy' }
]);
});
test('explicit https:// scheme is preserved', () => {
expect(extractCaddyUrls({ caddy: 'https://app.example.com' })[0].url).toBe(
'https://app.example.com'
);
});
test(':80 port implies http and is stripped', () => {
expect(extractCaddyUrls({ caddy: 'plain.example.com:80' })[0].url).toBe(
'http://plain.example.com'
);
});
test(':443 port stays https and is stripped', () => {
expect(extractCaddyUrls({ caddy: 'secure.example.com:443' })[0].url).toBe(
'https://secure.example.com'
);
});
test('a custom port keeps https and is preserved', () => {
expect(extractCaddyUrls({ caddy: 'app.example.com:8443' })[0].url).toBe(
'https://app.example.com:8443'
);
});
test('a path matcher is appended, trailing wildcard stripped', () => {
expect(extractCaddyUrls({ caddy: 'example.com/api/*' })[0].url).toBe(
'https://example.com/api'
);
});
test('snippet / named-matcher definitions are not addresses', () => {
const out = extractCaddyUrls({
caddy_0: '(snippet)',
'caddy_0.tls': 'internal',
caddy_1: 'site-a.com',
'caddy_1.import': 'snippet'
});
expect(out).toEqual([{ url: 'https://site-a.com', group: 'caddy_1' }]);
});
test('port-only / wildcard placeholders are skipped', () => {
expect(extractCaddyUrls({ caddy: ':8080' })).toEqual([]);
expect(extractCaddyUrls({ caddy: '*' })).toEqual([]);
expect(extractCaddyUrls({ caddy: ':443' })).toEqual([]);
});
test('duplicate addresses across keys are deduped', () => {
const out = extractCaddyUrls({ caddy_0: 'dup.example.com', caddy_1: 'dup.example.com' });
expect(out).toEqual([{ url: 'https://dup.example.com', group: 'caddy_0' }]);
});
});