Skip to content

Commit

Permalink
Fix remote ref resolution to work in accordance with the official tes…
Browse files Browse the repository at this point in the history
…t suite
  • Loading branch information
jonasschmidt committed May 31, 2019
1 parent c3ee22b commit 45df2be
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 24 deletions.
26 changes: 20 additions & 6 deletions lib/ex_json_schema/schema.ex
Expand Up @@ -96,8 +96,15 @@ defmodule ExJsonSchema.Schema do

defp resolve_with_root(root, schema, scope \\ "")

defp resolve_with_root(root, schema = %{"id" => id}, scope) when is_binary(id),
do: do_resolve(root, schema, scope <> id)
defp resolve_with_root(root, schema = %{"id" => id}, scope) when is_binary(id) do
scope =
case URI.parse(scope) do
%URI{host: nil} -> id
uri -> uri |> URI.merge(id) |> to_string()
end

do_resolve(root, schema, scope)
end

defp resolve_with_root(root, schema = %{}, scope), do: do_resolve(root, schema, scope)
defp resolve_with_root(root, non_schema, _scope), do: {root, non_schema}
Expand Down Expand Up @@ -129,10 +136,17 @@ defmodule ExJsonSchema.Schema do

defp resolve_property(root, {"$ref", ref}, scope) do
scoped_ref =
case ref do
"http://" <> _ -> ref
"https://" <> _ -> ref
_else -> (scope <> ref) |> String.replace("##", "#")
case URI.parse(ref) do
# TODO: this special case is only needed until there is proper support for URL references
# that point to a local schema (via scope changes)
%URI{host: nil, path: nil} = uri ->
to_string(uri)

ref_uri ->
case URI.parse(scope) do
%URI{host: nil} -> ref
scope_uri -> URI.merge(scope_uri, ref_uri) |> to_string()
end
end

{root, path} = resolve_ref!(root, scoped_ref)
Expand Down
12 changes: 0 additions & 12 deletions test/ex_json_schema/schema_test.exs
Expand Up @@ -86,18 +86,6 @@ defmodule ExJsonSchema.SchemaTest do
fn -> resolve(schema) end
end

test "changing the resolution scope" do
schema = %{
"id" => "#/foo_scope/",
"foo" => %{"$ref" => "bar"},
"foo_scope" => %{"bar" => "baz"}
}

resolved = resolve(schema)
path = get_in(resolved.schema, ["foo", "$ref"])
assert get_fragment!(resolved, path) == "baz"
end

test "caching a resolved remote reference" do
schema = %{"$ref" => "http://localhost:1234/integer.json"}

Expand Down
5 changes: 0 additions & 5 deletions test/json_schema_test_suite_test.exs
Expand Up @@ -40,11 +40,6 @@ defmodule ExJsonSchema.JsonSchemaTestSuiteTest do
"ref" => %{
"ref overrides any sibling keywords" => ["ref valid, maxItems ignored"],
"Recursive references between schemas" => ["valid tree", "invalid tree"]
},
"refRemote" => %{
"root ref in remote ref" => ["string is valid", "null is valid", "object is invalid"],
"base URI change - change folder" => ["number is valid", "string is invalid"],
"base URI change - change folder in subschema" => ["number is valid", "string is invalid"]
}
}

Expand Down

0 comments on commit 45df2be

Please sign in to comment.