using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Drivers;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Drivers;
///
/// Closes deferment.md G-4. A guard already existed for DriverTypeNames ↔ the /raw
/// driver PICKER, but not for the two dispatch maps downstream of it, so a driver could be registered,
/// offered in the picker, and then have no config form — which is exactly what happened to
/// Calculation (G-1) and to Sql/MTConnect/Calculation on the device modal (G-2). Both survived
/// review because nothing could see them.
/// These are ordinary map lookups rather than reflection over a private field: the two modals were
/// converted from a Razor @switch — unreachable from a test, since it compiles into
/// BuildRenderTree's IL — to DriverConfigFormMap / DeviceFormMap. There is no bUnit
/// in this project, so a map is the only thing a test can hold on to.
///
[Trait("Category", "Unit")]
public sealed class DriverFormMapParityTests
{
/// Every declared driver type must have a typed config form. There is no exemption: a driver
/// with no configurable surface still needs a form to say so, or the operator meets a bare warning.
[Fact]
public void Every_declared_driver_type_has_a_typed_config_form()
{
var missing = DriverTypeNames.All
.Where(t => DriverConfigFormMap.Resolve(t) is null)
.OrderBy(t => t, StringComparer.Ordinal)
.ToList();
missing.ShouldBeEmpty(
$"these driver types are registered and offered in the /raw picker but DriverConfigModal has no "
+ $"form for them, so their config is unauthorable through the UI: {string.Join(", ", missing)}");
}
/// The reverse direction — a mapped type that is no longer a declared driver type is a stale
/// entry, and would keep a deleted driver's form reachable.
[Fact]
public void Every_config_form_maps_to_a_declared_driver_type()
{
var declared = DriverTypeNames.All.ToHashSet(StringComparer.OrdinalIgnoreCase);
var stale = DriverConfigFormMap.MappedDriverTypes
.Where(t => !declared.Contains(t))
.OrderBy(t => t, StringComparer.Ordinal)
.ToList();
stale.ShouldBeEmpty($"DriverConfigFormMap has entries for undeclared driver types: {string.Join(", ", stale)}");
}
///
/// Every declared driver type must EITHER have a typed device form OR be declared single-connection.
/// The either/or matters: demanding a device form from every driver would be wrong (Sql has one
/// connection string, MTConnect one Agent URI, Calculation no connection at all), and a test that has
/// to be suppressed for five drivers stops being read. Forcing the choice to be explicit is what makes
/// this a guard — a new driver cannot silently fall through.
///
[Fact]
public void Every_declared_driver_type_has_a_device_form_or_is_declared_single_connection()
{
var unaccounted = DriverTypeNames.All
.Where(t => DeviceFormMap.Resolve(t) is null && !DeviceFormMap.IsSingleConnection(t))
.OrderBy(t => t, StringComparer.Ordinal)
.ToList();
unaccounted.ShouldBeEmpty(
$"these driver types have neither a typed device form nor a place in "
+ $"DeviceFormMap.SingleConnectionDriverTypes, so DeviceModal falls through to its "
+ $"\"no typed device form\" warning: {string.Join(", ", unaccounted)}");
}
/// The reverse direction for the device map.
[Fact]
public void Every_device_form_maps_to_a_declared_driver_type()
{
var declared = DriverTypeNames.All.ToHashSet(StringComparer.OrdinalIgnoreCase);
var stale = DeviceFormMap.MappedDriverTypes
.Concat(DeviceFormMap.SingleConnectionDriverTypes)
.Where(t => !declared.Contains(t))
.Distinct(StringComparer.OrdinalIgnoreCase)
.OrderBy(t => t, StringComparer.Ordinal)
.ToList();
stale.ShouldBeEmpty($"DeviceFormMap references undeclared driver types: {string.Join(", ", stale)}");
}
///
/// A driver that authors its connection on the DRIVER form must have a driver form to author it on.
/// Without this, declaring a type single-connection would be a way to opt out of both maps at once
/// and leave the connection unauthorable anywhere.
///
[Fact]
public void Every_single_connection_driver_has_a_driver_config_form()
{
var missing = DeviceFormMap.SingleConnectionDriverTypes
.Where(t => DriverConfigFormMap.Resolve(t) is null)
.OrderBy(t => t, StringComparer.Ordinal)
.ToList();
missing.ShouldBeEmpty(
$"these types are declared single-connection but have no driver config form, so their connection "
+ $"cannot be authored anywhere: {string.Join(", ", missing)}");
}
}