Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
dalinicus committed Jun 8, 2024
1 parent 089ef5e commit 18246d6
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 94 deletions.
3 changes: 1 addition & 2 deletions custom_components/ac_infinity/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType

from custom_components.ac_infinity import (
Expand Down Expand Up @@ -78,7 +77,7 @@ def is_on(self) -> bool | None:


async def async_setup_entry(
hass: HomeAssistant, config: ConfigEntry, add_entities_callback: AddEntitiesCallback
hass: HomeAssistant, config: ConfigEntry, add_entities_callback
) -> None:
"""Set Up the AC Infinity BinarySensor Platform."""

Expand Down
3 changes: 1 addition & 2 deletions custom_components/ac_infinity/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform, UnitOfTemperature
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType

from custom_components.ac_infinity import (
Expand Down Expand Up @@ -475,7 +474,7 @@ async def async_set_native_value(self, value: float) -> None:


async def async_setup_entry(
hass: HomeAssistant, config: ConfigEntry, add_entities_callback: AddEntitiesCallback
hass: HomeAssistant, config: ConfigEntry, add_entities_callback
) -> None:
"""Set up the AC Infinity Platform."""

Expand Down
18 changes: 14 additions & 4 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ def add_entities_callback(
):
self._added_entities = new_entities

@property
def added_entities(self):
return self._added_entities


async def execute_and_get_controller_entity(
setup_fixture, async_setup_entry, property_key: str
Expand All @@ -60,12 +64,14 @@ async def execute_and_get_controller_entity(

found = [
sensor
for sensor in test_objects.entities._added_entities
for sensor in test_objects.entities.added_entities
if property_key in sensor.unique_id
]
assert len(found) == 1
entity = found[0]

return found[0]
assert isinstance(entity, ACInfinityControllerEntity)
return entity


async def execute_and_get_port_entity(
Expand All @@ -84,12 +90,14 @@ async def execute_and_get_port_entity(

found = [
sensor
for sensor in test_objects.entities._added_entities
for sensor in test_objects.entities.added_entities
if sensor.unique_id.endswith(data_key) and f"port_{port}" in sensor.unique_id
]
assert len(found) == 1
entity = found[0]

return found[0]
assert isinstance(entity, ACInfinityPortEntity)
return entity


def setup_entity_mocks(mocker: MockFixture):
Expand Down Expand Up @@ -127,6 +135,8 @@ def setup_entity_mocks(mocker: MockFixture):
source="",
title="",
version=0,
unique_id=None,
options=None,
)

entities = EntitiesTracker()
Expand Down
66 changes: 32 additions & 34 deletions tests/test_ac_infinity.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,43 +40,43 @@ class TestACInfinity:
async def test_update_logged_in_should_be_called_if_not_logged_in(
self, mocker: MockFixture
):
"""if client is already logged in, than log in should not be called"""
"""if client is already logged in, then log in should not be called"""

mocker.patch.object(ACInfinityClient, "is_logged_in", return_value=False)
mocker.patch.object(
ACInfinityClient, "get_all_device_info", return_value=DEVICE_INFO_LIST_ALL
)
mocker.patch.object(
ACInfinityClient,
"get_device_port_settings",
"get_port_settings",
return_value=DEVICE_SETTINGS_PAYLOAD,
)
mockLogin: MockType = mocker.patch.object(ACInfinityClient, "login")
mock_login: MockType = mocker.patch.object(ACInfinityClient, "login")

ac_infinity = ACInfinityService(EMAIL, PASSWORD)
await ac_infinity.update()

assert mockLogin.called
assert mock_login.called

async def test_update_logged_in_should_not_be_called_if_not_necessary(
self, mocker: MockFixture
):
"""if client is not already logged in, than log in should be called"""
"""if client is not already logged in, then log in should be called"""

mocker.patch.object(ACInfinityClient, "is_logged_in", return_value=True)
mocker.patch.object(
ACInfinityClient, "get_all_device_info", return_value=DEVICE_INFO_LIST_ALL
)
mocker.patch.object(
ACInfinityClient,
"get_device_port_settings",
"get_port_settings",
return_value=DEVICE_SETTINGS_PAYLOAD,
)
mockLogin: MockType = mocker.patch.object(ACInfinityClient, "login")
mock_login: MockType = mocker.patch.object(ACInfinityClient, "login")

ac_infinity = ACInfinityService(EMAIL, PASSWORD)
await ac_infinity.update()
assert not mockLogin.called
assert not mock_login.called

async def test_update_data_set(self, mocker: MockFixture):
"""data should be set once update is called"""
Expand All @@ -87,7 +87,7 @@ async def test_update_data_set(self, mocker: MockFixture):
)
mocker.patch.object(
ACInfinityClient,
"get_device_port_settings",
"get_port_settings",
return_value=DEVICE_SETTINGS_PAYLOAD,
)
mocker.patch.object(ACInfinityClient, "login")
Expand Down Expand Up @@ -116,7 +116,7 @@ async def test_update_retried_on_failure(self, mocker: MockFixture):
)
mocker.patch.object(
ACInfinityClient,
"get_device_port_settings",
"get_port_settings",
return_value=DEVICE_SETTINGS_PAYLOAD,
)
mocker.patch.object(ACInfinityClient, "login")
Expand All @@ -138,14 +138,14 @@ async def test_update_retried_on_failure(self, mocker: MockFixture):
],
)
@pytest.mark.parametrize("device_id", [DEVICE_ID, str(DEVICE_ID)])
async def test_get_device_property_gets_correct_property(
self, device_id, property_key, value
async def test_get_controller_property_gets_correct_property(
self, device_id, property_key: str, value
):
"""getting a device property returns the correct value"""
ac_infinity = ACInfinityService(EMAIL, PASSWORD)
ac_infinity._controller_properties = DEVICE_INFO_DATA

result = ac_infinity.get_device_property(device_id, property_key)
result = ac_infinity.get_controller_property(device_id, property_key)
assert result == value

@pytest.mark.parametrize(
Expand All @@ -156,14 +156,14 @@ async def test_get_device_property_gets_correct_property(
("MyFakeField", str(DEVICE_ID)),
],
)
async def test_get_device_property_returns_null_properly(
async def test_get_controller_property_returns_null_properly(
self, property_key, device_id
):
"""the absence of a value should return None instead of keyerror"""
ac_infinity = ACInfinityService(EMAIL, PASSWORD)
ac_infinity._controller_properties = DEVICE_INFO_DATA

result = ac_infinity.get_device_property(device_id, property_key)
result = ac_infinity.get_controller_property(device_id, property_key)
assert result is None

@pytest.mark.parametrize(
Expand All @@ -176,14 +176,14 @@ async def test_get_device_property_returns_null_properly(
],
)
@pytest.mark.parametrize("device_id", [DEVICE_ID, str(DEVICE_ID)])
async def test_get_device_port_property_gets_correct_property(
self, device_id, port_num, property_key, value
async def test_get_port_property_gets_correct_property(
self, device_id, port_num, property_key: str, value
):
"""getting a porp property gets the correct property from the correct port"""
"""getting a port property gets the correct property from the correct port"""
ac_infinity = ACInfinityService(EMAIL, PASSWORD)
ac_infinity._controller_properties = DEVICE_INFO_DATA

result = ac_infinity.get_device_port_property(device_id, port_num, property_key)
result = ac_infinity.get_port_property(device_id, port_num, property_key)
assert result == value

@pytest.mark.parametrize(
Expand All @@ -196,14 +196,14 @@ async def test_get_device_port_property_gets_correct_property(
(SENSOR_PORT_KEY_SPEAK, str(DEVICE_ID), 9),
],
)
async def test_get_device_port_property_returns_null_properly(
async def test_get_port_property_returns_null_properly(
self, property_key, device_id, port_num
):
"""the absence of a value should return None instead of keyerror"""
ac_infinity = ACInfinityService(EMAIL, PASSWORD)
ac_infinity._controller_properties = DEVICE_INFO_DATA

result = ac_infinity.get_device_port_property(device_id, port_num, property_key)
result = ac_infinity.get_port_property(device_id, port_num, property_key)
assert result is None

async def test_get_device_all_device_meta_data_returns_meta_data(self):
Expand All @@ -230,16 +230,16 @@ async def test_get_device_all_device_meta_data_returns_empty_list(self, data):
assert result == []

@pytest.mark.parametrize(
"devType,expected_model",
"dev_type,expected_model",
[(11, "UIS Controller 69 Pro (CTR69P)"), (3, "UIS Controller Type 3")],
)
async def test_ac_infinity_device_has_correct_device_info(
self, devType: int, expected_model: str
self, dev_type: int, expected_model: str
):
"""getting device returns an model object that contains correct device info for the device registry"""
"""getting device returns a model object that contains correct device info for the device registry"""
ac_infinity = ACInfinityService(EMAIL, PASSWORD)
ac_infinity._controller_properties = DEVICE_INFO_DATA
ac_infinity._controller_properties[str(DEVICE_ID)]["devType"] = devType
ac_infinity._controller_properties[str(DEVICE_ID)]["devType"] = dev_type

result = ac_infinity.get_all_controller_properties()
assert len(result) > 0
Expand All @@ -265,20 +265,20 @@ async def test_ac_infinity_device_has_correct_device_info(
],
)
@pytest.mark.parametrize("device_id", [DEVICE_ID, str(DEVICE_ID)])
async def test_get_device_port_setting_gets_correct_property(
async def test_get_port_setting_gets_correct_property(
self, device_id, setting_key, value
):
"""getting a port setting gets the correct setting from the correct port"""
ac_infinity = ACInfinityService(EMAIL, PASSWORD)
ac_infinity._controller_properties = DEVICE_INFO_DATA
ac_infinity._port_settings = DEVICE_SETTINGS

result = ac_infinity.get_device_port_setting(device_id, 1, setting_key)
result = ac_infinity.get_port_setting(device_id, 1, setting_key)
assert result == value

@pytest.mark.parametrize("default_value", [0, None, 5455])
@pytest.mark.parametrize("device_id", [DEVICE_ID, str(DEVICE_ID)])
async def test_get_device_port_setting_gets_returns_default_if_value_is_null(
async def test_get_port_setting_gets_returns_default_if_value_is_null(
self, device_id, default_value
):
"""getting a port setting returns 0 instead of null if the key exists but the value is null"""
Expand All @@ -288,7 +288,7 @@ async def test_get_device_port_setting_gets_returns_default_if_value_is_null(

ac_infinity._port_settings[str(DEVICE_ID)][1][SENSOR_SETTING_KEY_SURPLUS] = None

result = ac_infinity.get_device_port_setting(
result = ac_infinity.get_port_setting(
device_id, 1, SENSOR_SETTING_KEY_SURPLUS, default_value=default_value
)
assert result == default_value
Expand All @@ -303,7 +303,7 @@ async def test_get_device_port_setting_gets_returns_default_if_value_is_null(
(PROPERTY_PORT_KEY_NAME, str(DEVICE_ID)),
],
)
async def test_get_device_port_setting_returns_null_properly(
async def test_get_port_setting_returns_null_properly(
self,
setting_key,
device_id,
Expand All @@ -313,7 +313,7 @@ async def test_get_device_port_setting_returns_null_properly(
ac_infinity._controller_properties = DEVICE_INFO_DATA
ac_infinity._port_settings = DEVICE_SETTINGS

result = ac_infinity.get_device_port_setting(device_id, 1, setting_key)
result = ac_infinity.get_port_setting(device_id, 1, setting_key)
assert result is None

async def test_set_device_port_setting(self, mocker: MockFixture):
Expand Down Expand Up @@ -346,9 +346,7 @@ async def test_set_device_port_settings(self, mocker: MockFixture):
ac_infinity._controller_properties = DEVICE_INFO_DATA
ac_infinity._port_settings = DEVICE_SETTINGS

await ac_infinity.update_port_settings(
DEVICE_ID, 1, [(SETTING_KEY_AT_TYPE, 2)]
)
await ac_infinity.update_port_settings(DEVICE_ID, 1, [(SETTING_KEY_AT_TYPE, 2)])

mocked_sets.assert_called_with(DEVICE_ID, 1, [(SETTING_KEY_AT_TYPE, 2)])

Expand Down
10 changes: 6 additions & 4 deletions tests/test_binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
)
from pytest_mock import MockFixture

from custom_components.ac_infinity import ACInfinityPortEntity
from custom_components.ac_infinity.binary_sensor import (
ACInfinityPortBinarySensorEntity,
async_setup_entry,
Expand All @@ -12,7 +13,6 @@
DOMAIN,
SENSOR_PORT_KEY_ONLINE,
)
from custom_components.ac_infinity.sensor import ACInfinityPortSensorEntity
from tests import (
ACTestObjects,
execute_and_get_port_entity,
Expand Down Expand Up @@ -44,7 +44,7 @@ async def test_async_setup_all_sensors_created(self, setup):
async def test_async_setup_entry_plug_created_for_each_port(self, setup, port):
"""Sensor for device port connected is created on setup"""

sensor: ACInfinityPortSensorEntity = await execute_and_get_port_entity(
sensor: ACInfinityPortEntity = await execute_and_get_port_entity(
setup, async_setup_entry, port, SENSOR_PORT_KEY_ONLINE
)

Expand All @@ -64,14 +64,16 @@ async def test_async_setup_entry_plug_created_for_each_port(self, setup, port):
(4, False),
],
)
async def test_async_update_plug_value_Correct(self, setup, port, expected):
async def test_async_update_plug_value_correct(self, setup, port, expected):
"""Reported sensor value matches the value in the json payload"""

test_objects: ACTestObjects = setup
sensor: ACInfinityPortBinarySensorEntity = await execute_and_get_port_entity(
sensor: ACInfinityPortEntity = await execute_and_get_port_entity(
setup, async_setup_entry, port, SENSOR_PORT_KEY_ONLINE
)
sensor._handle_coordinator_update()

assert isinstance(sensor, ACInfinityPortBinarySensorEntity)
assert sensor.is_on == expected

test_objects.write_ha_mock.assert_called()
11 changes: 7 additions & 4 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,38 @@
from custom_components.ac_infinity.client import (
API_URL_ADD_DEV_MODE,
API_URL_GET_DEV_MODE_SETTING,
API_URL_GET_DEV_SETTING,
API_URL_GET_DEVICE_INFO_LIST_ALL,
API_URL_LOGIN,
API_URL_UPDATE_ADV_SETTING,
API_URL_GET_DEV_SETTING,
ACInfinityClient,
ACInfinityClientCannotConnect,
ACInfinityClientInvalidAuth,
ACInfinityClientRequestFailed,
)
from custom_components.ac_infinity.const import (
CONTROLLER_SETTING_KEY_CALIBRATE_HUMIDITY,
SENSOR_SETTING_KEY_SURPLUS,
SETTING_KEY_ON_SPEED,
SETTING_KEY_TARGET_HUMIDITY_SWITCH,
SETTING_KEY_TARGET_TEMPERATURE_SWITCH,
SETTING_KEY_TARGET_VPD_SWITCH, CONTROLLER_SETTING_KEY_CALIBRATE_HUMIDITY,
SETTING_KEY_TARGET_VPD_SWITCH,
)
from tests.data_models import (
UPDATE_SUCCESS_PAYLOAD,
CONTROLLER_SETTINGS_PAYLOAD,
DEVICE_ID,
DEVICE_INFO_LIST_ALL_PAYLOAD,
DEVICE_SETTINGS_PAYLOAD,
EMAIL,
HOST,
LOGIN_PAYLOAD,
PASSWORD,
USER_ID, CONTROLLER_SETTINGS_PAYLOAD,
UPDATE_SUCCESS_PAYLOAD,
USER_ID,
)


# noinspection SpellCheckingInspection
@pytest.mark.asyncio
class TestACInfinityClient:
async def test_is_logged_in_returns_false_if_not_logged_in(self):
Expand Down
Loading

0 comments on commit 18246d6

Please sign in to comment.