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

- 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:
master
2025-12-16 16:40:19 +02:00
parent 415eff1207
commit 2170a58734
206 changed files with 30547 additions and 534 deletions

View File

@@ -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;
}