139 lines
5.0 KiB
TypeScript
139 lines
5.0 KiB
TypeScript
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
import { FritzMapper, type IFritzSnapshot } from '../../ts/integrations/fritz/index.js';
|
|
|
|
const snapshot: IFritzSnapshot = {
|
|
connected: true,
|
|
updatedAt: '2026-01-01T00:00:00.000Z',
|
|
router: {
|
|
host: '192.168.178.1',
|
|
port: 49000,
|
|
ssl: false,
|
|
name: 'Home Fritz',
|
|
model: 'FRITZ!Box 7590',
|
|
serialNumber: 'AABBCCDDEEFF',
|
|
macAddress: 'AA:BB:CC:DD:EE:FF',
|
|
firmware: '8.02',
|
|
latestFirmware: '8.03',
|
|
updateAvailable: true,
|
|
actions: ['reboot', 'reconnect', 'firmware_update'],
|
|
},
|
|
devices: [
|
|
{
|
|
mac: '11:22:33:44:55:66',
|
|
name: 'Kitchen Phone',
|
|
ipAddress: '192.168.178.45',
|
|
connected: true,
|
|
connectedTo: 'Repeater',
|
|
connectionType: 'LAN',
|
|
ssid: 'Home WiFi',
|
|
wanAccess: true,
|
|
},
|
|
],
|
|
interfaces: [
|
|
{
|
|
name: 'wan',
|
|
label: 'WAN',
|
|
connected: true,
|
|
rxBytes: 2_000_000_000,
|
|
txBytes: 1_000_000_000,
|
|
rxRateKbps: 125.5,
|
|
txRateKbps: 42.5,
|
|
},
|
|
],
|
|
connection: {
|
|
connection: 'dsl',
|
|
wanEnabled: true,
|
|
ipv6Active: true,
|
|
isConnected: true,
|
|
isLinked: true,
|
|
externalIp: '203.0.113.10',
|
|
externalIpv6: '2001:db8::1',
|
|
transmissionRate: [42_500, 125_500],
|
|
maxBitRate: [50_000_000, 250_000_000],
|
|
maxLinkedBitRate: [60_000_000, 300_000_000],
|
|
noiseMargin: [80, 90],
|
|
attenuation: [120, 130],
|
|
bytesSent: 1_000_000_000,
|
|
bytesReceived: 2_000_000_000,
|
|
cpuTemperature: 56,
|
|
},
|
|
sensors: {},
|
|
wifiNetworks: [
|
|
{ index: 1, switchName: 'Main 2.4Ghz', ssid: 'Home WiFi', enabled: true, band: '2.4Ghz' },
|
|
],
|
|
portForwards: [
|
|
{ index: 0, description: 'SSH', enabled: true, internalClient: '192.168.178.2', internalPort: 22, externalPort: 22, protocol: 'TCP', connectionType: 'WANIPConnection' },
|
|
],
|
|
callDeflections: [
|
|
{ id: 1, enabled: false, type: 'fromNumber', number: '123', deflectionToNumber: '456', mode: 'eImmediately' },
|
|
],
|
|
update: {
|
|
installedVersion: '8.02',
|
|
latestVersion: '8.03',
|
|
updateAvailable: true,
|
|
releaseUrl: 'https://example.invalid/fritzos',
|
|
},
|
|
actions: [
|
|
{ target: 'service', action: 'set_guest_wifi_password' },
|
|
{ target: 'service', action: 'dial' },
|
|
],
|
|
};
|
|
|
|
tap.test('maps FRITZ router, tracker equivalents, interfaces, traffic sensors, and controls', async () => {
|
|
const normalized = FritzMapper.toSnapshot({ snapshot });
|
|
const devices = FritzMapper.toDevices(normalized);
|
|
const entities = FritzMapper.toEntities(normalized);
|
|
|
|
expect(devices.some((deviceArg) => deviceArg.id === 'fritz.router.aa_bb_cc_dd_ee_ff')).toBeTrue();
|
|
expect(devices.some((deviceArg) => deviceArg.id === 'fritz.client.11_22_33_44_55_66')).toBeTrue();
|
|
expect(entities.find((entityArg) => entityArg.id === 'sensor.home_fritz_gb_received')?.state).toEqual(2);
|
|
expect(entities.find((entityArg) => entityArg.id === 'sensor.home_fritz_download_throughput')?.state).toEqual(125.5);
|
|
expect(entities.find((entityArg) => entityArg.id === 'sensor.home_fritz_wan_download')?.state).toEqual(2);
|
|
expect(entities.find((entityArg) => entityArg.id === 'binary_sensor.kitchen_phone_connected')?.attributes?.nativePlatform).toEqual('device_tracker');
|
|
expect(entities.find((entityArg) => entityArg.id === 'switch.home_fritz_wi_fi_main_2_4ghz')?.state).toEqual('on');
|
|
expect(entities.find((entityArg) => entityArg.id === 'switch.kitchen_phone_internet_access')?.state).toEqual('on');
|
|
expect(entities.find((entityArg) => entityArg.id === 'button.kitchen_phone_wake_on_lan')?.available).toBeTrue();
|
|
expect(entities.find((entityArg) => entityArg.id === 'update.home_fritz_fritz_os')?.attributes?.latestVersion).toEqual('8.03');
|
|
});
|
|
|
|
tap.test('models only represented FRITZ commands safely', async () => {
|
|
const normalized = FritzMapper.toSnapshot({ snapshot });
|
|
const rebootCommand = FritzMapper.commandForService(normalized, {
|
|
domain: 'fritz',
|
|
service: 'reboot',
|
|
target: {},
|
|
});
|
|
const wifiCommand = FritzMapper.commandForService(normalized, {
|
|
domain: 'switch',
|
|
service: 'turn_off',
|
|
target: { entityId: 'switch.home_fritz_wi_fi_main_2_4ghz' },
|
|
});
|
|
const wolCommand = FritzMapper.commandForService(normalized, {
|
|
domain: 'button',
|
|
service: 'press',
|
|
target: { entityId: 'button.kitchen_phone_wake_on_lan' },
|
|
});
|
|
const serviceCommand = FritzMapper.commandForService(normalized, {
|
|
domain: 'fritz',
|
|
service: 'set_guest_wifi_password',
|
|
target: {},
|
|
data: { password: 'safe-passphrase' },
|
|
});
|
|
const invalidGuestPassword = FritzMapper.commandForService(normalized, {
|
|
domain: 'fritz',
|
|
service: 'set_guest_wifi_password',
|
|
target: {},
|
|
data: { password: 'short' },
|
|
});
|
|
|
|
expect(rebootCommand?.type).toEqual('router.action');
|
|
expect(wifiCommand?.action).toEqual('set_wifi_enabled');
|
|
expect(wifiCommand?.payload?.enabled).toBeFalse();
|
|
expect(wolCommand?.type).toEqual('client.action');
|
|
expect(wolCommand?.mac).toEqual('11:22:33:44:55:66');
|
|
expect(serviceCommand?.type).toEqual('service.action');
|
|
expect(invalidGuestPassword).toBeUndefined();
|
|
});
|
|
|
|
export default tap.start();
|