diff --git a/.github/workflows/elixir-latest.yml b/.github/workflows/elixir-latest.yml new file mode 100644 index 0000000..939630b --- /dev/null +++ b/.github/workflows/elixir-latest.yml @@ -0,0 +1,37 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Elixir CI (latest) + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + workflow_dispatch: + +permissions: + contents: read + +jobs: + build: + + name: Build and test + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Elixir + id: setup-beam + uses: erlef/setup-beam@e6d7c94229049569db56a7ad5a540c051a010af9 # + with: + elixir-version: '> 0' # [Required] Define the Elixir version + otp-version: '> 0' # [Required] Define the Erlang/OTP version + - name: Unlock dependencies + run: mix deps.unlock --all + - name: Install dependencies + run: mix deps.get + - name: Run tests + run: mix test diff --git a/.github/workflows/elixir-min.yml b/.github/workflows/elixir-min.yml new file mode 100644 index 0000000..8203247 --- /dev/null +++ b/.github/workflows/elixir-min.yml @@ -0,0 +1,40 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Elixir CI (min) + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + workflow_dispatch: + +permissions: + contents: read + +jobs: + build: + + name: Build and test + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Set up Elixir + id: setup-beam + uses: erlef/setup-beam@e6d7c94229049569db56a7ad5a540c051a010af9 # + with: + elixir-version: '1.12' # [Required] Define the Elixir version + otp-version: '24.x' # [Required] Define the Erlang/OTP version + - name: Restore dependencies cache + uses: actions/cache@v5 + with: + path: deps + key: ${{ runner.os }}-mix-${{ steps.setup-beam.outputs.elixir-version }}-${{ hashFiles('**/mix.lock') }} + - name: Install dependencies + run: mix deps.get + - name: Run tests + run: mix test diff --git a/config/config.exs b/config/config.exs index d2d855e..becde76 100644 --- a/config/config.exs +++ b/config/config.exs @@ -1 +1 @@ -use Mix.Config +import Config diff --git a/lib/trot.ex b/lib/trot.ex index 411e566..25ecc42 100644 --- a/lib/trot.ex +++ b/lib/trot.ex @@ -43,10 +43,10 @@ defmodule Trot do |> Enum.reduce([], &decode_pair(&1, &2)) end - defp decode_pair({key, nil}, acc) do - key = String.to_atom(key) - Keyword.put(acc, key, true) - end + # Handle empty assign + defp decode_pair({key, nil}, acc), do: Keyword.put(acc, String.to_atom(key), true) + # Decoder behavior changed in Elixir 1.11 - an empty assign now comes as an empty string instead of nil + defp decode_pair({key, ""}, acc), do: Keyword.put(acc, String.to_atom(key), true) defp decode_pair({key, value}, acc) do key = String.to_atom(key) case Poison.decode(value) do diff --git a/lib/trot/router.ex b/lib/trot/router.ex index 170b5f5..56057e7 100644 --- a/lib/trot/router.ex +++ b/lib/trot/router.ex @@ -47,10 +47,10 @@ defmodule Trot.Router do pass: ["text/*"], json_decoder: Poison, body_reader: {Trot.CacheBodyReader, :read_body, []}], - "Elixir.PlugHeartbeat": [path: Application.get_env(:trot, :heartbeat, "/heartbeat")], + "Elixir.PlugHeartbeat": [path: Application.compile_env(:trot, :heartbeat, "/heartbeat")], ] - pre_routing = Application.get_env(:trot, :pre_routing, default_pre_routing) - post_routing = Application.get_env(:trot, :post_routing, []) + pre_routing = Application.compile_env(:trot, :pre_routing, default_pre_routing) + post_routing = Application.compile_env(:trot, :post_routing, []) @static_root Path.relative_to_cwd("priv/static") @path_root "/" @@ -146,11 +146,11 @@ defmodule Trot.Router do def make_response(conn = %Plug.Conn{}, _conn), do: conn def make_response({:redirect, to}, conn), do: do_redirect(to, conn) def make_response({:badrpc, {:EXIT, {reason, _metadata}}}, conn) do - Logger.warn("Bad RPC error: #{inspect reason}") + Logger.warning("Bad RPC error: #{inspect reason}") make_response({:internal_server_error, inspect(reason)}, conn) end def make_response({:badrpc, reason}, conn) do - Logger.warn("Bad RPC error: #{inspect reason}") + Logger.warning("Bad RPC error: #{inspect reason}") make_response({:internal_server_error, inspect(reason)}, conn) end def make_response(body, conn) when is_binary(body), do: make_response({:ok, body}, conn) diff --git a/mix.exs b/mix.exs index f579f60..9f1562a 100644 --- a/mix.exs +++ b/mix.exs @@ -6,7 +6,7 @@ defmodule Trot.Mixfile do def project do [app: :trot, version: @version, - elixir: "~> 1.6", + elixir: "~> 1.12", deps: deps(), name: "Trot", docs: [main: "readme", @@ -20,7 +20,9 @@ defmodule Trot.Mixfile do end def application do - [applications: [:logger, :plug, :cowboy, :plug_heartbeat, :slime], + [ + # :crypto required by Plug.Crypto, :eex required by Calliope + extra_applications: [:logger, :crypto, :eex], mod: {Trot, []}] end @@ -28,14 +30,13 @@ defmodule Trot.Mixfile do [ {:plug_cowboy, "~> 2.0"}, {:cowboy, "~> 2.5"}, - {:poison, "~> 3.1"}, + {:poison, "~> 6.0"}, {:calliope, "~> 0.4.2"}, - {:plug_heartbeat, "~> 0.2"}, - {:earmark, "~> 1.2", only: :dev}, - {:ex_doc, "~> 0.16", only: :dev, runtime: false}, + {:plug_heartbeat, "~> 1.0"}, + {:ex_doc, "~> 0.33", only: :dev, runtime: false}, {:inch_ex, ">= 0.0.0", only: :docs}, - {:credo, "~> 0.8", only: [:dev, :test]}, - {:slime, "~> 1.1.0"}, + {:credo, "~> 1.7.6", only: [:dev, :test], runtime: false}, + {:slime, "~> 1.3"}, ] end diff --git a/mix.lock b/mix.lock index e5833aa..028bbd1 100644 --- a/mix.lock +++ b/mix.lock @@ -1,23 +1,27 @@ %{ - "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, - "calliope": {:hex, :calliope, "0.4.2", "29d8585331f3c04f95d6e2f7c8367d660cfb6c2dc031bd3d22afb7e7201eb5c6", [:mix], [], "hexpm"}, - "cowboy": {:hex, :cowboy, "2.6.3", "99aa50e94e685557cad82e704457336a453d4abcb77839ad22dbe71f311fcc06", [:rebar3], [{:cowlib, "~> 2.7.3", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, - "cowlib": {:hex, :cowlib, "2.7.3", "a7ffcd0917e6d50b4d5fb28e9e2085a0ceb3c97dea310505f7460ff5ed764ce9", [:rebar3], [], "hexpm"}, - "credo": {:hex, :credo, "0.10.2", "03ad3a1eff79a16664ed42fc2975b5e5d0ce243d69318060c626c34720a49512", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, - "earmark": {:hex, :earmark, "1.4.0", "397e750b879df18198afc66505ca87ecf6a96645545585899f6185178433cc09", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, - "inch_ex": {:hex, :inch_ex, "2.0.0", "24268a9284a1751f2ceda569cd978e1fa394c977c45c331bb52a405de544f4de", [:mix], [{:bunt, "~> 0.2", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, - "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, - "makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, - "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, - "neotoma": {:hex, :neotoma, "1.7.3", "d8bd5404b73273989946e4f4f6d529e5c2088f5fa1ca790b4dbe81f4be408e61", [:rebar], [], "hexpm"}, - "nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm"}, - "plug": {:hex, :plug, "1.8.3", "12d5f9796dc72e8ac9614e94bda5e51c4c028d0d428e9297650d09e15a684478", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.1.0", "b75768153c3a8a9e8039d4b25bb9b14efbc58e9c4a6e6a270abff1cd30cbe320", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, - "plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"}, - "plug_heartbeat": {:hex, :plug_heartbeat, "0.2.0", "912485e20cf483da21d6dfd4f6ed0dcc8d497f497b123231a73a326239b3f2f1", [:mix], [{:cowboy, ">= 1.0.0", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, ">= 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, - "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"}, - "slime": {:hex, :slime, "1.1.0", "7069adbb52817c2191af9c756ec44510c02eb75975f4e4a12184f3f8e4007296", [:mix], [{:neotoma, "~> 1.7", [hex: :neotoma, repo: "hexpm", optional: false]}], "hexpm"}, + "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, + "calliope": {:hex, :calliope, "0.4.2", "29d8585331f3c04f95d6e2f7c8367d660cfb6c2dc031bd3d22afb7e7201eb5c6", [:mix], [], "hexpm", "3e355b0057ce52e402172e3f37f739765450b9c7ec18bf84c56c12007363283c"}, + "cowboy": {:hex, :cowboy, "2.14.2", "4008be1df6ade45e4f2a4e9e2d22b36d0b5aba4e20b0a0d7049e28d124e34847", [:make, :rebar3], [{:cowlib, ">= 2.16.0 and < 3.0.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, ">= 1.8.0 and < 3.0.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "569081da046e7b41b5df36aa359be71a0c8874e5b9cff6f747073fc57baf1ab9"}, + "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, + "cowlib": {:hex, :cowlib, "2.16.0", "54592074ebbbb92ee4746c8a8846e5605052f29309d3a873468d76cdf932076f", [:make, :rebar3], [], "hexpm", "7f478d80d66b747344f0ea7708c187645cfcc08b11aa424632f78e25bf05db51"}, + "credo": {:hex, :credo, "1.7.6", "b8f14011a5443f2839b04def0b252300842ce7388f3af177157c86da18dfbeea", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "146f347fb9f8cbc5f7e39e3f22f70acbef51d441baa6d10169dd604bfbc55296"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.40", "f3534689f6b58f48aa3a9ac850d4f05832654fe257bf0549c08cc290035f70d5", [:mix], [], "hexpm", "cdb34f35892a45325bad21735fadb88033bcb7c4c296a999bde769783f53e46a"}, + "ex_doc": {:hex, :ex_doc, "0.33.0", "690562b153153c7e4d455dc21dab86e445f66ceba718defe64b0ef6f0bd83ba0", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "3f69adc28274cb51be37d09b03e4565232862a4b10288a3894587b0131412124"}, + "file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"}, + "inch_ex": {:hex, :inch_ex, "2.0.0", "24268a9284a1751f2ceda569cd978e1fa394c977c45c331bb52a405de544f4de", [:mix], [{:bunt, "~> 0.2", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "96d0ec5ecac8cf63142d02f16b7ab7152cf0f0f1a185a80161b758383c9399a8"}, + "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, + "makeup": {:hex, :makeup, "1.2.1", "e90ac1c65589ef354378def3ba19d401e739ee7ee06fb47f94c687016e3713d1", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d36484867b0bae0fea568d10131197a4c2e47056a6fbe84922bf6ba71c8d17ce"}, + "makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"}, + "makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"}, + "mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"}, + "neotoma": {:hex, :neotoma, "1.7.3", "d8bd5404b73273989946e4f4f6d529e5c2088f5fa1ca790b4dbe81f4be408e61", [:rebar], [], "hexpm", "2da322b9b1567ffa0706a7f30f6bbbde70835ae44a1050615f4b4a3d436e0f28"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, + "plug": {:hex, :plug, "1.18.1", "5067f26f7745b7e31bc3368bc1a2b818b9779faa959b49c934c17730efc911cf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "57a57db70df2b422b564437d2d33cf8d33cd16339c1edb190cd11b1a3a546cc2"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.7.5", "261f21b67aea8162239b2d6d3b4c31efde4daa22a20d80b19c2c0f21b34b270e", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "20884bf58a90ff5a5663420f5d2c368e9e15ed1ad5e911daf0916ea3c57f77ac"}, + "plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"}, + "plug_heartbeat": {:hex, :plug_heartbeat, "1.0.0", "11b263a4c04d45b85c16ae815dd9a29ad405d7962769313c1244959328ebc39c", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "fa17f6eac7f4d91fcef36d253bc0114ff8c4d6e91665f2b06be1beb753cbb6aa"}, + "poison": {:hex, :poison, "6.0.0", "9bbe86722355e36ffb62c51a552719534257ba53f3271dacd20fbbd6621a583a", [:mix], [{:decimal, "~> 2.1", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "bb9064632b94775a3964642d6a78281c07b7be1319e0016e1643790704e739a2"}, + "ranch": {:hex, :ranch, "2.2.0", "25528f82bc8d7c6152c57666ca99ec716510fe0925cb188172f41ce93117b1b0", [:make, :rebar3], [], "hexpm", "fa0b99a1780c80218a4197a59ea8d3bdae32fbff7e88527d7d8a4787eff4f8e7"}, + "slime": {:hex, :slime, "1.3.1", "d6781854092a638e451427c33e67be348352651a7917a128155b8a41ac88d0a2", [:mix], [{:neotoma, "~> 1.7", [hex: :neotoma, repo: "hexpm", optional: false]}], "hexpm", "099b09280297e0c6c8d1f56b0033b885fc4eb541ad3c4a75f88a589354e2501b"}, + "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, } diff --git a/test/trot/live_reload_test.exs b/test/trot/live_reload_test.exs index a9deba6..4fa037c 100644 --- a/test/trot/live_reload_test.exs +++ b/test/trot/live_reload_test.exs @@ -3,7 +3,9 @@ defmodule Trot.LiveReloadTest do import Trot.TestHelper setup do - Path.relative_to_cwd("lib/trot.ex") |> File.touch!() + tempfile = Path.relative_to_cwd("lib/tmp-test-#{:binary.encode_hex(:rand.bytes(16))}.ex") + :ok = File.touch!(tempfile) + on_exit(fn -> File.rm!(tempfile) end) end test "reloading maintains the requested URL" do diff --git a/test/trot/route_test.exs b/test/trot/route_test.exs index 9bf455f..faf9afc 100644 --- a/test/trot/route_test.exs +++ b/test/trot/route_test.exs @@ -139,7 +139,7 @@ defmodule Trot.RouterTest do test "route returns a bad rpc call with a nested error message" do conn = call(Router, :get, "/badrpc/nested") assert conn.status == 500 - assert conn.resp_body == ~S'{%Protocol.UndefinedError{description: nil, protocol: Enumerable, value: ""}}' + assert conn.resp_body == {%Protocol.UndefinedError{description: nil, protocol: Enumerable, value: ""}} |> inspect end test "route returns redirect" do