实验课表

This commit is contained in:
2026-07-28 21:25:21 +08:00 Unverified
parent ec979f640d
commit 51c3b81e27
7 changed files with 687 additions and 28 deletions
@@ -138,6 +138,107 @@ public sealed class ExperimentsControllerTests
Assert.Empty(fixture.Db.ExperimentBookings);
}
[Fact]
public async Task StudentTimetable_IncludesCentralizedAndBookedSelfScheduledSessions()
{
await using var fixture = await ExperimentFixture.CreateAsync();
var manager = fixture.Controller(fixture.ManagerScope);
await manager.CreateProject(
fixture.ProjectRequest(ExperimentArrangementMode.Centralized),
CancellationToken.None);
var centralized = await fixture.Db.ExperimentProjects.SingleAsync();
await manager.CreateSession(
centralized.Id,
fixture.SessionRequest(1, 2),
CancellationToken.None);
await manager.PublishProject(centralized.Id, CancellationToken.None);
await manager.CreateProject(
fixture.ProjectRequest(ExperimentArrangementMode.SelfScheduled),
CancellationToken.None);
var selfScheduled = await fixture.Db.ExperimentProjects.SingleAsync(
x => x.ArrangementMode == ExperimentArrangementMode.SelfScheduled);
await manager.CreateSession(
selfScheduled.Id,
fixture.SessionRequest(4, 2),
CancellationToken.None);
await manager.PublishProject(selfScheduled.Id, CancellationToken.None);
var selfSession = await fixture.Db.ExperimentSessions.SingleAsync(
x => x.ExperimentProjectId == selfScheduled.Id);
var studentController = fixture.Controller(fixture.StudentScope);
Assert.IsType<NoContentResult>(
await studentController.Book(
selfSession.Id,
CancellationToken.None));
var student = await fixture.Db.Students.AsNoTracking().SingleAsync();
var service = new TimetableDataService(fixture.Db);
var timetable = await service.BuildAsync(
TimetableResourceType.Class,
student.AdministrativeClassId,
fixture.Term.Id,
null,
false,
student.Id,
new TimetableStudentDto(student.StudentNumber, student.Name),
CancellationToken.None);
Assert.NotNull(timetable);
Assert.Equal(2, timetable.ExperimentEntries.Count);
Assert.Contains(
timetable.ExperimentEntries,
x => x.ExperimentArrangementMode ==
ExperimentArrangementMode.Centralized);
Assert.Contains(
timetable.ExperimentEntries,
x => x.Id == selfSession.Id &&
x.ExperimentArrangementMode ==
ExperimentArrangementMode.SelfScheduled);
Assert.All(
timetable.ExperimentEntries,
x =>
{
Assert.True(x.IsExperiment);
Assert.Equal(fixture.Term.StartDate, x.ExperimentDate);
Assert.Equal(1, x.StartWeek);
});
var publicClassTimetable = await service.BuildAsync(
TimetableResourceType.Class,
student.AdministrativeClassId,
fixture.Term.Id,
null,
false,
null,
null,
CancellationToken.None);
Assert.NotNull(publicClassTimetable);
Assert.Empty(publicClassTimetable.ExperimentEntries);
var booking = await fixture.Db.ExperimentBookings.SingleAsync();
Assert.IsType<NoContentResult>(
await studentController.CancelBooking(
booking.Id,
CancellationToken.None));
timetable = await service.BuildAsync(
TimetableResourceType.Class,
student.AdministrativeClassId,
fixture.Term.Id,
null,
false,
student.Id,
new TimetableStudentDto(student.StudentNumber, student.Name),
CancellationToken.None);
Assert.NotNull(timetable);
Assert.Single(timetable.ExperimentEntries);
Assert.Equal(
ExperimentArrangementMode.Centralized,
timetable.ExperimentEntries[0].ExperimentArrangementMode);
}
private sealed class ExperimentFixture : IAsyncDisposable
{
private ExperimentFixture(