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, allOf/$ref composition causes two categories of cascade noise in the structured evaluation output that must be filtered before reporting:
1. falseSchema entries — every `unevaluatedProperties: false` sub-schema emits a
"False schema does not allow …" entry for each value at that path. These are always
redundant with the parent unevaluatedProperties entry.
2. Root-level unevaluatedProperties listing only known model attributes as unexpected —
the validator can't prove top-level fields were "evaluated" through allOf/$ref, so it
reports every legitimate root property as unexpected at root "".
For example, validating a DRO with an unexpected ‘releaseTags` in `administrative` produces one actionable error plus ~12 cascade entries. The de-noiser keeps the actionable error and discards the rest.
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
-
.validator_for(def_name) ⇒ JSONSchema validator
A cached per-definition validator.
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.
47 48 49 50 |
# File 'lib/cocina/models/validators/json_schema_validator.rb', line 47 def initialize(clazz, attributes) @clazz = clazz @attributes = attributes end |
Class Method Details
.document ⇒ Hash
Returns a hash representation of the schema.json document.
38 39 40 41 42 43 |
# File 'lib/cocina/models/validators/json_schema_validator.rb', line 38 def self.document @document ||= begin file_content = ::File.read(SCHEMA_PATH) JSON.parse(file_content) end end |
.validate ⇒ Object
27 28 29 |
# File 'lib/cocina/models/validators/json_schema_validator.rb', line 27 def self.validate(...) new(...).validate end |
.validator_for(def_name) ⇒ JSONSchema validator
Returns a cached per-definition validator.
32 33 34 35 |
# File 'lib/cocina/models/validators/json_schema_validator.rb', line 32 def self.validator_for(def_name) @validators ||= {} @validators[def_name] ||= JSONSchema.validator_for({ '$ref' => "#/$defs/#{def_name}", '$defs' => document['$defs'] }) 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 cascade errors before raising a ValidationError.
Uses the structured evaluation API to capture sub-errors inside anyOf branches, producing actionable messages (e.g. path-qualified minItems/pattern failures) rather than the generic “not valid under anyOf” message.
64 65 66 67 68 69 70 71 |
# File 'lib/cocina/models/validators/json_schema_validator.rb', line 64 def validate attributes['cocinaVersion'] = Cocina::Models::VERSION if clazz.attribute_names.include?(:cocinaVersion) evaluation = self.class.validator_for(method_name).evaluate(attributes.as_json) return if evaluation.valid? raise ValidationError, "When validating #{method_name}: " + (evaluation).join(', ') end |