using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.AdminUI.ScriptAnalysis; namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.ScriptAnalysis; /// /// R04:P1 / S2 — the Monaco editor no longer ships its text over the circuit per keystroke; the page reads it on /// demand at blur / Save. That single read is one hub message, so the Blazor hub's receive limit is raised from /// the 32 KB default to 1 MB, and the JS refuses (rather than sends) a value that would not fit. /// public sealed class MonacoSyncTests { private static HubOptions ComponentHubOptions(IServiceProvider sp) { // ComponentHub is internal to Microsoft.AspNetCore.Components.Server; resolve its options by type name. var hubType = Type.GetType("Microsoft.AspNetCore.Components.Server.ComponentHub, Microsoft.AspNetCore.Components.Server", throwOnError: true)!; var optionsType = typeof(IOptions<>).MakeGenericType(typeof(HubOptions<>).MakeGenericType(hubType)); var options = sp.GetRequiredService(optionsType); return (HubOptions)optionsType.GetProperty("Value")!.GetValue(options)!; } [Fact] public void The_blazor_hub_accepts_a_1_MB_message() { var services = new ServiceCollection(); services.AddLogging(); services.AddAdminUI(); using var sp = services.BuildServiceProvider(); ComponentHubOptions(sp).MaximumReceiveMessageSize.ShouldBe(1024 * 1024); ScriptEditorLimits.HubMaximumReceiveMessageSize.ShouldBe(1024 * 1024); } [Fact] public void Without_AddAdminUI_the_default_limit_is_the_32_KB_that_truncated_large_scripts() { // Positive control for the test above: the 1 MB comes from AddAdminUI, not from a framework default. var services = new ServiceCollection(); services.AddLogging(); services.AddRazorComponents().AddInteractiveServerComponents(); using var sp = services.BuildServiceProvider(); (ComponentHubOptions(sp).MaximumReceiveMessageSize ?? 32 * 1024).ShouldBe(32 * 1024); } [Fact] public void The_editor_sync_budget_leaves_headroom_inside_the_hub_limit_and_fits_a_100_KB_script() { ScriptEditorLimits.MaxEditorSyncBytes.ShouldBeLessThan((int)ScriptEditorLimits.HubMaximumReceiveMessageSize); ScriptEditorLimits.MaxEditorSyncBytes.ShouldBeGreaterThan(4 * 100 * 1024); // 100 KB even after escaping twice } }