using System.Buffers;
using AyCode.Core;
using AyCode.Core.Extensions;
using AyCode.Core.Tests.TestModels;
using AyCode.Services.Server.SignalRs;
using AyCode.Services.SignalRs;
using AyCode.Services.Tests.SignalRs;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.AspNetCore.SignalR.Protocol;
namespace AyCode.Services.Server.Tests.SignalRs;
///
/// Testable SignalR client that allows testing without real HubConnection.
/// Routes all messages through AyCodeBinaryHubProtocol with multi-segment splitting
/// to exercise the full serialization/deserialization pipeline.
///
public class TestableSignalRClient2 : AcSignalRClientBase, IAcSignalRHubItemServer
{
private HubConnectionState _connectionState = HubConnectionState.Connected;
private readonly TestableSignalRHub2 _signalRHub;
private readonly TestMultiSegmentProtocol _protocol = new();
private readonly TestInvocationBinder _binder = new();
///
/// Testable SignalR client that allows testing without real HubConnection.
///
public TestableSignalRClient2(TestableSignalRHub2 signalRHub, TestLogger logger) : base(logger)
{
MsDelay = 0;
MsFirstDelay = 0;
_signalRHub = signalRHub;
}
#region Override virtual methods for testing
protected override Task MessageReceived(int messageTag, SignalParams signalParams, object data)
{
throw new NotImplementedException();
}
protected override HubConnectionState GetConnectionState() => _connectionState;
protected override bool IsConnected() => _connectionState == HubConnectionState.Connected;
protected override Task StartConnectionInternal()
{
_connectionState = HubConnectionState.Connected;
return Task.CompletedTask;
}
protected override Task StopConnectionInternal()
{
_connectionState = HubConnectionState.Disconnected;
return Task.CompletedTask;
}
protected override ValueTask DisposeConnectionInternal() => ValueTask.CompletedTask;
protected override Task SendToHubAsync(int messageTag, int? requestId, SignalParams signalParams, object? data)
{
// Protocol round-trip: serialize → multi-segment split → deserialize
var invocation = new InvocationMessage(
nameof(IAcSignalRHubClient.OnReceiveMessage),
[messageTag, requestId, signalParams, data ?? Array.Empty()]);
var bytes = _protocol.GetMessageBytes(invocation);
var sequence = new ReadOnlySequence(bytes);
if (!_protocol.TryParseMessage(ref sequence, _binder, out var parsed) || parsed is not InvocationMessage invMsg)
throw new InvalidOperationException(
$"Protocol round-trip failed. ByteCount={bytes.Length}, Parsed={parsed?.GetType().Name ?? "null"}, " +
$"Tag={messageTag}, RequestId={requestId}, DataType={data?.GetType().Name ?? "null"}");
var args = invMsg.Arguments;
return _signalRHub.OnReceiveMessage(
(int)args[0]!, (int?)args[1], (SignalParams)args[2]!, args[3]!);
}
#endregion
}