forked from erp-dev/erp
feat: big version, added tasks for backup_database and stock change, added health check api, approve sse (support channel via merchant)
This commit is contained in:
144
api_v1/tests.py
144
api_v1/tests.py
@@ -1,8 +1,25 @@
|
||||
from django.test import TestCase
|
||||
import shutil
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.test import TestCase, override_settings
|
||||
from django.contrib.auth.models import User, Permission
|
||||
from rest_framework.test import APIClient
|
||||
from rest_framework import status
|
||||
from basic_info.models import Merchant, UserProfile
|
||||
from basic_info.models import (
|
||||
Employee,
|
||||
Merchant,
|
||||
MerchantTypeEnum,
|
||||
Product,
|
||||
ProductCategory,
|
||||
ProductUnitEnum,
|
||||
Supplier,
|
||||
UserProfile,
|
||||
WareHouse,
|
||||
WareHouseModeEnum,
|
||||
)
|
||||
from api_v1 import tasks
|
||||
|
||||
|
||||
class UserCreationAPITestCase(TestCase):
|
||||
@@ -110,3 +127,126 @@ class UserCreationAPITestCase(TestCase):
|
||||
response = self.client.post('/api/v1/users/create/', data, format='json')
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertIn('password', response.data)
|
||||
|
||||
|
||||
@override_settings(
|
||||
CELERY_TASK_ALWAYS_EAGER=True,
|
||||
CELERY_TASK_EAGER_PROPAGATES=True,
|
||||
)
|
||||
class PurchaseOrderAPITestCase(TestCase):
|
||||
"""采购单 API 测试"""
|
||||
|
||||
def setUp(self):
|
||||
self.merchant = Merchant.objects.create(name='PO商户', type=MerchantTypeEnum.FACTORY)
|
||||
self.supplier = Supplier.objects.create(merchant=self.merchant, name='供应商A')
|
||||
self.warehouse = WareHouse.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='主仓',
|
||||
mode=WareHouseModeEnum.RESTRICT_IN,
|
||||
)
|
||||
category = ProductCategory.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='品类',
|
||||
product_prefix='FAB',
|
||||
)
|
||||
self.product = Product.objects.create(
|
||||
merchant=self.merchant,
|
||||
category=category,
|
||||
name='产品1',
|
||||
human_id='FAB-001',
|
||||
unit=ProductUnitEnum.METER,
|
||||
)
|
||||
self.user = User.objects.create_user(username='po_user', password='pass123')
|
||||
self.employee = Employee.objects.create(
|
||||
merchant=self.merchant,
|
||||
sys_user=self.user,
|
||||
name='仓管',
|
||||
)
|
||||
self.client = APIClient()
|
||||
self.client.force_authenticate(user=self.user)
|
||||
self.payload = {
|
||||
'supplier': self.supplier.id,
|
||||
'warehouse': self.warehouse.id,
|
||||
'order_date': '2025-11-26',
|
||||
'total_amount': '1500.00',
|
||||
'items': [
|
||||
{
|
||||
'product_id': self.product.id,
|
||||
'quantities': ['10.0', '5.0'],
|
||||
}
|
||||
],
|
||||
'remarks': '接口测试',
|
||||
}
|
||||
|
||||
def test_create_purchase_order_success(self):
|
||||
with patch('business.services.create_purchase_order_stock_entries.delay') as mock_delay:
|
||||
response = self.client.post('/api/v1/purchase-orders/', self.payload, format='json')
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertIn('id', response.data)
|
||||
mock_delay.assert_called_once()
|
||||
|
||||
def test_create_purchase_order_invalid_supplier(self):
|
||||
payload = {**self.payload, 'supplier': 999}
|
||||
response = self.client.post('/api/v1/purchase-orders/', payload, format='json')
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertIn('不存在', response.data['error'])
|
||||
|
||||
def test_create_purchase_order_unauthenticated(self):
|
||||
self.client.force_authenticate(user=None)
|
||||
response = self.client.post('/api/v1/purchase-orders/', self.payload, format='json')
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
|
||||
@override_settings(
|
||||
CELERY_TASK_ALWAYS_EAGER=True,
|
||||
CELERY_TASK_EAGER_PROPAGATES=True,
|
||||
)
|
||||
class CeleryTasksTestCase(TestCase):
|
||||
"""验证 Celery 任务的执行结果"""
|
||||
|
||||
def setUp(self):
|
||||
self.merchant = Merchant.objects.create(name='Celery商户', type=MerchantTypeEnum.FACTORY)
|
||||
category = ProductCategory.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='Celery品类',
|
||||
product_prefix='CLY',
|
||||
)
|
||||
for idx in range(3):
|
||||
Product.objects.create(
|
||||
merchant=self.merchant,
|
||||
category=category,
|
||||
name=f'Celery产品{idx}',
|
||||
human_id=f'CLY-{idx:03d}',
|
||||
unit=ProductUnitEnum.METER,
|
||||
)
|
||||
|
||||
def test_ping_task_returns_payload(self):
|
||||
result = tasks.ping_task.delay('celery hello')
|
||||
payload = result.get(timeout=5)
|
||||
self.assertEqual(payload['message'], 'celery hello')
|
||||
self.assertIn('timestamp', payload)
|
||||
self.assertIn('task_id', payload)
|
||||
|
||||
def test_merchant_product_count(self):
|
||||
result = tasks.merchant_product_count.delay(self.merchant.id)
|
||||
payload = result.get(timeout=5)
|
||||
self.assertEqual(payload['merchant_id'], self.merchant.id)
|
||||
self.assertEqual(payload['product_count'], 3)
|
||||
|
||||
def test_backup_database_creates_file(self):
|
||||
tmpdir = Path(tempfile.mkdtemp())
|
||||
self.addCleanup(lambda: shutil.rmtree(tmpdir, ignore_errors=True))
|
||||
with patch('api_v1.tasks._dump_database_to_sql') as mock_dump:
|
||||
def fake_dump(path: Path):
|
||||
path.write_text('-- dummy sql\n', encoding='utf-8')
|
||||
|
||||
mock_dump.side_effect = fake_dump
|
||||
result = tasks.backup_database.delay(output_dir=str(tmpdir), filename_prefix='test-backup')
|
||||
payload = result.get(timeout=10)
|
||||
backup_path = Path(payload['backup_path'])
|
||||
self.assertTrue(backup_path.exists())
|
||||
self.assertTrue(backup_path.is_file())
|
||||
self.assertEqual(backup_path.parent.resolve(), tmpdir.resolve())
|
||||
self.assertEqual(backup_path.suffix, '.sql')
|
||||
self.assertTrue(backup_path.read_text(encoding='utf-8').strip())
|
||||
|
||||
Reference in New Issue
Block a user