From 3060b3b5f83136538b08c3f7d09cefa0e08e33f8 Mon Sep 17 00:00:00 2001 From: Yohanna Lisnichuk Date: Fri, 13 Dec 2024 15:29:40 -0300 Subject: [PATCH 1/4] feat: add collection notes endpoint --- docs/_static/openapi.yaml | 20 ++++++++++++++++++++ process/views.py | 15 +++++++++++++++ tests/fixtures/complete_db.json | 4 ++++ tests/test_views.py | 20 ++++++++++++++++++++ 4 files changed, 59 insertions(+) diff --git a/docs/_static/openapi.yaml b/docs/_static/openapi.yaml index 4ad73f81..31fbe76c 100644 --- a/docs/_static/openapi.yaml +++ b/docs/_static/openapi.yaml @@ -123,6 +123,25 @@ paths: publication_policy: type: string description: '' + /api/collections/{id}/notes/: + get: + operationId: collections_notes_retrieve + description: Return the notes for the compiled collection and its parent collection. + parameters: + - in: path + name: id + schema: + type: integer + required: true + tags: + - collections + security: + - cookieAuth: [] + - basicAuth: [] + - {} + responses: + '200': + description: No response body /api/collections/{id}/tree/: get: operationId: collections_tree_list @@ -357,6 +376,7 @@ components: source_id: type: string description: If sourced from Scrapy, this should be the name of the spider. + pattern: ^([a-z]+_)*[a-z]+$ data_version: type: string format: date-time diff --git a/process/views.py b/process/views.py index 1a8e5df0..874541d9 100644 --- a/process/views.py +++ b/process/views.py @@ -232,6 +232,21 @@ def metadata(self, request, pk=None): return Response(metadata) + @action(detail=True) + def notes(self, request, pk=None): + """Return the notes for the compiled collection and its parent collection.""" + compiled_collection = get_object_or_404(Collection, pk=pk) + collection = compiled_collection.get_root_parent() + + if compiled_collection.transform_type != Collection.Transform.COMPILE_RELEASES: + return Response("The collection must be a compiled collection", status=status.HTTP_400_BAD_REQUEST) + + notes_db = CollectionNote.objects.filter(collection_id__in=[compiled_collection.id, collection.id]) + notes = {level: [] for level in CollectionNote.Level.values} # noqa: PD011 + for note in notes_db: + notes[note.code].append([note.note, note.data]) + return Response(notes) + @extend_schema(responses=TreeSerializer(many=True)) @action(detail=True) def tree(self, request, pk=None): diff --git a/tests/fixtures/complete_db.json b/tests/fixtures/complete_db.json index 7efc1a6f..13414d6a 100644 --- a/tests/fixtures/complete_db.json +++ b/tests/fixtures/complete_db.json @@ -80,6 +80,8 @@ "fields": { "collection": 1, "note": "adsfsdfsdsadf", + "code": "INFO", + "data": {}, "stored_at": "2020-12-29T13:50:28.589" } }, @@ -89,6 +91,8 @@ "fields": { "collection": 2, "note": "adsfsdfsdsadf", + "code": "WARNING", + "data": {}, "stored_at": "2020-12-29T13:50:28.597" } }, diff --git a/tests/test_views.py b/tests/test_views.py index 5817fb7f..4b5c152e 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -108,6 +108,26 @@ def test_destroy_ok(self): response = self.client.delete(f"{base_url}/1/") self.assertEqual(response.status_code, 202) + def test_notes_404(self): + response = self.client.get(f"{base_url}/900/notes/?format=json") + self.assertEqual(response.status_code, 404) + + def test_notes_not_compiled(self): + response = self.client.get(f"{base_url}/1/notes/?format=json") + self.assertEqual(response.status_code, 400) + + def test_notes_ok(self): + response = self.client.get(f"{base_url}/3/notes/?format=json") + self.assertEqual(response.status_code, 200) + self.assertJSONEqual( + response.content, + { + "INFO": [["adsfsdfsdsadf", {}]], + "ERROR": [], + "WARNING": [], + }, + ) + def test_retrieve_404(self): response = self.client.get(f"{base_url}/2/tree/") self.assertEqual(response.status_code, 404) From d8308994d78692a596e9feab493d92a300693cf3 Mon Sep 17 00:00:00 2001 From: James McKinney <26463+jpmckinney@users.noreply.github.com> Date: Fri, 13 Dec 2024 15:34:44 -0500 Subject: [PATCH 2/4] chore: Avoid one-time-use variable --- process/views.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/process/views.py b/process/views.py index 874541d9..3f2e788e 100644 --- a/process/views.py +++ b/process/views.py @@ -241,9 +241,8 @@ def notes(self, request, pk=None): if compiled_collection.transform_type != Collection.Transform.COMPILE_RELEASES: return Response("The collection must be a compiled collection", status=status.HTTP_400_BAD_REQUEST) - notes_db = CollectionNote.objects.filter(collection_id__in=[compiled_collection.id, collection.id]) - notes = {level: [] for level in CollectionNote.Level.values} # noqa: PD011 - for note in notes_db: + notes = {level: [] for level in CollectionNote.Level.values} # noqa: PD011 # false positive + for note in CollectionNote.objects.filter(collection_id__in=[compiled_collection.id, collection.id]): notes[note.code].append([note.note, note.data]) return Response(notes) From 09b7c71c5217382d0558b0d8ba0dc26862b521ec Mon Sep 17 00:00:00 2001 From: Yohanna Lisnichuk Date: Mon, 16 Dec 2024 16:50:40 -0300 Subject: [PATCH 3/4] fix: required root collection for notes endpoint --- process/views.py | 22 ++++++++++++++-------- tests/test_views.py | 12 ++++++------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/process/views.py b/process/views.py index 874541d9..ddd11ebc 100644 --- a/process/views.py +++ b/process/views.py @@ -234,14 +234,20 @@ def metadata(self, request, pk=None): @action(detail=True) def notes(self, request, pk=None): - """Return the notes for the compiled collection and its parent collection.""" - compiled_collection = get_object_or_404(Collection, pk=pk) - collection = compiled_collection.get_root_parent() - - if compiled_collection.transform_type != Collection.Transform.COMPILE_RELEASES: - return Response("The collection must be a compiled collection", status=status.HTTP_400_BAD_REQUEST) - - notes_db = CollectionNote.objects.filter(collection_id__in=[compiled_collection.id, collection.id]) + """Return the notes for the collection and its child collections.""" + root_collection = get_object_or_404(Collection, pk=pk) + if root_collection.transform_type: + return Response("The collection must be a root collection", status=status.HTTP_400_BAD_REQUEST) + compiled_collection = root_collection.get_compiled_collection() + upgraded_collection = root_collection.get_upgraded_collection() + + ids = [ + collection.id + for collection in [root_collection, compiled_collection, upgraded_collection] + if collection is not None + ] + + notes_db = CollectionNote.objects.filter(collection_id__in=ids) notes = {level: [] for level in CollectionNote.Level.values} # noqa: PD011 for note in notes_db: notes[note.code].append([note.note, note.data]) diff --git a/tests/test_views.py b/tests/test_views.py index 4b5c152e..b5452379 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -112,22 +112,22 @@ def test_notes_404(self): response = self.client.get(f"{base_url}/900/notes/?format=json") self.assertEqual(response.status_code, 404) - def test_notes_not_compiled(self): - response = self.client.get(f"{base_url}/1/notes/?format=json") - self.assertEqual(response.status_code, 400) - def test_notes_ok(self): - response = self.client.get(f"{base_url}/3/notes/?format=json") + response = self.client.get(f"{base_url}/1/notes/?format=json") self.assertEqual(response.status_code, 200) self.assertJSONEqual( response.content, { "INFO": [["adsfsdfsdsadf", {}]], "ERROR": [], - "WARNING": [], + "WARNING": [["adsfsdfsdsadf", {}]], }, ) + def test_notes_compiled(self): + response = self.client.get(f"{base_url}/3/notes/?format=json") + self.assertEqual(response.status_code, 400) + def test_retrieve_404(self): response = self.client.get(f"{base_url}/2/tree/") self.assertEqual(response.status_code, 404) From 01ad2678c4d029d42089109ca8c95e97875e35df Mon Sep 17 00:00:00 2001 From: Yohanna Lisnichuk Date: Mon, 16 Dec 2024 17:15:09 -0300 Subject: [PATCH 4/4] docs: update OpenAPI docs --- docs/_static/openapi.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_static/openapi.yaml b/docs/_static/openapi.yaml index 31fbe76c..45d8ef0f 100644 --- a/docs/_static/openapi.yaml +++ b/docs/_static/openapi.yaml @@ -126,7 +126,7 @@ paths: /api/collections/{id}/notes/: get: operationId: collections_notes_retrieve - description: Return the notes for the compiled collection and its parent collection. + description: Return the notes for the collection and its child collections. parameters: - in: path name: id