diff --git a/integration_test/json_test.exs b/integration_test/json_test.exs new file mode 100644 index 0000000..e03fc01 --- /dev/null +++ b/integration_test/json_test.exs @@ -0,0 +1,95 @@ +defmodule Ecto.Integration.JsonTest do + use Ecto.Integration.Case, async: true + + import Ecto.Query + + alias Ecto.Integration.TestRepo + alias Ecto.Integration.Order + + test "json_extract_path with primitive values" do + order = %Order{ + meta: %{ + :id => 123, + :time => ~T[09:00:00], + "code" => "good", + "'single quoted'" => "bar", + "\"double quoted\"" => "baz", + "enabled" => true, + "extra" => [%{"enabled" => false}] + } + } + + order = TestRepo.insert!(order) + + assert TestRepo.one(from(o in Order, select: o.meta["id"])) == 123 + assert TestRepo.one(from(o in Order, select: o.meta["bad"])) == nil + assert TestRepo.one(from(o in Order, select: o.meta["bad"]["bad"])) == nil + + field = "id" + assert TestRepo.one(from(o in Order, select: o.meta[^field])) == 123 + assert TestRepo.one(from(o in Order, select: o.meta["time"])) == "09:00:00" + assert TestRepo.one(from(o in Order, select: o.meta["'single quoted'"])) == "bar" + assert TestRepo.one(from(o in Order, select: o.meta["';"])) == nil + assert TestRepo.one(from(o in Order, select: o.meta["\"double quoted\""])) == "baz" + assert TestRepo.one(from(o in Order, select: o.meta["enabled"])) == 1 + assert TestRepo.one(from(o in Order, select: o.meta["extra"][0]["enabled"])) == 0 + + # where + assert TestRepo.one(from(o in Order, where: o.meta["id"] == 123, select: o.id)) == + order.id + + assert TestRepo.one(from(o in Order, where: o.meta["id"] == 456, select: o.id)) == + nil + + assert TestRepo.one(from(o in Order, where: o.meta["code"] == "good", select: o.id)) == + order.id + + assert TestRepo.one(from(o in Order, where: o.meta["code"] == "bad", select: o.id)) == + nil + + assert TestRepo.one( + from(o in Order, where: o.meta["enabled"] == true, select: o.id) + ) == order.id + + assert TestRepo.one( + from(o in Order, + where: o.meta["extra"][0]["enabled"] == false, + select: o.id + ) + ) == order.id + end + + test "json_extract_path with arrays and objects" do + order = %Order{meta: %{tags: [%{name: "red"}, %{name: "green"}]}} + order = TestRepo.insert!(order) + + assert TestRepo.one(from(o in Order, select: o.meta["tags"][0]["name"])) == "red" + assert TestRepo.one(from(o in Order, select: o.meta["tags"][99]["name"])) == nil + + index = 1 + + assert TestRepo.one(from(o in Order, select: o.meta["tags"][^index]["name"])) == + "green" + + # where + assert TestRepo.one( + from(o in Order, where: o.meta["tags"][0]["name"] == "red", select: o.id) + ) == order.id + + assert TestRepo.one( + from(o in Order, where: o.meta["tags"][0]["name"] == "blue", select: o.id) + ) == nil + + assert TestRepo.one( + from(o in Order, where: o.meta["tags"][99]["name"] == "red", select: o.id) + ) == nil + end + + test "json_extract_path with embeds" do + order = %Order{items: [%{valid_at: ~D[2020-01-01]}]} + TestRepo.insert!(order) + + assert TestRepo.one(from(o in Order, select: o.items[0]["valid_at"])) == + "2020-01-01" + end +end diff --git a/integration_test/test_helper.exs b/integration_test/test_helper.exs index 633fe44..ce93da3 100644 --- a/integration_test/test_helper.exs +++ b/integration_test/test_helper.exs @@ -111,10 +111,9 @@ ExUnit.start( # SQLite3 does not support the concat function :concat, - + # SQLite3 does not support placeholders :placeholders, - - # Fails the regex matching because it uses square brackets outside of the parameter list - :parameter_logging + # SQLite3 stores booleans as integers, causing Ecto's json_extract_path tests to fail + :json_extract_path ] )