da2578833d
R04:P1 - the editor no longer ships its full text JS->.NET on every keystroke. It reports at blur, and ScriptEdit / the VirtualTag modal read the authoritative value with MonacoEditor.GetValueAsync at Save (validation runs after the pull). The Blazor hub's MaximumReceiveMessageSize is raised from 32 KB to 1 MB. The JS refuses a value that would not fit instead of sending an oversize frame, and Save surfaces that refusal rather than persisting stale source. R04:P9 - diagnostics carry a generation counter and an AbortController. Every edit aborts the in-flight request, and only the response for the current text is applied. R04:S2 - the always-empty inlay-hints provider, endpoint, service method and contracts are removed. R04:S3 - MarkersChanged is typed (DiagnosticMarker) and feeds a new ScriptProblemsList. Clicking a problem calls RevealLineAsync. Markers cross to .NET only when a list subscribes. Refs #745 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
57 lines
2.5 KiB
C#
57 lines
2.5 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
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
|
|
}
|
|
}
|