Fl4m3Ph03n1x
Background
I have a Plug Router that has some simple endpoints. One of these endpoints is a put method that receives a JSON body. I want to use Plug.Parsers to decode the body before processing it but I am having errors and I don’t know why.
Code
This is my router. Requests come here to be dispatched:
defmodule Api do
use Plug.Router
plug :match
plug Plug.Parsers, parsers: [:urlencoded, :json],
json_decoder: Jason
plug :dispatch
put "/cars" do
IO.inspect conn
Conn.send_resp(conn, Status.code(:ok), "OK")
end
end
To exercise this code, I have the following test:
test "returns 200 OK when the list of cars is loaded correctly" do
# Arrange
body_params = "[
{
\"id\": 1,
\"number\": 4
},
{
\"id\": 2,
\"number\": 6
}
]"
conn =
:put
|> conn("/cars")
|> put_req_header("accept", "application/json")
|> put_req_header("content-type", "application/json")
|> put_body_params(body_params)
# Act
conn = Api.call(conn, @opts)
# Assert
assert conn.state == :sent
assert conn.status == 200
assert conn.resp_body == "OK"
end
According to my knowledge, this should work, but I get the following error:
test PUT /cars returns 200 OK when the list of cars is loaded correctly (ApiTest)
test/api_test.exs:69
** (BadMapError) expected a map, got: “[\n {\n "id": 1,\n "number": 4\n },\n {\n "id": 2,\n "number": 6\n }\n ]”
code: conn = Api.call(conn, @opts)
stacktrace:
(stdlib 3.10) :maps.merge(%{}, “[\n {\n "id": 1,\n "seats": 4\n },\n {\n "id": 2,\n "seats": 6\n }\n ]”)
(plug 1.10.4) lib/plug/parsers.ex:354: Plug.Parsers.merge_params/4
(plug 1.10.4) lib/plug/parsers.ex:299: Plug.Parsers.call/2
(api 0.1.0) lib/api.ex:1: Api.plug_builder_call/2
test/api_test.exs:91: (test)
Questions
- Is my configuration of the router incorrect?
- Will the parser be applied to all incoming requests?
- What happens if I get a request that is not JSON? (will the parser ignore it?)
- What am I doing wrong?
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 2- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
harmon25
Might need a content-length header in the request that is the byte_size of the encoded JSON stringEDIT: can’t find this ‘put_body_params’ function documented, you sure that’s the correct way to test such a thing with Plug? Are you testing Jason or?al2o3cr
Using
put_body_paramsentirely short-circuits the parsing inPlug.Parser- that only happens whenbody_paramsis a%Plug.Unfetched{}.You want to set the body to the unparsed JSON when calling
Plug.Test.conn/3: