Skip to content

Commit

Permalink
Merge pull request #444 from maykinmedia/feature/324-objects-previous…
Browse files Browse the repository at this point in the history
…-records

don't show previous records available on some date
  • Loading branch information
annashamray authored Sep 18, 2024
2 parents 99fa73d + 2c3ff52 commit 9b7f37e
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 14 deletions.
6 changes: 4 additions & 2 deletions src/objects/api/v2/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ def filter_data_icontains(self, queryset, name, value: str):
return queryset.extra(where=[where_str], params=[value])

def filter_date(self, queryset, name, value: date_):
return queryset.filter_for_date(value)
"""actual filtering is performed in the viewset"""
return queryset

def filter_registration_date(self, queryset, name, value: date_):
return queryset.filter_for_registration_date(value)
"""actual filtering is performed in the viewset"""
return queryset
32 changes: 21 additions & 11 deletions src/objects/api/v2/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from django.conf import settings
from django.db import models
from django.utils.dateparse import parse_date

from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema, extend_schema_view
Expand All @@ -26,6 +27,7 @@
ObjectSerializer,
PermissionSerializer,
)
from ..utils import is_date
from .filters import ObjectRecordFilterSet


Expand Down Expand Up @@ -91,22 +93,30 @@ def get_queryset(self):

# show only allowed objects
base = base.filter_for_token(token_auth)

# show only actual objects
date = getattr(self.request, "query_params", {}).get("date", None)
registration_date = getattr(self.request, "query_params", {}).get(
"registrationDate", None
)
if not date and not registration_date:
base = base.filter_for_date(datetime.date.today())

return base

def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
# show only actual objects
if self.action in ("list", "search", "retrieve"):
date = getattr(self.request, "query_params", {}).get("date", None)
registration_date = getattr(self.request, "query_params", {}).get(
"registrationDate", None
)

if date and is_date(date):
queryset = queryset.filter_for_date(parse_date(date))
elif registration_date and is_date(registration_date):
queryset = queryset.filter_for_registration_date(
parse_date(registration_date)
)
else:
queryset = queryset.filter_for_date(datetime.date.today())

# keep only records with max index per object
return queryset.keep_max_record_per_object()
queryset = queryset.keep_max_record_per_object()

# filter on the rest of query params
return super().filter_queryset(queryset)

def perform_destroy(self, instance):
instance.object.delete()
Expand Down
133 changes: 132 additions & 1 deletion src/objects/tests/v2/test_object_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

from ..constants import GEO_WRITE_KWARGS
from ..utils import mock_objecttype, mock_objecttype_version, mock_service_oas_get
from .utils import reverse
from .utils import reverse, reverse_lazy

OBJECT_TYPES_API = "https://example.com/objecttypes/v1/"

Expand Down Expand Up @@ -492,3 +492,134 @@ def test_update_object_correctionFor(self, m):

last_record = object.last_record
self.assertIsNone(last_record.correct)


@freeze_time("2024-08-31")
class ObjectsAvailableRecordsTests(TokenAuthMixin, APITestCase):
"""
tests for https://github.com/maykinmedia/objects-api/issues/324
today = 31.08
Object X
record 1: startAt=01.08 endAt=31.08 attr=A
record 2: startAt=31.08 endAt=31.08 attr=B
if filter records on attr=A, no record should be shown
if no filter records on attr=A, record 2 should be shown
"""

url = reverse_lazy("object-list")

@classmethod
def setUpTestData(cls):
super().setUpTestData()

cls.object_type = ObjectTypeFactory.create(service__api_root=OBJECT_TYPES_API)
PermissionFactory.create(
object_type=cls.object_type,
mode=PermissionModes.read_and_write,
token_auth=cls.token_auth,
)

cls.object = ObjectFactory.create(object_type=cls.object_type)
ObjectRecordFactory.create(
object=cls.object,
data={"name": "old"},
start_at="2024-08-01",
end_at="2024-08-31",
registration_at="2024-08-02",
)
ObjectRecordFactory.create(
object=cls.object,
data={"name": "new"},
start_at="2024-08-31",
end_at="2024-08-31",
registration_at="2024-08-30",
)

@freeze_time("2024-08-31")
def test_list_available_today(self):
with self.subTest("filter on old name"):
response = self.client.get(self.url, {"data_attrs": "name__exact__old"})

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["count"], 0)

with self.subTest("without filter on old name"):
response = self.client.get(self.url)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["count"], 1)
object_data = response.json()["results"][0]
self.assertEqual(object_data["uuid"], str(self.object.uuid))
self.assertEqual(object_data["record"]["data"], {"name": "new"})

def test_list_available_for_date(self):
with self.subTest("filter on old name"):
response = self.client.get(
self.url, {"data_attrs": "name__exact__old", "date": "2024-08-31"}
)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["count"], 0)

with self.subTest("filter on old name and old date"):
response = self.client.get(
self.url, {"data_attrs": "name__exact__old", "date": "2024-08-30"}
)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["count"], 1)
object_data = response.json()["results"][0]
self.assertEqual(object_data["uuid"], str(self.object.uuid))
self.assertEqual(object_data["record"]["data"], {"name": "old"})

with self.subTest("without filter on old name"):
response = self.client.get(self.url, {"date": "2024-08-31"})

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["count"], 1)
object_data = response.json()["results"][0]
self.assertEqual(object_data["uuid"], str(self.object.uuid))
self.assertEqual(object_data["record"]["data"], {"name": "new"})

def test_list_incorrect_date(self):
response = self.client.get(self.url, {"date": "2024-31-08"})

self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.json(), {"date": ["Enter a valid date."]})

def test_list_available_for_registration_date(self):
with self.subTest("filter on old name"):
response = self.client.get(
self.url,
{"data_attrs": "name__exact__old", "registrationDate": "2024-08-31"},
)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["count"], 0)

with self.subTest("filter on old name and old date"):
response = self.client.get(self.url, {"registrationDate": "2024-08-29"})

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["count"], 1)
object_data = response.json()["results"][0]
self.assertEqual(object_data["uuid"], str(self.object.uuid))
self.assertEqual(object_data["record"]["data"], {"name": "old"})

with self.subTest("without filter on old name"):
response = self.client.get(self.url, {"registrationDate": "2024-08-31"})

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["count"], 1)
object_data = response.json()["results"][0]
self.assertEqual(object_data["uuid"], str(self.object.uuid))
self.assertEqual(object_data["record"]["data"], {"name": "new"})

def test_list_incorrect_registration_date(self):
response = self.client.get(self.url, {"registrationDate": "2024-31-08"})

self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.json(), {"registrationDate": ["Enter a valid date."]})

0 comments on commit 9b7f37e

Please sign in to comment.