namespace Yh.SchClass.OpenApi.Tests; /// /// VSchClass(班级)端点的请求契约对拍:路径、HTTP 方法、query 参数名必须与 Java /// VClassController 逐字一致(参数名大小写敏感)。 /// public class SchClassVClassClientTests { private const string Root = "/oapi/VSchClass/"; [Fact] public async Task VSchClass_全部17个端点_路径与参数名对齐() { var handler = SchClassTestHost.Ok(); var api = SchClassTestHost.Api(handler); await api.VClass.GetVClassListAsync("S1"); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetVClassList", "?SchSerID=S1"); await api.VClass.GetEleVClassListAsync("S1"); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetEleVClassList", "?SchSerID=S1"); await api.VClass.GetSchArrVClassListAsync("S1,S2"); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetSchArrVClassList", "?SchIDArr=S1,S2"); await api.VClass.GetEleSchArrVClassListAsync("S1,S2"); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetEleSchArrVClassList", "?SchIDArr=S1,S2"); await api.VClass.GetFunTimeSchClassAsync("2026-09-01", "S1"); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetFunTimeSchClass", "?time=2026-09-01&SchSerID=S1"); await api.VClass.GetVClassFirstAsync("1001"); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetVClassFirst", "?ClassID=1001"); await api.VClass.GetEleVClassFirstAsync("1001"); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetEleVClassFirst", "?ClassID=1001"); await api.VClass.GetVClassIdsListAsync("1001,1002"); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetVClassIdsList", "?ClassIds=1001,1002"); await api.VClass.GetEleVClassIdsListAsync("1001,1002"); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetEleVClassIdsList", "?ClassIds=1001,1002"); await api.VClass.GetGradeClassListAsync("S1", 3, 11); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetGradeClassList", "?SchSerID=S1&Schooling=3&GradeId=11"); await api.VClass.GetTeachClassArrAsync(77); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetTeachClassArr", "?UserTeaSerID=77"); await api.VClass.GetSchArrVClassListAllAsync(); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetSchArrVClassListAll"); await api.VClass.GetEleSchArrVClassListAllAsync(); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetEleSchArrVClassListAll"); // POST @RequestBody String:按 text/plain 原样提交,不加引号 await api.VClass.GetSchArrVClassListPostAsync("S1,S2"); SchClassTestHost.VerifyBody(handler, Root + "GetSchArrVClassListPost", "S1,S2"); await api.VClass.GetElectiveClassByIdAsync(5); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetElectiveClassById", "?electiveId=5"); await api.VClass.GetElectiveClassByGradeAsync(1, 2); SchClassTestHost.Verify(handler, HttpMethod.Get, Root + "GetElectiveClassByGrade", "?schoolId=1&gradeId=2"); await api.VClass.GetElectiveClassByTeachersAsync("7,8"); SchClassTestHost.VerifyBody(handler, Root + "GetElectiveClassByTeachers", "7,8"); } [Fact] public async Task null参数_从query中丢弃() { var handler = SchClassTestHost.Ok(); var api = SchClassTestHost.Api(handler); await api.VClass.GetGradeClassListAsync("S1", null, null); Assert.Equal("?SchSerID=S1", Uri.UnescapeDataString(handler.LastRequest!.RequestUri!.Query)); } [Fact] public async Task 完整URL_由baseHost与oapi前缀拼成() { var handler = SchClassTestHost.Ok(); await SchClassTestHost.Api(handler).VClass.GetVClassListAsync("S1"); Assert.Equal("http://base.yunhaixingtong.com/oapi/VSchClass/GetVClassList?SchSerID=S1", handler.LastRequest!.RequestUri!.ToString()); } [Fact] public async Task 配置了BasePath时_路径前缀正确拼接() { var handler = SchClassTestHost.Ok(); var api = new SchClassOpenApi(new HttpClient(handler), new SchClassOpenApiOptions { BaseHost = "http://gw", BasePath = "/base.yunhaixingtong.com" }); await api.VClass.GetSchArrVClassListAllAsync(); Assert.Equal("/base.yunhaixingtong.com/oapi/VSchClass/GetSchArrVClassListAll", handler.LastRequest!.RequestUri!.AbsolutePath); } }