using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
namespace ZB.MOM.WW.OtOpcUa.AdminUI.Tests.Uns;
///
/// Parity guards for the per-driver CSV column dispatch map (deferment.md G-5). It was
/// already a testable structure — unlike the two Razor @switch blocks that needed extracting
/// first — so nothing but the tests was missing.
///
///
/// The browse-commit seam (G-6) is guarded next door, not here (Gitea #558). This class used to
/// also hold Browse_commit_falls_back_to_the_generic_address_key_for_exactly_the_non_browsable_drivers,
/// over the same RawBrowseCommitMapper.BuildTagConfig seam
/// now enumerates. Two guards over one seam means two
/// hand-authored lists of "drivers that legitimately reach the generic key", and the pair can only
/// drift — this one's was additionally MISNAMED (NonBrowsableDriverTypes really meant "types
/// that produce the generic key": AbLegacy is genuinely non-browsable yet correctly absent,
/// because it has a typed branch). The surviving list is
/// RawBrowseCommitMapperParityTests.GenericKeyExemptions, which is named for what it holds,
/// carries a written reason per entry, and is checked against a derived browsable set rather
/// than a second hand-authored one.
///
[Trait("Category", "Unit")]
public sealed class DriverDispatchMapParityTests
{
///
/// Driver types with a typed tag editor but no CSV map, so import/export silently degrades them to
/// the raw TagConfigJson fallback. Empty — every editor-backed driver now has typed columns.
/// Deliberately expressed as "has a typed editor ⇒ has typed CSV columns" rather than
/// "every driver type", because a driver with no typed editor has nothing to project into columns.
/// Tying the two maps together is what makes this catch the next omission.
///
[Fact]
public void Every_driver_with_a_typed_tag_editor_has_typed_csv_columns()
{
var missing = DriverTypeNames.All
.Where(t => TagConfigEditorMap.Resolve(t) is not null && CsvColumnMap.Resolve(t) is null)
.OrderBy(t => t, StringComparer.Ordinal)
.ToList();
missing.ShouldBeEmpty(
$"these driver types have a typed tag editor but no CsvColumnMap entry, so CSV import/export "
+ $"drops them to the raw TagConfigJson fallback: {string.Join(", ", missing)}");
}
/// A CSV map for a driver type that no longer exists is a stale entry.
[Fact]
public void Every_csv_map_targets_a_declared_driver_type()
{
var declared = DriverTypeNames.All.ToHashSet(StringComparer.OrdinalIgnoreCase);
var stale = CsvColumnMap.All
.Select(m => m.DriverType)
.Where(t => !declared.Contains(t))
.OrderBy(t => t, StringComparer.Ordinal)
.ToList();
stale.ShouldBeEmpty($"CsvColumnMap has entries for undeclared driver types: {string.Join(", ", stale)}");
}
}