'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const { EventEmitter } = require('node:events'); const { altaKeyFromName, cameraFromService, isLocalAddress, normalizeResults, scanCameras, } = require('../src/discovery'); const validService = (overrides = {}) => ({ name: 'ABH7-C62U-GC3E', type: 'vaioncam', protocol: 'tcp', host: 'avacam-abh7-c62u-gc3e.local.', addresses: ['fe80::1', '10.0.0.223'], port: 443, ...overrides, }); test('extracts an Alta Key from service names', () => { assert.equal(altaKeyFromName('abh7-c62u-gc3e'), 'ABH7-C62U-GC3E'); assert.equal(altaKeyFromName('ABH7-C62U-GC3E._vaioncam._tcp.local'), 'ABH7-C62U-GC3E'); assert.equal(altaKeyFromName('not-a-key'), null); }); test('projects a correlated local Bonjour service into a safe camera row', () => { assert.deepEqual(cameraFromService(validService()), { alta_key: 'ABH7-C62U-GC3E', hostname: 'avacam-abh7-c62u-gc3e.local', web_ui_url: 'https://avacam-abh7-c62u-gc3e.local', ip_address: '10.0.0.223', port: 443, service: '_vaioncam._tcp.local', }); }); test('rejects uncorrelated or non-local service announcements', () => { assert.equal(cameraFromService(validService({ type: undefined })), null); assert.equal(cameraFromService(validService({ protocol: undefined })), null); assert.equal(cameraFromService(validService({ host: 'avacam-attacker.local.' })), null); assert.equal(cameraFromService(validService({ port: 8443 })), null); assert.equal(cameraFromService(validService({ addresses: ['203.0.113.10'] })), null); assert.equal(cameraFromService(validService({ addresses: [] })), null); }); test('recognizes supported private and link-local IP scopes', () => { for (const address of ['10.0.0.1', '172.16.0.1', '172.31.255.254', '192.168.1.1', '169.254.1.1', 'fe80::1', 'fc00::1', 'fd12::1']) { assert.equal(isLocalAddress(address), true, address); } for (const address of ['8.8.8.8', '172.32.0.1', '2001:4860:4860::8888', 'not-an-ip']) { assert.equal(isLocalAddress(address), false, address); } }); test('deduplicates and sorts cameras', () => { const a = { alta_key: 'AHG2-Z4ND-FVRN', ip_address: '10.0.0.192' }; const b = { alta_key: 'ABH7-C62U-GC3E', ip_address: '10.0.0.223' }; assert.deepEqual(normalizeResults([a, b, a]), [b, a]); }); test('scans through the Bonjour adapter and closes resources', async () => { let browserStopped = false; let bonjourDestroyed = false; class FakeBonjour { find(query) { assert.deepEqual(query, { type: 'vaioncam', protocol: 'tcp' }); const browser = new EventEmitter(); browser.stop = () => { browserStopped = true; }; process.nextTick(() => browser.emit('up', validService())); return browser; } destroy() { bonjourDestroyed = true; } } const rows = await scanCameras({ durationMs: 5, BonjourClass: FakeBonjour }); assert.equal(rows.length, 1); assert.equal(rows[0].alta_key, 'ABH7-C62U-GC3E'); assert.equal(browserStopped, true); assert.equal(bonjourDestroyed, true); }); test('caps scan results and closes discovery immediately at the cap', async () => { let browserStopped = false; class FakeBonjour { find() { const browser = new EventEmitter(); browser.stop = () => { browserStopped = true; }; process.nextTick(() => { for (let index = 0; index < 10; index += 1) { const key = `AAAA-BBBB-${String(index).padStart(4, '0')}`; browser.emit('up', validService({ name: key, host: `avacam-${key.toLowerCase()}.local.`, addresses: [`10.0.0.${index + 1}`], })); } }); return browser; } destroy() {} } const rows = await scanCameras({ durationMs: 1000, maxResults: 3, BonjourClass: FakeBonjour }); assert.equal(rows.length, 3); assert.equal(browserStopped, true); });