Skip to content

Commit

Permalink
Add more tests for ref resolution
Browse files Browse the repository at this point in the history
Ensure that the `$id` and retrieval URI handling are both done
correctly. JSON Schema specifies that `$id` has precedence, so one of
the tests confirms that preference.
  • Loading branch information
sirosen committed Aug 3, 2023
1 parent 90f545d commit b785746
Showing 1 changed file with 72 additions and 5 deletions.
77 changes: 72 additions & 5 deletions tests/acceptance/test_remote_ref_resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,8 @@
}


@pytest.mark.parametrize("check_passes", (True, False))
@pytest.mark.parametrize("casename", ("case1", "case2"))
def test_remote_ref_resolution_simple_case(
run_line, check_passes, casename, tmp_path, monkeypatch
):
@pytest.fixture(autouse=True)
def _mock_schema_cache_dir(monkeypatch, tmp_path):
def _fake_compute_default_cache_dir(self):
return str(tmp_path)

Expand All @@ -51,6 +48,10 @@ def _fake_compute_default_cache_dir(self):
_fake_compute_default_cache_dir,
)


@pytest.mark.parametrize("check_passes", (True, False))
@pytest.mark.parametrize("casename", ("case1", "case2"))
def test_remote_ref_resolution_simple_case(run_line, check_passes, casename, tmp_path):
main_schema_loc = "https://example.com/main.json"
responses.add("GET", main_schema_loc, json=CASES[casename]["main_schema"])
for name, subschema in CASES[casename]["other_schemas"].items():
Expand All @@ -74,3 +75,69 @@ def _fake_compute_default_cache_dir(self):
assert result.exit_code == 0, output
else:
assert result.exit_code == 1, output


# this test ensures that `$id` is preferred for the base URI over
# the retrieval URI
@pytest.mark.parametrize("check_passes", (True, False))
def test_ref_resolution_prefers_id_over_retrieval_uri(run_line, tmp_path, check_passes):
main_schema = {
"$id": "https://example.org/schemas/main.json",
"$schema": "http://json-schema.org/draft-07/schema",
"properties": {
"title": {"$ref": "./title_schema.json"},
},
"additionalProperties": False,
}
title_schema = {"type": "string"}

retrieval_uri = "https://example.org/alternate-path-retrieval-only/schemas/main"
responses.add("GET", retrieval_uri, json=main_schema)
responses.add(
"GET", "https://example.org/schemas/title_schema.json", json=title_schema
)

instance_path = tmp_path / "instance.json"
instance_path.write_text(json.dumps({"title": "doc one" if check_passes else 2}))

result = run_line(
["check-jsonschema", "--schemafile", retrieval_uri, str(instance_path)]
)
output = f"\nstdout:\n{result.stdout}\n\nstderr:\n{result.stderr}"
if check_passes:
assert result.exit_code == 0, output
else:
assert result.exit_code == 1, output


@pytest.mark.parametrize("check_passes", (True, False))
def test_ref_resolution_does_not_callout_for_absolute_ref_to_retrieval_uri(
run_line, tmp_path, check_passes
):
retrieval_uri = "https://example.net/schemas/main"

main_schema = {
"$id": "https://example.net/schemas/some-uri-which-will-never-be-used/main.json",
"$schema": "http://json-schema.org/draft-07/schema",
"$defs": {"title": {"type": "string"}},
"properties": {
"title": {"$ref": f"{retrieval_uri}#/$defs/title"},
},
"additionalProperties": False,
}

# exactly one GET to the retrieval URI will work
responses.add("GET", retrieval_uri, json=main_schema)
responses.add("GET", retrieval_uri, json={"error": "permafrost melted"}, status=500)

instance_path = tmp_path / "instance.json"
instance_path.write_text(json.dumps({"title": "doc one" if check_passes else 2}))

result = run_line(
["check-jsonschema", "--schemafile", retrieval_uri, str(instance_path)]
)
output = f"\nstdout:\n{result.stdout}\n\nstderr:\n{result.stderr}"
if check_passes:
assert result.exit_code == 0, output
else:
assert result.exit_code == 1, output

0 comments on commit b785746

Please sign in to comment.