502 lines
16 KiB
C#
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
|
|
} |