from types import SimpleNamespace from mqtt_home.broker_devices import BrokerDevice, BrokerDeviceRegistry def make_rule(id=1, topic_pattern="home/+/state", device_type="switch", command_template="home/{device_id}/set", state_value_path="state", is_enabled=True): return SimpleNamespace( id=id, topic_pattern=topic_pattern, device_type=device_type, command_template=command_template, state_value_path=state_value_path, is_enabled=is_enabled, ) def test_create_device_on_match(): registry = BrokerDeviceRegistry() rule = make_rule() device = registry.update_or_create("home/fire/state", '{"state":"on"}', rule) assert device is not None assert device.id == "broker:fire" assert device.name == "fire" assert device.type == "switch" assert device.state == "on" assert device.command_topic == "home/fire/set" assert device.is_online is True assert device.rule_id == 1 def test_update_existing_device(): registry = BrokerDeviceRegistry() rule = make_rule() registry.update_or_create("home/fire/state", '{"state":"on"}', rule) device = registry.update_or_create("home/fire/state", '{"state":"off"}', rule) assert device.state == "off" assert len(registry.get_all()) == 1 def test_different_topics_different_devices(): registry = BrokerDeviceRegistry() rule = make_rule() registry.update_or_create("home/fire/state", '{"state":"on"}', rule) registry.update_or_create("home/servo/state", '{"state":"off"}', rule) assert len(registry.get_all()) == 2 def test_no_match_returns_none(): registry = BrokerDeviceRegistry() rule = make_rule(topic_pattern="home/+/state") result = registry.update_or_create("living/light/status", '{"state":"on"}', rule) assert result is None def test_remove_by_rule(): registry = BrokerDeviceRegistry() rule1 = make_rule(id=1) rule2 = make_rule(id=2, topic_pattern="sensor/+/data") registry.update_or_create("home/fire/state", '{"state":"on"}', rule1) registry.update_or_create("sensor/temp/data", '{"value":25}', rule2) assert len(registry.get_all()) == 2 removed = registry.remove_by_rule(1) assert removed == ["broker:fire"] assert len(registry.get_all()) == 1 assert registry.get("broker:fire") is None def test_full_payload_as_state(): registry = BrokerDeviceRegistry() rule = make_rule(state_value_path=None) device = registry.update_or_create("home/fire/state", '{"state":"on","brightness":128}', rule) assert device.state == '{"state":"on","brightness":128}' def test_get_device(): registry = BrokerDeviceRegistry() rule = make_rule() registry.update_or_create("home/fire/state", '{"state":"on"}', rule) assert registry.get("broker:fire") is not None assert registry.get("broker:nonexistent") is None def test_clear(): registry = BrokerDeviceRegistry() rule = make_rule() registry.update_or_create("home/fire/state", '{"state":"on"}', rule) registry.clear() assert len(registry.get_all()) == 0