支持下载标准导入模板。 导出严格沿用当前关键词、学院、分类、课程性质和状态筛选。 以课程编码为唯一键:存在则更新,不存在则新增。 校验学院编码、课程分类、课程性质、学分学时及考核方式。 整批原子导入,任一行错误则全部不写入,并提示具体行号。 学院管理员仍只能维护本学院的专业课和实践课,无法借 Excel 越权。 界面入口沿用现有课程库工具栏样式。
102 lines
3.5 KiB
C#
102 lines
3.5 KiB
C#
using Jiaowu.Api.Domain.Academic;
|
|
using Jiaowu.Api.Infrastructure.Graduation;
|
|
|
|
namespace Jiaowu.Api.Tests;
|
|
|
|
public sealed class GraduationAuditRulesTests
|
|
{
|
|
[Fact]
|
|
public void Curriculum_groups_Accept_Any_Options_That_Fulfill_Required_Credits()
|
|
{
|
|
var football = new Course { Code = "PE101", Name = "足球", Credits = 1 };
|
|
var basketball = new Course { Code = "PE102", Name = "篮球", Credits = 1 };
|
|
var swimming = new Course { Code = "PE103", Name = "游泳", Credits = 1 };
|
|
var module = new CurriculumModule
|
|
{
|
|
Code = "SPORTS",
|
|
Name = "大学体育",
|
|
RequiredCredits = 2,
|
|
Courses = [Option(football), Option(basketball), Option(swimming)]
|
|
};
|
|
|
|
var completed = CurriculumCompletionRules.Evaluate(
|
|
[module],
|
|
new HashSet<Guid>([football.Id, swimming.Id]));
|
|
var incomplete = CurriculumCompletionRules.Evaluate(
|
|
[module],
|
|
new HashSet<Guid>([football.Id]));
|
|
|
|
Assert.Equal(1, completed.RequirementCount);
|
|
Assert.Equal(1, completed.PassedRequirementCount);
|
|
Assert.Empty(completed.MissingRequirements);
|
|
Assert.Equal(0, incomplete.PassedRequirementCount);
|
|
Assert.Contains("大学体育(还差 1 学分)", incomplete.MissingRequirements);
|
|
}
|
|
|
|
[Fact]
|
|
public void Curriculum_groups_Still_Require_Every_Fixed_Course()
|
|
{
|
|
var ideology = new Course { Code = "MORAL101", Name = "思想道德与法治", Credits = 3 };
|
|
var module = new CurriculumModule
|
|
{
|
|
Code = "MORAL",
|
|
Name = "德育课程",
|
|
RequiredCredits = 3,
|
|
Courses =
|
|
[
|
|
new CurriculumCourse
|
|
{
|
|
CourseId = ideology.Id,
|
|
Course = ideology,
|
|
Type = CurriculumCourseType.Required
|
|
}
|
|
]
|
|
};
|
|
|
|
var result = CurriculumCompletionRules.Evaluate([module], new HashSet<Guid>());
|
|
|
|
Assert.Equal(1, result.RequirementCount);
|
|
Assert.Equal(0, result.PassedRequirementCount);
|
|
Assert.Contains("思想道德与法治", result.MissingRequirements);
|
|
}
|
|
|
|
[Fact]
|
|
public void Active_student_with_full_credits_and_courses_is_eligible()
|
|
{
|
|
var conclusion = GraduationAuditRules.Evaluate(
|
|
true, StudentStatus.Active, 160, 162, 42, 42, 0);
|
|
|
|
Assert.Equal(GraduationAuditConclusion.Eligible, conclusion);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(false, StudentStatus.Active, 160, 162, 42, 42, 0)]
|
|
[InlineData(true, StudentStatus.Suspended, 160, 162, 42, 42, 0)]
|
|
[InlineData(true, StudentStatus.Active, 160, 159, 42, 42, 0)]
|
|
[InlineData(true, StudentStatus.Active, 160, 162, 42, 41, 0)]
|
|
[InlineData(true, StudentStatus.Active, 160, 162, 42, 42, 1)]
|
|
public void Any_unresolved_requirement_makes_student_ineligible(
|
|
bool hasPlan,
|
|
StudentStatus status,
|
|
decimal requiredCredits,
|
|
decimal earnedCredits,
|
|
int requiredCourses,
|
|
int passedRequiredCourses,
|
|
int failedCourses)
|
|
{
|
|
var conclusion = GraduationAuditRules.Evaluate(
|
|
hasPlan, status, requiredCredits, earnedCredits,
|
|
requiredCourses, passedRequiredCourses, failedCourses);
|
|
|
|
Assert.Equal(GraduationAuditConclusion.Ineligible, conclusion);
|
|
}
|
|
|
|
private static CurriculumCourse Option(Course course) =>
|
|
new()
|
|
{
|
|
CourseId = course.Id,
|
|
Course = course,
|
|
Type = CurriculumCourseType.Elective
|
|
};
|
|
}
|