121 lines
4.8 KiB
TypeScript
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();
|