using Jiaowu.Api.Domain.Academic; using Jiaowu.Api.Infrastructure.Persistence; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; namespace Jiaowu.Api.Tests; public sealed class PersistenceTests : IAsyncLifetime { private readonly SqliteConnection _connection = new("Data Source=:memory:"); private AppDbContext _db = null!; public async Task InitializeAsync() { await _connection.OpenAsync(); var options = new DbContextOptionsBuilder() .UseSqlite(_connection) .Options; _db = new AppDbContext(options); await _db.Database.EnsureCreatedAsync(); } public async Task DisposeAsync() { await _db.DisposeAsync(); await _connection.DisposeAsync(); } [Fact] public async Task Catalog_codes_are_unique() { _db.Campuses.Add(new Campus { Code = "MAIN", Name = "主校区" }); await _db.SaveChangesAsync(); _db.Campuses.Add(new Campus { Code = "MAIN", Name = "另一个校区" }); await Assert.ThrowsAsync(() => _db.SaveChangesAsync()); } [Fact] public async Task Organization_relations_can_be_persisted() { var campus = new Campus { Code = "EAST", Name = "东校区" }; var college = new College { Code = "ART", Name = "艺术学院", CampusId = campus.Id }; var major = new Major { Code = "1305", Name = "设计学", CollegeId = college.Id, DegreeType = "艺术学学士" }; _db.AddRange(campus, college, major); await _db.SaveChangesAsync(); var saved = await _db.Majors .Include(x => x.College) .ThenInclude(x => x!.Campus) .SingleAsync(); Assert.Equal("东校区", saved.College!.Campus!.Name); } [Fact] public async Task People_and_course_relations_can_be_persisted() { var campus = new Campus { Code = "MAIN", Name = "主校区" }; var college = new College { Code = "CS", Name = "计算机学院", CampusId = campus.Id }; var major = new Major { Code = "080901", Name = "计算机科学与技术", CollegeId = college.Id, DegreeType = "工学学士" }; var administrativeClass = new AdministrativeClass { Code = "CS2026-01", Name = "计科 2026-1 班", MajorId = major.Id, Grade = 2026 }; _db.AddRange( campus, college, major, administrativeClass, new Teacher { TeacherNumber = "T2026001", Name = "陈老师", CollegeId = college.Id, Status = TeacherStatus.Active }, new Student { StudentNumber = "202601001", Name = "周同学", AdministrativeClassId = administrativeClass.Id, EnrollmentYear = 2026, EnrollmentDate = new DateOnly(2026, 9, 7), Status = StudentStatus.Active }, new Course { Code = "CS101", Name = "程序设计基础", CollegeId = college.Id, Credits = 4, TotalHours = 64, LectureHours = 40, PracticeHours = 24, Nature = CourseNature.MajorRequired, AssessmentMethod = AssessmentMethod.Examination }); await _db.SaveChangesAsync(); var teacher = await _db.Teachers.Include(x => x.College).SingleAsync(); var student = await _db.Students .Include(x => x.AdministrativeClass) .ThenInclude(x => x!.Major) .SingleAsync(); var course = await _db.Courses.Include(x => x.College).SingleAsync(); Assert.Equal("计算机学院", teacher.College!.Name); Assert.Equal("计算机科学与技术", student.AdministrativeClass!.Major!.Name); Assert.Equal(4m, course.Credits); Assert.Equal(course.TotalHours, course.LectureHours + course.PracticeHours); } }