""" PrintingJob API 测试 """ from django.test import TestCase from rest_framework.test import APIClient from rest_framework import status from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission from basic_info import models as basic_models from printing import models as printing_models User = get_user_model() class PrintingJobAPITestCase(TestCase): """测试 PrintingJob API""" def setUp(self): self.client = APIClient() # 创建商户 self.merchant = basic_models.Merchant.objects.create( name='测试印花厂', type=basic_models.MerchantTypeEnum.FACTORY ) # 创建用户 self.user = User.objects.create_user( username='testuser', password='testpass123', email='test@example.com' ) # 创建员工并关联商户 self.employee = basic_models.Employee.objects.create( sys_user=self.user, merchant=self.merchant, name='测试员工', mobile='13800138000', job_type=basic_models.EmployeeTypeEnum.PRINTER, status=basic_models.EmployeeStatusEnum.ACTIVE ) # 创建客户 self.customer = basic_models.Customer.objects.create( merchant=self.merchant, name='测试客户', mobile='13900139000', area='测试地区' ) # 创建印染订单 self.printing_order = printing_models.PrintingOrder.objects.create( customer=self.customer, fabric='测试布料', width='150cm' ) # 创建产品类别 self.category = basic_models.ProductCategory.objects.create( merchant=self.merchant, name='测试类别' ) # 创建产品 self.product = basic_models.Product.objects.create( merchant=self.merchant, category=self.category, name='测试产品', human_id='TEST001', unit=basic_models.ProductUnitEnum.METER ) # 认证用户 self.client.force_authenticate(user=self.user) # 给用户添加基础权限 view_perm = Permission.objects.get(codename='view_printingjob') add_perm = Permission.objects.get(codename='add_printingjob') change_perm = Permission.objects.get(codename='change_printingjob') self.user.user_permissions.add(view_perm, add_perm, change_perm) def test_create_printing_job(self): """测试创建印染款式明细""" data = { 'printing_order': self.printing_order.id, 'product': self.product.id, 'quantity': 100, 'unit': '米', 'size': '50*60', 'pieces': 10, 'description': '测试备注' } response = self.client.post('/api/v1/printing-jobs/', data, format='json') self.assertEqual(response.status_code, status.HTTP_201_CREATED) # 验证创建成功 job = printing_models.PrintingJob.objects.filter( printing_order=self.printing_order, product=self.product ).first() self.assertIsNotNone(job) self.assertEqual(job.quantity, 100) self.assertEqual(job.unit, '米') self.assertEqual(job.pieces, 10) def test_list_printing_jobs(self): """测试获取款式明细列表""" # 创建测试数据 printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=100, unit='米', size='50*60', pieces=10 ) printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=200, unit='米', size='60*70', pieces=20 ) response = self.client.get('/api/v1/printing-jobs/') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 2) def test_retrieve_printing_job(self): """测试获取款式明细详情""" job = printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=100, unit='米', size='50*60', pieces=10, description='详情测试' ) response = self.client.get(f'/api/v1/printing-jobs/{job.id}/') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['quantity'], 100) self.assertEqual(response.data['unit'], '米') self.assertIn('product_name', response.data) self.assertEqual(response.data['product_name'], self.product.name) def test_update_printing_job(self): """测试更新款式明细""" job = printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=100, unit='米', size='50*60', pieces=10 ) update_data = { 'printing_order': self.printing_order.id, 'product': self.product.id, 'quantity': 200, 'unit': '码', 'size': '60*70', 'pieces': 20, 'description': '更新后的备注' } response = self.client.put( f'/api/v1/printing-jobs/{job.id}/', update_data, format='json' ) self.assertEqual(response.status_code, status.HTTP_200_OK) job.refresh_from_db() self.assertEqual(job.quantity, 200) self.assertEqual(job.unit, '码') self.assertEqual(job.pieces, 20) def test_partial_update_printing_job(self): """测试部分更新款式明细""" job = printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=100, unit='米', size='50*60', pieces=10 ) patch_data = { 'quantity': 150, 'pieces': 15 } response = self.client.patch( f'/api/v1/printing-jobs/{job.id}/', patch_data, format='json' ) self.assertEqual(response.status_code, status.HTTP_200_OK) job.refresh_from_db() self.assertEqual(job.quantity, 150) self.assertEqual(job.pieces, 15) self.assertEqual(job.unit, '米') # 未修改字段保持不变 def test_delete_printing_job_forbidden(self): """测试删除款式明细被禁用""" # 添加删除权限以便测试destroy方法的自定义逻辑 delete_perm = Permission.objects.get(codename='delete_printingjob') self.user.user_permissions.add(delete_perm) job = printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=100, unit='米', size='50*60', pieces=10 ) response = self.client.delete(f'/api/v1/printing-jobs/{job.id}/') self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) self.assertIn('不支持删除', response.data['detail']) # 验证明细仍然存在 self.assertTrue( printing_models.PrintingJob.objects.filter(id=job.id).exists() ) def test_filter_by_printing_order(self): """测试按印染订单过滤""" order2 = printing_models.PrintingOrder.objects.create( customer=self.customer, fabric='其他布料', width='160cm' ) printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=100, unit='米', size='50*60', pieces=10 ) printing_models.PrintingJob.objects.create( printing_order=order2, product=self.product, quantity=200, unit='米', size='60*70', pieces=20 ) response = self.client.get(f'/api/v1/printing-jobs/?printing_order={self.printing_order.id}') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]['printing_order'], self.printing_order.id) def test_filter_by_product(self): """测试按产品过滤""" product2 = basic_models.Product.objects.create( merchant=self.merchant, category=self.category, name='产品2', human_id='TEST002', unit=basic_models.ProductUnitEnum.METER ) printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=100, unit='米', size='50*60', pieces=10 ) printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=product2, quantity=200, unit='米', size='60*70', pieces=20 ) response = self.client.get(f'/api/v1/printing-jobs/?product={self.product.id}') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]['product'], self.product.id) def test_filter_by_quantity_range(self): """测试按数量范围过滤""" printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=50, unit='米', size='50*60', pieces=10 ) printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=150, unit='米', size='60*70', pieces=20 ) printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=250, unit='米', size='70*80', pieces=30 ) response = self.client.get('/api/v1/printing-jobs/?quantity_min=100&quantity_max=200') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 1) self.assertEqual(response.data[0]['quantity'], 150) def test_search_by_product_name(self): """测试按产品名称搜索""" product2 = basic_models.Product.objects.create( merchant=self.merchant, category=self.category, name='特殊产品', human_id='TEST003', unit=basic_models.ProductUnitEnum.METER ) printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=100, unit='米', size='50*60', pieces=10 ) printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=product2, quantity=200, unit='米', size='60*70', pieces=20 ) response = self.client.get('/api/v1/printing-jobs/?search=特殊') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 1) self.assertIn('特殊', response.data[0]['product_name']) def test_ordering(self): """测试排序""" job1 = printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=100, unit='米', size='50*60', pieces=10 ) job2 = printing_models.PrintingJob.objects.create( printing_order=self.printing_order, product=self.product, quantity=200, unit='米', size='60*70', pieces=20 ) # 按数量升序 response = self.client.get('/api/v1/printing-jobs/?ordering=quantity') self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data[0]['quantity'], 100) self.assertEqual(response.data[1]['quantity'], 200) # 按数量降序 response = self.client.get('/api/v1/printing-jobs/?ordering=-quantity') self.assertEqual(response.data[0]['quantity'], 200) self.assertEqual(response.data[1]['quantity'], 100) def test_validate_quantity_positive(self): """测试数量必须大于0""" data = { 'printing_order': self.printing_order.id, 'product': self.product.id, 'quantity': 0, # 无效数量 'unit': '米', 'size': '50*60', 'pieces': 10 } response = self.client.post('/api/v1/printing-jobs/', data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertIn('quantity', response.data) def test_validate_pieces_positive(self): """测试件数必须大于0""" data = { 'printing_order': self.printing_order.id, 'product': self.product.id, 'quantity': 100, 'unit': '米', 'size': '50*60', 'pieces': 0 # 无效件数 } response = self.client.post('/api/v1/printing-jobs/', data, format='json') self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertIn('pieces', response.data)