const fs = require('fs'); const path = require('path'); const { spawnSync } = require('child_process'); const CaddyfileGenerator = require('./caddyfile-generator'); describe('cross-host SSO installer contract', () => { test('generated auth snippet exposes the public one-time exchange landing route', () => { const snippet = new CaddyfileGenerator()._authSnippet(3001); expect(snippet).toContain('@needsAuth not path /dashcaddy-sso'); expect(snippet).toContain('handle /dashcaddy-sso'); expect(snippet).toContain('rewrite * /api/v1/auth/sso-exchange'); expect(snippet).toContain('reverse_proxy localhost:3001'); }); test('shell installer emits the same exchange landing contract', () => { const installer = fs.readFileSync(path.join(__dirname, '..', '..', 'install.sh'), 'utf8'); expect(installer).toContain('@needsAuth not path /dashcaddy-sso'); expect(installer).toContain('handle /dashcaddy-sso'); expect(installer).toContain('rewrite * /api/v1/auth/sso-exchange'); }); test('Caddy parser accepts a complete service config using the generated snippet', () => { const available = spawnSync('caddy', ['version'], { encoding: 'utf8' }); if (available.status !== 0) return; const generator = new CaddyfileGenerator(); const config = `${generator._authSnippet(3001)}\nexample.test {\n import dashcaddy_auth plex\n respond "ok" 200\n}\n`; const result = spawnSync('caddy', ['validate', '--config', '-', '--adapter', 'caddyfile'], { input: config, encoding: 'utf8', }); expect(result.status).toBe(0); expect(`${result.stdout}\n${result.stderr}`).toContain('Valid configuration'); }); });