Repository: fronzbot/blinkpy

Issue:
No Cameras Enabled for Motion
**Describe the bug**
When arming or disarming the sync module, the message "No Cameras Enabled for Motion" is seen in the Blink app if there are no cameras enabled.  This message is returned in the API but is not handled.  Instead "Cannot obtain new token for server auth." is logged as an error and nothing is returned.  The request does succeed though.

**To Reproduce**
Steps to reproduce the behavior:

1. Disable all individual cameras
2. Issue a request for the sync module to disarm

**Expected behavior**
The return in this case is: `{'message': 'No Cameras Enabled for Motion', 'code': 304}`.  I would expect that this message is used as the display (info only) and that the return is as per a successful call.

**Home Assistant version (if applicable):** N/A

**`blinkpy` version (not needed if filling out Home Assistant version):** 0.14.2


Comments:

Patch:
diff --git a/blinkpy/helpers/errors.py b/blinkpy/helpers/errors.py
index a3b89b3..b81404b 100644
--- a/blinkpy/helpers/errors.py
+++ b/blinkpy/helpers/errors.py
@@ -11,3 +11,5 @@ AUTH_TOKEN = (
     "Authentication header incorrect.  Are you sure you received your token?"
 )
 REQUEST = (4, "Cannot perform request (get/post type incorrect)")
+
+BLINK_ERRORS = [101, 400, 404]
diff --git a/blinkpy/helpers/util.py b/blinkpy/helpers/util.py
index 84e2816..cff1187 100644
--- a/blinkpy/helpers/util.py
+++ b/blinkpy/helpers/util.py
@@ -86,16 +86,21 @@ def http_req(blink, url='http://example.com', data=None, headers=None,
     try:
         response = blink.session.send(prepped, stream=stream)
         if json_resp and 'code' in response.json():
-            if is_retry:
+            resp_dict = response.json()
+            code = resp_dict['code']
+            message = resp_dict['message']
+            if is_retry and code in ERROR.BLINK_ERRORS:
                 _LOGGER.error("Cannot obtain new token for server auth.")
                 return None
-            else:
+            elif code in ERROR.BLINK_ERRORS:
                 headers = attempt_reauthorization(blink)
                 if not headers:
                     raise exceptions.ConnectionError
                 return http_req(blink, url=url, data=data, headers=headers,
                                 reqtype=reqtype, stream=stream,
                                 json_resp=json_resp, is_retry=True)
+            _LOGGER.warning("Response from server: %s - %s", code, message)
+
     except (exceptions.ConnectionError, exceptions.Timeout):
         _LOGGER.info("Cannot connect to server with url %s.", url)
         if not is_retry:
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000..631a790
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,13 @@
+codecov:
+  branch: dev
+coverage:
+  status:
+    project:
+      default:
+        threshold: 0.02
+
+comment: true
+require_ci_to_pass: yes
+range: 65..90
+round: down
+precision: 1
diff --git a/tox.ini b/tox.ini
index f1b8dfc..1cb3c1f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -8,7 +8,7 @@ setenv =
     LANG=en_US.UTF-8
     PYTHONPATH = {toxinidir}
 commands = 
-    pytest --timeout=9 --durations=10 
+    pytest --timeout=9 --durations=10 --cov=blinkpy --cov-report term-missing {posargs}
 deps = 
     -r{toxinidir}/requirements.txt
     -r{toxinidir}/requirements_test.txt


Test patch:
diff --git a/tests/test_blinkpy.py b/tests/test_blinkpy.py
index 613ac23..686641c 100644
--- a/tests/test_blinkpy.py
+++ b/tests/test_blinkpy.py
@@ -123,8 +123,8 @@ class TestBlinkSetup(unittest.TestCase):
     def test_bad_request(self, mock_sess):
         """Check that we raise an Exception with a bad request."""
         self.blink.session = create_session()
-        explog = ("ERROR:blinkpy.helpers.util:"
-                  "Cannot obtain new token for server auth.")
+        explog = ("WARNING:blinkpy.helpers.util:"
+                  "Response from server: 200 - foo")
         with self.assertRaises(BlinkException):
             http_req(self.blink, reqtype='bad')