1111# String generation
1212import random
1313import string
14- import sys
1514
1615# Testing
1716import aiohttp
3231# as inclusion point
3332
3433
35- class TestPlugwise :
34+ class TestPlugwise : # pylint: disable=attribute-defined-outside-init
3635 """Tests for Plugwise Smile."""
3736
3837 def _write_json (self , call , data ):
@@ -53,7 +52,7 @@ async def setup_app(
5352 self ,
5453 broken = False ,
5554 timeout = False ,
56- put_timeout = False ,
55+ raise_timeout = False ,
5756 ):
5857 """Create mock webserver for Smile to interface with."""
5958 app = aiohttp .web .Application ()
@@ -72,18 +71,24 @@ async def setup_app(
7271
7372 # Introducte timeout with 2 seconds, test by setting response to 10ms
7473 # Don't actually wait 2 seconds as this will prolongue testing
75- if not put_timeout :
74+ if not raise_timeout :
7675 app .router .add_route (
7776 "PUT" , "/core/locations{tail:.*}" , self .smile_set_temp_or_preset
7877 )
7978 app .router .add_route ("PUT" , "/core/rules{tail:.*}" , self .smile_set_schedule )
8079 app .router .add_route (
8180 "PUT" , "/core/appliances{tail:.*}" , self .smile_set_relay
8281 )
82+ app .router .add_route (
83+ "DELETE" , "/core/notifications{tail:.*}" , self .smile_del_notification
84+ )
8385 else :
8486 app .router .add_route ("PUT" , "/core/locations{tail:.*}" , self .smile_timeout )
8587 app .router .add_route ("PUT" , "/core/rules{tail:.*}" , self .smile_timeout )
8688 app .router .add_route ("PUT" , "/core/appliances{tail:.*}" , self .smile_timeout )
89+ app .router .add_route (
90+ "DELETE" , "/core/notifications{tail:.*}" , self .smile_timeout
91+ )
8792
8893 return app
8994
@@ -94,9 +99,9 @@ async def smile_appliances(self, request):
9499 os .path .dirname (__file__ ),
95100 f"../userdata/{ self .smile_setup } /core.appliances.xml" ,
96101 )
97- f = open (userdata )
98- data = f .read ()
99- f .close ()
102+ filedata = open (userdata )
103+ data = filedata .read ()
104+ filedata .close ()
100105 return aiohttp .web .Response (text = data )
101106
102107 async def smile_domain_objects (self , request ):
@@ -105,9 +110,9 @@ async def smile_domain_objects(self, request):
105110 os .path .dirname (__file__ ),
106111 f"../userdata/{ self .smile_setup } /core.domain_objects.xml" ,
107112 )
108- f = open (userdata )
109- data = f .read ()
110- f .close ()
113+ filedata = open (userdata )
114+ data = filedata .read ()
115+ filedata .close ()
111116 return aiohttp .web .Response (text = data )
112117
113118 async def smile_locations (self , request ):
@@ -116,9 +121,9 @@ async def smile_locations(self, request):
116121 os .path .dirname (__file__ ),
117122 f"../userdata/{ self .smile_setup } /core.locations.xml" ,
118123 )
119- f = open (userdata )
120- data = f .read ()
121- f .close ()
124+ filedata = open (userdata )
125+ data = filedata .read ()
126+ filedata .close ()
122127 return aiohttp .web .Response (text = data )
123128
124129 async def smile_modules (self , request ):
@@ -127,9 +132,9 @@ async def smile_modules(self, request):
127132 os .path .dirname (__file__ ),
128133 f"../userdata/{ self .smile_setup } /core.modules.xml" ,
129134 )
130- f = open (userdata )
131- data = f .read ()
132- f .close ()
135+ filedata = open (userdata )
136+ data = filedata .read ()
137+ filedata .close ()
133138 return aiohttp .web .Response (text = data )
134139
135140 async def smile_status (self , request ):
@@ -139,12 +144,12 @@ async def smile_status(self, request):
139144 os .path .dirname (__file__ ),
140145 f"../userdata/{ self .smile_setup } /system_status_xml.xml" ,
141146 )
142- f = open (userdata )
143- data = f .read ()
144- f .close ()
147+ filedata = open (userdata )
148+ data = filedata .read ()
149+ filedata .close ()
145150 return aiohttp .web .Response (text = data )
146151 except OSError :
147- raise self . ConnectError
152+ raise aiohttp . web . HTTPNotFound
148153
149154 async def smile_set_temp_or_preset (self , request ):
150155 """Render generic API calling endpoint."""
@@ -161,6 +166,11 @@ async def smile_set_relay(self, request):
161166 text = "<xml />"
162167 raise aiohttp .web .HTTPAccepted (text = text )
163168
169+ async def smile_del_notification (self , request ):
170+ """Render generic API calling endpoint."""
171+ text = "<xml />"
172+ raise aiohttp .web .HTTPAccepted (text = text )
173+
164174 async def smile_timeout (self , request ):
165175 """Render timeout endpoint."""
166176 raise asyncio .TimeoutError
@@ -169,12 +179,12 @@ async def smile_broken(self, request):
169179 """Render server error endpoint."""
170180 raise aiohttp .web .HTTPInternalServerError (text = "Internal Server Error" )
171181
172- async def connect (self , broken = False , timeout = False , put_timeout = False ):
182+ async def connect (self , broken = False , timeout = False , raise_timeout = False ):
173183 """Connect to a smile environment and perform basic asserts."""
174184 port = aiohttp .test_utils .unused_port ()
175185
176186 # Happy flow
177- app = await self .setup_app (broken , timeout , put_timeout )
187+ app = await self .setup_app (broken , timeout , raise_timeout )
178188
179189 server = aiohttp .test_utils .TestServer (
180190 app , port = port , scheme = "http" , host = "127.0.0.1"
@@ -200,6 +210,21 @@ async def connect(self, broken=False, timeout=False, put_timeout=False):
200210 text = await resp .text ()
201211 assert "xml" in text
202212
213+ # Test lack of websession
214+ try :
215+ smile = pw_smile .Smile (
216+ host = server .host ,
217+ username = "smile" ,
218+ password = "" .join (
219+ random .choice (string .ascii_lowercase ) for i in range (8 )
220+ ),
221+ port = server .port ,
222+ websession = None ,
223+ )
224+ assert False
225+ except Exception : # pylint disable=broad-except
226+ assert True
227+
203228 smile = pw_smile .Smile (
204229 host = server .host ,
205230 username = "smile" ,
@@ -219,16 +244,19 @@ async def connect(self, broken=False, timeout=False, put_timeout=False):
219244 assert connection_state
220245 assert smile .smile_type is not None
221246 return server , smile , client
222- except (pw_exceptions .DeviceTimeoutError , pw_exceptions .InvalidXMLError ) as e :
247+ except (
248+ pw_exceptions .DeviceTimeoutError ,
249+ pw_exceptions .InvalidXMLError ,
250+ ) as exception :
223251 await self .disconnect (server , client )
224- raise e
252+ raise exception
225253
226254 # Wrap connect for invalid connections
227- async def connect_wrapper (self , put_timeout = False ):
255+ async def connect_wrapper (self , raise_timeout = False ):
228256 """Wrap connect to try negative testing before positive testing."""
229- if put_timeout :
257+ if raise_timeout :
230258 _LOGGER .warning ("Connecting to device exceeding timeout in handling:" )
231- return await self .connect (put_timeout = True )
259+ return await self .connect (raise_timeout = True )
232260
233261 try :
234262 _LOGGER .warning ("Connecting to device exceeding timeout in response:" )
@@ -479,7 +507,7 @@ async def test_connect_legacy_anna(self):
479507 await smile .close_connection ()
480508 await self .disconnect (server , client )
481509
482- server , smile , client = await self .connect_wrapper (put_timeout = True )
510+ server , smile , client = await self .connect_wrapper (raise_timeout = True )
483511 await self .tinker_thermostat (
484512 smile ,
485513 "c34c6864216446528e95d88985e714cc" ,
@@ -540,7 +568,7 @@ async def test_connect_legacy_anna_2(self):
540568 await smile .close_connection ()
541569 await self .disconnect (server , client )
542570
543- server , smile , client = await self .connect_wrapper (put_timeout = True )
571+ server , smile , client = await self .connect_wrapper (raise_timeout = True )
544572 await self .tinker_thermostat (
545573 smile ,
546574 "c34c6864216446528e95d88985e714cc" ,
@@ -587,7 +615,7 @@ async def test_connect_smile_p1_v2(self):
587615 await smile .close_connection ()
588616 await self .disconnect (server , client )
589617
590- server , smile , client = await self .connect_wrapper (put_timeout = True )
618+ server , smile , client = await self .connect_wrapper (raise_timeout = True )
591619
592620 @pytest .mark .asyncio
593621 async def test_connect_smile_p1_v2_2 (self ):
@@ -674,7 +702,7 @@ async def test_connect_anna_v4(self):
674702 await smile .close_connection ()
675703 await self .disconnect (server , client )
676704
677- server , smile , client = await self .connect_wrapper (put_timeout = True )
705+ server , smile , client = await self .connect_wrapper (raise_timeout = True )
678706 await self .tinker_thermostat (
679707 smile ,
680708 "eb5309212bf5407bb143e5bfa3b18aee" ,
@@ -709,7 +737,7 @@ async def test_connect_anna_v4_no_tag(self):
709737 await smile .close_connection ()
710738 await self .disconnect (server , client )
711739
712- server , smile , client = await self .connect_wrapper (put_timeout = True )
740+ server , smile , client = await self .connect_wrapper (raise_timeout = True )
713741 await self .tinker_thermostat (
714742 smile ,
715743 "eb5309212bf5407bb143e5bfa3b18aee" ,
@@ -766,7 +794,7 @@ async def test_connect_anna_without_boiler_fw3(self):
766794 await smile .close_connection ()
767795 await self .disconnect (server , client )
768796
769- server , smile , client = await self .connect_wrapper (put_timeout = True )
797+ server , smile , client = await self .connect_wrapper (raise_timeout = True )
770798 await self .tinker_thermostat (
771799 smile ,
772800 "c34c6864216446528e95d88985e714cc" ,
@@ -823,7 +851,7 @@ async def test_connect_anna_without_boiler_fw4(self):
823851 await smile .close_connection ()
824852 await self .disconnect (server , client )
825853
826- server , smile , client = await self .connect_wrapper (put_timeout = True )
854+ server , smile , client = await self .connect_wrapper (raise_timeout = True )
827855 await self .tinker_thermostat (
828856 smile ,
829857 "c34c6864216446528e95d88985e714cc" ,
@@ -884,7 +912,7 @@ async def test_connect_adam_plus_anna(self):
884912 await smile .close_connection ()
885913 await self .disconnect (server , client )
886914
887- server , smile , client = await self .connect_wrapper (put_timeout = True )
915+ server , smile , client = await self .connect_wrapper (raise_timeout = True )
888916 await self .tinker_thermostat (
889917 smile ,
890918 "009490cc2f674ce6b576863fbb64f867" ,
@@ -982,6 +1010,7 @@ async def test_connect_adam_zone_per_device(self):
9821010 assert not smile .single_master_thermostat ()
9831011
9841012 assert "af82e4ccf9c548528166d38e560662a4" in smile .notifications
1013+ await smile .delete_notification ()
9851014
9861015 await self .device_test (smile , testdata )
9871016 await self .tinker_thermostat (
@@ -994,7 +1023,7 @@ async def test_connect_adam_zone_per_device(self):
9941023 await smile .close_connection ()
9951024 await self .disconnect (server , client )
9961025
997- server , smile , client = await self .connect_wrapper (put_timeout = True )
1026+ server , smile , client = await self .connect_wrapper (raise_timeout = True )
9981027 await self .tinker_thermostat (
9991028 smile ,
10001029 "c50f167537524366a5af7aa3942feb1e" ,
@@ -1007,6 +1036,12 @@ async def test_connect_adam_zone_per_device(self):
10071036 good_schemas = ["CV Jessie" ],
10081037 unhappy = True ,
10091038 )
1039+ try :
1040+ await smile .delete_notification ()
1041+ assert False
1042+ except pw_exceptions .ResponseError :
1043+ print ("HOI responseerror" )
1044+ assert True
10101045 await smile .close_connection ()
10111046 await self .disconnect (server , client )
10121047
@@ -1077,7 +1112,7 @@ async def test_connect_adam_multiple_devices_per_zone(self):
10771112 await smile .close_connection ()
10781113 await self .disconnect (server , client )
10791114
1080- server , smile , client = await self .connect_wrapper (put_timeout = True )
1115+ server , smile , client = await self .connect_wrapper (raise_timeout = True )
10811116 await self .tinker_thermostat (
10821117 smile ,
10831118 "c50f167537524366a5af7aa3942feb1e" ,
0 commit comments