using System.Text.Json; using Microsoft.Extensions.Options; using StellaOps.Aoc; using StellaOps.Concelier.Core.Aoc; namespace StellaOps.Concelier.WebService.Tests.Aoc; /// /// Regression tests ensuring AOC verify consistently emits ERR_AOC_001 and maintains /// mapper/guard parity across all violation scenarios. /// Per CONCELIER-WEB-AOC-19-007. /// public sealed class AocVerifyRegressionTests { private static readonly AocGuardOptions GuardOptions = AocGuardOptions.Default; [Fact] public void Verify_ForbiddenField_EmitsErrAoc001() { var guard = new AocWriteGuard(); var json = CreateJsonWithForbiddenField("severity", "high"); var result = guard.Validate(json.RootElement, GuardOptions); Assert.False(result.IsValid); var violation = Assert.Single(result.Violations.Where(v => v.Path == "/severity")); Assert.Equal("ERR_AOC_001", violation.ErrorCode); Assert.Equal(AocViolationCode.ForbiddenField, violation.Code); } [Theory] [InlineData("severity")] [InlineData("cvss")] [InlineData("cvss_vector")] [InlineData("merged_from")] [InlineData("consensus_provider")] [InlineData("reachability")] [InlineData("asset_criticality")] [InlineData("risk_score")] public void Verify_AllForbiddenFields_EmitErrAoc001(string forbiddenField) { var guard = new AocWriteGuard(); var json = CreateJsonWithForbiddenField(forbiddenField, "forbidden_value"); var result = guard.Validate(json.RootElement, GuardOptions); Assert.False(result.IsValid); var violation = result.Violations.FirstOrDefault(v => v.Path == $"/{forbiddenField}"); Assert.NotNull(violation); Assert.Equal("ERR_AOC_001", violation.ErrorCode); Assert.Equal(AocViolationCode.ForbiddenField, violation.Code); } [Fact] public void Verify_DerivedField_EmitsErrAoc006() { var guard = new AocWriteGuard(); var json = CreateJsonWithDerivedField("effective_status", "affected"); var result = guard.Validate(json.RootElement, GuardOptions); Assert.False(result.IsValid); var violation = result.Violations.FirstOrDefault(v => v.Path == "/effective_status" && v.ErrorCode == "ERR_AOC_006"); Assert.NotNull(violation); Assert.Equal(AocViolationCode.DerivedFindingDetected, violation.Code); } [Theory] [InlineData("effective_status")] [InlineData("effective_range")] [InlineData("effective_severity")] [InlineData("effective_cvss")] public void Verify_AllDerivedFields_EmitErrAoc006(string derivedField) { var guard = new AocWriteGuard(); var json = CreateJsonWithDerivedField(derivedField, "derived_value"); var result = guard.Validate(json.RootElement, GuardOptions); Assert.False(result.IsValid); var violation = result.Violations.FirstOrDefault(v => v.Path == $"/{derivedField}" && v.ErrorCode == "ERR_AOC_006"); Assert.NotNull(violation); Assert.Equal(AocViolationCode.DerivedFindingDetected, violation.Code); } [Fact] public void Verify_UnknownField_EmitsErrAoc007() { var guard = new AocWriteGuard(); var json = CreateJsonWithUnknownField("completely_unknown_field", "some_value"); var result = guard.Validate(json.RootElement, GuardOptions); Assert.False(result.IsValid); var violation = Assert.Single(result.Violations.Where(v => v.Path == "/completely_unknown_field" && v.ErrorCode == "ERR_AOC_007")); Assert.Equal(AocViolationCode.UnknownField, violation.Code); } [Fact] public void Verify_MergeAttempt_EmitsErrAoc002() { var guard = new AocWriteGuard(); var json = CreateJsonWithMergedFrom(["obs-1", "obs-2"]); var result = guard.Validate(json.RootElement, GuardOptions); Assert.False(result.IsValid); // merged_from triggers ERR_AOC_001 (forbidden field) var violation = result.Violations.FirstOrDefault(v => v.Path == "/merged_from"); Assert.NotNull(violation); Assert.Equal("ERR_AOC_001", violation.ErrorCode); } [Fact] public void Verify_MultipleViolations_EmitsAllErrorCodes() { var guard = new AocWriteGuard(); var json = CreateJsonWithMultipleViolations(); var result = guard.Validate(json.RootElement, GuardOptions); Assert.False(result.IsValid); // Should have ERR_AOC_001 for forbidden field Assert.Contains(result.Violations, v => v.ErrorCode == "ERR_AOC_001"); // Should have ERR_AOC_006 for derived field Assert.Contains(result.Violations, v => v.ErrorCode == "ERR_AOC_006"); // Should have ERR_AOC_007 for unknown field Assert.Contains(result.Violations, v => v.ErrorCode == "ERR_AOC_007"); } [Fact] public void Verify_ValidDocument_NoViolations() { var guard = new AocWriteGuard(); var json = CreateValidJson(); var result = guard.Validate(json.RootElement, GuardOptions); Assert.True(result.IsValid); Assert.Empty(result.Violations); } [Fact] public void Verify_ErrorCodeConsistency_AcrossMultipleRuns() { var guard = new AocWriteGuard(); var json = CreateJsonWithForbiddenField("severity", "critical"); // Run validation multiple times var results = Enumerable.Range(0, 10) .Select(_ => guard.Validate(json.RootElement, GuardOptions)) .ToList(); // All should produce same error code var allErrorCodes = results .SelectMany(r => r.Violations) .Select(v => v.ErrorCode) .Distinct() .ToList(); Assert.Single(allErrorCodes); Assert.Equal("ERR_AOC_001", allErrorCodes[0]); } [Fact] public void Verify_PathConsistency_AcrossMultipleRuns() { var guard = new AocWriteGuard(); var json = CreateJsonWithForbiddenField("cvss", "9.8"); // Run validation multiple times var results = Enumerable.Range(0, 10) .Select(_ => guard.Validate(json.RootElement, GuardOptions)) .ToList(); // All should produce same path var allPaths = results .SelectMany(r => r.Violations) .Select(v => v.Path) .Distinct() .ToList(); Assert.Single(allPaths); Assert.Equal("/cvss", allPaths[0]); } [Fact] public void Verify_MapperGuardParity_ValidationResultsMatch() { var guard = new AocWriteGuard(); var validator = new AdvisorySchemaValidator(guard, Options.Create(GuardOptions)); // Create document with forbidden field var json = CreateJsonWithForbiddenField("severity", "high"); // Validate with guard directly var guardResult = guard.Validate(json.RootElement, GuardOptions); // Both should detect the violation Assert.False(guardResult.IsValid); Assert.Contains(guardResult.Violations, v => v.ErrorCode == "ERR_AOC_001" && v.Path == "/severity"); } [Fact] public void Verify_ViolationMessage_ContainsMeaningfulDetails() { var guard = new AocWriteGuard(); var json = CreateJsonWithForbiddenField("severity", "high"); var result = guard.Validate(json.RootElement, GuardOptions); var violation = result.Violations.First(v => v.ErrorCode == "ERR_AOC_001"); // Message should not be empty Assert.False(string.IsNullOrWhiteSpace(violation.Message)); // Path should be correct Assert.Equal("/severity", violation.Path); } private static JsonDocument CreateJsonWithForbiddenField(string field, string value) { return JsonDocument.Parse($$""" { "tenant": "test", "{{field}}": "{{value}}", "source": {"vendor": "test", "connector": "test", "version": "1.0"}, "upstream": { "upstream_id": "CVE-2024-0001", "content_hash": "sha256:abc", "retrieved_at": "2024-01-01T00:00:00Z", "signature": {"present": false}, "provenance": {} }, "content": {"format": "OSV", "raw": {}}, "identifiers": {"aliases": [], "primary": "CVE-2024-0001"}, "linkset": {} } """); } private static JsonDocument CreateJsonWithDerivedField(string field, string value) { return JsonDocument.Parse($$""" { "tenant": "test", "{{field}}": "{{value}}", "source": {"vendor": "test", "connector": "test", "version": "1.0"}, "upstream": { "upstream_id": "CVE-2024-0001", "content_hash": "sha256:abc", "retrieved_at": "2024-01-01T00:00:00Z", "signature": {"present": false}, "provenance": {} }, "content": {"format": "OSV", "raw": {}}, "identifiers": {"aliases": [], "primary": "CVE-2024-0001"}, "linkset": {} } """); } private static JsonDocument CreateJsonWithUnknownField(string field, string value) { return JsonDocument.Parse($$""" { "tenant": "test", "{{field}}": "{{value}}", "source": {"vendor": "test", "connector": "test", "version": "1.0"}, "upstream": { "upstream_id": "CVE-2024-0001", "content_hash": "sha256:abc", "retrieved_at": "2024-01-01T00:00:00Z", "signature": {"present": false}, "provenance": {} }, "content": {"format": "OSV", "raw": {}}, "identifiers": {"aliases": [], "primary": "CVE-2024-0001"}, "linkset": {} } """); } private static JsonDocument CreateJsonWithMergedFrom(string[] mergedFrom) { var mergedArray = string.Join(", ", mergedFrom.Select(m => $"\"{m}\"")); return JsonDocument.Parse($$""" { "tenant": "test", "merged_from": [{{mergedArray}}], "source": {"vendor": "test", "connector": "test", "version": "1.0"}, "upstream": { "upstream_id": "CVE-2024-0001", "content_hash": "sha256:abc", "retrieved_at": "2024-01-01T00:00:00Z", "signature": {"present": false}, "provenance": {} }, "content": {"format": "OSV", "raw": {}}, "identifiers": {"aliases": [], "primary": "CVE-2024-0001"}, "linkset": {} } """); } private static JsonDocument CreateJsonWithMultipleViolations() { return JsonDocument.Parse(""" { "tenant": "test", "severity": "high", "effective_status": "affected", "unknown_custom_field": "value", "source": {"vendor": "test", "connector": "test", "version": "1.0"}, "upstream": { "upstream_id": "CVE-2024-0001", "content_hash": "sha256:abc", "retrieved_at": "2024-01-01T00:00:00Z", "signature": {"present": false}, "provenance": {} }, "content": {"format": "OSV", "raw": {}}, "identifiers": {"aliases": [], "primary": "CVE-2024-0001"}, "linkset": {} } """); } private static JsonDocument CreateValidJson() { return JsonDocument.Parse(""" { "tenant": "test", "source": {"vendor": "test", "connector": "test", "version": "1.0"}, "upstream": { "upstream_id": "CVE-2024-0001", "content_hash": "sha256:abc", "retrieved_at": "2024-01-01T00:00:00Z", "signature": {"present": false}, "provenance": {} }, "content": {"format": "OSV", "raw": {}}, "identifiers": {"aliases": [], "primary": "CVE-2024-0001"}, "linkset": {} } """); } }