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 }); it('persists and returns external on create/get/update', async () => { const id = 'ext-test'; await services.create({ id, name: 'Ext', url: 'http://10.0.0.1', external: 'https://ext.example.com' }); expect((await services.get(id)).external).toBe('https://ext.example.com'); const upd = await services.update(id, { external: 'https://ext2.example.com' }); expect(upd.external).toBe('https://ext2.example.com'); }); });