From ed7a7fda5fe36ce48af29ef9a10b130d21abd899 Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Thu, 31 Jul 2025 14:39:29 -0500 Subject: [PATCH 01/12] 58 Unit test fixes for matter test cases This change covers the matter test case updates associated with #2310. --- .../src/test/test_aqara_matter_lock.lua | 17 +++- .../src/test/test_bridged_matter_lock.lua | 90 +++++++++++-------- .../matter-lock/src/test/test_matter_lock.lua | 11 ++- .../src/test/test_matter_lock_battery.lua | 24 +++-- .../test/test_matter_lock_batteryLevel.lua | 39 ++++---- .../src/test/test_matter_lock_codes.lua | 28 +++--- .../src/test/test_matter_lock_cota.lua | 21 ++--- .../src/test/test_matter_lock_unlatch.lua | 26 +++--- .../src/test/test_new_matter_lock.lua | 26 +++--- .../src/test/test_new_matter_lock_battery.lua | 32 ++++++- 10 files changed, 190 insertions(+), 124 deletions(-) diff --git a/drivers/SmartThings/matter-lock/src/test/test_aqara_matter_lock.lua b/drivers/SmartThings/matter-lock/src/test/test_aqara_matter_lock.lua index b64324d8f7..7427ad31d0 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_aqara_matter_lock.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_aqara_matter_lock.lua @@ -41,7 +41,8 @@ local mock_device = test.mock_device.build_test_matter_device({ cluster_id = clusters.DoorLock.ID, cluster_type = "SERVER", cluster_revision = 1, - feature_map = 0x0001, --u32 bitmap + feature_map = clusters.DoorLock.types.Feature.PIN_CREDENTIAL | + clusters.DoorLock.types.Feature.USER } }, device_types = { @@ -52,6 +53,13 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lockAlarm.alarm.clear({state_change = true})) + ) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device) subscribe_request:merge(clusters.DoorLock.attributes.OperatingMode:subscribe(mock_device)) subscribe_request:merge(clusters.DoorLock.attributes.NumberOfTotalUsersSupported:subscribe(mock_device)) @@ -63,7 +71,12 @@ local function test_init() subscribe_request:merge(clusters.DoorLock.events.DoorLockAlarm:subscribe(mock_device)) subscribe_request:merge(clusters.DoorLock.events.LockUserChange:subscribe(mock_device)) test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) + ) + mock_device:expect_metadata_update({ profile = "lock-user-pin" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua b/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua index 3c95216dc5..41ecbd612e 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_bridged_matter_lock.lua @@ -15,6 +15,7 @@ local test = require "integration_test" test.add_package_capability("lockAlarm.yml") local t_utils = require "integration_test.utils" +local capabilities = require "st.capabilities" local clusters = require "st.matter.clusters" local mock_device_record = { @@ -41,58 +42,75 @@ local mock_device_record = { local mock_device = test.mock_device.build_test_matter_device(mock_device_record) local mock_device_record_level = { - profile = t_utils.get_profile_definition("lock-nocodes-notamper-batteryLevel.yml"), - manufacturer_info = {vendor_id = 0x129F, product_id = 0x0001}, -- Level Lock Plus - endpoints = { - { - endpoint_id = 2, - clusters = { - {cluster_id = clusters.Basic.ID, cluster_type = "SERVER"}, - }, - device_types = { - device_type_id = 0x0016, device_type_revision = 1, -- RootNode - } + profile = t_utils.get_profile_definition("lock-nocodes-notamper-batteryLevel.yml"), + manufacturer_info = {vendor_id = 0x129F, product_id = 0x0001}, -- Level Lock Plus + endpoints = { + { + endpoint_id = 2, + clusters = { + {cluster_id = clusters.Basic.ID, cluster_type = "SERVER"}, }, - { - endpoint_id = 10, - clusters = { - {cluster_id = clusters.DoorLock.ID, cluster_type = "SERVER", feature_map = 0x0000}, - }, + device_types = { + device_type_id = 0x0016, device_type_revision = 1, -- RootNode + } + }, + { + endpoint_id = 10, + clusters = { + {cluster_id = clusters.DoorLock.ID, cluster_type = "SERVER", feature_map = 0x0000}, }, }, + }, } local mock_device_level = test.mock_device.build_test_matter_device(mock_device_record_level) local function test_init() - local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device) - subscribe_request:merge(clusters.DoorLock.events.DoorLockAlarm:subscribe(mock_device)) - subscribe_request:merge(clusters.DoorLock.events.LockOperation:subscribe(mock_device)) - subscribe_request:merge(clusters.DoorLock.events.LockUserChange:subscribe(mock_device)) - test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.tamperAlert.tamper.clear()) + ) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lockCodes.lockCodes("[]", {visibility = {displayed = false}})) + ) + local req = clusters.DoorLock.attributes.MaxPINCodeLength:read(mock_device, 10) + req:merge(clusters.DoorLock.attributes.MinPINCodeLength:read(mock_device, 10)) + req:merge(clusters.DoorLock.attributes.NumberOfPINUsersSupported:read(mock_device, 10)) + test.socket.matter:__expect_send({mock_device.id, req}) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device) + subscribe_request:merge(clusters.DoorLock.events.DoorLockAlarm:subscribe(mock_device)) + subscribe_request:merge(clusters.DoorLock.events.LockOperation:subscribe(mock_device)) + subscribe_request:merge(clusters.DoorLock.events.LockUserChange:subscribe(mock_device)) + test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) + test.mock_device.add_test_device(mock_device) + - local subscribe_request_level = clusters.DoorLock.attributes.LockState:subscribe(mock_device_level) - test.socket["matter"]:__expect_send({mock_device_level.id, subscribe_request_level}) - test.mock_device.add_test_device(mock_device_level) + test.mock_device.add_test_device(mock_device_level) + test.socket.device_lifecycle:__queue_receive({ mock_device_level.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_level.id, "init" }) + local subscribe_request_level = clusters.DoorLock.attributes.LockState:subscribe(mock_device_level) + test.socket["matter"]:__expect_send({mock_device_level.id, subscribe_request_level}) end test.set_test_init_function(test_init) test.register_coroutine_test( - "doConfigure lifecycle event for base-lock-nobattery", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) - mock_device:expect_metadata_update({ profile = "base-lock-nobattery" }) - mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - end + "doConfigure lifecycle event for base-lock-nobattery", + function() + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ profile = "base-lock-nobattery" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + end ) test.register_coroutine_test( - "doConfigure lifecycle event for Level Lock Plus profile", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device_level.id, "doConfigure" }) - mock_device_level:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - end + "doConfigure lifecycle event for Level Lock Plus profile", + function() + test.socket.device_lifecycle:__queue_receive({ mock_device_level.id, "doConfigure" }) + mock_device_level:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + end ) test.run_registered_tests() diff --git a/drivers/SmartThings/matter-lock/src/test/test_matter_lock.lua b/drivers/SmartThings/matter-lock/src/test/test_matter_lock.lua index 7701d5a90c..0123d43239 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_matter_lock.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_matter_lock.lua @@ -43,12 +43,21 @@ local mock_device_record = { local mock_device = test.mock_device.build_test_matter_device(mock_device_record) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.tamperAlert.tamper.clear()) + ) + mock_device:expect_metadata_update({ profile = "lock-without-codes" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device) subscribe_request:merge(clusters.PowerSource.attributes.BatPercentRemaining:subscribe(mock_device)) subscribe_request:merge(clusters.DoorLock.events.DoorLockAlarm:subscribe(mock_device)) subscribe_request:merge(clusters.DoorLock.events.LockOperation:subscribe(mock_device)) test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_battery.lua b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_battery.lua index 6aff133939..92af7fcabc 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_battery.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_battery.lua @@ -15,6 +15,7 @@ local test = require "integration_test" test.add_package_capability("lockAlarm.yml") local t_utils = require "integration_test.utils" +local capabilities = require "st.capabilities" local clusters = require "st.matter.clusters" local uint32 = require "st.matter.data_types.Uint32" @@ -67,28 +68,41 @@ local mock_device_no_battery_record = { local mock_device_no_battery = test.mock_device.build_test_matter_device(mock_device_no_battery_record) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.tamperAlert.tamper.clear()) + ) + mock_device:expect_metadata_update({ profile = "lock-without-codes" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device) subscribe_request:merge(clusters.PowerSource.attributes.BatPercentRemaining:subscribe(mock_device)) subscribe_request:merge(clusters.DoorLock.events.DoorLockAlarm:subscribe(mock_device)) subscribe_request:merge(clusters.DoorLock.events.LockOperation:subscribe(mock_device)) subscribe_request:merge(clusters.DoorLock.events.LockUserChange:subscribe(mock_device)) test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - local read_attribute_list = clusters.PowerSource.attributes.AttributeList:read() - test.socket.matter:__expect_send({mock_device.id, read_attribute_list}) + test.socket.matter:__expect_send({mock_device.id, clusters.PowerSource.attributes.AttributeList:read()}) end test.set_test_init_function(test_init) local function test_init_no_battery() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_no_battery) + test.socket.device_lifecycle:__queue_receive({ mock_device_no_battery.id, "added" }) + test.socket.capability:__expect_send( + mock_device_no_battery:generate_test_message("main", capabilities.tamperAlert.tamper.clear()) + ) + mock_device_no_battery:expect_metadata_update({ profile = "lock-without-codes-nobattery" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_no_battery.id, "init" }) local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device_no_battery) - subscribe_request:merge(clusters.PowerSource.attributes.BatPercentRemaining:subscribe(mock_device)) + subscribe_request:merge(clusters.PowerSource.attributes.BatPercentRemaining:subscribe(mock_device_no_battery)) subscribe_request:merge(clusters.DoorLock.events.DoorLockAlarm:subscribe(mock_device_no_battery)) subscribe_request:merge(clusters.DoorLock.events.LockOperation:subscribe(mock_device_no_battery)) subscribe_request:merge(clusters.DoorLock.events.LockUserChange:subscribe(mock_device_no_battery)) test.socket["matter"]:__expect_send({mock_device_no_battery.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_no_battery) test.socket.device_lifecycle:__queue_receive({ mock_device_no_battery.id, "doConfigure" }) mock_device_no_battery:expect_metadata_update({ profile = "base-lock-nobattery" }) mock_device_no_battery:expect_metadata_update({ provisioning_state = "PROVISIONED" }) diff --git a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_batteryLevel.lua b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_batteryLevel.lua index 22f9ccd29a..d76556a42d 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_batteryLevel.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_batteryLevel.lua @@ -44,10 +44,15 @@ local mock_device = test.mock_device.build_test_matter_device(mock_device_record local function test_init() - local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device) - subscribe_request:merge(clusters.PowerSource.attributes.BatChargeLevel:subscribe(mock_device)) - test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + local subscribe_request = clusters.DoorLock.attributes.LockState:subscribe(mock_device) + subscribe_request:merge(clusters.PowerSource.attributes.BatChargeLevel:subscribe(mock_device)) + test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) @@ -84,20 +89,20 @@ test.register_message_test( message = mock_device:generate_test_message("main", capabilities.batteryLevel.battery.warning()), }, { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.PowerSource.attributes.BatChargeLevel:build_test_report_data( - mock_device, 10, clusters.PowerSource.types.BatChargeLevelEnum.OK - ), - }, - }, - { - channel = "capability", - direction = "send", - message = mock_device:generate_test_message("main", capabilities.batteryLevel.battery.normal()), + channel = "matter", + direction = "receive", + message = { + mock_device.id, + clusters.PowerSource.attributes.BatChargeLevel:build_test_report_data( + mock_device, 10, clusters.PowerSource.types.BatChargeLevelEnum.OK + ), }, + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.batteryLevel.battery.normal()), + }, } ) diff --git a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_codes.lua b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_codes.lua index c672410296..ad68ffbe3b 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_codes.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_codes.lua @@ -12,20 +12,6 @@ -- See the License for the specific language governing permissions and -- limitations under the License. --- Copyright 2022 SmartThings --- --- Licensed under the Apache License, Version 2.0 (the "License"); --- you may not use this file except in compliance with the License. --- You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- Mock out globals local test = require "integration_test" local capabilities = require "st.capabilities" test.add_package_capability("lockAlarm.yml") @@ -35,6 +21,7 @@ local clusters = require "st.matter.clusters" local DoorLock = clusters.DoorLock local im = require "st.matter.interaction_model" local types = DoorLock.types + local mock_device_record = { profile = t_utils.get_profile_definition("base-lock.yml"), manufacturer_info = {vendor_id = 0xcccc, product_id = 0x1}, @@ -56,7 +43,7 @@ local mock_device_record = { cluster_type = "SERVER", feature_map = 0x0101, -- PIN & USR }, - {cluster_id = clusters.PowerSource.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.PowerSource.ID, cluster_type = "SERVER", feature_map = 0}, }, }, }, @@ -64,13 +51,18 @@ local mock_device_record = { local mock_device = test.mock_device.build_test_matter_device(mock_device_record) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) local subscribe_request = DoorLock.attributes.LockState:subscribe(mock_device) subscribe_request:merge(clusters.PowerSource.attributes.BatPercentRemaining:subscribe(mock_device)) subscribe_request:merge(DoorLock.events.LockUserChange:subscribe(mock_device)) subscribe_request:merge(DoorLock.events.LockOperation:subscribe(mock_device)) subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device)) test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ profile = "base-lock-nobattery" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) @@ -189,11 +181,11 @@ local function init_code_slot(slot_number, name, device) ) local credential = DoorLock.types.DlCredential( - { + { credential_type = DoorLock.types.DlCredentialType.PIN, credential_index = slot_number, } - ) + ) test.socket.matter:__expect_send( { device.id, diff --git a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_cota.lua b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_cota.lua index 6303ec7bcd..f25fe2a19c 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_cota.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_cota.lua @@ -12,20 +12,6 @@ -- See the License for the specific language governing permissions and -- limitations under the License. --- Copyright 2022 SmartThings --- --- Licensed under the Apache License, Version 2.0 (the "License"); --- you may not use this file except in compliance with the License. --- You may obtain a copy of the License at --- --- http://www.apache.org/licenses/LICENSE-2.0 --- --- Unless required by applicable law or agreed to in writing, software --- distributed under the License is distributed on an "AS IS" BASIS, --- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. --- See the License for the specific language governing permissions and --- limitations under the License. --- Mock out globals local test = require "integration_test" local capabilities = require "st.capabilities" test.add_package_capability("lockAlarm.yml") @@ -64,6 +50,9 @@ local mock_device_record = { local mock_device = test.mock_device.build_test_matter_device(mock_device_record) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) local subscribe_request = DoorLock.attributes.LockState:subscribe(mock_device) subscribe_request:merge(clusters.PowerSource.attributes.BatPercentRemaining:subscribe(mock_device)) subscribe_request:merge(DoorLock.events.LockUserChange:subscribe(mock_device)) @@ -71,7 +60,9 @@ local function test_init() subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device)) test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) test.socket.matter:__expect_send({mock_device.id, DoorLock.attributes.RequirePINforRemoteOperation:read(mock_device, 10)}) - test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.socket.matter:__expect_send({mock_device.id, clusters.PowerSource.attributes.AttributeList:read()}) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_unlatch.lua b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_unlatch.lua index 2e390f4d34..92adc6c6fd 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_matter_lock_unlatch.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_matter_lock_unlatch.lua @@ -54,28 +54,28 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lockAlarm.alarm("clear", {state_change = true})) + ) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) local subscribe_request = DoorLock.attributes.LockState:subscribe(mock_device) subscribe_request:merge(DoorLock.attributes.OperatingMode:subscribe(mock_device)) subscribe_request:merge(DoorLock.events.LockOperation:subscribe(mock_device)) subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device)) test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ profile = "lock-unlatch" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}})) + ) end test.set_test_init_function(test_init) -test.register_coroutine_test( - "Assert profile applied over doConfigure", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) - mock_device:expect_metadata_update({ profile = "lock-unlatch" }) - mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}})) - ) - end -) - test.register_coroutine_test( "Handle received OperatingMode(Normal, Vacation) from Matter device.", function() diff --git a/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock.lua b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock.lua index 9659c9484d..442593b188 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock.lua @@ -55,6 +55,13 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lockAlarm.alarm.clear({state_change = true})) + ) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) local subscribe_request = DoorLock.attributes.LockState:subscribe(mock_device) subscribe_request:merge(DoorLock.attributes.OperatingMode:subscribe(mock_device)) subscribe_request:merge(DoorLock.attributes.NumberOfTotalUsersSupported:subscribe(mock_device)) @@ -68,23 +75,16 @@ local function test_init() subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device)) subscribe_request:merge(DoorLock.events.LockUserChange:subscribe(mock_device)) test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ profile = "lock-user-pin" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) + ) end test.set_test_init_function(test_init) -test.register_coroutine_test( - "Assert profile applied over doConfigure", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) - mock_device:expect_metadata_update({ profile = "lock-user-pin" }) - mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) - ) - end -) - test.register_coroutine_test( "Handle received OperatingMode(Normal, Vacation) from Matter device.", function() diff --git a/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua index 603f056c06..728f452d79 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua @@ -174,24 +174,43 @@ local mock_device_user_pin_schedule_unlatch = test.mock_device.build_test_matter }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lockAlarm.alarm.clear({state_change = true})) + ) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) local subscribe_request = DoorLock.attributes.LockState:subscribe(mock_device) subscribe_request:merge(DoorLock.attributes.OperatingMode:subscribe(mock_device)) subscribe_request:merge(DoorLock.events.LockOperation:subscribe(mock_device)) subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device)) test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) end local function test_init_unlatch() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_unlatch) + test.socket.device_lifecycle:__queue_receive({ mock_device_unlatch.id, "added" }) + test.socket.capability:__expect_send( + mock_device_unlatch:generate_test_message("main", capabilities.lockAlarm.alarm.clear({state_change = true})) + ) + test.socket.device_lifecycle:__queue_receive({ mock_device_unlatch.id, "init" }) local subscribe_request = DoorLock.attributes.LockState:subscribe(mock_device_unlatch) subscribe_request:merge(DoorLock.attributes.OperatingMode:subscribe(mock_device_unlatch)) subscribe_request:merge(DoorLock.events.LockOperation:subscribe(mock_device_unlatch)) subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device_unlatch)) test.socket["matter"]:__expect_send({mock_device_unlatch.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_unlatch) end local function test_init_user_pin() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_user_pin) + test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin.id, "added" }) + test.socket.capability:__expect_send( + mock_device_user_pin:generate_test_message("main", capabilities.lockAlarm.alarm.clear({state_change = true})) + ) + test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin.id, "init" }) local subscribe_request = DoorLock.attributes.LockState:subscribe(mock_device_user_pin) subscribe_request:merge(DoorLock.attributes.OperatingMode:subscribe(mock_device_user_pin)) subscribe_request:merge(DoorLock.attributes.NumberOfTotalUsersSupported:subscribe(mock_device_user_pin)) @@ -203,10 +222,16 @@ local function test_init_user_pin() subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device_user_pin)) subscribe_request:merge(DoorLock.events.LockUserChange:subscribe(mock_device_user_pin)) test.socket["matter"]:__expect_send({mock_device_user_pin.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_user_pin) end local function test_init_user_pin_schedule_unlatch() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_user_pin_schedule_unlatch) + test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin_schedule_unlatch.id, "added" }) + test.socket.capability:__expect_send( + mock_device_user_pin_schedule_unlatch:generate_test_message("main", capabilities.lockAlarm.alarm.clear({state_change = true})) + ) + test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin_schedule_unlatch.id, "init" }) local subscribe_request = DoorLock.attributes.LockState:subscribe(mock_device_user_pin_schedule_unlatch) subscribe_request:merge(DoorLock.attributes.OperatingMode:subscribe(mock_device_user_pin_schedule_unlatch)) subscribe_request:merge(DoorLock.attributes.NumberOfTotalUsersSupported:subscribe(mock_device_user_pin_schedule_unlatch)) @@ -220,7 +245,6 @@ local function test_init_user_pin_schedule_unlatch() subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device_user_pin_schedule_unlatch)) subscribe_request:merge(DoorLock.events.LockUserChange:subscribe(mock_device_user_pin_schedule_unlatch)) test.socket["matter"]:__expect_send({mock_device_user_pin_schedule_unlatch.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_user_pin_schedule_unlatch) end test.set_test_init_function(test_init) From c09098d6be7ad4edd41850be0cd3c374f6908699 Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Wed, 6 Aug 2025 11:49:54 -0500 Subject: [PATCH 02/12] Update matter-appliance UTs --- .../src/test/test_cook_top.lua | 19 ++- .../src/test/test_dishwasher.lua | 8 +- .../src/test/test_extractor_hood.lua | 16 +-- .../src/test/test_laundry_dryer.lua | 5 +- .../src/test/test_laundry_washer.lua | 6 +- .../src/test/test_matter_appliance_rpc_5.lua | 108 ++++++++++++------ .../src/test/test_microwave_oven.lua | 8 +- .../matter-appliance/src/test/test_oven.lua | 8 +- .../src/test/test_refrigerator.lua | 6 +- 9 files changed, 119 insertions(+), 65 deletions(-) diff --git a/drivers/SmartThings/matter-appliance/src/test/test_cook_top.lua b/drivers/SmartThings/matter-appliance/src/test/test_cook_top.lua index 1fffd78597..9aa45f7951 100644 --- a/drivers/SmartThings/matter-appliance/src/test/test_cook_top.lua +++ b/drivers/SmartThings/matter-appliance/src/test/test_cook_top.lua @@ -70,34 +70,29 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.TemperatureMeasurement.attributes.MeasuredValue, clusters.TemperatureControl.attributes.SelectedTemperatureLevel, clusters.TemperatureControl.attributes.SupportedTemperatureLevels } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device)) end end - test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) + mock_device:expect_metadata_update({ profile = "cook-surface-one-tl-cook-surface-two-tl" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) -test.register_coroutine_test( - "Verify device profile update", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) - mock_device:expect_metadata_update({ profile = "cook-surface-one-tl-cook-surface-two-tl" }) - mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - end -) - test.register_coroutine_test( "Assert component to endpoint map", function() diff --git a/drivers/SmartThings/matter-appliance/src/test/test_dishwasher.lua b/drivers/SmartThings/matter-appliance/src/test/test_dishwasher.lua index f35a88c012..c6923c3de4 100644 --- a/drivers/SmartThings/matter-appliance/src/test/test_dishwasher.lua +++ b/drivers/SmartThings/matter-appliance/src/test/test_dishwasher.lua @@ -57,6 +57,8 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.DishwasherMode.attributes.CurrentMode, @@ -71,7 +73,6 @@ local function test_init() clusters.TemperatureControl.attributes.SelectedTemperatureLevel, clusters.TemperatureControl.attributes.SupportedTemperatureLevels } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then @@ -79,12 +80,13 @@ local function test_init() end end test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) local read_req = clusters.TemperatureControl.attributes.MinTemperature:read() read_req:merge(clusters.TemperatureControl.attributes.MaxTemperature:read()) test.socket.matter:__expect_send({mock_device.id, read_req}) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) mock_device:expect_metadata_update({ profile = "dishwasher-tn-tl" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end diff --git a/drivers/SmartThings/matter-appliance/src/test/test_extractor_hood.lua b/drivers/SmartThings/matter-appliance/src/test/test_extractor_hood.lua index 8d02396191..91339b78ca 100644 --- a/drivers/SmartThings/matter-appliance/src/test/test_extractor_hood.lua +++ b/drivers/SmartThings/matter-appliance/src/test/test_extractor_hood.lua @@ -15,7 +15,6 @@ local test = require "integration_test" local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" - local clusters = require "st.matter.clusters" local mock_device = test.mock_device.build_test_matter_device({ @@ -86,6 +85,8 @@ local mock_device_onoff = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local subscribed_attributes = { [capabilities.fanMode.ID] = { clusters.FanControl.attributes.FanModeSequence, @@ -117,16 +118,16 @@ local function test_init() end end end - - test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) mock_device:expect_metadata_update({ profile = "extractor-hood-hepa-ac-wind" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function test_init_onoff() + test.disable_startup_messages() local cluster_subscribe_list = { clusters.FanControl.attributes.FanModeSequence, clusters.FanControl.attributes.FanMode, @@ -135,15 +136,16 @@ local function test_init_onoff() clusters.FanControl.attributes.WindSetting, clusters.OnOff.attributes.OnOff } - local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) + local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_onoff) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then - subscribe_request:merge(cluster:subscribe(mock_device)) + subscribe_request:merge(cluster:subscribe(mock_device_onoff)) end end - test.socket.matter:__expect_send({mock_device_onoff.id, subscribe_request}) test.mock_device.add_test_device(mock_device_onoff) test.socket.device_lifecycle:__queue_receive({ mock_device_onoff.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_onoff.id, "init" }) + test.socket.matter:__expect_send({mock_device_onoff.id, subscribe_request}) test.socket.device_lifecycle:__queue_receive({ mock_device_onoff.id, "doConfigure"}) mock_device_onoff:expect_metadata_update({ profile = "extractor-hood-wind-light" }) mock_device_onoff:expect_metadata_update({ provisioning_state = "PROVISIONED" }) diff --git a/drivers/SmartThings/matter-appliance/src/test/test_laundry_dryer.lua b/drivers/SmartThings/matter-appliance/src/test/test_laundry_dryer.lua index 7695c51d48..10e0de0f5e 100644 --- a/drivers/SmartThings/matter-appliance/src/test/test_laundry_dryer.lua +++ b/drivers/SmartThings/matter-appliance/src/test/test_laundry_dryer.lua @@ -56,6 +56,8 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.LaundryWasherMode.attributes.CurrentMode, @@ -76,8 +78,9 @@ local function test_init() end end test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) local read_req = clusters.TemperatureControl.attributes.MinTemperature:read() read_req:merge(clusters.TemperatureControl.attributes.MaxTemperature:read()) diff --git a/drivers/SmartThings/matter-appliance/src/test/test_laundry_washer.lua b/drivers/SmartThings/matter-appliance/src/test/test_laundry_washer.lua index 966d1f7d17..0334bf61cb 100644 --- a/drivers/SmartThings/matter-appliance/src/test/test_laundry_washer.lua +++ b/drivers/SmartThings/matter-appliance/src/test/test_laundry_washer.lua @@ -56,6 +56,8 @@ local mock_device_washer = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_washer) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.LaundryWasherMode.attributes.CurrentMode, @@ -69,7 +71,6 @@ local function test_init() clusters.TemperatureControl.attributes.SelectedTemperatureLevel, clusters.TemperatureControl.attributes.SupportedTemperatureLevels } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request_washer = cluster_subscribe_list[1]:subscribe(mock_device_washer) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then @@ -77,8 +78,9 @@ local function test_init() end end test.socket.matter:__expect_send({ mock_device_washer.id, subscribe_request_washer }) - test.mock_device.add_test_device(mock_device_washer) test.socket.device_lifecycle:__queue_receive({ mock_device_washer.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_washer.id, "init" }) + test.socket.matter:__expect_send({ mock_device_washer.id, subscribe_request_washer }) test.socket.device_lifecycle:__queue_receive({ mock_device_washer.id, "doConfigure"}) local read_req = clusters.TemperatureControl.attributes.MinTemperature:read() read_req:merge(clusters.TemperatureControl.attributes.MaxTemperature:read()) diff --git a/drivers/SmartThings/matter-appliance/src/test/test_matter_appliance_rpc_5.lua b/drivers/SmartThings/matter-appliance/src/test/test_matter_appliance_rpc_5.lua index 57ec49cfbf..8f9a8c81d8 100644 --- a/drivers/SmartThings/matter-appliance/src/test/test_matter_appliance_rpc_5.lua +++ b/drivers/SmartThings/matter-appliance/src/test/test_matter_appliance_rpc_5.lua @@ -268,6 +268,8 @@ local mock_device_refrigerator = test.mock_device.build_test_matter_device({ }) local function test_init_dishwasher() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_dishwasher) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.DishwasherMode.attributes.CurrentMode, @@ -282,7 +284,6 @@ local function test_init_dishwasher() clusters.TemperatureControl.attributes.SelectedTemperatureLevel, clusters.TemperatureControl.attributes.SupportedTemperatureLevels } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_dishwasher) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then @@ -290,11 +291,21 @@ local function test_init_dishwasher() end end test.socket.matter:__expect_send({ mock_device_dishwasher.id, subscribe_request }) - test.mock_device.add_test_device(mock_device_dishwasher) test.socket.device_lifecycle:__queue_receive({ mock_device_dishwasher.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_dishwasher.id, "init" }) + test.socket.matter:__expect_send({ mock_device_dishwasher.id, subscribe_request }) + local read_req = clusters.TemperatureControl.attributes.MinTemperature:read() + read_req:merge(clusters.TemperatureControl.attributes.MaxTemperature:read()) + test.socket.matter:__expect_send({mock_device_dishwasher.id, read_req}) + test.socket.device_lifecycle:__queue_receive({ mock_device_dishwasher.id, "doConfigure"}) + mock_device_dishwasher:expect_metadata_update({ profile = "dishwasher-tn-tl" }) + mock_device_dishwasher:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end -local function test_init_washer_dryer() +local function test_init_dryer() + test.disable_startup_messages() + test.socket.matter:__set_channel_ordering("relaxed") + test.mock_device.add_test_device(mock_device_dryer) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.LaundryWasherMode.attributes.CurrentMode, @@ -308,29 +319,62 @@ local function test_init_washer_dryer() clusters.TemperatureControl.attributes.SelectedTemperatureLevel, clusters.TemperatureControl.attributes.SupportedTemperatureLevels } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_dryer) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device_dryer)) end end - local subscribe_request_washer = cluster_subscribe_list[1]:subscribe(mock_device_washer) + test.socket.matter:__expect_send({ mock_device_dryer.id, subscribe_request }) + test.socket.device_lifecycle:__queue_receive({ mock_device_dryer.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_dryer.id, "init" }) + test.socket.matter:__expect_send({ mock_device_dryer.id, subscribe_request }) + test.socket.device_lifecycle:__queue_receive({ mock_device_dryer.id, "doConfigure"}) + local read_req = clusters.TemperatureControl.attributes.MinTemperature:read() + read_req:merge(clusters.TemperatureControl.attributes.MaxTemperature:read()) + test.socket.matter:__expect_send({mock_device_dryer.id, read_req}) + mock_device_dryer:expect_metadata_update({ profile = "laundry-dryer-tn-tl" }) + mock_device_dryer:expect_metadata_update({ provisioning_state = "PROVISIONED" }) +end + +local function test_init_washer() + test.disable_startup_messages() + test.socket.matter:__set_channel_ordering("relaxed") + test.mock_device.add_test_device(mock_device_washer) + local cluster_subscribe_list = { + clusters.OnOff.attributes.OnOff, + clusters.LaundryWasherMode.attributes.CurrentMode, + clusters.LaundryWasherMode.attributes.SupportedModes, + clusters.OperationalState.attributes.OperationalState, + clusters.OperationalState.attributes.OperationalError, + clusters.OperationalState.attributes.AcceptedCommandList, + clusters.TemperatureControl.attributes.TemperatureSetpoint, + clusters.TemperatureControl.attributes.MaxTemperature, + clusters.TemperatureControl.attributes.MinTemperature, + clusters.TemperatureControl.attributes.SelectedTemperatureLevel, + clusters.TemperatureControl.attributes.SupportedTemperatureLevels + } + local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_washer) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then - subscribe_request_washer:merge(cluster:subscribe(mock_device_washer)) + subscribe_request:merge(cluster:subscribe(mock_device_washer)) end end - test.socket.matter:__expect_send({ mock_device_dryer.id, subscribe_request }) - test.socket.matter:__expect_send({ mock_device_washer.id, subscribe_request_washer }) - test.mock_device.add_test_device(mock_device_dryer) - test.mock_device.add_test_device(mock_device_washer) - test.socket.device_lifecycle:__queue_receive({ mock_device_dryer.id, "added" }) + test.socket.matter:__expect_send({ mock_device_washer.id, subscribe_request }) test.socket.device_lifecycle:__queue_receive({ mock_device_washer.id, "added" }) - test.set_rpc_version(5) + test.socket.device_lifecycle:__queue_receive({ mock_device_washer.id, "init" }) + test.socket.matter:__expect_send({ mock_device_washer.id, subscribe_request }) + test.socket.device_lifecycle:__queue_receive({ mock_device_washer.id, "doConfigure"}) + local read_req = clusters.TemperatureControl.attributes.MinTemperature:read() + read_req:merge(clusters.TemperatureControl.attributes.MaxTemperature:read()) + test.socket.matter:__expect_send({mock_device_washer.id, read_req}) + mock_device_washer:expect_metadata_update({ profile = "laundry-washer-tn-tl" }) + mock_device_washer:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function test_init_oven() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_oven) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.TemperatureMeasurement.attributes.MeasuredValue, @@ -342,7 +386,6 @@ local function test_init_oven() clusters.OvenMode.attributes.CurrentMode, clusters.OvenMode.attributes.SupportedModes, } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_oven) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then @@ -350,12 +393,16 @@ local function test_init_oven() end end test.socket.matter:__expect_send({ mock_device_oven.id, subscribe_request }) - test.mock_device.add_test_device(mock_device_oven) test.socket.device_lifecycle:__queue_receive({ mock_device_oven.id, "added" }) - test.set_rpc_version(5) + test.socket.device_lifecycle:__queue_receive({ mock_device_oven.id, "init" }) + test.socket.matter:__expect_send({ mock_device_oven.id, subscribe_request }) + test.socket.device_lifecycle:__queue_receive({ mock_device_oven.id, "doConfigure"}) + mock_device_oven:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function test_init_refrigerator() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_refrigerator) local cluster_subscribe_list = { clusters.RefrigeratorAlarm.attributes.State, clusters.RefrigeratorAndTemperatureControlledCabinetMode.attributes.CurrentMode, @@ -365,7 +412,6 @@ local function test_init_refrigerator() clusters.TemperatureControl.attributes.MinTemperature, clusters.TemperatureMeasurement.attributes.MeasuredValue } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_refrigerator) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then @@ -373,14 +419,19 @@ local function test_init_refrigerator() end end test.socket.matter:__expect_send({ mock_device_refrigerator.id, subscribe_request }) - test.mock_device.add_test_device(mock_device_refrigerator) test.socket.device_lifecycle:__queue_receive({ mock_device_refrigerator.id, "added" }) - test.set_rpc_version(5) + test.socket.device_lifecycle:__queue_receive({ mock_device_refrigerator.id, "init" }) + test.socket.matter:__expect_send({ mock_device_refrigerator.id, subscribe_request }) + test.socket.device_lifecycle:__queue_receive({ mock_device_refrigerator.id, "doConfigure"}) + local read_req = clusters.TemperatureControl.attributes.MinTemperature:read() + read_req:merge(clusters.TemperatureControl.attributes.MaxTemperature:read()) + test.socket.matter:__expect_send({mock_device_refrigerator.id, read_req}) + mock_device_refrigerator:expect_metadata_update({ profile = "refrigerator-freezer-tn-tl" }) + mock_device_refrigerator:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for dishwasher", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_dishwasher.id, @@ -420,7 +471,6 @@ test.register_coroutine_test( test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for dishwasher, temp bounds out of range and temp setpoint converted from F to C", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_dishwasher.id, @@ -460,7 +510,6 @@ test.register_coroutine_test( test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for laundry washer", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_washer.id, @@ -495,12 +544,11 @@ test.register_coroutine_test( { mock_device_washer.id, clusters.TemperatureControl.commands.SetTemperature(mock_device_washer, washer_ep, 28 * 100, nil) } ) end, - { test_init = test_init_washer_dryer } + { test_init = test_init_washer } ) test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for laundry washer, temp bounds out of range and temp setpoint converted from F to C", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_washer.id, @@ -535,12 +583,11 @@ test.register_coroutine_test( { mock_device_washer.id, clusters.TemperatureControl.commands.SetTemperature(mock_device_washer, washer_ep, 50 * 100, nil) } ) end, - { test_init = test_init_washer_dryer } + { test_init = test_init_washer } ) test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for laundry dryer", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_dryer.id, @@ -575,12 +622,11 @@ test.register_coroutine_test( { mock_device_dryer.id, clusters.TemperatureControl.commands.SetTemperature(mock_device_dryer, dryer_ep, 40 * 100, nil) } ) end, - { test_init = test_init_washer_dryer } + { test_init = test_init_dryer } ) test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for laundry dryer, temp bounds out of range and temp setpoint converted from F to C", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_dryer.id, @@ -615,12 +661,11 @@ test.register_coroutine_test( { mock_device_dryer.id, clusters.TemperatureControl.commands.SetTemperature(mock_device_dryer, dryer_ep, 40 * 100, nil) } ) end, - { test_init = test_init_washer_dryer } + { test_init = test_init_dryer } ) test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for oven", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_oven.id, @@ -660,7 +705,6 @@ test.register_coroutine_test( test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for oven, temp bounds out of range and temp setpoint converted from F to C", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_oven.id, @@ -700,7 +744,6 @@ test.register_coroutine_test( test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for refrigerator endpoint", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_refrigerator.id, @@ -740,7 +783,6 @@ test.register_coroutine_test( test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for refrigerator endpoint, temp bounds out of range and temp setpoint converted from F to C", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_refrigerator.id, @@ -780,7 +822,6 @@ test.register_coroutine_test( test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for freezer endpoint", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_refrigerator.id, @@ -820,7 +861,6 @@ test.register_coroutine_test( test.register_coroutine_test( "temperatureSetpoint command should send appropriate commands for freezer endpoint, temp bounds out of range and temp setpoint converted from F to C", function() - test.socket.capability:__set_channel_ordering("relaxed") test.socket.matter:__queue_receive( { mock_device_refrigerator.id, diff --git a/drivers/SmartThings/matter-appliance/src/test/test_microwave_oven.lua b/drivers/SmartThings/matter-appliance/src/test/test_microwave_oven.lua index 3d7008b036..3c2e1fbc51 100644 --- a/drivers/SmartThings/matter-appliance/src/test/test_microwave_oven.lua +++ b/drivers/SmartThings/matter-appliance/src/test/test_microwave_oven.lua @@ -54,6 +54,8 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.OperationalState.attributes.OperationalState, clusters.OperationalState.attributes.OperationalError, @@ -63,17 +65,19 @@ local function test_init() clusters.MicrowaveOvenControl.attributes.MaxCookTime, clusters.MicrowaveOvenControl.attributes.CookTime } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device)) end end + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) test.socket.matter:__expect_send({ mock_device.id, clusters.MicrowaveOvenControl.attributes.MaxCookTime:read( mock_device, APPLICATION_ENDPOINT) }) - test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function init_supported_microwave_oven_modes() diff --git a/drivers/SmartThings/matter-appliance/src/test/test_oven.lua b/drivers/SmartThings/matter-appliance/src/test/test_oven.lua index 6af4556c6a..58c38e078c 100644 --- a/drivers/SmartThings/matter-appliance/src/test/test_oven.lua +++ b/drivers/SmartThings/matter-appliance/src/test/test_oven.lua @@ -112,6 +112,8 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.TemperatureMeasurement.attributes.MeasuredValue, @@ -123,7 +125,6 @@ local function test_init() clusters.OvenMode.attributes.CurrentMode, clusters.OvenMode.attributes.SupportedModes, } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then @@ -131,8 +132,11 @@ local function test_init() end end test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-appliance/src/test/test_refrigerator.lua b/drivers/SmartThings/matter-appliance/src/test/test_refrigerator.lua index 1ef5734d0f..3dc19750f3 100644 --- a/drivers/SmartThings/matter-appliance/src/test/test_refrigerator.lua +++ b/drivers/SmartThings/matter-appliance/src/test/test_refrigerator.lua @@ -67,6 +67,8 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.RefrigeratorAlarm.attributes.State, clusters.RefrigeratorAndTemperatureControlledCabinetMode.attributes.CurrentMode, @@ -76,7 +78,6 @@ local function test_init() clusters.TemperatureControl.attributes.MinTemperature, clusters.TemperatureMeasurement.attributes.MeasuredValue } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then @@ -84,8 +85,9 @@ local function test_init() end end test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) local read_req = clusters.TemperatureControl.attributes.MinTemperature:read() read_req:merge(clusters.TemperatureControl.attributes.MaxTemperature:read()) From 0697c51f240dd78146e8132d0c4e855b328b3e32 Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Wed, 6 Aug 2025 13:06:41 -0500 Subject: [PATCH 03/12] Updating UTs for matter-energy --- .../matter-energy/src/test/test_battery_storage.lua | 9 ++++++--- .../SmartThings/matter-energy/src/test/test_evse.lua | 11 ++++++++--- .../matter-energy/src/test/test_evse_energy_meas.lua | 11 ++++++++--- .../matter-energy/src/test/test_solar_power.lua | 10 +++++++--- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/drivers/SmartThings/matter-energy/src/test/test_battery_storage.lua b/drivers/SmartThings/matter-energy/src/test/test_battery_storage.lua index 453858d7c2..27f8585185 100644 --- a/drivers/SmartThings/matter-energy/src/test/test_battery_storage.lua +++ b/drivers/SmartThings/matter-energy/src/test/test_battery_storage.lua @@ -62,6 +62,8 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.ElectricalPowerMeasurement.attributes.ActivePower, clusters.ElectricalEnergyMeasurement.attributes.PeriodicEnergyExported, @@ -69,16 +71,15 @@ local function test_init() clusters.PowerSource.attributes.BatPercentRemaining, clusters.PowerSource.attributes.BatChargeState } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device)) end end - test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) test.socket.matter:__expect_send({ mock_device.id, @@ -90,6 +91,8 @@ local function test_init() clusters.ElectricalEnergyMeasurement.attributes.CumulativeEnergyExported:read(mock_device, BATTERY_STORAGE_EP) }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-energy/src/test/test_evse.lua b/drivers/SmartThings/matter-energy/src/test/test_evse.lua index ad9db31150..6add71bde9 100644 --- a/drivers/SmartThings/matter-energy/src/test/test_evse.lua +++ b/drivers/SmartThings/matter-energy/src/test/test_evse.lua @@ -75,6 +75,8 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.EnergyEvse.attributes.State, clusters.EnergyEvse.attributes.SupplyState, @@ -90,19 +92,22 @@ local function test_init() clusters.DeviceEnergyManagementMode.attributes.CurrentMode, clusters.DeviceEnergyManagementMode.attributes.SupportedModes, } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device)) end end - test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.evseChargingSession.targetEndTime("1970-01-01T00:00:00Z"))) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) + mock_device:expect_metadata_update({ profile = "evse-power-meas" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-energy/src/test/test_evse_energy_meas.lua b/drivers/SmartThings/matter-energy/src/test/test_evse_energy_meas.lua index 91332241b7..84c431ffe2 100644 --- a/drivers/SmartThings/matter-energy/src/test/test_evse_energy_meas.lua +++ b/drivers/SmartThings/matter-energy/src/test/test_evse_energy_meas.lua @@ -75,6 +75,8 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.EnergyEvse.attributes.State, clusters.EnergyEvse.attributes.SupplyState, @@ -89,16 +91,15 @@ local function test_init() clusters.ElectricalEnergyMeasurement.attributes.PeriodicEnergyImported, clusters.ElectricalEnergyMeasurement.attributes.PeriodicEnergyExported, } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device)) end end - test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) test.socket.matter:__expect_send({ mock_device.id, @@ -107,6 +108,10 @@ local function test_init() test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.evseChargingSession.targetEndTime("1970-01-01T00:00:00Z"))) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) + mock_device:expect_metadata_update({ profile = "evse-energy-meas" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-energy/src/test/test_solar_power.lua b/drivers/SmartThings/matter-energy/src/test/test_solar_power.lua index 049b364d6f..87fde17a23 100644 --- a/drivers/SmartThings/matter-energy/src/test/test_solar_power.lua +++ b/drivers/SmartThings/matter-energy/src/test/test_solar_power.lua @@ -71,21 +71,22 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.ElectricalPowerMeasurement.attributes.ActivePower, clusters.ElectricalEnergyMeasurement.attributes.PeriodicEnergyExported, clusters.ElectricalEnergyMeasurement.attributes.PeriodicEnergyImported } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device)) end end - test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({ mock_device.id, subscribe_request }) local read_req = clusters.ElectricalEnergyMeasurement.attributes.CumulativeEnergyExported:read(mock_device, SOLAR_POWER_EP_ONE) read_req:merge(clusters.ElectricalEnergyMeasurement.attributes.CumulativeEnergyExported:read(mock_device, SOLAR_POWER_EP_TWO)) @@ -93,6 +94,9 @@ local function test_init() mock_device.id, read_req }) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) From f6314525309fdc293474b55b3827c7ca67f1e8c0 Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Wed, 6 Aug 2025 13:17:37 -0500 Subject: [PATCH 04/12] Updating UTs for matter-media --- .../src/test/test_matter_media_speaker.lua | 8 +- .../test/test_matter_media_video_player.lua | 90 +++++++++++++++++-- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/drivers/SmartThings/matter-media/src/test/test_matter_media_speaker.lua b/drivers/SmartThings/matter-media/src/test/test_matter_media_speaker.lua index 5444652b29..03a1ddb8da 100644 --- a/drivers/SmartThings/matter-media/src/test/test_matter_media_speaker.lua +++ b/drivers/SmartThings/matter-media/src/test/test_matter_media_speaker.lua @@ -51,19 +51,23 @@ local mock_device = test.mock_device.build_test_matter_device({ local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.LevelControl.attributes.CurrentLevel } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device)) end end + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-media/src/test/test_matter_media_video_player.lua b/drivers/SmartThings/matter-media/src/test/test_matter_media_video_player.lua index 52cde71ed3..1c82b5dd6f 100644 --- a/drivers/SmartThings/matter-media/src/test/test_matter_media_video_player.lua +++ b/drivers/SmartThings/matter-media/src/test/test_matter_media_video_player.lua @@ -86,22 +86,62 @@ local mock_device_variable_speed = test.mock_device.build_test_matter_device({ local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.MediaPlayback.attributes.CurrentState } - test.socket.matter:__set_channel_ordering("relaxed") local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do - print(i) if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device)) end - print(subscribe_request) end + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + + test.socket.capability:__expect_send( + mock_device:generate_test_message( + "main", capabilities.mediaPlayback.supportedPlaybackCommands({"play", "pause", "stop"}) + ) + ) + test.socket.capability:__expect_send( + mock_device:generate_test_message( + "main", capabilities.mediaTrackControl.supportedTrackControlCommands({"previousTrack", "nextTrack"}) + ) + ) + test.socket.capability:__expect_send( + mock_device:generate_test_message( + "main", capabilities.keypadInput.supportedKeyCodes({ + "UP", + "DOWN", + "LEFT", + "RIGHT", + "SELECT", + "BACK", + "EXIT", + "MENU", + "SETTINGS", + "HOME", + "NUMBER0", + "NUMBER1", + "NUMBER2", + "NUMBER3", + "NUMBER4", + "NUMBER5", + "NUMBER6", + "NUMBER7", + "NUMBER8", + "NUMBER9" + }) + ) + ) + + test.mock_device.add_test_device(mock_device_variable_speed) subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_variable_speed) for i, cluster in ipairs(cluster_subscribe_list) do print(i) @@ -110,8 +150,48 @@ local function test_init() end print(subscribe_request) end + test.socket.device_lifecycle:__queue_receive({ mock_device_variable_speed.id, "init" }) test.socket.matter:__expect_send({mock_device_variable_speed.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_variable_speed) + + test.socket.device_lifecycle:__queue_receive({ mock_device_variable_speed.id, "doConfigure" }) + mock_device_variable_speed:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + + test.socket.capability:__expect_send( + mock_device_variable_speed:generate_test_message( + "main", capabilities.mediaPlayback.supportedPlaybackCommands({"play", "pause", "stop", "rewind", "fastForward"}) + ) + ) + test.socket.capability:__expect_send( + mock_device_variable_speed:generate_test_message( + "main", capabilities.mediaTrackControl.supportedTrackControlCommands({"previousTrack", "nextTrack"}) + ) + ) + test.socket.capability:__expect_send( + mock_device_variable_speed:generate_test_message( + "main", capabilities.keypadInput.supportedKeyCodes({ + "UP", + "DOWN", + "LEFT", + "RIGHT", + "SELECT", + "BACK", + "EXIT", + "MENU", + "SETTINGS", + "HOME", + "NUMBER0", + "NUMBER1", + "NUMBER2", + "NUMBER3", + "NUMBER4", + "NUMBER5", + "NUMBER6", + "NUMBER7", + "NUMBER8", + "NUMBER9" + }) + ) + ) end test.set_test_init_function(test_init) From 3e50b1fcd1e69d72dcb4f583b4f758b44fd9cc31 Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Wed, 6 Aug 2025 13:43:01 -0500 Subject: [PATCH 05/12] Update UTs for matter-rvc This commit also includes a small fix for LuaLibs v15+. --- drivers/SmartThings/matter-rvc/src/init.lua | 9 +++------ .../matter-rvc/src/test/test_matter_rvc.lua | 11 +++++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/SmartThings/matter-rvc/src/init.lua b/drivers/SmartThings/matter-rvc/src/init.lua index c8fae5aaad..4165535fef 100644 --- a/drivers/SmartThings/matter-rvc/src/init.lua +++ b/drivers/SmartThings/matter-rvc/src/init.lua @@ -16,9 +16,6 @@ local MatterDriver = require "st.matter.driver" local capabilities = require "st.capabilities" local clusters = require "st.matter.clusters" -local area_type = require "Global.types.AreaTypeTag" -local landmark = require "Global.types.LandmarkTag" - local embedded_cluster_utils = require "embedded_cluster_utils" -- Include driver-side definitions when lua libs api version is < 10 @@ -512,15 +509,15 @@ local function rvc_service_area_supported_areas_handler(driver, device, ib, resp if location_info.location_name.value ~= "" then area_name = location_info.location_name.value elseif location_info.floor_number.value ~= nil and location_info.area_type.value ~= nil then - area_name = location_info.floor_number.value .. "F " .. upper_to_camelcase(string.gsub(area_type.pretty_print(location_info.area_type),"AreaTypeTag: ","")) + area_name = location_info.floor_number.value .. "F " .. upper_to_camelcase(string.gsub(clusters.Global.types.AreaTypeTag.pretty_print(location_info.area_type),"AreaTypeTag: ","")) elseif location_info.floor_number.value ~= nil then area_name = location_info.floor_number.value .. "F" elseif location_info.area_type.value ~= nil then - area_name = upper_to_camelcase(string.gsub(area_type.pretty_print(location_info.area_type),"AreaTypeTag: ","")) + area_name = upper_to_camelcase(string.gsub(clusters.Global.types.AreaTypeTag.pretty_print(location_info.area_type),"AreaTypeTag: ","")) end end if area_name == "" then - area_name = upper_to_camelcase(string.gsub(landmark.pretty_print(landmark_info.landmark_tag),"LandmarkTag: ","")) + area_name = upper_to_camelcase(string.gsub(clusters.Global.types.LandmarkTag.pretty_print(landmark_info.landmark_tag),"LandmarkTag: ","")) end table.insert(supported_areas, {["areaId"] = area_id, ["areaName"] = area_name}) end diff --git a/drivers/SmartThings/matter-rvc/src/test/test_matter_rvc.lua b/drivers/SmartThings/matter-rvc/src/test/test_matter_rvc.lua index 1fb2afb752..5bed191802 100644 --- a/drivers/SmartThings/matter-rvc/src/test/test_matter_rvc.lua +++ b/drivers/SmartThings/matter-rvc/src/test/test_matter_rvc.lua @@ -64,6 +64,8 @@ local mock_device = test.mock_device.build_test_matter_device({ }) local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local subscribed_attributes = { [capabilities.mode.ID] = { clusters.RvcRunMode.attributes.SupportedModes, @@ -90,9 +92,14 @@ local function test_init() end end end - test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure"}) + mock_device:expect_metadata_update({ profile = "rvc-clean-mode-service-area" }) + test.socket.matter:__expect_send({mock_device.id, clusters.RvcOperationalState.attributes.AcceptedCommandList:read()}) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) From e9b6906f8490694d486077807b7277cbe502a93d Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Wed, 6 Aug 2025 14:19:15 -0500 Subject: [PATCH 06/12] Updating UTs for matter-sensor --- .../src/test/test_matter_flow_sensor.lua | 3 +-- .../test/test_matter_freeze_leak_sensor.lua | 18 +++++++---------- .../src/test/test_matter_pressure_sensor.lua | 12 +++-------- .../src/test/test_matter_rain_sensor.lua | 18 +++++++---------- .../src/test/test_matter_sensor.lua | 3 --- .../src/test/test_matter_sensor_battery.lua | 9 +++++---- .../test/test_matter_sensor_featuremap.lua | 20 +++++++++---------- .../src/test/test_matter_sensor_rpc.lua | 2 -- .../src/test/test_matter_smoke_co_alarm.lua | 2 +- .../test_matter_smoke_co_alarm_battery.lua | 4 +++- 10 files changed, 37 insertions(+), 54 deletions(-) diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_flow_sensor.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_flow_sensor.lua index 880ed55c89..f6312dfc8f 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_flow_sensor.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_flow_sensor.lua @@ -53,6 +53,7 @@ local subscribed_attributes = { } local function test_init() + test.mock_device.add_test_device(mock_device) local subscribe_request = subscribed_attributes[1]:subscribe(mock_device) for i, cluster in ipairs(subscribed_attributes) do if i > 1 then @@ -60,8 +61,6 @@ local function test_init() end end test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_freeze_leak_sensor.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_freeze_leak_sensor.lua index 46bc88a771..a7309839df 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_freeze_leak_sensor.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_freeze_leak_sensor.lua @@ -63,29 +63,25 @@ local subscribed_attributes = { } local function test_init_freeze_leak() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_freeze_leak) local subscribe_request = subscribed_attributes[1]:subscribe(mock_device_freeze_leak) for i, cluster in ipairs(subscribed_attributes) do if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device_freeze_leak)) end end + test.socket.device_lifecycle:__queue_receive({ mock_device_freeze_leak.id, "init" }) test.socket.matter:__expect_send({mock_device_freeze_leak.id, clusters.BooleanStateConfiguration.attributes.SupportedSensitivityLevels:read(mock_device_freeze_leak, 1)}) test.socket.matter:__expect_send({mock_device_freeze_leak.id, clusters.BooleanStateConfiguration.attributes.SupportedSensitivityLevels:read(mock_device_freeze_leak, 2)}) test.socket.matter:__expect_send({mock_device_freeze_leak.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_freeze_leak) + + test.socket.device_lifecycle:__queue_receive({ mock_device_freeze_leak.id, "doConfigure" }) + mock_device_freeze_leak:expect_metadata_update({ profile = "freeze-leak-fault-freezeSensitivity-leakSensitivity" }) + mock_device_freeze_leak:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init_freeze_leak) -test.register_coroutine_test( - "Test profile change on init for Freeze and Leak combined device type", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device_freeze_leak.id, "doConfigure" }) - mock_device_freeze_leak:expect_metadata_update({ profile = "freeze-leak-fault-freezeSensitivity-leakSensitivity" }) - mock_device_freeze_leak:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - end, - { test_init = test_init_freeze_leak } -) - test.register_message_test( "Boolean state freeze detection reports should generate correct messages", { diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_pressure_sensor.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_pressure_sensor.lua index 27d3b90842..68134ed677 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_pressure_sensor.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_pressure_sensor.lua @@ -49,17 +49,11 @@ local mock_device = test.mock_device.build_test_matter_device({ endpoints = matter_endpoints }) -local function subscribe_on_init(dev) - local subscribe_request = PressureMeasurementCluster.attributes.MeasuredValue:subscribe(mock_device) - subscribe_request:merge(clusters.PowerSource.attributes.BatPercentRemaining:subscribe(mock_device)) - return subscribe_request -end - local function test_init() - test.socket.matter:__expect_send({mock_device.id, subscribe_on_init(mock_device)}) test.mock_device.add_test_device(mock_device) - -- don't check the battery for this device since we are just testing the "pressure-battery" profile specifically - mock_device:set_field("__battery_checked", 1, {persist = true}) + local subscribe_request = PressureMeasurementCluster.attributes.MeasuredValue:subscribe(mock_device) + subscribe_request:merge(clusters.PowerSource.attributes.BatPercentRemaining:subscribe(mock_device)) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_rain_sensor.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_rain_sensor.lua index b23f72de53..835de811ae 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_rain_sensor.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_rain_sensor.lua @@ -55,28 +55,24 @@ local subscribed_attributes = { } local function test_init_rain() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_rain) local subscribe_request = subscribed_attributes[1]:subscribe(mock_device_rain) for i, cluster in ipairs(subscribed_attributes) do if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device_rain)) end end + test.socket.device_lifecycle:__queue_receive({ mock_device_rain.id, "init" }) test.socket.matter:__expect_send({mock_device_rain.id, clusters.BooleanStateConfiguration.attributes.SupportedSensitivityLevels:read(mock_device_rain, 1)}) test.socket.matter:__expect_send({mock_device_rain.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_rain) + + test.socket.device_lifecycle:__queue_receive({ mock_device_rain.id, "doConfigure" }) + mock_device_rain:expect_metadata_update({ profile = "rain-fault-rainSensitivity" }) + mock_device_rain:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init_rain) -test.register_coroutine_test( - "Test profile change on init for Freeze and Leak combined device type", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device_rain.id, "doConfigure" }) - mock_device_rain:expect_metadata_update({ profile = "rain-fault-rainSensitivity" }) - mock_device_rain:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - end, - { test_init = test_init_rain } -) - test.register_message_test( "Boolean state rain detection reports should generate correct messages", { diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor.lua index 9a607aaf57..5c25bf9c06 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor.lua @@ -78,9 +78,6 @@ end local function test_init() test.socket.matter:__expect_send({mock_device.id, subscribe_on_init(mock_device)}) test.mock_device.add_test_device(mock_device) - -- don't check the battery for this device because we are using the catch-all "sensor.yml" profile just for testing - mock_device:set_field("__battery_checked", 1, {persist = true}) - test.set_rpc_version(5) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_battery.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_battery.lua index 48b72e232c..72484efffe 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_battery.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_battery.lua @@ -56,20 +56,21 @@ local cluster_subscribe_list_humidity_battery = { } local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_humidity_battery) local subscribe_request_humidity_battery = cluster_subscribe_list_humidity_battery[1]:subscribe(mock_device_humidity_battery) for i, cluster in ipairs(cluster_subscribe_list_humidity_battery) do if i > 1 then subscribe_request_humidity_battery:merge(cluster:subscribe(mock_device_humidity_battery)) end end - test.socket.matter:__expect_send({mock_device_humidity_battery.id, subscribe_request_humidity_battery}) - test.mock_device.add_test_device(mock_device_humidity_battery) - test.socket.device_lifecycle:__queue_receive({ mock_device_humidity_battery.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_humidity_battery.id, "init" }) + + test.socket.device_lifecycle:__queue_receive({ mock_device_humidity_battery.id, "doConfigure" }) local read_attribute_list = clusters.PowerSource.attributes.AttributeList:read() test.socket.matter:__expect_send({mock_device_humidity_battery.id, read_attribute_list}) - test.socket.device_lifecycle:__queue_receive({ mock_device_humidity_battery.id, "doConfigure" }) mock_device_humidity_battery:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_featuremap.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_featuremap.lua index 91d795d885..ed9718b947 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_featuremap.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_featuremap.lua @@ -125,52 +125,52 @@ local cluster_subscribe_list_temp_humidity = { } local function test_init_humidity_battery() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_humidity_battery) local subscribe_request_humidity_battery = cluster_subscribe_list_humidity_battery[1]:subscribe(mock_device_humidity_battery) for i, cluster in ipairs(cluster_subscribe_list_humidity_battery) do if i > 1 then subscribe_request_humidity_battery:merge(cluster:subscribe(mock_device_humidity_battery)) end end - + test.socket.device_lifecycle:__queue_receive({ mock_device_humidity_battery.id, "init" }) test.socket.matter:__expect_send({mock_device_humidity_battery.id, subscribe_request_humidity_battery}) - test.mock_device.add_test_device(mock_device_humidity_battery) - test.socket.device_lifecycle:__queue_receive({ mock_device_humidity_battery.id, "added" }) test.socket.device_lifecycle:__queue_receive({ mock_device_humidity_battery.id, "doConfigure" }) - mock_device_humidity_battery:expect_metadata_update({ provisioning_state = "PROVISIONED" }) local read_attribute_list = clusters.PowerSource.attributes.AttributeList:read() test.socket.matter:__expect_send({mock_device_humidity_battery.id, read_attribute_list}) + mock_device_humidity_battery:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function test_init_humidity_no_battery() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_humidity_no_battery) local subscribe_request_humidity_no_battery = cluster_subscribe_list_humidity_no_battery[1]:subscribe(mock_device_humidity_no_battery) for i, cluster in ipairs(cluster_subscribe_list_humidity_no_battery) do if i > 1 then subscribe_request_humidity_no_battery:merge(cluster:subscribe(mock_device_humidity_no_battery)) end end - + test.socket.device_lifecycle:__queue_receive({ mock_device_humidity_no_battery.id, "init" }) test.socket.matter:__expect_send({mock_device_humidity_no_battery.id, subscribe_request_humidity_no_battery}) - test.mock_device.add_test_device(mock_device_humidity_no_battery) - test.socket.device_lifecycle:__queue_receive({ mock_device_humidity_no_battery.id, "added" }) test.socket.device_lifecycle:__queue_receive({ mock_device_humidity_no_battery.id, "doConfigure" }) mock_device_humidity_no_battery:expect_metadata_update({ profile = "humidity" }) mock_device_humidity_no_battery:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function test_init_temp_humidity() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device_temp_humidity) local subscribe_request_temp_humidity = cluster_subscribe_list_temp_humidity[1]:subscribe(mock_device_temp_humidity) for i, cluster in ipairs(cluster_subscribe_list_temp_humidity) do if i > 1 then subscribe_request_temp_humidity:merge(cluster:subscribe(mock_device_temp_humidity)) end end - + test.socket.device_lifecycle:__queue_receive({ mock_device_temp_humidity.id, "init" }) test.socket.matter:__expect_send({mock_device_temp_humidity.id, subscribe_request_temp_humidity}) - test.mock_device.add_test_device(mock_device_temp_humidity) - test.socket.device_lifecycle:__queue_receive({ mock_device_temp_humidity.id, "added" }) test.socket.device_lifecycle:__queue_receive({ mock_device_temp_humidity.id, "doConfigure" }) mock_device_temp_humidity:expect_metadata_update({ profile = "temperature-humidity" }) mock_device_temp_humidity:expect_metadata_update({ provisioning_state = "PROVISIONED" }) diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_rpc.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_rpc.lua index d8b38e392a..7eb31d5c29 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_rpc.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_sensor_rpc.lua @@ -57,8 +57,6 @@ end local function test_init() test.socket.matter:__expect_send({mock_device.id, subscribe_on_init(mock_device)}) test.mock_device.add_test_device(mock_device) - -- don't check the battery for this device because we are using the catch-all "sensor.yml" profile just for testing - mock_device:set_field("__battery_checked", 1, {persist = true}) test.set_rpc_version(3) end test.set_test_init_function(test_init) diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_smoke_co_alarm.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_smoke_co_alarm.lua index a7b448f189..86060ab442 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_smoke_co_alarm.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_smoke_co_alarm.lua @@ -75,7 +75,7 @@ local cluster_subscribe_list = { local function test_init() -- The startup messages are enabled, so this device will get an init, - -- and doConfigure (because provisioing_state is TYPED on the device). + -- and doConfigure (because provisioning_state is TYPED on the device). test.mock_device.add_test_device(mock_device) local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_smoke_co_alarm_battery.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_smoke_co_alarm_battery.lua index 9bcdc54e44..b618b3e5d6 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_smoke_co_alarm_battery.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_smoke_co_alarm_battery.lua @@ -72,18 +72,20 @@ local cluster_subscribe_list = { } local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then subscribe_request:merge(cluster:subscribe(mock_device)) end end + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) test.socket.matter:__expect_send({mock_device.id, subscribe_request}) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) local read_attribute_list = clusters.PowerSource.attributes.AttributeList:read() test.socket.matter:__expect_send({mock_device.id, read_attribute_list}) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device) end test.set_test_init_function(test_init) From 6c6264f044a7e928fbeb912751d83981f5ed2155 Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Wed, 6 Aug 2025 15:02:01 -0500 Subject: [PATCH 07/12] Updating UTs for matter-switch --- .../test/test_aqara_climate_sensor_w100.lua | 14 ++-- .../src/test/test_aqara_light_switch_h2.lua | 13 ++- .../src/test/test_electrical_sensor.lua | 10 ++- .../src/test/test_matter_button.lua | 12 ++- .../src/test/test_matter_light_fan.lua | 10 ++- .../src/test/test_matter_multi_button.lua | 5 +- .../test/test_matter_switch_device_types.lua | 81 ++++++++++++++----- .../test_multi_switch_parent_child_lights.lua | 20 +++-- .../test_multi_switch_parent_child_plugs.lua | 19 +++-- .../src/test/test_third_reality_mk1.lua | 12 ++- 10 files changed, 134 insertions(+), 62 deletions(-) diff --git a/drivers/SmartThings/matter-switch/src/test/test_aqara_climate_sensor_w100.lua b/drivers/SmartThings/matter-switch/src/test/test_aqara_climate_sensor_w100.lua index 06c726854a..d2e99b2331 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_aqara_climate_sensor_w100.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_aqara_climate_sensor_w100.lua @@ -18,7 +18,6 @@ local capabilities = require "st.capabilities" local utils = require "st.utils" local dkjson = require "dkjson" local uint32 = require "st.matter.data_types.Uint32" - local clusters = require "st.matter.generated.zap_clusters" local button_attr = capabilities.button.button @@ -121,6 +120,8 @@ local function configure_buttons() end local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(aqara_mock_device) local cluster_subscribe_list = { clusters.PowerSource.server.attributes.BatPercentRemaining, clusters.TemperatureMeasurement.attributes.MeasuredValue, @@ -140,18 +141,17 @@ local function test_init() end end + test.socket.device_lifecycle:__queue_receive({ aqara_mock_device.id, "added" }) + test.socket.matter:__expect_send({aqara_mock_device.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ aqara_mock_device.id, "init" }) test.socket.matter:__expect_send({aqara_mock_device.id, subscribe_request}) - aqara_mock_device:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. + test.socket.device_lifecycle:__queue_receive({ aqara_mock_device.id, "doConfigure" }) local read_attribute_list = clusters.PowerSource.attributes.AttributeList:read() test.socket.matter:__expect_send({aqara_mock_device.id, read_attribute_list}) configure_buttons() aqara_mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(aqara_mock_device) - test.set_rpc_version(5) - - test.socket.device_lifecycle:__queue_receive({ aqara_mock_device.id, "added" }) - test.socket.matter:__expect_send({aqara_mock_device.id, subscribe_request}) local device_info_copy = utils.deep_copy(aqara_mock_device.raw_st_data) device_info_copy.profile.id = "3-button-battery-temperature-humidity" diff --git a/drivers/SmartThings/matter-switch/src/test/test_aqara_light_switch_h2.lua b/drivers/SmartThings/matter-switch/src/test/test_aqara_light_switch_h2.lua index 2e5aef1f2d..7e04e0016d 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_aqara_light_switch_h2.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_aqara_light_switch_h2.lua @@ -160,7 +160,8 @@ local function configure_buttons() end local function test_init() - local opts = { persist = true } + test.disable_startup_messages() + test.mock_device.add_test_device(aqara_mock_device) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.Switch.server.events.InitialPress, @@ -177,15 +178,16 @@ local function test_init() subscribe_request:merge(cluster:subscribe(aqara_mock_device)) end end - test.socket.matter:__expect_send({aqara_mock_device.id, subscribe_request}) -- Test added -> doConfigure logic test.socket.device_lifecycle:__queue_receive({ aqara_mock_device.id, "added" }) test.socket.matter:__expect_send({aqara_mock_device.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ aqara_mock_device.id, "init" }) + test.socket.matter:__expect_send({aqara_mock_device.id, subscribe_request}) test.socket.device_lifecycle:__queue_receive({ aqara_mock_device.id, "doConfigure" }) + configure_buttons() aqara_mock_device:expect_metadata_update({ profile = "4-button" }) aqara_mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(aqara_mock_device) -- to test powerConsumptionReport test.timer.__create_and_queue_test_time_advance_timer(60 * 15, "interval", "create_poll_report_schedule") @@ -209,11 +211,6 @@ local function test_init() parent_assigned_child_key = string.format("%d", aqara_child2_ep) }) - test.socket.device_lifecycle:__queue_receive({ aqara_mock_device.id, "added" }) - configure_buttons() - test.socket.matter:__expect_send({aqara_mock_device.id, subscribe_request}) - - aqara_mock_device:set_field(DEFERRED_CONFIGURE, true, opts) local device_info_copy = utils.deep_copy(aqara_mock_device.raw_st_data) device_info_copy.profile.id = "4-button" local device_info_json = dkjson.encode(device_info_copy) diff --git a/drivers/SmartThings/matter-switch/src/test/test_electrical_sensor.lua b/drivers/SmartThings/matter-switch/src/test/test_electrical_sensor.lua index 4f88338185..cb85d6cd1a 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_electrical_sensor.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_electrical_sensor.lua @@ -16,11 +16,13 @@ local test = require "integration_test" local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" local uint32 = require "st.matter.data_types.Uint32" - local clusters = require "st.matter.clusters" +local version = require "version" -clusters.ElectricalEnergyMeasurement = require "ElectricalEnergyMeasurement" -clusters.ElectricalPowerMeasurement = require "ElectricalPowerMeasurement" +if version.api < 11 then + clusters.ElectricalEnergyMeasurement = require "ElectricalEnergyMeasurement" + clusters.ElectricalPowerMeasurement = require "ElectricalPowerMeasurement" +end local mock_device = test.mock_device.build_test_matter_device({ profile = t_utils.get_profile_definition("plug-level-power-energy-powerConsumption.yml"), @@ -59,7 +61,7 @@ local mock_device = test.mock_device.build_test_matter_device({ { device_type_id = 0x010B, device_type_revision = 1 }, -- OnOff Dimmable Plug } }, - { + { endpoint_id = 3, clusters = { { cluster_id = clusters.ElectricalEnergyMeasurement.ID, cluster_type = "SERVER", feature_map = 14, }, diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_button.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_button.lua index 8d10daea11..23023b3d02 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_matter_button.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_button.lua @@ -58,20 +58,24 @@ local function configure_buttons() end local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local subscribe_request = CLUSTER_SUBSCRIBE_LIST[1]:subscribe(mock_device) for i, clus in ipairs(CLUSTER_SUBSCRIBE_LIST) do if i > 1 then subscribe_request:merge(clus:subscribe(mock_device)) end end + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - mock_device:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device) local read_attribute_list = clusters.PowerSource.attributes.AttributeList:read() test.socket.matter:__expect_send({mock_device.id, read_attribute_list}) configure_buttons() - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) - test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + local device_info_copy = utils.deep_copy(mock_device.raw_st_data) device_info_copy.profile.id = "buttons-battery" local device_info_json = dkjson.encode(device_info_copy) diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_light_fan.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_light_fan.lua index b211bf8f53..078b99c7fe 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_matter_light_fan.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_light_fan.lua @@ -84,13 +84,19 @@ local CLUSTER_SUBSCRIBE_LIST ={ } local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local subscribe_request = CLUSTER_SUBSCRIBE_LIST[1]:subscribe(mock_device) for i, clus in ipairs(CLUSTER_SUBSCRIBE_LIST) do if i > 1 then subscribe_request:merge(clus:subscribe(mock_device)) end end + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) - mock_device:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) mock_device:expect_metadata_update({ profile = "light-color-level-fan" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button.lua index 05d8f4562a..d8b0116101 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button.lua @@ -135,7 +135,7 @@ local function test_init() test.socket.matter:__expect_send({mock_device.id, subscribe_request}) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) - --doConfigure sets the provisioing state to provisioned + --doConfigure sets the provisioning state to provisioned test.socket.matter:__expect_send({mock_device.id, clusters.PowerSource.attributes.AttributeList:read()}) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) expect_configure_buttons() @@ -149,9 +149,6 @@ local function test_init() test.socket.matter:__expect_send({mock_device.id, subscribe_request}) expect_configure_buttons() end - - - test.set_test_init_function(test_init) test.register_message_test( diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_switch_device_types.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_switch_device_types.lua index d2c7da6085..dd0a36a1e9 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_matter_switch_device_types.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_switch_device_types.lua @@ -1,8 +1,23 @@ +-- Copyright 2025 SmartThings +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + local test = require "integration_test" local t_utils = require "integration_test.utils" - local clusters = require "st.matter.clusters" +test.disable_startup_messages() + local mock_device_onoff = test.mock_device.build_test_matter_device({ profile = t_utils.get_profile_definition("matter-thing.yml"), manufacturer_info = { @@ -406,16 +421,19 @@ local mock_device_light_level_motion = test.mock_device.build_test_matter_device }) local function test_init_parent_child_switch_types() + test.mock_device.add_test_device(mock_device_parent_child_switch_types) local subscribe_request = clusters.OnOff.attributes.OnOff:subscribe(mock_device_parent_child_switch_types) + + test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_switch_types.id, "added" }) + test.socket.matter:__expect_send({mock_device_parent_child_switch_types.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_switch_types.id, "init" }) test.socket.matter:__expect_send({mock_device_parent_child_switch_types.id, subscribe_request}) - mock_device_parent_child_switch_types:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_switch_types.id, "doConfigure" }) mock_device_parent_child_switch_types:expect_metadata_update({ profile = "switch-level" }) mock_device_parent_child_switch_types:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device_parent_child_switch_types) - mock_device_parent_child_switch_types:expect_device_create({ type = "EDGE_CHILD", label = "Matter Switch 2", @@ -427,7 +445,8 @@ end local function test_init_onoff() test.mock_device.add_test_device(mock_device_onoff) - mock_device_onoff:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. + test.socket.device_lifecycle:__queue_receive({ mock_device_onoff.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_onoff.id, "init" }) test.socket.device_lifecycle:__queue_receive({ mock_device_onoff.id, "doConfigure" }) mock_device_onoff:expect_metadata_update({ profile = "switch-binary" }) mock_device_onoff:expect_metadata_update({ provisioning_state = "PROVISIONED" }) @@ -438,13 +457,18 @@ local function test_init_onoff_client() end local function test_init_parent_client_child_server() + test.mock_device.add_test_device(mock_device_parent_client_child_server) local subscribe_request = clusters.OnOff.attributes.OnOff:subscribe(mock_device_parent_client_child_server) + + test.socket.device_lifecycle:__queue_receive({ mock_device_parent_client_child_server.id, "added" }) + test.socket.matter:__expect_send({mock_device_parent_client_child_server.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device_parent_client_child_server.id, "init" }) test.socket.matter:__expect_send({mock_device_parent_client_child_server.id, subscribe_request}) - mock_device_parent_client_child_server:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. + test.socket.device_lifecycle:__queue_receive({ mock_device_parent_client_child_server.id, "doConfigure" }) mock_device_parent_client_child_server:expect_metadata_update({ profile = "switch-binary" }) mock_device_parent_client_child_server:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device_parent_client_child_server) end local function test_init_dimmer() @@ -457,13 +481,15 @@ end local function test_init_color_dimmer() test.mock_device.add_test_device(mock_device_color_dimmer) - mock_device_color_dimmer:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. + test.socket.device_lifecycle:__queue_receive({ mock_device_color_dimmer.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_color_dimmer.id, "init" }) test.socket.device_lifecycle:__queue_receive({ mock_device_color_dimmer.id, "doConfigure" }) mock_device_color_dimmer:expect_metadata_update({ profile = "switch-color-level" }) mock_device_color_dimmer:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function test_init_mounted_on_off_control() + test.mock_device.add_test_device(mock_device_mounted_on_off_control) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, } @@ -473,15 +499,19 @@ local function test_init_mounted_on_off_control() subscribe_request:merge(cluster:subscribe(mock_device_mounted_on_off_control)) end end + test.socket.device_lifecycle:__queue_receive({ mock_device_mounted_on_off_control.id, "added" }) + test.socket.matter:__expect_send({mock_device_mounted_on_off_control.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device_mounted_on_off_control.id, "init" }) test.socket.matter:__expect_send({mock_device_mounted_on_off_control.id, subscribe_request}) - mock_device_mounted_on_off_control:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. + test.socket.device_lifecycle:__queue_receive({ mock_device_mounted_on_off_control.id, "doConfigure" }) mock_device_mounted_on_off_control:expect_metadata_update({ profile = "switch-binary" }) mock_device_mounted_on_off_control:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device_mounted_on_off_control) end local function test_init_mounted_dimmable_load_control() + test.mock_device.add_test_device(mock_device_mounted_dimmable_load_control) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, } @@ -491,23 +521,28 @@ local function test_init_mounted_dimmable_load_control() subscribe_request:merge(cluster:subscribe(mock_device_mounted_dimmable_load_control)) end end + test.socket.device_lifecycle:__queue_receive({ mock_device_mounted_dimmable_load_control.id, "added" }) test.socket.matter:__expect_send({mock_device_mounted_dimmable_load_control.id, subscribe_request}) - mock_device_mounted_dimmable_load_control:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. + + test.socket.device_lifecycle:__queue_receive({ mock_device_mounted_dimmable_load_control.id, "init" }) + test.socket.matter:__expect_send({mock_device_mounted_dimmable_load_control.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_device_mounted_dimmable_load_control.id, "doConfigure" }) mock_device_mounted_dimmable_load_control:expect_metadata_update({ profile = "switch-level" }) mock_device_mounted_dimmable_load_control:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device_mounted_dimmable_load_control) end local function test_init_water_valve() test.mock_device.add_test_device(mock_device_water_valve) - mock_device_water_valve:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. + test.socket.device_lifecycle:__queue_receive({ mock_device_water_valve.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_water_valve.id, "init" }) test.socket.device_lifecycle:__queue_receive({ mock_device_water_valve.id, "doConfigure" }) mock_device_water_valve:expect_metadata_update({ profile = "water-valve-level" }) mock_device_water_valve:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function test_init_parent_child_different_types() + test.mock_device.add_test_device(mock_device_parent_child_different_types) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.LevelControl.attributes.CurrentLevel, @@ -527,15 +562,16 @@ local function test_init_parent_child_different_types() subscribe_request:merge(cluster:subscribe(mock_device_parent_child_different_types)) end end + test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_different_types.id, "added" }) + test.socket.matter:__expect_send({mock_device_parent_child_different_types.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_different_types.id, "init" }) test.socket.matter:__expect_send({mock_device_parent_child_different_types.id, subscribe_request}) - mock_device_parent_child_different_types:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_different_types.id, "doConfigure" }) mock_device_parent_child_different_types:expect_metadata_update({ profile = "switch-binary" }) mock_device_parent_child_different_types:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device_parent_child_different_types) - mock_device_parent_child_different_types:expect_device_create({ type = "EDGE_CHILD", label = "Matter Switch 2", @@ -546,11 +582,12 @@ local function test_init_parent_child_different_types() end local function test_init_parent_child_unsupported_device_type() - mock_device_parent_child_unsupported_device_type:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. + test.mock_device.add_test_device(mock_device_parent_child_unsupported_device_type) + test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_unsupported_device_type.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_unsupported_device_type.id, "init" }) test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_unsupported_device_type.id, "doConfigure" }) mock_device_parent_child_unsupported_device_type:expect_metadata_update({ profile = "switch-binary" }) mock_device_parent_child_unsupported_device_type:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device_parent_child_unsupported_device_type) mock_device_parent_child_unsupported_device_type:expect_device_create({ type = "EDGE_CHILD", @@ -562,6 +599,7 @@ local function test_init_parent_child_unsupported_device_type() end local function test_init_light_level_motion() + test.mock_device.add_test_device(mock_device_light_level_motion) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.LevelControl.attributes.CurrentLevel, @@ -576,12 +614,15 @@ local function test_init_light_level_motion() end end + test.socket.device_lifecycle:__queue_receive({ mock_device_light_level_motion.id, "added" }) test.socket.matter:__expect_send({mock_device_light_level_motion.id, subscribe_request}) - mock_device_light_level_motion:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. + + test.socket.device_lifecycle:__queue_receive({ mock_device_light_level_motion.id, "init" }) + test.socket.matter:__expect_send({mock_device_light_level_motion.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_device_light_level_motion.id, "doConfigure" }) mock_device_light_level_motion:expect_metadata_update({ profile = "light-level-motion" }) mock_device_light_level_motion:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device_light_level_motion) end test.register_coroutine_test( diff --git a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua index 66f019cdb0..cff4c7b60b 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_lights.lua @@ -15,8 +15,10 @@ local test = require "integration_test" local t_utils = require "integration_test.utils" local capabilities = require "st.capabilities" - local clusters = require "st.matter.clusters" + +test.disable_startup_messages() + local TRANSITION_TIME = 0 local OPTIONS_MASK = 0x01 local OPTIONS_OVERRIDE = 0x01 @@ -159,6 +161,7 @@ for i, endpoint in ipairs(mock_device.endpoints) do end local function test_init() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.LevelControl.attributes.CurrentLevel, @@ -178,14 +181,17 @@ local function test_init() subscribe_request:merge(cluster:subscribe(mock_device)) end end + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - mock_device:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) mock_device:expect_metadata_update({ profile = "light-binary" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device) for _, child in pairs(mock_children) do test.mock_device.add_test_device(child) end @@ -227,6 +233,7 @@ for i, endpoint in ipairs(mock_device_parent_child_endpoints_non_sequential.endp end local function test_init_parent_child_endpoints_non_sequential() + test.mock_device.add_test_device(mock_device_parent_child_endpoints_non_sequential) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.LevelControl.attributes.CurrentLevel, @@ -246,14 +253,17 @@ local function test_init_parent_child_endpoints_non_sequential() subscribe_request:merge(cluster:subscribe(mock_device_parent_child_endpoints_non_sequential)) end end + + test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_endpoints_non_sequential.id, "added" }) + test.socket.matter:__expect_send({mock_device_parent_child_endpoints_non_sequential.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_endpoints_non_sequential.id, "init" }) test.socket.matter:__expect_send({mock_device_parent_child_endpoints_non_sequential.id, subscribe_request}) - mock_device_parent_child_endpoints_non_sequential:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. test.socket.device_lifecycle:__queue_receive({ mock_device_parent_child_endpoints_non_sequential.id, "doConfigure" }) mock_device_parent_child_endpoints_non_sequential:expect_metadata_update({ profile = "light-binary" }) mock_device_parent_child_endpoints_non_sequential:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device_parent_child_endpoints_non_sequential) for _, child in pairs(mock_children_non_sequential) do test.mock_device.add_test_device(child) end diff --git a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua index a69cdfeda7..85aff57401 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_multi_switch_parent_child_plugs.lua @@ -15,9 +15,10 @@ local test = require "integration_test" local t_utils = require "integration_test.utils" local capabilities = require "st.capabilities" - local clusters = require "st.matter.clusters" +test.disable_startup_messages() + local child_profile = t_utils.get_profile_definition("plug-binary.yml") local child_profile_override = t_utils.get_profile_definition("switch-binary.yml") local parent_ep = 10 @@ -152,18 +153,22 @@ for i, endpoint in ipairs(mock_device.endpoints) do end local function test_init() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, } local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - mock_device:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) mock_device:expect_metadata_update({ profile = "plug-binary" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device) for _, child in pairs(mock_children) do test.mock_device.add_test_device(child) end @@ -215,18 +220,22 @@ for i, endpoint in ipairs(mock_device_child_profile_override.endpoints) do end local function test_init_child_profile_override() + test.mock_device.add_test_device(mock_device_child_profile_override) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, } local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_child_profile_override) + + test.socket.device_lifecycle:__queue_receive({ mock_device_child_profile_override.id, "added" }) + test.socket.matter:__expect_send({mock_device_child_profile_override.id, subscribe_request}) + + test.socket.device_lifecycle:__queue_receive({ mock_device_child_profile_override.id, "init" }) test.socket.matter:__expect_send({mock_device_child_profile_override.id, subscribe_request}) - mock_device_child_profile_override:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case. test.socket.device_lifecycle:__queue_receive({ mock_device_child_profile_override.id, "doConfigure" }) mock_device_child_profile_override:expect_metadata_update({ profile = "plug-binary" }) mock_device_child_profile_override:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.mock_device.add_test_device(mock_device_child_profile_override) for _, child in pairs(mock_children_child_profile_override) do test.mock_device.add_test_device(child) end diff --git a/drivers/SmartThings/matter-switch/src/test/test_third_reality_mk1.lua b/drivers/SmartThings/matter-switch/src/test/test_third_reality_mk1.lua index 03c0e7ee74..7fcbb5aafd 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_third_reality_mk1.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_third_reality_mk1.lua @@ -200,6 +200,8 @@ local function configure_buttons() end local function test_init() + test.disable_startup_messages() + test.mock_device.add_test_device(mock_device) local cluster_subscribe_list = { clusters.Switch.events.InitialPress } @@ -207,13 +209,17 @@ local function test_init() for i, clus in ipairs(cluster_subscribe_list) do if i > 1 then subscribe_request:merge(clus:subscribe(mock_device)) end end + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) mock_device:expect_metadata_update({ profile = "12-button-keyboard" }) mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) configure_buttons() - test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + local device_info_copy = utils.deep_copy(mock_device.raw_st_data) device_info_copy.profile.id = "12-buttons-keyboard" local device_info_json = dkjson.encode(device_info_copy) From 6ae16892854a43d049d174b7b1157971874e51b4 Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Thu, 7 Aug 2025 12:08:36 -0500 Subject: [PATCH 08/12] Updating UTs for matter-thermostat --- .../src/test/test_matter_air_purifier.lua | 1 + .../src/test/test_matter_heat_pump.lua | 26 +++- .../src/test/test_matter_room_ac.lua | 40 ++--- .../src/test/test_matter_room_ac_modular.lua | 90 +++++++---- .../src/test/test_matter_thermo_battery.lua | 13 +- .../test/test_matter_thermo_featuremap.lua | 3 +- ...st_matter_thermo_multiple_device_types.lua | 119 +++++++++----- .../src/test/test_matter_thermostat.lua | 32 ++-- ...est_matter_thermostat_composed_bridged.lua | 35 ++--- .../test/test_matter_thermostat_modular.lua | 41 +++-- .../src/test/test_matter_thermostat_rpc5.lua | 145 ++++++++++++++++++ .../src/test/test_matter_water_heater.lua | 51 +----- 12 files changed, 389 insertions(+), 207 deletions(-) create mode 100644 drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_rpc5.lua diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_air_purifier.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_air_purifier.lua index f05c5ee175..d9cb8c6309 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_air_purifier.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_air_purifier.lua @@ -12,6 +12,7 @@ -- See the License for the specific language governing permissions and -- limitations under the License. local test = require "integration_test" +test.set_rpc_version(0) local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" local SinglePrecisionFloat = require "st.matter.data_types.SinglePrecisionFloat" diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_heat_pump.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_heat_pump.lua index 3a33e94251..9af8c51982 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_heat_pump.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_heat_pump.lua @@ -83,6 +83,8 @@ local device_desc = { } local test_init_common = function(device) + test.disable_startup_messages() + test.mock_device.add_test_device(device) local cluster_subscribe_list = { clusters.Thermostat.attributes.SystemMode, clusters.Thermostat.attributes.ControlSequenceOfOperation, @@ -107,7 +109,6 @@ local test_init_common = function(device) subscribe_request:merge(cluster:subscribe(device)) end end - test.socket.matter:__expect_send({ device.id, subscribe_request }) test.socket.device_lifecycle:__queue_receive({ device.id, "added" }) local read_request_on_added = { clusters.Thermostat.attributes.ControlSequenceOfOperation, @@ -124,7 +125,8 @@ local test_init_common = function(device) device.id, read_request }) - test.mock_device.add_test_device(device) + test.socket.device_lifecycle:__queue_receive({ device.id, "init" }) + test.socket.matter:__expect_send({ device.id, subscribe_request }) end local mock_device = test.mock_device.build_test_matter_device(device_desc) @@ -181,6 +183,11 @@ test.register_message_test( clusters.Thermostat.server.attributes.OccupiedHeatingSetpoint:build_test_report_data(mock_device, THERMOSTAT_ONE_EP, 40*100) } }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("thermostatOne", capabilities.thermostatHeatingSetpoint.heatingSetpointRange({ value = { maximum = 100.0, minimum = 0.0, step = 0.1 }, unit = "C" })) + }, { channel = "capability", direction = "send", @@ -194,6 +201,11 @@ test.register_message_test( clusters.Thermostat.server.attributes.OccupiedHeatingSetpoint:build_test_report_data(mock_device, THERMOSTAT_TWO_EP, 23*100) } }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("thermostatTwo", capabilities.thermostatHeatingSetpoint.heatingSetpointRange({ value = { maximum = 100.0, minimum = 0.0, step = 0.1 }, unit = "C" })) + }, { channel = "capability", direction = "send", @@ -213,6 +225,11 @@ test.register_message_test( clusters.Thermostat.server.attributes.OccupiedCoolingSetpoint:build_test_report_data(mock_device, THERMOSTAT_ONE_EP, 39*100) } }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("thermostatOne", capabilities.thermostatCoolingSetpoint.coolingSetpointRange({ value = { maximum = 100.0, minimum = 0.0, step = 0.1 }, unit = "C" })) + }, { channel = "capability", direction = "send", @@ -226,6 +243,11 @@ test.register_message_test( clusters.Thermostat.server.attributes.OccupiedCoolingSetpoint:build_test_report_data(mock_device, THERMOSTAT_TWO_EP, 19*100) } }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("thermostatTwo", capabilities.thermostatCoolingSetpoint.coolingSetpointRange({ value = { maximum = 100.0, minimum = 0.0, step = 0.1 }, unit = "C" })) + }, { channel = "capability", direction = "send", diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_room_ac.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_room_ac.lua index 6c30fae787..cec0cb9ffc 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_room_ac.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_room_ac.lua @@ -12,10 +12,10 @@ -- See the License for the specific language governing permissions and -- limitations under the License. local test = require "integration_test" +test.set_rpc_version(0) local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" local uint32 = require "st.matter.data_types.Uint32" - local clusters = require "st.matter.clusters" local mock_device = test.mock_device.build_test_matter_device({ @@ -35,15 +35,15 @@ local mock_device = test.mock_device.build_test_matter_device({ } }, { - endpoint_id = 1, - clusters = { - {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"}, - {cluster_id = clusters.FanControl.ID, cluster_type = "SERVER"}, - {cluster_id = clusters.Thermostat.ID, cluster_type = "SERVER", feature_map = 0}, - {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER"}, - {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "SERVER"}, - } + endpoint_id = 1, + clusters = { + {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.FanControl.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.Thermostat.ID, cluster_type = "SERVER", feature_map = 0}, + {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "SERVER"}, } + } } }) @@ -64,18 +64,18 @@ local mock_device_configure = test.mock_device.build_test_matter_device({ } }, { - endpoint_id = 1, - clusters = { - {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER", feature_map = 0}, - {cluster_id = clusters.FanControl.ID, cluster_type = "SERVER", feature_map = 63}, - {cluster_id = clusters.Thermostat.ID, cluster_type = "SERVER", feature_map = 63}, - {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, - {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, - }, - device_types = { - {device_type_id = 0x0072, device_type_revision = 1} -- Room Air Conditioner - } + endpoint_id = 1, + clusters = { + {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER", feature_map = 0}, + {cluster_id = clusters.FanControl.ID, cluster_type = "SERVER", feature_map = 63}, + {cluster_id = clusters.Thermostat.ID, cluster_type = "SERVER", feature_map = 63}, + {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, + {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, + }, + device_types = { + {device_type_id = 0x0072, device_type_revision = 1} -- Room Air Conditioner } + } } }) diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_room_ac_modular.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_room_ac_modular.lua index 096ce71221..9be85cd84b 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_room_ac_modular.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_room_ac_modular.lua @@ -16,9 +16,11 @@ local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" local utils = require "st.utils" local dkjson = require "dkjson" - local clusters = require "st.matter.clusters" +local im = require "st.matter.interaction_model" +local uint32 = require "st.matter.data_types.Uint32" +test.disable_startup_messages() test.set_rpc_version(8) local mock_device_basic = test.mock_device.build_test_matter_device({ @@ -38,18 +40,18 @@ local mock_device_basic = test.mock_device.build_test_matter_device({ } }, { - endpoint_id = 1, - clusters = { - {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER", feature_map = 0}, - {cluster_id = clusters.FanControl.ID, cluster_type = "SERVER", feature_map = 63}, - {cluster_id = clusters.Thermostat.ID, cluster_type = "SERVER", feature_map = 63}, - {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, - {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, - }, - device_types = { - {device_type_id = 0x0072, device_type_revision = 1} -- Room Air Conditioner - } + endpoint_id = 1, + clusters = { + {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER", feature_map = 0}, + {cluster_id = clusters.FanControl.ID, cluster_type = "SERVER", feature_map = 63}, + {cluster_id = clusters.Thermostat.ID, cluster_type = "SERVER", feature_map = 63}, + {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, + {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, + }, + device_types = { + {device_type_id = 0x0072, device_type_revision = 1} -- Room Air Conditioner } + } } }) @@ -70,22 +72,23 @@ local mock_device_no_state = test.mock_device.build_test_matter_device({ } }, { - endpoint_id = 1, - clusters = { - {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER", feature_map = 0}, - {cluster_id = clusters.FanControl.ID, cluster_type = "SERVER", feature_map = 63}, - {cluster_id = clusters.Thermostat.ID, cluster_type = "SERVER", feature_map = 63}, - {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, - {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, - }, - device_types = { - {device_type_id = 0x0072, device_type_revision = 1} -- Room Air Conditioner - } + endpoint_id = 1, + clusters = { + {cluster_id = clusters.OnOff.ID, cluster_type = "SERVER", feature_map = 0}, + {cluster_id = clusters.FanControl.ID, cluster_type = "SERVER", feature_map = 63}, + {cluster_id = clusters.Thermostat.ID, cluster_type = "SERVER", feature_map = 63}, + {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, + {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "SERVER", feature_map = 0}, + }, + device_types = { + {device_type_id = 0x0072, device_type_revision = 1} -- Room Air Conditioner } + } } }) local function initialize_mock_device(generic_mock_device, generic_subscribed_attributes) + test.mock_device.add_test_device(generic_mock_device) local subscribe_request = nil for _, attributes in pairs(generic_subscribed_attributes) do for _, attribute in ipairs(attributes) do @@ -97,12 +100,27 @@ local function initialize_mock_device(generic_mock_device, generic_subscribed_at end end test.socket.matter:__expect_send({generic_mock_device.id, subscribe_request}) - test.mock_device.add_test_device(generic_mock_device) return subscribe_request end +local function read_req_on_added(device) + local attributes = { + clusters.Thermostat.attributes.ControlSequenceOfOperation, + clusters.FanControl.attributes.FanModeSequence, + clusters.FanControl.attributes.WindSupport, + clusters.FanControl.attributes.RockSupport, + clusters.Thermostat.attributes.AttributeList, + } + local read_request = im.InteractionRequest(im.InteractionRequest.RequestType.READ, {}) + for _, clus in ipairs(attributes) do + read_request:merge(clus:read(device)) + end + test.socket.matter:__expect_send({ device.id, read_request }) +end + local subscribe_request_basic local function test_init_basic() + test.socket.matter:__set_channel_ordering("relaxed") local subscribed_attributes = { [capabilities.switch.ID] = { clusters.OnOff.attributes.OnOff @@ -145,6 +163,8 @@ local function test_init_basic() clusters.FanControl.attributes.WindSetting }, } + test.socket.device_lifecycle:__queue_receive({ mock_device_basic.id, "added" }) + read_req_on_added(mock_device_basic) subscribe_request_basic = initialize_mock_device(mock_device_basic, subscribed_attributes) local read_setpoint_deadband = clusters.Thermostat.attributes.MinSetpointDeadBand:read() test.socket.matter:__expect_send({mock_device_basic.id, read_setpoint_deadband}) @@ -204,8 +224,8 @@ for _, attributes in pairs(subscribed_attributes_no_state) do end end - local function test_init_no_state() + test.socket.matter:__set_channel_ordering("relaxed") local subscribed_attributes = { [capabilities.switch.ID] = { clusters.OnOff.attributes.OnOff @@ -249,6 +269,8 @@ local function test_init_no_state() }, } + test.socket.device_lifecycle:__queue_receive({ mock_device_no_state.id, "added" }) + read_req_on_added(mock_device_no_state) -- initially, device onboards WITH thermostatOperatingState, the test below will -- check if it is removed correctly when switching to modular profile. This is done -- to test that cases where the modular profile is different from the static profile @@ -260,10 +282,16 @@ local function test_init_no_state() end -- run the profile configuration tests -local function test_room_ac_device_type_update_modular_profile(generic_mock_device, expected_metadata, subscribe_request) +local function test_room_ac_device_type_update_modular_profile(generic_mock_device, expected_metadata, subscribe_request, thermostat_attr_list_value) test.socket.device_lifecycle:__queue_receive({generic_mock_device.id, "doConfigure"}) - generic_mock_device:expect_metadata_update(expected_metadata) generic_mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.wait_for_events() + test.socket.matter:__queue_receive({ + generic_mock_device.id, + clusters.Thermostat.attributes.AttributeList:build_test_report_data(generic_mock_device, 1, {thermostat_attr_list_value}) + }) + generic_mock_device:expect_metadata_update(expected_metadata) + local device_info_copy = utils.deep_copy(generic_mock_device.raw_st_data) device_info_copy.profile.id = "room-air-conditioner-modular" local device_info_json = dkjson.encode(device_info_copy) @@ -292,9 +320,7 @@ local expected_metadata_basic= { test.register_coroutine_test( "Device with modular profile should enable correct optional capabilities - basic", function() - mock_device_basic:set_field("__BATTERY_SUPPORT", "NO_BATTERY") -- since we're assuming this would have happened during device_added in this case. - mock_device_basic:set_field("__THERMOSTAT_RUNNING_STATE_SUPPORT", true) -- since we're assuming this would have happened during device_added in this case. - test_room_ac_device_type_update_modular_profile(mock_device_basic, expected_metadata_basic, subscribe_request_basic) + test_room_ac_device_type_update_modular_profile(mock_device_basic, expected_metadata_basic, subscribe_request_basic, uint32(0x29)) end, { test_init = test_init_basic } ) @@ -319,9 +345,7 @@ local expected_metadata_no_state = { test.register_coroutine_test( "Device with modular profile should enable correct optional capabilities - no thermo state", function() - mock_device_no_state:set_field("__BATTERY_SUPPORT", "NO_BATTERY") -- since we're assuming this would have happened during device_added in this case. - mock_device_no_state:set_field("__THERMOSTAT_RUNNING_STATE_SUPPORT", false) -- since we're assuming this would have happened during device_added in this case. - test_room_ac_device_type_update_modular_profile(mock_device_no_state, expected_metadata_no_state, subscribe_request_no_state) + test_room_ac_device_type_update_modular_profile(mock_device_no_state, expected_metadata_no_state, subscribe_request_no_state, uint32(0)) end, { test_init = test_init_no_state } ) diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_battery.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_battery.lua index 67de61b532..35f312c67e 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_battery.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_battery.lua @@ -17,6 +17,8 @@ local t_utils = require "integration_test.utils" local clusters = require "st.matter.clusters" local uint32 = require "st.matter.data_types.Uint32" +test.set_rpc_version(7) + local mock_device = test.mock_device.build_test_matter_device({ profile = t_utils.get_profile_definition("thermostat-batteryLevel.yml"), manufacturer_info = { @@ -70,17 +72,6 @@ local cluster_subscribe = { } local function test_init() - -- test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) - -- local read_req = clusters.Thermostat.attributes.ControlSequenceOfOperation:read() - -- read_req:merge(clusters.FanControl.attributes.FanModeSequence:read()) - -- read_req:merge(clusters.FanControl.attributes.WindSupport:read()) - -- read_req:merge(clusters.FanControl.attributes.RockSupport:read()) - -- read_req:merge(clusters.FanControl.attributes.RockSupport:read()) - -- read_req:merge(clusters.Thermostat.attributes.AttributeList:read()) - -- read_req:merge(clusters.PowerSource.attributes.AttributeList:read()) - -- test.socket.matter:__expect_send({mock_device.id, read_req}) - - -- test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) local subscribe_request= cluster_subscribe[1]:subscribe(mock_device) for i, cluster in ipairs(cluster_subscribe) do if i > 1 then diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_featuremap.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_featuremap.lua index 59ae9a433f..37f73d0e50 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_featuremap.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_featuremap.lua @@ -15,9 +15,10 @@ local test = require "integration_test" local t_utils = require "integration_test.utils" local uint32 = require "st.matter.data_types.Uint32" - local clusters = require "st.matter.clusters" +test.set_rpc_version(7) + local mock_device = test.mock_device.build_test_matter_device({ profile = t_utils.get_profile_definition("thermostat-humidity-fan.yml"), manufacturer_info = { diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_multiple_device_types.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_multiple_device_types.lua index d1a70c3f06..2086036be5 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_multiple_device_types.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_multiple_device_types.lua @@ -14,8 +14,10 @@ local test = require "integration_test" local t_utils = require "integration_test.utils" - local clusters = require "st.matter.clusters" +local dkjson = require "dkjson" +local uint32 = require "st.matter.data_types.Uint32" +local utils = require "st.utils" local mock_device = test.mock_device.build_test_matter_device({ profile = t_utils.get_profile_definition("thermostat-humidity-fan.yml"), @@ -135,32 +137,18 @@ local cluster_subscribe_list = { clusters.FanControl.attributes.FanModeSequence, } -local cluster_subscribe_list_disorder_endpoints = { - clusters.Thermostat.attributes.LocalTemperature, - clusters.Thermostat.attributes.OccupiedCoolingSetpoint, - clusters.Thermostat.attributes.OccupiedHeatingSetpoint, - clusters.Thermostat.attributes.AbsMinCoolSetpointLimit, - clusters.Thermostat.attributes.AbsMaxCoolSetpointLimit, - clusters.Thermostat.attributes.AbsMinHeatSetpointLimit, - clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit, - clusters.Thermostat.attributes.SystemMode, - clusters.Thermostat.attributes.ThermostatRunningState, - clusters.Thermostat.attributes.ControlSequenceOfOperation, - clusters.RelativeHumidityMeasurement.attributes.MeasuredValue, - clusters.FanControl.attributes.FanMode, - clusters.FanControl.attributes.FanModeSequence, -} - -local function test_init() - mock_device:set_field("MIN_SETPOINT_DEADBAND_CHECKED", 1, {persist = true}) - test.socket.matter:__set_channel_ordering("relaxed") - local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) - for i, cluster in ipairs(cluster_subscribe_list) do +local function get_subscribe_request(device, attribute_list) + local subscribe_request = attribute_list[1]:subscribe(device) + for i, cluster in ipairs(attribute_list) do if i > 1 then - subscribe_request:merge(cluster:subscribe(mock_device)) + subscribe_request:merge(cluster:subscribe(device)) end end - test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + return subscribe_request +end + +local function test_init() + test.disable_startup_messages() test.mock_device.add_test_device(mock_device) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) @@ -171,19 +159,14 @@ local function test_init() read_req:merge(clusters.FanControl.attributes.RockSupport:read()) read_req:merge(clusters.Thermostat.attributes.AttributeList:read()) test.socket.matter:__expect_send({mock_device.id, read_req}) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + test.socket.matter:__expect_send({mock_device.id, get_subscribe_request(mock_device, cluster_subscribe_list)}) end test.set_test_init_function(test_init) local function test_init_disorder_endpoints() - mock_device_disorder_endpoints:set_field("MIN_SETPOINT_DEADBAND_CHECKED", 1, {persist = true}) - test.socket.matter:__set_channel_ordering("relaxed") - local subscribe_request_disorder_endpoints = cluster_subscribe_list_disorder_endpoints[1]:subscribe(mock_device_disorder_endpoints) - for i, cluster in ipairs(cluster_subscribe_list_disorder_endpoints) do - if i > 1 then - subscribe_request_disorder_endpoints:merge(cluster:subscribe(mock_device_disorder_endpoints)) - end - end - test.socket.matter:__expect_send({mock_device_disorder_endpoints.id, subscribe_request_disorder_endpoints}) + test.disable_startup_messages() test.mock_device.add_test_device(mock_device_disorder_endpoints) test.socket.device_lifecycle:__queue_receive({ mock_device_disorder_endpoints.id, "added" }) @@ -194,25 +177,79 @@ local function test_init_disorder_endpoints() read_req:merge(clusters.FanControl.attributes.RockSupport:read()) read_req:merge(clusters.Thermostat.attributes.AttributeList:read()) test.socket.matter:__expect_send({mock_device_disorder_endpoints.id, read_req}) + + test.socket.device_lifecycle:__queue_receive({ mock_device_disorder_endpoints.id, "init" }) + test.socket.matter:__expect_send({mock_device_disorder_endpoints.id, get_subscribe_request( + mock_device_disorder_endpoints, cluster_subscribe_list)}) end +-- run the profile configuration tests +local function test_thermostat_device_type_update_modular_profile(generic_mock_device, expected_metadata, subscribe_request) + test.socket.device_lifecycle:__queue_receive({generic_mock_device.id, "doConfigure"}) + generic_mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.wait_for_events() + test.socket.matter:__queue_receive({ + generic_mock_device.id, + clusters.Thermostat.attributes.AttributeList:build_test_report_data(generic_mock_device, 1, {uint32(0)}) + }) + generic_mock_device:expect_metadata_update(expected_metadata) + + test.wait_for_events() + + local device_info_copy = utils.deep_copy(generic_mock_device.raw_st_data) + device_info_copy.profile.id = "thermostat-modular" + local device_info_json = dkjson.encode(device_info_copy) + test.socket.device_lifecycle:__queue_receive({ generic_mock_device.id, "infoChanged", device_info_json }) + test.socket.matter:__expect_send({generic_mock_device.id, subscribe_request}) +end + +local expected_metadata = { + optional_component_capabilities={ + { + "main", + { + "relativeHumidityMeasurement", + "fanMode", + "fanOscillationMode", + "thermostatHeatingSetpoint", + "thermostatCoolingSetpoint" + }, + }, + }, + profile="thermostat-modular", +} + +local new_cluster_subscribe_list = { + clusters.Thermostat.attributes.LocalTemperature, + clusters.Thermostat.attributes.OccupiedCoolingSetpoint, + clusters.Thermostat.attributes.OccupiedHeatingSetpoint, + clusters.Thermostat.attributes.AbsMinCoolSetpointLimit, + clusters.Thermostat.attributes.AbsMaxCoolSetpointLimit, + clusters.Thermostat.attributes.AbsMinHeatSetpointLimit, + clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit, + clusters.Thermostat.attributes.SystemMode, + clusters.Thermostat.attributes.ThermostatRunningState, + clusters.Thermostat.attributes.ControlSequenceOfOperation, + clusters.RelativeHumidityMeasurement.attributes.MeasuredValue, + clusters.FanControl.attributes.FanMode, + clusters.FanControl.attributes.FanModeSequence, + clusters.FanControl.attributes.RockSupport, -- These two attributes will be subscribed to following the profile + clusters.FanControl.attributes.RockSetting, -- change since the fanOscillationMode capability will be enabled. +} + test.register_coroutine_test( "Profile change on doConfigure lifecycle event no battery & state support", function() - mock_device:set_field("__THERMOSTAT_RUNNING_STATE_SUPPORT", false) - test.socket.device_lifecycle:__queue_receive({mock_device.id, "doConfigure"}) - mock_device:expect_metadata_update({ profile = "thermostat-humidity-fan-nostate-nobattery" }) - mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test_thermostat_device_type_update_modular_profile(mock_device, expected_metadata, + get_subscribe_request(mock_device, new_cluster_subscribe_list)) end ) test.register_coroutine_test( "Profile change on doConfigure lifecycle event no battery & state support with disorder endpoints", function() - mock_device_disorder_endpoints:set_field("__THERMOSTAT_RUNNING_STATE_SUPPORT", false) - test.socket.device_lifecycle:__queue_receive({mock_device_disorder_endpoints.id, "doConfigure"}) - mock_device_disorder_endpoints:expect_metadata_update({ profile = "thermostat-humidity-fan-nostate-nobattery" }) - mock_device_disorder_endpoints:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test_thermostat_device_type_update_modular_profile(mock_device_disorder_endpoints, expected_metadata, + get_subscribe_request(mock_device_disorder_endpoints, new_cluster_subscribe_list)) end, { test_init = test_init_disorder_endpoints } ) diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat.lua index 767b21a36e..4a6eb49c8d 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat.lua @@ -219,6 +219,11 @@ test.register_message_test( clusters.Thermostat.server.attributes.OccupiedHeatingSetpoint:build_test_report_data(mock_device, 1, 40*100) } }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.thermostatHeatingSetpoint.heatingSetpointRange({ value = { maximum = 100.0, minimum = 0.0, step = 0.1 }, unit = "C" })) + }, { channel = "capability", direction = "send", @@ -238,6 +243,11 @@ test.register_message_test( clusters.Thermostat.server.attributes.OccupiedCoolingSetpoint:build_test_report_data(mock_device, 1, 40*100) } }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.thermostatCoolingSetpoint.coolingSetpointRange({ value = { maximum = 100.0, minimum = 0.0, step = 0.1 }, unit = "C" })) + }, { channel = "capability", direction = "send", @@ -703,28 +713,6 @@ test.register_message_test( } ) -test.register_message_test( - "Setting the heating setpoint to a Fahrenheit value should send the appropriate commands", - { - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "thermostatHeatingSetpoint", component = "main", command = "setHeatingSetpoint", args = { 64 } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.Thermostat.attributes.OccupiedHeatingSetpoint:write(mock_device, 1, utils.round((64 - 32) * (5 / 9.0) * 100)) - } - } - } -) - test.register_message_test( "Setting the mode to cool should send the appropriate commands", { diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_composed_bridged.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_composed_bridged.lua index d8146257ef..c95592e0fb 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_composed_bridged.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_composed_bridged.lua @@ -157,6 +157,12 @@ test.register_message_test( clusters.Thermostat.server.attributes.OccupiedHeatingSetpoint:build_test_report_data(mock_device, 3, 40 * 100) } }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", + capabilities.thermostatHeatingSetpoint.heatingSetpointRange({ value = { minimum = 0.00, maximum = 100.00, step = 0.1 }, unit = "C" })) + }, { channel = "capability", direction = "send", @@ -177,6 +183,12 @@ test.register_message_test( clusters.Thermostat.server.attributes.OccupiedCoolingSetpoint:build_test_report_data(mock_device, 3, 40 * 100) } }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", + capabilities.thermostatCoolingSetpoint.coolingSetpointRange({ value = { minimum = 0.00, maximum = 100.00, step = 0.1 }, unit = "C" })) + }, { channel = "capability", direction = "send", @@ -513,29 +525,6 @@ test.register_message_test( } ) -test.register_message_test( - "Setting the heating setpoint to a Fahrenheit value should send the appropriate commands", - { - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "thermostatHeatingSetpoint", component = "main", command = "setHeatingSetpoint", args = { 64 } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.Thermostat.attributes.OccupiedHeatingSetpoint:write(mock_device, 3, - utils.round((64 - 32) * (5 / 9.0) * 100)) - } - } - } -) - test.register_message_test( "Setting the mode to cool should send the appropriate commands", { diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_modular.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_modular.lua index ee2d27c001..9c42c03ddb 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_modular.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_modular.lua @@ -14,12 +14,13 @@ local test = require "integration_test" local t_utils = require "integration_test.utils" -local utils = require "st.utils" -local dkjson = require "dkjson" - local clusters = require "st.matter.clusters" +local dkjson = require "dkjson" +local im = require "st.matter.interaction_model" +local uint32 = require "st.matter.data_types.Uint32" +local utils = require "st.utils" -test.set_rpc_version(8) +test.disable_startup_messages() local mock_device_basic = test.mock_device.build_test_matter_device({ profile = t_utils.get_profile_definition("thermostat-humidity-fan.yml"), @@ -49,7 +50,10 @@ local mock_device_basic = test.mock_device.build_test_matter_device({ }, {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER"}, {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "SERVER"}, - {cluster_id = clusters.PowerSource.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.PowerSource.ID, cluster_type = "SERVER", feature_map = 0}, + }, + device_types = { + {device_type_id = 0x0301, device_type_revision = 1} -- Thermostat } } } @@ -64,12 +68,12 @@ local function initialize_mock_device(generic_mock_device, generic_subscribed_at end end test.socket.matter:__expect_send({generic_mock_device.id, subscribe_request}) - test.mock_device.add_test_device(generic_mock_device) return subscribe_request end local subscribe_request_basic local function test_init() + test.mock_device.add_test_device(mock_device_basic) local subscribed_attributes = { clusters.Thermostat.attributes.LocalTemperature, clusters.Thermostat.attributes.OccupiedCoolingSetpoint, @@ -89,14 +93,35 @@ local function test_init() clusters.FanControl.attributes.FanModeSequence, clusters.PowerSource.attributes.BatPercentRemaining, } + test.socket.device_lifecycle:__queue_receive({ mock_device_basic.id, "added" }) + local read_attributes = { + clusters.Thermostat.attributes.ControlSequenceOfOperation, + clusters.FanControl.attributes.FanModeSequence, + clusters.FanControl.attributes.WindSupport, + clusters.FanControl.attributes.RockSupport, + clusters.Thermostat.attributes.AttributeList, + } + local read_request = im.InteractionRequest(im.InteractionRequest.RequestType.READ, {}) + for _, clus in ipairs(read_attributes) do + read_request:merge(clus:read(mock_device_basic)) + end + test.socket.matter:__expect_send({ mock_device_basic.id, read_request }) + + test.socket.device_lifecycle:__queue_receive({ mock_device_basic.id, "init" }) subscribe_request_basic = initialize_mock_device(mock_device_basic, subscribed_attributes) end -- run the profile configuration tests local function test_thermostat_device_type_update_modular_profile(generic_mock_device, expected_metadata, subscribe_request) test.socket.device_lifecycle:__queue_receive({generic_mock_device.id, "doConfigure"}) - generic_mock_device:expect_metadata_update(expected_metadata) generic_mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.wait_for_events() + test.socket.matter:__queue_receive({ + generic_mock_device.id, + clusters.Thermostat.attributes.AttributeList:build_test_report_data(generic_mock_device, 1, {uint32(0)}) + }) + generic_mock_device:expect_metadata_update(expected_metadata) + local device_info_copy = utils.deep_copy(generic_mock_device.raw_st_data) device_info_copy.profile.id = "thermostat-modular" local device_info_json = dkjson.encode(device_info_copy) @@ -122,8 +147,6 @@ local expected_metadata = { test.register_coroutine_test( "Device with modular profile should enable correct optional capabilities", function() - mock_device_basic:set_field("__BATTERY_SUPPORT", "NO_BATTERY") -- since we're assuming this would have happened during device_added in this case. - mock_device_basic:set_field("__THERMOSTAT_RUNNING_STATE_SUPPORT", false) -- since we're assuming this would have happened during device_added in this case. test_thermostat_device_type_update_modular_profile(mock_device_basic, expected_metadata, subscribe_request_basic) end, { test_init = test_init } diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_rpc5.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_rpc5.lua new file mode 100644 index 0000000000..b52b08027e --- /dev/null +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_rpc5.lua @@ -0,0 +1,145 @@ +-- Copyright 2022 SmartThings +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +local clusters = require "st.matter.clusters" +local test = require "integration_test" +local t_utils = require "integration_test.utils" +local utils = require "st.utils" + +-- Temperature values are converted to Celsius by the hub before reaching the driver for rpc > 5. +-- This test file is meant to verify that the driver converts Fahrenheit values > 40 degrees from F to C for rpc <= 5. +test.set_rpc_version(5) + +local mock_device = test.mock_device.build_test_matter_device({ + profile = t_utils.get_profile_definition("thermostat-humidity-fan.yml"), + manufacturer_info = { + vendor_id = 0x0000, + product_id = 0x0000, + }, + endpoints = { + { + endpoint_id = 0, + clusters = { + {cluster_id = clusters.Basic.ID, cluster_type = "SERVER"}, + }, + device_types = { + device_type_id = 0x0016, device_type_revision = 1, -- RootNode + } + }, + { + endpoint_id = 1, + clusters = { + {cluster_id = clusters.FanControl.ID, cluster_type = "SERVER"}, + { + cluster_id = clusters.Thermostat.ID, + cluster_revision=5, + cluster_type="SERVER", + feature_map=3, -- Heat and Cool features + }, + {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.PowerSource.ID, cluster_type = "SERVER"}, + } + } + } +}) + +local function test_init() + local cluster_subscribe_list = { + clusters.Thermostat.attributes.LocalTemperature, + clusters.Thermostat.attributes.OccupiedCoolingSetpoint, + clusters.Thermostat.attributes.OccupiedHeatingSetpoint, + clusters.Thermostat.attributes.AbsMinCoolSetpointLimit, + clusters.Thermostat.attributes.AbsMaxCoolSetpointLimit, + clusters.Thermostat.attributes.AbsMinHeatSetpointLimit, + clusters.Thermostat.attributes.AbsMaxHeatSetpointLimit, + clusters.Thermostat.attributes.SystemMode, + clusters.Thermostat.attributes.ThermostatRunningState, + clusters.Thermostat.attributes.ControlSequenceOfOperation, + clusters.TemperatureMeasurement.attributes.MeasuredValue, + clusters.TemperatureMeasurement.attributes.MinMeasuredValue, + clusters.TemperatureMeasurement.attributes.MaxMeasuredValue, + clusters.RelativeHumidityMeasurement.attributes.MeasuredValue, + clusters.FanControl.attributes.FanMode, + clusters.FanControl.attributes.FanModeSequence, + clusters.PowerSource.attributes.BatPercentRemaining, + } + local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) + for i, cluster in ipairs(cluster_subscribe_list) do + if i > 1 then + subscribe_request:merge(cluster:subscribe(mock_device)) + end + end + test.socket.matter:__expect_send({mock_device.id, subscribe_request}) + test.mock_device.add_test_device(mock_device) +end +test.set_test_init_function(test_init) + +test.register_message_test( + "Setting the heating setpoint to a Fahrenheit value should send the appropriate commands", + { + { + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "thermostatHeatingSetpoint", component = "main", command = "setHeatingSetpoint", args = { 90 } } + } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + clusters.Thermostat.attributes.OccupiedHeatingSetpoint:write(mock_device, 1, + utils.round((90 - 32) * (5 / 9.0) * 100)) + } + }, + { + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "thermostatHeatingSetpoint", component = "main", command = "setHeatingSetpoint", args = { 41 } } + } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + clusters.Thermostat.attributes.OccupiedHeatingSetpoint:write(mock_device, 1, + utils.round((41 - 32) * (5 / 9.0) * 100)) + } + }, + { + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "thermostatHeatingSetpoint", component = "main", command = "setHeatingSetpoint", args = { 35 } } + } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + clusters.Thermostat.attributes.OccupiedHeatingSetpoint:write(mock_device, 1, 35 * 100) + } + } + } +) + +test.run_registered_tests() diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_water_heater.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_water_heater.lua index 4f50ee621a..8fed2e2c62 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_water_heater.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_water_heater.lua @@ -106,29 +106,6 @@ local function test_init() end test.set_test_init_function(test_init) -test.register_message_test( - "Setting the heating setpoint to a Fahrenheit value should send the appropriate commands", - { - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "thermostatHeatingSetpoint", component = "main", command = "setHeatingSetpoint", args = { 90 } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.Thermostat.attributes.OccupiedHeatingSetpoint:write(mock_device, WATER_HEATER_EP, - utils.round((90 - 32) * (5 / 9.0) * 100)) - } - } - } -) - test.register_message_test( "Heating setpoint reports should generate correct messages", { @@ -140,6 +117,12 @@ test.register_message_test( clusters.Thermostat.server.attributes.OccupiedHeatingSetpoint:build_test_report_data(mock_device, 1, 70*100) } }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", + capabilities.thermostatHeatingSetpoint.heatingSetpointRange({ value = { minimum = 0.00, maximum = 100.00, step = 0.1 }, unit = "C" })) + }, { channel = "capability", direction = "send", @@ -170,28 +153,6 @@ test.register_message_test( } ) -test.register_message_test( - "Setting the heating setpoint to a Fahrenheit value should send the appropriate commands", - { - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "thermostatHeatingSetpoint", component = "main", command = "setHeatingSetpoint", args = { 100 } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.Thermostat.attributes.OccupiedHeatingSetpoint:write(mock_device, WATER_HEATER_EP, utils.round((100 - 32) * (5 / 9.0) * 100)) - } - } - } -) - test.register_message_test( "Ensure WaterHeaderMode supportedModes are registered and setting Oven mode should send appropriate commands", { From 247072d98e2a78a338d99d9196de76646123e6cd Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Thu, 7 Aug 2025 12:29:50 -0500 Subject: [PATCH 09/12] Additional changes to matter-thermostat UTs --- .../test/test_matter_air_purifier_modular.lua | 61 ++++++++++++++++--- ...est_matter_thermostat_composed_bridged.lua | 2 - 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_air_purifier_modular.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_air_purifier_modular.lua index c21de741e2..e5f44e3289 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_air_purifier_modular.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_air_purifier_modular.lua @@ -11,15 +11,19 @@ -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -- See the License for the specific language governing permissions and -- limitations under the License. + local test = require "integration_test" -test.set_rpc_version(8) local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" local utils = require "st.utils" local dkjson = require "dkjson" local clusters = require "st.matter.clusters" +local im = require "st.matter.interaction_model" +local uint32 = require "st.matter.data_types.Uint32" local version = require "version" +test.disable_startup_messages() + if version.api < 10 then clusters.HepaFilterMonitoring = require "HepaFilterMonitoring" clusters.ActivatedCarbonFilterMonitoring = require "ActivatedCarbonFilterMonitoring" @@ -224,6 +228,21 @@ local cluster_subscribe_list_configured = { } local function test_init_basic() + test.mock_device.add_test_device(mock_device_basic) + test.socket.device_lifecycle:__queue_receive({ mock_device_basic.id, "added" }) + local read_attributes = { + clusters.Thermostat.attributes.ControlSequenceOfOperation, + clusters.FanControl.attributes.FanModeSequence, + clusters.FanControl.attributes.WindSupport, + clusters.FanControl.attributes.RockSupport, + } + local read_request = im.InteractionRequest(im.InteractionRequest.RequestType.READ, {}) + for _, clus in ipairs(read_attributes) do + read_request:merge(clus:read(mock_device_basic)) + end + test.socket.matter:__expect_send({ mock_device_basic.id, read_request }) + + test.socket.device_lifecycle:__queue_receive({ mock_device_basic.id, "init" }) local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_basic) for i, cluster in ipairs(cluster_subscribe_list) do if i > 1 then @@ -231,10 +250,25 @@ local function test_init_basic() end end test.socket.matter:__expect_send({mock_device_basic.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_basic) end local function test_init_ap_thermo_aqs_preconfigured() + test.mock_device.add_test_device(mock_device_ap_thermo_aqs) + test.socket.device_lifecycle:__queue_receive({ mock_device_ap_thermo_aqs.id, "added" }) + local read_attributes = { + clusters.Thermostat.attributes.AttributeList, + clusters.Thermostat.attributes.ControlSequenceOfOperation, + clusters.FanControl.attributes.FanModeSequence, + clusters.FanControl.attributes.WindSupport, + clusters.FanControl.attributes.RockSupport, + } + local read_request = im.InteractionRequest(im.InteractionRequest.RequestType.READ, {}) + for _, clus in ipairs(read_attributes) do + read_request:merge(clus:read(mock_device_ap_thermo_aqs)) + end + test.socket.matter:__expect_send({ mock_device_ap_thermo_aqs.id, read_request }) + + test.socket.device_lifecycle:__queue_receive({ mock_device_ap_thermo_aqs.id, "init" }) local subscribe_request = nil for _, attributes in pairs(cluster_subscribe_list_configured) do for _, attribute in ipairs(attributes) do @@ -246,7 +280,6 @@ local function test_init_ap_thermo_aqs_preconfigured() end end test.socket.matter:__expect_send({mock_device_ap_thermo_aqs.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_ap_thermo_aqs) end local expected_update_metadata= { @@ -283,11 +316,16 @@ local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_basic) test.register_coroutine_test( "Test profile change on init for basic Air Purifier device", function() - mock_device_basic:set_field("__BATTERY_SUPPORT", "NO_BATTERY") -- since we're assuming this would have happened during device_added in this case. - mock_device_basic:set_field("__THERMOSTAT_RUNNING_STATE_SUPPORT", false) -- since we're assuming this would have happened during device_added in this case. test.socket.device_lifecycle:__queue_receive({ mock_device_basic.id, "doConfigure" }) + test.socket.matter:__queue_receive({ + mock_device_basic.id, + clusters.Thermostat.attributes.AttributeList:build_test_report_data(mock_device_basic, 1, {uint32(0)}) + }) mock_device_basic:expect_metadata_update(expected_update_metadata) mock_device_basic:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + + test.wait_for_events() + local device_info_copy = utils.deep_copy(mock_device_basic.raw_st_data) device_info_copy.profile.id = "air-purifier-modular" local device_info_json = dkjson.encode(device_info_copy) @@ -339,7 +377,6 @@ local expected_update_metadata= { local subscribe_request = nil for _, attributes in pairs(cluster_subscribe_list_configured) do - print("Adding attribute to subscribe", attributes) for _, attribute in ipairs(attributes) do if subscribe_request == nil then subscribe_request = attribute:subscribe(mock_device_ap_thermo_aqs) @@ -352,11 +389,17 @@ end test.register_coroutine_test( "Test profile change on init for AP and Thermo and AQS combined device type", function() - mock_device_ap_thermo_aqs:set_field("__BATTERY_SUPPORT", "NO_BATTERY") -- since we're assuming this would have happened during device_added in this case. - mock_device_ap_thermo_aqs:set_field("__THERMOSTAT_RUNNING_STATE_SUPPORT", false) -- since we're assuming this would have happened during device_added in this case. test.socket.device_lifecycle:__queue_receive({ mock_device_ap_thermo_aqs.id, "doConfigure" }) - mock_device_ap_thermo_aqs:expect_metadata_update(expected_update_metadata) mock_device_ap_thermo_aqs:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.wait_for_events() + test.socket.matter:__queue_receive({ + mock_device_ap_thermo_aqs.id, + clusters.Thermostat.attributes.AttributeList:build_test_report_data(mock_device_ap_thermo_aqs, 1, {uint32(0)}) + }) + mock_device_ap_thermo_aqs:expect_metadata_update(expected_update_metadata) + + test.wait_for_events() + local device_info_copy = utils.deep_copy(mock_device_ap_thermo_aqs.raw_st_data) device_info_copy.profile.id = "air-purifier-modular" local device_info_json = dkjson.encode(device_info_copy) diff --git a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_composed_bridged.lua b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_composed_bridged.lua index c95592e0fb..e901ac59a4 100644 --- a/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_composed_bridged.lua +++ b/drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_composed_bridged.lua @@ -15,8 +15,6 @@ local test = require "integration_test" local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" -local utils = require "st.utils" - local clusters = require "st.matter.clusters" local mock_device = test.mock_device.build_test_matter_device({ From 5d86cd647537d982ec99e0076a2c576877a81327 Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Thu, 7 Aug 2025 12:39:12 -0500 Subject: [PATCH 10/12] Updating UTs for matter-window-covering --- .../src/test/test_matter_window_covering.lua | 92 ++++++++----------- 1 file changed, 36 insertions(+), 56 deletions(-) diff --git a/drivers/SmartThings/matter-window-covering/src/test/test_matter_window_covering.lua b/drivers/SmartThings/matter-window-covering/src/test/test_matter_window_covering.lua index ed9d81f7f1..7f93764feb 100644 --- a/drivers/SmartThings/matter-window-covering/src/test/test_matter_window_covering.lua +++ b/drivers/SmartThings/matter-window-covering/src/test/test_matter_window_covering.lua @@ -17,8 +17,11 @@ local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" local uint32 = require "st.matter.data_types.Uint32" local clusters = require "st.matter.clusters" + local WindowCovering = clusters.WindowCovering +test.disable_startup_messages() + local mock_device = test.mock_device.build_test_matter_device( { profile = t_utils.get_profile_definition("window-covering-tilt-battery.yml"), @@ -36,44 +39,12 @@ local mock_device = test.mock_device.build_test_matter_device( }, { endpoint_id = 10, - clusters = { -- list the clusters - { - cluster_id = clusters.WindowCovering.ID, - cluster_type = "SERVER", - cluster_revision = 1, - feature_map = 3, - }, - {cluster_id = clusters.LevelControl.ID, cluster_type = "SERVER"}, - {cluster_id = clusters.PowerSource.ID, cluster_type = "SERVER", feature_map = 0x0002} - }, - }, - }, - } -) - -local mock_device_switch_to_battery = test.mock_device.build_test_matter_device( - { - profile = t_utils.get_profile_definition("window-covering.yml"), - manufacturer_info = {vendor_id = 0x0000, product_id = 0x0000}, - preferences = { presetPosition = 30 }, - endpoints = { - { - endpoint_id = 2, clusters = { - {cluster_id = clusters.Basic.ID, cluster_type = "SERVER"}, - }, - device_types = { - device_type_id = 0x0016, device_type_revision = 1, -- RootNode - } - }, - { - endpoint_id = 10, - clusters = { -- list the clusters { cluster_id = clusters.WindowCovering.ID, cluster_type = "SERVER", cluster_revision = 1, - feature_map = 1, + feature_map = 3, }, {cluster_id = clusters.LevelControl.ID, cluster_type = "SERVER"}, {cluster_id = clusters.PowerSource.ID, cluster_type = "SERVER", feature_map = 0x0002} @@ -100,7 +71,7 @@ local mock_device_mains_powered = test.mock_device.build_test_matter_device( }, { endpoint_id = 10, - clusters = { -- list the clusters + clusters = { { cluster_id = clusters.WindowCovering.ID, cluster_type = "SERVER", @@ -130,34 +101,45 @@ local CLUSTER_SUBSCRIBE_LIST_NO_BATTERY = { } local function test_init() + test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message( + "main", capabilities.windowShade.supportedWindowShadeCommands({"open", "close", "pause"}, + {visibility = {displayed = false}}) + ) + ) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) local subscribe_request = CLUSTER_SUBSCRIBE_LIST[1]:subscribe(mock_device) for i, clus in ipairs(CLUSTER_SUBSCRIBE_LIST) do if i > 1 then subscribe_request:merge(clus:subscribe(mock_device)) end end test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) -end -local function test_init_switch_to_battery() - local subscribe_request = CLUSTER_SUBSCRIBE_LIST_NO_BATTERY[1]:subscribe(mock_device_switch_to_battery) - for i, clus in ipairs(CLUSTER_SUBSCRIBE_LIST_NO_BATTERY) do - if i > 1 then subscribe_request:merge(clus:subscribe(mock_device_switch_to_battery)) end - end - test.socket.matter:__expect_send({mock_device_switch_to_battery.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_switch_to_battery) - test.socket.device_lifecycle:__queue_receive({ mock_device_switch_to_battery.id, "doConfigure" }) - mock_device_switch_to_battery:expect_metadata_update({ provisioning_state = "PROVISIONED" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) local read_attribute_list = clusters.PowerSource.attributes.AttributeList:read() - test.socket.matter:__expect_send({mock_device_switch_to_battery.id, read_attribute_list}) + test.socket.matter:__expect_send({mock_device.id, read_attribute_list}) end local function test_init_mains_powered() + test.mock_device.add_test_device(mock_device_mains_powered) + test.socket.device_lifecycle:__queue_receive({ mock_device_mains_powered.id, "added" }) + test.socket.capability:__expect_send( + mock_device_mains_powered:generate_test_message( + "main", capabilities.windowShade.supportedWindowShadeCommands({"open", "close", "pause"}, + {visibility = {displayed = false}}) + ) + ) + + test.socket.device_lifecycle:__queue_receive({ mock_device_mains_powered.id, "init" }) local subscribe_request = CLUSTER_SUBSCRIBE_LIST_NO_BATTERY[1]:subscribe(mock_device_mains_powered) for i, clus in ipairs(CLUSTER_SUBSCRIBE_LIST_NO_BATTERY) do if i > 1 then subscribe_request:merge(clus:subscribe(mock_device_mains_powered)) end end test.socket.matter:__expect_send({mock_device_mains_powered.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_mains_powered) + test.socket.device_lifecycle:__queue_receive({ mock_device_mains_powered.id, "doConfigure" }) mock_device_mains_powered:expect_metadata_update({ profile = "window-covering" }) mock_device_mains_powered:expect_metadata_update({ provisioning_state = "PROVISIONED" }) @@ -794,13 +776,12 @@ test.register_coroutine_test( function() test.socket.matter:__queue_receive( { - mock_device_switch_to_battery.id, - clusters.PowerSource.attributes.AttributeList:build_test_report_data(mock_device_switch_to_battery, 10, {uint32(12)}) + mock_device.id, + clusters.PowerSource.attributes.AttributeList:build_test_report_data(mock_device, 10, {uint32(12)}) } ) - mock_device_switch_to_battery:expect_metadata_update({ profile = "window-covering-battery" }) - end, - { test_init = test_init_switch_to_battery } + mock_device:expect_metadata_update({ profile = "window-covering-tilt-battery" }) + end ) test.register_coroutine_test( @@ -808,12 +789,11 @@ test.register_coroutine_test( function() test.socket.matter:__queue_receive( { - mock_device_switch_to_battery.id, - clusters.PowerSource.attributes.AttributeList:build_test_report_data(mock_device_switch_to_battery, 10, {uint32(10)}) + mock_device.id, + clusters.PowerSource.attributes.AttributeList:build_test_report_data(mock_device, 10, {uint32(10)}) } ) - end, - { test_init = test_init_switch_to_battery } + end ) test.register_coroutine_test( From f39f3f736e8fdb913e234d5ff8bf96d4c36e25d4 Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Wed, 13 Aug 2025 10:06:13 -0500 Subject: [PATCH 11/12] Addressing review feedback --- .../src/test/test_new_matter_lock_battery.lua | 168 +----- .../src/test/test_matter_media_speaker.lua | 547 +++++++++--------- .../test/test_matter_media_video_player.lua | 137 ++--- .../test/test_matter_freeze_leak_sensor.lua | 77 ++- 4 files changed, 362 insertions(+), 567 deletions(-) diff --git a/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua index 728f452d79..d8657ccae3 100644 --- a/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua +++ b/drivers/SmartThings/matter-lock/src/test/test_new_matter_lock_battery.lua @@ -186,6 +186,12 @@ local function test_init() subscribe_request:merge(DoorLock.events.LockOperation:subscribe(mock_device)) subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device)) test.socket["matter"]:__expect_send({mock_device.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) + test.socket.capability:__expect_send( + mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) + ) + test.socket.matter:__expect_send({mock_device.id, clusters.PowerSource.attributes.AttributeList:read()}) + mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function test_init_unlatch() @@ -201,6 +207,12 @@ local function test_init_unlatch() subscribe_request:merge(DoorLock.events.LockOperation:subscribe(mock_device_unlatch)) subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device_unlatch)) test.socket["matter"]:__expect_send({mock_device_unlatch.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_device_unlatch.id, "doConfigure" }) + test.socket.capability:__expect_send( + mock_device_unlatch:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}})) + ) + test.socket.matter:__expect_send({mock_device_unlatch.id, clusters.PowerSource.attributes.AttributeList:read()}) + mock_device_unlatch:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function test_init_user_pin() @@ -222,6 +234,12 @@ local function test_init_user_pin() subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device_user_pin)) subscribe_request:merge(DoorLock.events.LockUserChange:subscribe(mock_device_user_pin)) test.socket["matter"]:__expect_send({mock_device_user_pin.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin.id, "doConfigure" }) + test.socket.capability:__expect_send( + mock_device_user_pin:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) + ) + test.socket.matter:__expect_send({mock_device_user_pin.id, clusters.PowerSource.attributes.AttributeList:read()}) + mock_device_user_pin:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function test_init_user_pin_schedule_unlatch() @@ -245,6 +263,12 @@ local function test_init_user_pin_schedule_unlatch() subscribe_request:merge(DoorLock.events.DoorLockAlarm:subscribe(mock_device_user_pin_schedule_unlatch)) subscribe_request:merge(DoorLock.events.LockUserChange:subscribe(mock_device_user_pin_schedule_unlatch)) test.socket["matter"]:__expect_send({mock_device_user_pin_schedule_unlatch.id, subscribe_request}) + test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin_schedule_unlatch.id, "doConfigure" }) + test.socket.capability:__expect_send( + mock_device_user_pin_schedule_unlatch:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}})) + ) + test.socket.matter:__expect_send({mock_device_user_pin_schedule_unlatch.id, clusters.PowerSource.attributes.AttributeList:read()}) + mock_device_user_pin_schedule_unlatch:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end test.set_test_init_function(test_init) @@ -252,18 +276,6 @@ test.set_test_init_function(test_init) test.register_coroutine_test( "Test lock profile change when attributes related to BAT feature is not available.", function() - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) - mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device.id, @@ -288,18 +300,6 @@ test.register_coroutine_test( test.register_coroutine_test( "Test lock profile change when BatChargeLevel attribute is available", function() - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) - mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device.id, @@ -325,18 +325,6 @@ test.register_coroutine_test( test.register_coroutine_test( "Test lock profile change when BatChargeLevel and BatPercentRemaining attributes are available", function() - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) - mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device.id, @@ -363,18 +351,6 @@ test.register_coroutine_test( test.register_coroutine_test( "Test lock-unlatch profile change when attributes related to BAT feature is not available.", function() - test.socket.device_lifecycle:__queue_receive({ mock_device_unlatch.id, "doConfigure" }) - mock_device_unlatch:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device_unlatch:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device_unlatch.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device_unlatch.id, @@ -400,18 +376,6 @@ test.register_coroutine_test( test.register_coroutine_test( "Test lock-unlatch profile change when BatChargeLevel attribute is available", function() - test.socket.device_lifecycle:__queue_receive({ mock_device_unlatch.id, "doConfigure" }) - mock_device_unlatch:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device_unlatch:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device_unlatch.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device_unlatch.id, @@ -438,18 +402,6 @@ test.register_coroutine_test( test.register_coroutine_test( "Test lock-unlatch profile change when BatChargeLevel and BatPercentRemaining attributes are available", function() - test.socket.device_lifecycle:__queue_receive({ mock_device_unlatch.id, "doConfigure" }) - mock_device_unlatch:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device_unlatch:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device_unlatch.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device_unlatch.id, @@ -477,18 +429,6 @@ test.register_coroutine_test( test.register_coroutine_test( "Test lock-user-pin profile change when attributes related to BAT feature is not available.", function() - test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin.id, "doConfigure" }) - mock_device_user_pin:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device_user_pin:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device_user_pin.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device_user_pin.id, @@ -514,18 +454,6 @@ test.register_coroutine_test( test.register_coroutine_test( "Test lock-user-pin profile change when BatChargeLevel attribute is available", function() - test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin.id, "doConfigure" }) - mock_device_user_pin:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device_user_pin:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device_user_pin.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device_user_pin.id, @@ -552,18 +480,6 @@ test.register_coroutine_test( test.register_coroutine_test( "Test lock-user-pin profile change when BatChargeLevel and BatPercentRemaining attributes are available", function() - test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin.id, "doConfigure" }) - mock_device_user_pin:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device_user_pin:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device_user_pin.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device_user_pin.id, @@ -591,18 +507,6 @@ test.register_coroutine_test( test.register_coroutine_test( "Test lock-user-pin-schedule-unlatch profile change when attributes related to BAT feature is not available.", function() - test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin_schedule_unlatch.id, "doConfigure" }) - mock_device_user_pin_schedule_unlatch:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device_user_pin_schedule_unlatch:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device_user_pin_schedule_unlatch.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device_user_pin_schedule_unlatch.id, @@ -628,18 +532,6 @@ test.register_coroutine_test( test.register_coroutine_test( "Test lock-user-pin-schedule-unlatch profile change when BatChargeLevel attribute is available", function() - test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin_schedule_unlatch.id, "doConfigure" }) - mock_device_user_pin_schedule_unlatch:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device_user_pin_schedule_unlatch:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device_user_pin_schedule_unlatch.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device_user_pin_schedule_unlatch.id, @@ -666,18 +558,6 @@ test.register_coroutine_test( test.register_coroutine_test( "Test lock-user-pin-schedule-unlatch profile change when BatChargeLevel and BatPercentRemaining attributes are available", function() - test.socket.device_lifecycle:__queue_receive({ mock_device_user_pin_schedule_unlatch.id, "doConfigure" }) - mock_device_user_pin_schedule_unlatch:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - test.socket.capability:__expect_send( - mock_device_user_pin_schedule_unlatch:generate_test_message("main", capabilities.lock.supportedLockCommands({"lock", "unlock", "unlatch"}, {visibility = {displayed = false}})) - ) - test.socket.matter:__expect_send( - { - mock_device_user_pin_schedule_unlatch.id, - clusters.PowerSource.attributes.AttributeList:read() - } - ) - test.wait_for_events() test.socket.matter:__queue_receive( { mock_device_user_pin_schedule_unlatch.id, diff --git a/drivers/SmartThings/matter-media/src/test/test_matter_media_speaker.lua b/drivers/SmartThings/matter-media/src/test/test_matter_media_speaker.lua index 03a1ddb8da..cf5bc44648 100644 --- a/drivers/SmartThings/matter-media/src/test/test_matter_media_speaker.lua +++ b/drivers/SmartThings/matter-media/src/test/test_matter_media_speaker.lua @@ -15,7 +15,6 @@ local test = require "integration_test" local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" - local clusters = require "st.matter.clusters" local mock_device = test.mock_device.build_test_matter_device({ @@ -49,21 +48,14 @@ local mock_device = test.mock_device.build_test_matter_device({ } }) - local function test_init() test.disable_startup_messages() test.mock_device.add_test_device(mock_device) - local cluster_subscribe_list = { - clusters.OnOff.attributes.OnOff, - clusters.LevelControl.attributes.CurrentLevel - } - local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) - for i, cluster in ipairs(cluster_subscribe_list) do - if i > 1 then - subscribe_request:merge(cluster:subscribe(mock_device)) - end - end + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + local subscribe_request = clusters.OnOff.attributes.OnOff:subscribe(mock_device) + subscribe_request:merge(clusters.LevelControl.attributes.CurrentLevel:subscribe(mock_device)) test.socket.matter:__expect_send({mock_device.id, subscribe_request}) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) @@ -72,267 +64,267 @@ end test.set_test_init_function(test_init) test.register_message_test( - "Mute and unmute commands should send the appropriate commands", + "Mute and unmute commands should send the appropriate commands", + { { - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "audioMute", component = "main", command = "mute", args = { } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.OnOff.server.commands.Off(mock_device, 10) - } - }, - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "audioMute", component = "main", command = "unmute", args = { } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.OnOff.server.commands.On(mock_device, 10) - } - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.OnOff.attributes.OnOff:build_test_report_data(mock_device, 10, true) - } - }, - { - channel = "capability", - direction = "send", - message = mock_device:generate_test_message("main", capabilities.audioMute.mute.unmuted()) - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.OnOff.attributes.OnOff:build_test_report_data(mock_device, 10, false) - } - }, - { - channel = "capability", - direction = "send", - message = mock_device:generate_test_message("main", capabilities.audioMute.mute.muted()) - } + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "audioMute", component = "main", command = "mute", args = { } } + } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + clusters.OnOff.server.commands.Off(mock_device, 10) + } + }, + { + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "audioMute", component = "main", command = "unmute", args = { } } } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + clusters.OnOff.server.commands.On(mock_device, 10) + } + }, + { + channel = "matter", + direction = "receive", + message = { + mock_device.id, + clusters.OnOff.attributes.OnOff:build_test_report_data(mock_device, 10, true) + } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.audioMute.mute.unmuted()) + }, + { + channel = "matter", + direction = "receive", + message = { + mock_device.id, + clusters.OnOff.attributes.OnOff:build_test_report_data(mock_device, 10, false) + } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.audioMute.mute.muted()) + } + } ) test.register_message_test( - "Set mute command should send the appropriate commands", - { - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "audioMute", component = "main", command = "setMute", args = { "muted" } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.OnOff.server.commands.Off(mock_device, 10) - } - }, - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "audioMute", component = "main", command = "setMute", args = { "unmuted" } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.OnOff.server.commands.On(mock_device, 10) - } - } + "Set mute command should send the appropriate commands", + { + { + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "audioMute", component = "main", command = "setMute", args = { "muted" } } + } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + clusters.OnOff.server.commands.Off(mock_device, 10) + } + }, + { + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "audioMute", component = "main", command = "setMute", args = { "unmuted" } } + } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + clusters.OnOff.server.commands.On(mock_device, 10) + } } + } ) test.register_message_test( - "Set volume command should send the appropriate commands", + "Set volume command should send the appropriate commands", + { { - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "audioVolume", component = "main", command = "setVolume", args = { 20 } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.LevelControl.server.commands.MoveToLevelWithOnOff(mock_device, 10, math.floor(20/100.0 * 254), 0, 0, 0) - } - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.LevelControl.server.commands.MoveToLevelWithOnOff:build_test_command_response(mock_device, 10) - } - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.LevelControl.attributes.CurrentLevel:build_test_report_data(mock_device, 10, 50) - } - }, - { - channel = "capability", - direction = "send", - message = mock_device:generate_test_message("main", capabilities.audioVolume.volume(20)) - } + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "audioVolume", component = "main", command = "setVolume", args = { 20 } } + } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + clusters.LevelControl.server.commands.MoveToLevelWithOnOff(mock_device, 10, math.floor(20/100.0 * 254), 0, 0, 0) + } + }, + { + channel = "matter", + direction = "receive", + message = { + mock_device.id, + clusters.LevelControl.server.commands.MoveToLevelWithOnOff:build_test_command_response(mock_device, 10) + } + }, + { + channel = "matter", + direction = "receive", + message = { + mock_device.id, + clusters.LevelControl.attributes.CurrentLevel:build_test_report_data(mock_device, 10, 50) + } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.audioVolume.volume(20)) } + } ) test.register_message_test( - "Volume up/down command should send the appropriate commands", + "Volume up/down command should send the appropriate commands", + { { - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "audioVolume", component = "main", command = "setVolume", args = { 20 } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.LevelControl.server.commands.MoveToLevelWithOnOff(mock_device, 10, math.floor(20/100.0 * 254), 0, 0, 0) - } - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.LevelControl.server.commands.MoveToLevelWithOnOff:build_test_command_response(mock_device, 10) - } - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.LevelControl.attributes.CurrentLevel:build_test_report_data(mock_device, 10, 50 ) - } - }, - { - channel = "capability", - direction = "send", - message = mock_device:generate_test_message("main", capabilities.audioVolume.volume(20)) - }, - -- volume up - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "audioVolume", component = "main", command = "volumeUp", args = { } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.LevelControl.server.commands.MoveToLevelWithOnOff(mock_device, 10, math.floor(25/100.0 * 254), 0, 0, 0) - } - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.LevelControl.server.commands.MoveToLevelWithOnOff:build_test_command_response(mock_device, 10) - } - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.LevelControl.attributes.CurrentLevel:build_test_report_data(mock_device, 10, 63 ) - } - }, - { - channel = "capability", - direction = "send", - message = mock_device:generate_test_message("main", capabilities.audioVolume.volume(25)) - }, - -- volume down - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "audioVolume", component = "main", command = "volumeDown", args = { } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - clusters.LevelControl.server.commands.MoveToLevelWithOnOff(mock_device, 10, math.floor(20/100.0 * 254), 0, 0, 0) - } - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.LevelControl.server.commands.MoveToLevelWithOnOff:build_test_command_response(mock_device, 10) - } - }, - { - channel = "matter", - direction = "receive", - message = { - mock_device.id, - clusters.LevelControl.attributes.CurrentLevel:build_test_report_data(mock_device, 10, 50 ) - } - }, - { - channel = "capability", - direction = "send", - message = mock_device:generate_test_message("main", capabilities.audioVolume.volume(20)) - }, - } + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "audioVolume", component = "main", command = "setVolume", args = { 20 } } + } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + clusters.LevelControl.server.commands.MoveToLevelWithOnOff(mock_device, 10, math.floor(20/100.0 * 254), 0, 0, 0) + } + }, + { + channel = "matter", + direction = "receive", + message = { + mock_device.id, + clusters.LevelControl.server.commands.MoveToLevelWithOnOff:build_test_command_response(mock_device, 10) + } + }, + { + channel = "matter", + direction = "receive", + message = { + mock_device.id, + clusters.LevelControl.attributes.CurrentLevel:build_test_report_data(mock_device, 10, 50 ) + } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.audioVolume.volume(20)) + }, + -- volume up + { + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "audioVolume", component = "main", command = "volumeUp", args = { } } + } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + clusters.LevelControl.server.commands.MoveToLevelWithOnOff(mock_device, 10, math.floor(25/100.0 * 254), 0, 0, 0) + } + }, + { + channel = "matter", + direction = "receive", + message = { + mock_device.id, + clusters.LevelControl.server.commands.MoveToLevelWithOnOff:build_test_command_response(mock_device, 10) + } + }, + { + channel = "matter", + direction = "receive", + message = { + mock_device.id, + clusters.LevelControl.attributes.CurrentLevel:build_test_report_data(mock_device, 10, 63 ) + } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.audioVolume.volume(25)) + }, + -- volume down + { + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "audioVolume", component = "main", command = "volumeDown", args = { } } + } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + clusters.LevelControl.server.commands.MoveToLevelWithOnOff(mock_device, 10, math.floor(20/100.0 * 254), 0, 0, 0) + } + }, + { + channel = "matter", + direction = "receive", + message = { + mock_device.id, + clusters.LevelControl.server.commands.MoveToLevelWithOnOff:build_test_command_response(mock_device, 10) + } + }, + { + channel = "matter", + direction = "receive", + message = { + mock_device.id, + clusters.LevelControl.attributes.CurrentLevel:build_test_report_data(mock_device, 10, 50 ) + } + }, + { + channel = "capability", + direction = "send", + message = mock_device:generate_test_message("main", capabilities.audioVolume.volume(20)) + }, + } ) local function refresh_commands(dev) @@ -342,25 +334,24 @@ local function refresh_commands(dev) end test.register_message_test( - "Handle received refresh.", - { - { - channel = "capability", - direction = "receive", - message = { - mock_device.id, - { capability = "refresh", component = "main", command = "refresh", args = { } } - } - }, - { - channel = "matter", - direction = "send", - message = { - mock_device.id, - refresh_commands(mock_device) - } - }, - } + "Handle received refresh.", + { + { + channel = "capability", + direction = "receive", + message = { + mock_device.id, + { capability = "refresh", component = "main", command = "refresh", args = { } } + } + }, + { + channel = "matter", + direction = "send", + message = { + mock_device.id, + refresh_commands(mock_device) + } + }, + } ) - test.run_registered_tests() diff --git a/drivers/SmartThings/matter-media/src/test/test_matter_media_video_player.lua b/drivers/SmartThings/matter-media/src/test/test_matter_media_video_player.lua index 1c82b5dd6f..ebae93ca53 100644 --- a/drivers/SmartThings/matter-media/src/test/test_matter_media_video_player.lua +++ b/drivers/SmartThings/matter-media/src/test/test_matter_media_video_player.lua @@ -15,7 +15,6 @@ local test = require "integration_test" local capabilities = require "st.capabilities" local t_utils = require "integration_test.utils" - local clusters = require "st.matter.clusters" local mock_device = test.mock_device.build_test_matter_device({ @@ -84,21 +83,41 @@ local mock_device_variable_speed = test.mock_device.build_test_matter_device({ } }) +local supported_key_codes = { + "UP", + "DOWN", + "LEFT", + "RIGHT", + "SELECT", + "BACK", + "EXIT", + "MENU", + "SETTINGS", + "HOME", + "NUMBER0", + "NUMBER1", + "NUMBER2", + "NUMBER3", + "NUMBER4", + "NUMBER5", + "NUMBER6", + "NUMBER7", + "NUMBER8", + "NUMBER9" +} local function test_init() test.disable_startup_messages() test.mock_device.add_test_device(mock_device) + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" }) + + test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) local cluster_subscribe_list = { clusters.OnOff.attributes.OnOff, clusters.MediaPlayback.attributes.CurrentState } local subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device) - for i, cluster in ipairs(cluster_subscribe_list) do - if i > 1 then - subscribe_request:merge(cluster:subscribe(mock_device)) - end - end - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" }) + subscribe_request:merge(cluster_subscribe_list[2]:subscribe(mock_device)) test.socket.matter:__expect_send({mock_device.id, subscribe_request}) test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) @@ -116,41 +135,16 @@ local function test_init() ) test.socket.capability:__expect_send( mock_device:generate_test_message( - "main", capabilities.keypadInput.supportedKeyCodes({ - "UP", - "DOWN", - "LEFT", - "RIGHT", - "SELECT", - "BACK", - "EXIT", - "MENU", - "SETTINGS", - "HOME", - "NUMBER0", - "NUMBER1", - "NUMBER2", - "NUMBER3", - "NUMBER4", - "NUMBER5", - "NUMBER6", - "NUMBER7", - "NUMBER8", - "NUMBER9" - }) + "main", capabilities.keypadInput.supportedKeyCodes(supported_key_codes) ) ) test.mock_device.add_test_device(mock_device_variable_speed) - subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_variable_speed) - for i, cluster in ipairs(cluster_subscribe_list) do - print(i) - if i > 1 then - subscribe_request:merge(cluster:subscribe(mock_device_variable_speed)) - end - print(subscribe_request) - end + test.socket.device_lifecycle:__queue_receive({ mock_device_variable_speed.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_variable_speed.id, "init" }) + subscribe_request = cluster_subscribe_list[1]:subscribe(mock_device_variable_speed) + subscribe_request:merge(cluster_subscribe_list[2]:subscribe(mock_device_variable_speed)) test.socket.matter:__expect_send({mock_device_variable_speed.id, subscribe_request}) test.socket.device_lifecycle:__queue_receive({ mock_device_variable_speed.id, "doConfigure" }) @@ -168,28 +162,7 @@ local function test_init() ) test.socket.capability:__expect_send( mock_device_variable_speed:generate_test_message( - "main", capabilities.keypadInput.supportedKeyCodes({ - "UP", - "DOWN", - "LEFT", - "RIGHT", - "SELECT", - "BACK", - "EXIT", - "MENU", - "SETTINGS", - "HOME", - "NUMBER0", - "NUMBER1", - "NUMBER2", - "NUMBER3", - "NUMBER4", - "NUMBER5", - "NUMBER6", - "NUMBER7", - "NUMBER8", - "NUMBER9" - }) + "main", capabilities.keypadInput.supportedKeyCodes(supported_key_codes) ) ) end @@ -637,28 +610,7 @@ test.register_coroutine_test( test.socket.capability:__expect_send( mock_device:generate_test_message( "main", - capabilities.keypadInput.supportedKeyCodes({ - "UP", - "DOWN", - "LEFT", - "RIGHT", - "SELECT", - "BACK", - "EXIT", - "MENU", - "SETTINGS", - "HOME", - "NUMBER0", - "NUMBER1", - "NUMBER2", - "NUMBER3", - "NUMBER4", - "NUMBER5", - "NUMBER6", - "NUMBER7", - "NUMBER8", - "NUMBER9", - }) + capabilities.keypadInput.supportedKeyCodes(supported_key_codes) ) ) @@ -688,28 +640,7 @@ test.register_coroutine_test( test.socket.capability:__expect_send( mock_device_variable_speed:generate_test_message( "main", - capabilities.keypadInput.supportedKeyCodes({ - "UP", - "DOWN", - "LEFT", - "RIGHT", - "SELECT", - "BACK", - "EXIT", - "MENU", - "SETTINGS", - "HOME", - "NUMBER0", - "NUMBER1", - "NUMBER2", - "NUMBER3", - "NUMBER4", - "NUMBER5", - "NUMBER6", - "NUMBER7", - "NUMBER8", - "NUMBER9", - }) + capabilities.keypadInput.supportedKeyCodes(supported_key_codes) ) ) diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_freeze_leak_sensor.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_freeze_leak_sensor.lua index a7309839df..7aae047a29 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_freeze_leak_sensor.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_freeze_leak_sensor.lua @@ -19,61 +19,54 @@ local clusters = require "st.matter.clusters" clusters.BooleanStateConfiguration = require "BooleanStateConfiguration" local mock_device_freeze_leak = test.mock_device.build_test_matter_device({ - profile = t_utils.get_profile_definition("freeze-leak-fault-freezeSensitivity-leakSensitivity.yml"), - manufacturer_info = { - vendor_id = 0x0000, - product_id = 0x0000, + profile = t_utils.get_profile_definition("freeze-leak-fault-freezeSensitivity-leakSensitivity.yml"), + manufacturer_info = { + vendor_id = 0x0000, + product_id = 0x0000, + }, + endpoints = { + { + endpoint_id = 0, + clusters = { + {cluster_id = clusters.Basic.ID, cluster_type = "SERVER"}, + }, + device_types = { + {device_type_id = 0x0016, device_type_revision = 1} -- RootNode + } }, - endpoints = { - { - endpoint_id = 0, - clusters = { - {cluster_id = clusters.Basic.ID, cluster_type = "SERVER"}, - }, - device_types = { - {device_type_id = 0x0016, device_type_revision = 1} -- RootNode - } + { + endpoint_id = 1, + clusters = { + {cluster_id = clusters.BooleanState.ID, cluster_type = "SERVER", feature_map = 0}, + {cluster_id = clusters.BooleanStateConfiguration.ID, cluster_type = "SERVER", feature_map = 31}, }, - { - endpoint_id = 1, - clusters = { - {cluster_id = clusters.BooleanState.ID, cluster_type = "SERVER", feature_map = 0}, - {cluster_id = clusters.BooleanStateConfiguration.ID, cluster_type = "SERVER", feature_map = 31}, - }, - device_types = { - {device_type_id = 0x0043, device_type_revision = 1} -- Water Leak Detector - } + device_types = { + {device_type_id = 0x0043, device_type_revision = 1} -- Water Leak Detector + } + }, + { + endpoint_id = 2, + clusters = { + {cluster_id = clusters.BooleanState.ID, cluster_type = "SERVER", feature_map = 0}, + {cluster_id = clusters.BooleanStateConfiguration.ID, cluster_type = "SERVER", feature_map = 31}, }, - { - endpoint_id = 2, - clusters = { - {cluster_id = clusters.BooleanState.ID, cluster_type = "SERVER", feature_map = 0}, - {cluster_id = clusters.BooleanStateConfiguration.ID, cluster_type = "SERVER", feature_map = 31}, - }, - device_types = { - {device_type_id = 0x0041, device_type_revision = 1} -- Water Freeze Detector - } + device_types = { + {device_type_id = 0x0041, device_type_revision = 1} -- Water Freeze Detector } } + } }) -local subscribed_attributes = { - clusters.BooleanState.attributes.StateValue, - clusters.BooleanStateConfiguration.attributes.SensorFault, -} - local function test_init_freeze_leak() test.disable_startup_messages() test.mock_device.add_test_device(mock_device_freeze_leak) - local subscribe_request = subscribed_attributes[1]:subscribe(mock_device_freeze_leak) - for i, cluster in ipairs(subscribed_attributes) do - if i > 1 then - subscribe_request:merge(cluster:subscribe(mock_device_freeze_leak)) - end - end + test.socket.device_lifecycle:__queue_receive({ mock_device_freeze_leak.id, "added" }) + test.socket.device_lifecycle:__queue_receive({ mock_device_freeze_leak.id, "init" }) test.socket.matter:__expect_send({mock_device_freeze_leak.id, clusters.BooleanStateConfiguration.attributes.SupportedSensitivityLevels:read(mock_device_freeze_leak, 1)}) test.socket.matter:__expect_send({mock_device_freeze_leak.id, clusters.BooleanStateConfiguration.attributes.SupportedSensitivityLevels:read(mock_device_freeze_leak, 2)}) + local subscribe_request = clusters.BooleanState.attributes.StateValue:subscribe(mock_device_freeze_leak) + subscribe_request:merge(clusters.BooleanStateConfiguration.attributes.SensorFault:subscribe(mock_device_freeze_leak)) test.socket.matter:__expect_send({mock_device_freeze_leak.id, subscribe_request}) test.socket.device_lifecycle:__queue_receive({ mock_device_freeze_leak.id, "doConfigure" }) From 067efc53f5d14905f2592e687105bf106d7f6130 Mon Sep 17 00:00:00 2001 From: Nick DeBoom Date: Wed, 13 Aug 2025 10:11:39 -0500 Subject: [PATCH 12/12] Luacheck fixes --- .../matter-button/src/test/test_matter_multi_button.lua | 2 +- .../matter-switch/src/test/test_aqara_light_switch_h2.lua | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/SmartThings/matter-button/src/test/test_matter_multi_button.lua b/drivers/SmartThings/matter-button/src/test/test_matter_multi_button.lua index 09f4834a8f..2ecf083ba7 100644 --- a/drivers/SmartThings/matter-button/src/test/test_matter_multi_button.lua +++ b/drivers/SmartThings/matter-button/src/test/test_matter_multi_button.lua @@ -113,7 +113,7 @@ end test.set_test_init_function(test_init) --- this one is failing because it expects added or +-- this one is failing because it expects added or test.register_message_test( "Handle single press sequence, no hold", { { diff --git a/drivers/SmartThings/matter-switch/src/test/test_aqara_light_switch_h2.lua b/drivers/SmartThings/matter-switch/src/test/test_aqara_light_switch_h2.lua index 7e04e0016d..8b4d9ee76f 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_aqara_light_switch_h2.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_aqara_light_switch_h2.lua @@ -17,12 +17,9 @@ local t_utils = require "integration_test.utils" local capabilities = require "st.capabilities" local utils = require "st.utils" local dkjson = require "dkjson" - local clusters = require "st.matter.clusters" local button_attr = capabilities.button.button -local DEFERRED_CONFIGURE = "__DEFERRED_CONFIGURE" - local aqara_parent_ep = 4 local aqara_child1_ep = 1 local aqara_child2_ep = 2