From b2312edff571991ed5a9e06fba0b8d03ff0c7788 Mon Sep 17 00:00:00 2001 From: mono Date: Sat, 8 Aug 2026 13:28:44 -0500 Subject: [PATCH] test(#46): add order summary public and fill_codes tests --- .../tests/test_order_summary_public.py | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 tienda_ilusion/don_confiao/tests/test_order_summary_public.py diff --git a/tienda_ilusion/don_confiao/tests/test_order_summary_public.py b/tienda_ilusion/don_confiao/tests/test_order_summary_public.py new file mode 100644 index 0000000..fc96915 --- /dev/null +++ b/tienda_ilusion/don_confiao/tests/test_order_summary_public.py @@ -0,0 +1,193 @@ +from datetime import datetime, timezone + +from django.contrib.auth.models import User +from rest_framework import status +from rest_framework.test import APIClient, APITestCase + +from ..admin import CatalogSaleAdmin, SaleAdmin +from ..models.customers import Customer +from ..models.products import Product +from ..models.sales import CatalogSale, Sale +from .Mixins import LoginMixin + + +class TestOrderSummaryPublic(APITestCase, LoginMixin): + def setUp(self): + self.product = Product.objects.create( + name="Panela", price=5000, measuring_unit="UNIT" + ) + self.customer = Customer.objects.create( + name="Camilo", external_id="18" + ) + + def _create_sale(self): + sale = Sale.objects.create( + customer=self.customer, + date=datetime(2024, 9, 2, tzinfo=timezone.utc), + payment_method="CASH", + ) + sale.saleline_set.create( + product=self.product, quantity=2, unit_price=3000 + ) + return sale + + def _create_catalog_sale(self): + catalog_sale = CatalogSale.objects.create( + customer=self.customer, + date=datetime(2024, 9, 2, tzinfo=timezone.utc), + customer_name="Camilo", + ) + catalog_sale.catalogsaleline_set.create( + product=self.product, quantity=2, unit_price=3000 + ) + return catalog_sale + + def test_sale_has_auto_generated_code(self): + sale = self._create_sale() + self.assertTrue(sale.code) + self.assertEqual(len(sale.code), 32) + int(sale.code, 16) + + def test_sale_codes_are_distinct(self): + sale1 = self._create_sale() + sale2 = self._create_sale() + self.assertNotEqual(sale1.code, sale2.code) + + def test_catalog_sale_has_auto_generated_code(self): + catalog_sale = self._create_catalog_sale() + self.assertTrue(catalog_sale.code) + self.assertEqual(len(catalog_sale.code), 32) + int(catalog_sale.code, 16) + + def test_public_summary_by_code_without_auth(self): + sale = self._create_sale() + response = self.client.get( + f"/don_confiao/resumen_publico/{sale.code}" + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + data = response.json() + self.assertEqual(data["code"], sale.code) + self.assertIn("link", data) + self.assertTrue( + data["link"].endswith( + f"/don_confiao/resumen_publico/{sale.code}" + ) + ) + self.assertEqual(data["type"], "sale") + self.assertIn("lines", data) + self.assertGreaterEqual(len(data["lines"]), 1) + + def test_public_summary_invalid_code_returns_404(self): + response = self.client.get( + "/don_confiao/resumen_publico/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ) + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + + def test_public_summary_by_query_param(self): + sale = self._create_sale() + response = self.client.get( + "/don_confiao/resumen_publico", {"code": sale.code} + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.json()["code"], sale.code) + + def test_public_summary_for_catalog_sale(self): + catalog_sale = self._create_catalog_sale() + response = self.client.get( + f"/don_confiao/resumen_publico/{catalog_sale.code}" + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + data = response.json() + self.assertEqual(data["code"], catalog_sale.code) + self.assertEqual(data["type"], "catalog") + + def test_public_summary_with_duplicate_codes_does_not_500(self): + sale1 = self._create_sale() + sale2 = self._create_sale() + shared = "a" * 32 + Sale.objects.filter(pk__in=[sale1.pk, sale2.pk]).update(code=shared) + response = self.client.get( + f"/don_confiao/resumen_publico/{shared}" + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_existing_authenticated_summaries_include_code_and_link(self): + self.login() + sale = self._create_sale() + catalog_sale = self._create_catalog_sale() + + response = self.client.get( + f"/don_confiao/resumen_compra_json/{sale.id}" + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + data = response.json() + self.assertEqual(data["code"], sale.code) + self.assertIn("link", data) + + response = self.client.get( + f"/don_confiao/resumen_compra_catalogo_json/{catalog_sale.id}" + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + data = response.json() + self.assertEqual(data["code"], catalog_sale.code) + self.assertIn("link", data) + + def test_fill_codes_sales_endpoint_rewrites_all_codes(self): + self.login() + sale1 = self._create_sale() + sale2 = self._create_sale() + old_codes = {sale1.code, sale2.code} + + response = self.client.post("/don_confiao/api/sales/fill_codes/") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.json()["sales_updated"], 2) + + sale1.refresh_from_db() + sale2.refresh_from_db() + new_codes = {sale1.code, sale2.code} + self.assertNotIn(sale1.code, old_codes) + self.assertEqual(len(new_codes), 2) + + def test_fill_codes_catalog_sales_endpoint_rewrites_all_codes(self): + self.login() + catalog_sale = self._create_catalog_sale() + old_code = catalog_sale.code + + response = self.client.post( + "/don_confiao/api/catalog_sales/fill_codes/" + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.json()["catalog_sales_updated"], 1) + + catalog_sale.refresh_from_db() + self.assertNotEqual(catalog_sale.code, old_code) + + def test_fill_codes_endpoints_require_authentication(self): + response = self.client.post("/don_confiao/api/sales/fill_codes/") + self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) + + response = self.client.post( + "/don_confiao/api/catalog_sales/fill_codes/" + ) + self.assertEqual( + response.status_code, status.HTTP_401_UNAUTHORIZED + ) + + def test_fill_codes_endpoints_require_admin(self): + regular_user = User.objects.create_user( + username="regular", password="regularpass" + ) + client = APIClient() + client.force_authenticate(user=regular_user) + + response = client.post("/don_confiao/api/sales/fill_codes/") + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + response = client.post( + "/don_confiao/api/catalog_sales/fill_codes/" + ) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_admin_list_display_includes_code(self): + self.assertIn("code", SaleAdmin.list_display) + self.assertIn("code", CatalogSaleAdmin.list_display)