2020-05-24 09:16:39 -07:00
const data = require ( './stub/data' ) ;
const logger = require ( './stub/logger' ) ;
const zigbeeHerdsman = require ( './stub/zigbeeHerdsman' ) ;
const MQTT = require ( './stub/mqtt' ) ;
const settings = require ( '../lib/util/settings' ) ;
const Controller = require ( '../lib/controller' ) ;
const flushPromises = ( ) => new Promise ( setImmediate ) ;
2020-09-24 09:06:43 -07:00
const stringify = require ( 'json-stable-stringify-without-jsonify' ) ;
2020-05-24 09:16:39 -07:00
2020-10-09 12:40:33 -07:00
const { coordinator , bulb , unsupported , WXKG11LM , remote , ZNCZ02LM } = zigbeeHerdsman . devices ;
2020-05-24 09:16:39 -07:00
zigbeeHerdsman . returnDevices . push ( coordinator . ieeeAddr ) ;
zigbeeHerdsman . returnDevices . push ( bulb . ieeeAddr ) ;
zigbeeHerdsman . returnDevices . push ( unsupported . ieeeAddr ) ;
2020-07-29 14:10:03 -07:00
zigbeeHerdsman . returnDevices . push ( WXKG11LM . ieeeAddr ) ;
2020-08-31 09:48:04 -07:00
zigbeeHerdsman . returnDevices . push ( remote . ieeeAddr ) ;
2020-10-09 12:40:33 -07:00
zigbeeHerdsman . returnDevices . push ( ZNCZ02LM . ieeeAddr ) ;
2020-05-24 09:16:39 -07:00
describe ( 'Bridge' , ( ) => {
let controller ;
beforeEach ( async ( ) => {
2020-07-28 13:12:22 -07:00
MQTT . mock . reconnecting = false ;
2020-05-24 09:16:39 -07:00
data . writeDefaultConfiguration ( ) ;
settings . _reRead ( ) ;
settings . set ( [ 'advanced' , 'legacy_api' ] , false ) ;
data . writeDefaultState ( ) ;
logger . info . mockClear ( ) ;
logger . warn . mockClear ( ) ;
2020-07-28 13:12:22 -07:00
logger . setTransportsEnabled ( false ) ;
2020-05-24 09:16:39 -07:00
MQTT . publish . mockClear ( ) ;
2020-06-13 08:22:00 -07:00
const device = zigbeeHerdsman . devices . bulb ;
device . removeFromDatabase . mockClear ( ) ;
device . removeFromNetwork . mockClear ( ) ;
2020-05-24 09:16:39 -07:00
controller = new Controller ( ) ;
await controller . start ( ) ;
await flushPromises ( ) ;
} ) ;
it ( 'Should publish bridge info on startup' , async ( ) => {
const version = await require ( '../lib/util/utils' ) . getZigbee2mqttVersion ( ) ;
2020-09-04 09:42:24 -07:00
const directory = settings . get ( ) . advanced . log _directory ;
2020-05-24 09:16:39 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/info' ,
2020-12-02 12:38:48 -07:00
stringify ( { "commit" : version . commitHash , "config" : { "advanced" : { "adapter_concurrent" : null , "adapter_delay" : null , "availability_blacklist" : [ ] , "availability_blocklist" : [ ] , "availability_passlist" : [ ] , "availability_timeout" : 0 , "availability_whitelist" : [ ] , "cache_state" : true , "cache_state_persistent" : true , "cache_state_send_on_startup" : true , "channel" : 11 , "elapsed" : false , "ext_pan_id" : [ 221 , 221 , 221 , 221 , 221 , 221 , 221 , 221 ] , "homeassistant_discovery_topic" : "homeassistant" , "homeassistant_legacy_triggers" : true , "homeassistant_status_topic" : "hass/status" , "last_seen" : "disable" , "legacy_api" : false , "log_directory" : directory , "log_file" : "log.txt" , "log_level" : "info" , "log_output" : [ "console" , "file" ] , "log_rotation" : true , "log_syslog" : { } , "pan_id" : 6754 , "report" : false , "soft_reset_timeout" : 0 , "timestamp_format" : "YYYY-MM-DD HH:mm:ss" } , "ban" : [ ] , "blocklist" : [ ] , "device_options" : { } , "devices" : { "0x000b57fffec6a5b2" : { "friendly_name" : "bulb" , "retain" : true } , "0x000b57fffec6a5b3" : { "friendly_name" : "bulb_color" , "retain" : false } , "0x000b57fffec6a5b4" : { "friendly_name" : "bulb_color_2" , "retain" : false } , "0x000b57fffec6a5b7" : { "friendly_name" : "bulb_2" , "retain" : false } , "0x0017880104a44559" : { "friendly_name" : "J1_cover" } , "0x0017880104e43559" : { "friendly_name" : "U202DST600ZB" } , "0x0017880104e44559" : { "friendly_name" : "3157100_thermostat" } , "0x0017880104e45517" : { "friendly_name" : "remote" , "retain" : true } , "0x0017880104e45518" : { "friendly_name" : "0x0017880104e45518" } , "0x0017880104e45520" : { "friendly_name" : "button" , "retain" : false } , "0x0017880104e45521" : { "friendly_name" : "button_double_key" , "retain" : false } , "0x0017880104e45522" : { "friendly_name" : "weather_sensor" , "qos" : 1 , "retain" : false } , "0x0017880104e45523" : { "friendly_name" : "occupancy_sensor" , "retain" : false } , "0x0017880104e45524" : { "friendly_name" : "power_plug" , "retain" : false } , "0x0017880104e45526" : { "friendly_name" : "GL-S-007ZS" } , "0x0017880104e45529" : { "friendly_name" : "unsupported2" , "retain" : false } , "0x0017880104e45530" : { "friendly_name" : "button_double_key_interviewing" , "retain" : false } , "0x0017880104e45540" : { "friendly_name" : "ikea_onoff" } , "0x0017880104e45541" : { "friendly_name" : "wall_switch" , "retain" : false } , "0x0017880104e45542" : { "friendly_name" : "wall_switch_double" , "retain" : false } , "0x0017880104e45543" : { "friendly_name" : "led_controller_1" , "retain" : false } , "0x0017880104e45544" : { "friendly_name" : "led_controller_2" , "retain" : false } , "0x0017880104e45545" : { "friendly_name" : "dimmer_wall_switch" , "retain" : false } , "0x0017880104e45547" : { "friendly_name" : "curtain" , "retain" : false } , "0x0017880104e45548" : { "friendly_name" : "fan" , "retain" : false } , "0x0017880104e45549" : { "friendly_name" : "siren" , "retain" : false } , "0x0017880104e45550" : { "friendly_name" : "thermostat" , "retain" : false } , "0x0017880104e45551" : { "friendly_name" : "smart vent" , "retain" : false } , "0x0017880104e45552" : { "friendly_name" : "j1" , "retain" : false } , "0x0017880104e45553" : { "friendly_name" : "bulb_enddevice" , "retain" : false } , "0x0017880104e45559" : { "friendly_name" : "cc2530_router" , "retain" : false } , "0x0017880104e45560" : { "friendly_name" : "livolo" , "retain" : false } , "0x0017882104a44559" : { "friendly_name" : "TS0601_thermostat" } , "0x90fd9ffffe4b64aa" : { "friendly_name" : "SP600_OLD" } , "0x90fd9ffffe4b64ab" : { "friendly_name" : "SP600_NEW" } , "0x90fd9ffffe4b64ac" : { "friendly_name" : "MKS-CM-W5" } , "0x90fd9ffffe4b64ae" : { "friendly_name" : "tradfri_remote" , "retain" : false } , "0x90fd9ffffe4b64af" : { "friendly_name" : "roller_shutter" } , "0x90fd9ffffe4b64ax" : { "friendly_name" : "ZNLDP12LM" } } , "experimental" : { "output" : "json" } , "external_converters" : [ ] , "groups" : { "1" : { "friendly_name" : "group_1" , "retain" : false } , "11" : { "devices" : [ "bulb_2" ] , "friendly_name" : "group_with_tradfri" , "retain" : false } , "14" : { "devices" : [ "power_plug" ] , "friendly_name" : "switch_group" , "retain" : false } , "12" : { "devices" : [ "TS0601_thermostat" ] , "friendly_name" : "thermostat_group" , "retain" :
2020-05-24 09:16:39 -07:00
{ retain : true , qos : 0 } ,
expect . any ( Function )
) ;
} ) ;
it ( 'Should publish devices on startup' , async ( ) => {
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/devices' ,
2020-11-22 04:54:19 -07:00
stringify ( [ { "date_code" : null , "definition" : null , "endpoints" : { "1" : { "bindings" : [ ] , "clusters" : { "input" : [ ] , "output" : [ ] } } } , "friendly_name" : "Coordinator" , "ieee_address" : "0x00124b00120144ae" , "interview_completed" : false , "interviewing" : false , "network_address" : 0 , "power_source" : null , "software_build_id" : null , "supported" : false , "type" : "Coordinator" } , { "date_code" : null , "definition" : { "description" : "TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white" , "exposes" : [ { "features" : [ { "access" : 7 , "description" : "On/off state of this light" , "name" : "state" , "property" : "state" , "type" : "binary" , "value_off" : "OFF" , "value_on" : "ON" , "value_toggle" : "TOGGLE" } , { "access" : 7 , "description" : "Brightness of this light" , "name" : "brightness" , "property" : "brightness" , "type" : "numeric" , "value_max" : 254 , "value_min" : 0 } , { "access" : 7 , "description" : "Color temperature of this light" , "name" : "color_temp" , "property" : "color_temp" , "type" : "numeric" , "unit" : "mired" , "value_max" : 500 , "value_min" : 150 } ] , "type" : "light" } , { "access" : 2 , "description" : "Triggers an effect on the light (e.g. make light blink for a few seconds)" , "name" : "effect" , "property" : "effect" , "type" : "enum" , "values" : [ "blink" , "breathe" , "okay" , "channel_change" , "finish_effect" , "stop_effect" ] } , { "access" : 1 , "description" : "Link quality (signal strength)" , "name" : "linkquality" , "property" : "linkquality" , "type" : "numeric" , "unit" : "lqi" , "value_max" : 255 , "value_min" : 0 } ] , "model" : "LED1545G12" , "vendor" : "IKEA" } , "endpoints" : { "1" : { "bindings" : [ ] , "clusters" : { "input" : [ "genBasic" , "genScenes" , "genOnOff" , "genLevelCtrl" , "lightingColorCtrl" ] , "output" : [ "genScenes" , "genOta" ] } } } , "friendly_name" : "bulb" , "ieee_address" : "0x000b57fffec6a5b2" , "interview_completed" : true , "interviewing" : false , "network_address" : 40369 , "power_source" : "Mains (single phase)" , "software_build_id" : null , "supported" : true , "type" : "Router" } , { "date_code" : null , "definition" : { "description" : "Hue dimmer switch" , "exposes" : [ { "access" : 1 , "description" : "Remaining battery in %" , "name" : "battery" , "property" : "battery" , "type" : "numeric" , "unit" : "%" , "value_max" : 100 , "value_min" : 0 } , { "access" : 1 , "description" : "Triggered action (e.g. a button click)" , "name" : "action" , "property" : "action" , "type" : "enum" , "values" : [ "on-press" , "on-hold" , "on-release" , "up-press" , "up-hold" , "up-release" , "down-press" , "down-hold" , "down-release" , "off-press" , "off-hold" , "off-release" ] } , { "access" : 1 , "description" : "Link quality (signal strength)" , "name" : "linkquality" , "property" : "linkquality" , "type" : "numeric" , "unit" : "lqi" , "value_max" : 255 , "value_min" : 0 } ] , "model" : "324131092621" , "vendor" : "Philips" } , "endpoints" : { "1" : { "bindings" : [ { "cluster" : "genLevelCtrl" , "target" : { "endpoint" : 1 , "ieee_address" : "0x000b57fffec6a5b3" , "type" : "endpoint" } } , { "cluster" : "genOnOff" , "target" : { "id" : 1 , "type" : "group" } } ] , "clusters" : { "input" : [ "genBasic" ] , "output" : [ "genBasic" , "genOnOff" , "genLevelCtrl" , "genScenes" ] } } , "2" : { "bindings" : [ ] , "clusters" : { "input" : [ "genBasic" ] , "output" : [ "genOta" , "genOnOff" ] } } } , "friendly_name" : "remote" , "ieee_address" : "0x0017880104e45517" , "interview_completed" : true , "interviewing" : false , "network_address" : 6535 , "power_source" : "Battery" , "software_build_id" : null , "supported" : true , "type" : "EndDevice" } , { "date_code" : null , "definition" : null , "endpoints" : { "1" : { "bindings" : [ ] , "clusters" : { "input" : [ "genBasic" ] , "output" : [ "genBasic" , "genOnOff" , "genLevelCtrl" , "genScenes" ] } } } , "friendly_name" : "0x0017880104e45518" , "ieee_address" : "0x0017880104e45518" , "interview_completed" : true , "interviewing" : false , "network_address" : 6536 , "power_source" : "Battery" , "software_build_id" : null , "supported" : false , "type" : "EndDevice" } , { "date_code" : null , "definition" : { "description" : "Aqara wireless switch" , "exposes" : [ { "access" : 1 , "description" : "Remaining battery in %" , "name" : "battery" , "property" : "battery" , "type" : "numeric" , "unit" : "%" , "value_max" : 100 , "value_min" : 0 } , { "access" : 1 , "description" : "Triggered action (e.g. a button click)" , "name" : "action" , "property" : "action" , "type" : "enum" , "values" : [ "single" , "double" , "tripple" , "quadruple" , "hold" , "release" ] } , { "access" : 1 , "description" : "Link quality (signal strength)" , "name" : "linkquality" , "property" : "linkquality" , "type" : "numeric" , "unit" : "lqi" , "value_max" : 255 , "value_min" : 0 } ] ,
2020-10-09 12:57:54 -07:00
{ retain : true , qos : 0 } ,
expect . any ( Function )
2020-05-24 09:16:39 -07:00
) ;
} ) ;
2020-07-28 13:12:22 -07:00
it ( 'Should log to MQTT' , async ( ) => {
logger . setTransportsEnabled ( true ) ;
MQTT . publish . mockClear ( ) ;
logger . info . mockClear ( ) ;
logger . info ( "this is a test" ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/logging' ,
2020-08-13 11:00:35 -07:00
stringify ( { message : 'this is a test' , level : 'info' } ) ,
2020-07-28 13:12:22 -07:00
{ retain : false , qos : 0 } ,
expect . any ( Function )
) ;
expect ( logger . info ) . toHaveBeenCalledTimes ( 1 ) ;
} ) ;
it ( 'Shouldnt log to MQTT when not connected' , async ( ) => {
logger . setTransportsEnabled ( true ) ;
MQTT . mock . reconnecting = true ;
MQTT . publish . mockClear ( ) ;
logger . info . mockClear ( ) ;
logger . error . mockClear ( ) ;
logger . info ( "this is a test" ) ;
expect ( MQTT . publish ) . toHaveBeenCalledTimes ( 0 ) ;
expect ( logger . info ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( logger . error ) . toHaveBeenCalledTimes ( 0 ) ;
} ) ;
2020-08-30 02:30:38 -07:00
it ( 'Should publish groups on startup' , async ( ) => {
2020-07-28 13:12:22 -07:00
logger . setTransportsEnabled ( true ) ;
2020-05-24 09:16:39 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/groups' ,
2020-11-11 10:11:18 -07:00
stringify ( [ { "friendly_name" : "group_1" , "id" : 1 , "members" : [ ] } , { "friendly_name" : "group_tradfri_remote" , "id" : 15071 , "members" : [ ] } , { "friendly_name" : 99 , "id" : 99 , "members" : [ ] } , { "friendly_name" : "group_with_tradfri" , "id" : 11 , "members" : [ ] } , { "friendly_name" : "thermostat_group" , "id" : 12 , "members" : [ ] } , { "friendly_name" : "switch_group" , "id" : 14 , "members" : [ { "endpoint" : 1 , "ieee_address" : "0x0017880104e45524" } ] } , { "friendly_name" : "default_bind_group" , "id" : 901 , "members" : [ ] } , { "friendly_name" : "group_2" , "id" : 2 , "members" : [ ] } ] ) ,
2020-05-24 09:16:39 -07:00
{ retain : true , qos : 0 } ,
expect . any ( Function )
) ;
} ) ;
it ( 'Should publish event when device joined' , async ( ) => {
MQTT . publish . mockClear ( ) ;
await zigbeeHerdsman . events . deviceJoined ( { device : zigbeeHerdsman . devices . bulb } ) ;
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/event' ,
2020-08-13 11:00:35 -07:00
stringify ( { "type" : "device_joined" , "data" : { "friendly_name" : "bulb" , "ieee_address" : "0x000b57fffec6a5b2" } } ) ,
2020-08-20 11:55:40 -07:00
{ retain : false , qos : 0 } ,
expect . any ( Function )
) ;
} ) ;
it ( 'Should publish event when device announces' , async ( ) => {
MQTT . publish . mockClear ( ) ;
await zigbeeHerdsman . events . deviceAnnounce ( { device : zigbeeHerdsman . devices . bulb } ) ;
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/event' ,
stringify ( { "type" : "device_announce" , "data" : { "friendly_name" : "bulb" , "ieee_address" : "0x000b57fffec6a5b2" } } ) ,
2020-05-24 09:16:39 -07:00
{ retain : false , qos : 0 } ,
expect . any ( Function )
) ;
} ) ;
it ( 'Should publish event when device interview started' , async ( ) => {
MQTT . publish . mockClear ( ) ;
await zigbeeHerdsman . events . deviceInterview ( { device : zigbeeHerdsman . devices . bulb , status : 'started' } ) ;
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/event' ,
2020-08-13 11:00:35 -07:00
stringify ( { "type" : "device_interview" , "data" : { "friendly_name" : "bulb" , "status" : "started" , "ieee_address" : "0x000b57fffec6a5b2" } } ) ,
2020-05-24 09:16:39 -07:00
{ retain : false , qos : 0 } ,
expect . any ( Function )
) ;
} ) ;
it ( 'Should publish event and devices when device interview failed' , async ( ) => {
MQTT . publish . mockClear ( ) ;
await zigbeeHerdsman . events . deviceInterview ( { device : zigbeeHerdsman . devices . bulb , status : 'failed' } ) ;
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledTimes ( 2 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/event' ,
2020-08-13 11:00:35 -07:00
stringify ( { "type" : "device_interview" , "data" : { "friendly_name" : "bulb" , "status" : "failed" , "ieee_address" : "0x000b57fffec6a5b2" } } ) ,
2020-05-24 09:16:39 -07:00
{ retain : false , qos : 0 } ,
expect . any ( Function )
) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/devices' ,
expect . any ( String ) ,
{ retain : true , qos : 0 } ,
expect . any ( Function )
) ;
} ) ;
it ( 'Should publish event and devices when device interview successful' , async ( ) => {
MQTT . publish . mockClear ( ) ;
await zigbeeHerdsman . events . deviceInterview ( { device : zigbeeHerdsman . devices . bulb , status : 'successful' } ) ;
await zigbeeHerdsman . events . deviceInterview ( { device : zigbeeHerdsman . devices . unsupported , status : 'successful' } ) ;
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledTimes ( 4 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/event' ,
2020-11-22 04:54:19 -07:00
stringify ( { "data" : { "definition" : { "description" : "TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white" , "exposes" : [ { "features" : [ { "access" : 7 , "description" : "On/off state of this light" , "name" : "state" , "property" : "state" , "type" : "binary" , "value_off" : "OFF" , "value_on" : "ON" , "value_toggle" : "TOGGLE" } , { "access" : 7 , "description" : "Brightness of this light" , "name" : "brightness" , "property" : "brightness" , "type" : "numeric" , "value_max" : 254 , "value_min" : 0 } , { "access" : 7 , "description" : "Color temperature of this light" , "name" : "color_temp" , "property" : "color_temp" , "type" : "numeric" , "unit" : "mired" , "value_max" : 500 , "value_min" : 150 } ] , "type" : "light" } , { "access" : 2 , "description" : "Triggers an effect on the light (e.g. make light blink for a few seconds)" , "name" : "effect" , "property" : "effect" , "type" : "enum" , "values" : [ "blink" , "breathe" , "okay" , "channel_change" , "finish_effect" , "stop_effect" ] } , { "access" : 1 , "description" : "Link quality (signal strength)" , "name" : "linkquality" , "property" : "linkquality" , "type" : "numeric" , "unit" : "lqi" , "value_max" : 255 , "value_min" : 0 } ] , "model" : "LED1545G12" , "vendor" : "IKEA" } , "friendly_name" : "bulb" , "ieee_address" : "0x000b57fffec6a5b2" , "status" : "successful" , "supported" : true } , "type" : "device_interview" } ) ,
2020-05-24 09:16:39 -07:00
{ retain : false , qos : 0 } ,
expect . any ( Function )
) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/event' ,
2020-08-13 11:00:35 -07:00
stringify ( { "type" : "device_interview" , "data" : { "friendly_name" : "0x0017880104e45518" , "status" : "successful" , "ieee_address" : "0x0017880104e45518" , "supported" : false , "definition" : null } } ) ,
2020-05-24 09:16:39 -07:00
{ retain : false , qos : 0 } ,
expect . any ( Function )
) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/devices' ,
expect . any ( String ) ,
{ retain : true , qos : 0 } ,
expect . any ( Function )
) ;
} ) ;
it ( 'Should publish event and devices when device leaves' , async ( ) => {
MQTT . publish . mockClear ( ) ;
await zigbeeHerdsman . events . deviceLeave ( { ieeeAddr : zigbeeHerdsman . devices . bulb . ieeeAddr } ) ;
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledTimes ( 2 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/event' ,
2020-08-13 11:00:35 -07:00
stringify ( { "type" : "device_leave" , "data" : { "ieee_address" : "0x000b57fffec6a5b2" } } ) ,
2020-05-24 09:16:39 -07:00
{ retain : false , qos : 0 } ,
expect . any ( Function )
) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/devices' ,
expect . any ( String ) ,
{ retain : true , qos : 0 } ,
expect . any ( Function )
) ;
} ) ;
it ( 'Should allow permit join' , async ( ) => {
zigbeeHerdsman . permitJoin . mockClear ( ) ;
MQTT . publish . mockClear ( ) ;
2020-07-13 14:00:33 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/permit_join' , 'true' ) ;
2020-05-24 09:16:39 -07:00
await flushPromises ( ) ;
expect ( zigbeeHerdsman . permitJoin ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( zigbeeHerdsman . permitJoin ) . toHaveBeenCalledWith ( true ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/info' , expect . any ( String ) , { retain : true , qos : 0 } , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-07-13 14:00:33 -07:00
'zigbee2mqtt/bridge/response/permit_join' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "value" : true } , "status" : "ok" } ) ,
2020-05-24 09:16:39 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
zigbeeHerdsman . permitJoin . mockClear ( ) ;
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/permit_join' , stringify ( { "value" : false } ) ) ;
2020-05-24 09:16:39 -07:00
await flushPromises ( ) ;
expect ( zigbeeHerdsman . permitJoin ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( zigbeeHerdsman . permitJoin ) . toHaveBeenCalledWith ( false ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/info' , expect . any ( String ) , { retain : true , qos : 0 } , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-07-13 14:00:33 -07:00
'zigbee2mqtt/bridge/response/permit_join' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "value" : false } , "status" : "ok" } ) ,
2020-05-24 09:16:39 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
2020-10-11 06:12:07 -07:00
// Invalid payload
zigbeeHerdsman . permitJoin . mockClear ( ) ;
MQTT . publish . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/permit_join' , stringify ( { "value_bla" : false } ) ) ;
await flushPromises ( ) ;
expect ( zigbeeHerdsman . permitJoin ) . toHaveBeenCalledTimes ( 0 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/permit_join' ,
stringify ( { "data" : { } , "status" : "error" , "error" : "Invalid payload" } ) ,
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
2020-05-24 09:16:39 -07:00
} ) ;
2020-10-11 06:05:21 -07:00
it ( 'Should allow permit join via device' , async ( ) => {
const device = zigbeeHerdsman . devices . bulb ;
zigbeeHerdsman . permitJoin . mockClear ( ) ;
MQTT . publish . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/permit_join' , stringify ( { value : true , device : 'bulb' } ) ) ;
await flushPromises ( ) ;
expect ( zigbeeHerdsman . permitJoin ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( zigbeeHerdsman . permitJoin ) . toHaveBeenCalledWith ( true , device ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/info' , expect . any ( String ) , { retain : true , qos : 0 } , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/permit_join' ,
stringify ( { "data" : { "value" : true , "device" : "bulb" } , "status" : "ok" } ) ,
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
// Device does not exist
zigbeeHerdsman . permitJoin . mockClear ( ) ;
MQTT . publish . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/permit_join' , stringify ( { value : true , device : 'bulb_not_existing_woeeee' } ) ) ;
await flushPromises ( ) ;
expect ( zigbeeHerdsman . permitJoin ) . toHaveBeenCalledTimes ( 0 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/permit_join' ,
stringify ( { "data" : { } , "status" : "error" , "error" : "Device 'bulb_not_existing_woeeee' does not exist" } ) ,
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-05-24 09:16:39 -07:00
it ( 'Should put transaction in response when request is done with transaction' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/permit_join' , stringify ( { "value" : false , "transaction" : 22 } ) ) ;
2020-05-24 09:16:39 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-07-13 14:00:33 -07:00
'zigbee2mqtt/bridge/response/permit_join' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "value" : false } , "status" : "ok" , "transaction" : 22 } ) ,
2020-05-24 09:16:39 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-05-26 08:36:04 -07:00
it ( 'Should put error in response when request fails' , async ( ) => {
2020-05-24 09:16:39 -07:00
zigbeeHerdsman . permitJoin . mockImplementationOnce ( ( ) => { throw new Error ( 'Failed to connect to adapter' ) } ) ;
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/permit_join' , stringify ( { "value" : false } ) ) ;
2020-05-24 09:16:39 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-07-13 14:00:33 -07:00
'zigbee2mqtt/bridge/response/permit_join' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "Failed to connect to adapter" } ) ,
2020-05-24 09:16:39 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-06-15 09:58:32 -07:00
it ( 'Should put error in response when format is incorrect' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-10-11 06:05:21 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/config/last_seen' , stringify ( { "value_not_good" : false } ) ) ;
2020-06-15 09:58:32 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-10-11 06:05:21 -07:00
'zigbee2mqtt/bridge/response/config/last_seen' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "No value given" } ) ,
2020-06-15 09:58:32 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-05-24 09:16:39 -07:00
it ( 'Coverage satisfaction' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/random' , stringify ( { "value" : false } ) ) ;
2020-05-24 09:16:39 -07:00
const device = zigbeeHerdsman . devices . bulb ;
await zigbeeHerdsman . events . message ( { data : { onOff : 1 } , cluster : 'genOnOff' , device , endpoint : device . getEndpoint ( 1 ) , type : 'attributeReport' , linkquality : 10 } ) ;
await flushPromises ( ) ;
} ) ;
2020-06-13 08:22:00 -07:00
2020-07-21 12:14:39 -07:00
it ( 'Should allow a healthcheck' , async ( ) => {
MQTT . publish . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/health_check' , '' ) ;
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/health_check' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "healthy" : true } , "status" : "ok" } ) ,
2020-07-21 12:14:39 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-06-13 08:22:00 -07:00
it ( 'Should allow to remove device by string' , async ( ) => {
const device = zigbeeHerdsman . devices . bulb ;
controller . state . state = { '0x000b57fffec6a5b3' : { brightness : 100 } } ;
MQTT . publish . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/remove' , 'bulb' ) ;
await flushPromises ( ) ;
expect ( controller . state [ device . ieeeAddr ] ) . toBeUndefined ( ) ;
expect ( device . removeFromNetwork ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( device . removeFromDatabase ) . not . toHaveBeenCalled ( ) ;
expect ( settings . getDevice ( 'bulb' ) ) . toBeNull ( ) ;
2020-09-07 08:29:53 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bulb' , '' , { retain : true , qos : 0 } , expect . any ( Function ) ) ;
2020-06-13 08:22:00 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/devices' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/remove' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "id" : "bulb" , "block" : false , "force" : false } , "status" : "ok" } ) ,
2020-06-13 08:22:00 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
2020-07-15 14:22:32 -07:00
expect ( settings . get ( ) . blocklist ) . toStrictEqual ( [ ] ) ;
2020-10-06 10:28:32 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/devices' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/groups' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
2020-06-13 08:22:00 -07:00
} ) ;
it ( 'Should allow to remove device by object ID' , async ( ) => {
const device = zigbeeHerdsman . devices . bulb ;
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/remove' , stringify ( { id : "bulb" } ) ) ;
2020-06-13 08:22:00 -07:00
await flushPromises ( ) ;
expect ( device . removeFromNetwork ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( device . removeFromDatabase ) . not . toHaveBeenCalled ( ) ;
expect ( settings . getDevice ( 'bulb' ) ) . toBeNull ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/devices' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/remove' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "id" : "bulb" , "block" : false , "force" : false } , "status" : "ok" } ) ,
2020-06-13 08:22:00 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should allow to force remove device' , async ( ) => {
const device = zigbeeHerdsman . devices . bulb ;
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/remove' , stringify ( { id : "bulb" , force : true } ) ) ;
2020-06-13 08:22:00 -07:00
await flushPromises ( ) ;
expect ( device . removeFromDatabase ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( device . removeFromNetwork ) . not . toHaveBeenCalled ( ) ;
expect ( settings . getDevice ( 'bulb' ) ) . toBeNull ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/devices' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/remove' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "id" : "bulb" , "block" : false , "force" : true } , "status" : "ok" } ) ,
2020-06-13 08:22:00 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-07-15 14:22:32 -07:00
it ( 'Should allow to block device' , async ( ) => {
2020-06-13 08:22:00 -07:00
const device = zigbeeHerdsman . devices . bulb ;
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/remove' , stringify ( { id : "bulb" , block : true , force : true } ) ) ;
2020-06-13 08:22:00 -07:00
await flushPromises ( ) ;
expect ( device . removeFromDatabase ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( settings . getDevice ( 'bulb' ) ) . toBeNull ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/devices' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/remove' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "id" : "bulb" , "block" : true , "force" : true } , "status" : "ok" } ) ,
2020-06-13 08:22:00 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
2020-07-15 14:22:32 -07:00
expect ( settings . get ( ) . blocklist ) . toStrictEqual ( [ "0x000b57fffec6a5b2" ] ) ;
2020-06-13 08:22:00 -07:00
} ) ;
it ( 'Should allow to remove group' , async ( ) => {
const group = zigbeeHerdsman . groups . group _1 ;
MQTT . publish . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/group/remove' , 'group_1' ) ;
await flushPromises ( ) ;
2020-07-07 12:16:35 -07:00
expect ( group . removeFromNetwork ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( settings . getGroup ( 'group_1' ) ) . toBeNull ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/groups' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/group/remove' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "id" : "group_1" , "force" : false } , "status" : "ok" } ) ,
2020-07-07 12:16:35 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should allow to force remove group' , async ( ) => {
const group = zigbeeHerdsman . groups . group _1 ;
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/group/remove' , stringify ( { id : "group_1" , force : true } ) ) ;
2020-07-07 12:16:35 -07:00
await flushPromises ( ) ;
2020-06-13 08:22:00 -07:00
expect ( group . removeFromDatabase ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( settings . getGroup ( 'group_1' ) ) . toBeNull ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/groups' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/group/remove' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "id" : "group_1" , "force" : true } , "status" : "ok" } ) ,
2020-06-13 08:22:00 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should throw error on removing non-existing device' , async ( ) => {
const device = zigbeeHerdsman . devices . bulb ;
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/remove' , stringify ( { id : "non-existing-device" } ) ) ;
2020-06-13 08:22:00 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/remove' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "Device 'non-existing-device' does not exist" } ) ,
2020-06-13 08:22:00 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should throw error when remove device fails' , async ( ) => {
const device = zigbeeHerdsman . devices . bulb ;
MQTT . publish . mockClear ( ) ;
device . removeFromNetwork . mockImplementationOnce ( ( ) => { throw new Error ( 'device timeout' ) } )
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/remove' , stringify ( { id : "bulb" } ) ) ;
2020-06-13 08:22:00 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/remove' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "Failed to remove device 'bulb' (block: false, force: false) (Error: device timeout)" } ) ,
2020-06-13 08:22:00 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-06-13 10:35:09 -07:00
it ( 'Should allow rename device' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/rename' , stringify ( { from : 'bulb' , to : 'bulb_new_name' } ) ) ;
2020-06-13 10:35:09 -07:00
await flushPromises ( ) ;
expect ( settings . getDevice ( 'bulb' ) ) . toBeNull ( ) ;
2020-07-13 14:00:33 -07:00
expect ( settings . getDevice ( 'bulb_new_name' ) ) . toStrictEqual ( { "ID" : "0x000b57fffec6a5b2" , "friendly_name" : "bulb_new_name" , "friendlyName" : "bulb_new_name" , "retain" : true } ) ;
2020-09-07 08:29:53 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bulb' , '' , { retain : true , qos : 0 } , expect . any ( Function ) ) ;
2020-06-13 10:35:09 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/devices' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
2020-10-09 13:59:10 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bulb_new_name' , stringify ( { "brightness" : 50 , "color_temp" : 370 , "linkquality" : 99 , "state" : "ON" } ) , expect . any ( Object ) , expect . any ( Function ) ) ;
2020-06-13 10:35:09 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/rename' ,
2020-09-04 12:08:20 -07:00
stringify ( { "data" : { "from" : "bulb" , "to" : "bulb_new_name" , "homeassistant_rename" : false } , "status" : "ok" } ) ,
2020-06-13 10:35:09 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should allow rename group' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/group/rename' , stringify ( { from : 'group_1' , to : 'group_new_name' } ) ) ;
2020-06-13 10:35:09 -07:00
await flushPromises ( ) ;
expect ( settings . getGroup ( 'group_1' ) ) . toBeNull ( ) ;
2020-07-13 14:00:33 -07:00
expect ( settings . getGroup ( 'group_new_name' ) ) . toStrictEqual ( { "ID" : 1 , "devices" : [ ] , "friendly_name" : "group_new_name" , "friendlyName" : "group_new_name" , "optimistic" : true , "retain" : false } ) ;
2020-06-13 10:35:09 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/groups' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/group/rename' ,
2020-09-04 12:08:20 -07:00
stringify ( { "data" : { "from" : "group_1" , "to" : "group_new_name" , "homeassistant_rename" : false } , "status" : "ok" } ) ,
2020-06-13 10:35:09 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should throw error on invalid device rename payload' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/rename' , stringify ( { from _bla : 'bulb' , to : 'bulb_new_name' } ) ) ;
2020-06-13 10:35:09 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/rename' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "Invalid payload" } ) ,
2020-06-13 10:35:09 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should throw error on non-existing device rename' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/rename' , stringify ( { from : 'bulb_not_existing' , to : 'bulb_new_name' } ) ) ;
2020-06-13 10:35:09 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/rename' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "Device 'bulb_not_existing' does not exist" } ) ,
2020-06-13 10:35:09 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should allow to rename last joined device' , async ( ) => {
MQTT . publish . mockClear ( ) ;
await zigbeeHerdsman . events . deviceJoined ( { device : zigbeeHerdsman . devices . bulb } ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/rename' , stringify ( { last : true , to : 'bulb_new_name' } ) ) ;
2020-06-13 10:35:09 -07:00
await flushPromises ( ) ;
expect ( settings . getDevice ( 'bulb' ) ) . toBeNull ( ) ;
2020-07-13 14:00:33 -07:00
expect ( settings . getDevice ( 'bulb_new_name' ) ) . toStrictEqual ( { "ID" : "0x000b57fffec6a5b2" , "friendly_name" : "bulb_new_name" , "friendlyName" : "bulb_new_name" , "retain" : true } ) ;
2020-06-13 10:35:09 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/devices' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/rename' ,
2020-09-04 12:08:20 -07:00
stringify ( { "data" : { "from" : "bulb" , "to" : "bulb_new_name" , "homeassistant_rename" : false } , "status" : "ok" } ) ,
2020-06-13 10:35:09 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-09-19 01:57:39 -07:00
it ( 'Should throw error when renaming device through not allowed friendlyName' , async ( ) => {
MQTT . publish . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/rename' , stringify ( { from : 'bulb' , to : 'bulb_new_name/1' } ) ) ;
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/rename' ,
stringify ( { "data" : { } , "status" : "error" , "error" : ` Friendly name cannot end with a "/DIGIT" ('bulb_new_name/1') ` } ) ,
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-06-13 10:35:09 -07:00
it ( 'Should throw error when renaming last joined device but none has joined' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/rename' , stringify ( { last : true , to : 'bulb_new_name' } ) ) ;
2020-06-13 10:35:09 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/device/rename' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "No device has joined since start" } ) ,
2020-06-13 10:35:09 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-06-13 14:28:06 -07:00
it ( 'Should allow change device options' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-07-13 14:00:33 -07:00
expect ( settings . getDevice ( 'bulb' ) ) . toStrictEqual ( { "ID" : "0x000b57fffec6a5b2" , "friendly_name" : "bulb" , "friendlyName" : "bulb" , "retain" : true } ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/options' , stringify ( { options : { retain : false , transition : 1 } , id : 'bulb' } ) ) ;
2020-06-13 14:28:06 -07:00
await flushPromises ( ) ;
2020-07-13 14:00:33 -07:00
expect ( settings . getDevice ( 'bulb' ) ) . toStrictEqual ( { "ID" : "0x000b57fffec6a5b2" , "friendly_name" : "bulb" , "friendlyName" : "bulb" , "retain" : false , "transition" : 1 } ) ;
2020-06-13 14:28:06 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-06-13 15:28:24 -07:00
'zigbee2mqtt/bridge/response/device/options' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "from" : { "retain" : true } , "to" : { "retain" : false , "transition" : 1 } , "id" : "bulb" } , "status" : "ok" } ) ,
2020-06-13 14:28:06 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should allow change group options' , async ( ) => {
MQTT . publish . mockClear ( ) ;
expect ( settings . getGroup ( 'group_1' ) ) . toStrictEqual ( { "ID" : 1 , "devices" : [ ] , "friendly_name" : "group_1" , "retain" : false , "friendlyName" : "group_1" , "optimistic" : true } ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/group/options' , stringify ( { options : { retain : true , transition : 1 } , id : 'group_1' } ) ) ;
2020-06-13 14:28:06 -07:00
await flushPromises ( ) ;
expect ( settings . getGroup ( 'group_1' ) ) . toStrictEqual ( { "ID" : 1 , "devices" : [ ] , "friendly_name" : "group_1" , "retain" : true , "friendlyName" : "group_1" , "optimistic" : true , "transition" : 1 } ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-06-13 15:28:24 -07:00
'zigbee2mqtt/bridge/response/group/options' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "from" : { "optimistic" : true , "retain" : false } , "to" : { "optimistic" : true , "retain" : true , "transition" : 1 } , "id" : "group_1" } , "status" : "ok" } ) ,
2020-06-13 14:28:06 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should throw error on invalid device change options payload' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/device/options' , stringify ( { options _ : { retain : true , transition : 1 } , id : 'bulb' } ) ) ;
2020-06-13 14:28:06 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-06-13 15:28:24 -07:00
'zigbee2mqtt/bridge/response/device/options' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "Invalid payload" } ) ,
2020-06-13 14:28:06 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-06-13 14:42:58 -07:00
it ( 'Should allow to add group by string' , async ( ) => {
MQTT . publish . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/group/add' , 'group_193' ) ;
await flushPromises ( ) ;
2020-07-13 14:00:33 -07:00
expect ( settings . getGroup ( 'group_193' ) ) . toStrictEqual ( { "ID" : 3 , "devices" : [ ] , "friendly_name" : "group_193" , "friendlyName" : "group_193" , "optimistic" : true } ) ;
2020-06-13 14:42:58 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/groups' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/group/add' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "friendly_name" : "group_193" , "id" : 3 } , "status" : "ok" } ) ,
2020-06-13 14:42:58 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should allow to add group with ID' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/group/add' , stringify ( { friendly _name : "group_193" , id : 9 } ) ) ;
2020-06-13 14:42:58 -07:00
await flushPromises ( ) ;
2020-07-13 14:00:33 -07:00
expect ( settings . getGroup ( 'group_193' ) ) . toStrictEqual ( { "ID" : 9 , "devices" : [ ] , "friendly_name" : "group_193" , "friendlyName" : "group_193" , "optimistic" : true } ) ;
2020-06-13 14:42:58 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/groups' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/group/add' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "friendly_name" : "group_193" , "id" : 9 } , "status" : "ok" } ) ,
2020-06-13 14:42:58 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should throw error when add with invalid payload' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/group/add' , stringify ( { friendly _name9 : "group_193" } ) ) ;
2020-06-13 14:42:58 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/group/add' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "Invalid payload" } ) ,
2020-06-13 14:42:58 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-06-15 09:58:32 -07:00
2020-07-29 14:10:03 -07:00
it ( 'Should allow to enable/disable Home Assistant extension' , async ( ) => {
// Test if disabled intially
const device = zigbeeHerdsman . devices . WXKG11LM ;
settings . set ( [ 'devices' , device . ieeeAddr , 'legacy' ] , false ) ;
const payload = { data : { onOff : 1 } , cluster : 'genOnOff' , device , endpoint : device . getEndpoint ( 1 ) , type : 'attributeReport' , linkquality : 10 } ;
await zigbeeHerdsman . events . message ( payload ) ;
expect ( settings . get ( ) . homeassistant ) . toBeFalsy ( ) ;
expect ( MQTT . publish ) . not . toHaveBeenCalledWith ( 'zigbee2mqtt/button/action' , 'single' , { retain : false , qos : 0 } , expect . any ( Function ) ) ;
// Disable when already disabled should go OK
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/config/homeassistant' , stringify ( { value : false } ) ) ;
2020-07-29 14:10:03 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/config/homeassistant' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "value" : false } , "status" : "ok" } ) ,
2020-07-29 14:10:03 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
expect ( settings . get ( ) . homeassistant ) . toBeFalsy ( ) ;
// Enable
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/config/homeassistant' , stringify ( { value : true } ) ) ;
2020-07-29 14:10:03 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/config/homeassistant' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "value" : true } , "status" : "ok" } ) ,
2020-07-29 14:10:03 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
expect ( settings . get ( ) . homeassistant ) . toBeTruthy ( ) ;
MQTT . publish . mockClear ( ) ;
await zigbeeHerdsman . events . message ( payload ) ;
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/button/action' , 'single' , { retain : false , qos : 0 } , expect . any ( Function ) ) ;
// Disable
2020-08-13 11:00:35 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/config/homeassistant' , stringify ( { value : false } ) ) ;
2020-07-29 14:10:03 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/config/homeassistant' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "value" : false } , "status" : "ok" } ) ,
2020-07-29 14:10:03 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
expect ( settings . get ( ) . homeassistant ) . toBeFalsy ( ) ;
MQTT . publish . mockClear ( ) ;
await zigbeeHerdsman . events . message ( payload ) ;
await flushPromises ( ) ;
expect ( MQTT . publish ) . not . toHaveBeenCalledWith ( 'zigbee2mqtt/button/action' , 'single' , { retain : false , qos : 0 } , expect . any ( Function ) ) ;
} ) ;
it ( 'Should fail to set Home Assistant when invalid type' , async ( ) => {
MQTT . publish . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/config/homeassistant' , 'invalid_one' ) ;
await flushPromises ( ) ;
expect ( settings . get ( ) . homeassistant ) . toBeFalsy ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/config/homeassistant' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "'invalid_one' is not an allowed value, allowed: true,false" } ) ,
2020-07-29 14:10:03 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-06-15 09:58:32 -07:00
it ( 'Should allow to set last_seen' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-07-13 14:00:33 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/config/last_seen' , 'ISO_8601' ) ;
2020-06-15 09:58:32 -07:00
await flushPromises ( ) ;
expect ( settings . get ( ) . advanced . last _seen ) . toBe ( 'ISO_8601' ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-07-13 14:00:33 -07:00
'zigbee2mqtt/bridge/response/config/last_seen' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "value" : "ISO_8601" } , "status" : "ok" } ) ,
2020-06-15 09:58:32 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should fail to set last_seen when invalid type' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-07-13 14:00:33 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/config/last_seen' , 'invalid_one' ) ;
2020-06-15 09:58:32 -07:00
await flushPromises ( ) ;
expect ( settings . get ( ) . advanced . last _seen ) . toBe ( 'disable' ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-07-13 14:00:33 -07:00
'zigbee2mqtt/bridge/response/config/last_seen' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "'invalid_one' is not an allowed value, allowed: disable,ISO_8601,epoch,ISO_8601_local" } ) ,
2020-06-15 09:58:32 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should allow to set elapsed' , async ( ) => {
MQTT . publish . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/config/elapsed' , 'true' ) ;
await flushPromises ( ) ;
expect ( settings . get ( ) . advanced . elapsed ) . toBe ( true ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/config/elapsed' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "value" : true } , "status" : "ok" } ) ,
2020-06-15 09:58:32 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should fail to set last_seen when invalid type' , async ( ) => {
MQTT . publish . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/config/elapsed' , 'not_valid' ) ;
await flushPromises ( ) ;
expect ( settings . get ( ) . advanced . elapsed ) . toBe ( false ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/config/elapsed' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "'not_valid' is not an allowed value, allowed: true,false" } ) ,
2020-06-15 09:58:32 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should allow to set log level' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-07-13 14:00:33 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/config/log_level' , 'debug' ) ;
2020-06-15 09:58:32 -07:00
await flushPromises ( ) ;
expect ( logger . getLevel ( ) ) . toBe ( 'debug' ) ;
2020-06-15 10:06:08 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith ( 'zigbee2mqtt/bridge/info' , expect . any ( String ) , expect . any ( Object ) , expect . any ( Function ) ) ;
2020-06-15 09:58:32 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-07-13 14:00:33 -07:00
'zigbee2mqtt/bridge/response/config/log_level' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { "value" : 'debug' } , "status" : "ok" } ) ,
2020-06-15 09:58:32 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should fail to set log level when invalid type' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-07-13 14:00:33 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/config/log_level' , 'not_valid' ) ;
2020-06-15 09:58:32 -07:00
await flushPromises ( ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-07-13 14:00:33 -07:00
'zigbee2mqtt/bridge/response/config/log_level' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "'not_valid' is not an allowed value, allowed: error,warn,info,debug" } ) ,
2020-06-15 09:58:32 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-06-15 10:19:57 -07:00
it ( 'Should allow to touchlink factory reset (succeeds)' , async ( ) => {
2020-09-08 11:24:49 -07:00
MQTT . publish . mockClear ( ) ;
zigbeeHerdsman . touchlinkFactoryResetFirst . mockClear ( ) ;
zigbeeHerdsman . touchlinkFactoryResetFirst . mockReturnValueOnce ( true ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/touchlink/factory_reset' , '' ) ;
await flushPromises ( ) ;
expect ( zigbeeHerdsman . touchlinkFactoryResetFirst ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/touchlink/factory_reset' ,
stringify ( { "data" : { } , "status" : "ok" } ) ,
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Should allow to touchlink factory reset specific device' , async ( ) => {
2020-06-15 10:19:57 -07:00
MQTT . publish . mockClear ( ) ;
zigbeeHerdsman . touchlinkFactoryReset . mockClear ( ) ;
zigbeeHerdsman . touchlinkFactoryReset . mockReturnValueOnce ( true ) ;
2020-09-08 11:24:49 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/touchlink/factory_reset' , stringify ( { ieee _address : '0x1239' , channel : 12 } ) ) ;
2020-06-15 10:19:57 -07:00
await flushPromises ( ) ;
expect ( zigbeeHerdsman . touchlinkFactoryReset ) . toHaveBeenCalledTimes ( 1 ) ;
2020-09-08 11:24:49 -07:00
expect ( zigbeeHerdsman . touchlinkFactoryReset ) . toHaveBeenCalledWith ( '0x1239' , 12 ) ;
2020-06-15 10:19:57 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-07-13 14:00:33 -07:00
'zigbee2mqtt/bridge/response/touchlink/factory_reset' ,
2020-09-08 11:24:49 -07:00
stringify ( { "data" : { "ieee_address" : '0x1239' , "channel" : 12 } , "status" : "ok" } ) ,
2020-06-15 10:19:57 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-09-09 09:24:32 -07:00
it ( 'Should allow to touchlink identify specific device' , async ( ) => {
MQTT . publish . mockClear ( ) ;
zigbeeHerdsman . touchlinkIdentify . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/touchlink/identify' , stringify ( { ieee _address : '0x1239' , channel : 12 } ) ) ;
await flushPromises ( ) ;
expect ( zigbeeHerdsman . touchlinkIdentify ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( zigbeeHerdsman . touchlinkIdentify ) . toHaveBeenCalledWith ( '0x1239' , 12 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/touchlink/identify' ,
stringify ( { "data" : { "ieee_address" : '0x1239' , "channel" : 12 } , "status" : "ok" } ) ,
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
it ( 'Touchlink identify fails when payload is invalid' , async ( ) => {
MQTT . publish . mockClear ( ) ;
zigbeeHerdsman . touchlinkIdentify . mockClear ( ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/touchlink/identify' , stringify ( { ieee _address : '0x1239' } ) ) ;
await flushPromises ( ) ;
expect ( zigbeeHerdsman . touchlinkIdentify ) . toHaveBeenCalledTimes ( 0 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/touchlink/identify' ,
stringify ( { "data" : { } , "status" : "error" , "error" : "Invalid payload" } ) ,
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-06-15 10:19:57 -07:00
it ( 'Should allow to touchlink factory reset (fails)' , async ( ) => {
MQTT . publish . mockClear ( ) ;
2020-09-08 11:24:49 -07:00
zigbeeHerdsman . touchlinkFactoryResetFirst . mockClear ( ) ;
zigbeeHerdsman . touchlinkFactoryResetFirst . mockReturnValueOnce ( false ) ;
2020-07-13 14:00:33 -07:00
MQTT . events . message ( 'zigbee2mqtt/bridge/request/touchlink/factory_reset' , '' ) ;
2020-06-15 10:19:57 -07:00
await flushPromises ( ) ;
2020-09-08 11:24:49 -07:00
expect ( zigbeeHerdsman . touchlinkFactoryResetFirst ) . toHaveBeenCalledTimes ( 1 ) ;
2020-06-15 10:19:57 -07:00
expect ( MQTT . publish ) . toHaveBeenCalledWith (
2020-07-13 14:00:33 -07:00
'zigbee2mqtt/bridge/response/touchlink/factory_reset' ,
2020-08-13 11:00:35 -07:00
stringify ( { "data" : { } , "status" : "error" , "error" : "Failed to factory reset device through Touchlink" } ) ,
2020-06-15 10:19:57 -07:00
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-09-08 11:24:49 -07:00
it ( 'Should allow to touchlink scan' , async ( ) => {
MQTT . publish . mockClear ( ) ;
zigbeeHerdsman . touchlinkScan . mockClear ( ) ;
zigbeeHerdsman . touchlinkScan . mockReturnValueOnce ( [ { ieeeAddr : '0x123' , channel : 12 } , { ieeeAddr : '0x124' , channel : 24 } ] ) ;
MQTT . events . message ( 'zigbee2mqtt/bridge/request/touchlink/scan' , '' ) ;
await flushPromises ( ) ;
expect ( zigbeeHerdsman . touchlinkScan ) . toHaveBeenCalledTimes ( 1 ) ;
expect ( MQTT . publish ) . toHaveBeenCalledWith (
'zigbee2mqtt/bridge/response/touchlink/scan' ,
stringify ( { "data" : { "found" : [ { ieee _address : '0x123' , channel : 12 } , { ieee _address : '0x124' , channel : 24 } ] } , "status" : "ok" } ) ,
{ retain : false , qos : 0 } , expect . any ( Function )
) ;
} ) ;
2020-05-24 09:16:39 -07:00
} ) ;