using JdeScoping.Core.Models; using JdeScoping.Core.Models.Enums; using JdeScoping.Core.Models.Infrastructure; using JdeScoping.Core.Models.Search; using Microsoft.AspNetCore.SignalR.Client; using Shouldly; namespace JdeScoping.Api.IntegrationTests; /// /// Integration tests for SignalR hub functionality. /// Note: These tests require a running test server /// public class SignalRTests : IClassFixture { private readonly TestWebApplicationFactory _factory; public SignalRTests(TestWebApplicationFactory factory) { _factory = factory; } [Fact] public async Task Client_CanConnectToStatusHub() { // Arrange var server = _factory.Server; var hubConnection = new HubConnectionBuilder() .WithUrl( new Uri(server.BaseAddress, "/hubs/status"), options => options.HttpMessageHandlerFactory = _ => server.CreateHandler()) .Build(); // Act await hubConnection.StartAsync(); // Assert hubConnection.State.ShouldBe(HubConnectionState.Connected); // Cleanup await hubConnection.StopAsync(); } [Fact] public async Task Client_CanCallGetCachedStatus() { // Arrange var server = _factory.Server; var hubConnection = new HubConnectionBuilder() .WithUrl( new Uri(server.BaseAddress, "/hubs/status"), options => options.HttpMessageHandlerFactory = _ => server.CreateHandler()) .Build(); await hubConnection.StartAsync(); // Act var status = await hubConnection.InvokeAsync("GetCachedStatus"); // Assert status.ShouldNotBeNull(); status.Message.ShouldNotBeNullOrEmpty(); // Cleanup await hubConnection.StopAsync(); } [Fact] public async Task Client_ReceivesStatusUpdates() { // Arrange var server = _factory.Server; var hubConnection = new HubConnectionBuilder() .WithUrl( new Uri(server.BaseAddress, "/hubs/status"), options => options.HttpMessageHandlerFactory = _ => server.CreateHandler()) .Build(); StatusUpdate? receivedUpdate = null; var updateReceived = new TaskCompletionSource(); hubConnection.On("statusUpdate", update => { receivedUpdate = update; updateReceived.TrySetResult(true); }); await hubConnection.StartAsync(); // Act - Call SetStatus var testUpdate = new StatusUpdate { Message = "Test Status", Timestamp = DateTime.UtcNow }; await hubConnection.SendAsync("SetStatus", testUpdate); // Wait for update with timeout var received = await Task.WhenAny(updateReceived.Task, Task.Delay(TimeSpan.FromSeconds(5))); // Assert (received == updateReceived.Task).ShouldBeTrue("Status update was not received within timeout"); receivedUpdate.ShouldNotBeNull(); receivedUpdate.Message.ShouldBe("Test Status"); // Cleanup await hubConnection.StopAsync(); } [Fact] public async Task Client_ReceivesSearchUpdates() { // Arrange var server = _factory.Server; var hubConnection = new HubConnectionBuilder() .WithUrl( new Uri(server.BaseAddress, "/hubs/status"), options => options.HttpMessageHandlerFactory = _ => server.CreateHandler()) .Build(); SearchUpdate? receivedUpdate = null; var updateReceived = new TaskCompletionSource(); hubConnection.On("searchUpdate", update => { receivedUpdate = update; updateReceived.TrySetResult(true); }); await hubConnection.StartAsync(); // Act - Call PublishSearchUpdate var testUpdate = new SearchUpdate { Id = 42, UserName = "testuser", Name = "Test Search", Status = SearchStatus.Running, Timestamp = DateTime.UtcNow }; await hubConnection.SendAsync("PublishSearchUpdate", testUpdate); // Wait for update with timeout var received = await Task.WhenAny(updateReceived.Task, Task.Delay(TimeSpan.FromSeconds(5))); // Assert (received == updateReceived.Task).ShouldBeTrue("Search update was not received within timeout"); receivedUpdate.ShouldNotBeNull(); receivedUpdate.Id.ShouldBe(42); receivedUpdate.Name.ShouldBe("Test Search"); // Cleanup await hubConnection.StopAsync(); } }