diff --git a/FruitBank.Common/FruitBankConstClient.cs b/FruitBank.Common/FruitBankConstClient.cs index c444b5c..a41a2e9 100644 --- a/FruitBank.Common/FruitBankConstClient.cs +++ b/FruitBank.Common/FruitBankConstClient.cs @@ -7,7 +7,7 @@ public static class FruitBankConstClient { public static string DefaultLocale = "en-US"; - public static string BaseUrl = "http://localhost:59579"; //FrutiBank nop + public static string BaseUrl = "https://localhost:59579"; //FrutiBank nop //public static string BaseUrl = "https://shop.fruitbank.hu"; //FrutiBank nop #if RELEASE // public static string BaseUrl = "https://shop.fruitbank.hu"; //FrutiBank nop diff --git a/FruitBankHybrid.Shared.Tests/FruitBankHybrid.Shared.Tests.csproj b/FruitBankHybrid.Shared.Tests/FruitBankHybrid.Shared.Tests.csproj index b7edf0c..87c6638 100644 --- a/FruitBankHybrid.Shared.Tests/FruitBankHybrid.Shared.Tests.csproj +++ b/FruitBankHybrid.Shared.Tests/FruitBankHybrid.Shared.Tests.csproj @@ -72,4 +72,9 @@ + + + + + diff --git a/FruitBankHybrid.Shared.Tests/SandboxEndpointSimpleTests.cs b/FruitBankHybrid.Shared.Tests/SandboxEndpointSimpleTests.cs new file mode 100644 index 0000000..cb3c2d0 --- /dev/null +++ b/FruitBankHybrid.Shared.Tests/SandboxEndpointSimpleTests.cs @@ -0,0 +1,320 @@ +using AyCode.Core.Enums; +using AyCode.Core.Loggers; +using AyCode.Utils.Extensions; +using FruitBank.Common; +using FruitBank.Common.Dtos; +using FruitBank.Common.Entities; +using FruitBank.Common.Interfaces; +using FruitBank.Common.Loggers; +using FruitBankHybrid.Shared.Services.SignalRs; +using System.Diagnostics.CodeAnalysis; +using FruitBank.Common.SignalRs; +using AyCode.Services.SignalRs; + +namespace FruitBankHybrid.Shared.Tests; + +/// +/// Teszt a TestSignalREndpoint-hoz. +/// FONTOS: A SANDBOX-ot manuálisan kell elindítani a tesztek futtatása előtt! +/// Indítás: dotnet run --project Mango.Sandbox.EndPoints --urls http://localhost:59579 +/// +[TestClass] +public class SandboxEndpointSimpleTests +{ + private static readonly string SandboxUrl = FruitBankConstClient.BaseUrl; //"http://localhost:59579"; + private static readonly string HubUrl = $"{SandboxUrl}/fbHub"; + + // Teszt SignalR Tags (TestSignalRTags-ből) + private const int PingTag = SignalRTags.PingTag; + private const int EchoTag = SignalRTags.EchoTag; + private const int GetTestItemsTag = 9003; + + private FruitBankSignalRClient _signalRClient = null!; + + [TestInitialize] + public void TestInit() + { + if (!SandboxUrl.Contains("localhost:")) throw new Exception("NEM LOCALHOST-ON TESZTELÜNK!"); + + _signalRClient = new FruitBankSignalRClient(new List + { + //new ConsoleLogWriter(AppType.TestUnit, LogLevel.Detail, nameof(FruitBankClientTests)), + new SignaRClientLogItemWriter(AppType.TestUnit, LogLevel.Detail, nameof(SandboxEndpointSimpleTests)) + }); + } + + #region HTTP Endpoint Tests + + [TestMethod] + public async Task HealthEndpoint_ReturnsSuccess() + { + using var httpClient = new HttpClient(); + var response = await httpClient.GetAsync($"{SandboxUrl}/health"); + Assert.IsTrue(response.IsSuccessStatusCode, $"Health endpoint returned {response.StatusCode}"); + } + + [TestMethod] + public async Task RootEndpoint_ReturnsSandboxIsRunning() + { + using var httpClient = new HttpClient(); + var response = await httpClient.GetStringAsync(SandboxUrl); + Assert.AreEqual("SANDBOX is running!", response); + } + + #endregion + + #region SignalR Connection Tests + + [TestMethod] + public async Task SignalR_Negotiate_ReturnsSuccess() + { + using var httpClient = new HttpClient(); + var response = await httpClient.PostAsync($"{HubUrl}/negotiate?negotiateVersion=1", null); + Assert.IsTrue(response.IsSuccessStatusCode, $"SignalR negotiate returned {response.StatusCode}"); + } + + [TestMethod] + public async Task SignalR_Connect_Succeeds() + { + var testItems = await _signalRClient.GetAllAsync>(GetTestItemsTag); + Assert.IsNotNull(testItems); + } + + public class TestItem + { + public int Id { get; set; } + public string Name { get; set; } = string.Empty; + public decimal Value { get; set; } + } + +//[TestMethod] + //public async Task SignalR_Connect_Succeeds() + //{ + // var connection = new HubConnectionBuilder() + // .WithUrl(HubUrl) + // .Build(); + + // try + // { + // await connection.StartAsync(); + // Assert.AreEqual(HubConnectionState.Connected, connection.State); + // } + // finally + // { + // await connection.StopAsync(); + // } + //} + + //#endregion + + //#region TestSignalREndpoint Tests + + //[TestMethod] + //public async Task SignalR_Ping_ReturnsResponse() + //{ + // var testMessage = "Hello SignalR!"; + // await TestSignalREndpoint(PingTag, testMessage, "Ping", response => + // { + // Assert.IsNotNull(response, "Response should not be null"); + + // // Parse JSON response + // using var jsonDoc = JsonDocument.Parse(response); + // var root = jsonDoc.RootElement; + + // // Ellenőrizzük, hogy van Message property + // Assert.IsTrue(root.TryGetProperty("Message", out var messageElement) || + // root.TryGetProperty("message", out messageElement), + // "Response should contain 'Message' property"); + + // Console.WriteLine($"[Ping] Received message: {messageElement.GetString()}"); + // }); + //} + + //[TestMethod] + //public async Task SignalR_Echo_ReturnsEchoedData() + //{ + // var request = new { Id = 42, Name = "TestName" }; + // await TestSignalREndpoint(EchoTag, request, "Echo", response => + // { + // Assert.IsNotNull(response, "Response should not be null"); + + // using var jsonDoc = JsonDocument.Parse(response); + // var root = jsonDoc.RootElement; + + // // Ellenőrizzük az Id-t + // Assert.IsTrue(root.TryGetProperty("Id", out var idElement) || + // root.TryGetProperty("id", out idElement), + // "Response should contain 'Id' property"); + // Assert.AreEqual(42, idElement.GetInt32(), "Id should be 42"); + + // // Ellenőrizzük a Name-et + // Assert.IsTrue(root.TryGetProperty("Name", out var nameElement) || + // root.TryGetProperty("name", out nameElement), + // "Response should contain 'Name' property"); + // Assert.AreEqual("TestName", nameElement.GetString(), "Name should be 'TestName'"); + + // Console.WriteLine($"[Echo] Received: Id={idElement.GetInt32()}, Name={nameElement.GetString()}"); + // }); + //} + + //[TestMethod] + //public async Task SignalR_GetTestItems_ReturnsItemList() + //{ + // await TestSignalREndpoint(GetTestItemsTag, null, "GetTestItems", response => + // { + // Assert.IsNotNull(response, "Response should not be null"); + + // using var jsonDoc = JsonDocument.Parse(response); + // var root = jsonDoc.RootElement; + + // // Ellenőrizzük, hogy tömb-e + // Assert.AreEqual(JsonValueKind.Array, root.ValueKind, "Response should be an array"); + // Assert.IsTrue(root.GetArrayLength() > 0, "Array should have items"); + + // Console.WriteLine($"[GetTestItems] Received {root.GetArrayLength()} items"); + + // // Ellenőrizzük az első elemet + // var firstItem = root[0]; + // Assert.IsTrue(firstItem.TryGetProperty("Id", out _) || firstItem.TryGetProperty("id", out _), + // "Item should have 'Id' property"); + // Assert.IsTrue(firstItem.TryGetProperty("Name", out _) || firstItem.TryGetProperty("name", out _), + // "Item should have 'Name' property"); + // }); + //} + + //#endregion + + //#region EREDETI BUSINESS ENDPOINT TESZTEK - KIKOMMENTEZVE + + //// =========================================== + //// === Az alábbi tesztek az eredeti 3 endpoint-ot tesztelik === + //// === Visszaállításhoz: töröld a kommenteket és regisztráld az endpoint-okat a Program.cs-ben === + //// =========================================== + + //// [TestMethod] + //// public async Task SignalR_GetMeasuringUsers_ReturnsJson() + //// { + //// await TestSignalREndpoint(GetMeasuringUsersTag, null, "GetMeasuringUsers"); + //// } + + //// [TestMethod] + //// public async Task SignalR_GetStockQuantityHistoryDtos_ReturnsJson() + //// { + //// await TestSignalREndpoint(GetStockQuantityHistoryDtosTag, null, "GetStockQuantityHistoryDtos"); + //// } + + //// [TestMethod] + //// public async Task SignalR_GetStockQuantityHistoryDtosByProductId_ReturnsJson() + //// { + //// // ProductId = 10 + //// await TestSignalREndpoint(GetStockQuantityHistoryDtosByProductIdTag, 10, "GetStockQuantityHistoryDtosByProductId"); + //// } + + //// [TestMethod] + //// public async Task SignalR_GetShippingDocumentsByShippingId_ReturnsJson() + //// { + //// // ShippingId = 5 + //// await TestSignalREndpoint(GetShippingDocumentsByShippingIdTag, 5, "GetShippingDocumentsByShippingId"); + //// } + + //// [TestMethod] + //// public async Task SignalR_GetOrderDtoById_ReturnsJson() + //// { + //// // OrderId = 15 + //// await TestSignalREndpoint(GetOrderDtoByIdTag, 15, "GetOrderDtoById"); + //// } + + //// [TestMethod] + //// public async Task SignalR_GetStockTakingItemsById_ReturnsJson() + //// { + //// // StockTakingItemId = 200 + //// await TestSignalREndpoint(GetStockTakingItemsByIdTag, 200, "GetStockTakingItemsById"); + //// } + + //#endregion + + //#region Helper Methods + + //private async Task TestSignalREndpoint(int tag, object? parameter, string endpointName, Action? validateResponse = null) + //{ + // var connection = new HubConnectionBuilder() + // .WithUrl(HubUrl) + // .Build(); + + // string? receivedJson = null; + // int receivedTag = -1; + // var responseReceived = new TaskCompletionSource(); + + // connection.On("ReceiveMessage", (responseTag, data) => + // { + // receivedTag = responseTag; + // if (data != null && data.Length > 0) + // { + // receivedJson = Encoding.UTF8.GetString(data); + // } + // responseReceived.TrySetResult(true); + // }); + + // try + // { + // await connection.StartAsync(); + // Assert.AreEqual(HubConnectionState.Connected, connection.State, $"Failed to connect to SignalR hub for {endpointName}"); + + // // Készítsük el a request data-t + // // Ha nincs paraméter, null-t küldünk (nem üres byte tömböt!) + // byte[]? requestData = parameter != null + // ? Encoding.UTF8.GetBytes(JsonSerializer.Serialize(parameter)) + // : null; + + // // A Hub metódus neve: OnReceiveMessage (3 paraméter: messageTag, messageBytes, requestId) + // await connection.InvokeAsync("OnReceiveMessage", tag, requestData, (int?)null); + + // var completed = await Task.WhenAny(responseReceived.Task, Task.Delay(15000)); + + // if (completed == responseReceived.Task) + // { + // Console.WriteLine($"[{endpointName}] Response tag: {receivedTag}"); + // Console.WriteLine($"[{endpointName}] Response JSON: {receivedJson?.Substring(0, Math.Min(500, receivedJson?.Length ?? 0))}..."); + + // // Ellenőrizzük, hogy valid JSON-e (ha van adat) + // if (!string.IsNullOrEmpty(receivedJson)) + // { + // try + // { + // using var jsonDoc = JsonDocument.Parse(receivedJson); + // Assert.IsTrue( + // jsonDoc.RootElement.ValueKind == JsonValueKind.Array || + // jsonDoc.RootElement.ValueKind == JsonValueKind.Object || + // jsonDoc.RootElement.ValueKind == JsonValueKind.Null, + // $"[{endpointName}] Response is not a valid JSON"); + + // // Custom validation + // validateResponse?.Invoke(receivedJson); + // } + // catch (JsonException ex) + // { + // Assert.Fail($"[{endpointName}] Invalid JSON response: {ex.Message}"); + // } + // } + // } + // else + // { + // Assert.AreEqual(HubConnectionState.Connected, connection.State, + // $"[{endpointName}] Connection was closed - check SANDBOX logs for DI errors"); + // } + // } + // catch (Exception ex) + // { + // Assert.Fail($"[{endpointName}] SignalR error: {ex.Message}. Check SANDBOX logs for missing DI registrations."); + // } + // finally + // { + // if (connection.State == HubConnectionState.Connected) + // { + // await connection.StopAsync(); + // } + // } + //} + + #endregion +} diff --git a/FruitBankHybrid.Shared/Layout/MainLayout.razor b/FruitBankHybrid.Shared/Layout/MainLayout.razor index e59d447..b6e25a2 100644 --- a/FruitBankHybrid.Shared/Layout/MainLayout.razor +++ b/FruitBankHybrid.Shared/Layout/MainLayout.razor @@ -30,10 +30,12 @@ ShowCloseButton="true"> + @* @Body *@ @if (LoggedInModel.IsLoggedIn || IsOnLoginPage) { @Body } + diff --git a/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs b/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs index 48ddd68..178d594 100644 --- a/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs +++ b/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs @@ -54,7 +54,7 @@ public partial class MainLayout : LayoutComponentBase if (!firstRender) return; await LoggedInModel.TryAutoLoginAsync(); - + if (!LoggedInModel.IsLoggedIn && !IsOnLoginPage) { NavManager.NavigateTo("/Login"); @@ -63,7 +63,7 @@ public partial class MainLayout : LayoutComponentBase { StateHasChanged(); // Refresh UI after successful auto-login } - } + } private async Task SignalRClientOnMessageReceived(int messageTag, string? jsonMessage) { diff --git a/FruitBankHybrid.Web.Client/FruitBankHybrid.Web.Client.csproj b/FruitBankHybrid.Web.Client/FruitBankHybrid.Web.Client.csproj index e3b09f6..1e1f804 100644 --- a/FruitBankHybrid.Web.Client/FruitBankHybrid.Web.Client.csproj +++ b/FruitBankHybrid.Web.Client/FruitBankHybrid.Web.Client.csproj @@ -13,7 +13,7 @@ - + diff --git a/FruitBankHybrid.Web/Components/App.razor b/FruitBankHybrid.Web/Components/App.razor index a264b16..edd84b6 100644 --- a/FruitBankHybrid.Web/Components/App.razor +++ b/FruitBankHybrid.Web/Components/App.razor @@ -5,30 +5,30 @@ - - - + + + - - @DxResourceManager.RegisterScripts() - @DxResourceManager.RegisterTheme(Themes.Fluent) + @* *@ + @DxResourceManager.RegisterScripts() + @DxResourceManager.RegisterTheme(Themes.Fluent) - - - - - - - + + + + + + + - - + + @code { - private string AppendVersion(string path) => FileVersionProvider.AddFileVersionToPath("/", path); + private string AppendVersion(string path) => FileVersionProvider.AddFileVersionToPath("/", path); } \ No newline at end of file