from apps.orders.models import Order, OrderGroup from .base import OrdersTestCase class StatusTransitionTests(OrdersTestCase): def setUp(self): self.mock_external_clients() self.client.force_authenticate(user=self.customer) self.add_to_cart(self.product1, quantity=1) response = self.client.post('/api/v1/checkout/', { 'address_uuid': str(self.address.uuid), 'payment_method': OrderGroup.PaymentMethod.CASH_ON_DELIVERY, }) self.order = Order.objects.get(uuid=response.data['orders'][0]['uuid']) def _as_seller(self): self.client.force_authenticate(user=self.seller1) def test_seller_can_walk_the_full_status_stepper(self): self._as_seller() for action, expected_status in ( ('confirm', Order.Status.PREPARING), ('mark-ready', Order.Status.READY_TO_SHIP), ('mark-shipped', Order.Status.HANDED_TO_COURIER), ('mark-delivered', Order.Status.DELIVERED), ): response = self.client.post(f'/api/v1/seller/orders/{self.order.uuid}/{action}/') self.assertEqual(response.status_code, 200, response.data) self.order.refresh_from_db() self.assertEqual(self.order.status, expected_status) self.assertEqual(self.order.status_logs.count(), 5) # placed + 4 transitions def test_cannot_skip_a_status(self): self._as_seller() response = self.client.post(f'/api/v1/seller/orders/{self.order.uuid}/mark-delivered/') self.assertEqual(response.status_code, 409) def test_other_seller_cannot_act_on_this_order(self): self.client.force_authenticate(user=self.seller2) response = self.client.post(f'/api/v1/seller/orders/{self.order.uuid}/confirm/') self.assertEqual(response.status_code, 404) def test_customer_can_cancel_before_preparing(self): self.client.force_authenticate(user=self.customer) response = self.client.post(f'/api/v1/orders/{self.order.uuid}/cancel/') self.assertEqual(response.status_code, 200) self.order.refresh_from_db() self.assertEqual(self.order.status, Order.Status.CANCELLED) def test_cancelling_an_order_restocks_its_products(self): self.product1.refresh_from_db() stock_after_checkout = self.product1.stock_quantity sold_after_checkout = self.product1.sold_count self.assertEqual(stock_after_checkout, 49) # base.py seeds 50, checkout bought 1 self.assertEqual(sold_after_checkout, 1) self.client.force_authenticate(user=self.customer) response = self.client.post(f'/api/v1/orders/{self.order.uuid}/cancel/') self.assertEqual(response.status_code, 200) self.product1.refresh_from_db() self.assertEqual(self.product1.stock_quantity, stock_after_checkout + 1) self.assertEqual(self.product1.sold_count, sold_after_checkout - 1) def test_cancelling_after_confirm_also_restocks(self): self._as_seller() self.client.post(f'/api/v1/seller/orders/{self.order.uuid}/confirm/') self.client.post(f'/api/v1/seller/orders/{self.order.uuid}/cancel/') self.product1.refresh_from_db() self.assertEqual(self.product1.stock_quantity, 50) self.assertEqual(self.product1.sold_count, 0) def test_cannot_cancel_after_handed_to_courier(self): self._as_seller() for action in ('confirm', 'mark-ready', 'mark-shipped'): self.client.post(f'/api/v1/seller/orders/{self.order.uuid}/{action}/') self.client.force_authenticate(user=self.customer) response = self.client.post(f'/api/v1/orders/{self.order.uuid}/cancel/') self.assertEqual(response.status_code, 409)