Repository: gerva/tower-companion

Issue:
When no configuration file is set, `kick` raises a ConfigError
we should intercept the ConfigError and explain what's wrong with the configuration, instead of just printing the full stack trace

Discussion:
coveralls: 
[![Coverage Status](https://coveralls.io/builds/8472505/badge)](https://coveralls.io/builds/8472505)

Coverage remained the same at 100.0% when pulling **ad80837a4268266baeb9cebaa1d793a4d0bc46fb on michaelgaida:TC-26** into **5c373dd2992d4404e9a0e5fc0c5195f58c7ddb7a on gerva:master**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/8473235/badge)](https://coveralls.io/builds/8473235)

Coverage remained the same at 100.0% when pulling **2ac2caa48f1e7562fef046d4e62dc28cfec0ff63 on michaelgaida:TC-26** into **5c373dd2992d4404e9a0e5fc0c5195f58c7ddb7a on gerva:master**.


Patch:
diff --git a/lib/api.py b/lib/api.py
index 6d76e18..a131931 100644
--- a/lib/api.py
+++ b/lib/api.py
@@ -8,6 +8,7 @@ import json
 import requests
 import lib.validate as validate
 from lib.adhoc import AdHocError
+from lib.configuration import ConfigError
 
 
 class APIError(Exception):
@@ -27,7 +28,13 @@ class APIv1(object):
     # E: Instance of 'LookupDict' has no 'created' member (no-member)
     def __init__(self, config):
         self.config = config
-        self.host = config.get('host')
+        try:
+            self.host = config.get('host')
+        except ConfigError as error:
+            msg = "Missing key from configuration, {0}.".format(error)
+            msg = "{0} Please check your configuration.".format(msg)
+            raise APIError(msg)
+
         self.api_url = "https://{0}/api/v1".format(self.host)
 
     def _authentication(self):
@@ -38,14 +45,25 @@ class APIv1(object):
             (tuple) username, password
         """
         config = self.config
-        return (config.get('username'), config.get('password'))
+        try:
+            return (config.get('username'), config.get('password'))
+        except ConfigError as error:
+            msg = "Missing key from configuration, {0}.".format(error)
+            msg = "{0} Please check your configuration.".format(msg)
+            raise APIError(msg)
 
     def _verify_ssl(self):
         """
         Gets the value of verify_ssl from the actual configuraion
         """
         config = self.config
-        return config.getboolean('verify_ssl')
+        try:
+            return config.getboolean('verify_ssl')
+        except ConfigError as error:
+            msg = "Missing key from configuration, {0}.".format(error)
+            msg = "{0} Please check your configuration.".format(msg)
+            raise APIError(msg)
+
 
     def _get(self, url, params, data):
         auth = self._authentication()


Test patch:
diff --git a/test/test_api.py b/test/test_api.py
index 50b1a85..31d8d27 100644
--- a/test/test_api.py
+++ b/test/test_api.py
@@ -135,6 +135,25 @@ def test_get_json_error(monkeypatch):
     with pytest.raises(APIError):
         api._get_json(url='', params={}, data={})
 
+def test_less_configuration():
+    config = Config(None)
+    with pytest.raises(APIError):
+        api = APIv1(config)
+
+    config.update('host', HOST)
+    api = APIv1(config)
+    with pytest.raises(APIError):
+        api._authentication()
+
+    config.update('username', USERNAME)
+    api = APIv1(config)
+    with pytest.raises(APIError):
+        api._authentication()
+
+    config.update('password', PASSWORD)
+    api = APIv1(config)
+    with pytest.raises(APIError):
+        api._verify_ssl()
 
 def test_job_params(monkeypatch):
     def mockreturn(*args, **kwargs):