Files
medical_training/test/test_cms_students.py
T

129 lines
6.3 KiB
Python

"""CMS 带教医生 - 我的学生测试:CMS-TEA-1~2。
带教医生(doctor)仅能看到 teacher_student_relation 中
teacher=自己 且 status=1 的学生;只读,不能新增/编辑/删除。
"""
from rest_framework.test import APIClient
from apps.user.models import TeacherStudentRelation
from .conftest import (
CacheTestCase,
create_test_user,
get_auth_client,
ensure_institution,
ensure_department,
create_teacher_student_relation,
)
STUDENTS_URL = '/api/cms/students/'
def student_detail(pk):
return f'/api/cms/students/{pk}/'
class CmsStudentsTest(CacheTestCase):
def setUp(self):
super().setUp()
self.inst = ensure_institution(name='本院', code='TEA-A')
self.dept = ensure_department(name='内科')
self.doc = create_test_user(
phone='13940000001', password='Doc12345',
real_name='张医生', role_type='doctor', institution=self.inst,
)
self.other_doc = create_test_user(
phone='13940000002', real_name='李医生',
role_type='doctor', institution=self.inst,
)
# 名下进行中学生
self.stu_own = create_test_user(
phone='13940000011', real_name='我的学生',
role_type='student', institution=self.inst,
)
self.stu_own.department = self.dept
self.stu_own.save(update_fields=['department'])
# 名下已结束学生(status=0,列表应排除)
self.stu_ended = create_test_user(
phone='13940000012', real_name='已毕业学生',
role_type='student', institution=self.inst,
)
# 其他医生的学生(当前医生不应看到)
self.stu_other = create_test_user(
phone='13940000013', real_name='其他学生',
role_type='student', institution=self.inst,
)
create_teacher_student_relation(self.doc, self.stu_own, status=1)
create_teacher_student_relation(self.doc, self.stu_ended, status=0)
create_teacher_student_relation(self.other_doc, self.stu_other, status=1)
self.client = get_auth_client(self.doc)
# ── 权限 ──────────────────────────────────────────────────────────────────
def test_unauthenticated_401(self):
self.assertEqual(APIClient().get(STUDENTS_URL).status_code, 401)
def test_non_doctor_403(self):
admin = create_test_user(phone='13940000091', role_type='hospital_admin',
institution=self.inst)
resp = get_auth_client(admin).get(STUDENTS_URL)
self.assertEqual(resp.status_code, 403, resp.content)
self.assertEqual(resp.json()['code'], 'CMS_PERMISSION_DENIED')
# 学生本人也无权访问
resp2 = get_auth_client(self.stu_own).get(STUDENTS_URL)
self.assertEqual(resp2.status_code, 403, resp2.content)
# ── CMS-TEA-1 列表 ─────────────────────────────────────────────────────────
def test_list_own_active_students_only(self):
resp = self.client.get(STUDENTS_URL)
self.assertEqual(resp.status_code, 200, resp.content)
results = resp.json()['results']
ids = {u['id'] for u in results}
self.assertIn(self.stu_own.id, ids)
self.assertNotIn(self.stu_ended.id, ids) # status=0
self.assertNotIn(self.stu_other.id, ids) # 他医生
self.assertNotIn(self.doc.id, ids) # 不含自己
self.assertEqual(len(results), 1)
def test_list_search(self):
resp = self.client.get(STUDENTS_URL, {'search': '我的学生'})
self.assertEqual(resp.status_code, 200, resp.content)
ids = {u['id'] for u in resp.json()['results']}
self.assertEqual(ids, {self.stu_own.id})
def test_list_student_fields(self):
resp = self.client.get(STUDENTS_URL)
item = resp.json()['results'][0]
self.assertEqual(item['real_name'], '我的学生')
self.assertEqual(item['role_type'], 'student')
self.assertEqual(item['department_name'], '内科')
self.assertIn('total_training_count', item)
# ── CMS-TEA-2 详情 ─────────────────────────────────────────────────────────
def test_retrieve_own_student(self):
resp = self.client.get(student_detail(self.stu_own.id))
self.assertEqual(resp.status_code, 200, resp.content)
self.assertEqual(resp.json()['real_name'], '我的学生')
self.assertEqual(resp.json()['phone'], '13940000011')
def test_retrieve_other_student_404(self):
resp = self.client.get(student_detail(self.stu_other.id))
self.assertEqual(resp.status_code, 404, resp.content)
def test_retrieve_ended_student_404(self):
resp = self.client.get(student_detail(self.stu_ended.id))
self.assertEqual(resp.status_code, 404, resp.content)
# ── 软删除师生关系 ─────────────────────────────────────────────────────────
def test_soft_deleted_relation_excludes_student(self):
rel = TeacherStudentRelation.objects.get(teacher=self.doc, student=self.stu_own)
rel.delete() # SoftDeleteModel 逻辑删除
resp = self.client.get(STUDENTS_URL)
self.assertEqual(resp.status_code, 200, resp.content)
ids = {u['id'] for u in resp.json()['results']}
self.assertNotIn(self.stu_own.id, ids)
# ── 只读 ──────────────────────────────────────────────────────────────────
def test_readonly_methods_not_allowed(self):
self.assertEqual(self.client.post(STUDENTS_URL, {}).status_code, 405)
self.assertEqual(self.client.delete(student_detail(self.stu_own.id)).status_code, 405)