From 6ffd4de223b7e1ba09d2eaeec5f52ce897175df1 Mon Sep 17 00:00:00 2001 From: bfayers Date: Fri, 12 Feb 2021 11:31:22 +0000 Subject: [PATCH 1/8] add account stats GET before login POST --- libpurecool/dyson.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libpurecool/dyson.py b/libpurecool/dyson.py index 79a818f..a6ec1a1 100644 --- a/libpurecool/dyson.py +++ b/libpurecool/dyson.py @@ -52,6 +52,18 @@ def login(self): urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) _LOGGER.debug("Disabling insecure request warnings since " "dyson are using a self signed certificate.") + + #Must first check account status + accountstatus = requests.get(f"https://{self._dyson_api_url}/v1/userregistration/userstatus?country={self._country}&email={self._email}") + if accountstatus.status_code == requests.codes.ok: + json_status = accountstatus.json() + if json_status['accountStatus'] != "ACTIVE": + #The account is not active + self._logged = False + return self._logged + else: + self._logged = False + return self._logged request_body = { "Email": self._email, From b41eadf2fd918249354d7976dbf7fa21675ada3d Mon Sep 17 00:00:00 2001 From: bfayers Date: Fri, 12 Feb 2021 11:31:41 +0000 Subject: [PATCH 2/8] set verify=False because dyson run self signed certs --- libpurecool/dyson.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libpurecool/dyson.py b/libpurecool/dyson.py index a6ec1a1..f07b50e 100644 --- a/libpurecool/dyson.py +++ b/libpurecool/dyson.py @@ -54,7 +54,7 @@ def login(self): "dyson are using a self signed certificate.") #Must first check account status - accountstatus = requests.get(f"https://{self._dyson_api_url}/v1/userregistration/userstatus?country={self._country}&email={self._email}") + accountstatus = requests.get(f"https://{self._dyson_api_url}/v1/userregistration/userstatus?country={self._country}&email={self._email}", verify=False) if accountstatus.status_code == requests.codes.ok: json_status = accountstatus.json() if json_status['accountStatus'] != "ACTIVE": From ac5566fa91a913c875fc1b3ad4c336e636c56a2c Mon Sep 17 00:00:00 2001 From: bfayers Date: Fri, 12 Feb 2021 12:50:54 +0000 Subject: [PATCH 3/8] use the headers for the status check, maybe unnecesarry; also use json= instead of data= in the POST --- libpurecool/dyson.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libpurecool/dyson.py b/libpurecool/dyson.py index f07b50e..1cda87d 100644 --- a/libpurecool/dyson.py +++ b/libpurecool/dyson.py @@ -41,7 +41,7 @@ def __init__(self, email, password, country): self._country = country self._logged = False self._auth = None - self._headers = {'User-Agent': DYSON_API_USER_AGENT} + self._headers = {'User-Agent': DYSON_API_USER_AGENT, 'Content-Type': 'application/json'} if country == "CN": self._dyson_api_url = DYSON_API_URL_CN else: @@ -54,7 +54,7 @@ def login(self): "dyson are using a self signed certificate.") #Must first check account status - accountstatus = requests.get(f"https://{self._dyson_api_url}/v1/userregistration/userstatus?country={self._country}&email={self._email}", verify=False) + accountstatus = requests.get(f"https://{self._dyson_api_url}/v1/userregistration/userstatus?country={self._country}&email={self._email}", headers=self._headers, verify=False) if accountstatus.status_code == requests.codes.ok: json_status = accountstatus.json() if json_status['accountStatus'] != "ACTIVE": @@ -73,7 +73,7 @@ def login(self): "https://{0}/v1/userregistration/authenticate?country={1}".format( self._dyson_api_url, self._country), headers=self._headers, - data=request_body, + json=request_body, verify=False ) # pylint: disable=no-member From 8ac02d076007ceb08cb592ce0de322f8a25f6550 Mon Sep 17 00:00:00 2001 From: bfayers Date: Fri, 12 Feb 2021 13:12:40 +0000 Subject: [PATCH 4/8] some changes to bring style in line with existing code as well as to help CI pass --- libpurecool/dyson.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/libpurecool/dyson.py b/libpurecool/dyson.py index 1cda87d..9d720c5 100644 --- a/libpurecool/dyson.py +++ b/libpurecool/dyson.py @@ -41,7 +41,10 @@ def __init__(self, email, password, country): self._country = country self._logged = False self._auth = None - self._headers = {'User-Agent': DYSON_API_USER_AGENT, 'Content-Type': 'application/json'} + self._headers = { + 'User-Agent': DYSON_API_USER_AGENT, + 'Content-Type': 'application/json' + } if country == "CN": self._dyson_api_url = DYSON_API_URL_CN else: @@ -52,13 +55,17 @@ def login(self): urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) _LOGGER.debug("Disabling insecure request warnings since " "dyson are using a self signed certificate.") - - #Must first check account status - accountstatus = requests.get(f"https://{self._dyson_api_url}/v1/userregistration/userstatus?country={self._country}&email={self._email}", headers=self._headers, verify=False) + # Must first check account status + accountstatus = requests.get( + "https://{0}/v1/userregistration/userstatus?country={1}&email={2}".format( + self._dyson_api_url, self._country, self._email), + headers=self._headers, + verify=False) + # pylint: disable=no-member if accountstatus.status_code == requests.codes.ok: json_status = accountstatus.json() if json_status['accountStatus'] != "ACTIVE": - #The account is not active + # The account is not active self._logged = False return self._logged else: From 6307f4c44c2e74e0a620057a61e0193f69f0ec15 Mon Sep 17 00:00:00 2001 From: bfayers Date: Fri, 12 Feb 2021 13:14:31 +0000 Subject: [PATCH 5/8] Make changes as suggested by shenxn --- libpurecool/dyson.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libpurecool/dyson.py b/libpurecool/dyson.py index 9d720c5..0ca2f34 100644 --- a/libpurecool/dyson.py +++ b/libpurecool/dyson.py @@ -41,10 +41,7 @@ def __init__(self, email, password, country): self._country = country self._logged = False self._auth = None - self._headers = { - 'User-Agent': DYSON_API_USER_AGENT, - 'Content-Type': 'application/json' - } + self._headers = {'User-Agent': DYSON_API_USER_AGENT} if country == "CN": self._dyson_api_url = DYSON_API_URL_CN else: @@ -57,10 +54,11 @@ def login(self): "dyson are using a self signed certificate.") # Must first check account status accountstatus = requests.get( - "https://{0}/v1/userregistration/userstatus?country={1}&email={2}".format( - self._dyson_api_url, self._country, self._email), + "https://{0}/v1/userregistration/userstatus".format(self._dyson_api_url), + params={"country": self._country, "email": self._email}, headers=self._headers, - verify=False) + verify=False, + ) # pylint: disable=no-member if accountstatus.status_code == requests.codes.ok: json_status = accountstatus.json() From 3965d81938a6a0b596e9047d5d95746df2538554 Mon Sep 17 00:00:00 2001 From: bfayers Date: Sat, 13 Feb 2021 14:51:03 +0000 Subject: [PATCH 6/8] break up the format on line 57 --- libpurecool/dyson.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libpurecool/dyson.py b/libpurecool/dyson.py index 0ca2f34..fb3ad4e 100644 --- a/libpurecool/dyson.py +++ b/libpurecool/dyson.py @@ -54,7 +54,9 @@ def login(self): "dyson are using a self signed certificate.") # Must first check account status accountstatus = requests.get( - "https://{0}/v1/userregistration/userstatus".format(self._dyson_api_url), + "https://{0}/v1/userregistration/userstatus".format( + self._dyson_api_url + ), params={"country": self._country, "email": self._email}, headers=self._headers, verify=False, From f720d241c82a807d3e16ed33286a21bc78c294a5 Mon Sep 17 00:00:00 2001 From: bfayers Date: Sat, 27 Feb 2021 16:10:14 +0000 Subject: [PATCH 7/8] Updated login tests to work with call to userstatus --- tests/test_dyson_account.py | 60 ++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/tests/test_dyson_account.py b/tests/test_dyson_account.py index 69d18fa..a039f51 100644 --- a/tests/test_dyson_account.py +++ b/tests/test_dyson_account.py @@ -36,6 +36,44 @@ def _mocked_login_post_failed(*args, **kwargs): else: raise Exception("Unknown call") +def _mock_gets(*args, **kwargs): + if "provisioningservice" in args[0]: + return _mocked_list_devices(*args, **kwargs) + else: + return _mocked_status_get(*args, **kwargs) + +def _mocked_status_get(*args, **kwargs): + url = 'https://{0}{1}'.format(API_HOST, + '/v1/userregistration/userstatus') + params = {"country": "language", "email": "email"} + if args[0] == url and kwargs['params'] == params: + return MockResponse({ + 'accountStatus': 'ACTIVE' + }) + else: + raise Exception("Unknown call") + +def _mocked_status_get_cn(*args, **kwargs): + url = 'https://{0}{1}'.format(API_CN_HOST, + '/v1/userregistration/userstatus') + params = {"country": "CN", "email": "email"} + if args[0] == url and kwargs['params'] == params: + return MockResponse({ + 'accountStatus': 'ACTIVE' + }) + else: + raise Exception("Unknown call") + +def _mocked_status_get_failed(*args, **kwargs): + url = 'https://{0}{1}'.format(API_HOST, + '/v1/userregistration/userstatus') + params = {"country": "language", "email": "email"} + if args[0] == url and kwargs['params'] == params: + return MockResponse({ + 'accountStatus': 'INACTIVE' + }) + else: + raise Exception("Unknown call") def _mocked_login_post(*args, **kwargs): url = 'https://{0}{1}?{2}={3}'.format(API_HOST, @@ -43,7 +81,7 @@ def _mocked_login_post(*args, **kwargs): 'country', 'language') payload = {'Password': 'password', 'Email': 'email'} - if args[0] == url and kwargs['data'] == payload and \ + if args[0] == url and kwargs['json'] == payload and \ kwargs['headers'] == {'User-Agent': DYSON_API_USER_AGENT}: return MockResponse({ 'Account': 'account', @@ -59,7 +97,7 @@ def _mocked_login_post_cn(*args, **kwargs): 'country', 'CN') payload = {'Password': 'password', 'Email': 'email'} - if args[0] == url and kwargs['data'] == payload and \ + if args[0] == url and kwargs['json'] == payload and \ kwargs['headers'] == {'User-Agent': DYSON_API_USER_AGENT}: return MockResponse({ 'Account': 'account', @@ -167,32 +205,38 @@ def setUp(self): def tearDown(self): pass + @mock.patch('requests.get', side_effect=_mock_gets) @mock.patch('requests.post', side_effect=_mocked_login_post) - def test_connect_account(self, mocked_login): + def test_connect_account(self, mocked_login, mocked_status): dyson_account = DysonAccount("email", "password", "language") logged = dyson_account.login() + self.assertEqual(mocked_status.call_count, 1) self.assertEqual(mocked_login.call_count, 1) self.assertTrue(logged) + @mock.patch('requests.get', side_effect=_mocked_status_get_cn) @mock.patch('requests.post', side_effect=_mocked_login_post_cn) - def test_connect_account_cn(self, mocked_login): + def test_connect_account_cn(self, mocked_login, mocked_status): dyson_account = DysonAccount("email", "password", "CN") logged = dyson_account.login() + self.assertEqual(mocked_status.call_count, 1) self.assertEqual(mocked_login.call_count, 1) self.assertTrue(logged) + @mock.patch('requests.get', side_effect=_mocked_status_get_failed) @mock.patch('requests.post', side_effect=_mocked_login_post_failed) - def test_connect_account_failed(self, mocked_login): + def test_connect_account_failed(self, mocked_login, mocked_status): dyson_account = DysonAccount("email", "password", "language") logged = dyson_account.login() - self.assertEqual(mocked_login.call_count, 1) + self.assertEqual(mocked_status.call_count, 1) + self.assertEqual(mocked_login.call_count, 0) self.assertFalse(logged) def test_not_logged(self): dyson_account = DysonAccount("email", "password", "language") self.assertRaises(DysonNotLoggedException, dyson_account.devices) - @mock.patch('requests.get', side_effect=_mocked_list_devices) + @mock.patch('requests.get', side_effect=_mock_gets) @mock.patch('requests.post', side_effect=_mocked_login_post) def test_list_devices(self, mocked_login, mocked_list_devices): dyson_account = DysonAccount("email", "password", "language") @@ -200,7 +244,7 @@ def test_list_devices(self, mocked_login, mocked_list_devices): self.assertEqual(mocked_login.call_count, 1) self.assertTrue(dyson_account.logged) devices = dyson_account.devices() - self.assertEqual(mocked_list_devices.call_count, 2) + self.assertEqual(mocked_list_devices.call_count, 3) self.assertEqual(len(devices), 6) self.assertTrue(isinstance(devices[0], DysonPureCoolLink)) self.assertTrue(isinstance(devices[1], DysonPureHotCoolLink)) From dfe77cf295e80c7a4ea966ea21058d71bb333fae Mon Sep 17 00:00:00 2001 From: bfayers Date: Sat, 27 Feb 2021 16:17:23 +0000 Subject: [PATCH 8/8] Lint the changes for CI --- tests/test_dyson_account.py | 188 ++++++++++++++++++------------------ 1 file changed, 95 insertions(+), 93 deletions(-) diff --git a/tests/test_dyson_account.py b/tests/test_dyson_account.py index a039f51..39a1346 100644 --- a/tests/test_dyson_account.py +++ b/tests/test_dyson_account.py @@ -4,12 +4,17 @@ from libpurecool.dyson_pure_cool import DysonPureCool from libpurecool.dyson_pure_hotcool import DysonPureHotCool -from libpurecool.dyson import DysonAccount, DysonPureCoolLink, \ - DysonPureHotCoolLink, Dyson360Eye, DysonNotLoggedException, \ - DYSON_API_USER_AGENT +from libpurecool.dyson import ( + DysonAccount, + DysonPureCoolLink, + DysonPureHotCoolLink, + Dyson360Eye, + DysonNotLoggedException, + DYSON_API_USER_AGENT, +) -API_HOST = 'appapi.cp.dyson.com' -API_CN_HOST = 'appapi.cp.dyson.cn' +API_HOST = "appapi.cp.dyson.com" +API_CN_HOST = "appapi.cp.dyson.cn" class MockResponse: @@ -22,96 +27,93 @@ def json(self, **kwargs): def _mocked_login_post_failed(*args, **kwargs): - url = 'https://{0}{1}?{2}={3}'.format(API_HOST, - '/v1/userregistration/authenticate', - 'country', - 'language') - payload = {'Password': 'password', 'Email': 'email'} - if args[0] == url and kwargs['data'] == payload and \ - kwargs['headers'] == {'User-Agent': DYSON_API_USER_AGENT}: - return MockResponse({ - 'Account': 'account', - 'Password': 'password' - }, 401) + url = "https://{0}{1}?{2}={3}".format( + API_HOST, "/v1/userregistration/authenticate", "country", "language" + ) + payload = {"Password": "password", "Email": "email"} + if ( + args[0] == url + and kwargs["data"] == payload + and kwargs["headers"] == {"User-Agent": DYSON_API_USER_AGENT} + ): + return MockResponse( + {"Account": "account", "Password": "password"}, + 401) else: raise Exception("Unknown call") + def _mock_gets(*args, **kwargs): if "provisioningservice" in args[0]: return _mocked_list_devices(*args, **kwargs) else: return _mocked_status_get(*args, **kwargs) + def _mocked_status_get(*args, **kwargs): - url = 'https://{0}{1}'.format(API_HOST, - '/v1/userregistration/userstatus') + url = "https://{0}{1}".format(API_HOST, "/v1/userregistration/userstatus") params = {"country": "language", "email": "email"} - if args[0] == url and kwargs['params'] == params: - return MockResponse({ - 'accountStatus': 'ACTIVE' - }) + if args[0] == url and kwargs["params"] == params: + return MockResponse({"accountStatus": "ACTIVE"}) else: raise Exception("Unknown call") + def _mocked_status_get_cn(*args, **kwargs): - url = 'https://{0}{1}'.format(API_CN_HOST, - '/v1/userregistration/userstatus') + url = "https://{0}{1}".format(API_CN_HOST, + "/v1/userregistration/userstatus") params = {"country": "CN", "email": "email"} - if args[0] == url and kwargs['params'] == params: - return MockResponse({ - 'accountStatus': 'ACTIVE' - }) + if args[0] == url and kwargs["params"] == params: + return MockResponse( + {"accountStatus": "ACTIVE"} + ) else: raise Exception("Unknown call") + def _mocked_status_get_failed(*args, **kwargs): - url = 'https://{0}{1}'.format(API_HOST, - '/v1/userregistration/userstatus') + url = "https://{0}{1}".format(API_HOST, "/v1/userregistration/userstatus") params = {"country": "language", "email": "email"} - if args[0] == url and kwargs['params'] == params: - return MockResponse({ - 'accountStatus': 'INACTIVE' - }) + if args[0] == url and kwargs["params"] == params: + return MockResponse({"accountStatus": "INACTIVE"}) else: raise Exception("Unknown call") + def _mocked_login_post(*args, **kwargs): - url = 'https://{0}{1}?{2}={3}'.format(API_HOST, - '/v1/userregistration/authenticate', - 'country', - 'language') - payload = {'Password': 'password', 'Email': 'email'} - if args[0] == url and kwargs['json'] == payload and \ - kwargs['headers'] == {'User-Agent': DYSON_API_USER_AGENT}: - return MockResponse({ - 'Account': 'account', - 'Password': 'password' - }) + url = "https://{0}{1}?{2}={3}".format( + API_HOST, "/v1/userregistration/authenticate", "country", "language" + ) + payload = {"Password": "password", "Email": "email"} + if ( + args[0] == url + and kwargs["json"] == payload + and kwargs["headers"] == {"User-Agent": DYSON_API_USER_AGENT} + ): + return MockResponse({"Account": "account", "Password": "password"}) else: raise Exception("Unknown call") def _mocked_login_post_cn(*args, **kwargs): - url = 'https://{0}{1}?{2}={3}'.format(API_CN_HOST, - '/v1/userregistration/authenticate', - 'country', - 'CN') - payload = {'Password': 'password', 'Email': 'email'} - if args[0] == url and kwargs['json'] == payload and \ - kwargs['headers'] == {'User-Agent': DYSON_API_USER_AGENT}: - return MockResponse({ - 'Account': 'account', - 'Password': 'password' - }) + url = "https://{0}{1}?{2}={3}".format( + API_CN_HOST, "/v1/userregistration/authenticate", "country", "CN" + ) + payload = {"Password": "password", "Email": "email"} + if ( + args[0] == url + and kwargs["json"] == payload + and kwargs["headers"] == {"User-Agent": DYSON_API_USER_AGENT} + ): + return MockResponse({"Account": "account", "Password": "password"}) else: raise Exception("Unknown call") def _mocked_list_devices(*args, **kwargs): - url = 'https://{0}{1}'.format(API_HOST, - '/v1/provisioningservice/manifest') - url_v2 = 'https://{0}{1}'.format(API_HOST, - '/v2/provisioningservice/manifest') + url = "https://{0}{1}".format(API_HOST, "/v1/provisioningservice/manifest") + url_v2 = "https://{0}{1}".format(API_HOST, + "/v2/provisioningservice/manifest") if args[0] == url: return MockResponse( @@ -123,11 +125,11 @@ def _mocked_list_devices(*args, **kwargs): "ScaleUnit": "SU01", "Version": "21.03.08", "LocalCredentials": "1/aJ5t52WvAfn+z+fjDuef86kQDQPefbQ6/" - "70ZGysII1Ke1i0ZHakFH84DZuxsSQ4KTT2v" - "bCm7uYeTORULKLKQ==", + "70ZGysII1Ke1i0ZHakFH84DZuxsSQ4KTT2v" + "bCm7uYeTORULKLKQ==", "AutoUpdate": True, "NewVersionAvailable": False, - "ProductType": "475" + "ProductType": "475", }, { "Active": False, @@ -136,11 +138,11 @@ def _mocked_list_devices(*args, **kwargs): "ScaleUnit": "SU02", "Version": "21.02.04", "LocalCredentials": "1/aJ5t52WvAfn+z+fjDuebkH6aWl2H5Q1vCq" - "CQSjJfENzMefozxWaDoW1yDluPsi09SGT5nW" - "MxqxtrfkxnUtRQ==", + "CQSjJfENzMefozxWaDoW1yDluPsi09SGT5nW" + "MxqxtrfkxnUtRQ==", "AutoUpdate": False, "NewVersionAvailable": True, - "ProductType": "455" + "ProductType": "455", }, { "Active": True, @@ -149,12 +151,12 @@ def _mocked_list_devices(*args, **kwargs): "ScaleUnit": "SU01", "Version": "21.03.08", "LocalCredentials": "1/aJ5t52WvAfn+z+fjDuef86kQDQPefbQ6/" - "70ZGysII1Ke1i0ZHakFH84DZuxsSQ4KTT2v" - "bCm7uYeTORULKLKQ==", + "70ZGysII1Ke1i0ZHakFH84DZuxsSQ4KTT2v" + "bCm7uYeTORULKLKQ==", "AutoUpdate": True, "NewVersionAvailable": False, - "ProductType": "N223" - } + "ProductType": "N223", + }, ] ) @@ -167,33 +169,33 @@ def _mocked_list_devices(*args, **kwargs): "Version": "02.05.001.0006", "AutoUpdate": True, "LocalCredentials": "1/aJ5t52WvAfn+z+fjDuef86kQDQPefbQ6/" - "70ZGysII1Ke1i0ZHakFH84DZuxsSQ4KTT2v" - "bCm7uYeTORULKLKQ==", + "70ZGysII1Ke1i0ZHakFH84DZuxsSQ4KTT2v" + "bCm7uYeTORULKLKQ==", "NewVersionAvailable": False, - "ProductType": "438" + "ProductType": "438", }, { "Serial": "DB1-US-DBD1231D", "Name": "device-3", "Version": "02.05.001.0006", "LocalCredentials": "1/aJ5t52WvAfn+z+fjDuebkH6aWl2H5Q1vCq" - "CQSjJfENzMefozxWaDoW1yDluPsi09SGT5nW" - "MxqxtrfkxnUtRQ==", + "CQSjJfENzMefozxWaDoW1yDluPsi09SGT5nW" + "MxqxtrfkxnUtRQ==", "AutoUpdate": True, "NewVersionAvailable": False, - "ProductType": "520" + "ProductType": "520", }, { "Serial": "CB1-US-DBD1231C", "Name": "device-4", "Version": "02.05.001.0006", "LocalCredentials": "1/aJ5t52WvAfn+z+fjDuebkH6aWl2H5Q1vCq" - "CQSjJfENzMefozxWaDoW1yDluPsi09SGT5nW" - "MxqxtrfkxnUtRQ==", + "CQSjJfENzMefozxWaDoW1yDluPsi09SGT5nW" + "MxqxtrfkxnUtRQ==", "AutoUpdate": True, "NewVersionAvailable": False, - "ProductType": "527" - } + "ProductType": "527", + }, ] ) @@ -205,8 +207,8 @@ def setUp(self): def tearDown(self): pass - @mock.patch('requests.get', side_effect=_mock_gets) - @mock.patch('requests.post', side_effect=_mocked_login_post) + @mock.patch("requests.get", side_effect=_mock_gets) + @mock.patch("requests.post", side_effect=_mocked_login_post) def test_connect_account(self, mocked_login, mocked_status): dyson_account = DysonAccount("email", "password", "language") logged = dyson_account.login() @@ -214,8 +216,8 @@ def test_connect_account(self, mocked_login, mocked_status): self.assertEqual(mocked_login.call_count, 1) self.assertTrue(logged) - @mock.patch('requests.get', side_effect=_mocked_status_get_cn) - @mock.patch('requests.post', side_effect=_mocked_login_post_cn) + @mock.patch("requests.get", side_effect=_mocked_status_get_cn) + @mock.patch("requests.post", side_effect=_mocked_login_post_cn) def test_connect_account_cn(self, mocked_login, mocked_status): dyson_account = DysonAccount("email", "password", "CN") logged = dyson_account.login() @@ -223,8 +225,8 @@ def test_connect_account_cn(self, mocked_login, mocked_status): self.assertEqual(mocked_login.call_count, 1) self.assertTrue(logged) - @mock.patch('requests.get', side_effect=_mocked_status_get_failed) - @mock.patch('requests.post', side_effect=_mocked_login_post_failed) + @mock.patch("requests.get", side_effect=_mocked_status_get_failed) + @mock.patch("requests.post", side_effect=_mocked_login_post_failed) def test_connect_account_failed(self, mocked_login, mocked_status): dyson_account = DysonAccount("email", "password", "language") logged = dyson_account.login() @@ -236,8 +238,8 @@ def test_not_logged(self): dyson_account = DysonAccount("email", "password", "language") self.assertRaises(DysonNotLoggedException, dyson_account.devices) - @mock.patch('requests.get', side_effect=_mock_gets) - @mock.patch('requests.post', side_effect=_mocked_login_post) + @mock.patch("requests.get", side_effect=_mock_gets) + @mock.patch("requests.post", side_effect=_mocked_login_post) def test_list_devices(self, mocked_login, mocked_list_devices): dyson_account = DysonAccount("email", "password", "language") dyson_account.login() @@ -255,8 +257,8 @@ def test_list_devices(self, mocked_login, mocked_list_devices): self.assertTrue(devices[0].active) self.assertTrue(devices[0].auto_update) self.assertFalse(devices[0].new_version_available) - self.assertEqual(devices[0].serial, 'device-id-1') - self.assertEqual(devices[0].name, 'device-1') - self.assertEqual(devices[0].version, '21.03.08') - self.assertEqual(devices[0].product_type, '475') - self.assertEqual(devices[0].credentials, 'password1') + self.assertEqual(devices[0].serial, "device-id-1") + self.assertEqual(devices[0].name, "device-1") + self.assertEqual(devices[0].version, "21.03.08") + self.assertEqual(devices[0].product_type, "475") + self.assertEqual(devices[0].credentials, "password1")