forked from erp-dev/erp
feat: settlement first api beta
This commit is contained in:
229
settlement/test_tasks_handlers_admin.py
Normal file
229
settlement/test_tasks_handlers_admin.py
Normal file
@@ -0,0 +1,229 @@
|
||||
from datetime import date
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.contrib.admin.sites import AdminSite
|
||||
from django.test import TestCase
|
||||
|
||||
from basic_info import models as basic_models
|
||||
from settlement import handlers
|
||||
from settlement.admin import DailySettlementConfigAdmin
|
||||
from settlement.models import (
|
||||
DailySettlementConfig,
|
||||
NotificationChannelEnum,
|
||||
SettlementModuleEnum,
|
||||
)
|
||||
from settlement.tasks import run_daily_settlement, run_merchant_daily_settlement
|
||||
|
||||
|
||||
class SettlementTasksTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.merchant = basic_models.Merchant.objects.create(
|
||||
name='任务测试商户',
|
||||
type=basic_models.MerchantTypeEnum.FACTORY,
|
||||
)
|
||||
self.config = DailySettlementConfig.objects.create(
|
||||
merchant=self.merchant,
|
||||
settlement_modules=[SettlementModuleEnum.PLATE_ORDER],
|
||||
notification_enabled=False,
|
||||
notification_channel=NotificationChannelEnum.NONE,
|
||||
)
|
||||
|
||||
@patch('settlement.tasks.run_merchant_daily_settlement.delay')
|
||||
@patch('settlement.tasks.timezone.localdate')
|
||||
def test_run_daily_settlement_dispatches_only_configured_merchants(
|
||||
self,
|
||||
mock_localdate,
|
||||
mock_delay,
|
||||
):
|
||||
mock_localdate.return_value = date(2026, 2, 9)
|
||||
|
||||
merchant_without_modules = basic_models.Merchant.objects.create(
|
||||
name='无模块商户',
|
||||
type=basic_models.MerchantTypeEnum.FACTORY,
|
||||
)
|
||||
DailySettlementConfig.objects.create(
|
||||
merchant=merchant_without_modules,
|
||||
settlement_modules=[],
|
||||
notification_enabled=False,
|
||||
notification_channel=NotificationChannelEnum.NONE,
|
||||
)
|
||||
|
||||
result = run_daily_settlement.run()
|
||||
|
||||
self.assertEqual(result['total_merchants'], 1)
|
||||
self.assertEqual(result['settlement_date'], '2026-02-08')
|
||||
mock_delay.assert_called_once_with(
|
||||
merchant_id=self.merchant.id,
|
||||
settlement_date='2026-02-08',
|
||||
)
|
||||
|
||||
@patch('settlement.tasks.daily_settlement_completed.send')
|
||||
@patch('settlement.tasks.calculate_printing_order_daily_summary')
|
||||
@patch('settlement.tasks.calculate_plate_order_daily_summary')
|
||||
def test_run_merchant_daily_settlement_success(
|
||||
self,
|
||||
mock_plate_summary,
|
||||
mock_printing_summary,
|
||||
mock_signal_send,
|
||||
):
|
||||
self.config.settlement_modules = [
|
||||
SettlementModuleEnum.PLATE_ORDER,
|
||||
SettlementModuleEnum.PRINTING_ORDER,
|
||||
]
|
||||
self.config.save(update_fields=['settlement_modules'])
|
||||
|
||||
mock_plate_summary.return_value = {'total_orders': 1}
|
||||
mock_printing_summary.return_value = {'total_orders': 2}
|
||||
|
||||
result = run_merchant_daily_settlement.run(
|
||||
merchant_id=self.merchant.id,
|
||||
settlement_date='2026-02-08',
|
||||
)
|
||||
|
||||
self.assertEqual(result['merchant_id'], self.merchant.id)
|
||||
self.assertEqual(result['settlement_date'], '2026-02-08')
|
||||
self.assertEqual(result['status'], 'success')
|
||||
self.assertEqual(result['errors'], {})
|
||||
mock_plate_summary.assert_called_once()
|
||||
mock_printing_summary.assert_called_once()
|
||||
mock_signal_send.assert_called_once()
|
||||
|
||||
@patch('settlement.tasks.daily_settlement_completed.send')
|
||||
@patch('settlement.tasks.calculate_printing_order_daily_summary')
|
||||
@patch('settlement.tasks.calculate_plate_order_daily_summary')
|
||||
def test_run_merchant_daily_settlement_partial_when_one_module_fails(
|
||||
self,
|
||||
mock_plate_summary,
|
||||
mock_printing_summary,
|
||||
mock_signal_send,
|
||||
):
|
||||
self.config.settlement_modules = [
|
||||
SettlementModuleEnum.PLATE_ORDER,
|
||||
SettlementModuleEnum.PRINTING_ORDER,
|
||||
]
|
||||
self.config.save(update_fields=['settlement_modules'])
|
||||
|
||||
mock_plate_summary.side_effect = RuntimeError('plate failed')
|
||||
mock_printing_summary.return_value = {'total_orders': 2}
|
||||
|
||||
result = run_merchant_daily_settlement.run(
|
||||
merchant_id=self.merchant.id,
|
||||
settlement_date='2026-02-08',
|
||||
)
|
||||
|
||||
self.assertEqual(result['status'], 'partial')
|
||||
self.assertIn(SettlementModuleEnum.PLATE_ORDER, result['errors'])
|
||||
self.assertEqual(result['errors'][SettlementModuleEnum.PLATE_ORDER], 'plate failed')
|
||||
mock_signal_send.assert_called_once()
|
||||
|
||||
@patch('settlement.tasks.daily_settlement_completed.send')
|
||||
@patch('settlement.tasks.calculate_plate_order_daily_summary')
|
||||
def test_run_merchant_daily_settlement_failed_when_all_modules_fail(
|
||||
self,
|
||||
mock_plate_summary,
|
||||
mock_signal_send,
|
||||
):
|
||||
self.config.settlement_modules = [SettlementModuleEnum.PLATE_ORDER]
|
||||
self.config.save(update_fields=['settlement_modules'])
|
||||
|
||||
mock_plate_summary.side_effect = RuntimeError('plate failed')
|
||||
|
||||
result = run_merchant_daily_settlement.run(
|
||||
merchant_id=self.merchant.id,
|
||||
settlement_date='2026-02-08',
|
||||
)
|
||||
|
||||
self.assertEqual(result['status'], 'failed')
|
||||
self.assertIn(SettlementModuleEnum.PLATE_ORDER, result['errors'])
|
||||
mock_signal_send.assert_called_once()
|
||||
|
||||
@patch('settlement.tasks.daily_settlement_completed.send')
|
||||
@patch('settlement.tasks.calculate_plate_order_daily_summary')
|
||||
@patch('settlement.tasks.timezone.localdate')
|
||||
def test_run_merchant_daily_settlement_uses_yesterday_when_no_date(
|
||||
self,
|
||||
mock_localdate,
|
||||
mock_plate_summary,
|
||||
mock_signal_send,
|
||||
):
|
||||
mock_localdate.return_value = date(2026, 2, 9)
|
||||
self.config.settlement_modules = [SettlementModuleEnum.PLATE_ORDER]
|
||||
self.config.save(update_fields=['settlement_modules'])
|
||||
mock_plate_summary.return_value = {'total_orders': 1}
|
||||
|
||||
result = run_merchant_daily_settlement.run(merchant_id=self.merchant.id)
|
||||
|
||||
self.assertEqual(result['settlement_date'], '2026-02-08')
|
||||
mock_signal_send.assert_called_once()
|
||||
|
||||
|
||||
class SettlementHandlersTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.merchant = basic_models.Merchant.objects.create(
|
||||
name='处理器测试商户',
|
||||
type=basic_models.MerchantTypeEnum.FACTORY,
|
||||
)
|
||||
|
||||
@patch('settlement.handlers.logger.info')
|
||||
def test_handler_logs_when_notification_disabled(self, mock_logger_info):
|
||||
DailySettlementConfig.objects.create(
|
||||
merchant=self.merchant,
|
||||
settlement_modules=[SettlementModuleEnum.PLATE_ORDER],
|
||||
notification_enabled=False,
|
||||
notification_channel=NotificationChannelEnum.NONE,
|
||||
)
|
||||
|
||||
handlers.on_daily_settlement_completed(
|
||||
sender=self.__class__,
|
||||
merchant=self.merchant,
|
||||
settlement_date=date(2026, 2, 8),
|
||||
status='success',
|
||||
modules=[SettlementModuleEnum.PLATE_ORDER],
|
||||
errors={},
|
||||
task_id='task-1',
|
||||
)
|
||||
|
||||
self.assertTrue(mock_logger_info.called)
|
||||
|
||||
@patch('settlement.handlers.logger.info')
|
||||
def test_handler_logs_wecom_when_notification_enabled(self, mock_logger_info):
|
||||
DailySettlementConfig.objects.create(
|
||||
merchant=self.merchant,
|
||||
settlement_modules=[SettlementModuleEnum.PLATE_ORDER],
|
||||
notification_enabled=True,
|
||||
notification_channel=NotificationChannelEnum.WECOM,
|
||||
)
|
||||
|
||||
handlers.on_daily_settlement_completed(
|
||||
sender=self.__class__,
|
||||
merchant=self.merchant,
|
||||
settlement_date=date(2026, 2, 8),
|
||||
status='success',
|
||||
modules=[SettlementModuleEnum.PLATE_ORDER],
|
||||
errors={},
|
||||
task_id='task-2',
|
||||
)
|
||||
|
||||
self.assertTrue(mock_logger_info.called)
|
||||
|
||||
|
||||
class SettlementAdminTestCase(TestCase):
|
||||
def test_get_readonly_fields(self):
|
||||
admin_obj = DailySettlementConfigAdmin(
|
||||
DailySettlementConfig,
|
||||
admin_site=AdminSite(),
|
||||
)
|
||||
|
||||
self.assertEqual(admin_obj.get_readonly_fields(request=None, obj=None), [])
|
||||
|
||||
merchant = basic_models.Merchant.objects.create(
|
||||
name='后台测试商户',
|
||||
type=basic_models.MerchantTypeEnum.FACTORY,
|
||||
)
|
||||
config = DailySettlementConfig.objects.create(
|
||||
merchant=merchant,
|
||||
settlement_modules=[SettlementModuleEnum.PLATE_ORDER],
|
||||
notification_enabled=False,
|
||||
notification_channel=NotificationChannelEnum.NONE,
|
||||
)
|
||||
self.assertEqual(admin_obj.get_readonly_fields(request=None, obj=config), ['merchant'])
|
||||
Reference in New Issue
Block a user