- 提交体条件化:空数组不发送,修复全匹配/全新建两种场景被后端 @ArrayMinSize 拒 400 - 无论是否新建学生都先确认,避免已匹配学生被一键加入无提示 - 学员下拉保留学号/ID 兜底区分同名;科目去重键小写对齐后端唯一索引 - 任课老师空科目前端拦截;教师候选人相关调整
47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
||
import {
|
||
buildTeacherCandidateLabel,
|
||
buildTeacherCandidateOptions,
|
||
isTeacherCandidate,
|
||
type TeacherCandidateUser,
|
||
} from './teacher-candidate';
|
||
|
||
const baseUser = (overrides: Partial<TeacherCandidateUser> = {}): TeacherCandidateUser => ({
|
||
id: 1,
|
||
username: 'teacher',
|
||
name: '测试老师',
|
||
isArchived: false,
|
||
studentStatus: null,
|
||
roles: [{ code: 'teacher', name: '任课老师' }],
|
||
...overrides,
|
||
});
|
||
|
||
describe('class teacher candidates', () => {
|
||
it('keeps non-teacher staff roles because class duty is selected separately', () => {
|
||
expect(
|
||
isTeacherCandidate(baseUser({ roles: [{ code: 'academic', name: '教务管理员' }] })),
|
||
).toBe(true);
|
||
});
|
||
|
||
it('keeps staff-linked accounts so they can serve as head or life teachers', () => {
|
||
expect(isTeacherCandidate(baseUser({ studentStatus: 'staff' }))).toBe(true);
|
||
});
|
||
|
||
it('excludes active students, archived, and super-admin accounts', () => {
|
||
const users = [
|
||
baseUser({ id: 1, studentStatus: 'active' }),
|
||
baseUser({ id: 2, isArchived: true }),
|
||
baseUser({
|
||
id: 3,
|
||
roles: [{ code: 'super_admin', name: '超级管理员' }],
|
||
}),
|
||
];
|
||
|
||
expect(buildTeacherCandidateOptions(users)).toEqual([]);
|
||
});
|
||
|
||
it('shows real name, username, and system role', () => {
|
||
expect(buildTeacherCandidateLabel(baseUser())).toBe('测试老师(teacher) · 任课老师');
|
||
});
|
||
});
|