Files
ScadaBridge/tests/ZB.MOM.WW.ScadaBridge.CLI.Tests/Commands/TemplateAttributeListTests.cs
T
Joseph Doherty 513fa1aa16 docs(tests): fix CommentChecker findings across tests/ — 13,392 → 0 (repo-wide scan clean)
Comment/XML-doc changes only:
- add summaries to ~10k test methods, fixtures, fakes and helpers
  (+ <param> on theories, <returns> on async Task methods,
  <inheritdoc/> on interface implementations the checker can resolve)
- strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N,
  #NN, Component-0NN) from comments, keeping the explanatory text;
  reword false positives in comments only
- real docs on fakes implementing BCL/library interfaces
  (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime)
- reword the last 5 src/ false positives (CWE-1236, failures-1,
  year-0001, M365)

Only non-comment edits: four one-line nested classes split across lines
so members can carry docs. Build 0 errors / 0 warnings.
2026-10-07 15:05:49 -04:00

187 lines
7.2 KiB
C#

using System.CommandLine;
using ZB.MOM.WW.ScadaBridge.CLI.Commands;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ZB.MOM.WW.ScadaBridge.CLI.Tests.Commands;
/// <summary>
/// The <c>template attribute add</c> / <c>update</c> commands must support
/// structured multi-value (List) attributes — a new <c>--element-type</c> option,
/// a JSON-array <c>--value</c>, client-side element-type validation, and
/// <see cref="AddTemplateAttributeCommand.ElementDataType"/> /
/// <see cref="UpdateTemplateAttributeCommand.ElementDataType"/> wired into the
/// payload sent to the Management API.
/// </summary>
public class TemplateAttributeListTests
{
private static readonly Option<string> Url = new("--url") { Recursive = true };
private static readonly Option<string> Username = new("--username") { Recursive = true };
private static readonly Option<string> Password = new("--password") { Recursive = true };
private static readonly Option<string> Format = CliOptions.CreateFormatOption();
private static Command AttributeGroup()
=> TemplateCommands.Build(Url, Format, Username, Password)
.Subcommands.Single(c => c.Name == "attribute");
// ---- option surface ----
/// <summary>Verifies that the attribute add command exposes an element-type option.</summary>
[Fact]
public void AttributeAdd_HasElementTypeOption()
{
var add = AttributeGroup().Subcommands.Single(c => c.Name == "add");
Assert.Contains("--element-type", add.Options.Select(o => o.Name));
}
/// <summary>Verifies that the attribute update command exposes an element-type option.</summary>
[Fact]
public void AttributeUpdate_HasElementTypeOption()
{
var update = AttributeGroup().Subcommands.Single(c => c.Name == "update");
Assert.Contains("--element-type", update.Options.Select(o => o.Name));
}
// ---- client-side element-type validation (both directions) ----
/// <summary>Verifies that a List attribute with a valid scalar element type passes validation.</summary>
/// <param name="elementType">The scalar element type name under test.</param>
[Theory]
[InlineData("String")]
[InlineData("Int32")]
[InlineData("Float")]
[InlineData("Double")]
[InlineData("Boolean")]
[InlineData("DateTime")]
public void ValidateElementType_ListWithValidScalar_Ok(string elementType)
{
var ok = TemplateCommands.TryValidateElementType("List", elementType, out var error);
Assert.True(ok);
Assert.Null(error);
}
/// <summary>Verifies that element-type validation for a List attribute is case-insensitive.</summary>
[Fact]
public void ValidateElementType_ListWithValidScalar_CaseInsensitive()
{
var ok = TemplateCommands.TryValidateElementType("List", "string", out var error);
Assert.True(ok);
Assert.Null(error);
}
/// <summary>Verifies that a List attribute without an element type fails validation.</summary>
[Fact]
public void ValidateElementType_ListWithoutElementType_Error()
{
var ok = TemplateCommands.TryValidateElementType("List", null, out var error);
Assert.False(ok);
Assert.NotNull(error);
}
/// <summary>Verifies that a List attribute with a blank element type fails validation.</summary>
[Fact]
public void ValidateElementType_ListWithBlankElementType_Error()
{
var ok = TemplateCommands.TryValidateElementType("List", " ", out var error);
Assert.False(ok);
Assert.NotNull(error);
}
/// <summary>Verifies that a List attribute with an invalid scalar element type fails validation.</summary>
[Fact]
public void ValidateElementType_ListWithInvalidScalar_Error()
{
var ok = TemplateCommands.TryValidateElementType("List", "List", out var error);
Assert.False(ok);
Assert.NotNull(error);
}
/// <summary>Verifies that a List attribute with a binary element type fails validation.</summary>
[Fact]
public void ValidateElementType_ListWithBinaryScalar_Error()
{
// Binary is a DataType but not a permitted List element scalar.
var ok = TemplateCommands.TryValidateElementType("List", "Binary", out var error);
Assert.False(ok);
Assert.NotNull(error);
}
/// <summary>Verifies that a scalar attribute with an element type fails validation.</summary>
[Fact]
public void ValidateElementType_ScalarWithElementType_Error()
{
var ok = TemplateCommands.TryValidateElementType("String", "Int32", out var error);
Assert.False(ok);
Assert.NotNull(error);
}
/// <summary>Verifies that a scalar attribute without an element type passes validation.</summary>
[Fact]
public void ValidateElementType_ScalarWithoutElementType_Ok()
{
var ok = TemplateCommands.TryValidateElementType("Float", null, out var error);
Assert.True(ok);
Assert.Null(error);
}
// ---- payload wiring: the raw JSON value + ElementDataType flow into the command ----
/// <summary>Verifies that building an add command for a List attribute carries the element type and the raw JSON value.</summary>
[Fact]
public void BuildAddCommand_ListAttribute_CarriesElementTypeAndRawJsonValue()
{
var cmd = TemplateCommands.BuildAddAttributeCommand(
templateId: 7,
name: "WorkOrders",
dataType: "List",
value: """["WO-1","WO-2"]""",
description: null,
dataSource: null,
isLocked: false,
elementType: "String");
Assert.Equal(7, cmd.TemplateId);
Assert.Equal("List", cmd.DataType);
Assert.Equal("String", cmd.ElementDataType);
// The CLI forwards the raw JSON string unchanged — the API/codec parses it.
Assert.Equal("""["WO-1","WO-2"]""", cmd.Value);
}
/// <summary>Verifies that building an update command for a List attribute carries the element type and the raw JSON value.</summary>
[Fact]
public void BuildUpdateCommand_ListAttribute_CarriesElementTypeAndRawJsonValue()
{
var cmd = TemplateCommands.BuildUpdateAttributeCommand(
attributeId: 42,
name: "WorkOrders",
dataType: "List",
value: """["A","B"]""",
description: null,
dataSource: null,
isLocked: false,
elementType: "Int32");
Assert.Equal(42, cmd.AttributeId);
Assert.Equal("List", cmd.DataType);
Assert.Equal("Int32", cmd.ElementDataType);
Assert.Equal("""["A","B"]""", cmd.Value);
}
/// <summary>Verifies that building an add command for a scalar attribute leaves the element type null.</summary>
[Fact]
public void BuildAddCommand_ScalarAttribute_LeavesElementTypeNull()
{
var cmd = TemplateCommands.BuildAddAttributeCommand(
templateId: 1,
name: "Speed",
dataType: "Float",
value: "0",
description: null,
dataSource: null,
isLocked: false,
elementType: null);
Assert.Null(cmd.ElementDataType);
Assert.Equal("Float", cmd.DataType);
}
}