Files
integrations/test/pi_hole/test.pi_hole.mapper.node.ts
T

121 lines
4.8 KiB
TypeScript

import { expect, tap } from '@git.zone/tstest/tapbundle';
import { PiHoleMapper, type IPiHoleSnapshot } from '../../ts/integrations/pi_hole/index.js';
const v5Snapshot: IPiHoleSnapshot = PiHoleMapper.toSnapshot({
config: {
host: '192.168.1.2',
port: 80,
name: 'Home DNS',
apiVersion: 5,
rawData: {
v5Summary: {
status: 'enabled',
ads_blocked_today: 42,
ads_percentage_today: 21.55,
clients_ever_seen: 8,
dns_queries_today: 200,
domains_being_blocked: 150000,
queries_cached: 50,
queries_forwarded: 120,
unique_clients: 5,
unique_domains: 90,
},
v5Versions: {
core_current: 'v5.18.3',
core_latest: 'v5.18.4',
core_update: true,
web_current: 'v5.21',
web_latest: 'v5.21',
web_update: false,
FTL_current: 'v5.25.2',
FTL_latest: 'v5.25.2',
FTL_update: false,
},
},
},
online: true,
source: 'manual',
});
tap.test('maps Pi-hole v5 status, statistics, updates, and switch control', async () => {
const devices = PiHoleMapper.toDevices(v5Snapshot);
const entities = PiHoleMapper.toEntities(v5Snapshot);
expect(devices[0].id).toEqual('pi_hole.service.192_168_1_2_80');
expect(devices[0].online).toBeTrue();
expect(entities.find((entityArg) => entityArg.id === 'switch.home_dns')?.state).toEqual('on');
expect(entities.find((entityArg) => entityArg.id === 'binary_sensor.home_dns_status')?.state).toEqual('on');
expect(entities.find((entityArg) => entityArg.id === 'sensor.home_dns_ads_blocked_today')?.state).toEqual(42);
expect(entities.find((entityArg) => entityArg.id === 'sensor.home_dns_ads_percentage_blocked_today')?.state).toEqual(21.6);
expect(entities.find((entityArg) => entityArg.id === 'sensor.home_dns_dns_queries_today')?.state).toEqual(200);
expect(entities.find((entityArg) => entityArg.id === 'update.home_dns_core_update_available')?.attributes?.latestVersion).toEqual('v5.18.4');
});
tap.test('models Pi-hole enable, disable, and refresh commands without secrets', async () => {
const disableCommand = PiHoleMapper.commandForService(v5Snapshot, {
domain: 'switch',
service: 'turn_off',
target: { entityId: 'switch.home_dns' },
data: { duration: '00:10:00' },
});
const enableCommand = PiHoleMapper.commandForService(v5Snapshot, {
domain: 'pi_hole',
service: 'enable',
target: { deviceId: 'pi_hole.service.192_168_1_2_80' },
});
const refreshCommand = PiHoleMapper.commandForService(v5Snapshot, {
domain: 'pi_hole',
service: 'refresh',
target: {},
});
expect(Boolean(disableCommand && !('error' in disableCommand))).toBeTrue();
if (disableCommand && !('error' in disableCommand)) {
expect(disableCommand.type).toEqual('disable');
expect(disableCommand.path).toEqual('/admin/api.php');
expect(disableCommand.query).toEqual({ disable: 600 });
expect(JSON.stringify(disableCommand).includes('auth')).toBeFalse();
}
expect(Boolean(enableCommand && !('error' in enableCommand))).toBeTrue();
if (enableCommand && !('error' in enableCommand)) {
expect(enableCommand.query).toEqual({ enable: 'True' });
}
expect(refreshCommand && !('error' in refreshCommand) ? refreshCommand.type : undefined).toEqual('refresh');
});
tap.test('maps Pi-hole v6 nested summary and version payloads', async () => {
const snapshot = PiHoleMapper.toSnapshot({
config: {
host: 'pihole.local',
name: 'Family DNS',
apiVersion: 6,
rawData: {
v6Blocking: { blocking: 'disabled' },
v6Summary: {
queries: { blocked: 12, percent_blocked: 24.123, total: 50, cached: 8, forwarded: 30, unique_domains: 40 },
clients: { total: 6, active: 3 },
gravity: { domains_being_blocked: 180000 },
},
v6Versions: {
version: {
core: { local: { version: 'v6.0', hash: 'a' }, remote: { version: 'v6.1', hash: 'b' } },
web: { local: { version: 'v6.0', hash: 'c' }, remote: { version: 'v6.0', hash: 'c' } },
ftl: { local: { version: 'v6.0', hash: 'd' }, remote: { version: 'v6.0', hash: 'd' } },
},
},
},
},
online: true,
source: 'manual',
});
const entities = PiHoleMapper.toEntities(snapshot);
expect(entities.find((entityArg) => entityArg.id === 'switch.family_dns')?.state).toEqual('off');
expect(entities.find((entityArg) => entityArg.id === 'sensor.family_dns_ads_blocked')?.state).toEqual(12);
expect(entities.find((entityArg) => entityArg.id === 'sensor.family_dns_ads_percentage_blocked')?.state).toEqual(24.12);
expect(entities.find((entityArg) => entityArg.id === 'sensor.family_dns_dns_queries')?.state).toEqual(50);
expect(entities.find((entityArg) => entityArg.id === 'update.family_dns_core_update_available')?.state).toEqual('on');
});
export default tap.start();