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

Tests of products api filters and sorting #94

Merged
merged 4 commits into from
Apr 9, 2024
Merged
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
2 changes: 1 addition & 1 deletion Dshop/apps/products_catalogue/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def filter_availability(self, queryset, name, value):
value = int(value)
if value in (1, 3, 7, 14):
return queryset.filter(availability__lte=value)
return queryset.filter(**{name: value})
return queryset.filter(availability=value)

def __init__(self, *args, **kwargs):
super(ProductFilter, self).__init__(*args, **kwargs)
Expand Down
33 changes: 21 additions & 12 deletions Dshop/apps/products_catalogue/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import datetime
from decimal import Decimal
import pytest
from apps.products_catalogue.models import Category, Product


@pytest.fixture
def products():
category = Category.objects.create(name='Test Category', is_active=True)
products = []
for idx in range(1, 11):
created_at = datetime.datetime.now() - datetime.timedelta(seconds=idx)
Product.objects.create(
name=f"main product ${idx}",
category=category,
price=idx,
short_description="short desc inactive",
full_description="full_description inactive",
is_active=True,
availability=3,
created_at=created_at
)
prod = Product.objects.create(
name=f"main product ${idx}",
category=category,
price=idx,
short_description="short desc inactive",
full_description="full_description inactive",
is_active=True,
created_at=True,
availability=3,
)
products.append(prod)
return products


def expected_prod_set(prods):
return {(obj.id, obj.name, Decimal(obj.price), obj.category.id) for obj in prods}

def api_prod_set(response):
return {(el["id"], el["name"], Decimal(el["price"]), el["category"]) for el in response.data["results"]}
161 changes: 161 additions & 0 deletions Dshop/apps/products_catalogue/tests/test_api_product_filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
from decimal import Decimal
from django.urls import reverse
import pytest
from rest_framework.test import APIClient
from apps.products_catalogue.tests.conftest import api_prod_set, expected_prod_set
from apps.products_catalogue.models import Category


URL = reverse("products-api-list")
pytestmark = pytest.mark.django_db


@pytest.fixture
def named_products(products):
yanazPL marked this conversation as resolved.
Show resolved Hide resolved
for prod, name in zip(products, "JABIGCFHED"):
prod.name = name
prod.save()
return products

def test_products_api_order_by_price_asc(products):
response = APIClient().get(f"{URL}?order_by=price")
products_data = response.data["results"]
assert response.status_code == 200
assert response.data["count"] == 10
for value, prod in enumerate(products_data, start=1):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about 0 record?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

record 0 is there, but it's price is 1

assert Decimal(prod["price"]) == Decimal(value)

def test_products_api_order_by_price_desc(products):
response = APIClient().get(f"{URL}?order_by=-price")
products_data = response.data["results"]
assert response.status_code == 200
assert response.data["count"] == 10
for value, prod in zip(range(10, 5, -1), products_data):
assert Decimal(prod["price"]) == Decimal(value)

def test_products_api_filter_by_name(products):
response = APIClient().get(f"{URL}?name=main+product+$10")
products_data = response.data["results"]
assert response.status_code == 200
assert len(products_data) == 1
assert products_data[0]["name"] == "main product $10"

def test_products_api_filter_by_price(products):
PRICE = 10
response = APIClient().get(f"{URL}?price={PRICE}")
assert response.status_code == 200
assert len(response.data["results"]) == 1
assert Decimal(response.data["results"][0]["price"]) == PRICE
assert response.data["results"][0]["name"] == "main product $10"

@pytest.mark.parametrize("availability, other_availability", [
(1, 99),
(3, 99),
(7, 99),
(14, 99),
(90, 99),
(99, 1),
(110, 99)
])
def test_products_api_filter_by_availability(products, availability, other_availability):
for prod in products[5:]:
prod.availability = other_availability
prod.save()
remaining_products = products[:5]
for prod in remaining_products:
prod.availability = availability
prod.save()
response = APIClient().get(f"{URL}?availability={availability}")
expected_result = expected_prod_set(remaining_products)
api_results = api_prod_set(response)
assert response.status_code == 200
assert len(response.data["results"]) == 5
assert expected_result == api_results

@pytest.mark.parametrize("target_availability, expected_count", [
(1, 2),
(3, 4),
(7, 7),
(14, 10),
])
def test_products_api_filters_by_availability_days(products, target_availability, expected_count):
for prod, availability in zip(products, [1, 1, 3, 3, 7, 7, 7, 14, 14, 14]):
prod.availability = availability
prod.save()
response = APIClient().get(f"{URL}?availability={target_availability}")
assert response.status_code == 200
assert response.data["count"] == expected_count

def test_products_api_filters_availability_by_category(products, api_client):
other_cat = Category.objects.create(name="Test Category 2")
for prod in products[5:]:
prod.category = other_cat
prod.save()
response_1 = api_client.get(f"{URL}?category_name=Test+Category")
response_2 = api_client.get(f"{URL}?category_name=Test+Category+2")
api_result_1 = api_prod_set(response_1)
api_result_2 = api_prod_set(response_2)
expected_result_1 = expected_prod_set(products[:5])
expected_result_2 = expected_prod_set(products[5:])
assert response_1.status_code == 200
assert response_2.status_code == 200
assert len(response_1.data["results"]) == 5
assert len(response_2.data["results"]) == 5
assert response_1.data["count"] == 5
assert response_2.data["count"] == 5
assert api_result_1 == expected_result_1
assert api_result_2 == expected_result_2

def test_products_api_filters_price_lt(products):
MAX_PRICE = Decimal("5.5")
expected_results = expected_prod_set(products[:5])
response = APIClient().get(f"{URL}?price__lt={MAX_PRICE}")
api_results = api_prod_set(response)
assert response.status_code == 200
assert len(response.data["results"]) == 5
assert api_results == expected_results

def test_products_api_filters_price_gt(products):
MIN_PRICE = Decimal("5.5")
expected_results = expected_prod_set(products[5:])
response = APIClient().get(f"{URL}?price__gt={MIN_PRICE}")
api_results = api_prod_set(response)
assert response.status_code == 200
assert len(response.data["results"]) == 5
assert api_results == expected_results

def test_products_api_order_by_name_asc(named_products):
response = APIClient().get(f"{URL}?order_by=name")
assert response.status_code == 200
assert len(response.data["results"]) == 5
for name, el in zip("ABCDE", response.data["results"]):
assert name == el["name"]

def test_products_api_order_by_name_desc(named_products):
response = APIClient().get(f"{URL}?order_by=-name")
assert response.status_code == 200
assert len(response.data["results"]) == 5
for name, el in zip("JIHGF", response.data["results"]):
assert name == el["name"]

def test_products_api_oder_by_created_at_desc(products):
response = APIClient().get(f"{URL}?order_by=-created_at")
expected_results = [products[9], products[8], products[7], products[6], products[5]]
assert response.status_code == 200
assert len(response.data["results"]) == 5
for obj, el in zip(expected_results, response.data["results"]):
assert obj.id == el["id"]
assert obj.name == el["name"]
assert Decimal(obj.price) == Decimal(el["price"])
assert obj.category.id == el["category"]

def test_products_api_oder_by_created_at_asc(products):
response = APIClient().get(f"{URL}?order_by=created_at")
expected_results = products[:5]
assert response.status_code == 200
assert len(response.data["results"]) == 5
for obj, el in zip(expected_results, response.data["results"]):
assert obj.id == el["id"]
assert obj.name == el["name"]
assert Decimal(obj.price) == Decimal(el["price"])
assert obj.category.id == el["category"]
Loading