From 7a4dd61e55d9b4dad5ea8815ac6753a9a9aed065 Mon Sep 17 00:00:00 2001 From: Robbert Verbruggen Date: Tue, 6 Oct 2020 22:18:36 +0200 Subject: [PATCH 1/6] JSON Dump the body on requests If body is not None --- rachiopy/rachioobject.py | 4 ++ tests/test_device.py | 33 ++++++++-------- tests/test_notification.py | 39 +++++++++++-------- tests/test_schedulerule.py | 16 ++++---- tests/test_zone.py | 79 +++++++++++++++++++++++++------------- 5 files changed, 104 insertions(+), 67 deletions(-) diff --git a/rachiopy/rachioobject.py b/rachiopy/rachioobject.py index b38cc70..bb3bc22 100644 --- a/rachiopy/rachioobject.py +++ b/rachiopy/rachioobject.py @@ -1,4 +1,5 @@ """RachioObject module containing a helper class for all API calls.""" +import json from requests import Session @@ -33,6 +34,9 @@ def _request(self, path: str, method: str, body=None): object if it contains JSON). :rtype: tuple """ + if body is not None: + body = json.dumps(body) + url = f"{_API_URL}/{path}" response = self._http_session.request( method, url, headers=self._headers, data=body diff --git a/tests/test_device.py b/tests/test_device.py index 2a46743..53205c9 100644 --- a/tests/test_device.py +++ b/tests/test_device.py @@ -2,6 +2,7 @@ import unittest import uuid +import json from unittest.mock import patch from random import randrange @@ -24,7 +25,7 @@ def test_get(self, mock): """Test if the get method works as expected.""" mock.return_value = RESPONSE200 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) self.device.get(deviceid) @@ -42,7 +43,7 @@ def test_current_schedule(self, mock): """Test if the current schedule method works as expected.""" mock.return_value = RESPONSE200 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) self.device.current_schedule(deviceid) @@ -60,7 +61,7 @@ def test_event(self, mock): """Test if the event method works as expected.""" mock.return_value = RESPONSE200 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) starttime = 1414818000000 endtime = 1415739608103 @@ -84,7 +85,7 @@ def test_forecast(self, mock): """Test if the forecast method works as expected.""" mock.return_value = RESPONSE200 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) self.device.forecast(deviceid) @@ -128,7 +129,7 @@ def test_stop_water(self, mock): """Test if the stop water method works as expected.""" mock.return_value = RESPONSE204 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) self.device.stop_water(deviceid) @@ -139,14 +140,14 @@ def test_stop_water(self, mock): args[1], f"{BASE_API_URL}/device/stop_water", ) self.assertEqual(args[0], "PUT") - self.assertEqual(kwargs["data"], {"id": deviceid}) + self.assertEqual(kwargs["data"], json.dumps({"id": deviceid})) @patch("requests.Session.request") def test_rain_delay(self, mock): """Test if the rain delay method works as expected.""" mock.return_value = RESPONSE204 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) duration = randrange(604800) self.device.rain_delay(deviceid, duration) @@ -159,7 +160,7 @@ def test_rain_delay(self, mock): ) self.assertEqual(args[0], "PUT") self.assertEqual( - kwargs["data"], {"id": deviceid, "duration": duration} + kwargs["data"], json.dumps({"id": deviceid, "duration": duration}) ) # Check that values should be within range. @@ -173,7 +174,7 @@ def test_turn_on(self, mock): """Test if the turn on method works as expected.""" mock.return_value = RESPONSE204 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) self.device.turn_on(deviceid) @@ -184,14 +185,14 @@ def test_turn_on(self, mock): args[1], f"{BASE_API_URL}/device/on", ) self.assertEqual(args[0], "PUT") - self.assertEqual(kwargs["data"], {"id": deviceid}) + self.assertEqual(kwargs["data"], json.dumps({"id": deviceid})) @patch("requests.Session.request") def test_turn_off(self, mock): """Test if the turn off method works as expected.""" mock.return_value = RESPONSE204 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) self.device.turn_off(deviceid) @@ -202,14 +203,14 @@ def test_turn_off(self, mock): args[1], f"{BASE_API_URL}/device/off", ) self.assertEqual(args[0], "PUT") - self.assertEqual(kwargs["data"], {"id": deviceid}) + self.assertEqual(kwargs["data"], json.dumps({"id": deviceid})) @patch("requests.Session.request") def test_pause_zone_run(self, mock): """Test if the pause zone run method works as expected.""" mock.return_value = RESPONSE204 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) duration = randrange(3600) self.device.pause_zone_run(deviceid, duration) @@ -222,7 +223,7 @@ def test_pause_zone_run(self, mock): ) self.assertEqual(args[0], "PUT") self.assertEqual( - kwargs["data"], {"id": deviceid, "duration": duration} + kwargs["data"], json.dumps({"id": deviceid, "duration": duration}) ) # Check that values should be within range. @@ -238,7 +239,7 @@ def test_resume_zone_run(self, mock): """Test if the resume zone run method works as expected.""" mock.return_value = RESPONSE204 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) self.device.resume_zone_run(deviceid) @@ -249,4 +250,4 @@ def test_resume_zone_run(self, mock): args[1], f"{BASE_API_URL}/device/resume_zone_run", ) self.assertEqual(args[0], "PUT") - self.assertEqual(kwargs["data"], {"id": deviceid}) + self.assertEqual(kwargs["data"], json.dumps({"id": deviceid})) diff --git a/tests/test_notification.py b/tests/test_notification.py index 4a1dfb3..d212aca 100644 --- a/tests/test_notification.py +++ b/tests/test_notification.py @@ -3,6 +3,7 @@ import unittest from unittest.mock import patch import uuid +import json from rachiopy import Notification from tests.constants import BASE_API_URL, AUTHTOKEN, RESPONSE200, RESPONSE204 @@ -39,7 +40,7 @@ def test_get_device_webhook(self, mock): """Test if the get device webhook method works as expected.""" mock.return_value = RESPONSE200 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) self.notification.get_device_webhook(deviceid) @@ -57,7 +58,7 @@ def test_add(self, mock): """Test if the add method works as expected.""" mock.return_value = RESPONSE200 - deviceid = uuid.uuid4() + deviceid = str(uuid.uuid4()) externalid = "Test ID" url = "https://www.mydomain.com/another_webhook_new_url" eventtypes = [{"id": "1"}, {"id": "2"}] @@ -71,12 +72,14 @@ def test_add(self, mock): self.assertEqual(args[0], "POST") self.assertEqual( kwargs["data"], - { - "device": {"id": deviceid}, - "externalId": externalid, - "url": url, - "eventTypes": eventtypes, - }, + json.dumps( + { + "device": {"id": deviceid}, + "externalId": externalid, + "url": url, + "eventTypes": eventtypes, + } + ), ) @patch("requests.Session.request") @@ -84,7 +87,7 @@ def test_update(self, mock): """Test if the update method works as expected.""" mock.return_value = RESPONSE200 - hookid = uuid.uuid4() + hookid = str(uuid.uuid4()) externalid = "Test ID" url = "https://www.mydomain.com/another_webhook_new_url" eventtypes = [{"id": "1"}, {"id": "2"}] @@ -98,12 +101,14 @@ def test_update(self, mock): self.assertEqual(args[0], "PUT") self.assertEqual( kwargs["data"], - { - "id": hookid, - "externalId": externalid, - "url": url, - "eventTypes": eventtypes, - }, + json.dumps( + { + "id": hookid, + "externalId": externalid, + "url": url, + "eventTypes": eventtypes, + } + ), ) @patch("requests.Session.request") @@ -111,7 +116,7 @@ def test_delete(self, mock): """Test if the delete method works as expected.""" mock.return_value = RESPONSE204 - hookid = uuid.uuid4() + hookid = str(uuid.uuid4()) self.notification.delete(hookid) @@ -129,7 +134,7 @@ def test_get(self, mock): """Test if the get method works as expected.""" mock.return_value = RESPONSE200 - hookid = uuid.uuid4() + hookid = str(uuid.uuid4()) self.notification.get(hookid) diff --git a/tests/test_schedulerule.py b/tests/test_schedulerule.py index 84a82fa..b56a727 100644 --- a/tests/test_schedulerule.py +++ b/tests/test_schedulerule.py @@ -3,6 +3,7 @@ import unittest from unittest.mock import patch import uuid +import json from rachiopy import Schedulerule from tests.constants import BASE_API_URL, AUTHTOKEN, RESPONSE200, RESPONSE204 @@ -23,7 +24,7 @@ def test_get(self, mock): """Test if the get method works as expected.""" mock.return_value = RESPONSE200 - scheduleruleid = uuid.uuid4() + scheduleruleid = str(uuid.uuid4()) self.schedulerule.get(scheduleruleid) @@ -41,7 +42,7 @@ def test_skip(self, mock): """Test if the skip method works as expected.""" mock.return_value = RESPONSE204 - scheduleruleid = uuid.uuid4() + scheduleruleid = str(uuid.uuid4()) self.schedulerule.skip(scheduleruleid) @@ -50,14 +51,14 @@ def test_skip(self, mock): # Check that the mock function is called with the rights args. self.assertEqual(args[1], f"{BASE_API_URL}/schedulerule/skip") self.assertEqual(args[0], "PUT") - self.assertEqual(kwargs["data"], {"id": scheduleruleid}) + self.assertEqual(kwargs["data"], json.dumps({"id": scheduleruleid})) @patch("requests.Session.request") def test_start(self, mock): """Test if the start method works as expected.""" mock.return_value = RESPONSE204 - scheduleruleid = uuid.uuid4() + scheduleruleid = str(uuid.uuid4()) self.schedulerule.start(scheduleruleid) @@ -66,14 +67,14 @@ def test_start(self, mock): # Check that the mock function is called with the rights args. self.assertEqual(args[1], f"{BASE_API_URL}/schedulerule/start") self.assertEqual(args[0], "PUT") - self.assertEqual(kwargs["data"], {"id": scheduleruleid}) + self.assertEqual(kwargs["data"], json.dumps({"id": scheduleruleid})) @patch("requests.Session.request") def test_seasonal_adjustment(self, mock): """Test if the seasonal adjustment method works as expected.""" mock.return_value = RESPONSE200 - scheduleruleid = uuid.uuid4() + scheduleruleid = str(uuid.uuid4()) adjustment = 0.2 self.schedulerule.seasonal_adjustment(scheduleruleid, adjustment) @@ -86,5 +87,6 @@ def test_seasonal_adjustment(self, mock): ) self.assertEqual(args[0], "PUT") self.assertEqual( - kwargs["data"], {"id": scheduleruleid, "adjustment": adjustment} + kwargs["data"], + json.dumps({"id": scheduleruleid, "adjustment": adjustment}), ) diff --git a/tests/test_zone.py b/tests/test_zone.py index b024db4..e2a3b70 100644 --- a/tests/test_zone.py +++ b/tests/test_zone.py @@ -4,6 +4,7 @@ from unittest.mock import patch import uuid import random +import json from random import randrange from rachiopy import Zone @@ -17,9 +18,9 @@ class TestZoneMethods(unittest.TestCase): def setUp(self): self.zone = Zone(AUTHTOKEN) - zone1id = uuid.uuid4() - zone2id = uuid.uuid4() - zone3id = uuid.uuid4() + zone1id = str(uuid.uuid4()) + zone2id = str(uuid.uuid4()) + zone3id = str(uuid.uuid4()) duration1 = randrange(10800) duration2 = randrange(10800) duration3 = randrange(10800) @@ -54,7 +55,7 @@ def test_start(self, mock): """Test if the start method works as expected.""" mock.return_value = RESPONSE204 - zoneid = uuid.uuid4() + zoneid = str(uuid.uuid4()) duration = randrange(10800) self.zone.start(zoneid, duration) @@ -64,7 +65,9 @@ def test_start(self, mock): # Check that the mock function is called with the rights args. self.assertEqual(args[1], f"{BASE_API_URL}/zone/start") self.assertEqual(args[0], "PUT") - self.assertEqual(kwargs["data"], {"id": zoneid, "duration": duration}) + self.assertEqual( + kwargs["data"], json.dumps({"id": zoneid, "duration": duration}) + ) # Check that values should be within range. self.assertRaises(AssertionError, self.zone.start, zoneid, -1) @@ -87,12 +90,18 @@ def test_start_multiple(self, mock): self.assertEqual(args[0], "PUT") self.assertEqual( kwargs["data"], - { - "zones": [ - {"id": data[0], "duration": data[1], "sortOrder": count} - for (count, data) in enumerate(self.zones, 1) - ] - }, + json.dumps( + { + "zones": [ + { + "id": data[0], + "duration": data[1], + "sortOrder": count, + } + for (count, data) in enumerate(self.zones, 1) + ] + }, + ), ) @patch("requests.Session.request") @@ -100,7 +109,7 @@ def test_set_moisture_percent(self, mock): """Test if the set moisture percent method works as expected.""" mock.return_value = RESPONSE204 - zoneid = uuid.uuid4() + zoneid = str(uuid.uuid4()) percent = round(random.random(), 1) self.zone.set_moisture_percent(zoneid, percent) @@ -110,7 +119,9 @@ def test_set_moisture_percent(self, mock): # Check that the mock function is called with the rights args. self.assertEqual(args[1], f"{BASE_API_URL}/zone/setMoisturePercent") self.assertEqual(args[0], "PUT") - self.assertEqual(kwargs["data"], {"id": zoneid, "percent": percent}) + self.assertEqual( + kwargs["data"], json.dumps({"id": zoneid, "percent": percent}) + ) # Check that values should be within range. self.assertRaises( @@ -125,7 +136,7 @@ def test_set_moisture_level(self, mock): """Test if the set moisture level method works as expected.""" mock.return_value = RESPONSE204 - zoneid = uuid.uuid4() + zoneid = str(uuid.uuid4()) level = round(random.uniform(0.0, 100.0), 2) self.zone.set_moisture_level(zoneid, level) @@ -135,7 +146,9 @@ def test_set_moisture_level(self, mock): # Check that the mock function is called with the rights args. self.assertEqual(args[1], f"{BASE_API_URL}/zone/setMoistureLevel") self.assertEqual(args[0], "PUT") - self.assertEqual(kwargs["data"], {"id": zoneid, "level": level}) + self.assertEqual( + kwargs["data"], json.dumps({"id": zoneid, "level": level}) + ) @patch("requests.Session.request") def test_zoneschedule(self, mock): @@ -154,12 +167,18 @@ def test_zoneschedule(self, mock): self.assertEqual(args[0], "PUT") self.assertEqual( kwargs["data"], - { - "zones": [ - {"id": data[0], "duration": data[1], "sortOrder": count} - for (count, data) in enumerate(self.zones, 1) - ] - }, + json.dumps( + { + "zones": [ + { + "id": data[0], + "duration": data[1], + "sortOrder": count, + } + for (count, data) in enumerate(self.zones, 1) + ] + } + ), ) @patch("requests.Session.request") @@ -178,10 +197,16 @@ def test_zoneschedule_with_statement(self, mock): self.assertEqual(args[0], "PUT") self.assertEqual( kwargs["data"], - { - "zones": [ - {"id": data[0], "duration": data[1], "sortOrder": count} - for (count, data) in enumerate(self.zones, 1) - ] - }, + json.dumps( + { + "zones": [ + { + "id": data[0], + "duration": data[1], + "sortOrder": count, + } + for (count, data) in enumerate(self.zones, 1) + ] + } + ), ) From 5de26f3fca0eb1e678d74e2078447b1524dbf5aa Mon Sep 17 00:00:00 2001 From: Robbert Verbruggen Date: Wed, 7 Oct 2020 08:35:56 +0200 Subject: [PATCH 2/6] Create .pylintrc Exclude R0801: Similar lines in 4 files ==tests.test_notification:100 ==tests.test_zone:166 ==tests.test_zone:196 ==tests.test_zone:89 self.assertEqual(args[0], "PUT") self.assertEqual( kwargs["data"], json.dumps( { (duplicate-code) --- .pylintrc | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .pylintrc diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..77c6b36 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,2 @@ +[MESSAGES CONTROL] +disable=R0801 \ No newline at end of file From a1e3dcaf95eee77db0e4106fa4693e66badbf2e4 Mon Sep 17 00:00:00 2001 From: Robbert Verbruggen Date: Wed, 7 Oct 2020 09:10:51 +0200 Subject: [PATCH 3/6] Update test_zone.py Try to fix a hound issue --- tests/test_zone.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_zone.py b/tests/test_zone.py index e2a3b70..a634fa0 100644 --- a/tests/test_zone.py +++ b/tests/test_zone.py @@ -100,7 +100,7 @@ def test_start_multiple(self, mock): } for (count, data) in enumerate(self.zones, 1) ] - }, + } ), ) From cf3eb72fa27a91f270fd142d01355f6d47a67382 Mon Sep 17 00:00:00 2001 From: Robbert Verbruggen Date: Wed, 7 Oct 2020 09:54:03 +0200 Subject: [PATCH 4/6] Try fixing hound errors --- .flake8 | 2 ++ .hound.yml | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .flake8 diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..1d36346 --- /dev/null +++ b/.flake8 @@ -0,0 +1,2 @@ +[flake8] +max-line-length = 88 \ No newline at end of file diff --git a/.hound.yml b/.hound.yml index 9d60897..bb6710a 100644 --- a/.hound.yml +++ b/.hound.yml @@ -1,4 +1,5 @@ fail_on_violations: true python: - enabled: true \ No newline at end of file + enabled: true + config_file: .flake8 \ No newline at end of file From 61c992b739733d00d2e99d368dd093912adf671a Mon Sep 17 00:00:00 2001 From: Robbert Verbruggen Date: Wed, 7 Oct 2020 09:57:14 +0200 Subject: [PATCH 5/6] Update .flake8 Line lenght fix --- .flake8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.flake8 b/.flake8 index 1d36346..9f31e4c 100644 --- a/.flake8 +++ b/.flake8 @@ -1,2 +1,2 @@ [flake8] -max-line-length = 88 \ No newline at end of file +max-line-length = 79 \ No newline at end of file From 699543f5c3e9201c36a2ae9857a59613ffc62022 Mon Sep 17 00:00:00 2001 From: Robbert Verbruggen Date: Wed, 7 Oct 2020 09:59:17 +0200 Subject: [PATCH 6/6] Don't fail on hound --- .flake8 | 2 -- .hound.yml | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 9f31e4c..0000000 --- a/.flake8 +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max-line-length = 79 \ No newline at end of file diff --git a/.hound.yml b/.hound.yml index bb6710a..e21dcf5 100644 --- a/.hound.yml +++ b/.hound.yml @@ -1,5 +1,4 @@ -fail_on_violations: true +fail_on_violations: false python: - enabled: true - config_file: .flake8 \ No newline at end of file + enabled: true \ No newline at end of file