using System; using System.Text.Json; using Json.Schema; using Microsoft.Extensions.Logging.Abstractions; using StellaOps.Feedser.Source.Common.Json; namespace StellaOps.Feedser.Source.Common.Tests.Json; public sealed class JsonSchemaValidatorTests { private static JsonSchema CreateSchema() => JsonSchema.FromText(""" { "type": "object", "properties": { "id": { "type": "string" }, "count": { "type": "integer", "minimum": 1 } }, "required": ["id", "count"], "additionalProperties": false } """); [Fact] public void Validate_AllowsDocumentsMatchingSchema() { var schema = CreateSchema(); using var document = JsonDocument.Parse("""{"id":"abc","count":2}"""); var validator = new JsonSchemaValidator(NullLogger.Instance); var exception = Record.Exception(() => validator.Validate(document, schema, "valid-doc")); Assert.Null(exception); } [Fact] public void Validate_ThrowsWithDetailedViolations() { var schema = CreateSchema(); using var document = JsonDocument.Parse("""{"count":0,"extra":"nope"}"""); var validator = new JsonSchemaValidator(NullLogger.Instance); var ex = Assert.Throws(() => validator.Validate(document, schema, "invalid-doc")); Assert.Equal("invalid-doc", ex.DocumentName); Assert.NotEmpty(ex.Errors); Assert.Contains(ex.Errors, error => error.Keyword == "required"); Assert.Contains(ex.Errors, error => error.SchemaLocation.Contains("#/additionalProperties", StringComparison.Ordinal)); Assert.Contains(ex.Errors, error => error.Keyword == "minimum"); } }