fix(adminui): AB forms read/write the factory-bound *Ms duration keys, migrate legacy TimeSpan strings (#576)
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
+47
-5
@@ -137,7 +137,7 @@ public sealed class AbLegacyDriverPageFormSerializationTests
|
||||
var json = AbLegacyDriverForm.Serialize(form.ToOptions(loaded.Devices));
|
||||
|
||||
json.ShouldContain($"\"transport\":\"{savedValue}\"");
|
||||
json.ShouldContain("\"timeout\":\"00:00:07\"");
|
||||
json.ShouldContain("\"timeoutMs\":7000");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -153,7 +153,7 @@ public sealed class AbLegacyDriverPageFormSerializationTests
|
||||
form.TimeoutSeconds = 7;
|
||||
var json = AbLegacyDriverForm.Serialize(form.ToOptions(loaded.Devices));
|
||||
json.ShouldNotContain("transport", Case.Insensitive);
|
||||
json.ShouldContain("\"timeout\":\"00:00:07\"");
|
||||
json.ShouldContain("\"timeoutMs\":7000");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -208,12 +208,13 @@ public sealed class AbLegacyDriverPageFormSerializationTests
|
||||
var root = System.Text.Json.Nodes.JsonNode.Parse(
|
||||
AbLegacyDriverForm.Serialize(form.ToOptions(loaded.Devices), FullConfig))!.AsObject();
|
||||
|
||||
root["timeout"]!.GetValue<string>().ShouldBe("00:00:09");
|
||||
root["timeoutMs"]!.GetValue<int>().ShouldBe(9000);
|
||||
root.ContainsKey("timeout").ShouldBeFalse();
|
||||
root["transport"]!.GetValue<string>().ShouldBe("Native");
|
||||
root["probeTimeoutSeconds"]!.GetValue<int>().ShouldBe(12);
|
||||
root["probe"]!["enabled"]!.GetValue<bool>().ShouldBeTrue();
|
||||
root["probe"]!["interval"]!.GetValue<string>().ShouldBe("00:00:10");
|
||||
root["probe"]!["timeout"]!.GetValue<string>().ShouldBe("00:00:03");
|
||||
root["probe"]!["intervalMs"]!.GetValue<int>().ShouldBe(10000);
|
||||
root["probe"]!["timeoutMs"]!.GetValue<int>().ShouldBe(3000);
|
||||
root["probe"]!["probeAddress"]!.GetValue<string>().ShouldBe("S:1");
|
||||
root["probe"]!["futureProbeKnob"]!.GetValue<int>().ShouldBe(7);
|
||||
root["devices"]![0]!["futureDeviceKey"]!.GetValue<string>().ShouldBe("keep");
|
||||
@@ -234,4 +235,45 @@ public sealed class AbLegacyDriverPageFormSerializationTests
|
||||
root.ContainsKey("transport").ShouldBeFalse();
|
||||
root["futureOption"].ShouldNotBeNull();
|
||||
}
|
||||
|
||||
// ---- #576: the saved JSON must be what the driver FACTORY binds (integer-ms keys) ----
|
||||
|
||||
[Fact]
|
||||
public void An_edited_timeout_reaches_the_factory_bound_options()
|
||||
{
|
||||
var original = """{"timeoutMs":5000,"probe":{"enabled":true,"intervalMs":7000,"timeoutMs":1500,"probeAddress":"S:1"},"devices":[{"hostAddress":"ab://10.0.0.1/1,0","plcFamily":"Slc500"}]}""";
|
||||
var loaded = AbLegacyDriverForm.TryDeserialize(original)!;
|
||||
var form = AbLegacyDriverForm.FormModel.FromJson(original, loaded);
|
||||
form.TimeoutSeconds.ShouldBe(5);
|
||||
form.TimeoutSeconds = 11;
|
||||
|
||||
var saved = AbLegacyDriverForm.Serialize(form.ToOptions(loaded.Devices), original);
|
||||
var bound = ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.AbLegacyDriverFactoryExtensions.ParseOptions("t", saved);
|
||||
|
||||
bound.Timeout.ShouldBe(TimeSpan.FromSeconds(11));
|
||||
bound.Probe.Interval.ShouldBe(TimeSpan.FromSeconds(7));
|
||||
bound.Probe.Timeout.ShouldBe(TimeSpan.FromMilliseconds(1500));
|
||||
bound.Probe.ProbeAddress.ShouldBe("S:1");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_legacy_TimeSpan_string_key_is_loaded_then_migrated_to_ms_and_removed()
|
||||
{
|
||||
var original = """{"timeout":"00:00:05","probe":{"interval":"00:00:10","timeout":"00:00:03"}}""";
|
||||
var loaded = AbLegacyDriverForm.TryDeserialize(original)!;
|
||||
var form = AbLegacyDriverForm.FormModel.FromJson(original, loaded);
|
||||
form.TimeoutSeconds.ShouldBe(5);
|
||||
form.TimeoutSeconds = 6;
|
||||
|
||||
var saved = AbLegacyDriverForm.Serialize(form.ToOptions(loaded.Devices), original);
|
||||
var root = System.Text.Json.Nodes.JsonNode.Parse(saved)!.AsObject();
|
||||
root.ContainsKey("timeout").ShouldBeFalse();
|
||||
root["probe"]!.AsObject().ContainsKey("interval").ShouldBeFalse();
|
||||
root["probe"]!.AsObject().ContainsKey("timeout").ShouldBeFalse();
|
||||
|
||||
var bound = ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.AbLegacyDriverFactoryExtensions.ParseOptions("t", saved);
|
||||
bound.Timeout.ShouldBe(TimeSpan.FromSeconds(6));
|
||||
bound.Probe.Interval.ShouldBe(TimeSpan.FromSeconds(10));
|
||||
bound.Probe.Timeout.ShouldBe(TimeSpan.FromSeconds(3));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user