Files
lmxopcua/tests/Server/ZB.MOM.WW.OtOpcUa.AdminUI.Tests/ModbusDriverPageFormSerializationTests.cs
T
Joseph Doherty 96471d2345 refactor(adminui): B2-WP8 DriverTypeNames rewire + retire routed driver-authoring flow
Part 1 — rewire the three DriverType dispatch maps from hand-authored string
literals to the canonical DriverTypeNames constants (single source of truth):
- TagConfigEditorMap, TagConfigValidator (AdminUI)
- EquipmentTagConfigInspector (ControlPlane)
This FIXES the live drift ("TwinCat"->TwinCAT, "Focas"->FOCAS). The maps are
OrdinalIgnoreCase so behavior is identical; the value is no future drift.
Calculation is not added to the inspector (no CalculationTagDefinitionFactory.Inspect).
Added TagConfigDriverTypeNameGuardTests pinning the maps to the constants.

Part 2 — retire the routed /clusters/{id}/drivers driver-authoring flow (/raw
Waves A-C now cover driver/device/tag authoring end-to-end):
- Deleted DriverTypePicker, DriverEditRouter, the 8 *DriverPage shells, and the
  ClusterDrivers list page.
- Removed the "Drivers" tab from ClusterNav. Routes /clusters/{id}/drivers* now
  simply do not exist -> clean 404.
- The Forms/DeviceForms bodies, shared driver sections, and address pickers used
  by the /raw modals are untouched.

Part 3 — updated PageAuthorizationGuardTests census: removed the 10 deleted
ConfigEditor pages + ClusterDrivers, updated group-count comments (ConfigEditor
21->11, AuthenticatedRead 17->16). Removed the now-dead Clusters.Drivers usings
from the 4 *DriverPageFormSerializationTests + the guard test.

Claude-Session: https://claude.ai/code/session_01LVneM3eh1UtJxEisFXgmox
2026-07-16 04:39:22 -04:00

114 lines
4.3 KiB
C#

using System.Text.Json;
using System.Text.Json.Serialization;
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Driver.Modbus;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests;
public sealed class ModbusDriverPageFormSerializationTests
{
private static readonly JsonSerializerOptions _opts = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = false,
};
[Fact]
public void RoundTrip_PreservesKnownFields()
{
var original = new ModbusDriverOptions
{
Host = "10.0.0.42",
Port = 5020,
UnitId = 3,
Timeout = TimeSpan.FromSeconds(5),
MaxRegistersPerRead = 64,
MaxRegistersPerWrite = 60,
MaxCoilsPerRead = 500,
MaxReadGap = 8,
UseFC15ForSingleCoilWrites = true,
UseFC16ForSingleRegisterWrites = true,
DisableFC23 = true,
WriteOnChangeOnly = true,
AutoReconnect = false,
Family = ModbusFamily.DL205,
MelsecSubFamily = MelsecFamily.F_iQF,
Probe = new ModbusProbeOptions
{
Enabled = false,
Interval = TimeSpan.FromSeconds(10),
Timeout = TimeSpan.FromSeconds(3),
ProbeAddress = 7,
},
KeepAlive = new ModbusKeepAliveOptions
{
Enabled = false,
Time = TimeSpan.FromSeconds(60),
Interval = TimeSpan.FromSeconds(15),
RetryCount = 5,
},
Reconnect = new ModbusReconnectOptions
{
InitialDelay = TimeSpan.FromSeconds(1),
MaxDelay = TimeSpan.FromSeconds(60),
BackoffMultiplier = 1.5,
},
ProbeTimeoutSeconds = 10,
};
var json = JsonSerializer.Serialize(original, _opts);
var back = JsonSerializer.Deserialize<ModbusDriverOptions>(json, _opts);
back.ShouldNotBeNull();
back.Host.ShouldBe("10.0.0.42");
back.Port.ShouldBe(5020);
back.UnitId.ShouldBe((byte)3);
back.Timeout.ShouldBe(TimeSpan.FromSeconds(5));
back.MaxRegistersPerRead.ShouldBe((ushort)64);
back.MaxRegistersPerWrite.ShouldBe((ushort)60);
back.MaxCoilsPerRead.ShouldBe((ushort)500);
back.MaxReadGap.ShouldBe((ushort)8);
back.UseFC15ForSingleCoilWrites.ShouldBeTrue();
back.UseFC16ForSingleRegisterWrites.ShouldBeTrue();
back.DisableFC23.ShouldBeTrue();
back.WriteOnChangeOnly.ShouldBeTrue();
back.AutoReconnect.ShouldBeFalse();
back.Family.ShouldBe(ModbusFamily.DL205);
back.MelsecSubFamily.ShouldBe(MelsecFamily.F_iQF);
back.Probe.Enabled.ShouldBeFalse();
back.Probe.Interval.ShouldBe(TimeSpan.FromSeconds(10));
back.Probe.Timeout.ShouldBe(TimeSpan.FromSeconds(3));
back.Probe.ProbeAddress.ShouldBe((ushort)7);
back.KeepAlive.Enabled.ShouldBeFalse();
back.KeepAlive.Time.ShouldBe(TimeSpan.FromSeconds(60));
back.KeepAlive.Interval.ShouldBe(TimeSpan.FromSeconds(15));
back.KeepAlive.RetryCount.ShouldBe(5);
back.Reconnect.InitialDelay.ShouldBe(TimeSpan.FromSeconds(1));
back.Reconnect.MaxDelay.ShouldBe(TimeSpan.FromSeconds(60));
back.Reconnect.BackoffMultiplier.ShouldBe(1.5);
back.ProbeTimeoutSeconds.ShouldBe(10);
}
[Fact]
public void Deserialize_DropsUnknownFields()
{
var jsonWithExtra = """{"unknownField":"old-value","probeTimeoutSeconds":10}""";
var optsWithSkip = new JsonSerializerOptions(_opts)
{
UnmappedMemberHandling = JsonUnmappedMemberHandling.Skip,
};
var back = JsonSerializer.Deserialize<ModbusDriverOptions>(jsonWithExtra, optsWithSkip);
back.ShouldNotBeNull();
back.ProbeTimeoutSeconds.ShouldBe(10);
}
// v3 Batch-1 migration: the pre-declared Tags editor (ModbusDriverPage.ModbusTagRow +
// ModbusDriverOptions.Tags) was retired — tags moved to the Raw tree (/raw, Batch 2). The former
// TagRow_* / Tag_list_survives_* / ValidateRow_* / ToDefinition_preserves_* tests were removed.
// The connection/protocol-field + enum-serialization coverage (ModbusFamily, MelsecFamily) is
// retained by RoundTrip_PreservesKnownFields above unchanged.
}