1111# String generation
1212import random
1313import string
14+ from unittest .mock import patch
1415
1516# Testing
1617import aiohttp
@@ -54,6 +55,7 @@ async def setup_app(
5455 timeout = False ,
5556 raise_timeout = False ,
5657 fail_auth = False ,
58+ stretch = False ,
5759 ):
5860 """Create mock webserver for Smile to interface with."""
5961 app = aiohttp .web .Application ()
@@ -86,12 +88,17 @@ async def setup_app(
8688 "DELETE" , "/core/notifications{tail:.*}" , self .smile_del_notification
8789 )
8890 app .router .add_route ("PUT" , "/core/rules{tail:.*}" , self .smile_set_schedule )
89- app .router .add_route (
90- "PUT" , "/core/appliances{tail:.*}" , self .smile_set_relay
91- )
9291 app .router .add_route (
9392 "DELETE" , "/core/notifications{tail:.*}" , self .smile_del_notification
9493 )
94+ if not stretch :
95+ app .router .add_route (
96+ "PUT" , "/core/appliances{tail:.*}" , self .smile_set_relay
97+ )
98+ else :
99+ app .router .add_route (
100+ "PUT" , "/core/appliances{tail:.*}" , self .smile_set_relay_stretch
101+ )
95102 else :
96103 app .router .add_route ("PUT" , "/core/locations{tail:.*}" , self .smile_timeout )
97104 app .router .add_route ("PUT" , "/core/rules{tail:.*}" , self .smile_timeout )
@@ -176,6 +183,11 @@ async def smile_set_relay(self, request):
176183 text = "<xml />"
177184 raise aiohttp .web .HTTPAccepted (text = text )
178185
186+ async def smile_set_relay_stretch (self , request ):
187+ """Render generic API calling endpoint."""
188+ text = "<xml />"
189+ raise aiohttp .web .HTTPOk (text = text )
190+
179191 async def smile_del_notification (self , request ):
180192 """Render generic API calling endpoint."""
181193 text = "<xml />"
@@ -194,13 +206,18 @@ async def smile_fail_auth(self, request):
194206 raise aiohttp .web .HTTPUnauthorized ()
195207
196208 async def connect (
197- self , broken = False , timeout = False , raise_timeout = False , fail_auth = False
209+ self ,
210+ broken = False ,
211+ timeout = False ,
212+ raise_timeout = False ,
213+ fail_auth = False ,
214+ stretch = False ,
198215 ):
199216 """Connect to a smile environment and perform basic asserts."""
200217 port = aiohttp .test_utils .unused_port ()
201218
202219 # Happy flow
203- app = await self .setup_app (broken , timeout , raise_timeout , fail_auth )
220+ app = await self .setup_app (broken , timeout , raise_timeout , fail_auth , stretch )
204221
205222 server = aiohttp .test_utils .TestServer (
206223 app , port = port , scheme = "http" , host = "127.0.0.1"
@@ -271,7 +288,9 @@ async def connect(
271288 raise exception
272289
273290 # Wrap connect for invalid connections
274- async def connect_wrapper (self , raise_timeout = False , fail_auth = False ):
291+ async def connect_wrapper (
292+ self , raise_timeout = False , fail_auth = False , stretch = False
293+ ):
275294 """Wrap connect to try negative testing before positive testing."""
276295
277296 if fail_auth :
@@ -305,7 +324,7 @@ async def connect_wrapper(self, raise_timeout=False, fail_auth=False):
305324 _LOGGER .info (" + successfully passed XML issue handling." )
306325
307326 _LOGGER .info ("Connecting to functioning device:" )
308- return await self .connect ()
327+ return await self .connect (stretch = stretch )
309328
310329 # Generic disconnect
311330 @pytest .mark .asyncio
@@ -800,7 +819,7 @@ async def test_connect_anna_without_boiler_fw3(self):
800819 "a270735e4ccd45239424badc0578a2b1" : {
801820 "outdoor_temperature" : 10.8 ,
802821 },
803- ## Central
822+ # # Central
804823 # "c46b4794d28149699eacf053deedd003": {
805824 # "heating_state": False,
806825 # },
@@ -859,7 +878,7 @@ async def test_connect_anna_without_boiler_fw4(self):
859878 "a270735e4ccd45239424badc0578a2b1" : {
860879 "outdoor_temperature" : 16.6 ,
861880 },
862- ## Central
881+ # # Central
863882 # "c46b4794d28149699eacf053deedd003": {
864883 # "heating_state": True,
865884 # },
@@ -1414,7 +1433,7 @@ async def test_connect_stretch_v31(self):
14141433 }
14151434
14161435 self .smile_setup = "stretch_v31"
1417- server , smile , client = await self .connect_wrapper ()
1436+ server , smile , client = await self .connect_wrapper (stretch = True )
14181437 assert smile .smile_hostname == "stretch000000"
14191438
14201439 _LOGGER .info ("Basics:" )
@@ -1450,7 +1469,7 @@ async def test_connect_stretch_v23(self):
14501469 }
14511470
14521471 self .smile_setup = "stretch_v23"
1453- server , smile , client = await self .connect_wrapper ()
1472+ server , smile , client = await self .connect_wrapper (stretch = True )
14541473 assert smile .smile_hostname == "stretch000000"
14551474
14561475 _LOGGER .info ("Basics:" )
@@ -1536,6 +1555,17 @@ async def test_connect_fail_firmware(self):
15361555 except pw_exceptions .UnsupportedDeviceError :
15371556 assert True
15381557
1558+ # Test connect for timeout
1559+ @patch ("async_timeout.timeout" , side_effect = asyncio .exceptions .TimeoutError )
1560+ async def test_connect_timeout (self , timeout_test ):
1561+ """Wrap connect to raise timeout during get."""
1562+
1563+ try :
1564+ await self .connect_wrapper ()
1565+ assert False # pragma: no cover
1566+ except pw_exceptions .DeviceTimeoutError :
1567+ assert True
1568+
15391569 class PlugwiseTestError (Exception ):
15401570 """Plugwise test exceptions class."""
15411571
0 commit comments