diff --git a/backoffice/backoffice/workflows/api/views.py b/backoffice/backoffice/workflows/api/views.py index 734af996..6e4a1b77 100644 --- a/backoffice/backoffice/workflows/api/views.py +++ b/backoffice/backoffice/workflows/api/views.py @@ -1,7 +1,15 @@ import logging from django.shortcuts import get_object_or_404 +from django_elasticsearch_dsl_drf.filter_backends import ( + CompoundSearchFilterBackend, + DefaultOrderingFilterBackend, + FacetedSearchFilterBackend, + FilteringFilterBackend, + OrderingFilterBackend, +) from django_elasticsearch_dsl_drf.viewsets import BaseDocumentViewSet +from opensearch_dsl import TermsFacet from rest_framework import status, viewsets from rest_framework.decorators import action from rest_framework.response import Response @@ -150,13 +158,49 @@ def __init__(self, *args, **kwargs): document = WorkflowDocument serializer_class = WorkflowSerializer pagination_class = OSStandardResultsSetPagination - + filter_backends = [ + DefaultOrderingFilterBackend, + CompoundSearchFilterBackend, + FacetedSearchFilterBackend, + FilteringFilterBackend, + OrderingFilterBackend, + ] search_fields = { "workflow_type", "status", "is_update", } - ordering = ["_updated_at"] + + filter_fields = {"status": "status", "workflow_type": "workflow_type"} + + ordering_fields = {"_updated_at": "_updated_at"} + + ordering = ("-_updated_at",) + + faceted_search_fields = { + "status": { + "field": "status.keyword", + "facet": TermsFacet, + "options": { + "size": 10, + "order": { + "_key": "asc", + }, + }, + "enabled": True, + }, + "workflow_type": { + "field": "workflow_type.keyword", + "facet": TermsFacet, + "options": { + "size": 10, + "order": { + "_key": "asc", + }, + }, + "enabled": True, + }, + } def get_serializer_class(self): return WorkflowDocumentSerializer diff --git a/backoffice/backoffice/workflows/tests/test_views.py b/backoffice/backoffice/workflows/tests/test_views.py index 70b59a8b..139c77c2 100644 --- a/backoffice/backoffice/workflows/tests/test_views.py +++ b/backoffice/backoffice/workflows/tests/test_views.py @@ -1,5 +1,7 @@ import uuid +import dateutil +import dateutil.parser import pytest from django.apps import apps from django.contrib.auth import get_user_model @@ -362,3 +364,98 @@ def test_restart_with_params(self): url, json={"params": {"workflow_id": self.workflow.id}} ) self.assertEqual(response.status_code, 200) + + +class TestWorkflowSearchFilterViewSet(BaseTransactionTestCase): + endpoint = "/api/workflows/search/" + reset_sequences = True + fixtures = ["backoffice/fixtures/groups.json"] + + def setUp(self): + super().setUp() + + Workflow.objects.create( + data={}, + status=StatusChoices.APPROVAL, + core=True, + is_update=False, + workflow_type=WorkflowType.AUTHOR_CREATE, + ) + Workflow.objects.create( + data={}, + status=StatusChoices.RUNNING, + core=True, + is_update=False, + workflow_type=WorkflowType.AUTHOR_CREATE, + ) + + def test_facets(self): + self.api_client.force_authenticate(user=self.admin) + + response = self.api_client.get(reverse("search:workflow-list")) + + assert "_filter_status" in response.json()["facets"] + assert "_filter_workflow_type" in response.json()["facets"] + + def test_search_status(self): + self.api_client.force_authenticate(user=self.admin) + + url = ( + reverse("search:workflow-list") + f"?search=status:{StatusChoices.RUNNING}" + ) + + response = self.api_client.get(url) + + for item in response.json()["results"]: + print(item["status"]) + assert item["status"] == StatusChoices.RUNNING + + def test_search_workflow_type(self): + self.api_client.force_authenticate(user=self.admin) + + url = ( + reverse("search:workflow-list") + + f"?search=workflow_type:{WorkflowType.HEP_CREATE}" + ) + + response = self.api_client.get(url) + + for item in response.json()["results"]: + print(item["workflow_type"]) + assert item["workflow_type"] == WorkflowType.HEP_CREATE + + def test_filter_status(self): + self.api_client.force_authenticate(user=self.admin) + + url = reverse("search:workflow-list") + f'?status="={StatusChoices.RUNNING}' + + response = self.api_client.get(url) + + for item in response.json()["results"]: + assert item["status"] == StatusChoices.RUNNING + + def test_filter_workflow_type(self): + self.api_client.force_authenticate(user=self.admin) + + url = ( + reverse("search:workflow-list") + + f'?workflow_type="={WorkflowType.AUTHOR_CREATE}' + ) + + response = self.api_client.get(url) + + for item in response.json()["results"]: + assert item["workflow_type"] == WorkflowType.AUTHOR_CREATE + + def test_ordering(self): + self.api_client.force_authenticate(user=self.admin) + + url = reverse("search:workflow-list") + "?ordering=-_updated_at" + response = self.api_client.get(url) + + previous_date = None + for item in response.json()["results"]: + cur_date = dateutil.parser.parse(item["_updated_at"]) + if previous_date is not None: + assert cur_date < previous_date + previous_date = cur_date