feat(cli): instance import-overrides --file (T16)

This commit is contained in:
Joseph Doherty
2026-06-18 02:27:40 -04:00
parent 2cfe0de927
commit 586d54359c
3 changed files with 157 additions and 0 deletions
@@ -0,0 +1,91 @@
using ZB.MOM.WW.ScadaBridge.Commons.Types;
namespace ZB.MOM.WW.ScadaBridge.CLI.Tests;
/// <summary>
/// Verifies the CSV parsing behaviour that backs <c>instance import-overrides</c>:
/// parse errors block the apply step; valid CSV produces the expected
/// <c>attributeName → value</c> dictionary that <see cref="SetInstanceOverridesCommand"/>
/// consumes.
/// </summary>
public class ImportOverridesTests
{
// ── error path ───────────────────────────────────────────────────────────
[Fact]
public void CsvWithMissingHeader_ProducesErrors()
{
var result = OverrideCsvParser.Parse("Speed,100");
Assert.NotEmpty(result.Errors);
Assert.Empty(result.Rows);
}
[Fact]
public void CsvWithBlankAttributeName_ProducesError()
{
const string csv = "AttributeName,Value\n,100";
var result = OverrideCsvParser.Parse(csv);
Assert.NotEmpty(result.Errors);
// The bad row is excluded; no rows flow through.
Assert.Empty(result.Rows);
}
[Fact]
public void CsvWithWrongColumnCount_ProducesError()
{
const string csv = "AttributeName,Value\nSpeed,100,extra";
var result = OverrideCsvParser.Parse(csv);
Assert.NotEmpty(result.Errors);
Assert.Empty(result.Rows);
}
// ── happy path ───────────────────────────────────────────────────────────
[Fact]
public void ValidCsv_ProducesCorrectOverridesDictionary()
{
const string csv = """
AttributeName,Value
Speed,100
Mode,
Label,Hello
""";
var parseResult = OverrideCsvParser.Parse(csv);
Assert.Empty(parseResult.Errors);
Assert.Equal(3, parseResult.Rows.Count);
// Build the same dictionary that BuildImportOverrides produces.
var overrides = parseResult.Rows.ToDictionary(r => r.AttributeName, r => r.Value);
Assert.Equal("100", overrides["Speed"]);
Assert.Null(overrides["Mode"]); // empty Value → null → clear the override
Assert.Equal("Hello", overrides["Label"]);
}
[Fact]
public void ValidCsvWithElementTypeColumn_OverridesDictIgnoresElementType()
{
const string csv = """
AttributeName,Value,ElementType
Speed,100,Float
Mode,,
""";
var parseResult = OverrideCsvParser.Parse(csv);
Assert.Empty(parseResult.Errors);
Assert.Equal(2, parseResult.Rows.Count);
// ElementType is carried on the row but SetInstanceOverridesCommand only
// takes attributeName → value; confirm the dict shape matches.
var overrides = parseResult.Rows.ToDictionary(r => r.AttributeName, r => r.Value);
Assert.Equal("100", overrides["Speed"]);
Assert.Null(overrides["Mode"]);
}
}