2023-11-21 22:48:53 +00:00
|
|
|
# type: ignore
|
|
|
|
import logging
|
|
|
|
from typing import Type
|
|
|
|
|
|
|
|
import pytest # type: ignore # https://github.com/pytest-dev/pytest/issues/3342
|
|
|
|
|
|
|
|
from kasa import (
|
2023-12-04 18:50:05 +00:00
|
|
|
Credentials,
|
2023-11-21 22:48:53 +00:00
|
|
|
DeviceType,
|
2023-12-04 18:50:05 +00:00
|
|
|
Discover,
|
2023-11-21 22:48:53 +00:00
|
|
|
SmartBulb,
|
|
|
|
SmartDevice,
|
|
|
|
SmartDeviceException,
|
|
|
|
SmartDimmer,
|
|
|
|
SmartLightStrip,
|
|
|
|
SmartPlug,
|
|
|
|
)
|
2023-12-04 18:50:05 +00:00
|
|
|
from kasa.device_factory import (
|
|
|
|
DEVICE_TYPE_TO_CLASS,
|
|
|
|
connect,
|
|
|
|
get_protocol_from_connection_name,
|
|
|
|
)
|
|
|
|
from kasa.discover import DiscoveryResult
|
|
|
|
from kasa.iotprotocol import IotProtocol
|
2023-11-28 19:13:15 +00:00
|
|
|
from kasa.protocol import TPLinkProtocol, TPLinkSmartHomeProtocol
|
2023-11-21 22:48:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("custom_port", [123, None])
|
|
|
|
async def test_connect(discovery_data: dict, mocker, custom_port):
|
|
|
|
"""Make sure that connect returns an initialized SmartDevice instance."""
|
|
|
|
host = "127.0.0.1"
|
|
|
|
|
2023-12-04 18:50:05 +00:00
|
|
|
if "result" in discovery_data:
|
|
|
|
with pytest.raises(SmartDeviceException):
|
|
|
|
dev = await connect(host, port=custom_port)
|
|
|
|
else:
|
|
|
|
mocker.patch("kasa.TPLinkSmartHomeProtocol.query", return_value=discovery_data)
|
|
|
|
dev = await connect(host, port=custom_port)
|
|
|
|
assert issubclass(dev.__class__, SmartDevice)
|
|
|
|
assert dev.port == custom_port or dev.port == 9999
|
2023-11-21 22:48:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("custom_port", [123, None])
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
("device_type", "klass"),
|
|
|
|
(
|
|
|
|
(DeviceType.Plug, SmartPlug),
|
|
|
|
(DeviceType.Bulb, SmartBulb),
|
|
|
|
(DeviceType.Dimmer, SmartDimmer),
|
|
|
|
(DeviceType.LightStrip, SmartLightStrip),
|
|
|
|
(DeviceType.Unknown, SmartDevice),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
async def test_connect_passed_device_type(
|
|
|
|
discovery_data: dict,
|
|
|
|
mocker,
|
|
|
|
device_type: DeviceType,
|
|
|
|
klass: Type[SmartDevice],
|
|
|
|
custom_port,
|
|
|
|
):
|
|
|
|
"""Make sure that connect with a passed device type."""
|
|
|
|
host = "127.0.0.1"
|
|
|
|
|
2023-12-04 18:50:05 +00:00
|
|
|
if "result" in discovery_data:
|
|
|
|
with pytest.raises(SmartDeviceException):
|
|
|
|
dev = await connect(host, port=custom_port)
|
|
|
|
else:
|
|
|
|
mocker.patch("kasa.TPLinkSmartHomeProtocol.query", return_value=discovery_data)
|
|
|
|
dev = await connect(host, port=custom_port, device_type=device_type)
|
|
|
|
assert isinstance(dev, klass)
|
|
|
|
assert dev.port == custom_port or dev.port == 9999
|
2023-11-21 22:48:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_connect_query_fails(discovery_data: dict, mocker):
|
|
|
|
"""Make sure that connect fails when query fails."""
|
|
|
|
host = "127.0.0.1"
|
|
|
|
mocker.patch("kasa.TPLinkSmartHomeProtocol.query", side_effect=SmartDeviceException)
|
|
|
|
|
|
|
|
with pytest.raises(SmartDeviceException):
|
|
|
|
await connect(host)
|
|
|
|
|
|
|
|
|
|
|
|
async def test_connect_logs_connect_time(
|
|
|
|
discovery_data: dict, caplog: pytest.LogCaptureFixture, mocker
|
|
|
|
):
|
|
|
|
"""Test that the connect time is logged when debug logging is enabled."""
|
|
|
|
host = "127.0.0.1"
|
2023-12-04 18:50:05 +00:00
|
|
|
if "result" in discovery_data:
|
|
|
|
with pytest.raises(SmartDeviceException):
|
|
|
|
await connect(host)
|
|
|
|
else:
|
|
|
|
mocker.patch("kasa.TPLinkSmartHomeProtocol.query", return_value=discovery_data)
|
|
|
|
logging.getLogger("kasa").setLevel(logging.DEBUG)
|
|
|
|
await connect(host)
|
|
|
|
assert "seconds to connect" in caplog.text
|
2023-11-28 19:13:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_connect_pass_protocol(
|
2023-12-04 18:50:05 +00:00
|
|
|
all_fixture_data: dict,
|
2023-11-28 19:13:15 +00:00
|
|
|
mocker,
|
|
|
|
):
|
|
|
|
"""Test that if the protocol is passed in it's gets set correctly."""
|
2023-12-04 18:50:05 +00:00
|
|
|
if "discovery_result" in all_fixture_data:
|
|
|
|
discovery_info = {"result": all_fixture_data["discovery_result"]}
|
|
|
|
device_class = Discover._get_device_class(discovery_info)
|
|
|
|
else:
|
|
|
|
device_class = Discover._get_device_class(all_fixture_data)
|
|
|
|
|
|
|
|
device_type = list(DEVICE_TYPE_TO_CLASS.keys())[
|
|
|
|
list(DEVICE_TYPE_TO_CLASS.values()).index(device_class)
|
|
|
|
]
|
2023-11-28 19:13:15 +00:00
|
|
|
host = "127.0.0.1"
|
2023-12-04 18:50:05 +00:00
|
|
|
if "discovery_result" in all_fixture_data:
|
|
|
|
mocker.patch("kasa.IotProtocol.query", return_value=all_fixture_data)
|
|
|
|
mocker.patch("kasa.SmartProtocol.query", return_value=all_fixture_data)
|
|
|
|
|
|
|
|
dr = DiscoveryResult(**discovery_info["result"])
|
|
|
|
connection_name = (
|
|
|
|
dr.device_type.split(".")[0] + "." + dr.mgt_encrypt_schm.encrypt_type
|
|
|
|
)
|
|
|
|
protocol_class = get_protocol_from_connection_name(
|
|
|
|
connection_name, host
|
|
|
|
).__class__
|
|
|
|
else:
|
|
|
|
mocker.patch(
|
|
|
|
"kasa.TPLinkSmartHomeProtocol.query", return_value=all_fixture_data
|
|
|
|
)
|
|
|
|
protocol_class = TPLinkSmartHomeProtocol
|
|
|
|
|
|
|
|
dev = await connect(
|
|
|
|
host,
|
|
|
|
device_type=device_type,
|
|
|
|
protocol_class=protocol_class,
|
|
|
|
credentials=Credentials("", ""),
|
|
|
|
)
|
|
|
|
assert isinstance(dev.protocol, protocol_class)
|