Include personally enrolled courses in student course listings

This commit is contained in:
biss committed 2026-08-17 19:48:20 +08:00
1 parent 852668f0e5
commit 3b1b1f3c88
2 files changed
+99 -5

No files matched your search

@@ -340,11 +340,17 @@ public sealed class CoursesController(
isTeacher && db.TeachingTasks.Any(task => isTeacher && db.TeachingTasks.Any(task =>
task.CourseId == course.Id && task.CourseId == course.Id &&
task.Teachers.Any(item => item.Teacher!.UserId == userId)) || task.Teachers.Any(item => item.Teacher!.UserId == userId)) ||
isStudent && db.TeachingTasks.Any(task => isStudent && (
task.CourseId == course.Id && db.TeachingTasks.Any(task =>
task.Classes.Any(item => task.CourseId == course.Id &&
item.AdministrativeClass!.Students.Any(student => task.Classes.Any(item =>
student.UserId == userId)))); item.AdministrativeClass!.Students.Any(student =>
student.UserId == userId))) ||
db.CourseEnrollments.Any(enrollment =>
enrollment.Status == CourseEnrollmentStatus.Enrolled &&
enrollment.Student!.UserId == userId &&
enrollment.CourseSelectionOffering!.TeachingTask!.CourseId ==
course.Id)));
} }
private bool CanManage(Guid collegeId, CourseNature nature) private bool CanManage(Guid collegeId, CourseNature nature)
@@ -101,6 +101,84 @@ public sealed class CoursesControllerTests
Assert.Contains("OTHER-001", courses); Assert.Contains("OTHER-001", courses);
} }
[Fact]
public async Task Student_Get_IncludesCourseFromActivePersonalEnrollment()
{
await using var connection = new SqliteConnection("Data Source=:memory:");
await connection.OpenAsync();
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseSqlite(connection)
.Options;
await using var db = new AppDbContext(options);
await db.Database.EnsureCreatedAsync();
var studentUserId = Guid.NewGuid();
var college = new College { Code = "CS", Name = "计算机学院" };
var major = new Major
{
Code = "CS01", Name = "软件工程", CollegeId = college.Id, DegreeType = "本科"
};
var administrativeClass = new AdministrativeClass
{
Code = "SE2601", Name = "软件 2601", MajorId = major.Id, Grade = 2026
};
var student = new Student
{
StudentNumber = "20260001", Name = "测试学生", UserId = studentUserId,
AdministrativeClassId = administrativeClass.Id,
EnrollmentDate = new DateOnly(2026, 9, 1)
};
var category = new CourseCategory { Code = "CORE", Name = "核心课程" };
var selectedCourse = new Course
{
Code = "CS102", Name = "数据结构", CollegeId = college.Id,
CourseCategoryId = category.Id, Nature = CourseNature.MajorElective,
Credits = 3, TotalHours = 48, IsEnabled = true
};
var term = new AcademicTerm
{
Code = "2026-1", Name = "2026-2027-1", AcademicYear = "2026-2027",
Season = TermSeason.Autumn, StartDate = new DateOnly(2026, 9, 1),
EndDate = new DateOnly(2027, 1, 31), IsCurrent = true
};
var task = new TeachingTask
{
TaskNumber = "T-CS102", Name = "数据结构选课班", AcademicTermId = term.Id,
CourseId = selectedCourse.Id, Capacity = 50, Status = TeachingTaskStatus.Published
};
var round = new CourseSelectionRound
{
AcademicTermId = term.Id, Name = "第一轮", StartsAt = DateTime.UtcNow,
EndsAt = DateTime.UtcNow.AddDays(1), WithdrawalEndsAt = DateTime.UtcNow.AddDays(2)
};
var offering = new CourseSelectionOffering
{
CourseSelectionRoundId = round.Id, TeachingTaskId = task.Id, Capacity = 50
};
db.AddRange(college, major, administrativeClass, student, category, selectedCourse,
new ApplicationUser
{
Id = studentUserId, UserName = "20260001", DisplayName = "测试学生"
},
term, task, round, offering,
new CourseEnrollment
{
CourseSelectionOfferingId = offering.Id, StudentId = student.Id,
Status = CourseEnrollmentStatus.Enrolled
});
await db.SaveChangesAsync();
var controller = new CoursesController(
db, new StudentDataScope(studentUserId), NoOpAppCache.Instance);
var result = await controller.Get(cancellationToken: CancellationToken.None);
var ok = Assert.IsType<OkObjectResult>(result.Result);
var page = Assert.IsType<PagedResult<object>>(ok.Value);
Assert.Equal(1, page.Total);
Assert.Contains("CS102", JsonSerializer.Serialize(page.Items));
}
private sealed class TestDataScope(Guid collegeId) : ICurrentUserDataScope private sealed class TestDataScope(Guid collegeId) : ICurrentUserDataScope
{ {
public CurrentUserScope Current { get; } = new( public CurrentUserScope Current { get; } = new(
@@ -110,4 +188,14 @@ public sealed class CoursesControllerTests
DataScope.College, DataScope.College,
new HashSet<string>([SystemRoles.CollegeAdmin])); new HashSet<string>([SystemRoles.CollegeAdmin]));
} }
private sealed class StudentDataScope(Guid userId) : ICurrentUserDataScope
{
public CurrentUserScope Current { get; } = new(
userId,
"测试学生",
null,
DataScope.Self,
new HashSet<string>([SystemRoles.Student]));
}
} }