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();
}
}