feat: added tests for orders creation

This commit is contained in:
2024-05-13 13:23:01 +02:00
parent 9d83c3b30f
commit d8fa4dd5e1
5 changed files with 224 additions and 5 deletions
+1 -1
View File
@@ -181,9 +181,9 @@ class OrderLineSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = OrderLine model = OrderLine
fields = ( fields = (
"id",
"product", "product",
"quantity", "quantity",
"order",
"price", "price",
"base_total", "base_total",
"total", "total",
+38 -1
View File
@@ -1,5 +1,9 @@
from decimal import Decimal
from django.db.models.deletion import ProtectedError from django.db.models.deletion import ProtectedError
from django.utils.text import gettext_lazy as _ from django.utils.text import gettext_lazy as _
from django.shortcuts import get_object_or_404
from django.db import transaction
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from rest_framework.exceptions import ValidationError from rest_framework.exceptions import ValidationError
@@ -101,5 +105,38 @@ class OrderLineViewSet(ModelViewSet):
serializer_class = OrderLineSerializer serializer_class = OrderLineSerializer
queryset = OrderLine.objects.all() queryset = OrderLine.objects.all()
def perform_create(self, serializer):
with transaction.atomic():
order = get_object_or_404(Order, uuid=self.kwargs.get('order_id'))
product = serializer.validated_data.get('product')
price = product.prices.last()
tax = price.tax.value
quantity = serializer.validated_data.get('quantity')
base_total = quantity * price.price
taxes = base_total * (tax / Decimal('100'))
total = base_total + taxes
instance = serializer.save(
order=order,
price=price.price,
base_total=base_total,
tax_value=tax,
taxes=taxes,
total=total,
)
order.base_total += instance.base_total
order.total += instance.total
order.save()
def perform_destroy(self, instance):
order = instance.order
with transaction.atomic():
order.base_total -= instance.base_total
order.total -= instance.total
instance.delete()
order.save()
def get_queryset(self): def get_queryset(self):
return super().get_queryset().filter(order_id=self.kwargs.get("order_id")) return super().get_queryset().select_related('order').filter(order__uuid=self.kwargs.get("order_id"))
+183
View File
@@ -0,0 +1,183 @@
from decimal import Decimal
from rest_framework import status
from rest_framework.test import APITestCase
from config.tests.mixins import TestUserAuthenticationMixin
from shop.models import Product, ProductPrice, Tax, Customer
class TestOrdersAPI(APITestCase, TestUserAuthenticationMixin):
model_name = "productprice"
def setUp(self):
self.create_user()
self.tax = Tax.objects.create(
code="IVA",
value=21,
)
self.customer = Customer.objects.create(
vat_id="11111111H",
first_name="Darth",
last_name="Maull",
email="darth@maul.com",
address="Dathomir",
city="Dathomir",
state="Dathomir",
country="Dathomir",
zip="00001",
)
self.create_products()
def create_products(self):
self.product = Product.objects.create(
name="Papafritas",
description="Las mejores papafritas",
is_digital_asset=False,
url="",
)
ProductPrice.objects.create(
product=self.product,
price=Decimal("1.20"),
tax=self.tax,
)
def test_create_retrieve_order(self):
self.login()
response = self.client.post(
f"/api/v1/shop/orders/",
{
"customer": self.customer.pk,
"billing_address": self.customer.address,
"billing_city": self.customer.city,
"billing_state": self.customer.state,
"billing_country": self.customer.country,
"billing_zip": self.customer.zip,
"shipping_address": self.customer.address,
"shipping_city": self.customer.city,
"shipping_state": self.customer.state,
"shipping_country": self.customer.country,
"shipping_zip": self.customer.zip,
"contact_phone": "612345678",
}
)
assert response.status_code == status.HTTP_201_CREATED
pk = response.data.get('uuid')
response = self.client.get(f"/api/v1/shop/orders/{pk}/")
assert response.status_code == status.HTTP_200_OK
def test_create_retrieve_order_with_lines(self):
self.login()
response = self.client.post(
f"/api/v1/shop/orders/",
{
"customer": self.customer.pk,
"billing_address": self.customer.address,
"billing_city": self.customer.city,
"billing_state": self.customer.state,
"billing_country": self.customer.country,
"billing_zip": self.customer.zip,
"shipping_address": self.customer.address,
"shipping_city": self.customer.city,
"shipping_state": self.customer.state,
"shipping_country": self.customer.country,
"shipping_zip": self.customer.zip,
"contact_phone": "612345678",
}
)
assert response.status_code == status.HTTP_201_CREATED
pk = response.data.get('uuid')
response = self.client.get(f"/api/v1/shop/orders/{pk}/")
assert response.status_code == status.HTTP_200_OK
assert Decimal(response.data.get('base_total')) == Decimal('0.00')
assert Decimal(response.data.get('total')) == Decimal('0.00')
response = self.client.post(
f"/api/v1/shop/orders/{pk}/lines/",
{
"product": self.product.pk,
"quantity": "5",
}
)
assert response.status_code == status.HTTP_201_CREATED
response = self.client.get(f"/api/v1/shop/orders/{pk}/lines/")
assert len(response.data.get('results')) == 1
response = self.client.get(f"/api/v1/shop/orders/{pk}/")
assert response.status_code == status.HTTP_200_OK
assert Decimal(response.data.get('base_total')) == Decimal('6.00')
assert Decimal(response.data.get('total')) == Decimal('6.00') + (Decimal('6.00') * Decimal('0.21'))
def test_create_delete_order_with_lines(self):
self.login()
# Create order
response = self.client.post(
f"/api/v1/shop/orders/",
{
"customer": self.customer.pk,
"billing_address": self.customer.address,
"billing_city": self.customer.city,
"billing_state": self.customer.state,
"billing_country": self.customer.country,
"billing_zip": self.customer.zip,
"shipping_address": self.customer.address,
"shipping_city": self.customer.city,
"shipping_state": self.customer.state,
"shipping_country": self.customer.country,
"shipping_zip": self.customer.zip,
"contact_phone": "612345678",
}
)
assert response.status_code == status.HTTP_201_CREATED
pk = response.data.get('uuid')
response = self.client.get(f"/api/v1/shop/orders/{pk}/")
assert response.status_code == status.HTTP_200_OK
# Assert order is created with 0.00€
assert Decimal(response.data.get('base_total')) == Decimal('0.00')
assert Decimal(response.data.get('total')) == Decimal('0.00')
# Create order line
response = self.client.post(
f"/api/v1/shop/orders/{pk}/lines/",
{
"product": self.product.pk,
"quantity": "5",
}
)
line_pk = response.data.get('id')
assert response.status_code == status.HTTP_201_CREATED
response = self.client.get(f"/api/v1/shop/orders/{pk}/lines/")
assert len(response.data.get('results')) == 1
response = self.client.get(f"/api/v1/shop/orders/{pk}/")
assert response.status_code == status.HTTP_200_OK
# Assert order totals are set
assert Decimal(response.data.get('base_total')) == Decimal('6.00')
assert Decimal(response.data.get('total')) == Decimal('6.00') + (Decimal('6.00') * Decimal('0.21'))
# Delete line
response = self.client.delete(f"/api/v1/shop/orders/{pk}/lines/{line_pk}/")
assert response.status_code == status.HTTP_204_NO_CONTENT
response = self.client.get(f"/api/v1/shop/orders/{pk}/")
assert response.status_code == status.HTTP_200_OK
# Assert order totals are 0.00
assert Decimal(response.data.get('base_total')) == Decimal('0.00')
assert Decimal(response.data.get('total')) == Decimal('0.00')
+1 -1
View File
@@ -4,7 +4,7 @@ from rest_framework import status
from rest_framework.test import APITestCase from rest_framework.test import APITestCase
from config.tests.mixins import TestUserAuthenticationMixin from config.tests.mixins import TestUserAuthenticationMixin
from shop.models import Product, ProductBatch from shop.models import Product
class TestProductBatchesAPI(APITestCase, TestUserAuthenticationMixin): class TestProductBatchesAPI(APITestCase, TestUserAuthenticationMixin):
+1 -2
View File
@@ -2,10 +2,9 @@ from decimal import Decimal
from rest_framework import status from rest_framework import status
from rest_framework.test import APITestCase from rest_framework.test import APITestCase
from django.utils import timezone
from config.tests.mixins import TestUserAuthenticationMixin from config.tests.mixins import TestUserAuthenticationMixin
from shop.models import Product, ProductPrice, Tax, ProductBatch from shop.models import Product, ProductPrice, Tax
class TestProductPricessAPI(APITestCase, TestUserAuthenticationMixin): class TestProductPricessAPI(APITestCase, TestUserAuthenticationMixin):