todays product advirories implemented
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// AttestBuildCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_004_CLI_sbom_ingestion (SBI-001)
|
||||
// Description: Unit tests for attest build command
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
using StellaOps.Cli.Commands;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class AttestBuildCommandTests
|
||||
{
|
||||
private readonly Option<bool> _verboseOption = new("--verbose");
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task AttestBuild_Spdx3_OutputContainsVersion()
|
||||
{
|
||||
// Arrange
|
||||
var command = AttestCommandGroup.BuildAttestCommand(_verboseOption, CancellationToken.None);
|
||||
var root = new RootCommand { command };
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("attest build --format spdx3").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.Equal("SPDX-3.0", doc.RootElement.GetProperty("spdxVersion").GetString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// BinaryAnalysisCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_007_CLI_binary_analysis (BAN-002, BAN-003)
|
||||
// Description: Unit tests for binary fingerprint export and diff commands
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using StellaOps.Cli.Commands.Binary;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class BinaryAnalysisCommandTests
|
||||
{
|
||||
private static RootCommand BuildRoot()
|
||||
{
|
||||
var services = new ServiceCollection().BuildServiceProvider();
|
||||
var root = new RootCommand();
|
||||
root.Add(BinaryCommandGroup.BuildBinaryCommand(services, new Option<bool>("--verbose"), CancellationToken.None));
|
||||
return root;
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task BinaryFingerprintExport_JsonOutput_IncludesHashes()
|
||||
{
|
||||
var root = BuildRoot();
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("binary fingerprint export /tmp/app --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.True(doc.RootElement.TryGetProperty("hashes", out _));
|
||||
Assert.True(doc.RootElement.TryGetProperty("functionHashes", out _));
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task BinaryDiff_JsonOutput_IncludesSummary()
|
||||
{
|
||||
var root = BuildRoot();
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("binary diff /tmp/base /tmp/candidate --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.True(doc.RootElement.TryGetProperty("summary", out _));
|
||||
Assert.True(doc.RootElement.TryGetProperty("functionChanges", out _));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// DbConnectorsCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_008_CLI_advisory_sources (ASC-004)
|
||||
// Description: Unit tests for db connectors test command
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using StellaOps.Cli.Commands;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class DbConnectorsCommandTests
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly Option<bool> _verboseOption;
|
||||
|
||||
public DbConnectorsCommandTests()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton(NullLoggerFactory.Instance);
|
||||
_services = services.BuildServiceProvider();
|
||||
_verboseOption = new Option<bool>("--verbose");
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DbConnectorsTest_WithTimeout_ReportsFailure()
|
||||
{
|
||||
// Arrange
|
||||
var command = DbCommandGroup.BuildDbCommand(_services, _verboseOption, CancellationToken.None);
|
||||
var root = new RootCommand { command };
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("db connectors test nvd --timeout 00:00:00.001 --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
var rootElement = doc.RootElement;
|
||||
Assert.False(rootElement.GetProperty("passed").GetBoolean());
|
||||
Assert.NotNull(rootElement.GetProperty("errorDetails").GetString());
|
||||
Assert.Equal("CON_TIMEOUT_001", rootElement.GetProperty("reasonCode").GetString());
|
||||
Assert.NotNull(rootElement.GetProperty("remediationHint").GetString());
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task DbConnectorsTest_WithSufficientTimeout_ReturnsSuccess()
|
||||
{
|
||||
// Arrange
|
||||
var command = DbCommandGroup.BuildDbCommand(_services, _verboseOption, CancellationToken.None);
|
||||
var root = new RootCommand { command };
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("db connectors test nvd --timeout 00:00:02 --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
var rootElement = doc.RootElement;
|
||||
Assert.True(rootElement.GetProperty("passed").GetBoolean());
|
||||
Assert.True(rootElement.GetProperty("latencyMs").GetInt32() > 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// GraphLineageCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_004_CLI_sbom_ingestion (SBI-006)
|
||||
// Description: Unit tests for graph lineage show command
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Cli.Commands;
|
||||
using StellaOps.Cli.Configuration;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class GraphLineageCommandTests
|
||||
{
|
||||
private static RootCommand BuildRoot()
|
||||
{
|
||||
using var loggerFactory = LoggerFactory.Create(builder => builder.SetMinimumLevel(LogLevel.None));
|
||||
var services = new ServiceCollection().BuildServiceProvider();
|
||||
return CommandFactory.Create(services, new StellaOpsCliOptions(), CancellationToken.None, loggerFactory);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task GraphLineageShow_JsonOutput_IncludesTarget()
|
||||
{
|
||||
// Arrange
|
||||
var root = BuildRoot();
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("graph lineage show sha256:abc --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.Equal("sha256:abc", doc.RootElement.GetProperty("target").GetString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// IssuerKeysCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_009_CLI_vex_processing (VPR-004)
|
||||
// Description: Unit tests for issuer keys commands
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Cli.Commands;
|
||||
using StellaOps.Cli.Configuration;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class IssuerKeysCommandTests
|
||||
{
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task IssuerKeysList_ReturnsKeys()
|
||||
{
|
||||
using var loggerFactory = LoggerFactory.Create(builder => builder.SetMinimumLevel(LogLevel.None));
|
||||
var services = new ServiceCollection().BuildServiceProvider();
|
||||
var root = CommandFactory.Create(services, new StellaOpsCliOptions(), CancellationToken.None, loggerFactory);
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("issuer keys list --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.True(doc.RootElement.GetArrayLength() > 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// PolicyCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_010_CLI_policy_engine (PEN-001, PEN-002, PEN-003)
|
||||
// Description: Unit tests for policy lattice, verdict export, and promote commands
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Cli.Commands;
|
||||
using StellaOps.Cli.Configuration;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class PolicyCommandTests
|
||||
{
|
||||
private static RootCommand BuildRoot()
|
||||
{
|
||||
using var loggerFactory = LoggerFactory.Create(builder => builder.SetMinimumLevel(LogLevel.None));
|
||||
var services = new ServiceCollection().BuildServiceProvider();
|
||||
return CommandFactory.Create(services, new StellaOpsCliOptions(), CancellationToken.None, loggerFactory);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task PolicyLatticeExplain_JsonOutput_IncludesEvaluationOrder()
|
||||
{
|
||||
// Arrange
|
||||
var root = BuildRoot();
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("policy lattice explain --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
var evaluationOrder = doc.RootElement.GetProperty("evaluationOrder");
|
||||
Assert.True(evaluationOrder.GetArrayLength() > 0);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task PolicyVerdictsExport_FilteredOutcome_ReturnsSingleItem()
|
||||
{
|
||||
// Arrange
|
||||
var root = BuildRoot();
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("policy verdicts export --format json --outcome fail").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
var count = doc.RootElement.GetProperty("count").GetInt32();
|
||||
Assert.Equal(1, count);
|
||||
var item = doc.RootElement.GetProperty("items")[0];
|
||||
Assert.Equal("fail", item.GetProperty("outcome").GetString());
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task PolicyPromote_DryRun_JsonOutput()
|
||||
{
|
||||
// Arrange
|
||||
var root = BuildRoot();
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("policy promote P-7 --from dev --to stage --dry-run --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.True(doc.RootElement.GetProperty("dryRun").GetBoolean());
|
||||
Assert.Equal("dev", doc.RootElement.GetProperty("from").GetString());
|
||||
Assert.Equal("stage", doc.RootElement.GetProperty("to").GetString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// ReachabilityCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_006_CLI_reachability_analysis (RCA-003, RCA-004, RCA-007)
|
||||
// Description: Unit tests for reachability explain/witness/guards commands
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using StellaOps.Cli.Commands;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class ReachabilityCommandTests
|
||||
{
|
||||
private static RootCommand BuildReachabilityRoot()
|
||||
{
|
||||
var services = new ServiceCollection().BuildServiceProvider();
|
||||
var root = new RootCommand();
|
||||
root.Add(ReachabilityCommandGroup.BuildReachabilityCommand(services, new Option<bool>("--verbose"), CancellationToken.None));
|
||||
return root;
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ReachabilityExplain_JsonOutput_IncludesConfidence()
|
||||
{
|
||||
var root = BuildReachabilityRoot();
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("reachability explain sha256:abc --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.Equal("sha256:abc", doc.RootElement.GetProperty("digest").GetString());
|
||||
Assert.True(doc.RootElement.GetProperty("confidenceScore").GetInt32() > 0);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ReachabilityWitness_JsonOutput_IncludesPath()
|
||||
{
|
||||
var root = BuildReachabilityRoot();
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("reachability witness sha256:abc --vuln CVE-2024-1234 --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.Equal("CVE-2024-1234", doc.RootElement.GetProperty("cve").GetString());
|
||||
Assert.True(doc.RootElement.GetProperty("path").GetArrayLength() > 0);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ReachabilityGuards_CveFilter_ReturnsFilteredList()
|
||||
{
|
||||
var root = BuildReachabilityRoot();
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("reachability guards sha256:abc --cve CVE-2024-1234 --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.Equal(2, doc.RootElement.GetArrayLength());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// SarifExportCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_005_CLI_scanning_detection (SCD-003)
|
||||
// Description: Unit tests for SARIF export metadata injection
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using StellaOps.Cli.Commands;
|
||||
using StellaOps.Cli.Services;
|
||||
using StellaOps.Cli.Telemetry;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class SarifExportCommandTests
|
||||
{
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ScanSarifExport_IncludesMetadataProperties()
|
||||
{
|
||||
// Arrange
|
||||
var sarifJson = """
|
||||
{
|
||||
"version": "2.1.0",
|
||||
"runs": [
|
||||
{
|
||||
"tool": {
|
||||
"driver": { "name": "stella" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
var client = new Mock<IBackendOperationsClient>();
|
||||
client
|
||||
.Setup(c => c.GetScanSarifAsync(
|
||||
It.IsAny<string>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<bool>(),
|
||||
It.IsAny<string?>(),
|
||||
It.IsAny<CancellationToken>()))
|
||||
.ReturnsAsync(sarifJson);
|
||||
|
||||
using var loggerFactory = LoggerFactory.Create(builder => builder.SetMinimumLevel(LogLevel.None));
|
||||
var services = new ServiceCollection()
|
||||
.AddSingleton(client.Object)
|
||||
.AddSingleton<ILoggerFactory>(loggerFactory)
|
||||
.AddSingleton(new VerbosityState())
|
||||
.BuildServiceProvider();
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
await CommandHandlers.HandleScanSarifExportAsync(
|
||||
services,
|
||||
"scan-123",
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
false,
|
||||
CancellationToken.None);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
var properties = doc.RootElement.GetProperty("runs")[0].GetProperty("properties");
|
||||
Assert.Equal("scan-123", properties.GetProperty("digest").GetString());
|
||||
Assert.True(properties.TryGetProperty("scanTimestamp", out _));
|
||||
Assert.True(properties.TryGetProperty("policyProfileId", out _));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// ScanWorkersOptionTests.cs
|
||||
// Sprint: SPRINT_20260117_005_CLI_scanning_detection (SCD-005)
|
||||
// Description: Unit tests for scan run --workers option
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Cli.Commands;
|
||||
using StellaOps.Cli.Configuration;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class ScanWorkersOptionTests
|
||||
{
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void ScanRun_ParsesWorkersOption()
|
||||
{
|
||||
using var loggerFactory = LoggerFactory.Create(builder => builder.SetMinimumLevel(LogLevel.None));
|
||||
var services = new ServiceCollection().BuildServiceProvider();
|
||||
var root = CommandFactory.Create(services, new StellaOpsCliOptions(), CancellationToken.None, loggerFactory);
|
||||
|
||||
var scanCommand = Assert.Single(root.Subcommands, c => c.Name == "scan");
|
||||
var runCommand = Assert.Single(scanCommand.Subcommands, c => c.Name == "run");
|
||||
var workersOption = runCommand.Options.FirstOrDefault(o => o.Name == "workers") as Option<int?>;
|
||||
Assert.NotNull(workersOption);
|
||||
|
||||
var result = root.Parse("scan run --entry scanner --target . --workers 4");
|
||||
Assert.Equal(4, result.GetValueForOption(workersOption!));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// ScannerWorkersCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_005_CLI_scanning_detection (SCD-004)
|
||||
// Description: Unit tests for scanner workers get/set
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Cli.Commands;
|
||||
using StellaOps.Cli.Configuration;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class ScannerWorkersCommandTests
|
||||
{
|
||||
private static RootCommand BuildRoot()
|
||||
{
|
||||
using var loggerFactory = LoggerFactory.Create(builder => builder.SetMinimumLevel(LogLevel.None));
|
||||
var services = new ServiceCollection().BuildServiceProvider();
|
||||
return CommandFactory.Create(services, new StellaOpsCliOptions(), CancellationToken.None, loggerFactory);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task ScannerWorkers_SetThenGet_ReturnsPersistedConfig()
|
||||
{
|
||||
var tempDir = Path.Combine(Path.GetTempPath(), "stellaops-workers-tests", Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(tempDir);
|
||||
var configPath = Path.Combine(tempDir, "scanner-workers.json");
|
||||
|
||||
var originalEnv = Environment.GetEnvironmentVariable("STELLAOPS_CLI_WORKERS_CONFIG");
|
||||
Environment.SetEnvironmentVariable("STELLAOPS_CLI_WORKERS_CONFIG", configPath);
|
||||
|
||||
try
|
||||
{
|
||||
var root = BuildRoot();
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("scanner workers set --count 4 --pool fast --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var setDoc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.Equal(4, setDoc.RootElement.GetProperty("count").GetInt32());
|
||||
|
||||
writer = new StringWriter();
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("scanner workers get --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var getDoc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.Equal(4, getDoc.RootElement.GetProperty("count").GetInt32());
|
||||
Assert.Equal("fast", getDoc.RootElement.GetProperty("pool").GetString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
Environment.SetEnvironmentVariable("STELLAOPS_CLI_WORKERS_CONFIG", originalEnv);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// SignalsCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_006_CLI_reachability_analysis (RCA-006, RCA-007)
|
||||
// Description: Unit tests for signals inspect command
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using StellaOps.Cli.Commands;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class SignalsCommandTests
|
||||
{
|
||||
private static RootCommand BuildSignalsRoot()
|
||||
{
|
||||
var services = new ServiceCollection().BuildServiceProvider();
|
||||
var root = new RootCommand();
|
||||
root.Add(SignalsCommandGroup.BuildSignalsCommand(services, new Option<bool>("--verbose"), CancellationToken.None));
|
||||
return root;
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task SignalsInspect_JsonOutput_ReturnsSignals()
|
||||
{
|
||||
var root = BuildSignalsRoot();
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("signals inspect sha256:abc --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.True(doc.RootElement.GetArrayLength() > 0);
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,14 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using Moq.Protected;
|
||||
using Xunit;
|
||||
using StellaOps.Cli.Commands;
|
||||
using StellaOps.Cli.Commands.Proof;
|
||||
@@ -80,6 +84,17 @@ public class Sprint3500_0004_0001_CommandTests
|
||||
Assert.NotNull(verifyCommand);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ScoreCommand_HasExplainSubcommand()
|
||||
{
|
||||
// Act
|
||||
var command = ScoreReplayCommandGroup.BuildScoreCommand(_services, _verboseOption, _cancellationToken);
|
||||
var explainCommand = command.Subcommands.FirstOrDefault(c => c.Name == "explain");
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(explainCommand);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ScoreReplay_ParsesWithScanOption()
|
||||
{
|
||||
@@ -122,6 +137,58 @@ public class Sprint3500_0004_0001_CommandTests
|
||||
Assert.NotEmpty(result.Errors);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ScoreExplain_OutputsDeterministicJson_WhenApiUnavailable()
|
||||
{
|
||||
// Arrange
|
||||
var handlerMock = new Mock<HttpMessageHandler>();
|
||||
handlerMock
|
||||
.Protected()
|
||||
.Setup<Task<HttpResponseMessage>>(
|
||||
"SendAsync",
|
||||
ItExpr.IsAny<HttpRequestMessage>(),
|
||||
ItExpr.IsAny<CancellationToken>())
|
||||
.ReturnsAsync(new HttpResponseMessage(HttpStatusCode.InternalServerError));
|
||||
|
||||
var httpClient = new HttpClient(handlerMock.Object);
|
||||
var httpClientFactory = new Mock<IHttpClientFactory>();
|
||||
httpClientFactory
|
||||
.Setup(factory => factory.CreateClient("Scanner"))
|
||||
.Returns(httpClient);
|
||||
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton(httpClientFactory.Object);
|
||||
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
|
||||
var provider = services.BuildServiceProvider();
|
||||
|
||||
var command = ScoreReplayCommandGroup.BuildScoreCommand(provider, _verboseOption, _cancellationToken);
|
||||
var root = new RootCommand { command };
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("score explain sha256:abc --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
var output = writer.ToString();
|
||||
using var doc = JsonDocument.Parse(output);
|
||||
var rootElement = doc.RootElement;
|
||||
|
||||
Assert.Equal("sha256:abc", rootElement.GetProperty("digest").GetString());
|
||||
Assert.Equal(7.5, rootElement.GetProperty("finalScore").GetDouble());
|
||||
Assert.Equal(8.1, rootElement.GetProperty("scoreBreakdown").GetProperty("cvssScore").GetDouble());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UnknownsCommandGroup Tests
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// VexEvidenceExportCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_009_CLI_vex_processing (VPR-002)
|
||||
// Description: Unit tests for VEX evidence export command
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using StellaOps.Cli.Configuration;
|
||||
using StellaOps.Cli.Plugins.Vex;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class VexEvidenceExportCommandTests
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly StellaOpsCliOptions _options;
|
||||
private readonly Option<bool> _verboseOption;
|
||||
|
||||
public VexEvidenceExportCommandTests()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton(NullLoggerFactory.Instance);
|
||||
_services = services.BuildServiceProvider();
|
||||
_options = new StellaOpsCliOptions();
|
||||
_verboseOption = new Option<bool>("--verbose");
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task VexEvidenceExport_JsonOutput_IncludesTarget()
|
||||
{
|
||||
// Arrange
|
||||
var root = new RootCommand();
|
||||
var module = new VexCliCommandModule();
|
||||
module.RegisterCommands(root, _services, _options, _verboseOption, CancellationToken.None);
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("vex evidence export sha256:abc --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.Equal("sha256:abc", doc.RootElement.GetProperty("target").GetString());
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task VexEvidenceExport_OpenVexOutput_HasContext()
|
||||
{
|
||||
// Arrange
|
||||
var root = new RootCommand();
|
||||
var module = new VexCliCommandModule();
|
||||
module.RegisterCommands(root, _services, _options, _verboseOption, CancellationToken.None);
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("vex evidence export pkg:npm/lodash@4.17.21 --format openvex").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.Equal("https://openvex.dev/ns", doc.RootElement.GetProperty("@context").GetString());
|
||||
Assert.True(doc.RootElement.TryGetProperty("statements", out _));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// VexVerifyCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_009_CLI_vex_processing (VPR-001)
|
||||
// Task: VPR-001 - Add stella vex verify command
|
||||
// Description: Unit tests for VEX verify command
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using StellaOps.Cli.Configuration;
|
||||
using StellaOps.Cli.Plugins.Vex;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class VexVerifyCommandTests
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly StellaOpsCliOptions _options;
|
||||
private readonly Option<bool> _verboseOption;
|
||||
|
||||
public VexVerifyCommandTests()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton(NullLoggerFactory.Instance);
|
||||
_services = services.BuildServiceProvider();
|
||||
_options = new StellaOpsCliOptions();
|
||||
_verboseOption = new Option<bool>("--verbose");
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public void VexCommand_RegistersVerifySubcommand()
|
||||
{
|
||||
// Arrange
|
||||
var root = new RootCommand();
|
||||
var module = new VexCliCommandModule();
|
||||
|
||||
// Act
|
||||
module.RegisterCommands(root, _services, _options, _verboseOption, CancellationToken.None);
|
||||
var vexCommand = root.Children.OfType<Command>().FirstOrDefault(c => c.Name == "vex");
|
||||
var verifyCommand = vexCommand?.Subcommands.FirstOrDefault(c => c.Name == "verify");
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(vexCommand);
|
||||
Assert.NotNull(verifyCommand);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task VexVerify_ValidOpenVex_ReturnsSuccessJson()
|
||||
{
|
||||
// Arrange
|
||||
var root = new RootCommand();
|
||||
var module = new VexCliCommandModule();
|
||||
module.RegisterCommands(root, _services, _options, _verboseOption, CancellationToken.None);
|
||||
|
||||
var tempDir = Path.Combine(Path.GetTempPath(), "stellaops-vex-tests", Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(tempDir);
|
||||
var vexPath = Path.Combine(tempDir, "valid.openvex.json");
|
||||
|
||||
var vexJson = """
|
||||
{
|
||||
"@context": "https://openvex.dev/ns",
|
||||
"@id": "https://stellaops.dev/vex/example-1",
|
||||
"author": "stellaops",
|
||||
"timestamp": "2026-01-16T00:00:00Z",
|
||||
"statements": [
|
||||
{
|
||||
"vulnerability": { "name": "CVE-2025-0001" },
|
||||
"status": "not_affected",
|
||||
"products": ["pkg:oci/example@sha256:abc"]
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
await File.WriteAllTextAsync(vexPath, vexJson);
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse($"vex verify \"{vexPath}\" --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
var rootElement = doc.RootElement;
|
||||
Assert.True(rootElement.GetProperty("valid").GetBoolean());
|
||||
Assert.Equal("OpenVEX", rootElement.GetProperty("detectedFormat").GetString());
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task VexVerify_StrictModeWithoutSignature_Fails()
|
||||
{
|
||||
// Arrange
|
||||
var root = new RootCommand();
|
||||
var module = new VexCliCommandModule();
|
||||
module.RegisterCommands(root, _services, _options, _verboseOption, CancellationToken.None);
|
||||
|
||||
var tempDir = Path.Combine(Path.GetTempPath(), "stellaops-vex-tests", Guid.NewGuid().ToString("N"));
|
||||
Directory.CreateDirectory(tempDir);
|
||||
var vexPath = Path.Combine(tempDir, "valid.openvex.json");
|
||||
|
||||
var vexJson = """
|
||||
{
|
||||
"@context": "https://openvex.dev/ns",
|
||||
"@id": "https://stellaops.dev/vex/example-2",
|
||||
"author": "stellaops",
|
||||
"timestamp": "2026-01-16T00:00:00Z",
|
||||
"statements": [
|
||||
{
|
||||
"vulnerability": { "name": "CVE-2025-0002" },
|
||||
"status": "not_affected",
|
||||
"products": ["pkg:oci/example@sha256:def"]
|
||||
}
|
||||
]
|
||||
}
|
||||
""";
|
||||
|
||||
await File.WriteAllTextAsync(vexPath, vexJson);
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse($"vex verify \"{vexPath}\" --strict --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
var rootElement = doc.RootElement;
|
||||
Assert.False(rootElement.GetProperty("valid").GetBoolean());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// VexWebhooksCommandTests.cs
|
||||
// Sprint: SPRINT_20260117_009_CLI_vex_processing (VPR-003)
|
||||
// Description: Unit tests for VEX webhooks commands
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
using System.CommandLine;
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using StellaOps.Cli.Configuration;
|
||||
using StellaOps.Cli.Plugins.Vex;
|
||||
using StellaOps.TestKit;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Cli.Tests.Commands;
|
||||
|
||||
public sealed class VexWebhooksCommandTests
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly StellaOpsCliOptions _options;
|
||||
private readonly Option<bool> _verboseOption;
|
||||
|
||||
public VexWebhooksCommandTests()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton(NullLoggerFactory.Instance);
|
||||
_services = services.BuildServiceProvider();
|
||||
_options = new StellaOpsCliOptions();
|
||||
_verboseOption = new Option<bool>("--verbose");
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task VexWebhooksList_JsonOutput_ReturnsEntries()
|
||||
{
|
||||
var root = new RootCommand();
|
||||
var module = new VexCliCommandModule();
|
||||
module.RegisterCommands(root, _services, _options, _verboseOption, CancellationToken.None);
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("vex webhooks list --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.True(doc.RootElement.GetArrayLength() > 0);
|
||||
}
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
[Fact]
|
||||
public async Task VexWebhooksAdd_JsonOutput_ReturnsId()
|
||||
{
|
||||
var root = new RootCommand();
|
||||
var module = new VexCliCommandModule();
|
||||
module.RegisterCommands(root, _services, _options, _verboseOption, CancellationToken.None);
|
||||
|
||||
var writer = new StringWriter();
|
||||
var originalOut = Console.Out;
|
||||
int exitCode;
|
||||
|
||||
try
|
||||
{
|
||||
Console.SetOut(writer);
|
||||
exitCode = await root.Parse("vex webhooks add --url https://hooks.stellaops.dev/vex --events vex.created --format json").InvokeAsync();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Console.SetOut(originalOut);
|
||||
}
|
||||
|
||||
Assert.Equal(0, exitCode);
|
||||
|
||||
using var doc = JsonDocument.Parse(writer.ToString());
|
||||
Assert.True(doc.RootElement.GetProperty("id").GetString()?.StartsWith("wh-") == true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user