From 624f94823c1c17c8275006cfaa57a801406f8adc Mon Sep 17 00:00:00 2001 From: Ehouarn Date: Fri, 31 Oct 2025 17:48:24 +0100 Subject: [PATCH] Tests --- apps/food/models.py | 2 +- apps/food/tests/__init__.py | 0 apps/food/tests/test_food.py | 253 ++++++++++++++++++++++++++++++++++- apps/treasury/views.py | 1 - 4 files changed, 251 insertions(+), 5 deletions(-) create mode 100644 apps/food/tests/__init__.py diff --git a/apps/food/models.py b/apps/food/models.py index abbea83d..64e4c654 100644 --- a/apps/food/models.py +++ b/apps/food/models.py @@ -256,7 +256,7 @@ class TransformedFood(Food): self.allergens.set(self.allergens.union(child.allergens.all())) if not (child.polymorphic_ctype.model == 'basicfood' and child.date_type == 'DDM'): self.expiry_date = min(self.expiry_date, child.expiry_date) - return super().save(force_insert, force_update, using, update_fields) + return super().save(force_insert=False, force_update=force_update, using=using, update_fields=update_fields) class Meta: verbose_name = _('Transformed food') diff --git a/apps/food/tests/__init__.py b/apps/food/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/apps/food/tests/test_food.py b/apps/food/tests/test_food.py index 9c314bf7..d7390861 100644 --- a/apps/food/tests/test_food.py +++ b/apps/food/tests/test_food.py @@ -6,9 +6,12 @@ from django.contrib.auth.models import User from django.test import TestCase from django.urls import reverse from django.utils import timezone +from activity.models import Activity, ActivityType +from member.models import Club -from ..api.views import AllergenViewSet, BasicFoodViewSet, TransformedFoodViewSet, QRCodeViewSet -from ..models import Allergen, BasicFood, TransformedFood, QRCode +from ..api.views import AllergenViewSet, BasicFoodViewSet, TransformedFoodViewSet, QRCodeViewSet, \ + DishViewSet, SupplementViewSet, OrderViewSet, FoodTransactionViewSet +from ..models import Allergen, BasicFood, TransformedFood, QRCode, Dish, Supplement, Order, FoodTransaction class TestFood(TestCase): @@ -117,9 +120,229 @@ class TestFood(TestCase): self.assertEqual(response.status_code, 200) +class TestFoodOrder(TestCase): + """ + Test Food Order + """ + fixtures = ('initial',) + + def setUp(self): + self.user = User.objects.create_superuser( + username='admintoto', + password='toto1234', + email='toto@example.com' + ) + self.client.force_login(self.user) + + sess = self.client.session + sess['permission_mask'] = 42 + sess.save() + + self.basicfood = BasicFood.objects.create( + id=1, + name='basicfood', + owner=Club.objects.get(name="BDE"), + expiry_date=timezone.now(), + is_ready=True, + date_type='DLC', + ) + + self.transformedfood = TransformedFood.objects.create( + id=2, + name='transformedfood', + owner=Club.objects.get(name="BDE"), + expiry_date=timezone.now(), + is_ready=True, + ) + + self.second_transformedfood = TransformedFood.objects.create( + id=3, + name='second transformedfood', + owner=Club.objects.get(name="BDE"), + expiry_date=timezone.now(), + is_ready=True, + ) + + self.third_transformedfood = TransformedFood.objects.create( + id=4, + name='third transformedfood', + owner=Club.objects.get(name="BDE"), + expiry_date=timezone.now(), + is_ready=True, + ) + + self.activity = Activity.objects.create( + activity_type=ActivityType.objects.get(name="Perm bouffe"), + organizer=Club.objects.get(name="BDE"), + creater=self.user, + attendees_club_id=1, + date_start=timezone.now(), + date_end=timezone.now(), + name="Test activity", + open=True, + valid=True, + ) + + self.dish = Dish.objects.create( + main=self.transformedfood, + price=500, + activity=self.activity, + available=True, + ) + + self.second_dish = Dish.objects.create( + main=self.second_transformedfood, + price=1000, + activity=self.activity, + available=True, + ) + + self.supplement = Supplement.objects.create( + dish=self.dish, + food=self.basicfood, + price=100, + ) + + self.order = Order.objects.create( + user=self.user, + activity=self.activity, + dish=self.dish, + ) + self.order.supplements.add(self.supplement) + self.order.save() + + def test_dish_list(self): + """ + Try to display dish list + """ + response = self.client.get(reverse("food:dish_list", kwargs={"activity_pk": self.activity.pk})) + self.assertEqual(response.status_code, 200) + + def test_dish_create(self): + """ + Try to create a dish + """ + response = self.client.get(reverse("food:dish_create", kwargs={"activity_pk": self.activity.pk})) + self.assertEqual(response.status_code, 200) + + response = self.client.post(reverse("food:dish_create", kwargs={"activity_pk": self.activity.pk}), data={ + "main": self.third_transformedfood.pk, + "price": 4, + "activity": self.activity.pk, + "supplements-0-food": self.basicfood.pk, + "supplements-0-price": 0.5, + "supplements-TOTAL_FORMS": 1, + "supplements-INITIAL_FORMS": 0, + "supplements-MIN_NUM_FORMS": 0, + "supplements-MAX_NUM_FORMS": 1000, + }) + self.assertRedirects(response, reverse("food:dish_list", kwargs={"activity_pk": self.activity.pk}), 302, 200) + self.assertTrue(Dish.objects.filter(main=self.third_transformedfood).exists()) + self.assertTrue(Supplement.objects.filter(food=self.basicfood, price=50).exists()) + + def test_dish_update(self): + """ + Try to update a dish + """ + response = self.client.get(reverse("food:dish_update", kwargs={"activity_pk": self.activity.pk, "pk": self.dish.pk})) + self.assertEqual(response.status_code, 200) + + response = self.client.post(reverse("food:dish_update", kwargs={"activity_pk": self.activity.pk, "pk": self.dish.pk}), data={ + "price": 6, + "supplements-0-food": self.basicfood.pk, + "supplements-0-price": 1, + "supplements-1-food": self.basicfood.pk, + "supplements-1-price": 0.25, + "supplements-TOTAL_FORMS": 2, + "supplements-INITIAL_FORMS": 0, + "supplements-MIN_NUM_FORMS": 0, + "supplements-MAX_NUM_FORMS": 1000, + }) + self.assertRedirects(response, reverse("food:dish_detail", kwargs={"activity_pk": self.activity.pk, "pk": self.dish.pk}), 302, 200) + self.dish.refresh_from_db() + self.assertTrue(Dish.objects.filter(main=self.transformedfood, price=600).exists()) + self.assertTrue(Supplement.objects.filter(dish=self.dish, food=self.basicfood, price=25).exists()) + + def test_dish_detail(self): + """ + Try to display dish details + """ + response = self.client.get(reverse("food:dish_detail", kwargs={"activity_pk": self.activity.pk, "pk": self.dish.pk})) + self.assertEqual(response.status_code, 200) + + def test_dish_delete(self): + """ + Try to delete a dish + """ + response = self.client.get(reverse("food:dish_delete", kwargs={"activity_pk": self.activity.pk, "pk": self.dish.pk})) + self.assertEqual(response.status_code, 200) + + # Cannot delete already ordered Dish + response = self.client.delete(reverse("food:dish_delete", kwargs={"activity_pk": self.activity.pk, "pk": self.dish.pk})) + self.assertEqual(response.status_code, 403) + self.assertTrue(Dish.objects.filter(pk=self.dish.pk).exists()) + + # Can delete a Dish with no order + response = self.client.delete(reverse("food:dish_delete", kwargs={"activity_pk": self.activity.pk, "pk": self.second_dish.pk})) + self.assertRedirects(response, reverse("food:dish_list", kwargs={"activity_pk": self.activity.pk})) + self.assertFalse(Dish.objects.filter(pk=self.second_dish.pk).exists()) + + def test_order_food(self): + """ + Try to make an order + """ + response = self.client.get(reverse("food:order_create", kwargs={"activity_pk": self.activity.pk})) + self.assertEqual(response.status_code, 200) + + response = self.client.post(reverse("food:order_create", kwargs={"activity_pk": self.activity.pk}), data=dict( + user=self.user.pk, + activity=self.activity.pk, + dish=self.second_dish.pk, + supplements=self.supplement.pk + )) + self.assertRedirects(response, reverse("food:food_list")) + self.assertTrue(Order.objects.filter(user=self.user, dish=self.second_dish, activity=self.activity).exists()) + + def test_order_list(self): + """ + Try to display order list + """ + response = self.client.get(reverse("food:order_list", kwargs={"activity_pk": self.activity.pk})) + self.assertEqual(response.status_code, 200) + + def test_served_order_list(self): + """ + Try to display served order list + """ + response = self.client.get(reverse("food:served_order_list", kwargs={"activity_pk": self.activity.pk})) + self.assertEqual(response.status_code, 200) + + def test_serve_order(self): + """ + Try to serve an order, then to unserve it + """ + response = self.client.patch("/api/food/order/" + str(self.order.pk) + "/", data=dict( + served=True + ), content_type="application/json") + self.assertEqual(response.status_code, 200) + self.order.refresh_from_db() + self.assertTrue(Order.objects.filter(dish=self.dish, user=self.user, served=True).exists()) + self.assertIsNotNone(self.order.served_at) + + self.assertTrue(FoodTransaction.objects.filter(order=self.order, valid=True).exists()) + + response = self.client.patch("/api/food/order/" + str(self.order.pk) + "/", data=dict( + served=False + ), content_type="application/json") + self.assertEqual(response.status_code, 200) + self.assertTrue(Order.objects.filter(dish=self.dish, user=self.user, served=False).exists()) + + self.assertTrue(FoodTransaction.objects.filter(order=self.order, valid=False).exists()) + + class TestFoodAPI(TestAPI): def setUp(self) -> None: - super().setUP() + super().setUp() self.allergen = Allergen.objects.create( name='name', @@ -168,3 +391,27 @@ class TestFoodAPI(TestAPI): Load QRCode API page and test all filters and permissions """ self.check_viewset(QRCodeViewSet, '/api/food/qrcode/') + + def test_dish_api(self): + """ + Load Dish API page and test all filters and permissions + """ + self.check_viewset(DishViewSet, '/api/food/dish/') + + def test_supplement_api(self): + """ + Load Supplement API page and test all filters and permissions + """ + self.check_viewset(SupplementViewSet, '/api/food/supplement/') + + def test_order_api(self): + """ + Load Order API page and test all filters and permissions + """ + self.check_viewset(OrderViewSet, '/api/food/order/') + + def test_foodtransaction_api(self): + """ + Load FoodTransaction API page and test all filters and permissions + """ + self.check_viewset(FoodTransactionViewSet, '/api/food/foodtransaction/') diff --git a/apps/treasury/views.py b/apps/treasury/views.py index b3bfaf80..eb2fd0d7 100644 --- a/apps/treasury/views.py +++ b/apps/treasury/views.py @@ -74,7 +74,6 @@ class InvoiceCreateView(ProtectQuerysetMixin, ProtectedCreateView): # For each product, we save it formset = ProductFormSet(self.request.POST, instance=form.instance) - print(formset) if formset.is_valid(): for f in formset: # We don't save the product if the designation is not entered, ie. if the line is empty