feat: update init users
This commit is contained in:
@@ -432,7 +432,7 @@ django_eval(
|
||||
f'admin = User.objects.create_user(username="{ADMIN_PHONE}", password="{ROLE_PWD}", '
|
||||
f' phone="{ADMIN_PHONE}", real_name="Swagger管理员", role_type="super_admin", status=1); '
|
||||
f'teacher = User.objects.create_user(username="{TEACHER_PHONE}", password="{ROLE_PWD}", '
|
||||
f' phone="{TEACHER_PHONE}", real_name="Swagger教师", role_type="teacher", status=1); '
|
||||
f' phone="{TEACHER_PHONE}", real_name="Swagger带教医生", role_type="doctor", status=1); '
|
||||
f'student = User.objects.create_user(username="{STUDENT_PHONE}", password="{ROLE_PWD}", '
|
||||
f' phone="{STUDENT_PHONE}", real_name="Swagger学生", role_type="student", status=1); '
|
||||
f'TeacherStudentRelation.objects.create(teacher=teacher, student=student, '
|
||||
|
||||
+179
-179
@@ -1,179 +1,179 @@
|
||||
"""移动端病例列表 5 接口测试。
|
||||
|
||||
- 5.1 推荐病例 GET /api/case/mobile/recommended/
|
||||
- 5.2 科室专项 GET /api/case/mobile/specialty/
|
||||
- 5.3 薄弱环节 GET /api/case/mobile/weak/
|
||||
- 5.4 教学互动 GET /api/case/mobile/teaching/
|
||||
- 5.5 教师任务 GET /api/case/mobile/teacher-task/
|
||||
|
||||
均只取「已发布」病例(publish_status=2 & status=1 & is_deleted=0)。
|
||||
training_record 是 managed=False 只读表,迁移占位结构缺新列,故在 setUpClass 里按真实列
|
||||
重建该表(仅测试库),用 TransactionTestCase 允许 DDL(与 test_cms_training 一致)。
|
||||
"""
|
||||
import json
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.db import connection
|
||||
from django.test import TransactionTestCase
|
||||
from django.utils import timezone
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from apps.user.models import Department
|
||||
from apps.case.models import CaseBase
|
||||
from .conftest import create_test_user, get_auth_client, ensure_institution
|
||||
|
||||
CREATE_TR = """
|
||||
CREATE TABLE training_record (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id BIGINT NULL, case_id BIGINT NULL, teacher_id BIGINT NULL,
|
||||
training_mode VARCHAR(50) NULL, case_type VARCHAR(30) NULL,
|
||||
start_time DATETIME NULL, end_time DATETIME NULL, duration_seconds INT NULL,
|
||||
total_score DECIMAL(5,2) NULL, ai_score DECIMAL(5,2) NULL, teacher_score DECIMAL(5,2) NULL,
|
||||
evaluation_level VARCHAR(20) NULL, status VARCHAR(30) NULL,
|
||||
feedback TEXT NULL, thinking_chain TEXT NULL, diagnosis_path TEXT NULL,
|
||||
wrong_points JSON NULL, missed_questions JSON NULL, recommendation_result JSON NULL,
|
||||
ai_feedback_structured JSON NULL, osce_station_score JSON NULL,
|
||||
interruption_count INT NULL, emotion_analysis JSON NULL,
|
||||
prompt_version VARCHAR(50) NULL, rag_context_version VARCHAR(50) NULL,
|
||||
external_user_id VARCHAR(128) NULL, session_id BIGINT NULL, evaluation_record_id BIGINT NULL,
|
||||
score_type VARCHAR(20) NULL, pdf_file_path VARCHAR(512) NULL,
|
||||
created_at DATETIME NULL, updated_at DATETIME NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||
"""
|
||||
|
||||
REC_URL = '/api/case/mobile/recommended/'
|
||||
SPEC_URL = '/api/case/mobile/specialty/'
|
||||
WEAK_URL = '/api/case/mobile/weak/'
|
||||
TEACH_URL = '/api/case/mobile/teaching/'
|
||||
TASK_URL = '/api/case/mobile/teacher-task/'
|
||||
|
||||
|
||||
class MobileCaseListTest(TransactionTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
with connection.cursor() as c:
|
||||
c.execute('SET FOREIGN_KEY_CHECKS=0')
|
||||
c.execute('DROP TABLE IF EXISTS training_record')
|
||||
c.execute(CREATE_TR)
|
||||
c.execute('SET FOREIGN_KEY_CHECKS=1')
|
||||
|
||||
def _insert(self, user_id, case_id, total_score, status='completed', score_type='percentage'):
|
||||
now = timezone.now()
|
||||
with connection.cursor() as c:
|
||||
c.execute(
|
||||
"INSERT INTO training_record (user_id, case_id, training_mode, status, "
|
||||
"total_score, end_time, start_time, score_type, ai_feedback_structured, "
|
||||
"created_at, updated_at) VALUES (%s,%s,'practice',%s,%s,%s,%s,%s,%s,%s,%s)",
|
||||
[user_id, case_id, status, total_score, now, now, score_type,
|
||||
json.dumps({}), now, now],
|
||||
)
|
||||
return c.lastrowid
|
||||
|
||||
def setUp(self):
|
||||
cache.clear()
|
||||
with connection.cursor() as c:
|
||||
c.execute('DELETE FROM training_record')
|
||||
self.inst = ensure_institution(name='测试医院', code='MCL-H1')
|
||||
self.dept1 = Department.objects.create(name='心内科', category='临床')
|
||||
self.dept2 = Department.objects.create(name='呼吸科', category='临床')
|
||||
|
||||
# 已发布病例
|
||||
self.pub_trad1 = CaseBase.objects.create(
|
||||
title='急性心梗', case_type='traditional', department=self.dept1,
|
||||
institution=self.inst, chief_complaint='胸痛', tags='心内科,胸痛',
|
||||
publish_status=2, status=1)
|
||||
self.pub_teach = CaseBase.objects.create(
|
||||
title='医患沟通教学', case_type='teaching', department=self.dept1,
|
||||
institution=self.inst, competency_tags=['沟通人文', '医患沟通'],
|
||||
publish_status=2, status=1)
|
||||
self.pub_trad2 = CaseBase.objects.create(
|
||||
title='肺炎诊治', case_type='traditional', department=self.dept2,
|
||||
institution=self.inst, tags='呼吸科', publish_status=2, status=1)
|
||||
# 不应出现:草稿 / 禁用 / 已下架(软删)
|
||||
CaseBase.objects.create(title='草稿病例', case_type='traditional',
|
||||
department=self.dept1, institution=self.inst, publish_status=0, status=1)
|
||||
CaseBase.objects.create(title='禁用病例', case_type='traditional',
|
||||
department=self.dept1, institution=self.inst, publish_status=2, status=0)
|
||||
deleted = CaseBase.objects.create(title='已下架病例', case_type='teaching',
|
||||
department=self.dept1, institution=self.inst, publish_status=2, status=1)
|
||||
deleted.delete() # 软删除
|
||||
|
||||
self.stu = create_test_user(phone='13980000001', real_name='学生甲',
|
||||
role_type='student', institution=self.inst)
|
||||
self.stu.department = self.dept1
|
||||
self.stu.weak_dimensions = ['沟通人文']
|
||||
self.stu.save(update_fields=['department', 'weak_dimensions'])
|
||||
|
||||
# stu 已训练:pub_trad1 低分(60→薄弱),pub_trad2 高分(90)
|
||||
self._insert(self.stu.id, self.pub_trad1.id, 60)
|
||||
self._insert(self.stu.id, self.pub_trad2.id, 90)
|
||||
|
||||
self.client = get_auth_client(self.stu)
|
||||
|
||||
def _ids(self, resp):
|
||||
return [r['id'] for r in resp.json()['results']]
|
||||
|
||||
# ── 鉴权 ────────────────────────────────────────────────────────────────
|
||||
def test_unauthenticated_401(self):
|
||||
for url in (REC_URL, SPEC_URL, WEAK_URL, TEACH_URL, TASK_URL):
|
||||
self.assertEqual(APIClient().get(url).status_code, 401, url)
|
||||
|
||||
# ── 5.1 推荐 ───────────────────────────────────────────────────────────
|
||||
def test_recommended_only_published(self):
|
||||
resp = self.client.get(REC_URL)
|
||||
self.assertEqual(resp.status_code, 200, resp.content)
|
||||
ids = set(self._ids(resp))
|
||||
self.assertEqual(resp.json()['count'], 3)
|
||||
self.assertEqual(ids, {self.pub_trad1.id, self.pub_teach.id, self.pub_trad2.id})
|
||||
|
||||
def test_recommended_untrained_first(self):
|
||||
# pub_teach 未训练且命中薄弱标签+同科室 → 应排在已训练病例之前
|
||||
resp = self.client.get(REC_URL)
|
||||
self.assertEqual(self._ids(resp)[0], self.pub_teach.id, resp.content)
|
||||
|
||||
# ── 5.2 科室专项 ──────────────────────────────────────────────────────────
|
||||
def test_specialty_default_user_dept(self):
|
||||
resp = self.client.get(SPEC_URL)
|
||||
self.assertEqual(set(self._ids(resp)), {self.pub_trad1.id, self.pub_teach.id})
|
||||
|
||||
def test_specialty_explicit_department(self):
|
||||
resp = self.client.get(SPEC_URL, {'department': self.dept2.id})
|
||||
self.assertEqual(self._ids(resp), [self.pub_trad2.id])
|
||||
|
||||
# ── 5.3 薄弱环节 ──────────────────────────────────────────────────────────
|
||||
def test_weak_low_score_cases(self):
|
||||
resp = self.client.get(WEAK_URL)
|
||||
self.assertEqual(resp.status_code, 200, resp.content)
|
||||
results = resp.json()['results']
|
||||
self.assertEqual([r['id'] for r in results], [self.pub_trad1.id])
|
||||
self.assertEqual(results[0]['my_best_score'], 60.0)
|
||||
self.assertEqual(results[0]['my_train_count'], 1)
|
||||
|
||||
def test_weak_cold_start_fallback(self):
|
||||
# 新用户无训练记录,但 weak_dimensions 命中 pub_teach 能力标签 → 回退命中
|
||||
fresh = create_test_user(phone='13980000009', role_type='student', institution=self.inst)
|
||||
fresh.weak_dimensions = ['沟通人文']
|
||||
fresh.save(update_fields=['weak_dimensions'])
|
||||
resp = get_auth_client(fresh).get(WEAK_URL)
|
||||
self.assertEqual(self._ids(resp), [self.pub_teach.id], resp.content)
|
||||
|
||||
# ── 5.4 教学互动 ──────────────────────────────────────────────────────────
|
||||
def test_teaching_only_teaching_type(self):
|
||||
resp = self.client.get(TEACH_URL)
|
||||
self.assertEqual(self._ids(resp), [self.pub_teach.id])
|
||||
|
||||
# ── 5.5 教师任务(暂同教学互动)────────────────────────────────────────────
|
||||
def test_teacher_task_same_as_teaching(self):
|
||||
resp = self.client.get(TASK_URL)
|
||||
self.assertEqual(self._ids(resp), [self.pub_teach.id])
|
||||
|
||||
# ── 通用过滤 ──────────────────────────────────────────────────────────────
|
||||
def test_search_filter(self):
|
||||
resp = self.client.get(REC_URL, {'search': '心梗'})
|
||||
self.assertEqual(self._ids(resp), [self.pub_trad1.id])
|
||||
|
||||
def test_case_type_filter(self):
|
||||
resp = self.client.get(REC_URL, {'case_type': 'teaching'})
|
||||
self.assertEqual(self._ids(resp), [self.pub_teach.id])
|
||||
"""移动端病例列表 5 接口测试。
|
||||
|
||||
- 5.1 推荐病例 GET /api/case/mobile/recommended/
|
||||
- 5.2 科室专项 GET /api/case/mobile/specialty/
|
||||
- 5.3 薄弱环节 GET /api/case/mobile/weak/
|
||||
- 5.4 教学互动 GET /api/case/mobile/teaching/
|
||||
- 5.5 教师任务 GET /api/case/mobile/teacher-task/
|
||||
|
||||
均只取「已发布」病例(publish_status=2 & status=1 & is_deleted=0)。
|
||||
training_record 是 managed=False 只读表,迁移占位结构缺新列,故在 setUpClass 里按真实列
|
||||
重建该表(仅测试库),用 TransactionTestCase 允许 DDL(与 test_cms_training 一致)。
|
||||
"""
|
||||
import json
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.db import connection
|
||||
from django.test import TransactionTestCase
|
||||
from django.utils import timezone
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from apps.user.models import Department
|
||||
from apps.case.models import CaseBase
|
||||
from .conftest import create_test_user, get_auth_client, ensure_institution
|
||||
|
||||
CREATE_TR = """
|
||||
CREATE TABLE training_record (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id BIGINT NULL, case_id BIGINT NULL, teacher_id BIGINT NULL,
|
||||
training_mode VARCHAR(50) NULL, case_type VARCHAR(30) NULL,
|
||||
start_time DATETIME NULL, end_time DATETIME NULL, duration_seconds INT NULL,
|
||||
total_score DECIMAL(5,2) NULL, ai_score DECIMAL(5,2) NULL, teacher_score DECIMAL(5,2) NULL,
|
||||
evaluation_level VARCHAR(20) NULL, status VARCHAR(30) NULL,
|
||||
feedback TEXT NULL, thinking_chain TEXT NULL, diagnosis_path TEXT NULL,
|
||||
wrong_points JSON NULL, missed_questions JSON NULL, recommendation_result JSON NULL,
|
||||
ai_feedback_structured JSON NULL, osce_station_score JSON NULL,
|
||||
interruption_count INT NULL, emotion_analysis JSON NULL,
|
||||
prompt_version VARCHAR(50) NULL, rag_context_version VARCHAR(50) NULL,
|
||||
external_user_id VARCHAR(128) NULL, session_id BIGINT NULL, evaluation_record_id BIGINT NULL,
|
||||
score_type VARCHAR(20) NULL, pdf_file_path VARCHAR(512) NULL,
|
||||
created_at DATETIME NULL, updated_at DATETIME NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
|
||||
"""
|
||||
|
||||
REC_URL = '/api/case/mobile/recommended/'
|
||||
SPEC_URL = '/api/case/mobile/specialty/'
|
||||
WEAK_URL = '/api/case/mobile/weak/'
|
||||
TEACH_URL = '/api/case/mobile/teaching/'
|
||||
TASK_URL = '/api/case/mobile/teacher-task/'
|
||||
|
||||
|
||||
class MobileCaseListTest(TransactionTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
with connection.cursor() as c:
|
||||
c.execute('SET FOREIGN_KEY_CHECKS=0')
|
||||
c.execute('DROP TABLE IF EXISTS training_record')
|
||||
c.execute(CREATE_TR)
|
||||
c.execute('SET FOREIGN_KEY_CHECKS=1')
|
||||
|
||||
def _insert(self, user_id, case_id, total_score, status='completed', score_type='percentage'):
|
||||
now = timezone.now()
|
||||
with connection.cursor() as c:
|
||||
c.execute(
|
||||
"INSERT INTO training_record (user_id, case_id, training_mode, status, "
|
||||
"total_score, end_time, start_time, score_type, ai_feedback_structured, "
|
||||
"created_at, updated_at) VALUES (%s,%s,'practice',%s,%s,%s,%s,%s,%s,%s,%s)",
|
||||
[user_id, case_id, status, total_score, now, now, score_type,
|
||||
json.dumps({}), now, now],
|
||||
)
|
||||
return c.lastrowid
|
||||
|
||||
def setUp(self):
|
||||
cache.clear()
|
||||
with connection.cursor() as c:
|
||||
c.execute('DELETE FROM training_record')
|
||||
self.inst = ensure_institution(name='测试医院', code='MCL-H1')
|
||||
self.dept1 = Department.objects.create(name='心内科', category='临床')
|
||||
self.dept2 = Department.objects.create(name='呼吸科', category='临床')
|
||||
|
||||
# 已发布病例
|
||||
self.pub_trad1 = CaseBase.objects.create(
|
||||
title='急性心梗', case_type='traditional', department=self.dept1,
|
||||
institution=self.inst, chief_complaint='胸痛', tags='心内科,胸痛',
|
||||
publish_status=2, status=1)
|
||||
self.pub_teach = CaseBase.objects.create(
|
||||
title='医患沟通教学', case_type='teaching', department=self.dept1,
|
||||
institution=self.inst, competency_tags=['沟通人文', '医患沟通'],
|
||||
publish_status=2, status=1)
|
||||
self.pub_trad2 = CaseBase.objects.create(
|
||||
title='肺炎诊治', case_type='traditional', department=self.dept2,
|
||||
institution=self.inst, tags='呼吸科', publish_status=2, status=1)
|
||||
# 不应出现:草稿 / 禁用 / 已下架(软删)
|
||||
CaseBase.objects.create(title='草稿病例', case_type='traditional',
|
||||
department=self.dept1, institution=self.inst, publish_status=0, status=1)
|
||||
CaseBase.objects.create(title='禁用病例', case_type='traditional',
|
||||
department=self.dept1, institution=self.inst, publish_status=2, status=0)
|
||||
deleted = CaseBase.objects.create(title='已下架病例', case_type='teaching',
|
||||
department=self.dept1, institution=self.inst, publish_status=2, status=1)
|
||||
deleted.delete() # 软删除
|
||||
|
||||
self.stu = create_test_user(phone='13980000001', real_name='学生甲',
|
||||
role_type='student', institution=self.inst)
|
||||
self.stu.department = self.dept1
|
||||
self.stu.weak_dimensions = ['沟通人文']
|
||||
self.stu.save(update_fields=['department', 'weak_dimensions'])
|
||||
|
||||
# stu 已训练:pub_trad1 低分(60→薄弱),pub_trad2 高分(90)
|
||||
self._insert(self.stu.id, self.pub_trad1.id, 60)
|
||||
self._insert(self.stu.id, self.pub_trad2.id, 90)
|
||||
|
||||
self.client = get_auth_client(self.stu)
|
||||
|
||||
def _ids(self, resp):
|
||||
return [r['id'] for r in resp.json()['results']]
|
||||
|
||||
# ── 鉴权 ────────────────────────────────────────────────────────────────
|
||||
def test_unauthenticated_401(self):
|
||||
for url in (REC_URL, SPEC_URL, WEAK_URL, TEACH_URL, TASK_URL):
|
||||
self.assertEqual(APIClient().get(url).status_code, 401, url)
|
||||
|
||||
# ── 5.1 推荐 ───────────────────────────────────────────────────────────
|
||||
def test_recommended_only_published(self):
|
||||
resp = self.client.get(REC_URL)
|
||||
self.assertEqual(resp.status_code, 200, resp.content)
|
||||
ids = set(self._ids(resp))
|
||||
self.assertEqual(resp.json()['count'], 3)
|
||||
self.assertEqual(ids, {self.pub_trad1.id, self.pub_teach.id, self.pub_trad2.id})
|
||||
|
||||
def test_recommended_untrained_first(self):
|
||||
# pub_teach 未训练且命中薄弱标签+同科室 → 应排在已训练病例之前
|
||||
resp = self.client.get(REC_URL)
|
||||
self.assertEqual(self._ids(resp)[0], self.pub_teach.id, resp.content)
|
||||
|
||||
# ── 5.2 科室专项 ──────────────────────────────────────────────────────────
|
||||
def test_specialty_default_user_dept(self):
|
||||
resp = self.client.get(SPEC_URL)
|
||||
self.assertEqual(set(self._ids(resp)), {self.pub_trad1.id, self.pub_teach.id})
|
||||
|
||||
def test_specialty_explicit_department(self):
|
||||
resp = self.client.get(SPEC_URL, {'department': self.dept2.id})
|
||||
self.assertEqual(self._ids(resp), [self.pub_trad2.id])
|
||||
|
||||
# ── 5.3 薄弱环节 ──────────────────────────────────────────────────────────
|
||||
def test_weak_low_score_cases(self):
|
||||
resp = self.client.get(WEAK_URL)
|
||||
self.assertEqual(resp.status_code, 200, resp.content)
|
||||
results = resp.json()['results']
|
||||
self.assertEqual([r['id'] for r in results], [self.pub_trad1.id])
|
||||
self.assertEqual(results[0]['my_best_score'], 60.0)
|
||||
self.assertEqual(results[0]['my_train_count'], 1)
|
||||
|
||||
def test_weak_cold_start_fallback(self):
|
||||
# 新用户无训练记录,但 weak_dimensions 命中 pub_teach 能力标签 → 回退命中
|
||||
fresh = create_test_user(phone='13980000009', role_type='student', institution=self.inst)
|
||||
fresh.weak_dimensions = ['沟通人文']
|
||||
fresh.save(update_fields=['weak_dimensions'])
|
||||
resp = get_auth_client(fresh).get(WEAK_URL)
|
||||
self.assertEqual(self._ids(resp), [self.pub_teach.id], resp.content)
|
||||
|
||||
# ── 5.4 教学互动 ──────────────────────────────────────────────────────────
|
||||
def test_teaching_only_teaching_type(self):
|
||||
resp = self.client.get(TEACH_URL)
|
||||
self.assertEqual(self._ids(resp), [self.pub_teach.id])
|
||||
|
||||
# ── 5.5 教师任务(暂同教学互动)────────────────────────────────────────────
|
||||
def test_teacher_task_same_as_teaching(self):
|
||||
resp = self.client.get(TASK_URL)
|
||||
self.assertEqual(self._ids(resp), [self.pub_teach.id])
|
||||
|
||||
# ── 通用过滤 ──────────────────────────────────────────────────────────────
|
||||
def test_search_filter(self):
|
||||
resp = self.client.get(REC_URL, {'search': '心梗'})
|
||||
self.assertEqual(self._ids(resp), [self.pub_trad1.id])
|
||||
|
||||
def test_case_type_filter(self):
|
||||
resp = self.client.get(REC_URL, {'case_type': 'teaching'})
|
||||
self.assertEqual(self._ids(resp), [self.pub_teach.id])
|
||||
|
||||
@@ -245,7 +245,7 @@ class UserListDetailHappyPathTest(CacheTestCase):
|
||||
"""HP-6: teacher GET /users/ → 200,仅包含名下活跃学生"""
|
||||
teacher = create_test_user(
|
||||
phone='13900100010', password='Teacher1',
|
||||
real_name='王老师', role_type='teacher',
|
||||
real_name='王老师', role_type='doctor',
|
||||
)
|
||||
stu_own = create_test_user(
|
||||
phone='13900100011', password='Stu12345',
|
||||
@@ -277,7 +277,7 @@ class UserListDetailHappyPathTest(CacheTestCase):
|
||||
"""HP-7: 已结束(status=0)的师生关系学生不出现在列表"""
|
||||
teacher = create_test_user(
|
||||
phone='13900100020', password='Teacher1',
|
||||
real_name='李老师', role_type='teacher',
|
||||
real_name='李老师', role_type='doctor',
|
||||
)
|
||||
stu_active = create_test_user(
|
||||
phone='13900100021', password='Stu12345',
|
||||
@@ -339,7 +339,7 @@ class UserListDetailHappyPathTest(CacheTestCase):
|
||||
"""HP-10: teacher GET /users/{student.id}/ → 200,可查看名下学生"""
|
||||
teacher = create_test_user(
|
||||
phone='13900100050', password='Teacher1',
|
||||
real_name='赵老师', role_type='teacher',
|
||||
real_name='赵老师', role_type='doctor',
|
||||
)
|
||||
student = create_test_user(
|
||||
phone='13900100051', password='Stu12345',
|
||||
@@ -370,7 +370,7 @@ class UserListDetailHappyPathTest(CacheTestCase):
|
||||
)
|
||||
teacher = create_test_user(
|
||||
phone='13900100063', password='Teacher1',
|
||||
real_name='张老师', role_type='teacher',
|
||||
real_name='张老师', role_type='doctor',
|
||||
)
|
||||
|
||||
client = get_auth_client(admin)
|
||||
|
||||
@@ -272,16 +272,16 @@ class UserListDetailNegativeTest(CacheTestCase):
|
||||
self.assertEqual(resp.status_code, 403, resp.content)
|
||||
self.assertEqual(resp.json()['code'], 'USER_NO_LIST_PERMISSION')
|
||||
|
||||
def test_doctor_list_403(self):
|
||||
"""N12: doctor GET /users/ → 403 USER_NO_LIST_PERMISSION"""
|
||||
def test_doctor_list_returns_own_students_only(self):
|
||||
"""N12(新设计): doctor=带教医生 GET /users/ → 200,仅名下学生(无学生时为空列表)"""
|
||||
doctor = create_test_user(
|
||||
phone='13800002002', password='Doc12345',
|
||||
real_name='医生', role_type='doctor',
|
||||
)
|
||||
client = get_auth_client(doctor)
|
||||
resp = client.get(USER_LIST_URL)
|
||||
self.assertEqual(resp.status_code, 403, resp.content)
|
||||
self.assertEqual(resp.json()['code'], 'USER_NO_LIST_PERMISSION')
|
||||
self.assertEqual(resp.status_code, 200, resp.content)
|
||||
self.assertEqual(resp.json()['count'], 0) # 无名下学生 → 空
|
||||
|
||||
def test_unauth_list_401(self):
|
||||
"""N13: 未登录 GET /users/ → 401"""
|
||||
@@ -315,7 +315,7 @@ class UserListDetailNegativeTest(CacheTestCase):
|
||||
"""N16: teacher 查看非名下学生详情 → 403 USER_NO_VIEW_PERMISSION"""
|
||||
teacher = create_test_user(
|
||||
phone='13800002030', password='Teacher1',
|
||||
real_name='刘老师', role_type='teacher',
|
||||
real_name='刘老师', role_type='doctor',
|
||||
)
|
||||
unrelated = create_test_user(
|
||||
phone='13800002031', password='Stu12345',
|
||||
@@ -331,7 +331,7 @@ class UserListDetailNegativeTest(CacheTestCase):
|
||||
"""N17: teacher 查看已结束关系学生详情 → 403 USER_NO_VIEW_PERMISSION"""
|
||||
teacher = create_test_user(
|
||||
phone='13800002040', password='Teacher1',
|
||||
real_name='陈老师', role_type='teacher',
|
||||
real_name='陈老师', role_type='doctor',
|
||||
)
|
||||
student = create_test_user(
|
||||
phone='13800002041', password='Stu12345',
|
||||
|
||||
Reference in New Issue
Block a user