15
15
from kasa .deviceconfig import DeviceConfig
16
16
from kasa .exceptions import (
17
17
AuthenticationError ,
18
+ DeviceError ,
18
19
KasaException ,
19
20
SmartErrorCode ,
20
21
)
@@ -200,6 +201,22 @@ async def test_unencrypted_response(mocker, caplog):
200
201
)
201
202
202
203
204
+ async def test_device_blocked_response (mocker ):
205
+ host = "127.0.0.1"
206
+ mock_ssl_aes_device = MockSslAesDevice (host , device_blocked = True )
207
+ mocker .patch .object (
208
+ aiohttp .ClientSession , "post" , side_effect = mock_ssl_aes_device .post
209
+ )
210
+
211
+ transport = SslAesTransport (
212
+ config = DeviceConfig (host , credentials = Credentials (MOCK_USER , MOCK_PWD ))
213
+ )
214
+ msg = "Device blocked for 1685 seconds"
215
+
216
+ with pytest .raises (DeviceError , match = msg ):
217
+ await transport .perform_handshake ()
218
+
219
+
203
220
async def test_port_override ():
204
221
"""Test that port override sets the app_url."""
205
222
host = "127.0.0.1"
@@ -235,6 +252,11 @@ class MockSslAesDevice:
235
252
},
236
253
}
237
254
255
+ DEVICE_BLOCKED_RESP = {
256
+ "data" : {"code" : SmartErrorCode .DEVICE_BLOCKED .value , "sec_left" : 1685 },
257
+ "error_code" : SmartErrorCode .SESSION_EXPIRED .value ,
258
+ }
259
+
238
260
class _mock_response :
239
261
def __init__ (self , status , request : dict ):
240
262
self .status = status
@@ -263,6 +285,7 @@ def __init__(
263
285
send_error_code = 0 ,
264
286
secure_passthrough_error_code = 0 ,
265
287
digest_password_fail = False ,
288
+ device_blocked = False ,
266
289
):
<
57A7
/tr>267
290
self .host = host
268
291
self .http_client = HttpClient (DeviceConfig (self .host ))
@@ -277,6 +300,7 @@ def __init__(
277
300
self .do_not_encrypt_response = do_not_encrypt_response
278
301
self .want_default_username = want_default_username
279
302
self .digest_password_fail = digest_password_fail
303
+ self .device_blocked = device_blocked
280
304
281
305
async def post (self , url : URL , params = None , json = None , data = None , * _ , ** __ ):
282
306
if data :
@@ -303,6 +327,9 @@ async def _return_handshake1_response(self, url: URL, request: dict[str, Any]):
303
327
request_nonce = request ["params" ].get ("cnonce" )
304
328
request_username = request ["params" ].get ("username" )
305
329
330
+ if self .device_blocked :
331
+ return self ._mock_response (self .status_code , self .DEVICE_BLOCKED_RESP )
332
+
306
333
if (self .want_default_username and request_username != MOCK_ADMIN_USER ) or (
307
334
not self .want_default_username and request_username != MOCK_USER
308
335
):
0 commit comments