-
-
Notifications
You must be signed in to change notification settings - Fork 37.4k
Add tests for Plugwise integration #36371
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
fd56976
Initial plugwise testing (besides config_flow) code
9d68683
Improve docstrings
18a2e77
Add basic binary sensor tests for Anna environment
c996805
Add other platforms, improve coverage
2e6a2c6
Rebase for conflicts after time
2377a96
PR catchup
1ab739d
PR catchup
9409535
Updated testdata from module improvements
CoMPaTech abcab13
Catch-up with dev - update testdata
CoMPaTech 8751f4f
Adjust to improved net_electricity while correcting output of module …
CoMPaTech 5369a97
Add missing blacks
CoMPaTech 4cfa086
Commit Martins suggestions
CoMPaTech 1f5d607
Leave out exception specifics
CoMPaTech 61c1817
Revert error-handling, improve entry state checking
CoMPaTech 6b39bab
Re-add missing change in common
CoMPaTech cda9666
Catchup with dev and recent merge
CoMPaTech 948f27a
Catchup with reality, adjust values to new formatting (i.e. significa…
CoMPaTech 1befb97
Rewrite pickles to picklejson
CoMPaTech d019748
Use core load_fixture
CoMPaTech 5c5b5b7
Add testing dependency to requirements
CoMPaTech 47a0e9c
Upgrade jsonpickle from integration to testing
CoMPaTech File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| """Common initialisation for the Plugwise integration.""" | ||
|
|
||
| from homeassistant.components.plugwise import DOMAIN | ||
| from homeassistant.core import HomeAssistant | ||
|
|
||
| from tests.common import MockConfigEntry | ||
| from tests.test_util.aiohttp import AiohttpClientMocker | ||
|
|
||
|
|
||
| async def async_init_integration( | ||
| hass: HomeAssistant, | ||
| aioclient_mock: AiohttpClientMocker, | ||
| skip_setup: bool = False, | ||
| ): | ||
| """Initialize the Smile integration.""" | ||
|
|
||
| entry = MockConfigEntry( | ||
| domain=DOMAIN, data={"host": "1.1.1.1", "password": "test-password"} | ||
| ) | ||
| entry.add_to_hass(hass) | ||
|
|
||
| if not skip_setup: | ||
| await hass.config_entries.async_setup(entry.entry_id) | ||
| await hass.async_block_till_done() | ||
|
|
||
| return entry |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,167 @@ | ||
| """Setup mocks for the Plugwise integration tests.""" | ||
|
|
||
| from functools import partial | ||
| import re | ||
|
|
||
| from Plugwise_Smile.Smile import Smile | ||
| import jsonpickle | ||
| import pytest | ||
|
|
||
| from tests.async_mock import AsyncMock, patch | ||
| from tests.common import load_fixture | ||
| from tests.test_util.aiohttp import AiohttpClientMocker | ||
|
|
||
|
|
||
| def _read_json(environment, call): | ||
| """Undecode the json data.""" | ||
| fixture = load_fixture(f"plugwise/{environment}/{call}.json") | ||
| return jsonpickle.decode(fixture) | ||
|
|
||
|
|
||
| @pytest.fixture(name="mock_smile") | ||
| def mock_smile(): | ||
| """Create a Mock Smile for testing exceptions.""" | ||
| with patch( | ||
| "homeassistant.components.plugwise.config_flow.Smile", | ||
| ) as smile_mock: | ||
| smile_mock.InvalidAuthentication = Smile.InvalidAuthentication | ||
| smile_mock.ConnectionFailedError = Smile.ConnectionFailedError | ||
| smile_mock.return_value.connect.return_value = True | ||
| yield smile_mock.return_value | ||
|
|
||
|
|
||
| @pytest.fixture(name="mock_smile_unauth") | ||
| def mock_smile_unauth(aioclient_mock: AiohttpClientMocker) -> None: | ||
| """Mock the Plugwise Smile unauthorized for Home Assistant.""" | ||
| aioclient_mock.get(re.compile(".*"), status=401) | ||
| aioclient_mock.put(re.compile(".*"), status=401) | ||
|
|
||
|
|
||
| @pytest.fixture(name="mock_smile_error") | ||
| def mock_smile_error(aioclient_mock: AiohttpClientMocker) -> None: | ||
| """Mock the Plugwise Smile server failure for Home Assistant.""" | ||
| aioclient_mock.get(re.compile(".*"), status=500) | ||
| aioclient_mock.put(re.compile(".*"), status=500) | ||
|
|
||
|
|
||
| @pytest.fixture(name="mock_smile_notconnect") | ||
| def mock_smile_notconnect(): | ||
| """Mock the Plugwise Smile general connection failure for Home Assistant.""" | ||
| with patch("homeassistant.components.plugwise.Smile") as smile_mock: | ||
| smile_mock.InvalidAuthentication = Smile.InvalidAuthentication | ||
| smile_mock.ConnectionFailedError = Smile.ConnectionFailedError | ||
| smile_mock.PlugwiseError = Smile.PlugwiseError | ||
| smile_mock.return_value.connect.side_effect = AsyncMock(return_value=False) | ||
| yield smile_mock.return_value | ||
|
|
||
|
|
||
| def _get_device_data(chosen_env, device_id): | ||
| """Mock return data for specific devices.""" | ||
| return _read_json(chosen_env, "get_device_data/" + device_id) | ||
|
|
||
|
|
||
| @pytest.fixture(name="mock_smile_adam") | ||
| def mock_smile_adam(): | ||
| """Create a Mock Adam environment for testing exceptions.""" | ||
| chosen_env = "adam_multiple_devices_per_zone" | ||
| with patch("homeassistant.components.plugwise.Smile") as smile_mock: | ||
| smile_mock.InvalidAuthentication = Smile.InvalidAuthentication | ||
| smile_mock.ConnectionFailedError = Smile.ConnectionFailedError | ||
| smile_mock.XMLDataMissingError = Smile.XMLDataMissingError | ||
|
|
||
| smile_mock.return_value.gateway_id = "fe799307f1624099878210aa0b9f1475" | ||
| smile_mock.return_value.heater_id = "90986d591dcd426cae3ec3e8111ff730" | ||
| smile_mock.return_value.smile_version = "3.0.15" | ||
| smile_mock.return_value.smile_type = "thermostat" | ||
|
|
||
| smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True) | ||
| smile_mock.return_value.full_update_device.side_effect = AsyncMock( | ||
| return_value=True | ||
| ) | ||
| smile_mock.return_value.set_schedule_state.side_effect = AsyncMock( | ||
| return_value=True | ||
| ) | ||
| smile_mock.return_value.set_preset.side_effect = AsyncMock(return_value=True) | ||
| smile_mock.return_value.set_temperature.side_effect = AsyncMock( | ||
| return_value=True | ||
| ) | ||
| smile_mock.return_value.set_relay_state.side_effect = AsyncMock( | ||
| return_value=True | ||
| ) | ||
|
|
||
| smile_mock.return_value.get_all_devices.return_value = _read_json( | ||
| chosen_env, "get_all_devices" | ||
| ) | ||
| smile_mock.return_value.get_device_data.side_effect = partial( | ||
| _get_device_data, chosen_env | ||
| ) | ||
|
|
||
| yield smile_mock.return_value | ||
|
|
||
|
|
||
| @pytest.fixture(name="mock_smile_anna") | ||
| def mock_smile_anna(): | ||
| """Create a Mock Anna environment for testing exceptions.""" | ||
| chosen_env = "anna_heatpump" | ||
| with patch("homeassistant.components.plugwise.Smile") as smile_mock: | ||
| smile_mock.InvalidAuthentication = Smile.InvalidAuthentication | ||
| smile_mock.ConnectionFailedError = Smile.ConnectionFailedError | ||
| smile_mock.XMLDataMissingError = Smile.XMLDataMissingError | ||
|
|
||
| smile_mock.return_value.gateway_id = "015ae9ea3f964e668e490fa39da3870b" | ||
| smile_mock.return_value.heater_id = "1cbf783bb11e4a7c8a6843dee3a86927" | ||
| smile_mock.return_value.smile_version = "4.0.15" | ||
| smile_mock.return_value.smile_type = "thermostat" | ||
|
|
||
| smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True) | ||
| smile_mock.return_value.full_update_device.side_effect = AsyncMock( | ||
| return_value=True | ||
| ) | ||
| smile_mock.return_value.set_schedule_state.side_effect = AsyncMock( | ||
| return_value=True | ||
| ) | ||
| smile_mock.return_value.set_preset.side_effect = AsyncMock(return_value=True) | ||
| smile_mock.return_value.set_temperature.side_effect = AsyncMock( | ||
| return_value=True | ||
| ) | ||
| smile_mock.return_value.set_relay_state.side_effect = AsyncMock( | ||
| return_value=True | ||
| ) | ||
|
|
||
| smile_mock.return_value.get_all_devices.return_value = _read_json( | ||
| chosen_env, "get_all_devices" | ||
| ) | ||
| smile_mock.return_value.get_device_data.side_effect = partial( | ||
| _get_device_data, chosen_env | ||
| ) | ||
|
|
||
| yield smile_mock.return_value | ||
|
|
||
|
|
||
| @pytest.fixture(name="mock_smile_p1") | ||
| def mock_smile_p1(): | ||
| """Create a Mock P1 DSMR environment for testing exceptions.""" | ||
| chosen_env = "p1v3_full_option" | ||
| with patch("homeassistant.components.plugwise.Smile") as smile_mock: | ||
| smile_mock.InvalidAuthentication = Smile.InvalidAuthentication | ||
| smile_mock.ConnectionFailedError = Smile.ConnectionFailedError | ||
| smile_mock.XMLDataMissingError = Smile.XMLDataMissingError | ||
|
|
||
| smile_mock.return_value.gateway_id = "e950c7d5e1ee407a858e2a8b5016c8b3" | ||
| smile_mock.return_value.heater_id = None | ||
| smile_mock.return_value.smile_version = "3.3.9" | ||
| smile_mock.return_value.smile_type = "power" | ||
|
|
||
| smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True) | ||
| smile_mock.return_value.full_update_device.side_effect = AsyncMock( | ||
| return_value=True | ||
| ) | ||
|
|
||
| smile_mock.return_value.get_all_devices.return_value = _read_json( | ||
| chosen_env, "get_all_devices" | ||
| ) | ||
| smile_mock.return_value.get_device_data.side_effect = partial( | ||
| _get_device_data, chosen_env | ||
| ) | ||
|
|
||
| yield smile_mock.return_value |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| """Tests for the Plugwise binary_sensor integration.""" | ||
|
|
||
| from homeassistant.config_entries import ENTRY_STATE_LOADED | ||
| from homeassistant.const import STATE_OFF, STATE_ON | ||
|
|
||
| from tests.components.plugwise.common import async_init_integration | ||
|
|
||
|
|
||
| async def test_anna_climate_binary_sensor_entities(hass, mock_smile_anna): | ||
| """Test creation of climate related binary_sensor entities.""" | ||
| entry = await async_init_integration(hass, mock_smile_anna) | ||
| assert entry.state == ENTRY_STATE_LOADED | ||
|
|
||
| state = hass.states.get("binary_sensor.auxiliary_slave_boiler_state") | ||
| assert str(state.state) == STATE_OFF | ||
|
|
||
| state = hass.states.get("binary_sensor.auxiliary_dhw_state") | ||
| assert str(state.state) == STATE_OFF | ||
|
|
||
|
|
||
| async def test_anna_climate_binary_sensor_change(hass, mock_smile_anna): | ||
| """Test change of climate related binary_sensor entities.""" | ||
| entry = await async_init_integration(hass, mock_smile_anna) | ||
| assert entry.state == ENTRY_STATE_LOADED | ||
|
|
||
| hass.states.async_set("binary_sensor.auxiliary_dhw_state", STATE_ON, {}) | ||
| await hass.async_block_till_done() | ||
|
|
||
| state = hass.states.get("binary_sensor.auxiliary_dhw_state") | ||
| assert str(state.state) == STATE_ON | ||
|
|
||
| await hass.helpers.entity_component.async_update_entity( | ||
| "binary_sensor.auxiliary_dhw_state" | ||
| ) | ||
|
|
||
| state = hass.states.get("binary_sensor.auxiliary_dhw_state") | ||
| assert str(state.state) == STATE_OFF |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.