Add comprehensive security tests for OWASP A02, A05, A07, and A08 categories
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Lighthouse CI / Lighthouse Audit (push) Has been cancelled
Lighthouse CI / Axe Accessibility Audit (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
Manifest Integrity / Validate Schema Integrity (push) Has been cancelled
Lighthouse CI / Lighthouse Audit (push) Has been cancelled
Lighthouse CI / Axe Accessibility Audit (push) Has been cancelled
Manifest Integrity / Validate Contract Documents (push) Has been cancelled
Manifest Integrity / Validate Pack Fixtures (push) Has been cancelled
Manifest Integrity / Audit SHA256SUMS Files (push) Has been cancelled
Manifest Integrity / Verify Merkle Roots (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
- Implemented tests for Cryptographic Failures (A02) to ensure proper handling of sensitive data, secure algorithms, and key management. - Added tests for Security Misconfiguration (A05) to validate production configurations, security headers, CORS settings, and feature management. - Developed tests for Authentication Failures (A07) to enforce strong password policies, rate limiting, session management, and MFA support. - Created tests for Software and Data Integrity Failures (A08) to verify artifact signatures, SBOM integrity, attestation chains, and feed updates.
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// ProofCommandTests.cs
|
||||
// Sprint: SPRINT_0501_0007_0001_proof_chain_cli_integration
|
||||
// Tasks: #10, #11, #12
|
||||
// Description: Unit tests for proof chain CLI commands
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.CommandLine.IO;
|
||||
using System.CommandLine.Parsing;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// Unit tests for proof chain CLI commands.
|
||||
/// </summary>
|
||||
public class ProofCommandTests
|
||||
{
|
||||
private readonly Mock<ILogger<Proof.ProofCommandGroup>> _loggerMock;
|
||||
private readonly Proof.ProofCommandGroup _commandGroup;
|
||||
|
||||
public ProofCommandTests()
|
||||
{
|
||||
_loggerMock = new Mock<ILogger<Proof.ProofCommandGroup>>();
|
||||
_commandGroup = new Proof.ProofCommandGroup(_loggerMock.Object);
|
||||
}
|
||||
|
||||
#region Task #10: Unit Tests for Commands
|
||||
|
||||
[Fact]
|
||||
public void BuildCommand_CreatesProofCommandTree()
|
||||
{
|
||||
// Act
|
||||
var command = _commandGroup.BuildCommand();
|
||||
|
||||
// Assert
|
||||
Assert.Equal("proof", command.Name);
|
||||
Assert.Equal("Proof chain operations", command.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildCommand_HasVerifySubcommand()
|
||||
{
|
||||
// Act
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var verifyCommand = command.Subcommands.FirstOrDefault(c => c.Name == "verify");
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(verifyCommand);
|
||||
Assert.Equal("Verify an artifact's proof chain", verifyCommand.Description);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildCommand_HasSpineSubcommand()
|
||||
{
|
||||
// Act
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var spineCommand = command.Subcommands.FirstOrDefault(c => c.Name == "spine");
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(spineCommand);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VerifyCommand_HasRequiredArtifactArgument()
|
||||
{
|
||||
// Arrange
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var verifyCommand = command.Subcommands.First(c => c.Name == "verify");
|
||||
|
||||
// Act
|
||||
var artifactArg = verifyCommand.Arguments.FirstOrDefault(a => a.Name == "artifact");
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(artifactArg);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VerifyCommand_HasSbomOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var verifyCommand = command.Subcommands.First(c => c.Name == "verify");
|
||||
|
||||
// Act
|
||||
var sbomOption = verifyCommand.Options.FirstOrDefault(o =>
|
||||
o.Aliases.Contains("-s") || o.Aliases.Contains("--sbom"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(sbomOption);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VerifyCommand_HasOfflineOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var verifyCommand = command.Subcommands.First(c => c.Name == "verify");
|
||||
|
||||
// Act
|
||||
var offlineOption = verifyCommand.Options.FirstOrDefault(o =>
|
||||
o.Name == "--offline" || o.Aliases.Contains("--offline"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(offlineOption);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VerifyCommand_HasOutputFormatOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var verifyCommand = command.Subcommands.First(c => c.Name == "verify");
|
||||
|
||||
// Act
|
||||
var outputOption = verifyCommand.Options.FirstOrDefault(o =>
|
||||
o.Name == "--output" || o.Aliases.Contains("--output"));
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(outputOption);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Task #11: Exit Code Verification Tests
|
||||
|
||||
[Theory]
|
||||
[InlineData(0, "Success")]
|
||||
[InlineData(1, "PolicyViolation")]
|
||||
[InlineData(2, "SystemError")]
|
||||
public void ExitCodes_HaveCorrectValues(int expectedCode, string codeName)
|
||||
{
|
||||
// Arrange & Act
|
||||
var actualCode = codeName switch
|
||||
{
|
||||
"Success" => ExitCodes.Success,
|
||||
"PolicyViolation" => ExitCodes.PolicyViolation,
|
||||
"SystemError" => ExitCodes.SystemError,
|
||||
_ => throw new ArgumentException($"Unknown exit code: {codeName}")
|
||||
};
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedCode, actualCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExitCodes_Success_IsZero()
|
||||
{
|
||||
Assert.Equal(0, ExitCodes.Success);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExitCodes_PolicyViolation_IsOne()
|
||||
{
|
||||
Assert.Equal(1, ExitCodes.PolicyViolation);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExitCodes_SystemError_IsTwo()
|
||||
{
|
||||
Assert.Equal(2, ExitCodes.SystemError);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Task #12: CI/CD Integration Tests
|
||||
|
||||
[Fact]
|
||||
public void ProofVerify_ParsesArtifactDigest()
|
||||
{
|
||||
// Arrange
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var root = new RootCommand { command };
|
||||
var parser = new Parser(root);
|
||||
|
||||
// Act
|
||||
var result = parser.Parse("proof verify sha256:abc123def456");
|
||||
|
||||
// Assert
|
||||
Assert.Empty(result.Errors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProofVerify_ParsesWithSbomOption()
|
||||
{
|
||||
// Arrange
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var root = new RootCommand { command };
|
||||
var parser = new Parser(root);
|
||||
|
||||
// Act
|
||||
var result = parser.Parse("proof verify sha256:abc123 --sbom sbom.json");
|
||||
|
||||
// Assert
|
||||
Assert.Empty(result.Errors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProofVerify_ParsesWithJsonOutput()
|
||||
{
|
||||
// Arrange
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var root = new RootCommand { command };
|
||||
var parser = new Parser(root);
|
||||
|
||||
// Act
|
||||
var result = parser.Parse("proof verify sha256:abc123 --output json");
|
||||
|
||||
// Assert
|
||||
Assert.Empty(result.Errors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProofVerify_ParsesWithOfflineMode()
|
||||
{
|
||||
// Arrange
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var root = new RootCommand { command };
|
||||
var parser = new Parser(root);
|
||||
|
||||
// Act
|
||||
var result = parser.Parse("proof verify sha256:abc123 --offline");
|
||||
|
||||
// Assert
|
||||
Assert.Empty(result.Errors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProofVerify_ParsesWithAllOptions()
|
||||
{
|
||||
// Arrange
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var root = new RootCommand { command };
|
||||
var parser = new Parser(root);
|
||||
|
||||
// Act
|
||||
var result = parser.Parse(
|
||||
"proof verify sha256:abc123 --sbom sbom.json --vex vex.json --offline --output json -v");
|
||||
|
||||
// Assert
|
||||
Assert.Empty(result.Errors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ProofVerify_FailsWithoutArtifact()
|
||||
{
|
||||
// Arrange
|
||||
var command = _commandGroup.BuildCommand();
|
||||
var root = new RootCommand { command };
|
||||
var parser = new Parser(root);
|
||||
|
||||
// Act
|
||||
var result = parser.Parse("proof verify");
|
||||
|
||||
// Assert
|
||||
Assert.NotEmpty(result.Errors);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Standard exit codes for CI/CD integration (§15.2).
|
||||
/// </summary>
|
||||
public static class ExitCodes
|
||||
{
|
||||
/// <summary>No policy violations - safe to proceed.</summary>
|
||||
public const int Success = 0;
|
||||
|
||||
/// <summary>Policy violation detected - block deployment.</summary>
|
||||
public const int PolicyViolation = 1;
|
||||
|
||||
/// <summary>System/scanner error - cannot determine status.</summary>
|
||||
public const int SystemError = 2;
|
||||
}
|
||||
Reference in New Issue
Block a user