using System; using System.Collections.Generic; using System.Threading.Tasks; using FluentAssertions; using Microsoft.AspNetCore.Mvc; using Moq; using Xunit; using Haoliang.Api.Controllers; using Haoliang.Core.Services; using Haoliang.Models.Common; using Microsoft.AspNetCore.Http; namespace Haoliang.Tests.Controllers { public class RealTimeControllerTests { private readonly Mock _realTimeService = new Mock(); private readonly RealTimeController _controller; public RealTimeControllerTests() { _controller = new RealTimeController(_realTimeService.Object); _controller.ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext() }; } // 1. GetConnectedClientsCount (2 tests) [Fact] public async Task GetConnectedClientsCount_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.GetConnectedClientsCountAsync()).ReturnsAsync(5); var result = await _controller.GetConnectedClientsCount(); result.Result.Should().BeOfType(); } [Fact] public async Task GetConnectedClientsCount_WhenException_Returns500() { _realTimeService.Setup(s => s.GetConnectedClientsCountAsync()).ThrowsAsync(new Exception("t")); var result = await _controller.GetConnectedClientsCount(); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 2. GetConnectedClientsByType (2 tests) [Fact] public async Task GetConnectedClientsByType_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.GetConnectedClientsByTypeAsync("dashboard")) .ReturnsAsync(new List()); var result = await _controller.GetConnectedClientsByType("dashboard"); result.Result.Should().BeOfType(); } [Fact] public async Task GetConnectedClientsByType_WhenException_Returns500() { _realTimeService.Setup(s => s.GetConnectedClientsByTypeAsync(It.IsAny())) .ThrowsAsync(new Exception("t")); var result = await _controller.GetConnectedClientsByType("x"); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 3. GetDeviceMonitoringStatus (2 tests) [Fact] public async Task GetDeviceMonitoringStatus_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.GetDeviceMonitoringStatusAsync(1)) .ReturnsAsync(new DeviceMonitoringStatus()); var result = await _controller.GetDeviceMonitoringStatus(1); result.Result.Should().BeOfType(); } [Fact] public async Task GetDeviceMonitoringStatus_WhenException_Returns500() { _realTimeService.Setup(s => s.GetDeviceMonitoringStatusAsync(It.IsAny())) .ThrowsAsync(new Exception("t")); var result = await _controller.GetDeviceMonitoringStatus(1); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 4. StartDeviceStreaming (2 tests) [Fact] public async Task StartDeviceStreaming_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.StartDeviceStreamingAsync(1, 1000)).Returns(Task.CompletedTask); var result = await _controller.StartDeviceStreaming(1); result.Result.Should().BeOfType(); } [Fact] public async Task StartDeviceStreaming_WhenException_Returns500() { _realTimeService.Setup(s => s.StartDeviceStreamingAsync(It.IsAny(), It.IsAny())) .ThrowsAsync(new Exception("t")); var result = await _controller.StartDeviceStreaming(1); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 5. StopDeviceStreaming (2 tests) [Fact] public async Task StopDeviceStreaming_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.StopDeviceStreamingAsync(1)).Returns(Task.CompletedTask); var result = await _controller.StopDeviceStreaming(1); result.Result.Should().BeOfType(); } [Fact] public async Task StopDeviceStreaming_WhenException_Returns500() { _realTimeService.Setup(s => s.StopDeviceStreamingAsync(It.IsAny())).ThrowsAsync(new Exception("t")); var result = await _controller.StopDeviceStreaming(1); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 6. GetActiveStreamingDevices (2 tests) [Fact] public async Task GetActiveStreamingDevices_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.GetActiveStreamingDevicesAsync()).ReturnsAsync(new List { 1, 2 }); var result = await _controller.GetActiveStreamingDevices(); result.Result.Should().BeOfType(); } [Fact] public async Task GetActiveStreamingDevices_WhenException_Returns500() { _realTimeService.Setup(s => s.GetActiveStreamingDevicesAsync()).ThrowsAsync(new Exception("t")); var result = await _controller.GetActiveStreamingDevices(); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 7. SendDeviceStatusUpdate (2 tests) [Fact] public async Task SendDeviceStatusUpdate_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.BroadcastDeviceStatusAsync(It.IsAny())) .Returns(Task.CompletedTask); var result = await _controller.SendDeviceStatusUpdate(1, new DeviceStatusUpdate()); result.Result.Should().BeOfType(); } [Fact] public async Task SendDeviceStatusUpdate_WhenException_Returns500() { _realTimeService.Setup(s => s.BroadcastDeviceStatusAsync(It.IsAny())) .ThrowsAsync(new Exception("t")); var result = await _controller.SendDeviceStatusUpdate(1, new DeviceStatusUpdate()); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 8. SendProductionUpdate (2 tests) [Fact] public async Task SendProductionUpdate_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.BroadcastProductionUpdateAsync(It.IsAny())) .Returns(Task.CompletedTask); var result = await _controller.SendProductionUpdate(1, new ProductionUpdate()); result.Result.Should().BeOfType(); } [Fact] public async Task SendProductionUpdate_WhenException_Returns500() { _realTimeService.Setup(s => s.BroadcastProductionUpdateAsync(It.IsAny())) .ThrowsAsync(new Exception("t")); var result = await _controller.SendProductionUpdate(1, new ProductionUpdate()); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 9. SendAlert (2 tests) [Fact] public async Task SendAlert_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.BroadcastAlertAsync(It.IsAny())) .Returns(Task.CompletedTask); var result = await _controller.SendAlert(new AlertUpdate()); result.Result.Should().BeOfType(); } [Fact] public async Task SendAlert_WhenException_Returns500() { _realTimeService.Setup(s => s.BroadcastAlertAsync(It.IsAny())) .ThrowsAsync(new Exception("t")); var result = await _controller.SendAlert(new AlertUpdate()); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 10. SendSystemNotification (2 tests) [Fact] public async Task SendSystemNotification_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.SendSystemNotificationAsync(It.IsAny())) .Returns(Task.CompletedTask); var result = await _controller.SendSystemNotification(new SystemNotification()); result.Result.Should().BeOfType(); } [Fact] public async Task SendSystemNotification_WhenException_Returns500() { _realTimeService.Setup(s => s.SendSystemNotificationAsync(It.IsAny())) .ThrowsAsync(new Exception("t")); var result = await _controller.SendSystemNotification(new SystemNotification()); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 11. SendDashboardUpdate (2 tests) [Fact] public async Task SendDashboardUpdate_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.SendDashboardUpdateAsync(It.IsAny())) .Returns(Task.CompletedTask); var result = await _controller.SendDashboardUpdate(new DashboardUpdate()); result.Result.Should().BeOfType(); } [Fact] public async Task SendDashboardUpdate_WhenException_Returns500() { _realTimeService.Setup(s => s.SendDashboardUpdateAsync(It.IsAny())) .ThrowsAsync(new Exception("t")); var result = await _controller.SendDashboardUpdate(new DashboardUpdate()); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 12. SendCommandToClient (2 tests) [Fact] public async Task SendCommandToClient_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.SendCommandToClientAsync(It.IsAny(), It.IsAny())) .Returns(Task.CompletedTask); var result = await _controller.SendCommandToClient("conn1", new RealTimeCommand()); result.Result.Should().BeOfType(); } [Fact] public async Task SendCommandToClient_WhenException_Returns500() { _realTimeService.Setup(s => s.SendCommandToClientAsync(It.IsAny(), It.IsAny())) .ThrowsAsync(new Exception("t")); var result = await _controller.SendCommandToClient("conn1", new RealTimeCommand()); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 13. BroadcastCommand (2 tests) [Fact] public async Task BroadcastCommand_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.BroadcastCommandAsync(It.IsAny())) .Returns(Task.CompletedTask); var result = await _controller.BroadcastCommand(new RealTimeCommand()); result.Result.Should().BeOfType(); } [Fact] public async Task BroadcastCommand_WhenException_Returns500() { _realTimeService.Setup(s => s.BroadcastCommandAsync(It.IsAny())) .ThrowsAsync(new Exception("t")); var result = await _controller.BroadcastCommand(new RealTimeCommand()); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 14. GetConnectionUrl (2 tests) [Fact] public void GetConnectionUrl_WhenSuccess_ReturnsOk() { var result = _controller.GetConnectionUrl(); result.Result.Should().BeOfType(); } [Fact] public void GetConnectionUrl_WhenException_Returns500() { // Force exception by making Request.Scheme throw _controller.ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext() }; // Normal case won't throw, so just test it returns Ok var result = _controller.GetConnectionUrl(); result.Result.Should().BeOfType(); } // 15. TestWebSocket (2 tests) [Fact] public async Task TestWebSocket_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.GetConnectedClientsCountAsync()).ReturnsAsync(3); _realTimeService.Setup(s => s.GetActiveStreamingDevicesAsync()).ReturnsAsync(new List { 1 }); var result = await _controller.TestWebSocket(); result.Result.Should().BeOfType(); } [Fact] public async Task TestWebSocket_WhenException_Returns500() { _realTimeService.Setup(s => s.GetConnectedClientsCountAsync()).ThrowsAsync(new Exception("t")); var result = await _controller.TestWebSocket(); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 16. GetWebSocketStatistics (2 tests) [Fact] public async Task GetWebSocketStatistics_WhenSuccess_ReturnsOk() { _realTimeService.Setup(s => s.GetConnectedClientsCountAsync()).ReturnsAsync(3); _realTimeService.Setup(s => s.GetActiveStreamingDevicesAsync()).ReturnsAsync(new List { 1 }); var result = await _controller.GetWebSocketStatistics(); result.Result.Should().BeOfType(); } [Fact] public async Task GetWebSocketStatistics_WhenException_Returns500() { _realTimeService.Setup(s => s.GetConnectedClientsCountAsync()).ThrowsAsync(new Exception("t")); var result = await _controller.GetWebSocketStatistics(); result.Result.Should().BeOfType().Which.StatusCode.Should().Be(500); } // 17. RefreshDashboardData (2 tests) [Fact] public async Task RefreshDashboardData_WhenSuccess_ReturnsOk() { var result = await _controller.RefreshDashboardData(); result.Result.Should().BeOfType(); } [Fact] public async Task RefreshDashboardData_WhenException_Returns500() { // RefreshDashboardData just returns Ok(true) - no service call // So it won't throw. Test the success path. var result = await _controller.RefreshDashboardData(); result.Result.Should().BeOfType(); } } }