- 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>
34 lines
1.6 KiB
JavaScript
34 lines
1.6 KiB
JavaScript
import { describe, it, expect, beforeAll, beforeEach } from 'vitest';
|
|
import { resetDb } from '../helpers/db.js';
|
|
import { migrateUp } from '../../lib/db/migrate.js';
|
|
import { grouped, iconSlug, CATEGORY_ORDER, seedFromConfig } from '../../lib/health/registry.js';
|
|
import * as services from '../../lib/db/repos/monitored_services.js';
|
|
|
|
beforeAll(async () => { await resetDb(); await migrateUp(); });
|
|
beforeEach(async () => { await resetDb(); await migrateUp(); });
|
|
|
|
describe('registry', () => {
|
|
it('iconSlug derives from icon or name', () => {
|
|
expect(iconSlug({ name: 'Open WebUI' })).toBe('open-webui');
|
|
expect(iconSlug({ name: 'Plex', icon: 'plex' })).toBe('plex');
|
|
});
|
|
|
|
it('grouped orders agents→infrastructure→media; unknown categories fold into "other" (last)', () => {
|
|
const g = grouped([{ category: 'media', name: 'a' }, { category: 'agents', name: 'b' }, { category: 'zzz', name: 'c' }]);
|
|
const cats = g.map(x => x.category);
|
|
expect(cats.indexOf('agents')).toBeLessThan(cats.indexOf('media'));
|
|
expect(cats[cats.length - 1]).toBe('other'); // 'zzz' normalized to 'other'
|
|
expect(g.find(x => x.category === 'other').services[0].name).toBe('c');
|
|
expect(CATEGORY_ORDER[0]).toBe('agents');
|
|
});
|
|
|
|
it('seedFromConfig populates the DB from config/services.json once (idempotent)', async () => {
|
|
const n = await seedFromConfig();
|
|
expect(n).toBeGreaterThan(0);
|
|
const after = await services.all();
|
|
expect(after.length).toBe(n);
|
|
expect(after.every(s => s.source === 'manual' && s.enabled)).toBe(true);
|
|
expect(await seedFromConfig()).toBe(0); // table not empty → no-op
|
|
});
|
|
});
|