Skip to content

Commit 671a66a

Browse files
committed
✅(backend) tests
I am adding more tests Signed-off-by: charles <charles.englebert@protonmail.com>
1 parent 263e05c commit 671a66a

File tree

4 files changed

+203
-254
lines changed

4 files changed

+203
-254
lines changed

src/backend/core/tests/documents/test_api_documents_descendants_filters.py

Lines changed: 0 additions & 95 deletions
This file was deleted.
Lines changed: 74 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,56 @@
11
"""
2-
Tests for Documents API endpoint in impress's core app: list
2+
Tests for Documents API endpoint in impress's core app: search
33
"""
44

5-
import random
6-
from json import loads as json_loads
7-
8-
from django.test import RequestFactory
5+
from unittest import mock
96

107
import pytest
118
import responses
129
from faker import Faker
10+
from rest_framework import response as drf_response
1311
from rest_framework.test import APIClient
1412

15-
from core import factories, models
13+
from core import factories
1614
from core.services.search_indexers import get_document_indexer
1715

1816
fake = Faker()
1917
pytestmark = pytest.mark.django_db
2018

2119

22-
def build_search_url(**kwargs):
23-
"""Build absolute uri for search endpoint with ORDERED query arguments"""
24-
return (
25-
RequestFactory()
26-
.get("/api/v1.0/documents/search/", dict(sorted(kwargs.items())))
27-
.build_absolute_uri()
28-
)
29-
30-
31-
@pytest.mark.parametrize("role", models.LinkRoleChoices.values)
32-
@pytest.mark.parametrize("reach", models.LinkReachChoices.values)
3320
@responses.activate
34-
def test_api_documents_search_anonymous(reach, role, indexer_settings):
21+
def test_api_documents_search_anonymous(indexer_settings):
3522
"""
36-
Anonymous users should not be allowed to search documents whatever the
37-
link reach and link role
23+
Anonymous users should be allowed to search documents with Find.
3824
"""
3925
indexer_settings.SEARCH_INDEXER_QUERY_URL = "http://find/api/v1.0/search"
4026

41-
# Find response
27+
# mock Find response
4228
responses.add(
4329
responses.POST,
4430
"http://find/api/v1.0/search",
4531
json=[],
4632
status=200,
4733
)
4834

49-
response = APIClient().get("/api/v1.0/documents/search/", data={"q": "alpha"})
35+
with mock.patch(
36+
"core.services.search_indexers.FindDocumentIndexer.search_query"
37+
) as search_query:
38+
q = "alpha"
39+
response = APIClient().get("/api/v1.0/documents/search/", data={"q": q})
40+
41+
assert search_query.call_count == 1
42+
assert search_query.call_args[1] == {
43+
"data": {
44+
"q": q,
45+
"visited": [],
46+
"services": ["docs"],
47+
"nb_results": 50,
48+
"order_by": "updated_at",
49+
"order_direction": "desc",
50+
"path": None,
51+
},
52+
"token": None,
53+
}
5054

5155
assert response.status_code == 200
5256
assert response.json() == {
@@ -59,100 +63,76 @@ def test_api_documents_search_anonymous(reach, role, indexer_settings):
5963

6064
def test_api_documents_search_fall_back_on_search_list(indexer_settings):
6165
"""
62-
Missing SEARCH_INDEXER_QUERY_URL, so the indexer is not properly configured.
63-
Should fallback on title filter
66+
When indexer is not configured and no path is provided,
67+
should fall back on list method
6468
"""
6569
indexer_settings.SEARCH_INDEXER_QUERY_URL = None
66-
6770
assert get_document_indexer() is None
6871

6972
user = factories.UserFactory()
70-
document = factories.DocumentFactory(title="alpha")
71-
access = factories.UserDocumentAccessFactory(document=document, user=user)
72-
7373
client = APIClient()
7474
client.force_login(user)
7575

76-
response = client.get("/api/v1.0/documents/search/", data={"q": "alpha"})
76+
with mock.patch("core.api.viewsets.DocumentViewSet.list") as mock_list:
77+
mocked_response = {
78+
"count": 0,
79+
"next": None,
80+
"previous": None,
81+
"results": [{"title": "mocked list result"}],
82+
}
83+
mock_list.return_value = drf_response.Response(mocked_response)
7784

78-
assert response.status_code == 200
79-
content = response.json()
80-
results = content.pop("results")
81-
assert content == {
82-
"count": 1,
83-
"next": None,
84-
"previous": None,
85-
}
86-
assert len(results) == 1
87-
assert results[0] == {
88-
"id": str(document.id),
89-
"abilities": document.get_abilities(user),
90-
"ancestors_link_reach": None,
91-
"ancestors_link_role": None,
92-
"computed_link_reach": document.computed_link_reach,
93-
"computed_link_role": document.computed_link_role,
94-
"created_at": document.created_at.isoformat().replace("+00:00", "Z"),
95-
"creator": str(document.creator.id),
96-
"depth": 1,
97-
"excerpt": document.excerpt,
98-
"link_reach": document.link_reach,
99-
"link_role": document.link_role,
100-
"nb_accesses_ancestors": 1,
101-
"nb_accesses_direct": 1,
102-
"numchild": 0,
103-
"path": document.path,
104-
"title": document.title,
105-
"updated_at": document.updated_at.isoformat().replace("+00:00", "Z"),
106-
"deleted_at": None,
107-
"user_role": access.role,
108-
'is_favorite': False,
109-
}
85+
response = client.get("/api/v1.0/documents/search/", data={"q": "alpha"})
86+
87+
assert mock_list.call_count == 1
88+
assert mock_list.call_args[0][0].GET.get("title") == "alpha"
89+
90+
assert response.json() == mocked_response
11091

11192

11293
def test_api_documents_search_fallback_on_search_list_sub_docs(indexer_settings):
11394
"""
11495
When indexer is not configured and path parameter is provided,
115-
should use _list_sub_docs to filter by path and title
96+
should call _list_descendants() method
11697
"""
11798
indexer_settings.SEARCH_INDEXER_QUERY_URL = None
118-
11999
assert get_document_indexer() is None
120100

121101
user = factories.UserFactory()
122-
123-
# Create a parent document and children
124-
parent = factories.DocumentFactory(title="parent alpha", users=[user])
125-
child1 = factories.DocumentFactory(title="child alpha", parent=parent, users=[user])
126-
child2 = factories.DocumentFactory(title="child beta", parent=parent, users=[user])
127-
other = factories.DocumentFactory(title="other alpha", users=[user])
128-
129102
client = APIClient()
130103
client.force_login(user)
131104

132-
# Search with path filter - should return parent and child1 only
133-
response = client.get(
134-
"/api/v1.0/documents/search/",
135-
data={"q": "alpha", "path": parent.path}
136-
)
105+
parent = factories.DocumentFactory(title="parent", users=[user])
137106

138-
assert response.status_code == 200
139-
content = response.json()
140-
results = content["results"]
141-
142-
result_ids = {r["id"] for r in results}
143-
assert str(parent.id) in result_ids
144-
assert str(child1.id) in result_ids
145-
assert str(child2.id) not in result_ids
146-
assert str(other.id) not in result_ids
107+
with mock.patch(
108+
"core.api.viewsets.DocumentViewSet._list_descendants"
109+
) as mock_list_descendants:
110+
mocked_response = {
111+
"count": 0,
112+
"next": None,
113+
"previous": None,
114+
"results": [{"title": "mocked _list_descendants result"}],
115+
}
116+
mock_list_descendants.return_value = drf_response.Response(mocked_response)
117+
118+
response = client.get(
119+
"/api/v1.0/documents/search/", data={"q": "alpha", "path": parent.path}
120+
)
121+
122+
assert mock_list_descendants.call_count == 1
123+
assert mock_list_descendants.call_args[0][0].GET.get("title") == "alpha"
124+
assert mock_list_descendants.call_args[0][0].GET.get("path") == parent.path
125+
126+
assert response.json() == mocked_response
147127

148128

149129
@responses.activate
150130
def test_api_documents_search_invalid_params(indexer_settings):
151131
"""Validate the format of documents as returned by the search view."""
152132
indexer_settings.SEARCH_INDEXER_QUERY_URL = "http://find/api/v1.0/search"
133+
assert get_document_indexer() is not None
153134

154135
user = factories.UserFactory()
155-
156136
client = APIClient()
157137
client.force_login(user)
158138

@@ -161,34 +141,24 @@ def test_api_documents_search_invalid_params(indexer_settings):
161141
assert response.status_code == 400
162142
assert response.json() == {"q": ["This field is required."]}
163143

164-
response = client.get("/api/v1.0/documents/search/", data={"q": " "})
165-
166-
assert response.status_code == 400
167-
assert response.json() == {"q": ["This field may not be blank."]}
168-
169-
response = client.get(
170-
"/api/v1.0/documents/search/", data={"q": "any", "page": "NaN"}
171-
)
172-
173-
assert response.status_code == 400
174-
assert response.json() == {"page": ["A valid integer is required."]}
175-
176144

177145
@responses.activate
178-
def test_api_documents_search_format(indexer_settings):
146+
def test_api_documents_search_success(indexer_settings):
179147
"""Validate the format of documents as returned by the search view."""
180148
indexer_settings.SEARCH_INDEXER_QUERY_URL = "http://find/api/v1.0/search"
181-
182149
assert get_document_indexer() is not None
183150

184-
document={"id": "doc-123", "title": "alpha", "path": "path/to/alpha.pdf"}
151+
document = {"id": "doc-123", "title": "alpha", "path": "path/to/alpha.pdf"}
185152

186153
# Find response
187154
responses.add(
188155
responses.POST,
189156
"http://find/api/v1.0/search",
190157
json=[
191-
{"_id": str(document["id"]), "_source": {"title": document["title"], "path": document["path"]}},
158+
{
159+
"_id": str(document["id"]),
160+
"_source": {"title": document["title"], "path": document["path"]},
161+
},
192162
],
193163
status=200,
194164
)
@@ -202,5 +172,6 @@ def test_api_documents_search_format(indexer_settings):
202172
"next": None,
203173
"previous": None,
204174
}
205-
assert len(results) == 1
206-
assert results[0] == {'id': document["id"], 'title': document["title"], 'path': document["path"]}
175+
assert results == [
176+
{"id": document["id"], "title": document["title"], "path": document["path"]}
177+
]

0 commit comments

Comments
 (0)