Skip to content

Commit d494ee9

Browse files
authored
Enhance tests for Motion Gateway interface detection
Refactor tests for Motion Gateway interface detection, adding tests for dual and single NIC scenarios, interface timeout handling, and fallback mechanisms.
1 parent 23c9c2a commit d494ee9

1 file changed

Lines changed: 136 additions & 14 deletions

File tree

Lines changed: 136 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,143 @@
1-
"""Test the Motionblinds config flow."""
1+
"""Tests for Motion Gateway interface detection."""
2+
import asyncio
3+
from unittest.mock import AsyncMock, MagicMock, patch
24

3-
from unittest.mock import Mock
5+
import pytest
46

5-
from motionblinds import DEVICE_TYPES_WIFI, BlindType
7+
from homeassistant.components.motion_blindds.gateway import ConnectMotionGateway
8+
from homeassistant.components.motion_blinds.const import DEFAULT_INTERFACE
69

7-
from homeassistant.components.motion_blinds.gateway import device_name
8-
from homeassistant.core import HomeAssistant
910

10-
TEST_BLIND_MAC = "abcdefghujkl0001"
11+
MOCK_ADAPTERS_DUAL_NIC = [
12+
{
13+
"ipv4": [{"address": "192.168.1.10"}],
14+
"enabled": True,
15+
"default": True,
16+
},
17+
{
18+
"ipv4": [{"address": "192.168.20.10"}],
19+
"enabled": True,
20+
"default": False,
21+
},
22+
]
1123

24+
MOCK_ADAPTERS_SINGLE_NIC = [
25+
{
26+
"ipv4": [{"address": "192.168.1.10"}],
27+
"enabled": True,
28+
"default": True,
29+
},
30+
]
1231

13-
async def test_device_name(hass: HomeAssistant) -> None:
14-
"""test_device_name."""
15-
blind = Mock()
16-
blind.blind_type = BlindType.RollerBlind.name
17-
blind.mac = TEST_BLIND_MAC
18-
assert device_name(blind) == "RollerBlind 0001"
1932

20-
blind.device_type = DEVICE_TYPES_WIFI[0]
21-
assert device_name(blind) == "RollerBlind"
33+
async def test_get_interfaces_dual_nic_default_prioritized(hass):
34+
"""Test that default interface is first in list with multiple NICs."""
35+
gateway = ConnectMotionGateway(hass)
36+
37+
with patch(
38+
"homeassistant.components.motion_blinds.gateway.network.async_get_adapters",
39+
return_value=MOCK_ADAPTERS_DUAL_NIC,
40+
):
41+
interfaces = await gateway.async_get_interfaces()
42+
43+
# Default interface (192.168.1.10) must be first
44+
assert interfaces[0] == "192.168.1.10"
45+
46+
47+
async def test_get_interfaces_single_nic(hass):
48+
"""Test that single NIC setup still works correctly."""
49+
gateway = ConnectMotionGateway(hass)
50+
51+
with patch(
52+
"homeassistant.components.motion_blinds.gateway.network.async_get_adapters",
53+
return_value=MOCK_ADAPTERS_SINGLE_NIC,
54+
):
55+
interfaces = await gateway.async_get_interfaces()
56+
57+
assert interfaces[0] == "192.168.1.10"
58+
59+
60+
async def test_check_interface_timeout_moves_to_next(hass):
61+
"""Test that a timed out interface check moves to the next interface."""
62+
gateway = ConnectMotionGateway(hass)
63+
successful_interface = "192.168.1.10"
64+
65+
with patch(
66+
"homeassistant.components.motion_blinds.gateway.network.async_get_adapters",
67+
return_value=MOCK_ADAPTERS_DUAL_NIC,
68+
), patch(
69+
"homeassistant.components.motion_blinds.gateway.AsyncMotionMulticast"
70+
) as mock_multicast, patch(
71+
"homeassistant.components.motion_blinds.gateway.MotionGateway"
72+
):
73+
mock_instance = MagicMock()
74+
mock_instance.Start_listen = AsyncMock()
75+
mock_instance.Stop_listen = MagicMock()
76+
mock_multicast.return_value = mock_instance
77+
78+
call_count = 0
79+
80+
async def check_interface_side_effect():
81+
nonlocal call_count
82+
call_count += 1
83+
# First interface times out, second succeeds
84+
if call_count == 1:
85+
await asyncio.sleep(10) # Will be cancelled by timeout
86+
return True
87+
88+
with patch.object(
89+
gateway,
90+
"check_interface",
91+
side_effect=check_interface_side_effect,
92+
):
93+
result = await gateway.async_check_interface("192.168.1.1", "testkey")
94+
95+
assert result == successful_interface
96+
97+
98+
async def test_check_interface_found_on_first_try(hass):
99+
"""Test that correct interface on first try returns immediately."""
100+
gateway = ConnectMotionGateway(hass)
101+
102+
with patch(
103+
"homeassistant.components.motion_blinds.gateway.network.async_get_adapters",
104+
return_value=MOCK_ADAPTERS_DUAL_NIC,
105+
), patch(
106+
"homeassistant.components.motion_blinds.gateway.AsyncMotionMulticast"
107+
) as mock_multicast, patch(
108+
"homeassistant.components.motion_blinds.gateway.MotionGateway"
109+
):
110+
mock_instance = MagicMock()
111+
mock_instance.Start_listen = AsyncMock()
112+
mock_instance.Stop_listen = MagicMock()
113+
mock_multicast.return_value = mock_instance
114+
115+
with patch.object(gateway, "check_interface", return_value=True):
116+
result = await gateway.async_check_interface("192.168.1.1", "testkey")
117+
118+
# Should return the first (default) interface immediately
119+
assert result == "192.168.1.10"
120+
121+
122+
async def test_check_interface_none_working_falls_back(hass):
123+
"""Test fallback to stored interface when none work."""
124+
gateway = ConnectMotionGateway(hass, interface="0.0.0.0")
125+
126+
with patch(
127+
"homeassistant.components.motion_blinds.gateway.network.async_get_adapters",
128+
return_value=MOCK_ADAPTERS_DUAL_NIC,
129+
), patch(
130+
"homeassistant.components.motion_blinds.gateway.AsyncMotionMulticast"
131+
) as mock_multicast, patch(
132+
"homeassistant.components.motion_blinds.gateway.MotionGateway"
133+
):
134+
mock_instance = MagicMock()
135+
mock_instance.Start_listen = AsyncMock()
136+
mock_instance.Stop_listen = MagicMock()
137+
mock_multicast.return_value = mock_instance
138+
139+
with patch.object(gateway, "check_interface", return_value=False):
140+
result = await gateway.async_check_interface("192.168.1.1", "testkey")
141+
142+
# Should fall back to stored interface
143+
assert result == "0.0.0.0"

0 commit comments

Comments
 (0)