FruitBank/Tests/Mango.Sandbox/Mango.Sandbox.EndPoints.Tests/SignalRClientToEndpointTest.cs

502 lines
16 KiB
C#

using AyCode.Services.SignalRs;
using Mango.Sandbox.EndPoints;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Mango.Sandbox.EndPoints.Tests;
/// <summary>
/// Komplex SignalR tesztek a SignalRClientSandbox használatával.
/// Az AcSignalRClientBase GetByIdAsync, GetAllAsync, PostDataAsync, GetAllIntoAsync metódusait teszteli.
/// FONTOS: A SANDBOX-ot manuálisan kell elindítani a tesztek futtatása előtt!
/// </summary>
[TestClass]
public class SignalRClientToEndpointTest
{
private static readonly string HubUrl = "http://localhost:59579/fbHub";
private static SignalRClientSandbox _client = null!;
[ClassInitialize]
public static async Task ClassInitialize(TestContext context)
{
// Sandbox ellenőrzés
//using var httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(5) };
//try
//{
// var response = await httpClient.GetAsync("http://localhost:59579/health");
// Assert.IsTrue(response.IsSuccessStatusCode,
// "SANDBOX not running! Start: dotnet run --project Mango.Sandbox.EndPoints --urls http://localhost:59579");
//}
//catch (Exception ex)
//{
// Assert.Fail($"SANDBOX not running! {ex.Message}");
//}
_client = new SignalRClientSandbox(HubUrl);
await _client.StartConnection();
}
[ClassCleanup]
public static async Task ClassCleanup()
{
if (_client != null)
await _client.StopConnection();
}
#region GetAllAsync Tesztek - Paraméter nélkül
[TestMethod]
public async Task GetAllAsync_NoParams_ReturnsTestItems()
{
// Act - GetAllAsync<T>(tag)
var result = await _client.GetAllAsync<List<TestItem>>(TestSignalRTags.GetTestItems);
// Assert
Assert.IsNotNull(result);
Assert.IsTrue(result.Count > 0);
Console.WriteLine($"[GetAllAsync] Received {result.Count} items");
}
[TestMethod]
public async Task GetAllAsync_NoParams_Callback_ReturnsTestItems()
{
// Arrange
List<TestItem>? receivedItems = null;
var tcs = new TaskCompletionSource<bool>();
// Act - GetAllAsync<T>(tag, callback)
await _client.GetAllAsync<List<TestItem>>(TestSignalRTags.GetTestItems, response =>
{
receivedItems = response.ResponseData;
tcs.SetResult(true);
return Task.CompletedTask;
});
await Task.WhenAny(tcs.Task, Task.Delay(5000));
// Assert
Assert.IsNotNull(receivedItems);
Assert.IsTrue(receivedItems.Count > 0);
}
[TestMethod]
public async Task GetAllAsync_HandleNoParams_ReturnsOk()
{
// Act - paraméter nélküli metódus
var result = await _client.GetAllAsync<string>(TestSignalRTags.NoParams);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("OK", result);
}
#endregion
#region GetByIdAsync Tesztek - Egyetlen ID
[TestMethod]
public async Task GetByIdAsync_SingleInt_ReturnsFormattedString()
{
// Act - GetByIdAsync<T>(tag, id)
var result = await _client.GetByIdAsync<string>(TestSignalRTags.SingleIntParam, 42);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("Received: 42", result);
}
[TestMethod]
public async Task GetByIdAsync_String_ReturnsEcho()
{
// Act
var result = await _client.GetByIdAsync<string>(TestSignalRTags.StringParam, "Hello World");
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("Echo: Hello World", result);
}
[TestMethod]
public async Task GetByIdAsync_Bool_ReturnsTrue()
{
// Act
var result = await _client.GetByIdAsync<bool>(TestSignalRTags.BoolParam, true);
// Assert
Assert.IsTrue(result);
}
[TestMethod]
public async Task GetByIdAsync_Guid_ReturnsSameGuid()
{
// Arrange
var guid = Guid.NewGuid();
// Act
var result = await _client.GetByIdAsync<Guid>(TestSignalRTags.GuidParam, guid);
// Assert
Assert.AreEqual(guid, result);
}
[TestMethod]
public async Task GetByIdAsync_Decimal_ReturnsDoubled()
{
// Act
var result = await _client.GetByIdAsync<decimal>(TestSignalRTags.DecimalParam, 123.45m);
// Assert
Assert.AreEqual(246.90m, result);
}
[TestMethod]
public async Task GetByIdAsync_Long_ReturnsSameLong()
{
// Act
var result = await _client.GetByIdAsync<long>(TestSignalRTags.LongParam, 9223372036854775807L);
// Assert
Assert.AreEqual(9223372036854775807L, result);
}
[TestMethod]
public async Task GetByIdAsync_Double_ReturnsSameDouble()
{
// Act
var result = await _client.GetByIdAsync<double>(TestSignalRTags.DoubleParam, 3.14159);
// Assert
Assert.AreEqual(3.14159, result, 0.00001);
}
[TestMethod]
public async Task GetByIdAsync_Enum_ReturnsSameEnum()
{
// Act
var result = await _client.GetByIdAsync<TestStatus>(TestSignalRTags.EnumParam, (int)TestStatus.Active);
// Assert
Assert.AreEqual(TestStatus.Active, result);
}
[TestMethod]
public async Task GetByIdAsync_SingleInt_Callback_ReturnsFormattedString()
{
// Arrange
string? receivedResult = null;
var tcs = new TaskCompletionSource<bool>();
// Act - GetByIdAsync<T>(tag, callback, id)
await _client.GetByIdAsync<string>(TestSignalRTags.SingleIntParam, response =>
{
receivedResult = response.ResponseData;
tcs.SetResult(true);
return Task.CompletedTask;
}, 100);
await Task.WhenAny(tcs.Task, Task.Delay(5000));
// Assert
Assert.IsNotNull(receivedResult);
Assert.AreEqual("Received: 100", receivedResult);
}
#endregion
#region GetByIdAsync Tesztek - Több ID (object[])
[TestMethod]
public async Task GetByIdAsync_TwoInts_ReturnsSum()
{
// Act - GetByIdAsync<T>(tag, ids[])
var result = await _client.GetByIdAsync<int>(TestSignalRTags.TwoIntParams, new object[] { 10, 20 });
// Assert
Assert.AreEqual(30, result);
}
[TestMethod]
public async Task GetByIdAsync_MultipleTypes_ReturnsFormattedString()
{
// Act
var result = await _client.GetByIdAsync<string>(TestSignalRTags.MultipleTypesParams, new object[] { true, "test", 123 });
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("True-test-123", result);
}
[TestMethod]
public async Task GetByIdAsync_FiveParams_ReturnsFormattedString()
{
// Arrange
var guid = Guid.NewGuid();
// Act
var result = await _client.GetByIdAsync<string>(TestSignalRTags.FiveParams, new object[] { 1, "text", true, guid, 99.99m });
// Assert
Assert.IsNotNull(result);
Assert.AreEqual($"1-text-True-{guid}-99.99", result);
}
[TestMethod]
public async Task GetByIdAsync_TwoInts_Callback_ReturnsSum()
{
// Arrange
int? receivedResult = null;
var tcs = new TaskCompletionSource<bool>();
// Act - GetByIdAsync<T>(tag, callback, ids[])
await _client.GetByIdAsync<int>(TestSignalRTags.TwoIntParams, response =>
{
receivedResult = response.ResponseData;
tcs.SetResult(true);
return Task.CompletedTask;
}, new object[] { 5, 7 });
await Task.WhenAny(tcs.Task, Task.Delay(5000));
// Assert
Assert.IsNotNull(receivedResult);
Assert.AreEqual(12, receivedResult.Value);
}
#endregion
#region GetAllAsync Tesztek - ContextParams-szal
[TestMethod]
public async Task GetAllAsync_WithContextParams_IntArray_ReturnsDoubled()
{
// Act - GetAllAsync<T>(tag, contextParams[])
var result = await _client.GetAllAsync<int[]>(TestSignalRTags.IntArrayParam, new object[] { new[] { 1, 2, 3 } });
// Assert
Assert.IsNotNull(result);
CollectionAssert.AreEqual(new[] { 2, 4, 6 }, result);
}
[TestMethod]
public async Task GetAllAsync_WithContextParams_StringList_ReturnsUppercased()
{
// Act
var result = await _client.GetAllAsync<List<string>>(TestSignalRTags.StringListParam, new object[] { new List<string> { "apple", "banana" } });
// Assert
Assert.IsNotNull(result);
CollectionAssert.AreEqual(new List<string> { "APPLE", "BANANA" }, result);
}
[TestMethod]
public async Task GetAllAsync_WithContextParams_Callback_IntArray()
{
// Arrange
int[]? receivedResult = null;
var tcs = new TaskCompletionSource<bool>();
// Act - GetAllAsync<T>(tag, callback, contextParams[])
await _client.GetAllAsync<int[]>(TestSignalRTags.IntArrayParam, response =>
{
receivedResult = response.ResponseData;
tcs.SetResult(true);
return Task.CompletedTask;
}, new object[] { new[] { 5, 10, 15 } });
await Task.WhenAny(tcs.Task, Task.Delay(5000));
// Assert
Assert.IsNotNull(receivedResult);
CollectionAssert.AreEqual(new[] { 10, 20, 30 }, receivedResult);
}
#endregion
#region PostDataAsync Tesztek - Komplex Objektumok
[TestMethod]
public async Task PostDataAsync_TestEchoRequest_ReturnsEchoResponse()
{
// Arrange
var request = new TestEchoRequest { Id = 42, Name = "TestName" };
// Act - PostDataAsync<TPost, TResponse>(tag, data)
var result = await _client.PostDataAsync<TestEchoRequest, TestEchoResponse>(TestSignalRTags.EchoTag, request);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(42, result.Id);
Assert.AreEqual("TestName", result.Name);
Assert.IsTrue(result.EchoedSuccessfully);
}
[TestMethod]
public async Task PostDataAsync_TestOrderItem_ReturnsProcessedItem()
{
// Arrange
var item = new TestOrderItem { Id = 1, ProductName = "TestProduct", Quantity = 5, UnitPrice = 10m };
// Act
var result = await _client.PostDataAsync(TestSignalRTags.TestOrderItemParam, item);
//await Task.Delay(1000);
// Assert
Assert.IsNotNull(result);
//Assert.AreEqual("Processed: TestProduct", result.ProductName);
Assert.AreEqual(item.Quantity * 2, result.Quantity); // doubled
}
[TestMethod]
public async Task PostDataAsync_TestOrder_ReturnsNestedOrder()
{
// Arrange
var order = new TestOrder
{
Id = 100,
CustomerName = "Test Customer",
OrderDate = DateTime.UtcNow,
Status = TestStatus.Active,
Items = [new() { Id = 1, ProductName = "Item1", Quantity = 2, UnitPrice = 10m }]
};
// Act
var result = await _client.PostDataAsync<TestOrder, TestOrder>(TestSignalRTags.TestOrderParam, order);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(100, result.Id);
Assert.AreEqual("Test Customer", result.CustomerName);
Assert.AreEqual(1, result.Items.Count);
}
[TestMethod]
public async Task PostDataAsync_SharedTag_ReturnsTag()
{
// Arrange
var tag = new SharedTag { Id = 1, Name = "Tag1", Description = "Desc", IsActive = true };
// Act
var result = await _client.PostDataAsync<SharedTag, SharedTag>(TestSignalRTags.SharedTagParam, tag);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("Tag1", result.Name);
Assert.AreEqual("Desc", result.Description);
}
[TestMethod]
public async Task PostDataAsync_Callback_TestEchoRequest()
{
// Arrange
var request = new TestEchoRequest { Id = 99, Name = "CallbackTest" };
TestEchoResponse? receivedResult = null;
var tcs = new TaskCompletionSource<bool>();
// Act - PostDataAsync<TPost, TResponse>(tag, data, callback)
await _client.PostDataAsync<TestEchoRequest, TestEchoResponse>(TestSignalRTags.EchoTag, request, response =>
{
receivedResult = response.ResponseData;
tcs.SetResult(true);
return Task.CompletedTask;
});
await Task.WhenAny(tcs.Task, Task.Delay(5000));
// Assert
Assert.IsNotNull(receivedResult);
Assert.AreEqual(99, receivedResult.Id);
}
#endregion
#region Edge Case Tesztek
[TestMethod]
public async Task GetByIdAsync_EmptyString_ReturnsEchoOfEmpty()
{
// Act
var result = await _client.GetByIdAsync<string>(TestSignalRTags.StringParam, "");
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("Echo: ", result);
}
[TestMethod]
public async Task GetByIdAsync_Zero_ReturnsFormattedString()
{
// Act
var result = await _client.GetByIdAsync<string>(TestSignalRTags.SingleIntParam, 0);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("Received: 0", result);
}
[TestMethod]
public async Task GetByIdAsync_NegativeInt_ReturnsFormattedString()
{
// Act
var result = await _client.GetByIdAsync<string>(TestSignalRTags.SingleIntParam, -42);
// Assert
Assert.IsNotNull(result);
Assert.AreEqual("Received: -42", result);
}
[TestMethod]
public async Task GetAllAsync_EmptyArray_ReturnsEmptyArray()
{
// Act
var result = await _client.GetAllAsync<int[]>(TestSignalRTags.IntArrayParam, new object[] { Array.Empty<int>() });
// Assert
Assert.IsNotNull(result);
Assert.AreEqual(0, result.Length);
}
#endregion
#region Binary Serialization Tesztek - AcBinaryDeserializationException reprodukálása
/// <summary>
/// Reprodukálja a GetMeasuringUsers hibát: AcBinaryDeserializationException: Invalid interned string index
/// A hiba akkor jelentkezik, amikor a szerver Binary formátumban küldi a választ (List<CustomerDto>),
/// de a kliens deszerializálásnál az interned string index hibás.
/// </summary>
[TestMethod]
public async Task GetAllAsync_CustomerDtoList_BinaryDeserialization_ThrowsInternedStringIndexError()
{
// Act - GetAllAsync<List<TestCustomerDto>>(tag)
// Ez a hívás a GetMeasuringUsers-höz hasonló forgatókönyvet reprodukál
var result = await _client.GetAllAsync<List<TestCustomerDto>>(TestSignalRTags.GetCustomerDtoList);
// Assert
Assert.IsNotNull(result);
Assert.IsTrue(result.Count > 0, "Should return at least one CustomerDto");
// Ellenőrizzük, hogy minden CustomerDto megfelelően deszerializálódott
foreach (var dto in result)
{
Assert.IsTrue(dto.Id > 0, $"CustomerDto.Id should be > 0, got {dto.Id}");
Assert.IsFalse(string.IsNullOrEmpty(dto.Username), "CustomerDto.Username should not be empty");
Assert.IsFalse(string.IsNullOrEmpty(dto.Email), "CustomerDto.Email should not be empty");
Console.WriteLine($"[GetAllAsync_CustomerDtoList] Id={dto.Id}, Username={dto.Username}, Email={dto.Email}, FullName={dto.FullName}");
}
}
/// <summary>
/// Nagyobb CustomerDto lista tesztelése - több interned string a szerializációban
/// </summary>
[TestMethod]
public async Task GetAllAsync_LargeCustomerDtoList_BinaryDeserialization_Success()
{
// Act
var result = await _client.GetAllAsync<List<TestCustomerDto>>(TestSignalRTags.GetLargeCustomerDtoList);
// Assert
Assert.IsNotNull(result);
Assert.IsTrue(result.Count >= 10, $"Should return at least 10 CustomerDtos, got {result.Count}");
Console.WriteLine($"[GetAllAsync_LargeCustomerDtoList] Received {result.Count} items");
}
#endregion
}