已完善实验管理权限:

校级管理员可查看全部实验项目与成绩单。
学院管理员仅可查看本学院开课,或由本学院教师承担/管理的实验课。
场次取消、参与学生查看也同步执行上述范围校验,避免通过场次 ID 越权。
增加覆盖:校级全量、学院自有课程、跨学院管理课程可见、无关学院课程不可见。
This commit is contained in:
biss committed 2026-08-13 21:16:11 +08:00
1 parent 1e45ede5be
commit 5872c06042
3 files changed
+97 -9

No files matched your search

@@ -179,10 +179,65 @@ public sealed class ExperimentGradesControllerTests
Status = ExperimentProjectStatus.Published,
PublishedAt = DateTime.UtcNow
};
fixture.Db.AddRange(otherCollege, otherCourse, otherTask, otherProject);
var managedCourse = new Course
{
CollegeId = otherCollege.Id,
Code = "SHARED-LAB",
Name = "跨学院管理实验",
Credits = 1,
TotalHours = 16,
PracticeHours = 16,
Nature = CourseNature.Practice,
AssessmentMethod = AssessmentMethod.Assessment
};
var managedTask = new TeachingTask
{
AcademicTermId = fixture.Term.Id,
CourseId = managedCourse.Id,
TaskNumber = "SHARED-LAB-01",
Name = "跨学院管理实验班",
Capacity = 20,
Status = TeachingTaskStatus.Published,
Teachers =
[
new TeachingTaskTeacher
{
TeacherId = await fixture.Db.Teachers
.Where(x => x.UserId == fixture.TeacherScope.Current.UserId)
.Select(x => x.Id)
.SingleAsync(),
IsPrimary = true
}
]
};
var managedProject = new ExperimentProject
{
TeachingTaskId = managedTask.Id,
Code = "SHARED-LAB",
Name = "可见的跨学院实验",
ArrangementMode = ExperimentArrangementMode.Centralized,
StartDate = fixture.Term.StartDate,
EndDate = fixture.Term.EndDate,
Status = ExperimentProjectStatus.Published,
PublishedAt = DateTime.UtcNow
};
fixture.Db.AddRange(
otherCollege, otherCourse, otherTask, otherProject,
managedCourse, managedTask, managedProject);
await fixture.Db.SaveChangesAsync();
fixture.Db.ChangeTracker.Clear();
var schoolScope = new FixedScope(new CurrentUserScope(
Guid.NewGuid(),
"校级管理员",
null,
DataScope.All,
new HashSet<string>([SystemRoles.AcademicAdmin])));
var schoolPage = Assert.IsType<OkObjectResult>(await fixture
.ExperimentGrades(schoolScope)
.GetManagement(null, null, null, null, 1, 10, CancellationToken.None));
Assert.Equal(3, Property<int>(schoolPage.Value, "Total"));
var collegeScope = new FixedScope(new CurrentUserScope(
Guid.NewGuid(),
"学院管理员",
@@ -198,11 +253,17 @@ public sealed class ExperimentGradesControllerTests
1,
10,
CancellationToken.None));
Assert.Equal(1, Property<int>(page.Value, "Total"));
var course = Assert.Single(Property<System.Collections.IEnumerable>(
page.Value, "Items").Cast<object>());
Assert.Equal(2, Property<int>(page.Value, "Total"));
var courses = Property<System.Collections.IEnumerable>(page.Value, "Items")
.Cast<object>()
.ToList();
Assert.Equal(2, courses.Count);
Assert.Contains(courses, course => Property<string>(course, "CourseCode") == "SHARED-LAB");
Assert.DoesNotContain(courses, course => Property<string>(course, "CourseCode") == "OTHER-LAB");
var ownCourse = Assert.Single(courses, course =>
Property<string>(course, "CourseCode") == "CSLAB");
Assert.Equal(12, Property<System.Collections.IEnumerable>(
course, "Projects").Cast<object>().Count());
ownCourse, "Projects").Cast<object>().Count());
var filtered = Assert.IsType<OkObjectResult>(await controller.GetManagement(
null,