using ClosedXML.Excel; using Jiaowu.Api.Domain.Academic; using Jiaowu.Api.Infrastructure.Timetables; namespace Jiaowu.Api.Tests; public sealed class TimetableExcelExporterTests { [Fact] public void Create_builds_week_grid_with_exam_and_flexible_course_section() { var timetable = new TimetableData( new TimetableTermDto( Guid.NewGuid(), "2026-2027 学年第一学期", "2026-2027", TermSeason.Autumn, new DateOnly(2026, 9, 1), new DateOnly(2027, 1, 15), true), new TimetableSubjectDto( Guid.NewGuid(), "CS2601", "计算机科学 2601 班", TimetableResourceType.Class, 2026, Guid.NewGuid(), "计算机科学与技术", Guid.NewGuid(), "计算机学院", null, null, null), null, null, new TimetablePlanDto( Guid.NewGuid(), "正式课表", "V1", SchedulePlanStatus.Published, DateTime.UtcNow, DateTime.UtcNow), [ new TimetableSlotDto( 1, "第一节", new TimeOnly(8, 0), new TimeOnly(8, 45)) ], [ new TimetableEntryDto( Guid.NewGuid(), Guid.NewGuid(), "TASK-01", "高等数学 01", "MATH101", "高等数学", ["张老师"], ["计算机科学 2601 班"], "101", "第一教学楼", "主校区", 1, 1, 2, 1, 16, WeekPattern.All, null) ], [ new FlexibleCourseDto( Guid.NewGuid(), "TASK-02", "劳动教育", "LAB101", "劳动教育", 1, 16, 1, 16, 1, ["李老师"], ["计算机科学 2601 班"], null) ], [ new TimetableEntryDto( Guid.NewGuid(), Guid.NewGuid(), "TASK-EXAM", "高等数学期末考试", "MATH101", "高等数学", ["张老师", "监考:李老师"], ["计算机科学 2601 班"], "201", "第二教学楼", "主校区", 2, 1, 1, 1, 1, WeekPattern.All, null, true, "2026-2027 学年第一学期期末考试", new DateOnly(2027, 1, 5), DateTime.UtcNow) ]) { ExperimentEntries = [ new TimetableEntryDto( Guid.NewGuid(), Guid.NewGuid(), "TASK-LAB", "程序设计实验教学班", "CSLAB101", "程序设计实验", ["陈老师"], ["计算机科学 2601 班"], "301", "实验中心", "主校区", 4, 1, 2, 2, 2, WeekPattern.All, null, false, null, null, DateTime.UtcNow, true, Guid.NewGuid(), "LAB-01", "基础控制实验", new DateOnly(2026, 9, 10), ExperimentArrangementMode.SelfScheduled) ] }; var bytes = TimetableExcelExporter.Create(timetable); using var stream = new MemoryStream(bytes); using var workbook = new XLWorkbook(stream); var sheet = workbook.Worksheet("课表"); Assert.Contains("计算机科学 2601 班", sheet.Cell("A1").GetString()); Assert.Contains("已融入 1 场考试", sheet.Cell("A2").GetString()); Assert.Contains("已融入 1 场实验", sheet.Cell("A2").GetString()); Assert.Contains("高等数学", sheet.Cell(5, 2).GetString()); Assert.Contains("【考试】高等数学", sheet.Cell(5, 3).GetString()); Assert.Contains("【实验】基础控制实验", sheet.Cell(5, 5).GetString()); Assert.Contains("自主预约", sheet.Cell(5, 5).GetString()); Assert.Contains("2027-01-05", sheet.Cell(5, 3).GetString()); Assert.Contains( sheet.CellsUsed(), cell => cell.GetString().Contains("非排时课程")); } }