import { describe, it, expect, beforeAll, beforeEach, afterEach, vi } from 'vitest'; import { resetDb } from '../helpers/db.js'; import { migrateUp } from '../../lib/db/migrate.js'; import * as worker from '../../lib/jobs/workers/discover.js'; import * as services from '../../lib/db/repos/monitored_services.js'; beforeAll(async () => { await resetDb(); await migrateUp(); }); beforeEach(async () => { await resetDb(); await migrateUp(); }); afterEach(() => worker._setProbes()); // restore real probes describe('discover.lan worker', () => { it('upserts disabled discovered candidates for live HTTP host:ports', async () => { // Fake: only .50:3000 and .60:8096 are "open". const tcp = vi.fn(async (host, port) => (host === '192.168.1.50' && port === 3000) || (host === '192.168.1.60' && port === 8096)); const http = vi.fn(async (url) => ({ code: 200, title: url.includes('8096') ? 'Jellyfin' : 'Gitea' })); worker._setProbes({ tcp, http }); const out = await worker.handler({ data: { subnet: '192.168.1' } }); expect(out.open).toBe(2); expect(out.added).toBe(2); const disc = await services.listDiscovered(); expect(disc.map(s => s.name).sort()).toEqual(['Gitea', 'Jellyfin']); expect(disc.every(s => s.source === 'discovered' && s.enabled === false)).toBe(true); expect(await services.listEnabled()).toHaveLength(0); // candidates don't auto-join the band }); it('does not re-add a service whose url already exists (manual wins, idempotent)', async () => { await services.create({ id: 'plex', name: 'Plex', category: 'media', url: 'http://192.168.1.50:32400', check: { type: 'http' } }); const tcp = vi.fn(async (host, port) => host === '192.168.1.50' && port === 32400); const http = vi.fn(async () => ({ code: 200, title: 'Plex' })); worker._setProbes({ tcp, http }); const out = await worker.handler({ data: { subnet: '192.168.1' } }); expect(out.open).toBe(1); expect(out.added).toBe(0); // url already known → skipped expect(await services.listDiscovered()).toHaveLength(0); }); });