From b424fab5a7263573951ce5f69c57f694131a886b Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Mar 2017 06:22:42 -0400 Subject: [PATCH 1/8] Introduced base skeleton for unittest --- requirements.txt | 4 +- setup.cfg | 4 + setup.py | 1 + tests/__init__.py | 1 + tests/test_ring.py | 208 +++++++++++++++++++++++++++++++++++++++++++++ tox.ini | 8 +- 6 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/test_ring.py diff --git a/requirements.txt b/requirements.txt index 7fd41edc..76e27bcf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,7 @@ flake8 +mock pylint +pytest +pytz requests tox -pytz diff --git a/setup.cfg b/setup.cfg index b88034e4..bec0b5e4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,6 @@ [metadata] description-file = README.md + +[tool:pytest] +testpaths = tests +norecursedirs = .git diff --git a/setup.py b/setup.py index 877de375..98d3feb2 100644 --- a/setup.py +++ b/setup.py @@ -14,6 +14,7 @@ license='LGPLv3+', include_package_data=True, install_requires=['requests', 'pytz'], + test_suite='tests', keywords=[ 'ring', 'door bell', diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..35ce998d --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +"""Tests for Ring Door Bell components.""" diff --git a/tests/test_ring.py b/tests/test_ring.py new file mode 100644 index 00000000..f2e29f3c --- /dev/null +++ b/tests/test_ring.py @@ -0,0 +1,208 @@ +"""The tests for the Ring platform.""" +import unittest +try: + import mock +except ImportError: + from unittest import mock + +USERNAME = 'foo' +PASSWORD = 'bar' + + +def mocked_requests_get(*args, **kwargs): + """Mock requests.get invocations.""" + class MockResponse: + """Class to represent a mocked response.""" + + def __init__(self, json_data, status_code): + """Initialize the mock response class.""" + self.json_data = json_data + self.status_code = status_code + + def json(self): + """Return the json of the response.""" + return self.json_data + + if str(args[0]).startswith('https://api.ring.com/clients_api/session'): + return MockResponse({ + "profile": { + "authentication_token": "12345678910", + "email": "foo@bar.org", + "features": { + "chime_dnd_enabled": False, + "chime_pro_enabled": True, + "delete_all_enabled": True, + "delete_all_settings_enabled": False, + "device_health_alerts_enabled": True, + "floodlight_cam_enabled": True, + "live_view_settings_enabled": True, + "lpd_enabled": True, + "lpd_motion_announcement_enabled": False, + "multiple_calls_enabled": True, + "multiple_delete_enabled": True, + "nw_enabled": True, + "nw_larger_area_enabled": False, + "nw_user_activated": False, + "owner_proactive_snoozing_enabled": True, + "power_cable_enabled": False, + "proactive_snoozing_enabled": False, + "reactive_snoozing_enabled": False, + "remote_logging_format_storing": False, + "remote_logging_level": 1, + "ringplus_enabled": True, + "starred_events_enabled": True, + "stickupcam_setup_enabled": True, + "subscriptions_enabled": True, + "ujet_enabled": False, + "video_search_enabled": False, + "vod_enabled": False}, + "first_name": "Foo", + "id": 999999, + "last_name": "Bar"} + }, 201) + elif str(args[0])\ + .startswith("https://api.ring.com/clients_api/ring_devices"): + return MockResponse({ + "authorized_doorbots": [], + "chimes": [ + { + "address": "123 Main St", + "alerts": {"connection": "online"}, + "description": "Downstairs", + "device_id": "abcdef123", + "do_not_disturb": {"seconds_left": 0}, + "features": {"ringtones_enabled": True}, + "firmware_version": "1.2.3", + "id": 999999, + "kind": "chime", + "latitude": 12.000000, + "longitude": -70.12345, + "owned": True, + "owner": { + "email": "foo@bar.org", + "first_name": "Marcelo", + "id": 999999, + "last_name": "Bar"}, + "settings": { + "ding_audio_id": None, + "ding_audio_user_id": None, + "motion_audio_id": None, + "motion_audio_user_id": None, + "volume": 2}, + "time_zone": "America/New_York"}], + "doorbots": [ + { + "address": "123 Main St", + "alerts": {"connection": "online"}, + "battery_life": 4081, + "description": "Front Door", + "device_id": "aacdef123", + "external_connection": False, + "features": { + "advanced_motion_enabled": False, + "motion_message_enabled": False, + "motions_enabled": True, + "people_only_enabled": False, + "shadow_correction_enabled": False, + "show_recordings": True}, + "firmware_version": "1.4.26", + "id": 987652, + "kind": "lpd_v1", + "latitude": 12.000000, + "longitude": -70.12345, + "motion_snooze": None, + "owned": True, + "owner": { + "email": "foo@bar.org", + "first_name": "Foo", + "id": 999999, + "last_name": "Bar"}, + "settings": { + "chime_settings": { + "duration": 3, + "enable": True, + "type": 0}, + "doorbell_volume": 1, + "enable_vod": True, + "live_view_preset_profile": "highest", + "live_view_presets": [ + "low", + "middle", + "high", + "highest"], + "motion_announcement": False, + "motion_snooze_preset_profile": "low", + "motion_snooze_presets": [ + "none", + "low", + "medium", + "high"]}, + "subscribed": True, + "subscribed_motions": True, + "time_zone": "America/New_York"}] + }, 200) + elif str(args[0]).startswith("https://api.ring.com/clients_api/doorbots"): + return MockResponse([{ + "answered": False, + "created_at": "2017-03-05T15:03:40.000Z", + "events": [], + "favorite": False, + "id": 987654321, + "kind": "motion", + "recording": {"status": "ready"}, + "snapshot_url": "" + }], 200) + + +class TestRing(unittest.TestCase): + """Test the Ring.""" + + @mock.patch('requests.Session.get', side_effect=mocked_requests_get) + @mock.patch('requests.Session.post', side_effect=mocked_requests_get) + def test_basic_attributes(self, get_mock, post_mock): + """Test the Ring class and methods.""" + from ring_doorbell import Ring + + myring = Ring(USERNAME, PASSWORD, persist_token=True) + self.assertTrue(myring.is_connected) + self.assertIsInstance(myring.features, dict) + self.assertFalse(myring.debug) + self.assertEqual(1, len(myring.chimes)) + self.assertNotEqual(2, len(myring.doorbells)) + self.assertTrue(myring._persist_token) + self.assertEquals('http://localhost/', myring._push_token_notify_url) + + +class TestRingChime(unittest.TestCase): + """Test the Ring Chime object.""" + + + @mock.patch('requests.Session.get', side_effect=mocked_requests_get) + @mock.patch('requests.Session.post', side_effect=mocked_requests_get) + def test_chime_attributes(self, get_mock, post_mock): + """Test the Ring Chime class and methods.""" + from ring_doorbell import Ring + + myring = Ring(USERNAME, PASSWORD, persist_token=True) + dev = myring.chimes[0] + + self.assertEqual('chime', dev.kind) + + +class TestRingDoorBell(unittest.TestCase): + """Test the Ring DoorBell object.""" + + + @mock.patch('requests.Session.get', side_effect=mocked_requests_get) + @mock.patch('requests.Session.post', side_effect=mocked_requests_get) + def test_doorbell_attributes(self, get_mock, post_mock): + """Test the Ring DoorBell class and methods.""" + from ring_doorbell import Ring + + myring = Ring(USERNAME, PASSWORD, persist_token=True) + dev = myring.doorbells[0] + + self.assertEqual('lpd_v1', dev.kind) + +if __name__ == '__main__': + unittest.main() diff --git a/tox.ini b/tox.ini index cff51f13..7dba1f66 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,16 @@ [tox] -envlist = py34, py35, py36, lint +envlist = py27, py35, py36, lint skip_missing_interpreters = True [testenv] setenv = PYTHONPATH = {toxinidir}:{toxinidir}/ring_doorbell +whitelist_externals = /usr/bin/env +install_command = /usr/bin/env LANG=C.UTF-8 pip install {opts} {packages} +commands = + py.test --verbose --color=auto --duration=0 +deps = + -r{toxinidir}/requirements.txt [testenv:lint] ignore_errors = True From e7f91616c02d01e1409803f948c7e109e569a3fd Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Mar 2017 06:25:51 -0400 Subject: [PATCH 2/8] Fixed lint --- tests/test_ring.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/test_ring.py b/tests/test_ring.py index f2e29f3c..740a594e 100644 --- a/tests/test_ring.py +++ b/tests/test_ring.py @@ -176,7 +176,6 @@ def test_basic_attributes(self, get_mock, post_mock): class TestRingChime(unittest.TestCase): """Test the Ring Chime object.""" - @mock.patch('requests.Session.get', side_effect=mocked_requests_get) @mock.patch('requests.Session.post', side_effect=mocked_requests_get) def test_chime_attributes(self, get_mock, post_mock): @@ -192,7 +191,6 @@ def test_chime_attributes(self, get_mock, post_mock): class TestRingDoorBell(unittest.TestCase): """Test the Ring DoorBell object.""" - @mock.patch('requests.Session.get', side_effect=mocked_requests_get) @mock.patch('requests.Session.post', side_effect=mocked_requests_get) def test_doorbell_attributes(self, get_mock, post_mock): @@ -203,6 +201,3 @@ def test_doorbell_attributes(self, get_mock, post_mock): dev = myring.doorbells[0] self.assertEqual('lpd_v1', dev.kind) - -if __name__ == '__main__': - unittest.main() From 8a6d7844e4b7a0eab8d6d32c4c98fe4707269715 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Mar 2017 06:30:28 -0400 Subject: [PATCH 3/8] Adding new tests to travis --- .travis.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 22d99d81..baaaf6d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,13 +3,13 @@ language: python matrix: fast_finish: true include: - #- python: "3.4.2" - #env: TOXENV=py34 + - python: "2.7" + env: TOXENV=py27 + - python: "3.5" + env: TOXENV=py35 + - python: "3.6" + env: TOXENV=py36 - python: "3.4.2" env: TOXENV=lint - #- python: "3.5" - # env: TOXENV=py35 - #- python: "3.6" - # env: TOXENV=py36 script: tox cache: pip From 11eb1ad1815d193578f79f650e669ebdd589a27e Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Mar 2017 06:49:17 -0400 Subject: [PATCH 4/8] Adding Coveralls --- .coveragerc | 2 ++ .travis.yml | 2 ++ requirements.txt | 5 ----- requirements_tests.txt | 6 ++++++ tox.ini | 1 + 5 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 .coveragerc create mode 100644 requirements_tests.txt diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 00000000..09de9c77 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +source = ring_doorbell diff --git a/.travis.yml b/.travis.yml index baaaf6d3..e21c6b25 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,5 +11,7 @@ matrix: env: TOXENV=py36 - python: "3.4.2" env: TOXENV=lint +install: pip install -U tox coveralls script: tox cache: pip +after_success: coveralls diff --git a/requirements.txt b/requirements.txt index 76e27bcf..03c5fdd6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,2 @@ -flake8 -mock -pylint -pytest pytz requests -tox diff --git a/requirements_tests.txt b/requirements_tests.txt new file mode 100644 index 00000000..e07ebba6 --- /dev/null +++ b/requirements_tests.txt @@ -0,0 +1,6 @@ +coveralls +flake8 +mock +pylint +pytest +tox diff --git a/tox.ini b/tox.ini index 7dba1f66..2993fe27 100644 --- a/tox.ini +++ b/tox.ini @@ -11,6 +11,7 @@ commands = py.test --verbose --color=auto --duration=0 deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/requirements_tests.txt [testenv:lint] ignore_errors = True From 0180abe7cd66b0e0f6e72d427b39eef1d0845366 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Mar 2017 07:03:27 -0400 Subject: [PATCH 5/8] Modified coveragerc --- .coveragerc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.coveragerc b/.coveragerc index 09de9c77..a5f7fcee 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,2 +1,5 @@ -[run] -source = ring_doorbell +[report] +omit = + */python?.?/* + */site-packages/nose/* + *__init__* From a2ea9c1892be91e14211471eaa2080126dd24307 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Mar 2017 07:12:47 -0400 Subject: [PATCH 6/8] Uploading badge to Readme --- README.md => README.rst | 4 ++++ 1 file changed, 4 insertions(+) rename README.md => README.rst (94%) diff --git a/README.md b/README.rst similarity index 94% rename from README.md rename to README.rst index 8647c18b..30551ad7 100644 --- a/README.md +++ b/README.rst @@ -1,3 +1,7 @@ +.. image:: https://coveralls.io/repos/github/tchellomello/python-ring-doorbell/badge.svg?branch=dev +:target: https://coveralls.io/github/tchellomello/python-ring-doorbell?branch=dev + + This project is a Python 2.7/3.x wrapper to access the Ring.com (http://www.ring.com) doorbell. ## Install From 77acdbb5fbf347c0ca2094329c4cd1a145b96609 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Mar 2017 07:13:51 -0400 Subject: [PATCH 7/8] Revert "Uploading badge to Readme" This reverts commit a2ea9c1892be91e14211471eaa2080126dd24307. --- README.rst => README.md | 4 ---- 1 file changed, 4 deletions(-) rename README.rst => README.md (94%) diff --git a/README.rst b/README.md similarity index 94% rename from README.rst rename to README.md index 30551ad7..8647c18b 100644 --- a/README.rst +++ b/README.md @@ -1,7 +1,3 @@ -.. image:: https://coveralls.io/repos/github/tchellomello/python-ring-doorbell/badge.svg?branch=dev -:target: https://coveralls.io/github/tchellomello/python-ring-doorbell?branch=dev - - This project is a Python 2.7/3.x wrapper to access the Ring.com (http://www.ring.com) doorbell. ## Install From eb341d2216fcf613dcc5d4ebc8687afecae355b9 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Mar 2017 18:08:43 -0400 Subject: [PATCH 8/8] added few more tests --- tests/test_ring.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_ring.py b/tests/test_ring.py index 740a594e..60381192 100644 --- a/tests/test_ring.py +++ b/tests/test_ring.py @@ -185,7 +185,13 @@ def test_chime_attributes(self, get_mock, post_mock): myring = Ring(USERNAME, PASSWORD, persist_token=True) dev = myring.chimes[0] + self.assertEqual('123 Main St', dev.address) + self.assertNotEqual(99999, dev.account_id) + self.assertEqual('abcdef123', dev.id) self.assertEqual('chime', dev.kind) + self.assertIsNotNone(dev.latitude) + self.assertEqual('America/New_York', dev.timezone) + self.assertEqual(2, dev.volume) class TestRingDoorBell(unittest.TestCase): @@ -200,4 +206,14 @@ def test_doorbell_attributes(self, get_mock, post_mock): myring = Ring(USERNAME, PASSWORD, persist_token=True) dev = myring.doorbells[0] + self.assertEqual(987652, dev.account_id) + self.assertEqual('123 Main St', dev.address) self.assertEqual('lpd_v1', dev.kind) + self.assertEqual(-70.12345, dev.longitude) + self.assertEqual('America/New_York', dev.timezone) + self.assertEqual(1, dev.volume) + + self.assertIsInstance(dev.history(limit=1, kind='motion'), list) + self.assertEqual(0, len(dev.history(limit=1, kind='ding'))) + + self.assertEqual('Mechanical', dev.existing_doorbell_type)