Class: Cocina::Models::Validators::JsonSchemaValidator
- Inherits:
-
Object
- Object
- Cocina::Models::Validators::JsonSchemaValidator
- Defined in:
- lib/cocina/models/validators/json_schema_validator.rb
Overview
Validates Cocina model instances against the JSON schema.
The schema uses OpenAPI 3.1.0 conventions with ‘unevaluatedProperties: false` to enforce strict validation. However, when schemas use `allOf` with `$ref` (which is common for composing mixins), json_schemer reports cascaded unevaluatedProperties errors that are not actionable.
For example, if a schema has:
AdminPolicy:
allOf:
- $ref: '#/$defs/AdminPolicyMixin' # defines properties
unevaluatedProperties: false
And an unexpected property appears at ‘/administrative/releaseTags`, json_schemer will report both:
- The actual error at `/administrative/releaseTags` (actionable)
- Cascaded errors for every known root property like `/label`, `/type` (noise)
This happens because ‘unevaluatedProperties` semantics with `allOf`/$ref can be ambiguous. See github.com/davishmcclurg/json_schemer/issues/157
To reduce noise while preserving actionable errors, this validator applies de-noising by keeping only:
1. All errors for nested properties (depth > 1)
2. Root-level errors for genuinely unknown properties (not in the model schema)
This filters out cascaded root-level false positives without hiding real nested issues.
Constant Summary collapse
- SCHEMA_PATH =
::File.('../../../../schema.json', __dir__)
Class Method Summary collapse
-
.document ⇒ Hash
A hash representation of the schema.json document.
- .validate ⇒ Object
Instance Method Summary collapse
-
#initialize(clazz, attributes) ⇒ JsonSchemaValidator
constructor
A new instance of JsonSchemaValidator.
-
#validate ⇒ NilClass
Validates attributes against the Cocina model schema.
Constructor Details
#initialize(clazz, attributes) ⇒ JsonSchemaValidator
Returns a new instance of JsonSchemaValidator.
52 53 54 55 |
# File 'lib/cocina/models/validators/json_schema_validator.rb', line 52 def initialize(clazz, attributes) @clazz = clazz @attributes = attributes end |
Class Method Details
.document ⇒ Hash
Returns a hash representation of the schema.json document.
43 44 45 46 47 48 |
# File 'lib/cocina/models/validators/json_schema_validator.rb', line 43 def self.document @document ||= begin file_content = ::File.read(SCHEMA_PATH) JSON.parse(file_content) end end |
.validate ⇒ Object
38 39 40 |
# File 'lib/cocina/models/validators/json_schema_validator.rb', line 38 def self.validate(...) new(...).validate end |
Instance Method Details
#validate ⇒ NilClass
Validates attributes against the Cocina model schema.
Injects the cocinaVersion if the model includes it as an attribute, then validates the attributes against the schema definition for this model. De-noises unevaluatedProperties errors before raising a ValidationError.
65 66 67 68 69 70 71 72 |
# File 'lib/cocina/models/validators/json_schema_validator.rb', line 65 def validate attributes['cocinaVersion'] = Cocina::Models::VERSION if clazz.attribute_names.include?(:cocinaVersion) errors = schema.ref("#/$defs/#{method_name}").validate(attributes.as_json).to_a return if errors.empty? raise ValidationError, "When validating #{method_name}: " + (errors).join(', ') end |