from decimal import Decimal from django.contrib.auth import get_user_model from django.test import Client, TestCase from django.urls import reverse from shipping.models import Shipment from shipping.services import buy_label, create_shipment_for_order, pirate_ship_csv, quote_rates from shop.models import Order class ShippingServiceTests(TestCase): def setUp(self): self.order = Order.objects.create( number="ORD-20260101-001", email="buyer@example.com", customer_name="Pat Lee", status=Order.Status.PAID, amount=Decimal("18.00"), shipping_address={ "line1": "123 Main", "city": "Aurora", "state": "IL", "zip": "60506", "country": "US", }, ) def test_quote_and_buy_stub_label(self): shipment = create_shipment_for_order(self.order) rates = quote_rates(shipment) self.assertGreaterEqual(len(rates), 1) shipment.refresh_from_db() self.assertEqual(shipment.status, Shipment.Status.RATED) buy_label(shipment, rate_id=rates[0]["id"]) shipment.refresh_from_db() self.assertEqual(shipment.status, Shipment.Status.LABELED) self.assertTrue(shipment.tracking_number) def test_pirate_ship_csv_includes_unshipped(self): csv_body = pirate_ship_csv() self.assertIn("ORD-20260101-001", csv_body) self.assertIn("123 Main", csv_body) self.assertIn("buyer@example.com", csv_body) def test_csv_omits_labeled_orders(self): shipment = create_shipment_for_order(self.order) quote_rates(shipment) buy_label(shipment) self.assertNotIn(self.order.number, pirate_ship_csv()) class ShippingPortalTests(TestCase): def setUp(self): User = get_user_model() self.user = User.objects.create_user("shipper", password="test-pass-123") self.client = Client() self.client.login(username="shipper", password="test-pass-123") self.order = Order.objects.create( number="ORD-20260101-002", email="a@example.com", status=Order.Status.PAID, amount=Decimal("9.00"), shipping_address={"line1": "9 Oak", "city": "Town", "state": "IL", "zip": "60189"}, ) def test_list_requires_login(self): self.assertEqual(Client().get(reverse("shipping:shipment_list")).status_code, 302) def test_create_shipment_from_portal(self): response = self.client.post( reverse("shipping:shipment_create"), {"order": str(self.order.pk), "weight_oz": "8"}, ) self.assertEqual(response.status_code, 302) shipment = Shipment.objects.get() self.assertEqual(shipment.weight_oz, 8) self.assertEqual(shipment.status, Shipment.Status.RATED) def test_csv_export(self): response = self.client.get(reverse("shipping:pirate_ship_export")) self.assertEqual(response.status_code, 200) self.assertEqual(response["Content-Type"], "text/csv") self.assertIn(b"ORD-20260101-002", response.content)