From bfe92e4f72ae363fe1c12c4c3bc1b4b7b6bdedd9 Mon Sep 17 00:00:00 2001 From: Richard Larocque Date: Tue, 29 Jan 2019 14:10:49 -0800 Subject: [PATCH] Expand references of DocuemntStore schemas This is a fix for https://github.com/thoughtbot/json_matchers/issues/92. Calls `expand_references!` on loaded schemas before adding them to the `DocumentStore`. This is intended to fix a bug where complex schemas that include more than one level of cross-file use of `$ref`s are not being validated correctly. This commit includes new test cases that reproduce this issue and show the effectiveness of the proposed fix. The inspiration for this fix comes from a command included in the `json_schema` gem. In that gem, the stand-alone validator command expands references within schemas before adding them to the store. It seems reasonable to do the same here. See https://github.com/brandur/json_schema/blob/20ccb82d7e18140d88ded508edd6c003865c98a0/lib/commands/validate_schema.rb#L92. --- lib/json_matchers/matcher.rb | 4 ++++ spec/factories.rb | 1 + spec/json_matchers/match_json_schema_spec.rb | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/lib/json_matchers/matcher.rb b/lib/json_matchers/matcher.rb index 088c972..325988a 100644 --- a/lib/json_matchers/matcher.rb +++ b/lib/json_matchers/matcher.rb @@ -36,6 +36,10 @@ def build_and_populate_document_store map { |schema_path| Parser.new(schema_path).parse }. each { |schema| document_store.add_schema(schema) } + document_store.to_a.each do |_k, schema| + schema.expand_references!(store: document_store) + end + document_store end end diff --git a/spec/factories.rb b/spec/factories.rb index 21a12e8..829d4f0 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -68,6 +68,7 @@ initialize_with do FakeSchema.new(name, { + "id": "file:/#{name}.json#", "$schema": "https://json-schema.org/draft-04/schema#", "type": "array", "items": { "$ref": "file:/#{items.name}.json#" }, diff --git a/spec/json_matchers/match_json_schema_spec.rb b/spec/json_matchers/match_json_schema_spec.rb index 3f4b6eb..3da3425 100644 --- a/spec/json_matchers/match_json_schema_spec.rb +++ b/spec/json_matchers/match_json_schema_spec.rb @@ -202,6 +202,24 @@ expect(json_as_array).not_to match_json_schema(schema) end + it "validates against a schema that uses nested $refs" do + schema = create(:schema, :referencing_locations, + items: create(:schema, :referencing_locations)) + json = build(:response, :location) + json_as_array = [[json.to_h]] + + expect(json_as_array).to match_json_schema(schema) + end + + it "fails against a schema that uses nested $refs" do + schema = create(:schema, :referencing_locations, + items: create(:schema, :referencing_locations)) + json = build(:response, :invalid_location) + json_as_array = [[json.to_h]] + + expect(json_as_array).not_to match_json_schema(schema) + end + it "validates against a schema referencing with 'definitions'" do schema = create(:schema, :referencing_definitions)