From 8c2a5f04926473a2a89667b7603e21cc31b80f61 Mon Sep 17 00:00:00 2001
From: Cqoicebordel <Cqoicebordel@users.noreply.github.com>
Date: Mon, 9 Feb 2015 18:28:08 +0100
Subject: [PATCH] DDG Definitions' unit tests

---
 searx/engines/duckduckgo_definitions.py       |   5 +-
 .../engines/test_duckduckgo_definitions.py    | 250 ++++++++++++++++++
 searx/tests/test_engines.py                   |   1 +
 3 files changed, 254 insertions(+), 2 deletions(-)
 create mode 100644 searx/tests/engines/test_duckduckgo_definitions.py

diff --git a/searx/engines/duckduckgo_definitions.py b/searx/engines/duckduckgo_definitions.py
index b66d6c0f2..793e97d22 100644
--- a/searx/engines/duckduckgo_definitions.py
+++ b/searx/engines/duckduckgo_definitions.py
@@ -25,9 +25,10 @@ def request(query, params):
 
 
 def response(resp):
-    search_res = json.loads(resp.text)
     results = []
 
+    search_res = json.loads(resp.text)
+
     content = ''
     heading = search_res.get('Heading', '')
     attributes = []
@@ -68,7 +69,7 @@ def response(resp):
             results.append({'title': heading, 'url': firstURL})
 
     # related topics
-    for ddg_result in search_res.get('RelatedTopics', None):
+    for ddg_result in search_res.get('RelatedTopics', []):
         if 'FirstURL' in ddg_result:
             suggestion = result_to_text(ddg_result.get('FirstURL', None),
                                         ddg_result.get('Text', None),
diff --git a/searx/tests/engines/test_duckduckgo_definitions.py b/searx/tests/engines/test_duckduckgo_definitions.py
new file mode 100644
index 000000000..71c84235c
--- /dev/null
+++ b/searx/tests/engines/test_duckduckgo_definitions.py
@@ -0,0 +1,250 @@
+from collections import defaultdict
+import mock
+from searx.engines import duckduckgo_definitions
+from searx.testing import SearxTestCase
+
+
+class TestDDGDefinitionsEngine(SearxTestCase):
+
+    def test_result_to_text(self):
+        url = ''
+        text = 'Text'
+        html_result = 'Html'
+        result = duckduckgo_definitions.result_to_text(url, text, html_result)
+        self.assertEqual(result, text)
+
+        html_result = '<a href="url">Text in link</a>'
+        result = duckduckgo_definitions.result_to_text(url, text, html_result)
+        self.assertEqual(result, 'Text in link')
+
+    def test_request(self):
+        query = 'test_query'
+        dicto = defaultdict(dict)
+        dicto['pageno'] = 1
+        params = duckduckgo_definitions.request(query, dicto)
+        self.assertIn('url', params)
+        self.assertIn(query, params['url'])
+        self.assertIn('duckduckgo.com', params['url'])
+
+    def test_response(self):
+        self.assertRaises(AttributeError, duckduckgo_definitions.response, None)
+        self.assertRaises(AttributeError, duckduckgo_definitions.response, [])
+        self.assertRaises(AttributeError, duckduckgo_definitions.response, '')
+        self.assertRaises(AttributeError, duckduckgo_definitions.response, '[]')
+
+        response = mock.Mock(text='{}')
+        self.assertEqual(duckduckgo_definitions.response(response), [])
+
+        response = mock.Mock(text='{"data": []}')
+        self.assertEqual(duckduckgo_definitions.response(response), [])
+
+        json = """
+        {
+          "DefinitionSource": "definition source",
+          "Heading": "heading",
+          "ImageWidth": 0,
+          "RelatedTopics": [
+            {
+              "Result": "Top-level domains",
+              "Icon": {
+                "URL": "",
+                "Height": "",
+                "Width": ""
+              },
+              "FirstURL": "https://first.url",
+              "Text": "text"
+            },
+            {
+              "Topics": [
+                {
+                  "Result": "result topic",
+                  "Icon": {
+                    "URL": "",
+                    "Height": "",
+                    "Width": ""
+                  },
+                  "FirstURL": "https://duckduckgo.com/?q=2%2F2",
+                  "Text": "result topic text"
+                }
+              ],
+              "Name": "name"
+            }
+          ],
+          "Entity": "Entity",
+          "Type": "A",
+          "Redirect": "",
+          "DefinitionURL": "http://definition.url",
+          "AbstractURL": "https://abstract.url",
+          "Definition": "this is the definition",
+          "AbstractSource": "abstract source",
+          "Infobox": {
+            "content": [
+              {
+                "data_type": "string",
+                "value": "1999",
+                "label": "Introduced",
+                "wiki_order": 0
+              }
+            ],
+            "meta": [
+              {
+                "data_type": "string",
+                "value": ".test",
+                "label": "article_title"
+              }
+            ]
+          },
+          "Image": "image.png",
+          "ImageIsLogo": 0,
+          "Abstract": "abstract",
+          "AbstractText": "abstract text",
+          "AnswerType": "",
+          "ImageHeight": 0,
+          "Results": [{
+                 "Result" : "result title",
+                 "Icon" : {
+                    "URL" : "result url",
+                    "Height" : 16,
+                    "Width" : 16
+                 },
+                 "FirstURL" : "result first url",
+                 "Text" : "result text"
+              }
+          ],
+          "Answer": "answer"
+        }
+        """
+        response = mock.Mock(text=json)
+        results = duckduckgo_definitions.response(response)
+        self.assertEqual(type(results), list)
+        self.assertEqual(len(results), 4)
+        self.assertEqual(results[0]['answer'], 'answer')
+        self.assertEqual(results[1]['title'], 'heading')
+        self.assertEqual(results[1]['url'], 'result first url')
+        self.assertEqual(results[2]['suggestion'], 'text')
+        self.assertEqual(results[3]['infobox'], 'heading')
+        self.assertEqual(results[3]['id'], 'http://definition.url')
+        self.assertEqual(results[3]['entity'], 'Entity')
+        self.assertIn('abstract', results[3]['content'])
+        self.assertIn('this is the definition', results[3]['content'])
+        self.assertEqual(results[3]['img_src'], 'image.png')
+        self.assertIn('Introduced', results[3]['attributes'][0]['label'])
+        self.assertIn('1999', results[3]['attributes'][0]['value'])
+        self.assertIn({'url': 'https://abstract.url', 'title': 'abstract source'}, results[3]['urls'])
+        self.assertIn({'url': 'http://definition.url', 'title': 'definition source'}, results[3]['urls'])
+        self.assertIn({'name': 'name', 'suggestions': ['result topic text']}, results[3]['relatedTopics'])
+
+        json = """
+        {
+          "DefinitionSource": "definition source",
+          "Heading": "heading",
+          "ImageWidth": 0,
+          "RelatedTopics": [],
+          "Entity": "Entity",
+          "Type": "A",
+          "Redirect": "",
+          "DefinitionURL": "",
+          "AbstractURL": "https://abstract.url",
+          "Definition": "",
+          "AbstractSource": "abstract source",
+          "Image": "",
+          "ImageIsLogo": 0,
+          "Abstract": "",
+          "AbstractText": "abstract text",
+          "AnswerType": "",
+          "ImageHeight": 0,
+          "Results": [],
+          "Answer": ""
+        }
+        """
+        response = mock.Mock(text=json)
+        results = duckduckgo_definitions.response(response)
+        self.assertEqual(type(results), list)
+        self.assertEqual(len(results), 1)
+        self.assertEqual(results[0]['url'], 'https://abstract.url')
+        self.assertEqual(results[0]['title'], 'heading')
+        self.assertEqual(results[0]['content'], '')
+
+        json = """
+        {
+          "DefinitionSource": "definition source",
+          "Heading": "heading",
+          "ImageWidth": 0,
+          "RelatedTopics": [
+            {
+              "Result": "Top-level domains",
+              "Icon": {
+                "URL": "",
+                "Height": "",
+                "Width": ""
+              },
+              "FirstURL": "https://first.url",
+              "Text": "heading"
+            },
+            {
+              "Name": "name"
+            },
+            {
+              "Topics": [
+                {
+                  "Result": "result topic",
+                  "Icon": {
+                    "URL": "",
+                    "Height": "",
+                    "Width": ""
+                  },
+                  "FirstURL": "https://duckduckgo.com/?q=2%2F2",
+                  "Text": "heading"
+                }
+              ],
+              "Name": "name"
+            }
+          ],
+          "Entity": "Entity",
+          "Type": "A",
+          "Redirect": "",
+          "DefinitionURL": "http://definition.url",
+          "AbstractURL": "https://abstract.url",
+          "Definition": "this is the definition",
+          "AbstractSource": "abstract source",
+          "Infobox": {
+            "meta": [
+              {
+                "data_type": "string",
+                "value": ".test",
+                "label": "article_title"
+              }
+            ]
+          },
+          "Image": "image.png",
+          "ImageIsLogo": 0,
+          "Abstract": "abstract",
+          "AbstractText": "abstract text",
+          "AnswerType": "",
+          "ImageHeight": 0,
+          "Results": [{
+                 "Result" : "result title",
+                 "Icon" : {
+                    "URL" : "result url",
+                    "Height" : 16,
+                    "Width" : 16
+                 },
+                 "Text" : "result text"
+              }
+          ],
+          "Answer": ""
+        }
+        """
+        response = mock.Mock(text=json)
+        results = duckduckgo_definitions.response(response)
+        self.assertEqual(type(results), list)
+        self.assertEqual(len(results), 1)
+        self.assertEqual(results[0]['infobox'], 'heading')
+        self.assertEqual(results[0]['id'], 'http://definition.url')
+        self.assertEqual(results[0]['entity'], 'Entity')
+        self.assertIn('abstract', results[0]['content'])
+        self.assertIn('this is the definition', results[0]['content'])
+        self.assertEqual(results[0]['img_src'], 'image.png')
+        self.assertIn({'url': 'https://abstract.url', 'title': 'abstract source'}, results[0]['urls'])
+        self.assertIn({'url': 'http://definition.url', 'title': 'definition source'}, results[0]['urls'])
+        self.assertIn({'name': 'name', 'suggestions': []}, results[0]['relatedTopics'])
diff --git a/searx/tests/test_engines.py b/searx/tests/test_engines.py
index 4a27f5adb..0570a5296 100644
--- a/searx/tests/test_engines.py
+++ b/searx/tests/test_engines.py
@@ -8,6 +8,7 @@ from searx.tests.engines.test_deezer import *  # noqa
 from searx.tests.engines.test_deviantart import *  # noqa
 from searx.tests.engines.test_digg import *  # noqa
 from searx.tests.engines.test_duckduckgo import *  # noqa
+from searx.tests.engines.test_duckduckgo_definitions import *  # noqa
 from searx.tests.engines.test_dummy import *  # noqa
 from searx.tests.engines.test_faroo import *  # noqa
 from searx.tests.engines.test_flickr import *  # noqa