From f6dd24377a04cceabea93cd9309726e7f3195295 Mon Sep 17 00:00:00 2001
From: Erwan Rouchet <rouchet@teklia.com>
Date: Fri, 7 Sep 2018 11:24:15 +0200
Subject: [PATCH] Add unit tests

---
 arkindex/project/tests/__init__.py     |   1 +
 arkindex/project/tests/test_elastic.py | 145 +++++++++++++++++++++++++
 2 files changed, 146 insertions(+)
 create mode 100644 arkindex/project/tests/test_elastic.py

diff --git a/arkindex/project/tests/__init__.py b/arkindex/project/tests/__init__.py
index 74b0c4a9fc..157fdf885c 100644
--- a/arkindex/project/tests/__init__.py
+++ b/arkindex/project/tests/__init__.py
@@ -57,6 +57,7 @@ class RedisMockMixin(object):
     def tearDown(self):
         for p in self.patches:
             p.stop()
+        self.messages.stop()
         self.redis.flushall()
 
 
diff --git a/arkindex/project/tests/test_elastic.py b/arkindex/project/tests/test_elastic.py
new file mode 100644
index 0000000000..608301e6f4
--- /dev/null
+++ b/arkindex/project/tests/test_elastic.py
@@ -0,0 +1,145 @@
+from unittest import TestCase
+from unittest.mock import patch, MagicMock
+from arkindex.project.elastic import ESQuerySet
+
+
+class TestESQuerySet(TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.es_index = 'es_index'
+        cls.es_type = 'es_type'
+        cls.query = {
+            "some": "query"
+        }
+        cls.aggs = {
+            "some": "aggs"
+        }
+        cls.sort = {
+            "some sort of": "sorts"
+        }
+        cls.post_process_mock = MagicMock()
+
+        cls.es_mock = patch('arkindex.project.elastic.Elasticsearch').start()
+
+        cls.esqs = ESQuerySet(
+            es_index=cls.es_index,
+            es_type=cls.es_type,
+            post_process=cls.post_process_mock,
+            query=cls.query,
+            aggs=cls.aggs,
+            sort=cls.sort,
+        )
+
+    def setUp(self):
+        self.es_mock.reset_mock()
+        self.es_mock().reset_mock()
+        self.post_process_mock.reset_mock()
+
+    def test_count(self):
+        """
+        Check the ESQuerySet supports the count() and __len__ methods and calls ES correctly
+        """
+        self.es_mock().count.return_value = {'count': 42}
+
+        self.assertEqual(self.esqs.count(), 42)
+        self.assertEqual(len(self.esqs), 42)
+
+        self.assertEqual(self.es_mock().count.call_count, 2)
+        args, kwargs = self.es_mock().count.call_args
+        self.assertEqual(len(args), 0)
+        self.assertDictEqual(kwargs, {
+            "index": self.es_index,
+            "doc_type": self.es_type,
+            "body": {
+                "query": self.query,
+            },
+        })
+
+    def test_iter(self):
+        """
+        Check trying to iterate on a ESQuerySet fetches all the results from ES
+        """
+        self.es_mock().count.return_value = {'count': 42}
+        self.es_mock().search.return_value = {'some': 'results'}
+
+        iter(self.esqs)
+
+        self.assertEqual(self.es_mock().count.call_count, 1)
+        self.assertEqual(self.es_mock().search.call_count, 1)
+        self.assertEqual(self.post_process_mock.call_count, 1)
+
+        args, kwargs = self.es_mock().search.call_args
+        self.assertEqual(len(args), 0)
+        self.assertEqual(kwargs['body']['from'], 0)
+        self.assertEqual(kwargs['body']['size'], 42)
+
+        args, kwargs = self.post_process_mock.call_args
+        self.assertTupleEqual(args, ({'some': 'results'}, ))
+
+    def test_slice(self):
+        """
+        Check retrieving a slice from the ESQuerySEt retrieves only this slice from ES
+        """
+        self.esqs[10:15]
+
+        self.assertEqual(self.es_mock().search.call_count, 1)
+        self.assertEqual(self.post_process_mock.call_count, 1)
+
+        args, kwargs = self.es_mock().search.call_args
+        self.assertEqual(len(args), 0)
+        self.assertDictEqual(kwargs, {
+            "index": self.es_index,
+            "doc_type": self.es_type,
+            "body": {
+                "from": 10,
+                "size": 5,
+                "_source": True,
+                "query": self.query,
+                "aggs": self.aggs,
+                "sort": self.sort,
+            }
+        })
+
+    def test_single_item(self):
+        """
+        Check retrieving a single item by index from the ESQuerySet retrieves a single item from ES
+        """
+        self.esqs[10]
+
+        self.assertEqual(self.es_mock().search.call_count, 1)
+        self.assertEqual(self.post_process_mock.call_count, 1)
+
+        args, kwargs = self.es_mock().search.call_args
+        self.assertEqual(len(args), 0)
+        self.assertDictEqual(kwargs, {
+            "index": self.es_index,
+            "doc_type": self.es_type,
+            "body": {
+                "from": 10,
+                "size": 1,
+                "_source": True,
+                "query": self.query,
+                "aggs": self.aggs,
+                "sort": self.sort,
+            }
+        })
+
+    def test_large_results(self):
+        """
+        Check the ESQuerySet caps to 10,000 results to prevent errors without the scroll API
+        """
+        self.es_mock().count.return_value = {'count': 99999}
+        self.es_mock().search.return_value = {'some': 'results'}
+
+        self.assertEqual(len(self.esqs), 10000)
+        self.esqs[500:20000]
+
+        self.assertEqual(self.es_mock().count.call_count, 1)
+        self.assertEqual(self.es_mock().search.call_count, 1)
+        self.assertEqual(self.post_process_mock.call_count, 1)
+
+        args, kwargs = self.es_mock().search.call_args
+        self.assertEqual(len(args), 0)
+        self.assertEqual(kwargs['body']['from'], 500)
+        self.assertEqual(kwargs['body']['size'], 10000)
-- 
GitLab