"""CMS 超级管理员 - 科室管理接口测试(CMS-DEPT-1~6,全局科室)。""" import io from openpyxl import Workbook from django.core.files.uploadedfile import SimpleUploadedFile from rest_framework.test import APIClient from apps.user.models import Department from .conftest import CacheTestCase, create_test_user, get_auth_client CMS_DEPT_URL = '/api/cms/departments/' XLSX_CT = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' def d_detail(pk): return f'/api/cms/departments/{pk}/' def make_xlsx(headers, rows): wb = Workbook(); ws = wb.active ws.append(headers) for r in rows: ws.append(r) buf = io.BytesIO(); wb.save(buf); buf.seek(0) return SimpleUploadedFile('dept.xlsx', buf.read(), content_type=XLSX_CT) def super_client(phone='13933300001'): admin = create_test_user(phone=phone, password='Admin123', role_type='super_admin') return get_auth_client(admin) class CmsDepartmentTest(CacheTestCase): def setUp(self): super().setUp() self.client = super_client() def test_requires_super_admin(self): self.assertEqual(APIClient().get(CMS_DEPT_URL).status_code, 401) u = create_test_user(phone='13933300009', role_type='doctor') self.assertEqual(get_auth_client(u).get(CMS_DEPT_URL).status_code, 403) def test_crud(self): # 新增 resp = self.client.post(CMS_DEPT_URL, {'name': '内科', 'category': '临床'}) self.assertEqual(resp.status_code, 201, resp.content) did = resp.json()['id'] # 列表 resp = self.client.get(CMS_DEPT_URL) self.assertEqual(resp.status_code, 200) self.assertIn('results', resp.json()) # 编辑 resp = self.client.patch(d_detail(did), {'category': '医技'}) self.assertEqual(resp.status_code, 200, resp.content) self.assertEqual(resp.json()['category'], '医技') def test_duplicate_name(self): Department.objects.create(name='外科', category='临床') resp = self.client.post(CMS_DEPT_URL, {'name': '外科'}) self.assertEqual(resp.status_code, 400, resp.content) self.assertEqual(resp.json()['code'], 'CMS_DEPARTMENT_NAME_EXISTS') def test_soft_delete(self): d = Department.objects.create(name='儿科', category='临床') resp = self.client.delete(d_detail(d.id)) self.assertEqual(resp.status_code, 204, resp.content) self.assertFalse(Department.objects.filter(id=d.id).exists()) self.assertTrue(Department.all_objects.get(id=d.id).is_deleted) def test_recreate_soft_deleted_name_returns_400(self): """软删后用相同名称重建:返回 400 CMS_DEPARTMENT_NAME_EXISTS(不产生重复行)。 按 all_objects 校验,避免与已停用科室同名而静默新建重复记录。 """ d = Department.objects.create(name='康复科', category='临床') self.client.delete(d_detail(d.id)) self.assertFalse(Department.objects.filter(name='康复科').exists()) resp = self.client.post(CMS_DEPT_URL, {'name': '康复科', 'category': '临床'}) self.assertEqual(resp.status_code, 400, resp.content) self.assertEqual(resp.json()['code'], 'CMS_DEPARTMENT_NAME_EXISTS') self.assertEqual(Department.all_objects.filter(name='康复科').count(), 1) def test_import_and_export(self): f = make_xlsx(['科室名称', '分类'], [['心内科', '临床'], ['', 'x'], ['心内科', '临床']]) resp = self.client.post('/api/cms/departments/import/', {'file': f}, format='multipart') self.assertEqual(resp.status_code, 200, resp.content) body = resp.json() self.assertEqual(body['success'], 1) # 1 成功;空名 + 重复各 1 失败 self.assertEqual(body['failed'], 2) # 导出 resp = self.client.get('/api/cms/departments/export/') self.assertEqual(resp.status_code, 200) self.assertEqual(resp['Content-Type'], XLSX_CT) def test_import_template(self): resp = self.client.get('/api/cms/departments/import-template/') self.assertEqual(resp.status_code, 200) self.assertEqual(resp['Content-Type'], XLSX_CT)