using Jiaowu.Api.Domain.Academic; using Jiaowu.Api.Infrastructure.Academic; using Jiaowu.Api.Infrastructure.Persistence; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; namespace Jiaowu.Api.Tests; public sealed class StudentCurrentCourseQueryTests { [Fact] public async Task GetAsync_CombinesAssignedAndEnrolledCourses_AndDeduplicatesByCourse() { await using var connection = new SqliteConnection("Data Source=:memory:"); await connection.OpenAsync(); var options = new DbContextOptionsBuilder() .UseSqlite(connection) .Options; await using var db = new AppDbContext(options); await db.Database.EnsureCreatedAsync(); var college = new College { Code = "CS", Name = "计算机学院" }; var major = new Major { Code = "CS01", Name = "软件工程", CollegeId = college.Id, DegreeType = "本科" }; var administrativeClass = new AdministrativeClass { Code = "SE2026", Name = "软件 2601", MajorId = major.Id, Grade = 2026 }; var student = new Student { StudentNumber = "20260001", Name = "测试学生", AdministrativeClassId = administrativeClass.Id, EnrollmentDate = new DateOnly(2026, 9, 1) }; 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 assignedCourse = new Course { Code = "CS101", Name = "程序设计", CollegeId = college.Id, Credits = 3 }; var selectedCourse = new Course { Code = "CS102", Name = "数据结构", CollegeId = college.Id, Credits = 4 }; var assignedTask = new TeachingTask { TaskNumber = "T-CS101", Name = "程序设计 2601", AcademicTermId = term.Id, CourseId = assignedCourse.Id, Capacity = 50, Status = TeachingTaskStatus.Published }; var duplicateSelectedTask = new TeachingTask { TaskNumber = "T-CS101-E", Name = "程序设计选课", AcademicTermId = term.Id, CourseId = assignedCourse.Id, Capacity = 50, Status = TeachingTaskStatus.Published }; var selectedTask = 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 duplicateOffering = new CourseSelectionOffering { CourseSelectionRoundId = round.Id, TeachingTaskId = duplicateSelectedTask.Id, Capacity = 50 }; var selectedOffering = new CourseSelectionOffering { CourseSelectionRoundId = round.Id, TeachingTaskId = selectedTask.Id, Capacity = 50 }; db.AddRange( college, major, administrativeClass, student, term, assignedCourse, selectedCourse, assignedTask, duplicateSelectedTask, selectedTask, round, duplicateOffering, selectedOffering, new TeachingTaskClass { TeachingTaskId = assignedTask.Id, AdministrativeClassId = administrativeClass.Id }, new CourseEnrollment { CourseSelectionOfferingId = duplicateOffering.Id, StudentId = student.Id, Status = CourseEnrollmentStatus.Enrolled }, new CourseEnrollment { CourseSelectionOfferingId = selectedOffering.Id, StudentId = student.Id, Status = CourseEnrollmentStatus.Enrolled }); await db.SaveChangesAsync(); var summaries = await StudentCurrentCourseQuery.GetAsync( db, [new CurrentCourseStudent(student.Id, administrativeClass.Id)], CancellationToken.None); var summary = summaries[student.Id]; Assert.Equal(2, summary.Courses.Count); Assert.Equal(7, summary.TotalCredits); Assert.Equal(["CS101", "CS102"], summary.Courses.Select(x => x.CourseCode)); } }