seller_central_backend/api/test_shipping.py
2026-10-11 12:29:00 +05:30

238 lines
8.4 KiB
Python

import pytest
from unittest.mock import patch, MagicMock
from django.urls import reverse
from django.contrib.auth.models import User
from rest_framework import status
from rest_framework.test import APIClient
from api.models import Order, ReturnRequest, SupplierProfile
from api.shipping_client import ShippingServiceClient
@pytest.fixture
def api_client():
return APIClient()
@pytest.fixture
def create_seller(db):
user = User.objects.create_user(username='shipping_seller', email='shipping@example.com', password='Password123!')
profile = SupplierProfile.objects.create(
user=user,
phone='9123456789',
store_name='Artisan Handlooms Store',
street='Plot 45 Industrial Area',
pincode='560077',
city='Bengaluru',
state='Karnataka'
)
order = Order.objects.create(
supplier=user,
order_id='ORD-SHIP-1001',
date='2026-09-25',
item='Handloom Pashmina Shawl',
quantity=1,
customer='Rohan Sharma',
total=2499.00,
status='Pending Acceptance'
)
return_req = ReturnRequest.objects.create(
supplier=user,
return_id='RET-SHIP-5001',
order_id='ORD-SHIP-1001',
customer='Rohan Sharma',
item='Handloom Pashmina Shawl',
reason='Color did not match expectations.',
status='Pending Approval'
)
return user, order, return_req
@pytest.mark.django_db
def test_shipping_client_forward_flow():
client = ShippingServiceClient(use_mock=True)
# 1. Forward Serviceability Check
serv_res = client.check_forward_serviceability('560077,110009')
assert serv_res is not None
# 2. Track Forward Order
track_res = client.track_delivery_order('SFX9928374102')
assert track_res is not None
# 3. Cancel Forward Order
cancel_res = client.cancel_delivery_order('ORD-SHIP-1001', 'SFX9928374102', 'Customer requested cancel')
assert cancel_res is not None
@pytest.mark.django_db
def test_shipping_client_reverse_flow():
client = ShippingServiceClient(use_mock=True)
# 1. Reverse Serviceability Check
serv_res = client.check_reverse_serviceability('560103,110009')
assert serv_res is not None
# 2. Track Reverse Request
track_res = client.track_customer_return_pickup('RET-SHIP-5001')
assert track_res is not None
# 3. Update QC Flag
qc_res = client.update_return_qc('RET-SHIP-5001', qc_check=True, serial_number='SN-9988112233')
assert qc_res is not None
@pytest.mark.django_db
def test_order_accept_initiates_delivery_pickup(api_client, create_seller):
user, order, _ = create_seller
api_client.force_authenticate(user=user)
url = reverse('order-accept', args=[order.id])
response = api_client.post(url)
assert response.status_code == status.HTTP_200_OK
assert response.data['status'] == 'Ready to Ship'
assert response.data['carrier'] == 'Shadowfax Logistics'
assert response.data['tracking'].startswith('SFX')
order.refresh_from_db()
assert order.status == 'Ready to Ship'
assert order.carrier == 'Shadowfax Logistics'
@pytest.mark.django_db
def test_order_track_and_cancel_pickup(api_client, create_seller):
user, order, _ = create_seller
api_client.force_authenticate(user=user)
order.tracking = 'SFX9928374102'
order.status = 'Ready to Ship'
order.save()
# Track Order
track_url = reverse('order-track', args=[order.id])
response = api_client.get(track_url)
assert response.status_code == status.HTTP_200_OK
# Cancel Pickup
cancel_url = reverse('order-cancel-pickup', args=[order.id])
response = api_client.post(cancel_url, {'reason': 'Out of stock'}, format='json')
assert response.status_code == status.HTTP_200_OK
order.refresh_from_db()
assert order.status == 'Cancelled'
@pytest.mark.django_db
def test_return_approve_initiates_customer_return_pickup(api_client, create_seller):
user, _, return_req = create_seller
api_client.force_authenticate(user=user)
url = reverse('return-action', args=[return_req.id])
response = api_client.post(url, {'action': 'Approved'}, format='json')
assert response.status_code == status.HTTP_200_OK
assert response.data['status'] == 'In Transit'
assert response.data['returning_tracking'] is not None
return_req.refresh_from_db()
assert return_req.status == 'In Transit'
assert return_req.returning_tracking is not None
@pytest.mark.django_db
def test_return_track_and_update_qc(api_client, create_seller):
user, _, return_req = create_seller
api_client.force_authenticate(user=user)
return_req.returning_tracking = 'SFX-REV-99182736'
return_req.status = 'In Transit'
return_req.save()
# Track Return
track_url = reverse('return-track', args=[return_req.id])
response = api_client.get(track_url)
assert response.status_code == status.HTTP_200_OK
# Update QC
qc_url = reverse('return-update-qc', args=[return_req.id])
response = api_client.post(qc_url, {'qc_check': True, 'serial_number': 'SN-ARTISAN-99'}, format='json')
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_standalone_shipping_endpoints(api_client, create_seller):
user, order, return_req = create_seller
api_client.force_authenticate(user=user)
# Forward Serviceability
res = api_client.post(reverse('shipping-forward-serviceability'), {'pincodes': '560077'}, format='json')
assert res.status_code == status.HTTP_200_OK
# Forward Create Pickup
res = api_client.post(reverse('shipping-forward-create-pickup'), {'order_id': order.order_id}, format='json')
assert res.status_code == status.HTTP_200_OK
# Forward Track
res = api_client.get(reverse('shipping-forward-track') + f'?order_id={order.order_id}')
assert res.status_code == status.HTTP_200_OK
# Reverse Serviceability
res = api_client.post(reverse('shipping-reverse-serviceability'), {'pincodes': '560103'}, format='json')
assert res.status_code == status.HTTP_200_OK
# Reverse Create Pickup
res = api_client.post(reverse('shipping-reverse-create-pickup'), {'return_id': return_req.return_id}, format='json')
assert res.status_code == status.HTTP_200_OK
# Reverse Track
res = api_client.get(reverse('shipping-reverse-track') + f'?return_id={return_req.return_id}')
assert res.status_code == status.HTTP_200_OK
# Reverse Update QC
res = api_client.put(reverse('shipping-reverse-update-qc'), {'return_id': return_req.return_id, 'serial_number': 'SN-1001'}, format='json')
assert res.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_print_shipping_and_return_labels(api_client, create_seller):
user, order, return_req = create_seller
api_client.force_authenticate(user=user)
# 1. Order ViewSet print_label before carrier assignment (Task 2: should be rejected)
order_label_url = reverse('order-print-label', args=[order.id])
res = api_client.get(order_label_url)
assert res.status_code == status.HTTP_400_BAD_REQUEST
assert res.data['status'] == 'error'
# Assign carrier and tracking
order.tracking = 'SFX-99887766'
order.carrier = 'Shadowfax Logistics'
order.status = 'Ready to Ship'
order.save()
# 1b. Order ViewSet print_label after carrier assignment
res = api_client.get(order_label_url)
assert res.status_code == status.HTTP_200_OK
assert res.data['status'] == 'success'
assert 'label' in res.data
assert res.data['label']['order_id'] == order.order_id
assert res.data['label']['carrier'] == 'Shadowfax Logistics'
assert 'barcode_url' in res.data['label']
# 2. ReturnRequest ViewSet print_label
return_label_url = reverse('return-print-label', args=[return_req.id])
res = api_client.get(return_label_url)
assert res.status_code == status.HTTP_200_OK
assert res.data['status'] == 'success'
assert 'label' in res.data
assert res.data['label']['return_id'] == return_req.return_id
assert res.data['label']['qc_instructions']['doorstep_qc'] is True
# 3. Standalone Shipping Forward Label Endpoint
res = api_client.get(reverse('shipping-forward-label') + f'?order_id={order.order_id}')
assert res.status_code == status.HTTP_200_OK
assert res.data['status'] == 'success'
# 4. Standalone Shipping Reverse Label Endpoint
res = api_client.get(reverse('shipping-reverse-label') + f'?return_id={return_req.return_id}')
assert res.status_code == status.HTTP_200_OK
assert res.data['status'] == 'success'