python-tado 0.18.1__tar.gz → 0.18.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {python_tado-0.18.1/python_tado.egg-info → python_tado-0.18.3}/PKG-INFO +3 -2
  2. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/const.py +6 -0
  3. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/exceptions.py +0 -4
  4. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/http.py +20 -11
  5. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/interface/api/hops_tado.py +12 -12
  6. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/interface/api/my_tado.py +1 -1
  7. {python_tado-0.18.1 → python_tado-0.18.3}/pyproject.toml +3 -2
  8. {python_tado-0.18.1 → python_tado-0.18.3/python_tado.egg-info}/PKG-INFO +3 -2
  9. {python_tado-0.18.1 → python_tado-0.18.3}/python_tado.egg-info/SOURCES.txt +2 -1
  10. {python_tado-0.18.1 → python_tado-0.18.3}/python_tado.egg-info/requires.txt +1 -0
  11. python_tado-0.18.3/tests/test_http.py +180 -0
  12. {python_tado-0.18.1 → python_tado-0.18.3}/tests/test_my_tado.py +1 -1
  13. {python_tado-0.18.1 → python_tado-0.18.3}/tests/test_my_zone.py +1 -1
  14. {python_tado-0.18.1 → python_tado-0.18.3}/tests/test_tado_interface.py +19 -7
  15. {python_tado-0.18.1 → python_tado-0.18.3}/AUTHORS +0 -0
  16. {python_tado-0.18.1 → python_tado-0.18.3}/LICENSE +0 -0
  17. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/__init__.py +0 -0
  18. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/__main__.py +0 -0
  19. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/interface/__init__.py +0 -0
  20. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/interface/api/__init__.py +0 -0
  21. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/interface/interface.py +0 -0
  22. /python_tado-0.18.1/PyTado/logging.py → /python_tado-0.18.3/PyTado/logger.py +0 -0
  23. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/zone/__init__.py +0 -0
  24. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/zone/hops_zone.py +0 -0
  25. {python_tado-0.18.1 → python_tado-0.18.3}/PyTado/zone/my_zone.py +0 -0
  26. {python_tado-0.18.1 → python_tado-0.18.3}/README.md +0 -0
  27. {python_tado-0.18.1 → python_tado-0.18.3}/python_tado.egg-info/dependency_links.txt +0 -0
  28. {python_tado-0.18.1 → python_tado-0.18.3}/python_tado.egg-info/entry_points.txt +0 -0
  29. {python_tado-0.18.1 → python_tado-0.18.3}/python_tado.egg-info/not-zip-safe +0 -0
  30. {python_tado-0.18.1 → python_tado-0.18.3}/python_tado.egg-info/top_level.txt +0 -0
  31. {python_tado-0.18.1 → python_tado-0.18.3}/setup.cfg +0 -0
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-tado
3
- Version: 0.18.1
3
+ Version: 0.18.3
4
4
  Summary: PyTado from chrism0dwk, modfied by w.malgadey, diplix, michaelarnauts, LenhartStephan, splifter, syssi, andersonshatch, Yippy, p0thi, Coffee2CodeNL, chiefdragon, FilBr, nikilase, albertomontesg, Moritz-Schmidt, palazzem
5
- Author-email: Chris Jewell <chrism0dwk@gmail.com>, "w.malgadey" <w.malgadey@gmail.com>
5
+ Author-email: Chris Jewell <chrism0dwk@gmail.com>, "w.malgadey" <w.malgadey@gmail.com>, FilBr <filippo.barba@protonmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
7
7
  Version 3, 29 June 2007
8
8
 
@@ -699,6 +699,7 @@ Requires-Dist: black>=24.3; extra == "dev"
699
699
  Requires-Dist: pytype; extra == "dev"
700
700
  Requires-Dist: pylint; extra == "dev"
701
701
  Requires-Dist: types-requests; extra == "dev"
702
+ Requires-Dist: responses; extra == "dev"
702
703
  Requires-Dist: coverage; extra == "dev"
703
704
  Requires-Dist: pytest; extra == "dev"
704
705
  Requires-Dist: pytest-cov; extra == "dev"
@@ -1,5 +1,11 @@
1
1
  """Constant values for the Tado component."""
2
2
 
3
+ # Api credentials
4
+ CLIENT_ID = "tado-web-app"
5
+ CLIENT_SECRET = (
6
+ "wZaRN7rpjn3FoNyF5IFuxg9uMzYJcvOoQ8QWiIqS3hfk6gLhVlG57j5YNoZL2Rtc"
7
+ )
8
+
3
9
  # Types
4
10
  TYPE_AIR_CONDITIONING = "AIR_CONDITIONING"
5
11
  TYPE_HEATING = "HEATING"
@@ -9,10 +9,6 @@ class TadoNotSupportedException(TadoException):
9
9
  """Exception to indicate a requested action is not supported by Tado."""
10
10
 
11
11
 
12
- class TadoXNotSupportedException(TadoException):
13
- """Exception to indicate a requested action is not supported by the Tado X API."""
14
-
15
-
16
12
  class TadoCredentialsException(TadoException):
17
13
  """Exception to indicate something with credentials"""
18
14
 
@@ -11,8 +11,9 @@ from typing import Any
11
11
 
12
12
  import requests
13
13
 
14
- from PyTado.exceptions import TadoWrongCredentialsException
15
- from PyTado.logging import Logger
14
+ from PyTado.const import CLIENT_ID, CLIENT_SECRET
15
+ from PyTado.exceptions import TadoException, TadoWrongCredentialsException
16
+ from PyTado.logger import Logger
16
17
 
17
18
  _LOGGER = Logger(__name__)
18
19
 
@@ -141,7 +142,8 @@ class Http:
141
142
  self._headers = {"Referer": "https://app.tado.com/"}
142
143
  self._username = username
143
144
  self._password = password
144
- self._id, self._x_api, self._token_refresh = self._login()
145
+ self._id, self._token_refresh = self._login()
146
+ self._x_api = self._check_x_line_generation()
145
147
 
146
148
  def _log_response(self, response: requests.Response, *args, **kwargs):
147
149
  og_request_method = response.request.method
@@ -250,10 +252,8 @@ class Http:
250
252
 
251
253
  url = "https://auth.tado.com/oauth/token"
252
254
  data = {
253
- "client_id": "tado-web-app",
254
- "client_secret": (
255
- "wZaRN7rpjn3FoNyF5IFuxg9uMzYJcvOoQ8QWiIqS3hfk6gLhVlG57j5YNoZL2Rtc"
256
- ),
255
+ "client_id": CLIENT_ID,
256
+ "client_secret": CLIENT_SECRET,
257
257
  "grant_type": "refresh_token",
258
258
  "scope": "home.user",
259
259
  "refresh_token": self._token_refresh,
@@ -274,9 +274,15 @@ class Http:
274
274
  },
275
275
  )
276
276
 
277
- self._set_oauth_header(response.json())
277
+ if response.status_code == 200:
278
+ self._set_oauth_header(response.json())
279
+ return
278
280
 
279
- def _login(self) -> tuple[int, bool, str] | None:
281
+ raise TadoException(
282
+ f"Unknown error while refreshing token with status code {response.status_code}"
283
+ )
284
+
285
+ def _login(self) -> tuple[int, str] | None:
280
286
 
281
287
  headers = self._headers
282
288
  headers["Content-Type"] = "application/json"
@@ -311,9 +317,12 @@ class Http:
311
317
  if response.status_code == 200:
312
318
  refresh_token = self._set_oauth_header(response.json())
313
319
  id_ = self._get_id()
314
- x_api_ = self._check_x_line_generation()
315
320
 
316
- return id_, x_api_, refresh_token
321
+ return id_, refresh_token
322
+
323
+ raise TadoException(
324
+ f"Login failed for unknown reason with status code {response.status_code}"
325
+ )
317
326
 
318
327
  def _get_id(self) -> int:
319
328
  request = TadoRequest()
@@ -8,7 +8,7 @@ from typing import Any
8
8
 
9
9
  from .my_tado import Tado, Timetable
10
10
 
11
- from ...logging import Logger
11
+ from ...logger import Logger
12
12
  from ...exceptions import TadoNotSupportedException
13
13
  from ...http import (
14
14
  Action,
@@ -56,7 +56,7 @@ class TadoX(Tado):
56
56
  # set to None until explicitly set
57
57
  self._auto_geofencing_supported = None
58
58
 
59
- def _create_request(self) -> TadoRequest:
59
+ def _create_x_request(self) -> TadoRequest:
60
60
  return TadoXRequest()
61
61
 
62
62
  def get_devices(self):
@@ -64,7 +64,7 @@ class TadoX(Tado):
64
64
  Gets device information.
65
65
  """
66
66
 
67
- request = self._create_request()
67
+ request = self._create_x_request()
68
68
  request.command = "roomsAndDevices"
69
69
 
70
70
  rooms: list[dict[str, Any]] = self._http.request(request)["rooms"]
@@ -77,7 +77,7 @@ class TadoX(Tado):
77
77
  Gets zones information.
78
78
  """
79
79
 
80
- request = self._create_request()
80
+ request = self._create_x_request()
81
81
  request.command = "roomsAndDevices"
82
82
 
83
83
  return self._http.request(request)["rooms"]
@@ -94,7 +94,7 @@ class TadoX(Tado):
94
94
  Gets current states of all zones.
95
95
  """
96
96
 
97
- request = self._create_request()
97
+ request = self._create_x_request()
98
98
  request.command = "rooms"
99
99
 
100
100
  return self._http.request(request)
@@ -104,7 +104,7 @@ class TadoX(Tado):
104
104
  Gets current state of Zone.
105
105
  """
106
106
 
107
- request = self._create_request()
107
+ request = self._create_x_request()
108
108
  request.command = f"rooms/{zone:d}"
109
109
  data = self._http.request(request)
110
110
 
@@ -150,7 +150,7 @@ class TadoX(Tado):
150
150
  Zone has 3 different schedules, one for each timetable (see setTimetable)
151
151
  """
152
152
 
153
- request = self._create_request()
153
+ request = self._create_x_request()
154
154
  request.command = f"rooms/{zone:d}/schedule"
155
155
 
156
156
  return self._http.request(request)
@@ -160,7 +160,7 @@ class TadoX(Tado):
160
160
  Set the schedule for a zone, day is required
161
161
  """
162
162
 
163
- request = self._create_request()
163
+ request = self._create_x_request()
164
164
  request.command = f"rooms/{zone:d}/schedule"
165
165
  request.action = Action.SET
166
166
  request.payload = data
@@ -173,7 +173,7 @@ class TadoX(Tado):
173
173
  Delete current overlay
174
174
  """
175
175
 
176
- request = self._create_request()
176
+ request = self._create_x_request()
177
177
  request.command = f"rooms/{zone:d}/resumeSchedule"
178
178
  request.action = Action.SET
179
179
 
@@ -213,7 +213,7 @@ class TadoX(Tado):
213
213
  if duration is not None:
214
214
  post_data["termination"]["durationInSeconds"] = duration
215
215
 
216
- request = self._create_request()
216
+ request = self._create_x_request()
217
217
  request.command = f"rooms/{zone:d}/manualControl"
218
218
  request.action = Action.SET
219
219
  request.payload = post_data
@@ -236,7 +236,7 @@ class TadoX(Tado):
236
236
 
237
237
  data = self.get_state(zone)
238
238
 
239
- if "activated" in data["openWindow"]:
239
+ if data["openWindow"] and "activated" in data["openWindow"]:
240
240
  return {"openWindowDetected": True}
241
241
  else:
242
242
  return {"openWindowDetected": False}
@@ -275,7 +275,7 @@ class TadoX(Tado):
275
275
  Set the Temperature offset on the device.
276
276
  """
277
277
 
278
- request = self._create_request()
278
+ request = self._create_x_request()
279
279
  request.command = f"roomsAndDevices/devices/{device_id}"
280
280
  request.action = Action.CHANGE
281
281
  request.payload = {"temperatureOffset": offset}
@@ -8,7 +8,7 @@ import logging
8
8
 
9
9
  from typing import Any
10
10
 
11
- from ...logging import Logger
11
+ from ...logger import Logger
12
12
  from ...exceptions import TadoNotSupportedException
13
13
  from ...http import (
14
14
  Action,
@@ -4,11 +4,12 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-tado"
7
- version = "0.18.1"
7
+ version = "0.18.3"
8
8
  description = "PyTado from chrism0dwk, modfied by w.malgadey, diplix, michaelarnauts, LenhartStephan, splifter, syssi, andersonshatch, Yippy, p0thi, Coffee2CodeNL, chiefdragon, FilBr, nikilase, albertomontesg, Moritz-Schmidt, palazzem"
9
9
  authors = [
10
10
  { name = "Chris Jewell", email = "chrism0dwk@gmail.com" },
11
11
  { name = "w.malgadey", email = "w.malgadey@gmail.com" },
12
+ { name = "FilBr", email = "filippo.barba@protonmail.com" },
12
13
  ]
13
14
  dependencies = ["requests"]
14
15
  requires-python = ">=3.11"
@@ -30,7 +31,7 @@ classifiers = [
30
31
  GitHub = "https://github.com/wmalgadey/PyTado"
31
32
 
32
33
  [project.optional-dependencies]
33
- dev = ["black>=24.3", "pytype", "pylint", "types-requests", "coverage", "pytest", "pytest-cov"]
34
+ dev = ["black>=24.3", "pytype", "pylint", "types-requests", "responses", "coverage", "pytest", "pytest-cov"]
34
35
 
35
36
  [project.scripts]
36
37
  pytado = "pytado.__main__:main"
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-tado
3
- Version: 0.18.1
3
+ Version: 0.18.3
4
4
  Summary: PyTado from chrism0dwk, modfied by w.malgadey, diplix, michaelarnauts, LenhartStephan, splifter, syssi, andersonshatch, Yippy, p0thi, Coffee2CodeNL, chiefdragon, FilBr, nikilase, albertomontesg, Moritz-Schmidt, palazzem
5
- Author-email: Chris Jewell <chrism0dwk@gmail.com>, "w.malgadey" <w.malgadey@gmail.com>
5
+ Author-email: Chris Jewell <chrism0dwk@gmail.com>, "w.malgadey" <w.malgadey@gmail.com>, FilBr <filippo.barba@protonmail.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
7
7
  Version 3, 29 June 2007
8
8
 
@@ -699,6 +699,7 @@ Requires-Dist: black>=24.3; extra == "dev"
699
699
  Requires-Dist: pytype; extra == "dev"
700
700
  Requires-Dist: pylint; extra == "dev"
701
701
  Requires-Dist: types-requests; extra == "dev"
702
+ Requires-Dist: responses; extra == "dev"
702
703
  Requires-Dist: coverage; extra == "dev"
703
704
  Requires-Dist: pytest; extra == "dev"
704
705
  Requires-Dist: pytest-cov; extra == "dev"
@@ -7,7 +7,7 @@ PyTado/__main__.py
7
7
  PyTado/const.py
8
8
  PyTado/exceptions.py
9
9
  PyTado/http.py
10
- PyTado/logging.py
10
+ PyTado/logger.py
11
11
  PyTado/interface/__init__.py
12
12
  PyTado/interface/interface.py
13
13
  PyTado/interface/api/__init__.py
@@ -23,6 +23,7 @@ python_tado.egg-info/entry_points.txt
23
23
  python_tado.egg-info/not-zip-safe
24
24
  python_tado.egg-info/requires.txt
25
25
  python_tado.egg-info/top_level.txt
26
+ tests/test_http.py
26
27
  tests/test_my_tado.py
27
28
  tests/test_my_zone.py
28
29
  tests/test_tado_interface.py
@@ -5,6 +5,7 @@ black>=24.3
5
5
  pytype
6
6
  pylint
7
7
  types-requests
8
+ responses
8
9
  coverage
9
10
  pytest
10
11
  pytest-cov
@@ -0,0 +1,180 @@
1
+ """Test the Http class."""
2
+
3
+ from datetime import datetime, timedelta
4
+ import json
5
+ import responses
6
+ import unittest
7
+
8
+ from PyTado.const import CLIENT_ID, CLIENT_SECRET
9
+ from PyTado.exceptions import TadoException, TadoWrongCredentialsException
10
+
11
+ from . import common
12
+
13
+ from PyTado.http import Http
14
+
15
+
16
+ class TestHttp(unittest.TestCase):
17
+ """Testcases for Http class."""
18
+
19
+ def setUp(self):
20
+ super().setUp()
21
+
22
+ # Mock the login response
23
+ responses.add(
24
+ responses.POST,
25
+ "https://auth.tado.com/oauth/token",
26
+ json={
27
+ "access_token": "value",
28
+ "expires_in": 1234,
29
+ "refresh_token": "another_value",
30
+ },
31
+ status=200,
32
+ )
33
+
34
+ responses.add(
35
+ responses.GET,
36
+ "https://my.tado.com/api/v2/homes/1234/",
37
+ json={"homes": [{"id": 1234}]},
38
+ status=200,
39
+ )
40
+
41
+ # Mock the get me response
42
+ responses.add(
43
+ responses.GET,
44
+ "https://my.tado.com/api/v2/me",
45
+ json={"homes": [{"id": 1234}]},
46
+ status=200,
47
+ )
48
+
49
+ @responses.activate
50
+ def test_login_successful(self):
51
+
52
+ instance = Http(
53
+ username="test_user",
54
+ password="test_pass",
55
+ debug=True,
56
+ )
57
+
58
+ # Verify that the login was successful
59
+ self.assertEqual(instance._id, 1234)
60
+ self.assertEqual(instance.is_x_line, False)
61
+
62
+ @responses.activate
63
+ def test_login_failed(self):
64
+
65
+ responses.replace(
66
+ responses.POST,
67
+ "https://auth.tado.com/oauth/token",
68
+ json={"error": "invalid_grant"},
69
+ status=400,
70
+ )
71
+
72
+ with self.assertRaises(
73
+ expected_exception=TadoWrongCredentialsException,
74
+ msg="Your username or password is invalid",
75
+ ):
76
+ Http(
77
+ username="test_user",
78
+ password="test_pass",
79
+ debug=True,
80
+ )
81
+
82
+ responses.replace(
83
+ responses.POST,
84
+ "https://auth.tado.com/oauth/token",
85
+ json={"error": "server failed"},
86
+ status=503,
87
+ )
88
+
89
+ with self.assertRaises(
90
+ expected_exception=TadoException,
91
+ msg="Login failed for unknown reason with status code 503",
92
+ ):
93
+ Http(
94
+ username="test_user",
95
+ password="test_pass",
96
+ debug=True,
97
+ )
98
+
99
+ @responses.activate
100
+ def test_line_x(self):
101
+
102
+ responses.replace(
103
+ responses.GET,
104
+ "https://my.tado.com/api/v2/homes/1234/",
105
+ json=json.loads(common.load_fixture("tadox/homes_response.json")),
106
+ status=200,
107
+ )
108
+
109
+ instance = Http(
110
+ username="test_user",
111
+ password="test_pass",
112
+ debug=True,
113
+ )
114
+
115
+ # Verify that the login was successful
116
+ self.assertEqual(instance._id, 1234)
117
+ self.assertEqual(instance.is_x_line, True)
118
+
119
+ @responses.activate
120
+ def test_refresh_token_success(self):
121
+ instance = Http(
122
+ username="test_user",
123
+ password="test_pass",
124
+ debug=True,
125
+ )
126
+
127
+ expected_params = {
128
+ "client_id": CLIENT_ID,
129
+ "client_secret": CLIENT_SECRET,
130
+ "grant_type": "refresh_token",
131
+ "scope": "home.user",
132
+ "refresh_token": "another_value",
133
+ }
134
+ # Mock the refresh token response
135
+ refresh_token = responses.replace(
136
+ responses.POST,
137
+ "https://auth.tado.com/oauth/token",
138
+ match=[
139
+ responses.matchers.query_param_matcher(expected_params),
140
+ ],
141
+ json={
142
+ "access_token": "new_value",
143
+ "expires_in": 1234,
144
+ "refresh_token": "new_refresh_value",
145
+ },
146
+ status=200,
147
+ )
148
+
149
+ # Force token refresh
150
+ instance._refresh_at = datetime.now() - timedelta(seconds=1)
151
+ instance._refresh_token()
152
+
153
+ assert refresh_token.call_count == 1
154
+
155
+ # Verify that the token was refreshed
156
+ self.assertEqual(instance._headers["Authorization"], "Bearer new_value")
157
+
158
+ @responses.activate
159
+ def test_refresh_token_failure(self):
160
+ instance = Http(
161
+ username="test_user",
162
+ password="test_pass",
163
+ debug=True,
164
+ )
165
+
166
+ # Mock the refresh token response with failure
167
+ refresh_token = responses.replace(
168
+ responses.POST,
169
+ "https://auth.tado.com/oauth/token",
170
+ json={"error": "invalid_grant"},
171
+ status=400,
172
+ )
173
+
174
+ # Force token refresh
175
+ instance._refresh_at = datetime.now() - timedelta(seconds=1)
176
+
177
+ with self.assertRaises(TadoException):
178
+ instance._refresh_token()
179
+
180
+ assert refresh_token.call_count == 1
@@ -16,7 +16,7 @@ class TadoTestCase(unittest.TestCase):
16
16
  def setUp(self) -> None:
17
17
  super().setUp()
18
18
  login_patch = mock.patch(
19
- "PyTado.http.Http._login", return_value=(1, False, "foo")
19
+ "PyTado.http.Http._login", return_value=(1, "foo")
20
20
  )
21
21
  get_me_patch = mock.patch("PyTado.interface.api.Tado.get_me")
22
22
  login_patch.start()
@@ -16,7 +16,7 @@ class TadoZoneTestCase(unittest.TestCase):
16
16
  def setUp(self) -> None:
17
17
  super().setUp()
18
18
  login_patch = mock.patch(
19
- "PyTado.http.Http._login", return_value=(1, False, "foo")
19
+ "PyTado.http.Http._login", return_value=(1, "foo")
20
20
  )
21
21
  get_me_patch = mock.patch("PyTado.interface.api.Tado.get_me")
22
22
  login_patch.start()
@@ -14,10 +14,14 @@ class TestTadoInterface(unittest.TestCase):
14
14
 
15
15
  def test_interface_with_tado_api(self):
16
16
  login_patch = mock.patch(
17
- "PyTado.http.Http._login", return_value=(1, False, "foo")
17
+ "PyTado.http.Http._login", return_value=(1, "foo")
18
18
  )
19
19
  login_mock = login_patch.start()
20
- self.addCleanup(login_patch.stop)
20
+ check_x_patch = mock.patch(
21
+ "PyTado.http.Http._check_x_line_generation", return_value=False
22
+ )
23
+ check_x_patch.start()
24
+ self.addCleanup(check_x_patch.stop)
21
25
 
22
26
  with mock.patch("PyTado.interface.api.my_tado.Tado.get_me") as mock_it:
23
27
  tado_interface = Tado("my@username.com", "mypassword")
@@ -38,10 +42,14 @@ class TestTadoInterface(unittest.TestCase):
38
42
 
39
43
  def test_interface_with_tadox_api(self):
40
44
  login_patch = mock.patch(
41
- "PyTado.http.Http._login", return_value=(1, True, "foo")
45
+ "PyTado.http.Http._login", return_value=(1, "foo")
42
46
  )
43
47
  login_mock = login_patch.start()
44
- self.addCleanup(login_patch.stop)
48
+ check_x_patch = mock.patch(
49
+ "PyTado.http.Http._check_x_line_generation", return_value=True
50
+ )
51
+ check_x_patch.start()
52
+ self.addCleanup(check_x_patch.stop)
45
53
 
46
54
  with mock.patch(
47
55
  "PyTado.interface.api.hops_tado.TadoX.get_me"
@@ -56,10 +64,14 @@ class TestTadoInterface(unittest.TestCase):
56
64
 
57
65
  def test_error_handling_on_api_calls(self):
58
66
  login_patch = mock.patch(
59
- "PyTado.http.Http._login", return_value=(1, False, "foo")
67
+ "PyTado.http.Http._login", return_value=(1, "foo")
68
+ )
69
+ login_mock = login_patch.start()
70
+ check_x_patch = mock.patch(
71
+ "PyTado.http.Http._check_x_line_generation", return_value=False
60
72
  )
61
- login_patch.start()
62
- self.addCleanup(login_patch.stop)
73
+ check_x_patch.start()
74
+ self.addCleanup(check_x_patch.stop)
63
75
 
64
76
  with mock.patch("PyTado.interface.api.my_tado.Tado.get_me") as mock_it:
65
77
  mock_it.side_effect = Exception("API Error")
File without changes
File without changes
File without changes
File without changes