Repository: chapinb/chickadee

Issue:
Chickadee passes fields as string instead of list to resolver
**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior. Please share (as you can):
1. Sample IP addresses causing issue: `1.1.1.1`
1. Arguments used to invoke chickadee: `chick = Chickadee(); chick.run('1.1.1.1')`
1. Error message or `chickadee.log` file: Returns `[{"count": 0}]`

**Version (please complete the following information):**
 - OS: Windows and macOS
 - Version:  d826822
 - Python version: 3.7.2

**Additional context**
Add any other context about the problem here.

Appears when you provide an IP address via API call.


Comments:

Patch:
diff --git a/libchickadee/backends/__init__.py b/libchickadee/backends/__init__.py
index 2b110e6..d1f79ef 100644
--- a/libchickadee/backends/__init__.py
+++ b/libchickadee/backends/__init__.py
@@ -62,13 +62,18 @@ class ResolverBase(object):
         Args:
             data (list, tuple, set, str): One or more IPs to resolve
 
-        Yield:
-            (dict) request data iterator
+        Returns:
+            (list) List of collected records.
 
         Example:
             >>> records = ['1.1.1.1', '2.2.2.2']
             >>> resolver = ResolverBase()
             >>> resolved_data = resolver.query(records)
+            >>> print(resolved_data)
+            [
+             {"query": "1.1.1.1", "country": "Australia", ...},
+             {"query": "2.2.2.2", "country": "France", ...}
+            ]
         """
 
         self.data = data
diff --git a/libchickadee/backends/ipapi.py b/libchickadee/backends/ipapi.py
index 14d5dac..398d9ea 100644
--- a/libchickadee/backends/ipapi.py
+++ b/libchickadee/backends/ipapi.py
@@ -182,7 +182,7 @@ class Resolver(ResolverBase):
 
         for x in orig_recs:
             params = {
-                'fields': ','.join(self.fields),
+                'fields': ','.join(self.fields) if isinstance(self.fields, list) else self.fields,
                 'lang': self.lang,
             }
             if self.api_key:
@@ -237,7 +237,7 @@ class Resolver(ResolverBase):
         )
         if rdata.status_code == 200:
             self.rate_limit(rdata.headers)
-            return rdata.json()
+            return [rdata.json()]
         elif rdata.status_code == 429:
             self.rate_limit(rdata.headers)
             self.sleeper()
diff --git a/libchickadee/chickadee.py b/libchickadee/chickadee.py
index 4ed060a..29ad97c 100644
--- a/libchickadee/chickadee.py
+++ b/libchickadee/chickadee.py
@@ -194,7 +194,7 @@ class Chickadee(object):
         self.input_data = None
         self.outformat = outformat
         self.outfile = outfile
-        self.fields = fields
+        self.fields = fields if isinstance(fields, list) else fields.split(',')
         self.force_single = False
         self.ignore_bogon = True
         self.lang = 'en'
@@ -380,7 +380,7 @@ class Chickadee(object):
 
             for element in data:
                 resolver.data = element
-                results.append(resolver.single())
+                results += resolver.single()
         else:
             results = resolver.query(distinct_ips)
 


Test patch:
diff --git a/libchickadee/test/test_backend_ipapi.py b/libchickadee/test/test_backend_ipapi.py
index c10895c..62a0ee9 100644
--- a/libchickadee/test/test_backend_ipapi.py
+++ b/libchickadee/test/test_backend_ipapi.py
@@ -72,7 +72,7 @@ class IPAPITestCase(unittest.TestCase):
             mock_query.return_value = MockResponse(json_data=self.expected_result[count], status_code=200)
             self.resolver.data = ip
             data = self.resolver.single()
-            self.assertEqual(data, self.expected_result[count])
+            self.assertEqual(data, [self.expected_result[count]])
 
     @patch("libchickadee.backends.ipapi.requests.post")
     def test_ipapi_resolve_batch(self, mock_query):
@@ -105,7 +105,7 @@ class IPAPITestCase(unittest.TestCase):
     def test_ipapi_rate_limiting(self, mock_get, mock_post):
         single = {
             "test_data": self.test_data_ips[1],
-            "expected_data": self.expected_result[1],
+            "expected_data": [self.expected_result[1]],
             "mock_data": [
                 MockResponse(json_data={}, status_code=429, rl='0', ttl='2'),
                 MockResponse(json_data=self.expected_result[1], status_code=200, rl='0', ttl='0')
diff --git a/libchickadee/test/test_chickadee.py b/libchickadee/test/test_chickadee.py
index 03ea9c6..7de8cba 100644
--- a/libchickadee/test/test_chickadee.py
+++ b/libchickadee/test/test_chickadee.py
@@ -188,7 +188,7 @@ class ChickadeeStringTestCase(unittest.TestCase):
         chickadee = Chickadee()
         chickadee.ignore_bogon = False
         chickadee.fields = self.fields
-        mock_query.return_value = self.expected_result.copy()
+        mock_query.return_value = self.expected_result
         data = chickadee.run(','.join(self.test_data_ips))
         res = [x for x in data]
         self.assertCountEqual(res, self.expected_result)
@@ -202,7 +202,7 @@ class ChickadeeStringTestCase(unittest.TestCase):
                 self.data = None
 
             def single(self):
-                return [x for x in expected_results if x['query'] == self.data][0]
+                return [x for x in expected_results if x['query'] == self.data]
 
         chickadee = Chickadee()
         chickadee.ignore_bogon = False
@@ -222,6 +222,13 @@ class ChickadeeStringTestCase(unittest.TestCase):
             failed = True
         self.assertTrue(failed)
 
+    @patch("libchickadee.backends.ipapi.Resolver.batch")
+    def test_manual_run(self, mock_query):
+        chick = Chickadee(fields=self.fields)
+        mock_query.return_value = [self.expected_result[1]]
+        actual = chick.run(self.test_data_ips[1])
+        self.assertDictEqual(self.expected_result[1], actual[0])
+
 
 class ChickadeeFileTestCase(unittest.TestCase):
     """Chickadee script tests."""