import { expect, tap } from '@git.zone/tstest/tapbundle'; import { PiHoleConfigFlow, PiHoleHttpMatcher, PiHoleManualMatcher, PiHoleCandidateValidator } from '../../ts/integrations/pi_hole/index.js'; tap.test('recognizes Pi-hole HTTP and manual discovery candidates', async () => { const httpMatch = await new PiHoleHttpMatcher().matches({ url: 'http://192.168.1.2/admin/api.php?summaryRaw', headers: { server: 'lighttpd' }, }); const manualMatch = await new PiHoleManualMatcher().matches({ host: 'pihole.local', name: 'Pi-hole', }); const validation = await new PiHoleCandidateValidator().validate(httpMatch.candidate!); expect(httpMatch.matched).toBeTrue(); expect(httpMatch.candidate?.integrationDomain).toEqual('pi_hole'); expect(httpMatch.candidate?.metadata?.apiVersion).toEqual(5); expect(httpMatch.candidate?.metadata?.location).toEqual('admin'); expect(manualMatch.matched).toBeTrue(); expect(manualMatch.candidate?.port).toEqual(80); expect(validation.matched).toBeTrue(); }); tap.test('config flow parses Pi-hole URL and validates credentials shape', async () => { const step = await new PiHoleConfigFlow().start({ source: 'manual', name: 'Pi-hole' }, {}); const missingKey = await step.submit!({ host: 'http://192.168.1.2:8080/admin/api.php' }); const done = await step.submit!({ host: 'http://192.168.1.2:8080/admin/api.php', apiKey: 'secret', apiVersion: '5', verifySsl: false, }); expect(missingKey.kind).toEqual('error'); expect(done.kind).toEqual('done'); expect(done.config?.host).toEqual('192.168.1.2'); expect(done.config?.port).toEqual(8080); expect(done.config?.location).toEqual('admin'); expect(done.config?.apiVersion).toEqual(5); expect(done.config?.apiKey).toEqual('secret'); }); export default tap.start();