Skip to content

Commit d61028b

Browse files
Merge pull request #2755 from IFRCGo/feature/ops-learning-coverage
Add ops-learning-coverage endpoint with tests
2 parents 7a6983a + d6c018d commit d61028b

5 files changed

Lines changed: 74 additions & 1 deletion

File tree

assets

main/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
router.register(r"public-per-stats", per_views.CountryPublicPerStatsViewset, basename="public_country_per_stats")
138138
router.register(r"per-stats", per_views.CountryPerStatsViewset, basename="country_per_stats")
139139
router.register(r"ops-learning", per_views.OpsLearningViewset, basename="ops_learning")
140+
router.register(r"ops-learning-coverage", per_views.OpsLearningCoverageViewset, basename="ops_learning_coverage")
140141
router.register(r"per-document-upload", per_views.PerDocumentUploadViewSet, basename="per_document_upload")
141142

142143
router.register(r"personnel_deployment", deployment_views.PersonnelDeploymentViewset, basename="personnel_deployment")

per/drf_views.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
LatestCountryOverviewSerializer,
7979
ListNiceDocSerializer,
8080
NiceDocumentSerializer,
81+
OpsLearningCoverageSerializer,
8182
OpsLearningCSVSerializer,
8283
OpsLearningInSerializer,
8384
OpsLearningOrganizationTypeSerializer,
@@ -1495,6 +1496,21 @@ def stats(self, request):
14951496
return response.Response(OpsLearningStatSerializer(data).data)
14961497

14971498

1499+
class OpsLearningCoverageViewset(viewsets.ReadOnlyModelViewSet):
1500+
"""Public OpsLearning coverage with minimal fields."""
1501+
1502+
queryset = OpsLearning.objects.all()
1503+
permission_classes = [permissions.AllowAny]
1504+
serializer_class = OpsLearningCoverageSerializer
1505+
filterset_class = OpsLearningFilter
1506+
1507+
def get_queryset(self):
1508+
qs = super().get_queryset()
1509+
if OpsLearning.is_user_admin(self.request.user):
1510+
return qs
1511+
return qs.filter(is_validated=True)
1512+
1513+
14981514
class PerDocumentUploadViewSet(viewsets.ModelViewSet):
14991515
queryset = PerDocumentUpload.objects.all()
15001516
serializer_class = PerDocumentUploadSerializer

per/serializers.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,15 @@ def get_document_name(self, obj):
11391139
return document.name
11401140

11411141

1142+
class OpsLearningCoverageSerializer(serializers.ModelSerializer):
1143+
class Meta:
1144+
model = OpsLearning
1145+
fields = (
1146+
"appeal_code",
1147+
"is_validated",
1148+
)
1149+
1150+
11421151
class PerDocumentUploadSerializer(serializers.ModelSerializer):
11431152
MAX_NUMBER_OF_DOCUMENTS = 10
11441153

per/test_views.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,3 +354,50 @@ def test_migrate_subcomponents(self):
354354
ops_learning.refresh_from_db()
355355
self.assertEqual(ops_learning.per_component.count(), 2)
356356
self.assertEqual(ops_learning.per_component_validated.count(), 2)
357+
358+
359+
class OpsLearningCoverageTestCase(APITestCase):
360+
361+
def setUp(self):
362+
super().setUp()
363+
country = CountryFactory.create()
364+
self.appeal1 = AppealFactory.create(code="APP-COV-1", country=country)
365+
self.appeal2 = AppealFactory.create(code="APP-COV-2", country=country)
366+
self.ops_learning1 = OpsLearningFactory.create(is_validated=True, appeal_code=self.appeal1)
367+
self.ops_learning2 = OpsLearningFactory.create(is_validated=False, appeal_code=self.appeal2)
368+
369+
def test_ops_learning_coverage_list(self):
370+
url = "/api/v2/ops-learning-coverage/"
371+
response = self.client.get(url)
372+
373+
self.assert_200(response)
374+
results = response.data["results"]
375+
self.assertEqual(len(results), 1)
376+
377+
result_keys = set(results[0].keys())
378+
self.assertEqual(result_keys, {"appeal_code", "is_validated"})
379+
380+
appeal_codes = {item["appeal_code"] for item in results}
381+
self.assertEqual(appeal_codes, {self.appeal1.code})
382+
383+
def test_ops_learning_coverage_list_admin(self):
384+
url = "/api/v2/ops-learning-coverage/"
385+
self.authenticate(self.ifrc_user)
386+
response = self.client.get(url)
387+
388+
self.assert_200(response)
389+
results = response.data["results"]
390+
self.assertEqual(len(results), 2)
391+
392+
appeal_codes = {item["appeal_code"] for item in results}
393+
self.assertEqual(appeal_codes, {self.appeal1.code, self.appeal2.code})
394+
395+
def test_ops_learning_coverage_filter_validated(self):
396+
url = "/api/v2/ops-learning-coverage/"
397+
response = self.client.get(url, {"is_validated": "true"})
398+
399+
self.assert_200(response)
400+
results = response.data["results"]
401+
self.assertEqual(len(results), 1)
402+
self.assertTrue(results[0]["is_validated"])
403+
self.assertEqual(results[0]["appeal_code"], self.appeal1.code)

0 commit comments

Comments
 (0)