audit work, fixed StellaOps.sln warnings/errors, fixed tests, sprints work, new advisories
This commit is contained in:
@@ -0,0 +1,241 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// DriftCommandTests.cs
|
||||
// Sprint: SPRINT_20260105_002_004_CLI (CLI-010)
|
||||
// Description: Unit tests for facet drift analysis CLI command.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
using StellaOps.Cli.Commands;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Unit tests for the drift command structure.
|
||||
/// </summary>
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class DriftCommandTests
|
||||
{
|
||||
[Fact]
|
||||
public void DriftCommand_HasCorrectName()
|
||||
{
|
||||
// Arrange & Act
|
||||
var command = BuildDriftCommand();
|
||||
|
||||
// Assert
|
||||
Assert.Equal("drift", command.Name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DriftCommand_HasCorrectDescription()
|
||||
{
|
||||
// Arrange & Act
|
||||
var command = BuildDriftCommand();
|
||||
|
||||
// Assert
|
||||
Assert.Contains("drift", command.Description);
|
||||
Assert.Contains("baseline", command.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DriftCommand_HasImageArgument()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
|
||||
// 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 DriftCommand_HasBaselineOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
|
||||
// Act
|
||||
var baselineOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "baseline" || o.Name == "--baseline" || o.Aliases.Contains("--baseline"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(baselineOpt);
|
||||
Assert.True(baselineOpt.Aliases.Contains("-b") || baselineOpt.Aliases.Contains("--baseline"));
|
||||
Assert.Contains("Baseline seal", baselineOpt.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DriftCommand_HasFormatOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
|
||||
// Act
|
||||
var formatOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "format" || o.Name == "--format" || o.Aliases.Contains("--format"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(formatOpt);
|
||||
Assert.Contains("table", formatOpt.Description);
|
||||
Assert.Contains("json", formatOpt.Description);
|
||||
Assert.Contains("yaml", formatOpt.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DriftCommand_HasVerboseFilesOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
|
||||
// Act
|
||||
var verboseFilesOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "verbose-files" || o.Name == "--verbose-files" || o.Aliases.Contains("--verbose-files"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(verboseFilesOpt);
|
||||
Assert.Contains("file changes", verboseFilesOpt.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DriftCommand_HasFailOnBreachOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
|
||||
// Act
|
||||
var failOnBreachOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "fail-on-breach" || o.Name == "--fail-on-breach" || o.Aliases.Contains("--fail-on-breach"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(failOnBreachOpt);
|
||||
Assert.Contains("error code", failOnBreachOpt.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DriftCommand_HasOutputOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
|
||||
// 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 DriftCommand_HasVerboseOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
|
||||
// Act
|
||||
var verboseOpt = command.Options.FirstOrDefault(o =>
|
||||
o.Name == "verbose" || o.Name == "--verbose" || o.Aliases.Contains("--verbose"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(verboseOpt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DriftCommand_AllOptionsAreConfigured()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
var expectedOptions = new[]
|
||||
{
|
||||
"baseline", "format", "verbose-files", "fail-on-breach", "output", "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 now an argument, not an option
|
||||
Assert.Contains("image", actualArgs);
|
||||
foreach (var expected in expectedOptions)
|
||||
{
|
||||
Assert.Contains(expected, actualOptionNames);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DriftCommand_ImageArgument_HasCorrectDescription()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
var imageArg = command.Arguments.First(a => a.Name == "image");
|
||||
|
||||
// Assert
|
||||
Assert.Contains("Image", imageArg.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DriftCommand_BaselineOption_HasCorrectAliases()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
var baselineOpt = command.Options.First(o =>
|
||||
o.Name == "baseline" || o.Name == "--baseline" || o.Aliases.Contains("--baseline"));
|
||||
|
||||
// Assert
|
||||
Assert.True(baselineOpt.Aliases.Contains("--baseline") || baselineOpt.Aliases.Contains("-b"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DriftCommand_OutputOption_HasCorrectAliases()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
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 DriftCommand_FormatOption_SupportsAllFormats()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
var formatOpt = command.Options.First(o =>
|
||||
o.Name == "format" || o.Name == "--format" || o.Aliases.Contains("--format"));
|
||||
|
||||
// Assert - verify description mentions all supported formats
|
||||
Assert.Contains("table", formatOpt.Description);
|
||||
Assert.Contains("json", formatOpt.Description);
|
||||
Assert.Contains("yaml", formatOpt.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DriftCommand_FailOnBreachOption_ExplainsBehavior()
|
||||
{
|
||||
// Arrange
|
||||
var command = BuildDriftCommand();
|
||||
var failOnBreachOpt = command.Options.First(o =>
|
||||
o.Name == "fail-on-breach" || o.Name == "--fail-on-breach" || o.Aliases.Contains("--fail-on-breach"));
|
||||
|
||||
// Assert
|
||||
Assert.Contains("quota", failOnBreachOpt.Description);
|
||||
}
|
||||
|
||||
private static Command BuildDriftCommand()
|
||||
{
|
||||
var mockServices = new Mock<IServiceProvider>();
|
||||
var verboseOption = new Option<bool>("--verbose");
|
||||
return DriftCommandGroup.BuildDriftCommand(
|
||||
mockServices.Object,
|
||||
verboseOption,
|
||||
CancellationToken.None);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user