using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Drivers; namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Drivers; /// /// G1-F5 / F-FU2: Test Connect honours the driver's configured ProbeTimeoutSeconds (so it can /// lengthen the budget, not only shorten it), aligned across Galaxy and OpcUaClient, and the button /// drains its clear timer (R04 L2). /// [Trait("Category", "Unit")] public sealed class TestConnectBudgetTests { [Theory] [InlineData("{\"ProbeTimeoutSeconds\":30}", 30)] // Galaxy default — was silently 10 s [InlineData("{\"probeTimeoutSeconds\":15}", 15)] // OpcUaClient default, camelCase [InlineData("{\"ProbeTimeoutSeconds\":\"25\"}", 25)] [InlineData("{\"ProbeTimeoutSeconds\":2.5}", 3)] [InlineData("{\"ProbeTimeoutSeconds\":600}", 60)] // clamped to the actor's max public void A_configured_timeout_is_the_budget(string json, int expected) => TestConnectBudget.Resolve(json).ShouldBe(expected); [Theory] [InlineData(null)] [InlineData("")] [InlineData("{}")] [InlineData("{\"ProbeTimeoutSeconds\":0}")] [InlineData("{\"ProbeTimeoutSeconds\":-5}")] [InlineData("{\"ProbeTimeoutSeconds\":null}")] [InlineData("not json")] [InlineData("[1,2]")] [InlineData("{\"Nested\":{\"ProbeTimeoutSeconds\":40}}")] // only the root key counts public void No_valid_configured_timeout_falls_back(string? json) => TestConnectBudget.Resolve(json, fallbackSeconds: 10).ShouldBe(10); [Fact] public void The_fallback_is_clamped_too() { TestConnectBudget.Resolve("{}", fallbackSeconds: 0).ShouldBe(TestConnectBudget.MinSeconds); TestConnectBudget.Resolve("{}", fallbackSeconds: 999).ShouldBe(TestConnectBudget.MaxSeconds); } [Fact] public void Button_resolves_its_budget_from_the_config_and_drains_a_threading_timer() { var src = AdminUiSource.Read("Components", "Shared", "Drivers", "DriverTestConnectButton.razor"); src.ShouldContain("TestConnectBudget.Resolve(json, TimeoutSeconds)"); src.ShouldContain("@implements IAsyncDisposable"); src.ShouldContain("System.Threading.Timer"); src.ShouldNotContain("System.Timers.Timer"); src.ShouldNotContain("async (_, _)"); } }