namespace Yh.SchClass.OpenApi.Tests; /// SchTree(教师组树)端点契约与 反序列化。 public class SchClassSchTreeClientTests { private const string Root = "/oapi/SchGroup/"; [Fact] public async Task SchGroup_GetTeaTree_路径与参数名对齐() { var handler = SchClassTestHost.Ok(); var api = SchClassTestHost.Api(handler); // 双参数齐全:按 Java 参数原名 SchSerID / schId 提交 await api.SchTree.GetTeaTreeAsync("S1", 2); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetTeaTree", "?SchSerID=S1&schId=2"); // 仅 schId(服务端优先使用) await api.SchTree.GetTeaTreeAsync(null, 5); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetTeaTree", "?schId=5"); // 仅 SchSerID await api.SchTree.GetTeaTreeAsync("S9", null); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetTeaTree", "?SchSerID=S9"); // 都缺:服务端返回 [](不抛异常) await api.SchTree.GetTeaTreeAsync(); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetTeaTree", ""); } [Fact] public async Task TeaTreeVO_嵌套树按Java原名反序列化() { // 教师叶子节点无 children 字段(Java @JsonInclude(NON_NULL) 省略) var handler = FakeHandler.Json(HttpStatusCode.OK, """ [{"id":10,"name":"第一中学","pid":0,"no":1,"type":1,"isParent":true,"photo":"", "children":[ {"id":31,"name":"教师组","pid":10,"no":1,"type":1,"isParent":true,"photo":"", "children":[ {"id":32,"name":"语文组","pid":31,"no":1,"type":1,"isParent":true,"photo":"", "children":[ {"id":77,"name":"王老师","pid":32,"no":0,"type":2,"isParent":false,"photo":""}]}, {"id":99,"name":"李老师","pid":31,"no":0,"type":2,"isParent":false,"photo":""}]}]}] """); var tree = await SchClassTestHost.Api(handler).SchTree.GetTeaTreeAsync("S001", null); Assert.Single(tree); var sch = tree[0]; Assert.Equal(10, sch.Id); Assert.Equal("第一中学", sch.Name); Assert.Equal(0, sch.Pid); Assert.Equal(1, sch.Type); Assert.True(sch.IsParent); Assert.Equal("", sch.Photo); var teaGroup = Assert.Single(sch.Children!); Assert.Equal(31, teaGroup.Id); Assert.Equal("教师组", teaGroup.Name); Assert.Equal(10, teaGroup.Pid); Assert.Equal(2, teaGroup.Children!.Count); var subject = teaGroup.Children[0]; Assert.Equal("语文组", subject.Name); var tea = Assert.Single(subject.Children!); Assert.Equal(77, tea.Id); Assert.Equal("王老师", tea.Name); Assert.Equal(32, tea.Pid); Assert.Equal(0, tea.No); Assert.Equal(2, tea.Type); Assert.False(tea.IsParent); Assert.Null(tea.Children); var ungrouped = teaGroup.Children[1]; Assert.Equal(99, ungrouped.Id); Assert.Equal("李老师", ungrouped.Name); Assert.Null(ungrouped.Children); } [Fact] public async Task GetTeaTree_两参数都缺时服务端空数组返回空列表() { var handler = FakeHandler.Json(HttpStatusCode.OK, "[]"); var tree = await SchClassTestHost.Api(handler).SchTree.GetTeaTreeAsync(); Assert.NotNull(tree); Assert.Empty(tree); } [Fact] public async Task GetTeaTree_服务端404时归一为空列表() { var handler = FakeHandler.Empty(HttpStatusCode.NotFound); var tree = await SchClassTestHost.Api(handler).SchTree.GetTeaTreeAsync("S001", null); Assert.NotNull(tree); Assert.Empty(tree); } }