audit work, fixed StellaOps.sln warnings/errors, fixed tests, sprints work, new advisories
This commit is contained in:
238
src/Cli/__Tests/StellaOps.Cli.Tests/Commands/SealCommandTests.cs
Normal file
238
src/Cli/__Tests/StellaOps.Cli.Tests/Commands/SealCommandTests.cs
Normal file
@@ -0,0 +1,238 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// SealCommandTests.cs
|
||||
// Sprint: SPRINT_20260105_002_004_CLI (CLI-006)
|
||||
// Description: Unit tests for facet seal CLI command.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
using StellaOps.Cli.Commands;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Unit tests for the seal command structure.
|
||||
/// </summary>
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class SealCommandTests
|
||||
{
|
||||
[Fact]
|
||||
public void SealCommand_HasCorrectName()
|
||||
{
|
||||
// Arrange & Act
|
||||
var command = BuildSealCommand();
|
||||
|
||||
// Assert
|
||||
Assert.Equal("seal", command.Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_HasCorrectDescription()
|
||||
{
|
||||
// Arrange & Act
|
||||
var command = BuildSealCommand();
|
||||
|
||||
// Assert
|
||||
Assert.Contains("facet seal", command.Description);
|
||||
Assert.Contains("drift detection", command.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_HasImageArgument()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
|
||||
// Act
|
||||
var imageArg = command.Arguments.FirstOrDefault(a => a.Name == "image");
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(imageArg);
|
||||
// Arguments are required by default in System.CommandLine
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_HasOutputOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
|
||||
// Act
|
||||
var outputOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "output" || o.Name == "--output" || o.Aliases.Contains("--output"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputOpt);
|
||||
Assert.True(outputOpt.Aliases.Contains("-o") || outputOpt.Aliases.Contains("--output"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_HasStoreOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
|
||||
// Act
|
||||
var storeOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "store" || o.Name == "--store" || o.Aliases.Contains("--store"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(storeOpt);
|
||||
Assert.Contains("Store seal", storeOpt.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_HasSignOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
|
||||
// Act
|
||||
var signOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "sign" || o.Name == "--sign" || o.Aliases.Contains("--sign"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(signOpt);
|
||||
Assert.Contains("Sign", signOpt.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_HasKeyOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
|
||||
// Act
|
||||
var keyOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "key" || o.Name == "--key" || o.Aliases.Contains("--key"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(keyOpt);
|
||||
Assert.True(keyOpt.Aliases.Contains("-k") || keyOpt.Aliases.Contains("--key"));
|
||||
Assert.Contains("Private key", keyOpt.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_HasFacetsOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
|
||||
// Act
|
||||
var facetsOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "facets" || o.Name == "--facets" || o.Aliases.Contains("--facets"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(facetsOpt);
|
||||
Assert.True(facetsOpt.Aliases.Contains("-f") || facetsOpt.Aliases.Contains("--facets"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_HasFormatOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
|
||||
// Act
|
||||
var formatOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "format" || o.Name == "--format" || o.Aliases.Contains("--format"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(formatOpt);
|
||||
Assert.Contains("json", formatOpt.Description);
|
||||
Assert.Contains("yaml", formatOpt.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_HasVerboseOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
|
||||
// Act
|
||||
var verboseOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "verbose" || o.Name == "--verbose" || o.Aliases.Contains("--verbose"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(verboseOpt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_AllOptionsAreConfigured()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
var expectedOptions = new[] { "output", "store", "sign", "key", "facets", "format", "verbose" };
|
||||
|
||||
// Act - normalize all option names by stripping leading dashes
|
||||
var actualOptionNames = command.Options
|
||||
.SelectMany(o => new[] { o.Name.TrimStart('-') }.Concat(o.Aliases.Select(a => a.TrimStart('-'))))
|
||||
.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
var actualArgs = command.Arguments.Select(a => a.Name).ToHashSet();
|
||||
|
||||
// Assert - image is an argument
|
||||
Assert.Contains("image", actualArgs);
|
||||
foreach (var expected in expectedOptions)
|
||||
{
|
||||
Assert.Contains(expected, actualOptionNames);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_ImageArgument_HasCorrectDescription()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
var imageArg = command.Arguments.First(a => a.Name == "image");
|
||||
|
||||
// Assert
|
||||
Assert.Contains("Image", imageArg.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_OutputOption_HasCorrectAliases()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
var outputOpt = command.Options.First(o =>
|
||||
o.Name == "output" || o.Name == "--output" || o.Aliases.Contains("--output"));
|
||||
|
||||
// Assert
|
||||
Assert.True(outputOpt.Aliases.Contains("--output") || outputOpt.Aliases.Contains("-o"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_KeyOption_HasCorrectAliases()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
var keyOpt = command.Options.First(o =>
|
||||
o.Name == "key" || o.Name == "--key" || o.Aliases.Contains("--key"));
|
||||
|
||||
// Assert
|
||||
Assert.True(keyOpt.Aliases.Contains("--key") || keyOpt.Aliases.Contains("-k"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SealCommand_FacetsOption_HasCorrectAliases()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildSealCommand();
|
||||
var facetsOpt = command.Options.First(o =>
|
||||
o.Name == "facets" || o.Name == "--facets" || o.Aliases.Contains("--facets"));
|
||||
|
||||
// Assert
|
||||
Assert.True(facetsOpt.Aliases.Contains("--facets") || facetsOpt.Aliases.Contains("-f"));
|
||||
}
|
||||
|
||||
private static Command BuildSealCommand()
|
||||
{
|
||||
var mockServices = new Mock<IServiceProvider>();
|
||||
var verboseOption = new Option<bool>("--verbose");
|
||||
return SealCommandGroup.BuildSealCommand(
|
||||
mockServices.Object,
|
||||
verboseOption,
|
||||
CancellationToken.None);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user