mbproxy: close out the dashboard code-review minor findings

Resolves the remaining Minor items from the 2026-05-15 review so the
web-UI dashboard work has no open follow-ups: a real-HubConnection
end-to-end test for the SignalR feed, stable mbproxy.admin.broadcast.*
log-event names, keyboard/aria accessibility on the fleet table,
frontend JS hardening (URL-decode guard, NaN guards, shared util.js),
reconciler<->capture-registry coverage, throwing-sink and embedded-asset
tests, broadcaster polish, and a soft upper bound on AdminPushIntervalMs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-05-16 16:36:39 -04:00
parent 374eecd205
commit 0308490aef
21 changed files with 576 additions and 67 deletions
@@ -366,4 +366,35 @@ public sealed class ReloadValidatorTests
Assert.False(valid);
Assert.Contains(errors, e => e.Contains("AdminPushIntervalMs"));
}
[Fact]
public void Validate_AdminPushIntervalMs_AboveUpperBound_Fails()
{
// The soft upper bound (60 s) catches a seconds-as-milliseconds typo that
// would make the "live" dashboard feed effectively non-live.
var opts = new MbproxyOptions
{
Plcs = [MakePlc("PLC-A", 5020)],
AdminPushIntervalMs = 60_001,
};
bool valid = ReloadValidator.Validate(opts, out var errors);
Assert.False(valid);
Assert.Contains(errors, e => e.Contains("AdminPushIntervalMs"));
}
[Fact]
public void Validate_AdminPushIntervalMs_AtUpperBound_Passes()
{
var opts = new MbproxyOptions
{
Plcs = [MakePlc("PLC-A", 5020)],
AdminPushIntervalMs = 60_000,
};
bool valid = ReloadValidator.Validate(opts, out var errors);
Assert.True(valid, string.Join("; ", errors));
}
}