自选项目实验优化

This commit is contained in:
2026-08-11 09:29:44 +08:00 Unverified
parent 9b32ee916c
commit e69ab6f580
11 changed files with 7578 additions and 67 deletions
@@ -161,7 +161,8 @@ public sealed class ExperimentsControllerTests
1,
2,
20,
null),
null,
[fixture.Teacher.Id]),
new ExperimentSessionBatchItem(
projectIds[1],
fixture.Classroom.Id,
@@ -169,7 +170,8 @@ public sealed class ExperimentsControllerTests
1,
2,
20,
null)
null,
[fixture.Teacher.Id])
]),
CancellationToken.None);
@@ -202,7 +204,8 @@ public sealed class ExperimentsControllerTests
1,
2,
20,
null),
null,
[fixture.Teacher.Id]),
new ExperimentSessionBatchItem(
projectIds[1],
fixture.SecondClassroom.Id,
@@ -210,7 +213,8 @@ public sealed class ExperimentsControllerTests
1,
2,
20,
null)
null,
[fixture.Teacher.Id])
]),
CancellationToken.None);
@@ -218,6 +222,65 @@ public sealed class ExperimentsControllerTests
Assert.Equal(2, await fixture.Db.ExperimentSessions.CountAsync());
}
[Fact]
public async Task SelfScheduledProject_AllowsMultipleCandidateSessionsAndRequiresSelectionWindow()
{
await using var fixture = await ExperimentFixture.CreateAsync();
var manager = fixture.Controller(fixture.ManagerScope);
var request = fixture.ProjectRequest(ExperimentArrangementMode.SelfScheduled) with
{
SelectionStartsAt = DateTime.UtcNow.AddHours(1),
SelectionEndsAt = DateTime.UtcNow.AddDays(1)
};
await manager.CreateProject(request, CancellationToken.None);
var project = await fixture.Db.ExperimentProjects.SingleAsync();
var result = await manager.CreateSessions(
new ExperimentSessionBatchRequest(
[
new ExperimentSessionBatchItem(project.Id, fixture.Classroom.Id,
fixture.Term.StartDate, 1, 2, 20, null, [fixture.Teacher.Id]),
new ExperimentSessionBatchItem(project.Id, fixture.SecondClassroom.Id,
fixture.Term.StartDate, 4, 2, 20, null, [fixture.Teacher.Id])
]),
CancellationToken.None);
Assert.IsType<CreatedResult>(result);
Assert.Equal(2, await fixture.Db.ExperimentSessions.CountAsync());
Assert.Equal(2, await fixture.Db.ExperimentSessionInstructors.CountAsync());
Assert.IsType<NoContentResult>(await manager.PublishProject(project.Id, CancellationToken.None));
var session = await fixture.Db.ExperimentSessions.OrderBy(x => x.StartPeriod).FirstAsync();
Assert.IsType<ConflictObjectResult>(
await fixture.Controller(fixture.StudentScope).Book(session.Id, CancellationToken.None));
}
[Fact]
public async Task BoundInstructor_CanCancelOwnSession()
{
await using var fixture = await ExperimentFixture.CreateAsync();
var manager = fixture.Controller(fixture.ManagerScope);
await manager.CreateProject(
fixture.ProjectRequest(ExperimentArrangementMode.SelfScheduled),
CancellationToken.None);
var project = await fixture.Db.ExperimentProjects.SingleAsync();
Assert.IsType<CreatedResult>(await manager.CreateSession(
project.Id, fixture.SessionRequest(1, 2, 20), CancellationToken.None));
var session = await fixture.Db.ExperimentSessions.SingleAsync();
Assert.IsType<NoContentResult>(await manager.PublishProject(project.Id, CancellationToken.None));
var instructorScope = new FixedScope(new CurrentUserScope(
fixture.Teacher.UserId!.Value,
fixture.Teacher.Name,
null,
DataScope.Self,
new HashSet<string>([SystemRoles.Teacher])));
Assert.IsType<NoContentResult>(await fixture.Controller(instructorScope)
.CancelSession(session.Id, CancellationToken.None));
Assert.Equal(ExperimentSessionStatus.Cancelled,
(await fixture.Db.ExperimentSessions.SingleAsync()).Status);
}
[Fact]
public async Task CentralizedProject_PublishesWhenBoundToPublishedExperimentSchedule()
{
@@ -509,6 +572,7 @@ public sealed class ExperimentsControllerTests
AppDbContext db,
AcademicTerm term,
TeachingTask task,
Teacher teacher,
Classroom classroom,
Classroom secondClassroom,
ScheduleEntry scheduleEntry,
@@ -519,6 +583,7 @@ public sealed class ExperimentsControllerTests
Db = db;
Term = term;
Task = task;
Teacher = teacher;
Classroom = classroom;
SecondClassroom = secondClassroom;
ScheduleEntry = scheduleEntry;
@@ -530,6 +595,7 @@ public sealed class ExperimentsControllerTests
public AppDbContext Db { get; }
public AcademicTerm Term { get; }
public TeachingTask Task { get; }
public Teacher Teacher { get; }
public Classroom Classroom { get; }
public Classroom SecondClassroom { get; }
public ScheduleEntry ScheduleEntry { get; }
@@ -600,7 +666,8 @@ public sealed class ExperimentsControllerTests
{
TeacherNumber = "T2099",
Name = "实验教师",
CollegeId = college.Id
CollegeId = college.Id,
UserId = manager.Id
};
var term = new AcademicTerm
{
@@ -655,7 +722,15 @@ public sealed class ExperimentsControllerTests
AcademicTermId = term.Id,
CourseId = course.Id,
Capacity = 40,
Status = TeachingTaskStatus.Published
Status = TeachingTaskStatus.Published,
Teachers =
[
new TeachingTaskTeacher
{
TeacherId = teacher.Id,
IsPrimary = true
}
]
};
db.AddRange(
manager,
@@ -712,6 +787,7 @@ public sealed class ExperimentsControllerTests
db,
term,
task,
teacher,
classroom,
secondClassroom,
scheduleEntry,
@@ -744,7 +820,13 @@ public sealed class ExperimentsControllerTests
"携带校园卡。",
Term.StartDate,
Term.StartDate.AddDays(14),
mode == ExperimentArrangementMode.Centralized ? ScheduleEntry.Id : null);
mode == ExperimentArrangementMode.Centralized ? ScheduleEntry.Id : null,
mode == ExperimentArrangementMode.SelfScheduled
? new DateTime(2020, 1, 1, 8, 0, 0)
: null,
mode == ExperimentArrangementMode.SelfScheduled
? new DateTime(2100, 1, 1, 18, 0, 0)
: null);
public ExperimentProjectBatchRequest BatchProjectRequest(
ExperimentArrangementMode mode) =>
@@ -771,7 +853,8 @@ public sealed class ExperimentsControllerTests
startPeriod,
periodCount,
capacity,
null);
null,
[Teacher.Id]);
public async ValueTask DisposeAsync()
{