Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix order filter date #999

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ and this project adheres to

## [Unreleased]

### Fixed

- Fix order filtering by creation date

## [2.12.0] - 2024-12-18

### Added
Expand Down
2 changes: 1 addition & 1 deletion src/backend/joanie/core/filters/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ class Meta:
field_name="product__type",
choices=enums.PRODUCT_TYPE_CHOICES,
)
created_on = filters.DateFilter(field_name="created_on", lookup_expr="exact")
created_on = filters.DateFilter(field_name="created_on", lookup_expr="date")
created_on_date_range = filters.DateFromToRangeFilter(field_name="created_on")

def filter_by_query(self, queryset, _name, value):
Expand Down
54 changes: 30 additions & 24 deletions src/backend/joanie/tests/core/api/admin/orders/test_list.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
"""Test suite for the admin orders API list endpoint."""

import uuid
from datetime import date
from datetime import date, datetime, timezone
from http import HTTPStatus
from unittest import mock

from django.conf import settings
from django.test import TestCase
from django.utils import timezone
from django.utils.datetime_safe import datetime as django_datetime

from joanie.core import enums, factories
from joanie.core.models import CourseState, Order
Expand All @@ -24,12 +22,20 @@ class OrdersAdminApiListTestCase(TestCase):
@staticmethod
def generate_orders_created_on(number: int, created_on=None):
"""Generate a batch of orders with a specific creation date."""
if created_on:
created_on = timezone.make_aware(created_on)
with mock.patch(
"django.utils.timezone.now", return_value=created_on or timezone.now()
):
return factories.OrderGeneratorFactory.create_batch(number)
orders = []
for _ in range(number):
if created_on:
created_on = datetime.combine(
created_on, datetime.now().time(), tzinfo=timezone.utc
)
with mock.patch(
"django.utils.timezone.now",
return_value=created_on or datetime.now(),
):
orders.append(factories.OrderFactory())
# orders default orderings are by creation date
orders.sort(key=lambda x: x.created_on, reverse=True)
return orders

def test_api_admin_orders_request_without_authentication(self):
"""
Expand Down Expand Up @@ -709,7 +715,7 @@ def test_api_admin_orders_list_filter_by_created_on_no_result(self):
"""
admin = factories.UserFactory(is_staff=True, is_superuser=True)
self.client.login(username=admin.username, password="password")
self.generate_orders_created_on(3, django_datetime(2024, 11, 30))
self.generate_orders_created_on(3, date(2024, 11, 30))

isoformat_searched_date = date(2024, 12, 1).isoformat() # YYYY-MM-DD

Expand All @@ -733,9 +739,9 @@ def test_api_admin_orders_list_filter_by_created_on(self):
# Create orders that are on runtime of this test
factories.OrderGeneratorFactory.create_batch(10)
# Create orders with a date in the past
self.generate_orders_created_on(4, django_datetime(2024, 2, 17))
self.generate_orders_created_on(4, date(2024, 2, 17))
# Create orders with the date we will query with
orders = self.generate_orders_created_on(3, django_datetime(2024, 11, 30))
orders = self.generate_orders_created_on(3, date(2024, 11, 30))

isoformat_searched_date = date(2024, 11, 30).isoformat() # YYYY-MM-DD

Expand Down Expand Up @@ -763,9 +769,9 @@ def test_api_admin_order_list_filter_by_created_on_before_and_after_date_no_resu
self.client.login(username=admin.username, password="password")

# Create orders with a date in the past
self.generate_orders_created_on(3, django_datetime(2024, 11, 20))
self.generate_orders_created_on(3, date(2024, 11, 20))
# Create orders with a date not inside the date range
self.generate_orders_created_on(2, django_datetime(2024, 12, 8))
self.generate_orders_created_on(2, date(2024, 12, 8))

isoformat_after_date = date(2024, 12, 1).isoformat()
isoformat_before_date = date(2024, 12, 7).isoformat()
Expand All @@ -790,12 +796,12 @@ def test_api_admin_order_list_filter_by_created_on_before_and_after(self): # py
self.client.login(username=admin.username, password="password")

# Create orders within the given range dates
orders_1 = self.generate_orders_created_on(3, django_datetime(2024, 11, 20))
orders_1 = self.generate_orders_created_on(3, date(2024, 11, 20))
# Create another batch within the given range dates
orders_2 = self.generate_orders_created_on(3, django_datetime(2024, 11, 30))
orders_2 = self.generate_orders_created_on(3, date(2024, 11, 30))
# Create orders that will be outside the range of the given dates
self.generate_orders_created_on(20, django_datetime(2024, 11, 9))
self.generate_orders_created_on(20, django_datetime(2024, 12, 2))
self.generate_orders_created_on(20, date(2024, 11, 9))
self.generate_orders_created_on(20, date(2024, 12, 2))

isoformat_after_date = date(2024, 11, 10).isoformat()
isoformat_before_date = date(2024, 12, 1).isoformat()
Expand Down Expand Up @@ -830,10 +836,10 @@ def test_api_admin_order_list_filter_by_created_on_date_range_only_with_after_da
self.client.login(username=admin.username, password="password")

# Create orders that will be outside the range of the given dates
self.generate_orders_created_on(10, django_datetime(2024, 11, 30))
self.generate_orders_created_on(10, date(2024, 11, 30))
# Create orders that are on the exact date and after the creation passed date in filter
orders_1 = self.generate_orders_created_on(2, django_datetime(2024, 12, 2))
orders_2 = self.generate_orders_created_on(2, django_datetime(2024, 12, 10))
orders_1 = self.generate_orders_created_on(2, date(2024, 12, 2))
orders_2 = self.generate_orders_created_on(2, date(2024, 12, 10))

isoformat_after_date = date(2024, 12, 2).isoformat()

Expand Down Expand Up @@ -867,10 +873,10 @@ def test_api_admin_order_list_filter_by_created_on_date_range_only_with_before_d
self.client.login(username=admin.username, password="password")

# Create orders that will match the filter before date in the query
orders_1 = self.generate_orders_created_on(2, django_datetime(2024, 11, 30))
orders_2 = self.generate_orders_created_on(3, django_datetime(2024, 11, 1))
orders_1 = self.generate_orders_created_on(2, date(2024, 11, 30))
orders_2 = self.generate_orders_created_on(3, date(2024, 11, 1))
# Create orders that are later than the passed before date
self.generate_orders_created_on(7, django_datetime(2024, 12, 2))
self.generate_orders_created_on(7, date(2024, 12, 2))

isoformat_before_date = date(2024, 11, 30).isoformat()

Expand Down
22 changes: 12 additions & 10 deletions src/backend/joanie/tests/core/test_api_certificate.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
"""Tests for the Certificate API"""

import uuid
from datetime import date, datetime, timezone
from http import HTTPStatus
from io import BytesIO
from unittest import mock

from django.utils import timezone
from django.utils.datetime_safe import datetime as django_datetime

from pdfminer.high_level import extract_text as pdf_extract_text
from rest_framework.pagination import PageNumberPagination

Expand All @@ -33,11 +31,13 @@ def generate_certificate_created_on_and_issued_on(
Generate a certificate for a user with a specific `created_on` date and `issued_on` date
"""
if created_on:
created_on = timezone.make_aware(created_on)
created_on = datetime.combine(
created_on, datetime.now().time(), tzinfo=timezone.utc
)

with mock.patch(
"django.utils.timezone.now",
return_value=created_on or timezone.now(),
return_value=created_on or datetime.now(),
):
certificate = factories.OrderCertificateFactory(
order=factories.OrderFactory(
Expand All @@ -46,7 +46,9 @@ def generate_certificate_created_on_and_issued_on(
)

if issued_on:
issued_on = timezone.make_aware(issued_on)
issued_on = datetime.combine(
issued_on, datetime.now().time(), tzinfo=timezone.utc
)
# Using the update method to by pass the auto_now and editable is False parameters
# on the field set on the model.
Certificate.objects.filter(pk=certificate.id).update(issued_on=issued_on)
Expand Down Expand Up @@ -79,16 +81,16 @@ def test_api_certificate_read_list_should_be_in_the_order_of_issued_on_field_val
factories.OrderCertificateFactory.create_batch(5)
# Create the certificates of the user
certificate_0 = self.generate_certificate_created_on_and_issued_on(
user, django_datetime(2024, 11, 12), django_datetime(2024, 11, 28)
user, date(2024, 11, 12), date(2024, 11, 28)
)
certificate_1 = self.generate_certificate_created_on_and_issued_on(
user, django_datetime(2024, 11, 13), django_datetime(2024, 11, 22)
user, date(2024, 11, 13), date(2024, 11, 22)
)
certificate_2 = self.generate_certificate_created_on_and_issued_on(
user, django_datetime(2024, 11, 15), django_datetime(2024, 11, 24)
user, date(2024, 11, 15), date(2024, 11, 24)
)
certificate_3 = self.generate_certificate_created_on_and_issued_on(
user, django_datetime(2024, 11, 15), django_datetime(2024, 11, 26)
user, date(2024, 11, 15), date(2024, 11, 26)
)

response = self.client.get(
Expand Down