Files
Academic-Affairs-System/tests/Jiaowu.Api.Tests/ScheduleConflictTests.cs
T
biss 6538b6080a 自动排课:保留手工安排,按教师、行政班、周次、节次、容量和场地约束补排。
课程约束:可限定校区、教学楼、指定教室、允许上课日、最早/最晚节次。
无教室课程:教室可为空,但仍校验教师和班级冲突。
作息维护:按学期维护节次、上下课时间和启用状态。
发布保护:发布前重新检查全部约束,并阻止学时未排满的课表发布。
工作台升级:增加“排课规则与作息”“自动排课”入口,自动生成后仍支持手工微调。
同时兼容 SQLite 和 MySQL,已生成正式迁移。
2026-07-24 19:19:18 +08:00

100 lines
3.0 KiB
C#

using Jiaowu.Api.Domain.Academic;
using Jiaowu.Api.Infrastructure.Scheduling;
namespace Jiaowu.Api.Tests;
public sealed class ScheduleConflictTests
{
[Fact]
public void Same_classroom_and_overlapping_weeks_conflict()
{
var classroomId = Guid.NewGuid();
var first = Entry(classroomId, WeekPattern.All, new TeachingTask
{
TaskNumber = "TASK-1",
Name = "教学班一"
});
var second = Entry(classroomId, WeekPattern.All, new TeachingTask
{
TaskNumber = "TASK-2",
Name = "教学班二"
});
Assert.True(ScheduleConflictDetector.TimeOverlaps(first, second));
Assert.Equal("教室", ScheduleConflictDetector.ConflictReason(first, second));
}
[Fact]
public void Odd_and_even_week_arrangements_do_not_overlap()
{
var first = Entry(Guid.NewGuid(), WeekPattern.Odd, new TeachingTask
{
TaskNumber = "TASK-1",
Name = "教学班一"
});
var second = Entry(Guid.NewGuid(), WeekPattern.Even, new TeachingTask
{
TaskNumber = "TASK-2",
Name = "教学班二"
});
Assert.False(ScheduleConflictDetector.TimeOverlaps(first, second));
}
[Fact]
public void Shared_teacher_conflicts_across_different_classrooms()
{
var teacherId = Guid.NewGuid();
var firstTask = new TeachingTask
{
TaskNumber = "TASK-1",
Name = "教学班一",
Teachers = [new TeachingTaskTeacher { TeacherId = teacherId }]
};
var secondTask = new TeachingTask
{
TaskNumber = "TASK-2",
Name = "教学班二",
Teachers = [new TeachingTaskTeacher { TeacherId = teacherId }]
};
var first = Entry(Guid.NewGuid(), WeekPattern.All, firstTask);
var second = Entry(Guid.NewGuid(), WeekPattern.All, secondTask);
Assert.Equal("教师", ScheduleConflictDetector.ConflictReason(first, second));
}
[Fact]
public void Two_roomless_courses_do_not_create_a_classroom_conflict()
{
var first = Entry(null, WeekPattern.All, new TeachingTask
{
TaskNumber = "ONLINE-1",
Name = "线上课程一"
});
var second = Entry(null, WeekPattern.All, new TeachingTask
{
TaskNumber = "ONLINE-2",
Name = "线上课程二"
});
Assert.True(ScheduleConflictDetector.TimeOverlaps(first, second));
Assert.Null(ScheduleConflictDetector.ConflictReason(first, second));
}
private static ScheduleEntry Entry(
Guid? classroomId,
WeekPattern weekPattern,
TeachingTask task) =>
new()
{
ClassroomId = classroomId,
DayOfWeek = 1,
StartPeriod = 1,
PeriodCount = 2,
StartWeek = 1,
EndWeek = 16,
WeekPattern = weekPattern,
TeachingTask = task
};
}