Files
Academic-Affairs-System/tests/Jiaowu.Api.Tests/OtherExamsControllerTests.cs
T

103 lines
4.8 KiB
C#

using Jiaowu.Api.Controllers;
using Jiaowu.Api.Domain.Academic;
using Jiaowu.Api.Domain.Identity;
using Jiaowu.Api.Infrastructure.Auth;
using Jiaowu.Api.Infrastructure.Persistence;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
namespace Jiaowu.Api.Tests;
public sealed class OtherExamsControllerTests
{
[Fact]
public async Task ReplaceResults_ReplacesExistingResultsInsideTransaction()
{
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 college = new College { Code = "CS", Name = "计算机学院" };
var major = new Major { Code = "SE", Name = "软件工程", CollegeId = college.Id, DegreeType = "工学" };
var administrativeClass = new AdministrativeClass { Code = "SE202601", Name = "软件工程 2026 级 1 班", MajorId = major.Id, Grade = 2026 };
var student = new Student
{
StudentNumber = "202600001",
Name = "测试学生",
AdministrativeClassId = administrativeClass.Id,
EnrollmentYear = 2026,
EnrollmentDate = new DateOnly(2026, 9, 1),
Status = StudentStatus.Active
};
var batch = new OtherExamBatch
{
ExamCode = "CET4",
Name = "大学英语四级",
ExamDate = new DateOnly(2026, 6, 1),
MetricKind = OtherExamMetricKind.Score,
MaxScore = 710
};
var oldResult = new OtherExamResult
{
OtherExamBatchId = batch.Id,
StudentId = student.Id,
Score = 500,
AttemptNumber = 1
};
db.AddRange(college, major, administrativeClass, student, batch, oldResult);
await db.SaveChangesAsync();
var controller = new OtherExamsController(db, new TestDataScope(college.Id));
var result = await controller.ReplaceResults(batch.Id, new ReplaceOtherExamResultsRequest([
new OtherExamResultRequest(student.StudentNumber, 610.5m, null, null, "已复核")
]), CancellationToken.None);
Assert.IsType<OkObjectResult>(result);
db.ChangeTracker.Clear();
var saved = await db.OtherExamResults.SingleAsync(x => x.OtherExamBatchId == batch.Id);
Assert.Equal(610.5m, saved.Score);
Assert.Equal("已复核", saved.Notes);
Assert.Equal(1, saved.AttemptNumber);
}
[Fact]
public async Task ReplaceResults_RejectsOverlongNotesBeforeDatabaseSave()
{
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 college = new College { Code = "CS", Name = "计算机学院" };
var major = new Major { Code = "SE", Name = "软件工程", CollegeId = college.Id, DegreeType = "工学" };
var administrativeClass = new AdministrativeClass { Code = "SE202601", Name = "软件工程 2026 级 1 班", MajorId = major.Id, Grade = 2026 };
var student = new Student { StudentNumber = "202600001", Name = "测试学生", AdministrativeClassId = administrativeClass.Id, EnrollmentYear = 2026, EnrollmentDate = new DateOnly(2026, 9, 1), Status = StudentStatus.Active };
var batch = new OtherExamBatch { ExamCode = "CET4", Name = "大学英语四级", ExamDate = new DateOnly(2026, 6, 1), MetricKind = OtherExamMetricKind.Score, MaxScore = 710 };
db.AddRange(college, major, administrativeClass, student, batch);
await db.SaveChangesAsync();
var controller = new OtherExamsController(db, new TestDataScope(college.Id));
var result = await controller.ReplaceResults(batch.Id, new ReplaceOtherExamResultsRequest([
new OtherExamResultRequest(student.StudentNumber, 610, null, null, new string('注', 501))
]), CancellationToken.None);
var validation = Assert.IsType<ObjectResult>(result);
Assert.Contains("备注不能超过 500 个字符", Assert.IsType<ValidationProblemDetails>(validation.Value).Detail);
Assert.Empty(await db.OtherExamResults.ToListAsync());
}
private sealed class TestDataScope(Guid collegeId) : ICurrentUserDataScope
{
public CurrentUserScope Current { get; } = new(
Guid.NewGuid(),
"测试管理员",
collegeId,
DataScope.College,
new HashSet<string>([SystemRoles.CollegeAdmin]));
}
}