diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Raw/RawManualTagEntryModalMergedConfigTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Raw/RawManualTagEntryModalMergedConfigTests.cs index b09d9f6a..b81c38d8 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Raw/RawManualTagEntryModalMergedConfigTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/Raw/RawManualTagEntryModalMergedConfigTests.cs @@ -64,6 +64,36 @@ public sealed class RawManualTagEntryModalMergedConfigTests GetDriverConfigJson(modal).ShouldBe("{}"); } + [Fact] + public async Task The_accessor_is_live_not_a_captured_snapshot() + { + const string merged = """{"endpoint":"10.0.0.1:44818","slot":0}"""; + + (string DriverType, string MergedConfigJson)? answer = null; + var svc = new FakeRawTreeService { OnLoadMergedProbeConfig = _ => answer }; + + var modal = new RawManualTagEntryModal(); + SetParameters(modal, visible: true, deviceId: "dev-1", driverType: "AbCip"); + InjectService(modal, svc); + + await OpenAsync(modal); + + // The delegate an already-rendered editor is holding. It must read the field on every call, not a + // value captured when the parameters were built — the resolve is awaited AFTER the rows are + // seeded, so a snapshot taken at build time is permanently "{}". + var accessor = GetAccessor(modal); + accessor().ShouldBe("{}"); + + SetParameters(modal, visible: false, deviceId: "dev-1", driverType: "AbCip"); + await OpenAsync(modal); + + answer = ("AbCip", merged); + SetParameters(modal, visible: true, deviceId: "dev-1", driverType: "AbCip"); + await OpenAsync(modal); + + accessor().ShouldBe(merged); + } + /// /// Sets the modal's [Parameter]s. By reflection because BL0005 forbids assigning component /// parameters from outside the component, and this project treats warnings as errors. @@ -108,7 +138,10 @@ public sealed class RawManualTagEntryModalMergedConfigTests } /// Invokes the GetDriverConfigJson Func the first seeded row's editor is handed. - private static string GetDriverConfigJson(RawManualTagEntryModal modal) + private static string GetDriverConfigJson(RawManualTagEntryModal modal) => GetAccessor(modal)(); + + /// The GetDriverConfigJson Func itself, so a test can retain and re-invoke it. + private static Func GetAccessor(RawManualTagEntryModal modal) { var rowsField = typeof(RawManualTagEntryModal).GetField( "_rows", @@ -127,6 +160,6 @@ public sealed class RawManualTagEntryModalMergedConfigTests var parameters = (IDictionary)build!.Invoke(modal, [rows[0]])!; - return ((Func)parameters["GetDriverConfigJson"])(); + return (Func)parameters["GetDriverConfigJson"]; } }