1159 lines
40 KiB
C#
1159 lines
40 KiB
C#
using AyCode.Core.Extensions;
|
|
using AyCode.Core.Helpers;
|
|
using AyCode.Core.Tests.TestModels;
|
|
using AyCode.Services.SignalRs;
|
|
using MessagePack.Resolvers;
|
|
using Microsoft.AspNetCore.SignalR.Client;
|
|
|
|
namespace AyCode.Services.Tests.SignalRs;
|
|
|
|
[TestClass]
|
|
public class AcSignalRClientBaseTests
|
|
{
|
|
private TestableSignalRClient _client = null!;
|
|
private TestLogger _logger = null!;
|
|
|
|
[TestInitialize]
|
|
public void Setup()
|
|
{
|
|
_logger = new TestLogger();
|
|
_client = new TestableSignalRClient(_logger);
|
|
_client.TransportSendTimeout = 100; // Short timeout for tests
|
|
}
|
|
|
|
#region Connection State Tests
|
|
|
|
[TestMethod]
|
|
public async Task StartConnection_WhenDisconnected_ConnectsSuccessfully()
|
|
{
|
|
_client.SetConnectionState(HubConnectionState.Disconnected);
|
|
|
|
await _client.StartConnection();
|
|
|
|
Assert.IsTrue(_client.GetPendingRequests().IsEmpty);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task StopConnection_ClearsState()
|
|
{
|
|
_client.RegisterPendingRequest(1, new SignalRRequestModel());
|
|
|
|
await _client.StopConnection();
|
|
|
|
// Connection should be stopped (no exception)
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region SendMessageToServerAsync Tests
|
|
|
|
[TestMethod]
|
|
public async Task SendMessageToServerAsync_SendsMessage()
|
|
{
|
|
await _client.SendMessageToServerAsync(TestClientTags.Ping);
|
|
|
|
Assert.AreEqual(1, _client.SentMessages.Count);
|
|
Assert.AreEqual(TestClientTags.Ping, _client.LastSentMessage?.MessageTag);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task SendMessageToServerAsync_WithMessage_SerializesCorrectly()
|
|
{
|
|
var idMessage = new IdMessage(42);
|
|
var message = new SignalPostJsonDataMessage<IdMessage>(idMessage);
|
|
|
|
await _client.SendMessageToServerAsync(TestClientTags.GetById, message, 1);
|
|
|
|
Assert.AreEqual(1, _client.SentMessages.Count);
|
|
var sent = _client.LastSentMessage;
|
|
Assert.IsNotNull(sent?.MessageBytes);
|
|
Assert.AreEqual(1, sent.RequestId);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task SendMessageToServerAsync_WhenDisconnected_LogsError()
|
|
{
|
|
_client.SetConnectionState(HubConnectionState.Disconnected);
|
|
|
|
await _client.SendMessageToServerAsync(TestClientTags.Ping, null, 1);
|
|
|
|
// Should attempt to connect first, then send
|
|
Assert.AreEqual(1, _client.SentMessages.Count);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetByIdAsync Tests
|
|
|
|
[TestMethod]
|
|
public async Task GetByIdAsync_SendsIdMessageWithSingleId()
|
|
{
|
|
_client.SetNextRequestId(100);
|
|
|
|
// Start the async operation but don't await the result (it will timeout)
|
|
_ = Task.Run(() => _client.GetByIdAsync<TestOrderItem>(TestClientTags.GetById, 42));
|
|
|
|
// Give it time to send
|
|
await Task.Delay(50);
|
|
|
|
Assert.IsTrue(_client.SentMessages.Count >= 1);
|
|
var sent = _client.SentMessages.FirstOrDefault(m => m.MessageTag == TestClientTags.GetById);
|
|
Assert.IsNotNull(sent);
|
|
Assert.AreEqual(100, sent.RequestId);
|
|
|
|
var idMessage = sent.AsIdMessage();
|
|
Assert.IsNotNull(idMessage);
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.AreEqual("42", idMessage.Ids[0]); // Direct JSON format
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetByIdAsync_WithGuid_SendsCorrectly()
|
|
{
|
|
var guid = Guid.Parse("12345678-1234-1234-1234-123456789abc");
|
|
_client.SetNextRequestId(101);
|
|
|
|
_ = Task.Run(() => _client.GetByIdAsync<TestGuidOrder>(TestClientTags.GetById, guid));
|
|
await Task.Delay(50);
|
|
|
|
var sent = _client.SentMessages.FirstOrDefault(m => m.MessageTag == TestClientTags.GetById);
|
|
Assert.IsNotNull(sent);
|
|
var idMessage = sent.AsIdMessage();
|
|
Assert.IsNotNull(idMessage);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("12345678"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetByIdAsync_WithMultipleIds_SendsAllIds()
|
|
{
|
|
_client.SetNextRequestId(102);
|
|
|
|
var task = _client.GetByIdAsync<List<TestOrderItem>>(TestClientTags.GetById, new object[] { 1, 2, 3 });
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
var idMessage = _client.LastSentMessage?.AsIdMessage();
|
|
Assert.IsNotNull(idMessage);
|
|
Assert.AreEqual(3, idMessage.Ids.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetByIdAsync_WithCallback_InvokesCallback()
|
|
{
|
|
_client.SetNextRequestId(103);
|
|
var callbackInvoked = false;
|
|
TestOrderItem? receivedData = null;
|
|
|
|
var task = _client.GetByIdAsync<TestOrderItem>(TestClientTags.GetById, async response =>
|
|
{
|
|
callbackInvoked = true;
|
|
receivedData = response.ResponseData;
|
|
await Task.CompletedTask;
|
|
}, 42);
|
|
|
|
await Task.Delay(10);
|
|
|
|
// Simulate server response
|
|
var responseItem = new TestOrderItem { Id = 42, ProductName = "Test Product" };
|
|
await _client.SimulateSuccessResponse(103, TestClientTags.GetById, responseItem);
|
|
|
|
await Task.Delay(10);
|
|
|
|
Assert.IsTrue(callbackInvoked);
|
|
Assert.IsNotNull(receivedData);
|
|
Assert.AreEqual(42, receivedData.Id);
|
|
Assert.AreEqual("Test Product", receivedData.ProductName);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetAllAsync Tests
|
|
|
|
[TestMethod]
|
|
public async Task GetAllAsync_SendsMessageWithoutParams()
|
|
{
|
|
_client.SetNextRequestId(200);
|
|
|
|
var task = _client.GetAllAsync<List<TestOrderItem>>(TestClientTags.GetAll);
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
Assert.AreEqual(1, _client.SentMessages.Count);
|
|
Assert.AreEqual(TestClientTags.GetAll, _client.LastSentMessage?.MessageTag);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetAllAsync_WithContextParams_SendsParams()
|
|
{
|
|
_client.SetNextRequestId(201);
|
|
|
|
var task = _client.GetAllAsync<List<TestOrderItem>>(TestClientTags.GetAll, new object[] { true, "filter" });
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
var idMessage = _client.LastSentMessage?.AsIdMessage();
|
|
Assert.IsNotNull(idMessage);
|
|
Assert.AreEqual(2, idMessage.Ids.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetAllAsync_WithEmptyParams_SendsWithoutMessage()
|
|
{
|
|
_client.SetNextRequestId(202);
|
|
|
|
var task = _client.GetAllAsync<List<TestOrderItem>>(TestClientTags.GetAll, Array.Empty<object>());
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
// Empty params should not create IdMessage
|
|
Assert.IsNull(_client.LastSentMessage?.MessageBytes);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PostDataAsync Tests
|
|
|
|
[TestMethod]
|
|
public async Task PostDataAsync_SendsComplexObject()
|
|
{
|
|
_client.SetNextRequestId(300);
|
|
var orderItem = new TestOrderItem { Id = 1, ProductName = "New Product", Quantity = 5 };
|
|
|
|
_ = Task.Run(() => _client.PostDataAsync<TestOrderItem, TestOrderItem>(TestClientTags.Create, orderItem));
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
Assert.IsTrue(_client.SentMessages.Count >= 1, $"Expected at least 1 message, got {_client.SentMessages.Count}");
|
|
var sent = _client.SentMessages.FirstOrDefault(m => m.MessageTag == TestClientTags.Create);
|
|
Assert.IsNotNull(sent);
|
|
Assert.IsNotNull(sent.MessageBytes);
|
|
|
|
var postData = sent.AsPostData<TestOrderItem>();
|
|
Assert.IsNotNull(postData);
|
|
Assert.AreEqual("New Product", postData.ProductName);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task PostDataAsync_WithNestedObject_SerializesCorrectly()
|
|
{
|
|
_client.SetNextRequestId(301);
|
|
var order = TestDataFactory.CreateOrder(itemCount: 2);
|
|
|
|
_ = Task.Run(() => _client.PostDataAsync<TestOrder, TestOrder>(TestClientTags.PostOrder, order));
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
var postData = _client.LastSentMessage?.AsPostData<TestOrder>();
|
|
Assert.IsNotNull(postData);
|
|
Assert.AreEqual(2, postData.Items.Count);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region OnReceiveMessage Tests
|
|
|
|
[TestMethod]
|
|
public async Task OnReceiveMessage_WithPendingRequest_SetsResponse()
|
|
{
|
|
var requestId = 400;
|
|
// Register with null callback - response will be stored in ResponseByRequestId
|
|
_client.RegisterPendingRequest(requestId, new SignalRRequestModel());
|
|
|
|
await _client.SimulateSuccessResponse(requestId, TestClientTags.Echo, "Hello");
|
|
|
|
// After receiving response, the request should have ResponseByRequestId set
|
|
// The pending request gets removed after callback handling, but for null callback
|
|
// it stays with the response set
|
|
var pending = _client.GetPendingRequests();
|
|
if (pending.TryGetValue(requestId, out var model))
|
|
{
|
|
Assert.IsNotNull(model.ResponseByRequestId);
|
|
}
|
|
// If not in pending, it means it was handled (which is also valid)
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task OnReceiveMessage_WithCallback_InvokesCallback()
|
|
{
|
|
var requestId = 401;
|
|
var callbackInvoked = false;
|
|
string? receivedData = null;
|
|
|
|
_client.RegisterPendingRequest(requestId, new SignalRRequestModel(new Action<ISignalResponseMessage<string>>(response =>
|
|
{
|
|
callbackInvoked = true;
|
|
receivedData = response.ResponseData;
|
|
})));
|
|
|
|
await _client.SimulateSuccessResponse(requestId, TestClientTags.Echo, "Hello World");
|
|
|
|
Assert.IsTrue(callbackInvoked);
|
|
Assert.IsNotNull(receivedData);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task OnReceiveMessage_WithoutPendingRequest_CallsMessageReceived()
|
|
{
|
|
var response = new SignalResponseJsonMessage(TestClientTags.GetStatus, SignalResponseStatus.Success, "OK");
|
|
var bytes = response.ToMessagePack(ContractlessStandardResolver.Options);
|
|
|
|
await _client.InvokeOnReceiveMessage(TestClientTags.GetStatus, bytes, null);
|
|
|
|
Assert.AreEqual(1, _client.ReceivedMessages.Count);
|
|
Assert.AreEqual(TestClientTags.GetStatus, _client.ReceivedMessages[0].MessageTag);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task OnReceiveMessage_WithEmptyBytes_LogsWarning()
|
|
{
|
|
await _client.InvokeOnReceiveMessage(TestClientTags.Echo, Array.Empty<byte>(), 999);
|
|
|
|
Assert.IsTrue(_logger.HasWarningLogs);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Error Handling Tests
|
|
|
|
[TestMethod]
|
|
public async Task GetByIdAsync_WithErrorResponse_ReturnsDefault()
|
|
{
|
|
_client.SetNextRequestId(500);
|
|
|
|
var task = Task.Run(async () =>
|
|
{
|
|
try
|
|
{
|
|
return await _client.GetByIdAsync<TestOrderItem>(TestClientTags.NotFound, 999);
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
});
|
|
|
|
await Task.Delay(10);
|
|
await _client.SimulateErrorResponse(500, TestClientTags.NotFound);
|
|
|
|
var result = await task;
|
|
Assert.IsNull(result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task SendMessageToServerAsync_WithZeroTag_LogsError()
|
|
{
|
|
await _client.SendMessageToServerAsync<string>(0, response => Task.CompletedTask);
|
|
|
|
Assert.IsTrue(_logger.HasErrorLogs);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Complex Scenario Tests
|
|
|
|
[TestMethod]
|
|
public async Task MultipleParallelRequests_HandleCorrectly()
|
|
{
|
|
_client.SetNextRequestId(600);
|
|
|
|
// Start multiple requests
|
|
var task1 = Task.Run(async () =>
|
|
{
|
|
var t = _client.GetByIdAsync<TestOrderItem>(TestClientTags.GetById, 1);
|
|
await Task.Delay(5);
|
|
return 600;
|
|
});
|
|
|
|
var task2 = Task.Run(async () =>
|
|
{
|
|
var t = _client.GetByIdAsync<TestOrderItem>(TestClientTags.GetById, 2);
|
|
await Task.Delay(5);
|
|
return 601;
|
|
});
|
|
|
|
await Task.WhenAll(task1, task2);
|
|
|
|
// Both requests should have been sent
|
|
Assert.AreEqual(2, _client.SentMessages.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task ConcurrentResponseHandling_ResolvesCorrectRequests()
|
|
{
|
|
_client.SetNextRequestId(700);
|
|
|
|
// Register two pending requests with callbacks
|
|
var results = new Dictionary<int, string?>();
|
|
|
|
_client.RegisterPendingRequest(700, new SignalRRequestModel(new Action<ISignalResponseMessage<string>>(response =>
|
|
{
|
|
results[700] = response.ResponseData;
|
|
})));
|
|
|
|
_client.RegisterPendingRequest(701, new SignalRRequestModel(new Action<ISignalResponseMessage<string>>(response =>
|
|
{
|
|
results[701] = response.ResponseData;
|
|
})));
|
|
|
|
// Simulate responses in reverse order
|
|
await _client.SimulateSuccessResponse(701, TestClientTags.Echo, "Response 701");
|
|
await _client.SimulateSuccessResponse(700, TestClientTags.Echo, "Response 700");
|
|
|
|
// Each request should get its correct response
|
|
Assert.AreEqual(2, results.Count);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IdMessage Single Primitive Parameter Tests
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithInt_SerializesAsNumber()
|
|
{
|
|
var idMessage = new IdMessage(42);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.AreEqual("42", idMessage.Ids[0]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithLong_SerializesAsNumber()
|
|
{
|
|
var idMessage = new IdMessage(9223372036854775807L);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.AreEqual("9223372036854775807", idMessage.Ids[0]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithBoolTrue_SerializesCorrectly()
|
|
{
|
|
var idMessage = new IdMessage(true);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.AreEqual("true", idMessage.Ids[0]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithBoolFalse_SerializesCorrectly()
|
|
{
|
|
var idMessage = new IdMessage(false);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.AreEqual("false", idMessage.Ids[0]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithString_SerializesAsQuotedString()
|
|
{
|
|
var idMessage = new IdMessage("hello");
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.AreEqual("\"hello\"", idMessage.Ids[0]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithDouble_SerializesAsNumber()
|
|
{
|
|
var idMessage = new IdMessage(3.14159);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].StartsWith("3.14"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithDecimal_SerializesAsNumber()
|
|
{
|
|
var idMessage = new IdMessage(99.99m);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.AreEqual("99.99", idMessage.Ids[0]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithGuid_SerializesAsQuotedString()
|
|
{
|
|
var guid = Guid.Parse("12345678-1234-1234-1234-123456789abc");
|
|
var idMessage = new IdMessage(guid);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("12345678"));
|
|
Assert.IsTrue(idMessage.Ids[0].StartsWith("\"") && idMessage.Ids[0].EndsWith("\""));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithDateTime_SerializesAsQuotedString()
|
|
{
|
|
var date = new DateTime(2024, 12, 25, 12, 30, 45, DateTimeKind.Utc);
|
|
var idMessage = new IdMessage(date);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("2024"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithEnum_SerializesAsNumber()
|
|
{
|
|
var idMessage = new IdMessage(TestStatus.Processing);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.AreEqual("2", idMessage.Ids[0]); // Processing = 2
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IdMessage Multiple Primitive Parameters Tests
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithTwoInts_SerializesCorrectly()
|
|
{
|
|
var idMessage = new IdMessage(new object[] { 10, 20 });
|
|
|
|
Assert.AreEqual(2, idMessage.Ids.Count);
|
|
Assert.AreEqual("10", idMessage.Ids[0]);
|
|
Assert.AreEqual("20", idMessage.Ids[1]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithThreeMixedTypes_SerializesCorrectly()
|
|
{
|
|
var idMessage = new IdMessage(new object[] { true, "test", 123 });
|
|
|
|
Assert.AreEqual(3, idMessage.Ids.Count);
|
|
Assert.AreEqual("true", idMessage.Ids[0]);
|
|
Assert.AreEqual("\"test\"", idMessage.Ids[1]);
|
|
Assert.AreEqual("123", idMessage.Ids[2]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithFiveParams_SerializesCorrectly()
|
|
{
|
|
var testGuid = Guid.NewGuid();
|
|
var idMessage = new IdMessage(new object[] { 42, "hello", true, testGuid, 99.99m });
|
|
|
|
Assert.AreEqual(5, idMessage.Ids.Count);
|
|
Assert.AreEqual("42", idMessage.Ids[0]);
|
|
Assert.AreEqual("\"hello\"", idMessage.Ids[1]);
|
|
Assert.AreEqual("true", idMessage.Ids[2]);
|
|
Assert.IsTrue(idMessage.Ids[3].Contains(testGuid.ToString()));
|
|
Assert.AreEqual("99.99", idMessage.Ids[4]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithIntBoolStringGuidDecimal_AllTypesSerializeCorrectly()
|
|
{
|
|
var guid = Guid.Parse("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee");
|
|
var idMessage = new IdMessage(new object[] {
|
|
42, // int
|
|
true, // bool
|
|
"text", // string
|
|
guid, // Guid
|
|
123.45m // decimal
|
|
});
|
|
|
|
Assert.AreEqual(5, idMessage.Ids.Count);
|
|
Assert.AreEqual("42", idMessage.Ids[0]);
|
|
Assert.AreEqual("true", idMessage.Ids[1]);
|
|
Assert.AreEqual("\"text\"", idMessage.Ids[2]);
|
|
Assert.IsTrue(idMessage.Ids[3].Contains("aaaaaaaa"));
|
|
Assert.AreEqual("123.45", idMessage.Ids[4]);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IdMessage No Parameters Tests
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithEmptyArray_HasNoIds()
|
|
{
|
|
var idMessage = new IdMessage(Array.Empty<object>());
|
|
|
|
Assert.AreEqual(0, idMessage.Ids.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetAllAsync_WithNullParams_SendsWithoutMessage()
|
|
{
|
|
_client.SetNextRequestId(203);
|
|
|
|
object[]? nullParams = null;
|
|
var task = _client.GetAllAsync<List<TestOrderItem>>(TestClientTags.GetAll, nullParams);
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
// Null params should not create IdMessage
|
|
Assert.IsNull(_client.LastSentMessage?.MessageBytes);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task SendMessageToServerAsync_NoParams_SendsWithoutBytes()
|
|
{
|
|
await _client.SendMessageToServerAsync(TestClientTags.Ping, null, 1);
|
|
|
|
Assert.AreEqual(1, _client.SentMessages.Count);
|
|
Assert.IsNull(_client.LastSentMessage?.MessageBytes);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IdMessage Complex Object Tests
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithComplexObject_SerializesAsJson()
|
|
{
|
|
var item = new TestOrderItem { Id = 1, ProductName = "Test", Quantity = 5 };
|
|
var idMessage = new IdMessage(item);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("\"ProductName\""));
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("\"Test\""));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithNestedObject_SerializesCorrectly()
|
|
{
|
|
var order = new TestOrder
|
|
{
|
|
Id = 100,
|
|
OrderNumber = "ORD-001",
|
|
Items = new List<TestOrderItem>
|
|
{
|
|
new() { Id = 1, ProductName = "Item A" },
|
|
new() { Id = 2, ProductName = "Item B" }
|
|
}
|
|
};
|
|
var idMessage = new IdMessage(order);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("ORD-001"));
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("Item A"));
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("Item B"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithSharedTag_IIdType_SerializesCorrectly()
|
|
{
|
|
var tag = new SharedTag { Id = 1, Name = "Important", Color = "#FF0000" };
|
|
var idMessage = new IdMessage(tag);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("Important"));
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("#FF0000"));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IdMessage Array/Collection Tests
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithIntArray_SerializesAsJsonArray()
|
|
{
|
|
var values = new[] { 1, 2, 3, 4, 5 };
|
|
var idMessage = new IdMessage(values);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("["));
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("1"));
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("5"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithStringList_SerializesAsJsonArray()
|
|
{
|
|
var items = new List<string> { "apple", "banana", "cherry" };
|
|
var idMessage = new IdMessage(items);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("apple"));
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("banana"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithGuidArray_SerializesAsJsonArray()
|
|
{
|
|
// Guid[] is treated as a single object and serialized as JSON array
|
|
// Use new object[] { guids } to pass it as single parameter
|
|
var guids = new[] { Guid.NewGuid(), Guid.NewGuid() };
|
|
var idMessage = new IdMessage(new object[] { guids });
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].StartsWith("["));
|
|
Assert.IsTrue(idMessage.Ids[0].EndsWith("]"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithGuidArrayAsMultipleParams_EnumeratesEachGuid()
|
|
{
|
|
// Using IEnumerable<Guid> constructor - each guid becomes separate Id
|
|
var guids = new[] { Guid.NewGuid(), Guid.NewGuid() };
|
|
var idMessage = new IdMessage((IEnumerable<Guid>)guids);
|
|
|
|
Assert.AreEqual(2, idMessage.Ids.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithEmptyArray_SerializesAsEmptyJsonArray()
|
|
{
|
|
var empty = Array.Empty<int>();
|
|
var idMessage = new IdMessage(empty);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.AreEqual("[]", idMessage.Ids[0]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithTestOrderItemList_SerializesAsJsonArray()
|
|
{
|
|
var items = new List<TestOrderItem>
|
|
{
|
|
new() { Id = 1, ProductName = "First" },
|
|
new() { Id = 2, ProductName = "Second" }
|
|
};
|
|
var idMessage = new IdMessage(items);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("First"));
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("Second"));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IdMessage Mixed Parameters (Primitive + Complex + Collection) Tests
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithIntAndDto_SerializesCorrectly()
|
|
{
|
|
var item = new TestOrderItem { Id = 10, ProductName = "Test" };
|
|
var idMessage = new IdMessage(new object[] { 42, item });
|
|
|
|
Assert.AreEqual(2, idMessage.Ids.Count);
|
|
Assert.AreEqual("42", idMessage.Ids[0]);
|
|
Assert.IsTrue(idMessage.Ids[1].Contains("Test"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithDtoAndList_SerializesCorrectly()
|
|
{
|
|
var item = new TestOrderItem { Id = 1, ProductName = "Product" };
|
|
var numbers = new List<int> { 1, 2, 3 };
|
|
var idMessage = new IdMessage(new object[] { item, numbers });
|
|
|
|
Assert.AreEqual(2, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("Product"));
|
|
Assert.IsTrue(idMessage.Ids[1].Contains("["));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithBoolArrayString_MixedWithArray_SerializesCorrectly()
|
|
{
|
|
var numbers = new[] { 1, 2, 3 };
|
|
var idMessage = new IdMessage(new object[] { true, numbers, "hello" });
|
|
|
|
Assert.AreEqual(3, idMessage.Ids.Count);
|
|
Assert.AreEqual("true", idMessage.Ids[0]);
|
|
Assert.IsTrue(idMessage.Ids[1].Contains("[1,2,3]") || idMessage.Ids[1].Contains("[1, 2, 3]"));
|
|
Assert.AreEqual("\"hello\"", idMessage.Ids[2]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithThreeComplexParams_SerializesCorrectly()
|
|
{
|
|
var item = new TestOrderItem { Id = 1, ProductName = "Product" };
|
|
var tags = new List<string> { "tag1", "tag2" };
|
|
var sharedTag = new SharedTag { Id = 1, Name = "Shared" };
|
|
var idMessage = new IdMessage(new object[] { item, tags, sharedTag });
|
|
|
|
Assert.AreEqual(3, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("Product"));
|
|
Assert.IsTrue(idMessage.Ids[1].Contains("tag1"));
|
|
Assert.IsTrue(idMessage.Ids[2].Contains("Shared"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithFiveMixedParams_AllTypesSerialize()
|
|
{
|
|
var guid = Guid.NewGuid();
|
|
var item = new TestOrderItem { Id = 5, ProductName = "Mixed" };
|
|
var numbers = new[] { 10, 20, 30 };
|
|
|
|
var idMessage = new IdMessage(new object[] {
|
|
42, // int
|
|
guid, // Guid
|
|
item, // complex object
|
|
numbers, // array
|
|
"final" // string
|
|
});
|
|
|
|
Assert.AreEqual(5, idMessage.Ids.Count);
|
|
Assert.AreEqual("42", idMessage.Ids[0]);
|
|
Assert.IsTrue(idMessage.Ids[1].Contains(guid.ToString()));
|
|
Assert.IsTrue(idMessage.Ids[2].Contains("Mixed"));
|
|
Assert.IsTrue(idMessage.Ids[3].Contains("["));
|
|
Assert.AreEqual("\"final\"", idMessage.Ids[4]);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region GetAllAsync Parameter Type Tests
|
|
|
|
[TestMethod]
|
|
public async Task GetAllAsync_WithSingleBoolParam_SerializesCorrectly()
|
|
{
|
|
_client.SetNextRequestId(210);
|
|
|
|
_ = _client.GetAllAsync<List<TestOrderItem>>(TestClientTags.GetAll, new object[] { true });
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
var idMessage = _client.LastSentMessage?.AsIdMessage();
|
|
Assert.IsNotNull(idMessage);
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.AreEqual("true", idMessage.Ids[0]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetAllAsync_WithIntAndString_SerializesCorrectly()
|
|
{
|
|
_client.SetNextRequestId(211);
|
|
|
|
_ = _client.GetAllAsync<List<TestOrderItem>>(TestClientTags.GetAll, new object[] { 100, "filter" });
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
var idMessage = _client.LastSentMessage?.AsIdMessage();
|
|
Assert.IsNotNull(idMessage);
|
|
Assert.AreEqual(2, idMessage.Ids.Count);
|
|
Assert.AreEqual("100", idMessage.Ids[0]);
|
|
Assert.AreEqual("\"filter\"", idMessage.Ids[1]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetAllAsync_WithGuidParam_SerializesCorrectly()
|
|
{
|
|
_client.SetNextRequestId(212);
|
|
var guid = Guid.NewGuid();
|
|
|
|
_ = _client.GetAllAsync<TestGuidOrder>(TestClientTags.GetAll, new object[] { guid });
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
var idMessage = _client.LastSentMessage?.AsIdMessage();
|
|
Assert.IsNotNull(idMessage);
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains(guid.ToString()));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetAllAsync_WithComplexObjectParam_SerializesCorrectly()
|
|
{
|
|
_client.SetNextRequestId(213);
|
|
var filter = new TestOrderItem { Id = 0, ProductName = "SearchFilter" };
|
|
|
|
_ = _client.GetAllAsync<List<TestOrderItem>>(TestClientTags.GetAll, new object[] { filter });
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
var idMessage = _client.LastSentMessage?.AsIdMessage();
|
|
Assert.IsNotNull(idMessage);
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("SearchFilter"));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetAllAsync_WithArrayParam_SerializesCorrectly()
|
|
{
|
|
_client.SetNextRequestId(214);
|
|
var ids = new[] { 1, 2, 3, 4, 5 };
|
|
|
|
_ = _client.GetAllAsync<List<TestOrderItem>>(TestClientTags.GetAll, new object[] { ids });
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
var idMessage = _client.LastSentMessage?.AsIdMessage();
|
|
Assert.IsNotNull(idMessage);
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("["));
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task GetAllAsync_WithThreeMixedParams_SerializesCorrectly()
|
|
{
|
|
_client.SetNextRequestId(215);
|
|
var tag = new SharedTag { Id = 1, Name = "Filter" };
|
|
|
|
_ = _client.GetAllAsync<List<TestOrderItem>>(TestClientTags.GetAll, new object[] { true, 50, tag });
|
|
await TaskHelper.WaitToAsync(() => _client.SentMessages.Count > 0, 1000, 10);
|
|
|
|
var idMessage = _client.LastSentMessage?.AsIdMessage();
|
|
Assert.IsNotNull(idMessage);
|
|
Assert.AreEqual(3, idMessage.Ids.Count);
|
|
Assert.AreEqual("true", idMessage.Ids[0]);
|
|
Assert.AreEqual("50", idMessage.Ids[1]);
|
|
Assert.IsTrue(idMessage.Ids[2].Contains("Filter"));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PostDataAsync Parameter Type Tests
|
|
|
|
[TestMethod]
|
|
public async Task PostDataAsync_WithSimpleDto_SerializesCorrectly()
|
|
{
|
|
_client.SetNextRequestId(320);
|
|
var item = new TestOrderItem { Id = 1, ProductName = "Simple", Quantity = 10, UnitPrice = 25.50m };
|
|
|
|
_ = Task.Run(() => _client.PostDataAsync<TestOrderItem, TestOrderItem>(TestClientTags.Create, item));
|
|
await Task.Delay(50);
|
|
|
|
var postData = _client.LastSentMessage?.AsPostData<TestOrderItem>();
|
|
Assert.IsNotNull(postData);
|
|
Assert.AreEqual("Simple", postData.ProductName);
|
|
Assert.AreEqual(10, postData.Quantity);
|
|
Assert.AreEqual(25.50m, postData.UnitPrice);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task PostDataAsync_WithDtoContainingList_SerializesCorrectly()
|
|
{
|
|
_client.SetNextRequestId(321);
|
|
var order = new TestOrder
|
|
{
|
|
Id = 1,
|
|
OrderNumber = "ORD-TEST",
|
|
Items = new List<TestOrderItem>
|
|
{
|
|
new() { Id = 1, ProductName = "A", Quantity = 1 },
|
|
new() { Id = 2, ProductName = "B", Quantity = 2 },
|
|
new() { Id = 3, ProductName = "C", Quantity = 3 }
|
|
}
|
|
};
|
|
|
|
_ = Task.Run(() => _client.PostDataAsync<TestOrder, TestOrder>(TestClientTags.PostOrder, order));
|
|
await Task.Delay(50);
|
|
|
|
var postData = _client.LastSentMessage?.AsPostData<TestOrder>();
|
|
Assert.IsNotNull(postData);
|
|
Assert.AreEqual("ORD-TEST", postData.OrderNumber);
|
|
Assert.AreEqual(3, postData.Items.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task PostDataAsync_WithDtoContainingSharedRefs_SerializesCorrectly()
|
|
{
|
|
_client.SetNextRequestId(322);
|
|
var sharedTag = new SharedTag { Id = 1, Name = "Shared" };
|
|
var order = new TestOrder
|
|
{
|
|
Id = 1,
|
|
OrderNumber = "ORD-SHARED",
|
|
PrimaryTag = sharedTag,
|
|
SecondaryTag = sharedTag
|
|
};
|
|
|
|
_ = Task.Run(() => _client.PostDataAsync<TestOrder, TestOrder>(TestClientTags.PostOrder, order));
|
|
await Task.Delay(50);
|
|
|
|
var postData = _client.LastSentMessage?.AsPostData<TestOrder>();
|
|
Assert.IsNotNull(postData);
|
|
Assert.IsNotNull(postData.PrimaryTag);
|
|
Assert.AreEqual("Shared", postData.PrimaryTag.Name);
|
|
}
|
|
|
|
[TestMethod]
|
|
public async Task PostDataAsync_WithList_SerializesCorrectly()
|
|
{
|
|
_client.SetNextRequestId(323);
|
|
var items = new List<TestOrderItem>
|
|
{
|
|
new() { Id = 1, ProductName = "First" },
|
|
new() { Id = 2, ProductName = "Second" }
|
|
};
|
|
|
|
_ = Task.Run(() => _client.PostDataAsync<List<TestOrderItem>, List<TestOrderItem>>(TestClientTags.Create, items));
|
|
await Task.Delay(50);
|
|
|
|
var postData = _client.LastSentMessage?.AsPostData<List<TestOrderItem>>();
|
|
Assert.IsNotNull(postData);
|
|
Assert.AreEqual(2, postData.Count);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Edge Cases Tests
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithNullInArray_HandlesGracefully()
|
|
{
|
|
// This tests how null values are handled - they should serialize as "null"
|
|
var idMessage = new IdMessage(new object[] { 42, null!, "text" });
|
|
|
|
Assert.AreEqual(3, idMessage.Ids.Count);
|
|
Assert.AreEqual("42", idMessage.Ids[0]);
|
|
// null should serialize as "null" JSON literal
|
|
Assert.AreEqual("null", idMessage.Ids[1]);
|
|
Assert.AreEqual("\"text\"", idMessage.Ids[2]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithSpecialCharactersInString_EscapesCorrectly()
|
|
{
|
|
var idMessage = new IdMessage("hello \"world\" \n\t\\");
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
// Should contain escaped characters
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("\\\""));
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithEmptyString_SerializesAsEmptyQuotedString()
|
|
{
|
|
var idMessage = new IdMessage("");
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.AreEqual("\"\"", idMessage.Ids[0]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithZeroValues_SerializesCorrectly()
|
|
{
|
|
var idMessage = new IdMessage(new object[] { 0, 0L, 0.0, 0m });
|
|
|
|
Assert.AreEqual(4, idMessage.Ids.Count);
|
|
Assert.AreEqual("0", idMessage.Ids[0]);
|
|
Assert.AreEqual("0", idMessage.Ids[1]);
|
|
Assert.AreEqual("0", idMessage.Ids[2]);
|
|
Assert.AreEqual("0", idMessage.Ids[3]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_WithGuidEmpty_SerializesCorrectly()
|
|
{
|
|
var idMessage = new IdMessage(Guid.Empty);
|
|
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
Assert.IsTrue(idMessage.Ids[0].Contains("00000000-0000-0000-0000-000000000000"));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region MessagePack Serialization Round-Trip Tests
|
|
|
|
[TestMethod]
|
|
public void SignalPostJsonDataMessage_MessagePackRoundTrip_PreservesPostDataJson()
|
|
{
|
|
// Arrange
|
|
var original = new SignalPostJsonDataMessage<IdMessage>(new IdMessage(42));
|
|
|
|
// Act - Serialize to MessagePack
|
|
var bytes = original.ToMessagePack(ContractlessStandardResolver.Options);
|
|
|
|
// Deserialize back
|
|
var deserialized = bytes.MessagePackTo<SignalPostJsonDataMessage<IdMessage>>(ContractlessStandardResolver.Options);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(deserialized);
|
|
Assert.IsNotNull(deserialized.PostDataJson, "PostDataJson should not be null after deserialization");
|
|
Assert.IsFalse(string.IsNullOrEmpty(deserialized.PostDataJson), "PostDataJson should not be empty");
|
|
|
|
// Verify PostData can be accessed
|
|
Assert.IsNotNull(deserialized.PostData);
|
|
Assert.AreEqual(1, deserialized.PostData.Ids.Count);
|
|
Assert.AreEqual("42", deserialized.PostData.Ids[0]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SignalPostJsonDataMessage_WithComplexObject_MessagePackRoundTrip()
|
|
{
|
|
// Arrange
|
|
var order = new TestOrderItem { Id = 1, ProductName = "Test", Quantity = 5 };
|
|
var original = new SignalPostJsonDataMessage<TestOrderItem>(order);
|
|
|
|
// Act
|
|
var bytes = original.ToMessagePack(ContractlessStandardResolver.Options);
|
|
var deserialized = bytes.MessagePackTo<SignalPostJsonDataMessage<TestOrderItem>>(ContractlessStandardResolver.Options);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(deserialized);
|
|
Assert.IsNotNull(deserialized.PostDataJson);
|
|
Assert.IsNotNull(deserialized.PostData);
|
|
Assert.AreEqual("Test", deserialized.PostData.ProductName);
|
|
Assert.AreEqual(5, deserialized.PostData.Quantity);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SignalPostJsonMessage_BaseClass_MessagePackRoundTrip()
|
|
{
|
|
// Test base class directly
|
|
var original = new SignalPostJsonMessage { PostDataJson = "{\"test\":123}" };
|
|
|
|
var bytes = original.ToMessagePack(ContractlessStandardResolver.Options);
|
|
var deserialized = bytes.MessagePackTo<SignalPostJsonMessage>(ContractlessStandardResolver.Options);
|
|
|
|
Assert.IsNotNull(deserialized);
|
|
Assert.AreEqual("{\"test\":123}", deserialized.PostDataJson);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void IdMessage_InSignalPostJsonDataMessage_RoundTrip_PreservesAllIds()
|
|
{
|
|
// Arrange - Multiple IDs
|
|
var idMessage = new IdMessage(new object[] { 1, "test", true, Guid.Empty });
|
|
var original = new SignalPostJsonDataMessage<IdMessage>(idMessage);
|
|
|
|
// Act
|
|
var bytes = original.ToMessagePack(ContractlessStandardResolver.Options);
|
|
var deserialized = bytes.MessagePackTo<SignalPostJsonDataMessage<IdMessage>>(ContractlessStandardResolver.Options);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(deserialized?.PostData);
|
|
Assert.AreEqual(4, deserialized.PostData.Ids.Count);
|
|
Assert.AreEqual("1", deserialized.PostData.Ids[0]);
|
|
Assert.AreEqual("\"test\"", deserialized.PostData.Ids[1]);
|
|
Assert.AreEqual("true", deserialized.PostData.Ids[2]);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SignalPostJsonDataMessage_DeserializeAsBaseType_WorksCorrectly()
|
|
{
|
|
// This simulates what the server does - deserializing as SignalPostJsonMessage (base type)
|
|
var original = new SignalPostJsonDataMessage<IdMessage>(new IdMessage(42));
|
|
|
|
// Serialize as derived type
|
|
var bytes = original.ToMessagePack(ContractlessStandardResolver.Options);
|
|
|
|
// Deserialize as BASE type (like server might do)
|
|
var deserialized = bytes.MessagePackTo<SignalPostJsonMessage>(ContractlessStandardResolver.Options);
|
|
|
|
// Assert - PostDataJson should still be available
|
|
Assert.IsNotNull(deserialized);
|
|
Assert.IsNotNull(deserialized.PostDataJson);
|
|
Assert.IsFalse(string.IsNullOrEmpty(deserialized.PostDataJson));
|
|
|
|
// Should be able to manually deserialize the JSON
|
|
var idMessage = deserialized.PostDataJson.JsonTo<IdMessage>();
|
|
Assert.IsNotNull(idMessage);
|
|
Assert.AreEqual(1, idMessage.Ids.Count);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SignalPostJsonDataMessage_WithIdMessage_ContainingInt_RoundTrip()
|
|
{
|
|
// Arrange - This is exactly what the client does when calling PostDataAsync<int, string>
|
|
var idMessage = new IdMessage(42);
|
|
var original = new SignalPostJsonDataMessage<IdMessage>(idMessage);
|
|
|
|
// Debug: print what's in PostDataJson
|
|
Console.WriteLine($"IdMessage.Ids[0]: {idMessage.Ids[0]}");
|
|
Console.WriteLine($"Original PostDataJson: {original.PostDataJson}");
|
|
|
|
// Act - Serialize to MessagePack (what client does)
|
|
var bytes = original.ToMessagePack(ContractlessStandardResolver.Options);
|
|
Console.WriteLine($"MessagePack bytes length: {bytes.Length}");
|
|
|
|
// Deserialize back (what server does)
|
|
var deserialized = bytes.MessagePackTo<SignalPostJsonDataMessage<IdMessage>>(ContractlessStandardResolver.Options);
|
|
|
|
// Assert
|
|
Assert.IsNotNull(deserialized);
|
|
Console.WriteLine($"Deserialized PostDataJson: {deserialized.PostDataJson}");
|
|
Assert.IsNotNull(deserialized.PostDataJson, "PostDataJson should not be null");
|
|
Assert.IsFalse(string.IsNullOrEmpty(deserialized.PostDataJson), "PostDataJson should not be empty");
|
|
|
|
// This is the key - PostData should be accessible
|
|
Assert.IsNotNull(deserialized.PostData, "PostData should be deserializable");
|
|
Console.WriteLine($"Deserialized PostData.Ids.Count: {deserialized.PostData.Ids.Count}");
|
|
Assert.AreEqual(1, deserialized.PostData.Ids.Count, "Should have 1 Id");
|
|
Assert.AreEqual("42", deserialized.PostData.Ids[0], "Id should be '42'");
|
|
}
|
|
|
|
#endregion
|
|
}
|