using Yh.Platform.Abstractions; using Yh.Platform.OpenApi; using Xunit; namespace Yh.Platform.OpenApi.Tests; public class OpenApiOptionsTests { [Theory] [InlineData(null, null)] [InlineData("", null)] [InlineData(" ", null)] [InlineData("/userbase", "/userbase")] [InlineData("/userbase/", "/userbase")] [InlineData("userbase", "/userbase")] public void NormalizeBasePath_归一化规则(string? input, string? expected) { Assert.Equal(expected, OpenApiOptions.NormalizeBasePath(input)); } [Fact] public void ResolveBaseUrl_拼接host与path并去尾斜杠() { var options = new OpenApiOptions { BaseHost = "http://base.bestsch.com/", BasePath = "/userbase/" }; Assert.Equal("http://base.bestsch.com/userbase", options.ResolveBaseUrl()); } [Fact] public void ResolveBaseUrl_path为空时挂根路径() { var options = new OpenApiOptions { BaseHost = "http://base.bestsch.com", BasePath = "" }; Assert.Equal("http://base.bestsch.com", options.ResolveBaseUrl()); } [Fact] public void 默认值_对齐Java客户端() { var options = new OpenApiOptions(); Assert.True(options.Enabled); Assert.Equal("/userbase", options.BasePath); Assert.Equal(1500, options.ConnectTimeoutMs); Assert.Equal(5000, options.ReadTimeoutMs); Assert.Equal(5000, options.WriteTimeoutMs); } } /// 静态门面 的初始化准入与委托行为。 public class YschBaseOpenApiTests : IDisposable { private sealed class StubUserClient : IOpenApiUserClient { public int Calls; public Task GetUserInfoAsync(int userId, CancellationToken ct = default) { Calls++; return Task.FromResult(new BoaUser(userId, "stub", "桩用户")); } public Task GetUserByIdAsync(string userId, CancellationToken ct = default) => throw new NotImplementedException(); public Task GetUserByLoginNameAsync(string loginName, CancellationToken ct = default) => throw new NotImplementedException(); public Task GetUserByPhoneAsync(string phone, CancellationToken ct = default) => throw new NotImplementedException(); public Task GetUserInfoAsync(string loginName, CancellationToken ct = default) => throw new NotImplementedException(); public Task> GetUserModuleAsync(int userId, int? schoolId = null, CancellationToken ct = default) => throw new NotImplementedException(); public Task AddUserAsync(SysUserRequest request, CancellationToken ct = default) => throw new NotImplementedException(); public Task EditUserAsync(int id, SysUserRequest request, CancellationToken ct = default) => throw new NotImplementedException(); public Task DeleteUserAsync(int id, int groupId, int schoolId, CancellationToken ct = default) => throw new NotImplementedException(); public Task DeleteUsersAsync(IReadOnlyList items, CancellationToken ct = default) => throw new NotImplementedException(); public Task> BatchAddUsersAsync(IReadOnlyList requests, CancellationToken ct = default) => throw new NotImplementedException(); public Task MoveUserToGroupAsync(SysUserMoveRequest request, CancellationToken ct = default) => throw new NotImplementedException(); public Task> GetUserRoleListAsync(int userId, CancellationToken ct = default) => throw new NotImplementedException(); public Task GetCurrentIdentityAsync(int userId, CancellationToken ct = default) => throw new NotImplementedException(); public Task> GetAvailableIdentitiesAsync(int userId, CancellationToken ct = default) => throw new NotImplementedException(); public Task SwitchIdentityAsync(int userId, int roleId, int schoolId, CancellationToken ct = default) => throw new NotImplementedException(); public Task UpdateUserPasswordAsync(int userId, string oldPassword, string newPassword, CancellationToken ct = default) => throw new NotImplementedException(); public Task SetUserGroupStateAsync(SysUserGroupStateRequest request, CancellationToken ct = default) => throw new NotImplementedException(); public Task GetUserGroupStateAsync(int userId, int groupId, int schoolId, CancellationToken ct = default) => throw new NotImplementedException(); public Task TransferUserToSchoolAsync(SysUserTransferSchoolRequest request, CancellationToken ct = default) => throw new NotImplementedException(); public Task ChangeUserStatusAsync(int userId, bool disabled, CancellationToken ct = default) => throw new NotImplementedException(); public Task BatchChangeUserStatusAsync(IReadOnlyList userIds, bool disabled, CancellationToken ct = default) => throw new NotImplementedException(); } public YschBaseOpenApiTests() { YschBaseOpenApi.SetUserClient(null); YschBaseOpenApi.SetGroupClient(null); YschBaseOpenApi.SetAppClient(null); } public void Dispose() { YschBaseOpenApi.SetUserClient(null); YschBaseOpenApi.SetGroupClient(null); YschBaseOpenApi.SetAppClient(null); } [Fact] public async Task 未初始化时抛InvalidOperationException并给出引导信息() { var ex = await Assert.ThrowsAsync(() => YschBaseOpenApi.GetUserInfoAsync(1)); Assert.Contains("AddYhOpenApi", ex.Message); Assert.Contains("SetUserClient", ex.Message); } [Fact] public async Task 初始化后门面委托到注入的client() { var stub = new StubUserClient(); YschBaseOpenApi.SetUserClient(stub); var user = await YschBaseOpenApi.GetUserInfoAsync(1001); Assert.Equal(1, stub.Calls); Assert.NotNull(user); Assert.Equal(1001, user!.Id); Assert.Equal("stub", user.Account); } }