from django.contrib.auth import get_user_model from django.core.files.uploadedfile import SimpleUploadedFile from django.test import TestCase from rest_framework.test import APIClient from basic_info import models as basic_models from shipment import models as shipment_models def tiny_gif(name='photo.gif'): return SimpleUploadedFile( name, ( b'GIF89a\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\xff\xff\xff!' b'\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00' b'\x00\x02\x02D\x01\x00;' ), content_type='image/gif', ) class ShipmentDeliveryPhotoV2APITest(TestCase): def setUp(self): self.client = APIClient() self.merchant = basic_models.Merchant.objects.create( name='送货照片商户', type=basic_models.MerchantTypeEnum.FACTORY, ) self.other_merchant = basic_models.Merchant.objects.create( name='其他送货照片商户', type=basic_models.MerchantTypeEnum.FACTORY, ) self.user = get_user_model().objects.create_user(username='shipment-photo-user', password='pass12345') self.employee = basic_models.Employee.objects.create( merchant=self.merchant, sys_user=self.user, name='送货照片员工', ) self.customer = basic_models.Customer.objects.create( merchant=self.merchant, name='照片客户', mobile='13800138000', ) self.other_customer = basic_models.Customer.objects.create( merchant=self.other_merchant, name='其他照片客户', mobile='13800138001', ) self.delivery = shipment_models.ShipmentDelivery.objects.create( merchant=self.merchant, driver_name='张司机', vehicle_trip='TRIP-001', created_by=self.user, ) self.other_delivery = shipment_models.ShipmentDelivery.objects.create( merchant=self.other_merchant, driver_name='李司机', vehicle_trip='TRIP-002', created_by=self.user, ) self.shipment = shipment_models.Shipment.objects.create( merchant=self.merchant, customer=self.customer, shipment_date='2026-04-28', created_by=self.user, delivery=self.delivery, ) self.shipment2 = shipment_models.Shipment.objects.create( merchant=self.merchant, customer=self.customer, shipment_date='2026-04-29', created_by=self.user, delivery=self.delivery, ) self.other_shipment = shipment_models.Shipment.objects.create( merchant=self.other_merchant, customer=self.other_customer, shipment_date='2026-04-30', created_by=self.user, delivery=self.other_delivery, ) self.client.force_authenticate(user=self.user) def test_create_shipment_delivery_photo_success(self): resp = self.client.post( '/api/v2/shipment-delivery-photos/', { 'shipment': str(self.shipment.id), 'delivery': str(self.delivery.id), 'remark': '已送达', 'photo': tiny_gif(), }, format='multipart', ) self.assertEqual(resp.status_code, 201) photo = shipment_models.ShipmentDeliveryPhoto.objects.get(id=resp.data['id']) self.assertEqual(photo.shipment_id, self.shipment.id) self.assertEqual(photo.delivery_id, self.delivery.id) self.assertEqual(photo.created_by_id, self.user.id) self.assertEqual(resp.data['shipment_id'], self.shipment.id) self.assertEqual(resp.data['delivery_id'], self.delivery.id) self.assertEqual(resp.data['remark'], '已送达') self.assertTrue(resp.data['photo']) def test_create_shipment_delivery_photo_rejects_delivery_mismatch(self): other_delivery_same_merchant = shipment_models.ShipmentDelivery.objects.create( merchant=self.merchant, driver_name='王司机', vehicle_trip='TRIP-003', created_by=self.user, ) resp = self.client.post( '/api/v2/shipment-delivery-photos/', { 'shipment': str(self.shipment.id), 'delivery': str(other_delivery_same_merchant.id), 'photo': tiny_gif('mismatch.gif'), }, format='multipart', ) self.assertEqual(resp.status_code, 400) self.assertIn('delivery', resp.data) def test_list_shipment_delivery_photos_supports_shipment_and_delivery_filters(self): photo1 = shipment_models.ShipmentDeliveryPhoto.objects.create( shipment=self.shipment, delivery=self.delivery, remark='第一张', photo=tiny_gif('one.gif'), created_by=self.user, ) shipment_models.ShipmentDeliveryPhoto.objects.create( shipment=self.shipment2, delivery=self.delivery, remark='第二张', photo=tiny_gif('two.gif'), created_by=self.user, ) resp = self.client.get( f'/api/v2/shipment-delivery-photos/?shipment_id={self.shipment.id}&delivery_id={self.delivery.id}' ) self.assertEqual(resp.status_code, 200) self.assertEqual([item['id'] for item in resp.data], [photo1.id]) def test_patch_shipment_delivery_photo_updates_remark(self): photo = shipment_models.ShipmentDeliveryPhoto.objects.create( shipment=self.shipment, delivery=self.delivery, remark='初始备注', photo=tiny_gif('patch.gif'), created_by=self.user, ) resp = self.client.patch( f'/api/v2/shipment-delivery-photos/{photo.id}/', {'remark': '更新备注'}, format='multipart', ) self.assertEqual(resp.status_code, 200) photo.refresh_from_db() self.assertEqual(photo.remark, '更新备注') def test_delete_shipment_delivery_photo_success(self): photo = shipment_models.ShipmentDeliveryPhoto.objects.create( shipment=self.shipment, delivery=self.delivery, remark='待删除', photo=tiny_gif('delete.gif'), created_by=self.user, ) resp = self.client.delete(f'/api/v2/shipment-delivery-photos/{photo.id}/') self.assertEqual(resp.status_code, 204) self.assertFalse(shipment_models.ShipmentDeliveryPhoto.objects.filter(id=photo.id).exists())