using System; using System.IO; using System.Threading.Tasks; using StellaOps.Policy; using Xunit; using StellaOps.TestKit; namespace StellaOps.Policy.Tests; public class PolicyValidationCliTests { [Trait("Category", TestCategories.Unit)] [Fact] public async Task RunAsync_EmitsCanonicalDigest_OnValidPolicy() { var tmp = Path.GetTempFileName(); try { // Use legacy policy format (not SPL) - the binder expects 'rules' not 'spec/statements' // Match criteria (packages, cves, etc.) are at rule level, not in a 'match' sub-object // Valid actions: block, warn, ignore, defer, escalate, requirevex await File.WriteAllTextAsync(tmp, """ { "version": "1.0", "metadata": { "name": "demo" }, "rules": [ { "name": "Block Critical", "id": "BLOCK-CRIT", "action": "block", "severity": ["critical"] } ] } """); var options = new PolicyValidationCliOptions { Inputs = new[] { tmp }, OutputJson = true, // Digest is only included in JSON output Strict = false, }; using var output = new StringWriter(); using var error = new StringWriter(); var cli = new PolicyValidationCli(output, error); var exit = await cli.RunAsync(options); Assert.Equal(0, exit); var text = output.ToString(); Assert.Contains("canonical.spl.digest:", text, StringComparison.Ordinal); } finally { File.Delete(tmp); } } }