forked from home-assistant/core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_cover.py
315 lines (254 loc) · 10.3 KB
/
test_cover.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
"""Tests for the Bond cover device."""
from datetime import timedelta
from bond_async import Action, DeviceType
from homeassistant.components.cover import (
ATTR_CURRENT_POSITION,
ATTR_POSITION,
DOMAIN as COVER_DOMAIN,
STATE_CLOSED,
)
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_CLOSE_COVER,
SERVICE_CLOSE_COVER_TILT,
SERVICE_OPEN_COVER,
SERVICE_OPEN_COVER_TILT,
SERVICE_SET_COVER_POSITION,
SERVICE_STOP_COVER,
SERVICE_STOP_COVER_TILT,
STATE_OPEN,
STATE_UNKNOWN,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_registry import EntityRegistry
from homeassistant.util import utcnow
from .common import (
help_test_entity_available,
patch_bond_action,
patch_bond_device_state,
setup_platform,
)
from tests.common import async_fire_time_changed
def shades(name: str):
"""Create motorized shades with given name."""
return {
"name": name,
"type": DeviceType.MOTORIZED_SHADES,
"actions": ["Open", "Close", "Hold"],
}
def shades_with_position(name: str):
"""Create motorized shades that supports set position."""
return {
"name": name,
"type": DeviceType.MOTORIZED_SHADES,
"actions": [Action.OPEN, Action.CLOSE, Action.HOLD, Action.SET_POSITION],
}
def tilt_only_shades(name: str):
"""Create motorized shades that only tilt."""
return {
"name": name,
"type": DeviceType.MOTORIZED_SHADES,
"actions": ["TiltOpen", "TiltClose", "Hold"],
}
def tilt_shades(name: str):
"""Create motorized shades with given name that can also tilt."""
return {
"name": name,
"type": DeviceType.MOTORIZED_SHADES,
"actions": ["Open", "Close", "Hold", "TiltOpen", "TiltClose", "Hold"],
}
async def test_entity_registry(hass: HomeAssistant) -> None:
"""Tests that the devices are registered in the entity registry."""
await setup_platform(
hass,
COVER_DOMAIN,
shades("name-1"),
bond_version={"bondid": "test-hub-id"},
bond_device_id="test-device-id",
)
registry: EntityRegistry = er.async_get(hass)
entity = registry.entities["cover.name_1"]
assert entity.unique_id == "test-hub-id_test-device-id"
async def test_open_cover(hass: HomeAssistant) -> None:
"""Tests that open cover command delegates to API."""
await setup_platform(
hass, COVER_DOMAIN, shades("name-1"), bond_device_id="test-device-id"
)
with patch_bond_action() as mock_open, patch_bond_device_state():
await hass.services.async_call(
COVER_DOMAIN,
SERVICE_OPEN_COVER,
{ATTR_ENTITY_ID: "cover.name_1"},
blocking=True,
)
await hass.async_block_till_done()
mock_open.assert_called_once_with("test-device-id", Action.open())
async def test_close_cover(hass: HomeAssistant) -> None:
"""Tests that close cover command delegates to API."""
await setup_platform(
hass, COVER_DOMAIN, shades("name-1"), bond_device_id="test-device-id"
)
with patch_bond_action() as mock_close, patch_bond_device_state():
await hass.services.async_call(
COVER_DOMAIN,
SERVICE_CLOSE_COVER,
{ATTR_ENTITY_ID: "cover.name_1"},
blocking=True,
)
await hass.async_block_till_done()
mock_close.assert_called_once_with("test-device-id", Action.close())
async def test_stop_cover(hass: HomeAssistant) -> None:
"""Tests that stop cover command delegates to API."""
await setup_platform(
hass, COVER_DOMAIN, shades("name-1"), bond_device_id="test-device-id"
)
with patch_bond_action() as mock_hold, patch_bond_device_state():
await hass.services.async_call(
COVER_DOMAIN,
SERVICE_STOP_COVER,
{ATTR_ENTITY_ID: "cover.name_1"},
blocking=True,
)
await hass.async_block_till_done()
mock_hold.assert_called_once_with("test-device-id", Action.hold())
async def test_tilt_open_cover(hass: HomeAssistant) -> None:
"""Tests that tilt open cover command delegates to API."""
await setup_platform(
hass, COVER_DOMAIN, tilt_only_shades("name-1"), bond_device_id="test-device-id"
)
with patch_bond_action() as mock_open, patch_bond_device_state():
await hass.services.async_call(
COVER_DOMAIN,
SERVICE_OPEN_COVER_TILT,
{ATTR_ENTITY_ID: "cover.name_1"},
blocking=True,
)
await hass.async_block_till_done()
mock_open.assert_called_once_with("test-device-id", Action.tilt_open())
assert hass.states.get("cover.name_1").state == STATE_UNKNOWN
async def test_tilt_close_cover(hass: HomeAssistant) -> None:
"""Tests that tilt close cover command delegates to API."""
await setup_platform(
hass, COVER_DOMAIN, tilt_only_shades("name-1"), bond_device_id="test-device-id"
)
with patch_bond_action() as mock_close, patch_bond_device_state():
await hass.services.async_call(
COVER_DOMAIN,
SERVICE_CLOSE_COVER_TILT,
{ATTR_ENTITY_ID: "cover.name_1"},
blocking=True,
)
await hass.async_block_till_done()
mock_close.assert_called_once_with("test-device-id", Action.tilt_close())
assert hass.states.get("cover.name_1").state == STATE_UNKNOWN
async def test_tilt_stop_cover(hass: HomeAssistant) -> None:
"""Tests that tilt stop cover command delegates to API."""
await setup_platform(
hass,
COVER_DOMAIN,
tilt_only_shades("name-1"),
bond_device_id="test-device-id",
state={"counter1": 123},
)
with patch_bond_action() as mock_hold, patch_bond_device_state():
await hass.services.async_call(
COVER_DOMAIN,
SERVICE_STOP_COVER_TILT,
{ATTR_ENTITY_ID: "cover.name_1"},
blocking=True,
)
await hass.async_block_till_done()
mock_hold.assert_called_once_with("test-device-id", Action.hold())
assert hass.states.get("cover.name_1").state == STATE_UNKNOWN
async def test_tilt_and_open(hass: HomeAssistant) -> None:
"""Tests that supports both tilt and open."""
await setup_platform(
hass,
COVER_DOMAIN,
tilt_shades("name-1"),
bond_device_id="test-device-id",
state={"open": False},
)
with patch_bond_action() as mock_open, patch_bond_device_state():
await hass.services.async_call(
COVER_DOMAIN,
SERVICE_OPEN_COVER_TILT,
{ATTR_ENTITY_ID: "cover.name_1"},
blocking=True,
)
await hass.async_block_till_done()
mock_open.assert_called_once_with("test-device-id", Action.tilt_open())
assert hass.states.get("cover.name_1").state == STATE_CLOSED
async def test_update_reports_open_cover(hass: HomeAssistant) -> None:
"""Tests that update command sets correct state when Bond API reports cover is open."""
await setup_platform(hass, COVER_DOMAIN, shades("name-1"))
with patch_bond_device_state(return_value={"open": 1}):
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done()
assert hass.states.get("cover.name_1").state == "open"
async def test_update_reports_closed_cover(hass: HomeAssistant) -> None:
"""Tests that update command sets correct state when Bond API reports cover is closed."""
await setup_platform(hass, COVER_DOMAIN, shades("name-1"))
with patch_bond_device_state(return_value={"open": 0}):
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done()
assert hass.states.get("cover.name_1").state == "closed"
async def test_cover_available(hass: HomeAssistant) -> None:
"""Tests that available state is updated based on API errors."""
await help_test_entity_available(
hass, COVER_DOMAIN, shades("name-1"), "cover.name_1"
)
async def test_set_position_cover(hass: HomeAssistant) -> None:
"""Tests that set position cover command delegates to API."""
await setup_platform(
hass,
COVER_DOMAIN,
shades_with_position("name-1"),
bond_device_id="test-device-id",
)
with patch_bond_action() as mock_hold, patch_bond_device_state(
return_value={"position": 0, "open": 1}
):
await hass.services.async_call(
COVER_DOMAIN,
SERVICE_SET_COVER_POSITION,
{ATTR_ENTITY_ID: "cover.name_1", ATTR_POSITION: 100},
blocking=True,
)
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done()
mock_hold.assert_called_once_with("test-device-id", Action.set_position(0))
entity_state = hass.states.get("cover.name_1")
assert entity_state.state == STATE_OPEN
assert entity_state.attributes[ATTR_CURRENT_POSITION] == 100
with patch_bond_action() as mock_hold, patch_bond_device_state(
return_value={"position": 100, "open": 0}
):
await hass.services.async_call(
COVER_DOMAIN,
SERVICE_SET_COVER_POSITION,
{ATTR_ENTITY_ID: "cover.name_1", ATTR_POSITION: 0},
blocking=True,
)
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done()
mock_hold.assert_called_once_with("test-device-id", Action.set_position(100))
entity_state = hass.states.get("cover.name_1")
assert entity_state.state == STATE_CLOSED
assert entity_state.attributes[ATTR_CURRENT_POSITION] == 0
with patch_bond_action() as mock_hold, patch_bond_device_state(
return_value={"position": 40, "open": 1}
):
await hass.services.async_call(
COVER_DOMAIN,
SERVICE_SET_COVER_POSITION,
{ATTR_ENTITY_ID: "cover.name_1", ATTR_POSITION: 60},
blocking=True,
)
async_fire_time_changed(hass, utcnow() + timedelta(seconds=30))
await hass.async_block_till_done()
mock_hold.assert_called_once_with("test-device-id", Action.set_position(40))
entity_state = hass.states.get("cover.name_1")
assert entity_state.state == STATE_OPEN
assert entity_state.attributes[ATTR_CURRENT_POSITION] == 60