diff --git a/.travis.yml b/.travis.yml index 91dbc68..8d2f979 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ +dist: trusty language: python python: 3.5 sudo: false @@ -8,6 +9,7 @@ addons: packages: - oracle-java8-set-default - elasticsearch + postgresql: "9.5" services: - elasticsearch env: diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d231b84..1a0793b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -20,6 +20,7 @@ Changelog - Only index records if the storage transaction is committed (fixes #15) - Do not allow to search if no read permission on collection or bucket (fixes #7) +- Fix empty results response when plugin was enabled after collection creation (ref #20) **Internal changes** diff --git a/dev-requirements.txt b/dev-requirements.txt index ff5d08f..0379f6f 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -7,3 +7,4 @@ pytest-capturelog mock unittest2 webtest +kinto[postgresql] diff --git a/kinto_elasticsearch/views.py b/kinto_elasticsearch/views.py index 89e3d10..f16f298 100644 --- a/kinto_elasticsearch/views.py +++ b/kinto_elasticsearch/views.py @@ -33,7 +33,14 @@ def search_view(request, **kwargs): indexer = request.registry.indexer try: results = indexer.search(bucket_id, collection_id, **kwargs) + + except elasticsearch.NotFoundError as e: + # If plugin was enabled after the creation of the collection. + indexer.create_index(bucket_id, collection_id) + results = indexer.search(bucket_id, collection_id, **kwargs) + except elasticsearch.RequestError as e: + # Malformed query. message = e.info["error"]["reason"] details = e.info["error"]["root_cause"][0] response = http_error(httpexceptions.HTTPBadRequest(), @@ -41,9 +48,12 @@ def search_view(request, **kwargs): message=message, details=details) raise response + except elasticsearch.ElasticsearchException as e: + # General failure. logger.exception("Index query failed.") results = {} + return results diff --git a/tests/__init__.py b/tests/__init__.py index 0861193..7ab88dc 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -28,4 +28,6 @@ def get_app_settings(cls, extras=None): config = configparser.ConfigParser() config.read(ini_path) settings = dict(config.items('app:main')) + if extras: + settings.update(extras) return settings diff --git a/tests/test_elasticsearch.py b/tests/test_elasticsearch.py index 90ad8d4..245faa4 100644 --- a/tests/test_elasticsearch.py +++ b/tests/test_elasticsearch.py @@ -40,6 +40,50 @@ def test_returns_false_if_connection_fails(self): assert not resp.json["elasticsearch"] +class PostActivation(BaseWebTest, unittest.TestCase): + + @classmethod + def get_app_settings(cls, extras=None): + settings = super().get_app_settings(extras) + settings['storage_backend'] = 'kinto.core.storage.postgresql' + settings['storage_url'] = 'postgres://postgres:postgres@localhost:5432/postgres' + settings['permission_backend'] = 'kinto.core.permission.postgresql' + settings['permission_url'] = settings['storage_url'] + return settings + + def setUp(self): + app = self.make_app(settings={"kinto.includes": ""}) + capabilities = app.get("/").json["capabilities"] + assert "elasticsearch" not in capabilities + + app.put("/buckets/bid", headers=self.headers) + app.put("/buckets/bid/collections/cid", headers=self.headers) + app.post_json("/buckets/bid/collections/cid/records", + {"data": {"before": "indexing"}}, + headers=self.headers) + + def test_search_does_not_fail(self): + resp = self.app.get("/buckets/bid/collections/cid/records", + headers=self.headers) + assert len(resp.json["data"]) == 1 + + resp = self.app.get("/buckets/bid/collections/cid/search", + headers=self.headers) + results = resp.json + assert len(results["hits"]["hits"]) == 0 + + def test_record_creation_does_not_fail(self): + self.app.post_json("/buckets/bid/collections/cid/records", + {"data": {"after": "indexing"}}, + headers=self.headers) + + resp = self.app.get("/buckets/bid/collections/cid/search", + headers=self.headers) + results = resp.json + assert len(results["hits"]["hits"]) == 1 + assert results["hits"]["hits"][0]["_source"]["after"] == "indexing" + + class RecordIndexing(BaseWebTest, unittest.TestCase): def setUp(self):