from datetime import datetime, time, timedelta from unittest.mock import patch from django.test import TestCase from django.utils import timezone from basic_info import models as basic_models from printing import models as printing_models class PlateOrderTiiaUploadTaskTestCase(TestCase): def setUp(self): self.merchant = basic_models.Merchant.objects.create( name='测试商户', type=basic_models.MerchantTypeEnum.FACTORY, ) self.customer = basic_models.Customer.objects.create( merchant=self.merchant, name='客户A', mobile='13900000000', area='A', ) @patch('api_v1.utils.tencentcloud_tiia.time.sleep', lambda *_args, **_kwargs: None) @patch('api_v1.utils.tencentcloud_tiia.upload_plate_order_images_to_tencent_tiia') def test_task_records_failure_and_continues(self, mocked_upload_plate_order): # 准备:创建 2 个 plate_order,并把 created_at 改到“昨天” po_ok = printing_models.PlateOrder.objects.create( merchant=self.merchant, customer=self.customer, plate_image=[{'url': 'https://example.com/a.png'}], ) po_bad = printing_models.PlateOrder.objects.create( merchant=self.merchant, customer=self.customer, plate_image=[{'url': 'https://example.com/b.png'}], ) yesterday = timezone.localdate() - timedelta(days=1) dt = timezone.make_aware(datetime.combine(yesterday, time.min)) printing_models.PlateOrder.objects.filter(id__in=[po_ok.id, po_bad.id]).update(created_at=dt) def side_effect(*, plate_order_id: int, rate_limiter=None): if plate_order_id == po_bad.id: raise ValueError('boom') return [{'image_url': 'https://example.com/a.png', 'ok': True, 'response': {'ok': 1}, 'error': None}] mocked_upload_plate_order.side_effect = side_effect from printing.tasks import upload_yesterday_plate_order_images_to_tencent_tiia payload = upload_yesterday_plate_order_images_to_tencent_tiia() self.assertEqual(payload['total_orders'], 2) self.assertEqual(payload['failed_count'], 1) self.assertIn(po_bad.id, payload['failed_ids']) # failure 表应落库 from printing.models import PlateOrderTiiaUploadFailure rec = PlateOrderTiiaUploadFailure.objects.filter(run_date=yesterday, plate_order_id=po_bad.id).first() self.assertIsNotNone(rec) self.assertGreaterEqual(rec.attempts, 1)