68 lines
4.1 KiB
JavaScript
68 lines
4.1 KiB
JavaScript
import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
|
|
import request from 'supertest';
|
|
import { setup } from './helpers.js';
|
|
import { resetDb } from '../helpers/db.js';
|
|
import { migrateUp } from '../../lib/db/migrate.js';
|
|
import * as statusRepo from '../../lib/db/repos/service_status.js';
|
|
import * as services from '../../lib/db/repos/monitored_services.js';
|
|
|
|
let app, ownerHeaders;
|
|
beforeAll(async () => { ({ app, ownerHeaders } = await setup()); });
|
|
beforeEach(async () => {
|
|
await resetDb(); await migrateUp();
|
|
await services.create({ id: 'gitea', name: 'Gitea', category: 'infrastructure', host: 'ct105', url: 'http://192.168.1.223:3000', icon: 'gitea', check: { type: 'http' } });
|
|
await statusRepo.upsert({ service_id: 'gitea', status: 'ok', latency_ms: 10, detail: '200' });
|
|
});
|
|
|
|
describe('health api (DB-backed registry)', () => {
|
|
it('401 without auth', async () => expect((await request(app).get('/api/health/services')).status).toBe(401));
|
|
it('POST /check rejects anonymous', async () => expect((await request(app).post('/api/health/check')).status).toBe(401));
|
|
it('POST /discover rejects anonymous', async () => expect((await request(app).post('/api/health/discover')).status).toBe(401));
|
|
it('POST /services rejects anonymous', async () => expect((await request(app).post('/api/health/services')).status).toBe(401));
|
|
|
|
it('GET /services returns grouped counts + merged status', async () => {
|
|
const res = await request(app).get('/api/health/services').set(ownerHeaders);
|
|
expect(res.status).toBe(200);
|
|
const infra = res.body.find(g => g.category === 'infrastructure');
|
|
expect(infra.healthy).toBe(1);
|
|
expect(infra.services.find(s => s.id === 'gitea').status).toBe('ok');
|
|
});
|
|
|
|
it('GET /services includes external on every tile; POST round-trips it', async () => {
|
|
const res = await request(app).get('/api/health/services').set(ownerHeaders);
|
|
const all = res.body.flatMap(g => g.services);
|
|
expect(all.every(s => 'external' in s)).toBe(true); // key present (may be null)
|
|
expect(all.find(s => s.id === 'gitea').external).toBeNull(); // no domain set
|
|
await request(app).post('/api/health/services').set(ownerHeaders)
|
|
.send({ id: 'gramps', name: 'Gramps', category: 'infrastructure', url: 'http://192.168.1.99', external: 'https://gramps.hynesy.com' });
|
|
const res2 = await request(app).get('/api/health/services').set(ownerHeaders);
|
|
const gramps = res2.body.flatMap(g => g.services).find(s => s.id === 'gramps');
|
|
expect(gramps.external).toBe('https://gramps.hynesy.com');
|
|
});
|
|
|
|
it('POST /services adds a service that shows up in the band', async () => {
|
|
const create = await request(app).post('/api/health/services').set(ownerHeaders)
|
|
.send({ id: 'ollama', name: 'Ollama', category: 'agents', host: 'ct102', url: 'http://192.168.1.185:11434' });
|
|
expect(create.status).toBe(201);
|
|
const res = await request(app).get('/api/health/services').set(ownerHeaders);
|
|
expect(res.body.find(g => g.category === 'agents').services.some(s => s.id === 'ollama')).toBe(true);
|
|
});
|
|
|
|
it('PATCH disables a service (drops out of the band); DELETE removes it', async () => {
|
|
await request(app).patch('/api/health/services/gitea').set(ownerHeaders).send({ enabled: false });
|
|
let res = await request(app).get('/api/health/services').set(ownerHeaders);
|
|
expect(res.body.find(g => g.category === 'infrastructure')).toBeUndefined(); // no enabled infra now
|
|
const del = await request(app).delete('/api/health/services/gitea').set(ownerHeaders);
|
|
expect(del.status).toBe(204);
|
|
expect((await request(app).delete('/api/health/services/gitea').set(ownerHeaders)).status).toBe(404);
|
|
});
|
|
|
|
it('GET /services/discovered lists owner-only candidates', async () => {
|
|
await services.upsertDiscovered({ id: 'disc-x', name: 'Mystery', url: 'http://192.168.1.99:8000' });
|
|
expect((await request(app).get('/api/health/services/discovered')).status).toBe(401); // anon
|
|
const res = await request(app).get('/api/health/services/discovered').set(ownerHeaders);
|
|
expect(res.status).toBe(200);
|
|
expect(res.body.map(s => s.id)).toContain('disc-x');
|
|
});
|
|
});
|