Skip to content

Commit 1b23afa

Browse files
committed
API tests
1 parent 5306d32 commit 1b23afa

File tree

2 files changed

+265
-1
lines changed

2 files changed

+265
-1
lines changed

sde_collections/tests/test_apis.py

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
import pytest
2+
from django.urls import reverse
3+
from rest_framework import status
4+
5+
from sde_collections.tests.factories import (
6+
CollectionFactory,
7+
CuratedUrlFactory,
8+
DeltaUrlFactory,
9+
)
10+
11+
12+
@pytest.mark.django_db
13+
class TestDeltaURLAPIView:
14+
"""Test suite for the Delta URL API endpoints"""
15+
16+
def setup_method(self):
17+
"""Setup test data"""
18+
self.collection = CollectionFactory()
19+
20+
def test_delta_url_api_empty_list(self, client):
21+
"""Should return empty list when no delta URLs exist"""
22+
url = reverse("sde_collections:delta-url-api", kwargs={"config_folder": self.collection.config_folder})
23+
response = client.get(url)
24+
25+
assert response.status_code == status.HTTP_200_OK
26+
assert len(response.json()["results"]) == 0
27+
28+
def test_delta_url_api_with_data(self, client):
29+
"""Should return list of non-excluded delta URLs for given config folder"""
30+
delta_url1 = DeltaUrlFactory(collection=self.collection)
31+
32+
url = reverse("sde_collections:delta-url-api", kwargs={"config_folder": self.collection.config_folder})
33+
response = client.get(url)
34+
35+
assert response.status_code == status.HTTP_200_OK
36+
data = response.json()["results"]
37+
assert len(data) == 1
38+
assert data[0]["url"] == delta_url1.url
39+
expected_title = delta_url1.generated_title if delta_url1.generated_title else delta_url1.scraped_title
40+
assert data[0]["title"] == expected_title
41+
42+
def test_delta_url_api_wrong_config_folder(self, client):
43+
"""Should return empty list for non-existent config folder"""
44+
url = reverse("sde_collections:delta-url-api", kwargs={"config_folder": "nonexistent"})
45+
response = client.get(url)
46+
47+
assert response.status_code == status.HTTP_200_OK
48+
assert len(response.json()["results"]) == 0
49+
50+
def test_delta_url_api_serializer_fields(self, client):
51+
"""Should return all expected fields in serializer"""
52+
DeltaUrlFactory(collection=self.collection)
53+
54+
url = reverse("sde_collections:delta-url-api", kwargs={"config_folder": self.collection.config_folder})
55+
response = client.get(url)
56+
57+
assert response.status_code == status.HTTP_200_OK
58+
data = response.json()["results"][0]
59+
expected_fields = {"url", "title", "document_type", "file_extension", "tree_root"}
60+
assert set(data.keys()) == expected_fields
61+
62+
def test_delta_url_api_pagination(self, client):
63+
"""Should correctly paginate results when multiple URLs exist"""
64+
[DeltaUrlFactory(collection=self.collection) for _ in range(15)]
65+
66+
url = reverse("sde_collections:delta-url-api", kwargs={"config_folder": self.collection.config_folder})
67+
response = client.get(url)
68+
69+
assert response.status_code == status.HTTP_200_OK
70+
data = response.json()
71+
assert "next" in data
72+
assert "previous" in data
73+
assert "count" in data
74+
assert data["count"] == 15
75+
76+
77+
@pytest.mark.django_db
78+
class TestCuratedURLAPIView:
79+
"""Test suite for the Curated URL API endpoints"""
80+
81+
def setup_method(self):
82+
"""Setup test data"""
83+
self.collection = CollectionFactory()
84+
85+
def test_curated_url_api_empty_list(self, client):
86+
"""Should return empty list when no curated URLs exist"""
87+
url = reverse("sde_collections:curated-url-api", kwargs={"config_folder": self.collection.config_folder})
88+
response = client.get(url)
89+
90+
assert response.status_code == status.HTTP_200_OK
91+
assert len(response.json()["results"]) == 0
92+
93+
def test_curated_url_api_with_data(self, client):
94+
"""Should return list of curated URLs for given config folder"""
95+
curated_url1 = CuratedUrlFactory(collection=self.collection, generated_title="Test Generated Title")
96+
97+
url = reverse("sde_collections:curated-url-api", kwargs={"config_folder": self.collection.config_folder})
98+
response = client.get(url)
99+
100+
assert response.status_code == status.HTTP_200_OK
101+
data = response.json()["results"]
102+
assert len(data) == 1
103+
assert data[0]["url"] == curated_url1.url
104+
assert data[0]["title"] == curated_url1.generated_title
105+
106+
def test_curated_url_api_wrong_config_folder(self, client):
107+
"""Should return empty list for non-existent config folder"""
108+
url = reverse("sde_collections:curated-url-api", kwargs={"config_folder": "nonexistent"})
109+
response = client.get(url)
110+
111+
assert response.status_code == status.HTTP_200_OK
112+
assert len(response.json()["results"]) == 0
113+
114+
def test_curated_url_api_serializer_fields(self, client):
115+
"""Should return all expected fields in serializer"""
116+
CuratedUrlFactory(collection=self.collection)
117+
118+
url = reverse("sde_collections:curated-url-api", kwargs={"config_folder": self.collection.config_folder})
119+
response = client.get(url)
120+
121+
assert response.status_code == status.HTTP_200_OK
122+
data = response.json()["results"][0]
123+
expected_fields = {"url", "title", "document_type", "file_extension", "tree_root"}
124+
assert set(data.keys()) == expected_fields
125+
126+
def test_candidate_url_api_alias(self, client):
127+
"""Should verify candidate-urls-api endpoint aliases to curated-urls-api"""
128+
curated_url = CuratedUrlFactory(collection=self.collection, generated_title="Test Generated Title")
129+
130+
curated_url = reverse(
131+
"sde_collections:curated-url-api", kwargs={"config_folder": self.collection.config_folder}
132+
)
133+
candidate_url = reverse(
134+
"sde_collections:candidate-url-api", kwargs={"config_folder": self.collection.config_folder}
135+
)
136+
137+
curated_response = client.get(curated_url)
138+
candidate_response = client.get(candidate_url)
139+
140+
assert curated_response.status_code == status.HTTP_200_OK
141+
assert candidate_response.status_code == status.HTTP_200_OK
142+
assert curated_response.json()["results"] == candidate_response.json()["results"]
143+
144+
def test_multiple_collections(self, client):
145+
"""Should only return URLs from the specified collection"""
146+
other_collection = CollectionFactory()
147+
148+
url1 = CuratedUrlFactory(collection=self.collection, generated_title="Test Generated Title 1")
149+
CuratedUrlFactory(collection=other_collection, generated_title="Test Generated Title 2")
150+
151+
url = reverse("sde_collections:curated-url-api", kwargs={"config_folder": self.collection.config_folder})
152+
response = client.get(url)
153+
154+
assert response.status_code == status.HTTP_200_OK
155+
data = response.json()["results"]
156+
assert len(data) == 1
157+
assert data[0]["url"] == url1.url
158+
assert data[0]["title"] == url1.generated_title
159+
160+
def test_curated_url_api_invalid_filters(self, client):
161+
"""Should handle invalid filter parameters gracefully"""
162+
CuratedUrlFactory(collection=self.collection)
163+
164+
url = reverse("sde_collections:curated-url-api", kwargs={"config_folder": self.collection.config_folder})
165+
response = client.get(f"{url}?invalid_filter=value")
166+
167+
assert response.status_code == status.HTTP_200_OK
168+
data = response.json()["results"]
169+
assert len(data) == 1
170+
171+
172+
@pytest.mark.django_db
173+
class TestCandidateURLAPIView:
174+
"""Test suite for the Candidate URL API endpoints. Note that this is an alias for Curated URL API"""
175+
176+
def setup_method(self):
177+
"""Setup test data"""
178+
self.collection = CollectionFactory()
179+
180+
def test_candidate_url_api_empty_list(self, client):
181+
"""Should return empty list when no candidate URLs exist"""
182+
url = reverse("sde_collections:candidate-url-api", kwargs={"config_folder": self.collection.config_folder})
183+
response = client.get(url)
184+
185+
assert response.status_code == status.HTTP_200_OK
186+
assert len(response.json()["results"]) == 0
187+
188+
def test_candidate_url_api_with_data(self, client):
189+
"""Should return list of candidate URLs for given config folder"""
190+
candidate_url1 = CuratedUrlFactory(collection=self.collection, generated_title="Test Generated Title")
191+
192+
url = reverse("sde_collections:candidate-url-api", kwargs={"config_folder": self.collection.config_folder})
193+
response = client.get(url)
194+
195+
assert response.status_code == status.HTTP_200_OK
196+
data = response.json()["results"]
197+
assert len(data) == 1
198+
assert data[0]["url"] == candidate_url1.url
199+
assert data[0]["title"] == candidate_url1.generated_title
200+
201+
def test_candidate_url_api_wrong_config_folder(self, client):
202+
"""Should return empty list for non-existent config folder"""
203+
url = reverse("sde_collections:candidate-url-api", kwargs={"config_folder": "nonexistent"})
204+
response = client.get(url)
205+
206+
assert response.status_code == status.HTTP_200_OK
207+
assert len(response.json()["results"]) == 0
208+
209+
def test_candidate_url_api_serializer_fields(self, client):
210+
"""Should return all expected fields in serializer"""
211+
CuratedUrlFactory(collection=self.collection)
212+
213+
url = reverse("sde_collections:candidate-url-api", kwargs={"config_folder": self.collection.config_folder})
214+
response = client.get(url)
215+
216+
assert response.status_code == status.HTTP_200_OK
217+
data = response.json()["results"][0]
218+
expected_fields = {"url", "title", "document_type", "file_extension", "tree_root"}
219+
assert set(data.keys()) == expected_fields
220+
221+
def test_candidate_url_api_alias(self, client):
222+
"""Should verify candidate-urls-api endpoint aliases to candidate-urls-api"""
223+
candidate_url = CuratedUrlFactory(collection=self.collection, generated_title="Test Generated Title")
224+
225+
candidate_url = reverse(
226+
"sde_collections:candidate-url-api", kwargs={"config_folder": self.collection.config_folder}
227+
)
228+
candidate_url = reverse(
229+
"sde_collections:candidate-url-api", kwargs={"config_folder": self.collection.config_folder}
230+
)
231+
232+
candidate_response = client.get(candidate_url)
233+
candidate_response = client.get(candidate_url)
234+
235+
assert candidate_response.status_code == status.HTTP_200_OK
236+
assert candidate_response.status_code == status.HTTP_200_OK
237+
assert candidate_response.json()["results"] == candidate_response.json()["results"]
238+
239+
def test_multiple_collections(self, client):
240+
"""Should only return URLs from the specified collection"""
241+
other_collection = CollectionFactory()
242+
243+
url1 = CuratedUrlFactory(collection=self.collection, generated_title="Test Generated Title 1")
244+
CuratedUrlFactory(collection=other_collection, generated_title="Test Generated Title 2")
245+
246+
url = reverse("sde_collections:candidate-url-api", kwargs={"config_folder": self.collection.config_folder})
247+
response = client.get(url)
248+
249+
assert response.status_code == status.HTTP_200_OK
250+
data = response.json()["results"]
251+
assert len(data) == 1
252+
assert data[0]["url"] == url1.url
253+
assert data[0]["title"] == url1.generated_title
254+
255+
def test_candidate_url_api_invalid_filters(self, client):
256+
"""Should handle invalid filter parameters gracefully"""
257+
CuratedUrlFactory(collection=self.collection)
258+
259+
url = reverse("sde_collections:candidate-url-api", kwargs={"config_folder": self.collection.config_folder})
260+
response = client.get(f"{url}?invalid_filter=value")
261+
262+
assert response.status_code == status.HTTP_200_OK
263+
data = response.json()["results"]
264+
assert len(data) == 1

sde_collections/urls.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
),
6363
path("curated-urls-api/<str:config_folder>/", view=views.CuratedURLAPIView.as_view(), name="curated-url-api"),
6464
path(
65-
"candidate-url-api/<str:config_folder>/",
65+
"candidate-urls-api/<str:config_folder>/",
6666
view=views.CuratedURLAPIView.as_view(),
6767
name="candidate-url-api",
6868
),

0 commit comments

Comments
 (0)