winofy-backend/apps/orders/tests/test_status_transitions.py
Ali Asadi 52adc732fa Initial Winofy backend: marketplace core (no payment integration)
Django 6 + DRF resource server against the Gooyal accounts OAuth2 service,
matching the Winsoo ecosystem's conventions. Covers locations, stores,
catalog, cart, checkout/orders (with the multi-store-cart split and the
status stepper), reviews, and notifications, plus a demo-data seed command.

Payment integration (wallet debits, online gateway, seller payouts) is
intentionally left out here — see feature/payment.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-10 14:03:15 +03:30

60 lines
2.6 KiB
Python

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_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)