|
2 | 2 |
|
3 | 3 | from unittest.mock import AsyncMock |
4 | 4 |
|
5 | | -from pysmartthings import Attribute, Capability |
| 5 | +from pysmartthings import Attribute, Capability, SmartThingsSinkError |
| 6 | +from pysmartthings.models import Subscription |
6 | 7 | import pytest |
7 | 8 | from syrupy import SnapshotAssertion |
8 | 9 |
|
9 | 10 | from homeassistant.components.smartthings import EVENT_BUTTON |
10 | | -from homeassistant.components.smartthings.const import DOMAIN |
| 11 | +from homeassistant.components.smartthings.const import CONF_SUBSCRIPTION_ID, DOMAIN |
| 12 | +from homeassistant.config_entries import ConfigEntryState |
| 13 | +from homeassistant.const import EVENT_HOMEASSISTANT_STOP |
11 | 14 | from homeassistant.core import Event, HomeAssistant |
12 | 15 | from homeassistant.helpers import device_registry as dr |
13 | 16 |
|
14 | 17 | from . import setup_integration, trigger_update |
15 | 18 |
|
16 | | -from tests.common import MockConfigEntry |
| 19 | +from tests.common import MockConfigEntry, load_fixture |
17 | 20 |
|
18 | 21 |
|
19 | 22 | async def test_devices( |
@@ -63,6 +66,178 @@ def capture_event(event: Event) -> None: |
63 | 66 | assert events[0] == snapshot |
64 | 67 |
|
65 | 68 |
|
| 69 | +@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"]) |
| 70 | +async def test_create_subscription( |
| 71 | + hass: HomeAssistant, |
| 72 | + devices: AsyncMock, |
| 73 | + mock_config_entry: MockConfigEntry, |
| 74 | +) -> None: |
| 75 | + """Test creating a subscription.""" |
| 76 | + assert CONF_SUBSCRIPTION_ID not in mock_config_entry.data |
| 77 | + |
| 78 | + await setup_integration(hass, mock_config_entry) |
| 79 | + |
| 80 | + devices.create_subscription.assert_called_once() |
| 81 | + |
| 82 | + assert ( |
| 83 | + mock_config_entry.data[CONF_SUBSCRIPTION_ID] |
| 84 | + == "f5768ce8-c9e5-4507-9020-912c0c60e0ab" |
| 85 | + ) |
| 86 | + |
| 87 | + devices.subscribe.assert_called_once_with( |
| 88 | + "397678e5-9995-4a39-9d9f-ae6ba310236c", |
| 89 | + "5aaaa925-2be1-4e40-b257-e4ef59083324", |
| 90 | + Subscription.from_json(load_fixture("subscription.json", DOMAIN)), |
| 91 | + ) |
| 92 | + |
| 93 | + |
| 94 | +@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"]) |
| 95 | +async def test_create_subscription_sink_error( |
| 96 | + hass: HomeAssistant, |
| 97 | + devices: AsyncMock, |
| 98 | + mock_config_entry: MockConfigEntry, |
| 99 | + snapshot: SnapshotAssertion, |
| 100 | +) -> None: |
| 101 | + """Test handling an error when creating a subscription.""" |
| 102 | + assert CONF_SUBSCRIPTION_ID not in mock_config_entry.data |
| 103 | + |
| 104 | + devices.create_subscription.side_effect = SmartThingsSinkError("Sink error") |
| 105 | + |
| 106 | + await setup_integration(hass, mock_config_entry) |
| 107 | + |
| 108 | + devices.subscribe.assert_not_called() |
| 109 | + |
| 110 | + assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY |
| 111 | + assert CONF_SUBSCRIPTION_ID not in mock_config_entry.data |
| 112 | + |
| 113 | + |
| 114 | +@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"]) |
| 115 | +async def test_update_subscription_identifier( |
| 116 | + hass: HomeAssistant, |
| 117 | + devices: AsyncMock, |
| 118 | + mock_config_entry: MockConfigEntry, |
| 119 | +) -> None: |
| 120 | + """Test updating the subscription identifier.""" |
| 121 | + await setup_integration(hass, mock_config_entry) |
| 122 | + |
| 123 | + assert ( |
| 124 | + mock_config_entry.data[CONF_SUBSCRIPTION_ID] |
| 125 | + == "f5768ce8-c9e5-4507-9020-912c0c60e0ab" |
| 126 | + ) |
| 127 | + |
| 128 | + devices.new_subscription_id_callback("abc") |
| 129 | + |
| 130 | + await hass.async_block_till_done() |
| 131 | + |
| 132 | + assert mock_config_entry.data[CONF_SUBSCRIPTION_ID] == "abc" |
| 133 | + |
| 134 | + |
| 135 | +@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"]) |
| 136 | +async def test_stale_subscription_id( |
| 137 | + hass: HomeAssistant, |
| 138 | + devices: AsyncMock, |
| 139 | + mock_config_entry: MockConfigEntry, |
| 140 | +) -> None: |
| 141 | + """Test updating the subscription identifier.""" |
| 142 | + mock_config_entry.add_to_hass(hass) |
| 143 | + |
| 144 | + hass.config_entries.async_update_entry( |
| 145 | + mock_config_entry, |
| 146 | + data={**mock_config_entry.data, CONF_SUBSCRIPTION_ID: "test"}, |
| 147 | + ) |
| 148 | + |
| 149 | + await hass.config_entries.async_setup(mock_config_entry.entry_id) |
| 150 | + await hass.async_block_till_done() |
| 151 | + |
| 152 | + assert ( |
| 153 | + mock_config_entry.data[CONF_SUBSCRIPTION_ID] |
| 154 | + == "f5768ce8-c9e5-4507-9020-912c0c60e0ab" |
| 155 | + ) |
| 156 | + devices.delete_subscription.assert_called_once_with("test") |
| 157 | + |
| 158 | + |
| 159 | +@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"]) |
| 160 | +async def test_remove_subscription_identifier( |
| 161 | + hass: HomeAssistant, |
| 162 | + devices: AsyncMock, |
| 163 | + mock_config_entry: MockConfigEntry, |
| 164 | +) -> None: |
| 165 | + """Test removing the subscription identifier.""" |
| 166 | + await setup_integration(hass, mock_config_entry) |
| 167 | + |
| 168 | + assert ( |
| 169 | + mock_config_entry.data[CONF_SUBSCRIPTION_ID] |
| 170 | + == "f5768ce8-c9e5-4507-9020-912c0c60e0ab" |
| 171 | + ) |
| 172 | + |
| 173 | + devices.new_subscription_id_callback(None) |
| 174 | + |
| 175 | + await hass.async_block_till_done() |
| 176 | + |
| 177 | + assert mock_config_entry.data[CONF_SUBSCRIPTION_ID] is None |
| 178 | + |
| 179 | + |
| 180 | +@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"]) |
| 181 | +async def test_max_connections_handling( |
| 182 | + hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry |
| 183 | +) -> None: |
| 184 | + """Test handling reaching max connections.""" |
| 185 | + await setup_integration(hass, mock_config_entry) |
| 186 | + |
| 187 | + assert ( |
| 188 | + mock_config_entry.data[CONF_SUBSCRIPTION_ID] |
| 189 | + == "f5768ce8-c9e5-4507-9020-912c0c60e0ab" |
| 190 | + ) |
| 191 | + |
| 192 | + devices.create_subscription.side_effect = SmartThingsSinkError("Sink error") |
| 193 | + |
| 194 | + devices.max_connections_reached_callback() |
| 195 | + |
| 196 | + await hass.async_block_till_done() |
| 197 | + |
| 198 | + assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY |
| 199 | + |
| 200 | + |
| 201 | +@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"]) |
| 202 | +async def test_unloading( |
| 203 | + hass: HomeAssistant, |
| 204 | + devices: AsyncMock, |
| 205 | + mock_config_entry: MockConfigEntry, |
| 206 | +) -> None: |
| 207 | + """Test unloading the integration.""" |
| 208 | + await setup_integration(hass, mock_config_entry) |
| 209 | + |
| 210 | + await hass.config_entries.async_unload(mock_config_entry.entry_id) |
| 211 | + devices.delete_subscription.assert_called_once_with( |
| 212 | + "f5768ce8-c9e5-4507-9020-912c0c60e0ab" |
| 213 | + ) |
| 214 | + # Deleting the subscription automatically deletes the subscription ID |
| 215 | + devices.new_subscription_id_callback(None) |
| 216 | + |
| 217 | + assert mock_config_entry.state is ConfigEntryState.NOT_LOADED |
| 218 | + assert mock_config_entry.data[CONF_SUBSCRIPTION_ID] is None |
| 219 | + |
| 220 | + |
| 221 | +@pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"]) |
| 222 | +async def test_shutdown( |
| 223 | + hass: HomeAssistant, |
| 224 | + devices: AsyncMock, |
| 225 | + mock_config_entry: MockConfigEntry, |
| 226 | +) -> None: |
| 227 | + """Test shutting down Home Assistant.""" |
| 228 | + await setup_integration(hass, mock_config_entry) |
| 229 | + |
| 230 | + hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP) |
| 231 | + devices.delete_subscription.assert_called_once_with( |
| 232 | + "f5768ce8-c9e5-4507-9020-912c0c60e0ab" |
| 233 | + ) |
| 234 | + # Deleting the subscription automatically deletes the subscription ID |
| 235 | + devices.new_subscription_id_callback(None) |
| 236 | + |
| 237 | + assert mock_config_entry.state is ConfigEntryState.LOADED |
| 238 | + assert mock_config_entry.data[CONF_SUBSCRIPTION_ID] is None |
| 239 | + |
| 240 | + |
66 | 241 | @pytest.mark.parametrize("device_fixture", ["da_ac_rac_000001"]) |
67 | 242 | async def test_removing_stale_devices( |
68 | 243 | hass: HomeAssistant, |
|
0 commit comments