Skip to content

Commit 57ec0c0

Browse files
authored
Merge pull request #1114 from NASA-IMPACT/3034-cosmos-api-test-cases
3034 cosmos api test cases
2 parents a739fd8 + a6c6d69 commit 57ec0c0

File tree

2 files changed

+267
-1
lines changed

2 files changed

+267
-1
lines changed

sde_collections/tests/test_apis.py

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