feat: 2.0.0-alpha.11 — DB-backed service registry + LAN auto-discovery
- monitored_services table (mig 015) replaces config/services.json (now a boot seed) - owner CRUD over /api/health/services; GET is DB-backed; cron+worker read the DB - discover.lan worker: pure-Node TCP sweep + HTTP-title probe -> disabled 'discovered' candidates (never clobbers curated entries); POST /api/health/discover + GET .../discovered - dashboard: Scan button + Discovered(N) section with one-click promote Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
48
tests/repos/monitored_services.test.js
Normal file
48
tests/repos/monitored_services.test.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
|
||||
import { resetDb } from '../helpers/db.js';
|
||||
import { migrateUp } from '../../lib/db/migrate.js';
|
||||
import * as repo from '../../lib/db/repos/monitored_services.js';
|
||||
|
||||
beforeAll(async () => { await resetDb(); await migrateUp(); });
|
||||
beforeEach(async () => { await resetDb(); await migrateUp(); });
|
||||
|
||||
const gitea = { id: 'gitea', name: 'Gitea', category: 'infrastructure', host: 'ct105', url: 'http://192.168.1.223:3000', icon: 'gitea', check: { type: 'http' } };
|
||||
|
||||
describe('monitored_services repo', () => {
|
||||
it('creates and lists enabled with check_cfg mapped to check', async () => {
|
||||
await repo.create(gitea);
|
||||
const list = await repo.listEnabled();
|
||||
expect(list).toHaveLength(1);
|
||||
expect(list[0].id).toBe('gitea');
|
||||
expect(list[0].check).toEqual({ type: 'http' }); // check_cfg -> check
|
||||
expect(list[0].source).toBe('manual');
|
||||
});
|
||||
|
||||
it('update patches fields (incl. check + enabled)', async () => {
|
||||
await repo.create(gitea);
|
||||
await repo.update('gitea', { name: 'Gitea CE', enabled: false, check: { type: 'tcp' } });
|
||||
expect((await repo.get('gitea')).name).toBe('Gitea CE');
|
||||
expect(await repo.listEnabled()).toHaveLength(0); // now disabled
|
||||
expect((await repo.get('gitea')).check).toEqual({ type: 'tcp' });
|
||||
});
|
||||
|
||||
it('remove deletes', async () => {
|
||||
await repo.create(gitea);
|
||||
expect(await repo.remove('gitea')).toBe(true);
|
||||
expect(await repo.get('gitea')).toBeNull();
|
||||
});
|
||||
|
||||
it('upsertDiscovered adds a disabled candidate, but never clobbers an existing url/id', async () => {
|
||||
await repo.create(gitea); // manual, enabled
|
||||
// same url -> skipped
|
||||
expect(await repo.upsertDiscovered({ id: 'gitea-x', name: 'g', url: gitea.url })).toBeNull();
|
||||
// new url -> inserted, disabled, source=discovered
|
||||
const d = await repo.upsertDiscovered({ id: 'plex', name: 'Plex?', url: 'http://192.168.1.230:32400' });
|
||||
expect(d.source).toBe('discovered');
|
||||
expect(d.enabled).toBe(false);
|
||||
expect(await repo.listEnabled()).toHaveLength(1); // only gitea
|
||||
expect(await repo.listDiscovered()).toHaveLength(1); // plex candidate
|
||||
// re-running discovery is idempotent (same id -> skipped)
|
||||
expect(await repo.upsertDiscovered({ id: 'plex', name: 'Plex?', url: 'http://192.168.1.230:32400' })).toBeNull();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user