Add unit tests for remote context (#4)

* Improve RemoteDocTest
* Add unit tests for remote context
* Add unit tests for default document loader
This commit is contained in:
rustra 2020-06-19 01:41:34 +02:00 committed by GitHub
parent ae50884370
commit 140faf4741
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 256 additions and 27 deletions

View File

@ -4,16 +4,9 @@ defmodule JSON.LD.DocumentLoader.Default do
alias JSON.LD.DocumentLoader.RemoteDocument
def load(url, _options) do
with {:ok, res} <-
HTTPoison.get(url, [accept: "application/ld+json"], [follow_redirect: true]),
{:ok, data} <-
Jason.decode(res.body)
do
{:ok, %RemoteDocument{
document: data,
document_url: res.request_url
}}
with {:ok, res} <- HTTPoison.get(url, [accept: "application/ld+json"], follow_redirect: true),
{:ok, data} <- Jason.decode(res.body) do
{:ok, %RemoteDocument{document: data, document_url: res.request_url}}
end
end
end

View File

@ -67,7 +67,8 @@ defmodule JSON.LD.Mixfile do
{:credo, "~> 1.4", only: [:dev, :test], runtime: false},
{:dialyxir, "~> 1.0", only: :dev, runtime: false},
{:ex_doc, "~> 0.22", only: :dev, runtime: false},
{:excoveralls, "~> 0.13", only: :test},
{:bypass, "~> 1.0", only: :test},
{:excoveralls, "~> 0.13", only: :test}
]
end

View File

@ -1,6 +1,9 @@
%{
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"bypass": {:hex, :bypass, "1.0.0", "b78b3dcb832a71aca5259c1a704b2e14b55fd4e1327ff942598b4e7d1a7ad83d", [:mix], [{:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: false]}], "hexpm", "5a1dc855dfcc86160458c7a70d25f65d498bd8012bd4c06a8d3baa368dda3c45"},
"certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"},
"cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"},
"cowlib": {:hex, :cowlib, "2.9.1", "61a6c7c50cf07fdd24b2f45b89500bb93b6686579b069a89f88cb211e1125c78", [:rebar3], [], "hexpm", "e4175dc240a70d996156160891e1c62238ede1729e45740bdd38064dad476170"},
"credo": {:hex, :credo, "1.4.0", "92339d4cbadd1e88b5ee43d427b639b68a11071b6f73854e33638e30a0ea11f5", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1fd3b70dce216574ce3c18bdf510b57e7c4c85c2ec9cad4bff854abaf7e58658"},
"decimal": {:hex, :decimal, "1.8.1", "a4ef3f5f3428bdbc0d35374029ffcf4ede8533536fa79896dd450168d9acdf3c", [:mix], [], "hexpm", "3cb154b00225ac687f6cbd4acc4b7960027c757a5152b369923ead9ddbca7aec"},
"dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"},
@ -15,11 +18,17 @@
"makeup": {:hex, :makeup, "1.0.1", "82f332e461dc6c79dbd82fbe2a9c10d48ed07146f0a478286e590c83c52010b5", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "49736fe5b66a08d8575bf5321d716bac5da20c8e6b97714fec2bcd6febcfa1f8"},
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"nimble_parsec": {:hex, :nimble_parsec, "0.5.3", "def21c10a9ed70ce22754fdeea0810dafd53c2db3219a0cd54cf5526377af1c6", [:mix], [], "hexpm", "589b5af56f4afca65217a1f3eb3fee7e79b09c40c742fddc1c312b3ac0b3399f"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
"plug": {:hex, :plug, "1.10.3", "c9cebe917637d8db0e759039cc106adca069874e1a9034fd6e3fdd427fd3c283", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "01f9037a2a1de1d633b5a881101e6a444bcabb1d386ca1e00bb273a1f1d9d939"},
"plug_cowboy": {:hex, :plug_cowboy, "2.3.0", "149a50e05cb73c12aad6506a371cd75750c0b19a32f81866e1a323dda9e0e99d", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bc595a1870cef13f9c1e03df56d96804db7f702175e4ccacdb8fc75c02a7b97e"},
"plug_crypto": {:hex, :plug_crypto, "1.1.2", "bdd187572cc26dbd95b87136290425f2b580a116d3fb1f564216918c9730d227", [:mix], [], "hexpm", "6b8b608f895b6ffcfad49c37c7883e8df98ae19c6a28113b02aa1e9c5b22d6b5"},
"protocol_ex": {:hex, :protocol_ex, "0.4.3", "4acbe35da85109dc40315c1139bb7a65ebc7fc102d384cd8b3038384fbb9b282", [:mix], [], "hexpm", "6ca5ddb3505c9c86f17cd3f19838b34bf89966ae17078f79f81983b6a4391fe9"},
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
"rdf": {:hex, :rdf, "0.8.0", "9e797e1120d7eb4285874eb3e293493670d3deddcca8315abec9598ca80ae7d4", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:protocol_ex, "~> 0.4", [hex: :protocol_ex, repo: "hexpm", optional: false]}], "hexpm", "d256e7d35d03dd22ae44850c31d5e7eca77563985b8ba7dbf6d639f7ddadd596"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"telemetry": {:hex, :telemetry, "0.4.1", "ae2718484892448a24470e6aa341bc847c3277bfb8d4e9289f7474d752c09c7f", [:rebar3], [], "hexpm", "4738382e36a0a9a2b6e25d67c960e40e1a2c95560b9f936d8e29de8cd858480f"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.5.0", "8516502659002cec19e244ebd90d312183064be95025a319a6c7e89f4bccd65b", [:rebar3], [], "hexpm", "d48d002e15f5cc105a696cf2f1bbb3fc72b4b770a184d8420c8db20da2674b38"},
}

View File

@ -9,20 +9,39 @@ defmodule JSON.LD.TestSuite.RemoteDocTest do
test_cases("remote-doc")
|> Enum.each(fn %{"name" => name, "input" => input} = test_case ->
@tag :test_suite
@tag :remote_doc_test_suite
@tag data: test_case
case hd(test_case["@type"]) do
"jld:PositiveEvaluationTest" ->
test "#{input}: #{name}",
%{data: %{"input" => input, "expect" => output} = test_case, base_iri: base_iri} do
assert JSON.LD.expand(j(input), test_case_options(test_case, base_iri)) == j(output)
end
"jld:NegativeEvaluationTest" ->
@tag skip: "TODO: "
test "#{input}: #{name}",
%{data: %{"input" => input, "expect" => output} = test_case, base_iri: base_iri} do
end
end
end)
if input in ~w[
remote-doc-0005-in.jsonld
remote-doc-0006-in.jsonld
remote-doc-0007-in.jsonld
remote-doc-0008-in.jsonld
] do
@tag skip: "TODO: Missed test file"
end
if input in ~w[
remote-doc-0009-in.jsonld
remote-doc-0010-in.json
remote-doc-0011-in.jldt
remote-doc-0012-in.json
] do
@tag skip: "TODO: Context from Link header is unsupported"
end
@tag :test_suite
@tag :remote_doc_test_suite
@tag data: test_case
case hd(test_case["@type"]) do
"jld:PositiveEvaluationTest" ->
test "#{input}: #{name}",
%{data: %{"input" => input, "expect" => output} = test_case, base_iri: base_iri} do
assert JSON.LD.expand(j(input), test_case_options(test_case, base_iri)) == j(output)
end
"jld:NegativeEvaluationTest" ->
@tag skip: "TODO: "
test "#{input}: #{name}",
%{data: %{"input" => input, "expect" => error} = test_case, base_iri: base_iri} do
end
end
end)
end

View File

@ -0,0 +1,23 @@
defmodule JSON.LD.DocumentLoader.Test do
@behaviour JSON.LD.DocumentLoader
alias JSON.LD.DocumentLoader.RemoteDocument
def load(url, _options) do
with {:ok, data} <- load_context(url) do
{:ok, %RemoteDocument{document: data, document_url: url}}
end
end
defp load_context("http://example.com/test-context") do
{:ok,
%{
"@context" => %{
"homepage" => %{"@id" => "http://xmlns.com/foaf/0.1/homepage", "@type" => "@id"},
"name" => "http://xmlns.com/foaf/0.1/name"
}
}}
end
defp load_context(_), do: {:error, :invalid_url}
end

View File

@ -1 +1,2 @@
ExUnit.start()
Application.ensure_all_started(:bypass)

View File

@ -0,0 +1,126 @@
defmodule JSON.LD.DocumentLoader.DefaultTest do
use ExUnit.Case, async: false
setup do
local =
Jason.decode!("""
{
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"homepage": {"@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id"}
},
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/"
}
""")
{:ok, local: local}
end
test "loads remote context (with 200 response code)", %{local: local} do
bypass = Bypass.open()
Bypass.expect(bypass, fn conn ->
assert "GET" == conn.method
assert "/test-context" == conn.request_path
context = %{
"@context" => %{
"homepage" => %{"@id" => "http://xmlns.com/foaf/0.1/homepage", "@type" => "@id"},
"name" => "http://xmlns.com/foaf/0.1/name"
}
}
Plug.Conn.resp(conn, 200, Jason.encode!(context))
end)
remote =
Jason.decode!("""
{
"@context": "http://localhost:#{bypass.port}/test-context",
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/"
}
""")
assert JSON.LD.expand(local) == JSON.LD.expand(remote)
end
test "loads remote context (with 302 response code)", %{local: local} do
bypass1 = Bypass.open(port: 44887)
bypass2 = Bypass.open(port: 44888)
Bypass.expect(bypass1, fn conn ->
assert "GET" == conn.method
assert "/test1-context" == conn.request_path
conn
|> Plug.Conn.put_resp_header("Location", "http://localhost:#{bypass2.port}/test2-context")
|> Plug.Conn.resp(302, "Found")
end)
Bypass.expect(bypass2, fn conn ->
assert "GET" == conn.method
assert "/test2-context" == conn.request_path
context = %{
"@context" => %{
"homepage" => %{"@id" => "http://xmlns.com/foaf/0.1/homepage", "@type" => "@id"},
"name" => "http://xmlns.com/foaf/0.1/name"
}
}
Plug.Conn.resp(conn, 200, Jason.encode!(context))
end)
remote =
Jason.decode!("""
{
"@context": "http://localhost:#{bypass1.port}/test1-context",
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/"
}
""")
assert JSON.LD.expand(local) == JSON.LD.expand(remote)
end
test "loads remote context referring to other remote contexts", %{local: local} do
bypass1 = Bypass.open(port: 44887)
bypass2 = Bypass.open(port: 44888)
Bypass.expect(bypass1, fn conn ->
assert "GET" == conn.method
assert "/test1-context" == conn.request_path
context = %{"@context": "http://localhost:#{bypass2.port}/test2-context"}
Plug.Conn.resp(conn, 200, Jason.encode!(context))
end)
Bypass.expect(bypass2, fn conn ->
assert "GET" == conn.method
assert "/test2-context" == conn.request_path
context = %{
"@context" => %{
"homepage" => %{"@id" => "http://xmlns.com/foaf/0.1/homepage", "@type" => "@id"},
"name" => "http://xmlns.com/foaf/0.1/name"
}
}
Plug.Conn.resp(conn, 200, Jason.encode!(context))
end)
remote =
Jason.decode!("""
{
"@context": "http://localhost:#{bypass1.port}/test1-context",
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/"
}
""")
assert JSON.LD.expand(local) == JSON.LD.expand(remote)
end
end

View File

@ -0,0 +1,57 @@
defmodule JSON.LD.RemoteContextTest do
use ExUnit.Case, async: false
alias JSON.LD.{DocumentLoader, LoadingRemoteContextFailedError, Options}
setup_all do
local =
Jason.decode! """
{
"@context": {
"name": "http://xmlns.com/foaf/0.1/name",
"homepage": {"@id": "http://xmlns.com/foaf/0.1/homepage", "@type": "@id"}
},
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/"
}
"""
remote =
Jason.decode! """
{
"@context": "http://example.com/test-context",
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/"
}
"""
{:ok, local: local, remote: remote}
end
describe "result is the same for identical local and remote contexts" do
test "expanded form of a JSON-LD document", %{local: local, remote: remote} do
assert JSON.LD.expand(local) ==
JSON.LD.expand(remote, %Options{document_loader: DocumentLoader.Test})
end
test "flattened form of a JSON-LD document", %{local: local, remote: remote} do
assert JSON.LD.flatten(local, nil) ==
JSON.LD.flatten(remote, nil, %Options{document_loader: DocumentLoader.Test})
end
end
test "failed loading of remote context" do
remote =
Jason.decode! """
{
"@context": "http://fake.com/fake-context",
"name": "Manu Sporny",
"homepage": "http://manu.sporny.org/"
}
"""
assert_raise LoadingRemoteContextFailedError, fn ->
JSON.LD.flatten(remote, nil, %Options{document_loader: DocumentLoader.Test})
end
end
end