/** * Sites Route Tests * * Tests Caddyfile management, site configuration, and external site endpoints */ const request = require('supertest'); const fs = require('fs'); const path = require('path'); const os = require('os'); const testServicesFile = path.join(os.tmpdir(), `sites-services-${Date.now()}.json`); const testConfigFile = path.join(os.tmpdir(), `sites-config-${Date.now()}.json`); const testCaddyfile = path.join(os.tmpdir(), `sites-Caddyfile-${Date.now()}`); process.env.SERVICES_FILE = testServicesFile; process.env.CONFIG_FILE = testConfigFile; process.env.CADDYFILE_PATH = testCaddyfile; process.env.ENABLE_HEALTH_CHECKER = 'false'; process.env.NODE_ENV = 'test'; fs.writeFileSync(testServicesFile, '[]', 'utf8'); fs.writeFileSync(testConfigFile, '{}', 'utf8'); fs.writeFileSync(testCaddyfile, '# Test Caddyfile', 'utf8'); const app = require('../server'); describe('Sites Routes', () => { afterAll(() => { for (const f of [testServicesFile, testConfigFile, testCaddyfile]) { try { fs.unlinkSync(f); } catch (e) { /* ignore */ } } }); describe('GET /api/caddyfile', () => { test('should return Caddyfile contents', async () => { const res = await request(app).get('/api/caddyfile'); expect(res.statusCode).toBe(200); expect(res.body.success).toBe(true); expect(res.body.content).toContain('Test Caddyfile'); }); }); describe('GET /api/apps/templates', () => { test('should return all templates with categories', async () => { const res = await request(app).get('/api/apps/templates'); expect(res.statusCode).toBe(200); expect(res.body).toHaveProperty('templates'); expect(res.body).toHaveProperty('categories'); expect(Object.keys(res.body.templates).length).toBeGreaterThan(50); }); }); describe('GET /api/apps/templates/:appId', () => { test('should return specific template', async () => { const res = await request(app).get('/api/apps/templates/plex'); expect(res.statusCode).toBe(200); expect(res.body.success).toBe(true); expect(res.body.template.name).toBe('Plex'); expect(res.body.template.docker).toBeDefined(); }); test('should return 404 for unknown template', async () => { const res = await request(app).get('/api/apps/templates/nonexistent'); expect(res.statusCode).toBe(404); }); }); describe('POST /api/site/external', () => { test('should reject missing required fields', async () => { const res = await request(app) .post('/api/site/external') .send({}); expect(res.statusCode).toBe(400); }); test('should reject invalid subdomain', async () => { const res = await request(app) .post('/api/site/external') .send({ subdomain: 'INVALID SUBDOMAIN!', targetUrl: 'https://example.com', name: 'Test', }); expect(res.statusCode).toBe(400); }); }); describe('GET /api/caddy/cas', () => { test('should return CA list from Caddyfile', async () => { const res = await request(app).get('/api/caddy/cas'); expect(res.statusCode).toBe(200); expect(res.body.status).toBe('success'); expect(Array.isArray(res.body.data.cas)).toBe(true); }); }); });