using System.Text.Json; using Jiaowu.Api.Contracts; using Jiaowu.Api.Controllers; using Jiaowu.Api.Domain.Academic; using Jiaowu.Api.Domain.Identity; using Jiaowu.Api.Infrastructure.Auth; using Jiaowu.Api.Infrastructure.Caching; using Jiaowu.Api.Infrastructure.Persistence; using Microsoft.AspNetCore.Mvc; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; namespace Jiaowu.Api.Tests; public sealed class CoursesControllerTests { [Fact] public async Task CollegeAdmin_GetWithoutCollegeFilter_ReturnsOnlyOwnCollegeCourses() { 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 ownCollege = new College { Code = "OWN", Name = "本院" }; var otherCollege = new College { Code = "OTHER", Name = "外院" }; var category = new CourseCategory { Code = "CORE", Name = "核心课程" }; db.AddRange( ownCollege, otherCollege, category, new Course { Code = "OWN-001", Name = "本院课程", CollegeId = ownCollege.Id, CourseCategoryId = category.Id, Nature = CourseNature.MajorRequired, Credits = 2, TotalHours = 32, IsEnabled = true }, new Course { Code = "OTHER-001", Name = "外院通识课程", CollegeId = otherCollege.Id, CourseCategoryId = category.Id, Nature = CourseNature.GeneralRequired, Credits = 2, TotalHours = 32, IsEnabled = true }); await db.SaveChangesAsync(); var scope = new TestDataScope(ownCollege.Id); var controller = new CoursesController(db, scope, NoOpAppCache.Instance); var result = await controller.Get(cancellationToken: CancellationToken.None); var ok = Assert.IsType(result.Result); var page = Assert.IsType>(ok.Value); Assert.Equal(1, page.Total); var items = JsonSerializer.Serialize(page.Items); Assert.Contains("OWN-001", items); Assert.DoesNotContain("OTHER-001", items); } [Fact] public async Task CollegeAdmin_CurriculumCourseOptions_IncludeEnabledCoursesFromOtherColleges() { 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 ownCollege = new College { Code = "OWN", Name = "本院" }; var otherCollege = new College { Code = "OTHER", Name = "外院" }; var category = new CourseCategory { Code = "CORE", Name = "核心课程" }; db.AddRange( ownCollege, otherCollege, category, new Course { Code = "OWN-001", Name = "本院课程", CollegeId = ownCollege.Id, CourseCategoryId = category.Id, Nature = CourseNature.MajorRequired, Credits = 2, TotalHours = 32, IsEnabled = true }, new Course { Code = "OTHER-001", Name = "外院课程", CollegeId = otherCollege.Id, CourseCategoryId = category.Id, Nature = CourseNature.MajorRequired, Credits = 2, TotalHours = 32, IsEnabled = true }); await db.SaveChangesAsync(); var controller = new CurriculumPlansController(db, new TestDataScope(ownCollege.Id)); var result = await controller.GetCourseOptions(CancellationToken.None); var ok = Assert.IsType(result); var courses = JsonSerializer.Serialize(ok.Value); Assert.Contains("OWN-001", courses); Assert.Contains("OTHER-001", courses); } private sealed class TestDataScope(Guid collegeId) : ICurrentUserDataScope { public CurrentUserScope Current { get; } = new( Guid.NewGuid(), "学院管理员", collegeId, DataScope.College, new HashSet([SystemRoles.CollegeAdmin])); } }