public void TestGetConnectionWithoutSession() { var httpContextMock = helper.CreateTunnelHttpContextMock("GET", sessionType: null); var tunnelHandlerMock = new Mock <ITunnelHandler>(); TunnelService tunnelService = new TunnelService(httpContextMock.Object.Request, httpContextMock.Object.Response); tunnelService.Handle(tunnelHandlerMock.Object, new TunnelHandleOptions() { CheckLogin = false }); /// 验证是否成功调用 OnTunnelRequest /// 正常获取的时候,信道不为空,并且有 Id 可以进行索引 /// 因为 CheckLogin 配置为 false,所以应该获取不到用户信息 tunnelHandlerMock.Verify( expression: x => x.OnTunnelRequest( It.Is <SDK.Tunnel.Tunnel>(tunnel => tunnel.Id != null), It.Is <SDK.Authorization.UserInfo>(user => user == null) ), times: Times.Once(), failMessage: "没有正确调用 OnTunnelRequest" ); /// 验证是否正确输出申请到的连接地址到客户端 httpContextMock.Verify( expression: x => x.Response.Write( It.Is <string>(content => helper.CheckBodyHasUrl(content)) ), times: Times.Once(), failMessage: "请求 WebSocket 连接没有进行合法的输出" ); }
public void TestGetConnectionWithInvalidSession() { var httpContextMock = helper.CreateTunnelHttpContextMock("GET", sessionType: "invalid"); var tunnelHandlerMock = new Mock <ITunnelHandler>(); TunnelService tunnelService = new TunnelService(httpContextMock.Object.Request, httpContextMock.Object.Response); tunnelService.Handle(tunnelHandlerMock.Object, new TunnelHandleOptions() { CheckLogin = true }); /// 验证是否调用 OnTunnelRequest /// 请求登录的情况下,如果会话无效,应该直接输出会话无效 tunnelHandlerMock.Verify( expression: x => x.OnTunnelRequest( It.IsAny <SDK.Tunnel.Tunnel>(), It.IsAny <SDK.Authorization.UserInfo>() ), times: Times.Never(), failMessage: "意外地调用了 OnTunnelRequest" ); /// 验证是否正确输出申请到的连接地址到客户端 httpContextMock.Verify( expression: x => x.Response.Write( It.Is <string>(content => helper.CheckBodyHasMagicId(JObject.Parse(content))) ), times: Times.Once(), failMessage: "请求 WebSocket 连接没有进行合法的输出" ); }
public void TestPostMessagePacket() { var httpContextMock = helper.CreateTunnelHttpContextMock("POST"); helper.SetupRequestBody(httpContextMock, helper.BuildPacket(new { type = "message", tunnelId = "tunnel1", content = new { type = "test-type", content = "test-content" }.ToJson() }.ToJson())); var tunnelService = new TunnelService(httpContextMock.Object.Request, httpContextMock.Object.Response); var tunnelHandlerMock = new Mock <ITunnelHandler>(); tunnelService.Handle(tunnelHandlerMock.Object); Func <TunnelMessage, bool> IsValidMessage = message => { return(message.Type == "test-type" && message.Content == "test-content"); }; tunnelHandlerMock.Verify( expression: x => x.OnTunnelMessage( It.Is((Tunnel tunnel) => tunnel.Id == "tunnel1"), It.Is((TunnelMessage message) => IsValidMessage(message)) ), times: Times.Once(), failMessage: "接收到关闭数据包之后没有正确调用 OnTunnelClose 事件" ); helper.VerifyHandleResponseSuccess(httpContextMock); }
public void TestPostBadRequest() { var httpContextMock = helper.CreateTunnelHttpContextMock("POST"); helper.SetupRequestBody(httpContextMock, "illegal request"); var tunnelService = new TunnelService(httpContextMock.Object.Request, httpContextMock.Object.Response); var tunnelHandlerMock = new Mock <ITunnelHandler>(); tunnelService.Handle(tunnelHandlerMock.Object); helper.CheckNoMethodIsCalled(tunnelHandlerMock); helper.VerifyHandleResponseFail(httpContextMock); }
public void TestPostSignatureErrorPacket() { var httpContextMock = helper.CreateTunnelHttpContextMock("POST"); helper.SetupRequestBody(httpContextMock, helper.BuildPacket(new { type = "connect", tunnelId = "tunnel1" }.ToJson(), fakeSignature: true)); var tunnelService = new TunnelService(httpContextMock.Object.Request, httpContextMock.Object.Response); var tunnelHandlerMock = new Mock <ITunnelHandler>(); tunnelService.Handle(tunnelHandlerMock.Object); helper.CheckNoMethodIsCalled(tunnelHandlerMock); helper.VerifyHandleResponseFail(httpContextMock); }
public void TestPostUnknowPacket() { var httpContextMock = helper.CreateTunnelHttpContextMock("POST"); helper.SetupRequestBody(httpContextMock, helper.BuildPacket(new { type = "unknown", tunnelId = "tunnel1" }.ToJson())); var tunnelService = new TunnelService(httpContextMock.Object.Request, httpContextMock.Object.Response); var tunnelHandlerMock = new Mock <ITunnelHandler>(); tunnelService.Handle(tunnelHandlerMock.Object); helper.CheckNoMethodIsCalled(tunnelHandlerMock); helper.VerifyHandleResponseSuccess(httpContextMock); }
/// <summary> /// GET /tunnel <para /> /// 请求建立隧道连接 <para /> /// /// POST /tunnel <para /> /// 用于信道服务器推送消息到业务服务器 /// </summary> public ActionResult Index() { // 创建信道服务处理信道相关请求 tunnelService = new TunnelService(Request, Response); // 信道服务会自动帮你响应请求,请不要使用 Response 进行二次请求 tunnelService.Handle( // 需要自己实现隧道消息处理器,TunnelHandler 是一个实现的范例,详情请看 TunnelHandler 的实现源码 handler: new ChatTunnelHandler(), // 配置是可选的,配置 CheckLogin 为 true 的话,会在隧道建立之前获取用户信息,以便业务将隧道和用户关联起来 options: new TunnelHandleOptions() { CheckLogin = true } ); // 返回 null 确保 MVC 框架不进行输出 return null; }
public void TestPostClosePacket() { var httpContextMock = helper.CreateTunnelHttpContextMock("POST"); helper.SetupRequestBody(httpContextMock, helper.BuildPacket(new { type = "close", tunnelId = "tunnel1" }.ToJson())); var tunnelService = new TunnelService(httpContextMock.Object.Request, httpContextMock.Object.Response); var tunnelHandlerMock = new Mock <ITunnelHandler>(); tunnelService.Handle(tunnelHandlerMock.Object); tunnelHandlerMock.Verify( expression: x => x.OnTunnelClose(It.Is((SDK.Tunnel.Tunnel tunnel) => tunnel.Id == "tunnel1")), times: Times.Once(), failMessage: "接收到关闭数据包之后没有正确调用 OnTunnelClose 事件" ); helper.VerifyHandleResponseSuccess(httpContextMock); }
public void TestPostBadNetwork() { var httpContextMock = helper.CreateTunnelHttpContextMock("POST"); httpContextMock.Setup(x => x.Request.InputStream).Throws(new HttpException("Bad Network")); var tunnelService = new TunnelService(httpContextMock.Object.Request, httpContextMock.Object.Response); var tunnelHandlerMock = new Mock <ITunnelHandler>(); Exception errorShouldThrow = null; try { tunnelService.Handle(tunnelHandlerMock.Object); } catch (Exception error) { errorShouldThrow = error; } helper.CheckNoMethodIsCalled(tunnelHandlerMock); Assert.IsNotNull(errorShouldThrow); }