# switchbot-mqtt - MQTT client controlling SwitchBot button & curtain automators, # compatible with home-assistant.io's MQTT Switch & Cover platform # # Copyright (C) 2020 Fabian Peter Hammerle # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import typing import pytest # pylint: disable=import-private-name; internal from switchbot_mqtt._utils import ( _mac_address_valid, _MQTTTopicLevel, _MQTTTopicPlaceholder, _parse_mqtt_topic, ) @pytest.mark.parametrize( ("mac_address", "valid"), [ ("aa:bb:cc:dd:ee:ff", True), ("AA:BB:CC:DD:EE:FF", True), ("AA:12:34:45:67:89", True), ("aabbccddeeff", False), # not supported by PySwitchbot ("aa:bb:cc:dd:ee:gg", False), ], ) def test__mac_address_valid(mac_address: str, valid: bool) -> None: # pylint: disable=protected-access assert _mac_address_valid(mac_address) == valid @pytest.mark.parametrize( ("expected_prefix", "expected_levels", "topic", "expected_attrs"), [ ( "", ["switchbot", _MQTTTopicPlaceholder.MAC_ADDRESS, "set"], "switchbot/aa:bb:cc:dd:ee:ff/set", {_MQTTTopicPlaceholder.MAC_ADDRESS: "aa:bb:cc:dd:ee:ff"}, ), ( "", ["switchbot", _MQTTTopicPlaceholder.MAC_ADDRESS, "set"], "switchbot//set", {_MQTTTopicPlaceholder.MAC_ADDRESS: ""}, ), ( "", ["prefix", _MQTTTopicPlaceholder.MAC_ADDRESS], "prefix/aa:bb:cc:dd:ee:f1", {_MQTTTopicPlaceholder.MAC_ADDRESS: "aa:bb:cc:dd:ee:f1"}, ), ( "", [_MQTTTopicPlaceholder.MAC_ADDRESS], "00:11:22:33:44:55", {_MQTTTopicPlaceholder.MAC_ADDRESS: "00:11:22:33:44:55"}, ), ( "prefix/", [_MQTTTopicPlaceholder.MAC_ADDRESS], "prefix/aa:bb:cc:dd:ee:f2", {_MQTTTopicPlaceholder.MAC_ADDRESS: "aa:bb:cc:dd:ee:f2"}, ), ( "prefix-", ["test", _MQTTTopicPlaceholder.MAC_ADDRESS, "42"], "prefix-test/aa:bb:cc:dd:ee:f3/42", {_MQTTTopicPlaceholder.MAC_ADDRESS: "aa:bb:cc:dd:ee:f3"}, ), ], ) def test__parse_mqtt_topic( expected_prefix: str, expected_levels: typing.List[_MQTTTopicLevel], topic: str, expected_attrs: typing.Dict[_MQTTTopicPlaceholder, str], ) -> None: assert ( _parse_mqtt_topic( topic=topic, expected_prefix=expected_prefix, expected_levels=expected_levels, ) == expected_attrs ) def test__parse_mqtt_topic_unexpected_prefix() -> None: with pytest.raises( ValueError, match=r"^expected topic prefix abcdefg/, got topic abcdef/aa:bb:cc:dd:ee:ff$", ): _parse_mqtt_topic( topic="abcdef/aa:bb:cc:dd:ee:ff", expected_prefix="abcdefg/", expected_levels=[_MQTTTopicPlaceholder.MAC_ADDRESS], ) @pytest.mark.parametrize( ("expected_prefix", "expected_levels", "topic"), [ ( "", ["switchbot", _MQTTTopicPlaceholder.MAC_ADDRESS, "set"], "switchbot/aa:bb:cc:dd:ee:ff", ), ( "", ["switchbot", _MQTTTopicPlaceholder.MAC_ADDRESS, "set"], "switchbot/aa:bb:cc:dd:ee:ff/change", ), ( "prfx", ["switchbot", _MQTTTopicPlaceholder.MAC_ADDRESS, "set"], "prfx/switchbot/aa:bb:cc:dd:ee:ff/set/suffix", ), ], ) def test__parse_mqtt_topic_fail( expected_prefix: str, expected_levels: typing.List[_MQTTTopicLevel], topic: str ) -> None: with pytest.raises(ValueError): _parse_mqtt_topic( topic=topic, expected_prefix=expected_prefix, expected_levels=expected_levels, )