"""移动端 U4 / CMS 端 U3 新登录语义 + 机构列表接口测试。""" from rest_framework.test import APIClient from apps.user.models import User, Institution from apps.user.auth import TRIAL_INSTITUTION_NAME, TRIAL_INSTITUTION_CODE from .conftest import ( CacheTestCase, USER_LOGIN_URL, USER_LOGIN_CODE_URL, USER_INSTITUTION_LIST_URL, inject_sms_code, create_test_user, ensure_institution, ) def _trial_institution(): inst, _ = Institution.objects.get_or_create( code=TRIAL_INSTITUTION_CODE, defaults={'name': TRIAL_INSTITUTION_NAME, 'type': 'hospital'}, ) return inst class InstitutionListTest(CacheTestCase): """机构列表接口(不分页、登录前可调用)。""" def setUp(self): super().setUp() self.client = APIClient() def test_list_unpaginated_with_trial_flag(self): ensure_institution(name='测试医院', code='TEST-HOSP-001') _trial_institution() resp = self.client.get(USER_INSTITUTION_LIST_URL) self.assertEqual(resp.status_code, 200, resp.content) data = resp.json() # 不分页:直接返回数组 self.assertIsInstance(data, list) by_code = {item['code']: item for item in data} self.assertIn('TEST-HOSP-001', by_code) self.assertIn(TRIAL_INSTITUTION_CODE, by_code) self.assertFalse(by_code['TEST-HOSP-001']['is_trial']) self.assertTrue(by_code[TRIAL_INSTITUTION_CODE]['is_trial']) class MobileLoginCodeTest(CacheTestCase): """U4 验证码登录(移动端)。""" def setUp(self): super().setUp() self.client = APIClient() def test_trial_first_register_then_login(self): _trial_institution() phone = '13900200001' # 首次:自动注册 inject_sms_code(phone, 'login', code='123456') resp = self.client.post(USER_LOGIN_CODE_URL, { 'phone': phone, 'code': '123456', 'institution_code': TRIAL_INSTITUTION_CODE, }) self.assertEqual(resp.status_code, 201, resp.content) self.assertTrue(resp.json()['is_new_user']) user = User.objects.get(phone=phone) self.assertEqual(user.role_type, 'student') # 再次:登录 inject_sms_code(phone, 'login', code='123456') resp = self.client.post(USER_LOGIN_CODE_URL, { 'phone': phone, 'code': '123456', 'institution_code': TRIAL_INSTITUTION_CODE, }) self.assertEqual(resp.status_code, 200, resp.content) self.assertFalse(resp.json()['is_new_user']) def test_non_trial_unregistered_403(self): ensure_institution(name='测试医院', code='TEST-HOSP-001') phone = '13900200002' inject_sms_code(phone, 'login', code='123456') resp = self.client.post(USER_LOGIN_CODE_URL, { 'phone': phone, 'code': '123456', 'institution_code': 'TEST-HOSP-001', }) self.assertEqual(resp.status_code, 403, resp.content) self.assertEqual(resp.json()['code'], 'AUTH_NOT_REGISTERED') def test_non_trial_institution_mismatch_403(self): inst_a = ensure_institution(name='医院A', code='HOSP-A') ensure_institution(name='医院B', code='HOSP-B') phone = '13900200003' create_test_user(phone=phone, password='x', role_type='student', institution=inst_a) inject_sms_code(phone, 'login', code='123456') resp = self.client.post(USER_LOGIN_CODE_URL, { 'phone': phone, 'code': '123456', 'institution_code': 'HOSP-B', }) self.assertEqual(resp.status_code, 403, resp.content) self.assertEqual(resp.json()['code'], 'AUTH_INSTITUTION_MISMATCH') def test_non_trial_registered_match_ok(self): inst_a = ensure_institution(name='医院A', code='HOSP-A') phone = '13900200004' create_test_user(phone=phone, password='x', role_type='student', institution=inst_a) inject_sms_code(phone, 'login', code='123456') resp = self.client.post(USER_LOGIN_CODE_URL, { 'phone': phone, 'code': '123456', 'institution_code': 'HOSP-A', }) self.assertEqual(resp.status_code, 200, resp.content) self.assertFalse(resp.json()['is_new_user']) def test_unknown_institution_code(self): phone = '13900200005' inject_sms_code(phone, 'login', code='123456') resp = self.client.post(USER_LOGIN_CODE_URL, { 'phone': phone, 'code': '123456', 'institution_code': 'NOPE', }) self.assertEqual(resp.json()['code'], 'USER_INSTITUTION_NOT_FOUND') class CmsPasswordLoginTest(CacheTestCase): """U3 密码登录(CMS 端:账号 + 密码 + 角色)。""" def setUp(self): super().setUp() self.client = APIClient() def test_login_by_phone_ok(self): phone = '13900300001' create_test_user(phone=phone, password='Doc12345', role_type='doctor') resp = self.client.post(USER_LOGIN_URL, { 'account': phone, 'password': 'Doc12345', 'role': 'doctor', }) self.assertEqual(resp.status_code, 200, resp.content) def test_login_by_username_ok(self): user = User.objects.create_user( username='cms_admin', password='Admin123', role_type='super_admin', status=1, ) resp = self.client.post(USER_LOGIN_URL, { 'account': 'cms_admin', 'password': 'Admin123', 'role': 'super_admin', }) self.assertEqual(resp.status_code, 200, resp.content) self.assertEqual(resp.json()['user']['id'], user.id) def test_missing_role_400(self): phone = '13900300002' create_test_user(phone=phone, password='Doc12345', role_type='doctor') resp = self.client.post(USER_LOGIN_URL, { 'account': phone, 'password': 'Doc12345', }) self.assertIn(resp.status_code, (400, 401)) self.assertEqual(resp.json()['code'], 'AUTH_BAD_CREDENTIALS') def test_invalid_role(self): phone = '13900300003' create_test_user(phone=phone, password='Stu12345', role_type='student') resp = self.client.post(USER_LOGIN_URL, { 'account': phone, 'password': 'Stu12345', 'role': 'student', }) self.assertEqual(resp.json()['code'], 'AUTH_INVALID_ROLE') def test_role_mismatch(self): phone = '13900300004' create_test_user(phone=phone, password='Doc12345', role_type='doctor') resp = self.client.post(USER_LOGIN_URL, { 'account': phone, 'password': 'Doc12345', 'role': 'content_admin', }) self.assertIn(resp.status_code, (400, 401)) self.assertEqual(resp.json()['code'], 'AUTH_BAD_CREDENTIALS')