From 4703c54b4348eab9858076af08f1a1334d7e091b Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Thu, 23 Jun 2022 00:14:34 -0400 Subject: [PATCH 1/3] Expanded mini and lotus tests --- tests/test_blinkpy.py | 174 +++++++++++++++++++++++++++++++++++------- 1 file changed, 145 insertions(+), 29 deletions(-) diff --git a/tests/test_blinkpy.py b/tests/test_blinkpy.py index e8841798..82d1c211 100644 --- a/tests/test_blinkpy.py +++ b/tests/test_blinkpy.py @@ -327,35 +327,6 @@ def test_initialize_blink_doorbells(self, mock_start): self.assertEqual(self.blink.sync["foo"].name, "foo") self.assertEqual(self.blink.sync["bar"].name, "bar") - # def test_blink_doorbell_cameras_returned(self): - # """Test that blink doorbell cameras are found if attached to sync module.""" - # self.blink.network_ids = ["1234"] - # self.blink.homescreen = { - # "doorbells": [ - # { - # "id": 1, - # "name": "foo", - # "network_id": 1234, - # "onboarded": True, - # "enabled": True, - # "status": "online", - # "thumbnail": "/foo/bar", - # "serial": "abc123", - # } - # ] - # } - # result = self.blink.setup_lotus() - # self.assertEqual(self.blink.network_ids, ["1234"]) - # self.assertEqual( - # result, [{"1234": {"name": "foo", "id": "1234", "type": "doorbell"}}] - # ) - - # self.blink.network_ids = [] - # self.blink.get_homescreen() - # result = self.blink.setup_lotus() - # self.assertEqual(self.blink.network_ids, []) - # self.assertEqual(result, []) - @mock.patch("blinkpy.api.request_camera_usage") def test_blink_doorbell_attached_to_sync(self, mock_usage): """Test that blink doorbell cameras are properly attached to sync module.""" @@ -380,6 +351,151 @@ def test_blink_doorbell_attached_to_sync(self, mock_usage): result, {"1234": [{"name": "foo", "id": "1234", "type": "doorbell"}]} ) + @mock.patch("blinkpy.api.request_camera_usage") + def test_blink_multi_doorbell(self, mock_usage): + """Test that multiple doorbells are properly attached to sync module.""" + self.blink.network_ids = ["1234"] + self.blink.homescreen = { + "doorbells": [ + { + "id": 1, + "name": "foo", + "network_id": 1234, + "onboarded": True, + "enabled": True, + "status": "online", + "thumbnail": "/foo/bar", + "serial": "abc123", + }, + { + "id": 2, + "name": "bar", + "network_id": 1234, + "onboarded": True, + "enabled": True, + "status": "online", + "thumbnail": "/bar/foo", + "serial": "zxc456", + }, + ] + } + expected = { + "1234": [ + {"name": "foo", "id": "1234", "type": "doorbell"}, + {"name": "bar", "id": "1234", "type": "doorbell"}, + ] + } + mock_usage.return_value = {"networks": [{"cameras": [], "network_id": 1234}]} + result = self.blink.setup_camera_list() + self.assertEqual(result, expected) + + @mock.patch("blinkpy.api.request_camera_usage") + def test_blink_multi_mini(self, mock_usage): + """Test that multiple minis are properly attached to sync module.""" + self.blink.network_ids = ["1234"] + self.blink.homescreen = { + "owls": [ + { + "id": 1, + "name": "foo", + "network_id": 1234, + "onboarded": True, + "enabled": True, + "status": "online", + "thumbnail": "/foo/bar", + "serial": "abc123", + }, + { + "id": 2, + "name": "bar", + "network_id": 1234, + "onboarded": True, + "enabled": True, + "status": "online", + "thumbnail": "/bar/foo", + "serial": "zxc456", + }, + ] + } + expected = { + "1234": [ + {"name": "foo", "id": "1234", "type": "mini"}, + {"name": "bar", "id": "1234", "type": "mini"}, + ] + } + mock_usage.return_value = {"networks": [{"cameras": [], "network_id": 1234}]} + result = self.blink.setup_camera_list() + self.assertEqual(result, expected) + + @mock.patch("blinkpy.api.request_camera_usage") + def test_blink_camera_mix(self, mock_usage): + """Test that a mix of cameras are properly attached to sync module.""" + self.blink.network_ids = ["1234"] + self.blink.homescreen = { + "doorbells": [ + { + "id": 1, + "name": "foo", + "network_id": 1234, + "onboarded": True, + "enabled": True, + "status": "online", + "thumbnail": "/foo/bar", + "serial": "abc123", + }, + { + "id": 2, + "name": "bar", + "network_id": 1234, + "onboarded": True, + "enabled": True, + "status": "online", + "thumbnail": "/bar/foo", + "serial": "zxc456", + }, + ], + "owls": [ + { + "id": 3, + "name": "dead", + "network_id": 1234, + "onboarded": True, + "enabled": True, + "status": "online", + "thumbnail": "/dead/beef", + "serial": "qwerty", + }, + { + "id": 4, + "name": "beef", + "network_id": 1234, + "onboarded": True, + "enabled": True, + "status": "online", + "thumbnail": "/beef/dead", + "serial": "dvorak", + }, + ], + } + expected = { + "1234": [ + {"name": "foo", "id": "1234", "type": "doorbell"}, + {"name": "bar", "id": "1234", "type": "doorbell"}, + {"name": "dead", "id": "1234", "type": "mini"}, + {"name": "beef", "id": "1234", "type": "mini"}, + {"name": "normal", "id": "1234"}, + ] + } + mock_usage.return_value = { + "networks": [ + {"cameras": [{"name": "normal", "id": "1234"}], "network_id": 1234} + ] + } + result = self.blink.setup_camera_list() + self.assertTrue("1234" in result) + for element in result["1234"]: + self.assertTrue(element in expected["1234"]) + class MockSync: """Mock sync module class.""" From 34a1d876c57a2f538d9f0b27765d0dfc5205b51f Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Sun, 26 Jun 2022 14:26:12 -0400 Subject: [PATCH 2/3] Add type param for regular cameras, add test to check for mixed camera usage --- blinkpy/blinkpy.py | 2 +- blinkpy/sync_module.py | 1 + tests/test_blinkpy.py | 9 ++++-- tests/test_sync_module.py | 64 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 4 deletions(-) diff --git a/blinkpy/blinkpy.py b/blinkpy/blinkpy.py index 41f3220e..049f78ed 100644 --- a/blinkpy/blinkpy.py +++ b/blinkpy/blinkpy.py @@ -221,7 +221,7 @@ def setup_camera_list(self): all_cameras[camera_network] = [] for camera in network["cameras"]: all_cameras[camera_network].append( - {"name": camera["name"], "id": camera["id"]} + {"name": camera["name"], "id": camera["id"], "type": "default"} ) mini_cameras = self.setup_owls() lotus_cameras = self.setup_lotus() diff --git a/blinkpy/sync_module.py b/blinkpy/sync_module.py index 1873a7bd..64ea61ad 100644 --- a/blinkpy/sync_module.py +++ b/blinkpy/sync_module.py @@ -125,6 +125,7 @@ def update_cameras(self, camera_type=BlinkCamera): type_map = { "mini": BlinkCameraMini, "lotus": BlinkDoorbell, + "default": BlinkCamera, } try: for camera_config in self.camera_list: diff --git a/tests/test_blinkpy.py b/tests/test_blinkpy.py index 82d1c211..e7fba3ad 100644 --- a/tests/test_blinkpy.py +++ b/tests/test_blinkpy.py @@ -103,8 +103,11 @@ def test_setup_cameras(self, mock_home, mock_req): self.assertEqual( result, { - "1234": [{"name": "foo", "id": 5678}, {"name": "bar", "id": 5679}], - "4321": [{"name": "test", "id": 0000}], + "1234": [ + {"name": "foo", "id": 5678, "type": "default"}, + {"name": "bar", "id": 5679, "type": "default"}, + ], + "4321": [{"name": "test", "id": 0000, "type": "default"}], }, ) @@ -483,7 +486,7 @@ def test_blink_camera_mix(self, mock_usage): {"name": "bar", "id": "1234", "type": "doorbell"}, {"name": "dead", "id": "1234", "type": "mini"}, {"name": "beef", "id": "1234", "type": "mini"}, - {"name": "normal", "id": "1234"}, + {"name": "normal", "id": "1234", "type": "default"}, ] } mock_usage.return_value = { diff --git a/tests/test_sync_module.py b/tests/test_sync_module.py index 67d52061..39d1b67e 100644 --- a/tests/test_sync_module.py +++ b/tests/test_sync_module.py @@ -2,6 +2,8 @@ import unittest from unittest import mock +from random import shuffle + from blinkpy.blinkpy import Blink from blinkpy.helpers.util import BlinkURLHandler from blinkpy.sync_module import BlinkSyncModule, BlinkOwl, BlinkLotus @@ -309,3 +311,65 @@ def test_lotus_start(self, mock_resp): self.assertTrue(lotus.start()) self.assertTrue("doo" in lotus.cameras) self.assertEqual(lotus.cameras["doo"].__class__, BlinkDoorbell) + + def test_sync_with_mixed_cameras(self, mock_resp): + """Test sync module with mixed cameras attached.""" + resp_sync = { + "syncmodule": { + "network_id": 1234, + "id": 1, + "serial": 456, + "status": "onboarded", + } + } + resp_network_info = {"network": {"sync_module_error": False}} + resp_videos = {"media": []} + resp_empty = {} + + self.blink.sync["test"].camera_list = [ + {"name": "foo", "id": 10, "type": "default"}, + {"name": "bar", "id": 11, "type": "mini"}, + {"name": "fake", "id": 12, "type": "lotus"}, + ] + + self.blink.homescreen = { + "owls": [{"name": "bar", "id": 3}], + "doorbells": [{"name": "fake", "id": 12}], + } + + side_effect = [ + resp_sync, + resp_network_info, + resp_videos, + resp_empty, + resp_empty, + resp_empty, + resp_empty, + resp_empty, + resp_empty, + ] + + mock_resp.side_effect = side_effect + + test_sync = self.blink.sync["test"] + + self.assertTrue(test_sync.start()) + self.assertEqual(test_sync.cameras["foo"].__class__, BlinkCamera) + self.assertEqual(test_sync.cameras["bar"].__class__, BlinkCameraMini) + self.assertEqual(test_sync.cameras["fake"].__class__, BlinkDoorbell) + + # Now shuffle the cameras and see if it still works + for i in range(0, 10): + shuffle(test_sync.camera_list) + mock_resp.side_effect = side_effect + self.assertTrue(test_sync.start()) + debug_msg = f"Iteration: {i}, {test_sync.camera_list}" + self.assertEqual( + test_sync.cameras["foo"].__class__, BlinkCamera, msg=debug_msg + ) + self.assertEqual( + test_sync.cameras["bar"].__class__, BlinkCameraMini, msg=debug_msg + ) + self.assertEqual( + test_sync.cameras["fake"].__class__, BlinkDoorbell, msg=debug_msg + ) From e8af30975f05bf1771492787d93eeb2a6646c263 Mon Sep 17 00:00:00 2001 From: Kevin Fronczak Date: Sun, 26 Jun 2022 14:39:18 -0400 Subject: [PATCH 3/3] Added some useful but missing tests --- tests/test_sync_module.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_sync_module.py b/tests/test_sync_module.py index 39d1b67e..da27e560 100644 --- a/tests/test_sync_module.py +++ b/tests/test_sync_module.py @@ -373,3 +373,15 @@ def test_sync_with_mixed_cameras(self, mock_resp): self.assertEqual( test_sync.cameras["fake"].__class__, BlinkDoorbell, msg=debug_msg ) + + def test_name_not_in_config(self, mock_resp): + """Check that function exits when name not in camera_config.""" + test_sync = self.blink.sync["test"] + test_sync.camera_list = [{"foo": "bar"}] + self.assertTrue(test_sync.update_cameras()) + + def test_camera_config_key_error(self, mock_resp): + """Check that update returns False on KeyError.""" + test_sync = self.blink.sync["test"] + test_sync.camera_list = [{"name": "foobar"}] + self.assertFalse(test_sync.update_cameras())