Files
dashcaddy/dashcaddy-api/__tests__/url-resolver.test.js
T
Hermes 7bc2a207f3 DC-005: Fix all 138 broken test paths after src/ refactor
After the DC-005 module reorganization (41 files moved into src/ subdirs),
138 test suites failed because the refactor script's path-rewrite logic
missed three categories:

1. Files inside src/ doing 'require("./src/...")' — should be 'require("../...")'
2. Files in src/X/Y/ doing 'require("../../../src/...")' — should be 'require("../../...")'
3. Test files in __tests__/ with leftover 'require("../../../src/...")' paths

Root cause: the original refactor script ran before all files were moved,
so it computed relative paths against stale filesystem state.

Result:
- 30/30 test suites pass
- 879/879 tests pass (was: 18/30 suites, 614/687 tests)

Also fixed:
- routes/apps/restore.js: wrong responses import path
- routes/*/*.js: '../../src/utilities/X' → '../src/utilities/X' (depth 2 routes)
2026-06-13 12:16:56 -07:00

123 lines
4.5 KiB
JavaScript

const { resolveServiceUrl } = require('../src/utilities/url-resolver');
describe('URL Resolver — DashCaddy service URL resolution', () => {
const buildServiceUrl = jest.fn(id => `https://${id}.sami`);
beforeEach(() => {
buildServiceUrl.mockClear();
});
describe('Internet connectivity check', () => {
it('always resolves "internet" to google.com regardless of config', () => {
expect(resolveServiceUrl('internet', null, null, buildServiceUrl))
.toBe('https://www.google.com');
expect(buildServiceUrl).not.toHaveBeenCalled();
});
it('ignores service object for internet ID', () => {
const service = { url: 'http://custom.test', isExternal: true, externalUrl: 'http://ext.test' };
expect(resolveServiceUrl('internet', service, {}, buildServiceUrl))
.toBe('https://www.google.com');
});
});
describe('External services (seedhost, cloud-hosted)', () => {
it('uses externalUrl for services marked isExternal', () => {
const service = { isExternal: true, externalUrl: 'https://usw123.seedhost.eu/sami/radarr' };
expect(resolveServiceUrl('radarr', service, {}, buildServiceUrl))
.toBe('https://usw123.seedhost.eu/sami/radarr');
});
it('ignores isExternal if externalUrl is missing', () => {
const service = { isExternal: true };
expect(resolveServiceUrl('plex', service, {}, buildServiceUrl))
.toBe('https://plex.sami');
});
});
describe('Custom URL override on service', () => {
it('uses service.url with http prefix as-is', () => {
const service = { url: 'http://192.168.1.100:32400' };
expect(resolveServiceUrl('plex', service, {}, buildServiceUrl))
.toBe('http://192.168.1.100:32400');
});
it('uses service.url with https prefix as-is', () => {
const service = { url: 'https://plex.mydomain.com' };
expect(resolveServiceUrl('plex', service, {}, buildServiceUrl))
.toBe('https://plex.mydomain.com');
});
it('prepends https:// to bare hostnames', () => {
const service = { url: 'plex.sami' };
expect(resolveServiceUrl('plex', service, {}, buildServiceUrl))
.toBe('https://plex.sami');
});
});
describe('DNS server resolution (Technitium, Pi-hole)', () => {
it('resolves DNS server by ID from siteConfig', () => {
const siteConfig = {
dnsServers: {
dns1: { ip: '192.168.254.204', port: 5380 },
dns2: { ip: '100.74.102.61', port: 5380 },
}
};
expect(resolveServiceUrl('dns1', null, siteConfig, buildServiceUrl))
.toBe('http://192.168.254.204:5380');
expect(resolveServiceUrl('dns2', null, siteConfig, buildServiceUrl))
.toBe('http://100.74.102.61:5380');
});
it('defaults to port 5380 when port is omitted', () => {
const siteConfig = { dnsServers: { dns1: { ip: '10.0.0.1' } } };
expect(resolveServiceUrl('dns1', null, siteConfig, buildServiceUrl))
.toBe('http://10.0.0.1:5380');
});
});
describe('Fallback to buildServiceUrl (Caddy subdomain/subdirectory)', () => {
it('falls back for local services with no special config', () => {
resolveServiceUrl('radarr', { name: 'Radarr' }, {}, buildServiceUrl);
expect(buildServiceUrl).toHaveBeenCalledWith('radarr');
});
it('works when service is null (top-card items)', () => {
expect(resolveServiceUrl('sonarr', null, {}, buildServiceUrl))
.toBe('https://sonarr.sami');
});
it('works when siteConfig is null', () => {
expect(resolveServiceUrl('jellyfin', null, null, buildServiceUrl))
.toBe('https://jellyfin.sami');
});
});
describe('Priority chain — higher priority wins', () => {
const fullService = {
isExternal: true,
externalUrl: 'https://external.test',
url: 'http://custom.test',
};
const siteConfig = {
dnsServers: { myservice: { ip: '10.0.0.1', port: 5380 } }
};
it('externalUrl wins over service.url and DNS', () => {
expect(resolveServiceUrl('myservice', fullService, siteConfig, buildServiceUrl))
.toBe('https://external.test');
});
it('service.url wins over DNS and fallback', () => {
const service = { url: 'http://custom.test' };
expect(resolveServiceUrl('myservice', service, siteConfig, buildServiceUrl))
.toBe('http://custom.test');
});
it('DNS wins over fallback', () => {
expect(resolveServiceUrl('myservice', null, siteConfig, buildServiceUrl))
.toBe('http://10.0.0.1:5380');
});
});
});