From e410e4f3f3f494b7ae6d3a46a3955baf542111ef Mon Sep 17 00:00:00 2001 From: Steven B <51370195+sdb9696@users.noreply.github.com> Date: Wed, 24 Apr 2024 12:25:16 +0100 Subject: [PATCH] Fix incorrect state updates in FakeTestProtocols (#861) --- kasa/iot/iotbulb.py | 1 + kasa/iot/iotstrip.py | 1 + kasa/tests/fakeprotocol_iot.py | 2 +- kasa/tests/fakeprotocol_smart.py | 6 ++++-- kasa/tests/smart/features/test_brightness.py | 2 ++ kasa/tests/smart/features/test_colortemp.py | 1 + kasa/tests/test_bulb.py | 1 + kasa/tests/test_cli.py | 14 +++++++------ kasa/tests/test_dimmer.py | 21 +++++++++++--------- kasa/tests/test_lightstrip.py | 1 + 10 files changed, 32 insertions(+), 18 deletions(-) diff --git a/kasa/iot/iotbulb.py b/kasa/iot/iotbulb.py index 834c49b1..f0ecaada 100644 --- a/kasa/iot/iotbulb.py +++ b/kasa/iot/iotbulb.py @@ -182,6 +182,7 @@ class IotBulb(IotDevice, Bulb): 50 >>> preset.brightness = 100 >>> asyncio.run(bulb.save_preset(preset)) + >>> asyncio.run(bulb.update()) >>> bulb.presets[0].brightness 100 diff --git a/kasa/iot/iotstrip.py b/kasa/iot/iotstrip.py index e1fdabae..17671545 100755 --- a/kasa/iot/iotstrip.py +++ b/kasa/iot/iotstrip.py @@ -66,6 +66,7 @@ class IotStrip(IotDevice): >>> strip.is_on True >>> asyncio.run(strip.turn_off()) + >>> asyncio.run(strip.update()) Accessing individual plugs can be done using the `children` property: diff --git a/kasa/tests/fakeprotocol_iot.py b/kasa/tests/fakeprotocol_iot.py index c15c6379..ac898c0a 100644 --- a/kasa/tests/fakeprotocol_iot.py +++ b/kasa/tests/fakeprotocol_iot.py @@ -413,4 +413,4 @@ class FakeIotProtocol(IotProtocol): for target in request: response.update(get_response_for_module(target)) - return response + return copy.deepcopy(response) diff --git a/kasa/tests/fakeprotocol_smart.py b/kasa/tests/fakeprotocol_smart.py index 32da9304..dd9b1f16 100644 --- a/kasa/tests/fakeprotocol_smart.py +++ b/kasa/tests/fakeprotocol_smart.py @@ -157,13 +157,15 @@ class FakeSmartTransport(BaseTransport): return self._handle_control_child(params) elif method == "component_nego" or method[:4] == "get_": if method in info: - return {"result": info[method], "error_code": 0} + result = copy.deepcopy(info[method]) + return {"result": result, "error_code": 0} if ( # FIXTURE_MISSING is for service calls not in place when # SMART fixtures started to be generated missing_result := self.FIXTURE_MISSING_MAP.get(method) ) and missing_result[0] in self.components: - retval = {"result": missing_result[1], "error_code": 0} + result = copy.deepcopy(missing_result[1]) + retval = {"result": result, "error_code": 0} else: # PARAMS error returned for KS240 when get_device_usage called # on parent device. Could be any error code though. diff --git a/kasa/tests/smart/features/test_brightness.py b/kasa/tests/smart/features/test_brightness.py index eb857269..c18dce97 100644 --- a/kasa/tests/smart/features/test_brightness.py +++ b/kasa/tests/smart/features/test_brightness.py @@ -20,6 +20,7 @@ async def test_brightness_component(dev: SmartDevice): # Test setting the value await feature.set_value(10) + await dev.update() assert feature.value == 10 with pytest.raises(ValueError): @@ -42,6 +43,7 @@ async def test_brightness_dimmable(dev: SmartDevice): # Test setting the value await feature.set_value(10) + await dev.update() assert feature.value == 10 with pytest.raises(ValueError): diff --git a/kasa/tests/smart/features/test_colortemp.py b/kasa/tests/smart/features/test_colortemp.py index e7022578..54f84b1b 100644 --- a/kasa/tests/smart/features/test_colortemp.py +++ b/kasa/tests/smart/features/test_colortemp.py @@ -20,6 +20,7 @@ async def test_colortemp_component(dev: SmartDevice): # We need to take the min here, as L9xx reports a range [9000, 9000]. new_value = min(feature.minimum_value + 1, feature.maximum_value) await feature.set_value(new_value) + await dev.update() assert feature.value == new_value with pytest.raises(ValueError): diff --git a/kasa/tests/test_bulb.py b/kasa/tests/test_bulb.py index 9e7ab517..668b034b 100644 --- a/kasa/tests/test_bulb.py +++ b/kasa/tests/test_bulb.py @@ -295,6 +295,7 @@ async def test_modify_preset(dev: IotBulb, mocker): assert preset.color_temp == 0 await dev.save_preset(preset) + await dev.update() assert dev.presets[0].brightness == 10 with pytest.raises(KasaException): diff --git a/kasa/tests/test_cli.py b/kasa/tests/test_cli.py index f190bf46..9fb46389 100644 --- a/kasa/tests/test_cli.py +++ b/kasa/tests/test_cli.py @@ -88,8 +88,8 @@ async def test_sysinfo(dev, runner): @turn_on async def test_state(dev, turn_on, runner): await handle_turn_on(dev, turn_on) - res = await runner.invoke(state, obj=dev) await dev.update() + res = await runner.invoke(state, obj=dev) if dev.is_on: assert "Device state: True" in res.output @@ -100,12 +100,12 @@ async def test_state(dev, turn_on, runner): @turn_on async def test_toggle(dev, turn_on, runner): await handle_turn_on(dev, turn_on) - await runner.invoke(toggle, obj=dev) + await dev.update() + assert dev.is_on == turn_on - if turn_on: - assert not dev.is_on - else: - assert dev.is_on + await runner.invoke(toggle, obj=dev) + await dev.update() + assert dev.is_on != turn_on @device_iot @@ -118,6 +118,7 @@ async def test_alias(dev, runner): new_alias = "new alias" res = await runner.invoke(alias, [new_alias], obj=dev) assert f"Setting alias to {new_alias}" in res.output + await dev.update() res = await runner.invoke(alias, obj=dev) assert f"Alias: {new_alias}" in res.output @@ -319,6 +320,7 @@ async def test_brightness(dev, runner): res = await runner.invoke(brightness, ["12"], obj=dev) assert "Setting brightness" in res.output + await dev.update() res = await runner.invoke(brightness, obj=dev) assert "Brightness: 12" in res.output diff --git a/kasa/tests/test_dimmer.py b/kasa/tests/test_dimmer.py index d63aa453..6399ca4f 100644 --- a/kasa/tests/test_dimmer.py +++ b/kasa/tests/test_dimmer.py @@ -12,10 +12,12 @@ async def test_set_brightness(dev, turn_on): await handle_turn_on(dev, turn_on) await dev.set_brightness(99) + await dev.update() assert dev.brightness == 99 assert dev.is_on == turn_on await dev.set_brightness(0) + await dev.update() assert dev.brightness == 1 assert dev.is_on == turn_on @@ -27,17 +29,18 @@ async def test_set_brightness_transition(dev, turn_on, mocker): query_helper = mocker.spy(IotDimmer, "_query_helper") await dev.set_brightness(99, transition=1000) - - assert dev.brightness == 99 - assert dev.is_on query_helper.assert_called_with( mocker.ANY, "smartlife.iot.dimmer", "set_dimmer_transition", {"brightness": 99, "duration": 1000}, ) + await dev.update() + assert dev.brightness == 99 + assert dev.is_on await dev.set_brightness(0, transition=1000) + await dev.update() assert dev.brightness == 1 @@ -58,15 +61,15 @@ async def test_turn_on_transition(dev, mocker): original_brightness = dev.brightness await dev.turn_on(transition=1000) - - assert dev.is_on - assert dev.brightness == original_brightness query_helper.assert_called_with( mocker.ANY, "smartlife.iot.dimmer", "set_dimmer_transition", {"brightness": original_brightness, "duration": 1000}, ) + await dev.update() + assert dev.is_on + assert dev.brightness == original_brightness @dimmer @@ -94,15 +97,15 @@ async def test_set_dimmer_transition(dev, turn_on, mocker): query_helper = mocker.spy(IotDimmer, "_query_helper") await dev.set_dimmer_transition(99, 1000) - - assert dev.is_on - assert dev.brightness == 99 query_helper.assert_called_with( mocker.ANY, "smartlife.iot.dimmer", "set_dimmer_transition", {"brightness": 99, "duration": 1000}, ) + await dev.update() + assert dev.is_on + assert dev.brightness == 99 @dimmer diff --git a/kasa/tests/test_lightstrip.py b/kasa/tests/test_lightstrip.py index ac80c52a..fc987d2e 100644 --- a/kasa/tests/test_lightstrip.py +++ b/kasa/tests/test_lightstrip.py @@ -27,6 +27,7 @@ async def test_effects_lightstrip_set_effect(dev: IotLightStrip): await dev.set_effect("Not real") await dev.set_effect("Candy Cane") + await dev.update() assert dev.effect["name"] == "Candy Cane"