This commit is contained in:
2026-07-24 12:42:51 +08:00 Unverified
commit 67905dfa16
56 changed files with 7630 additions and 0 deletions
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Jiaowu.Api\Jiaowu.Api.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,67 @@
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<AppDbContext>()
.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<DbUpdateException>(() => _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);
}
}
@@ -0,0 +1,36 @@
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Jiaowu.Api.Domain.Identity;
using Jiaowu.Api.Infrastructure.Auth;
using Microsoft.Extensions.Options;
namespace Jiaowu.Api.Tests;
public sealed class TokenServiceTests
{
[Fact]
public void Token_contains_identity_and_roles()
{
var options = Options.Create(new JwtOptions
{
Issuer = "tests",
Audience = "tests-web",
Key = "a-test-signing-key-that-is-at-least-32-bytes-long"
});
var user = new ApplicationUser
{
Id = Guid.NewGuid(),
UserName = "teacher01",
DisplayName = "陈老师"
};
var service = new TokenService(options);
var token = new JwtSecurityTokenHandler().ReadJwtToken(
service.Create(user, [SystemRoles.Teacher]));
Assert.Contains(token.Claims, x =>
x.Type == ClaimTypes.Role && x.Value == SystemRoles.Teacher);
Assert.Contains(token.Claims, x =>
x.Type == ClaimTypes.Name && x.Value == "陈老师");
}
}