Files
integrations/test/amcrest/test.amcrest.mapper.node.ts

100 lines
4.1 KiB
TypeScript

import { expect, tap } from '@git.zone/tstest/tapbundle';
import { AmcrestMapper, type IAmcrestSnapshot } from '../../ts/integrations/amcrest/index.js';
const snapshot: IAmcrestSnapshot = {
deviceInfo: {
id: 'AMC123',
name: 'Front Door Amcrest',
manufacturer: 'Amcrest',
model: 'IP2M-841',
serialNumber: 'AMC123',
host: '192.168.1.30',
port: 80,
protocol: 'http',
online: true,
},
cameras: [{
id: '0',
name: 'Front Door Camera',
channel: 0,
resolution: 'high',
subtype: 0,
streamSource: 'rtsp',
snapshotUrl: 'http://192.168.1.30:80/cgi-bin/snapshot.cgi?channel=0',
mjpegUrl: 'http://192.168.1.30:80/cgi-bin/mjpg/video.cgi?channel=0&subtype=0',
rtspUrl: 'rtsp://user:pass@192.168.1.30:554/cam/realmonitor?channel=1&subtype=0',
isStreaming: true,
isRecording: false,
motionDetectionEnabled: true,
audioEnabled: true,
supportsPtz: true,
available: true,
}],
sensors: [{ key: 'ptz_preset', name: 'PTZ Preset', value: 2, entityCategory: 'diagnostic', available: true }],
binarySensors: [
{ key: 'online', name: 'Online', isOn: true, deviceClass: 'connectivity', shouldPoll: true, available: true },
{ key: 'motion_detected', name: 'Motion Detected', isOn: true, deviceClass: 'motion', eventCodes: ['VideoMotion'], available: true },
],
switches: [{ key: 'privacy_mode', name: 'Privacy Mode', isOn: false, command: 'privacy_mode', entityCategory: 'config', available: true }],
events: [],
currentSettings: { privacy_mode: false },
connected: true,
updatedAt: '2026-01-01T00:00:00.000Z',
};
tap.test('maps Amcrest camera streams, binary sensors, sensors, and switches', async () => {
const devices = AmcrestMapper.toDevices(snapshot);
const entities = AmcrestMapper.toEntities(snapshot);
expect(devices.length).toEqual(1);
expect(devices[0].features.some((featureArg) => featureArg.capability === 'camera')).toBeTrue();
expect(entities.find((entityArg) => entityArg.id === 'camera.front_door_camera')?.attributes?.rtspUrl).toEqual('rtsp://user:pass@192.168.1.30:554/cam/realmonitor?channel=1&subtype=0');
expect(entities.find((entityArg) => entityArg.id === 'binary_sensor.motion_detected')?.state).toEqual('on');
expect(entities.find((entityArg) => entityArg.id === 'sensor.ptz_preset')?.state).toEqual(2);
expect(entities.find((entityArg) => entityArg.id === 'switch.privacy_mode')?.state).toEqual('off');
});
tap.test('models camera, switch, snapshot, and PTZ services as explicit commands', async () => {
const streamCommand = AmcrestMapper.commandForService(snapshot, {
domain: 'camera',
service: 'stream_source',
target: { entityId: 'camera.front_door_camera' },
});
const snapshotCommand = AmcrestMapper.commandForService(snapshot, {
domain: 'camera',
service: 'snapshot',
target: { entityId: 'camera.front_door_camera' },
});
const privacyCommand = AmcrestMapper.commandForService(snapshot, {
domain: 'switch',
service: 'turn_on',
target: { entityId: 'switch.privacy_mode' },
});
const ptzCommand = AmcrestMapper.commandForService(snapshot, {
domain: 'amcrest',
service: 'ptz_control',
target: { entityId: 'camera.front_door_camera' },
data: { movement: 'left', travel_time: '0.1' },
});
const presetCommand = AmcrestMapper.commandForService(snapshot, {
domain: 'amcrest',
service: 'goto_preset',
target: { entityId: 'camera.front_door_camera' },
data: { preset: 2 },
});
expect(streamCommand?.type).toEqual('stream_source');
expect(snapshotCommand?.type).toEqual('snapshot_image');
expect(snapshotCommand?.httpCommands?.[0].path).toEqual('/cgi-bin/snapshot.cgi?channel=0');
expect(privacyCommand?.type).toEqual('set_privacy_mode');
expect(privacyCommand?.enabled).toBeTrue();
expect(privacyCommand?.httpCommands?.[0].path.includes('LeLensMask[0].Enable=true')).toBeTrue();
expect(ptzCommand?.type).toEqual('ptz_control');
expect(ptzCommand?.movement).toEqual('left');
expect(ptzCommand?.travelTime).toEqual(0.1);
expect(presetCommand?.type).toEqual('goto_preset');
expect(presetCommand?.httpCommands?.[0].path.includes('code=GotoPreset')).toBeTrue();
});
export default tap.start();