-module(nine_elli_mid).
-export([urlencoded_params/1, json_request/1, json_response/1]).
-spec urlencoded_params(map()) -> map().
urlencoded_params(Context = #{req := Req, params := Params}) ->
case elli_request:get_header(<<"Content-Type">>, Req) of
<<"application/x-www-form-urlencoded">> ->
PostParams =
maps:from_list(
elli_request:post_args_decoded(Req)),
Context#{params => maps:merge(Params, PostParams)};
_ ->
Context
end.
-spec json_request(map()) -> map().
json_request(Context = #{req := Req}) ->
case elli_request:get_header(<<"Content-Type">>, Req) of
<<"application/json">> ->
case thoas:decode(
elli_request:body(Req))
of
{ok, Json} ->
Context#{json => Json};
_ ->
Context#{resp => {500, [], <<"JSON Decoding Error">>}}
end;
_ ->
Context#{resp => {400, [], <<"Expected JSON">>}}
end.
-spec json_response(map()) -> {integer(), list(), binary()}.
json_response(#{draft := Draft, status := Status}) ->
{Status, [{<<"Content-Type">>, <<"application/json">>}], thoas:encode(Draft)};
json_response(#{draft := Draft}) ->
{200, [{<<"Content-Type">>, <<"application/json">>}], thoas:encode(Draft)};
json_response(Context) ->
Context.
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-include_lib("elli/include/elli.hrl").
urlencoded_params_test() ->
Req = #req{headers = []},
?assertEqual(#{req => Req, params => #{}},
urlencoded_params(#{req => Req, params => #{}})),
Req1 =
#req{headers = [{<<"Content-Type">>, <<"application/x-www-form-urlencoded">>}],
body = <<"foo=stuff">>},
?assertEqual(#{req => Req1, params => #{foo => <<"bar">>, <<"foo">> => <<"stuff">>}},
urlencoded_params(#{req => Req1, params => #{foo => <<"bar">>}})).
json_request_test() ->
Req = #req{headers = []},
?assertEqual(#{req => Req, resp => {400, [], <<"Expected JSON">>}},
json_request(#{req => Req})),
Req1 =
#req{headers = [{<<"Content-Type">>, <<"application/json">>}],
body = <<"{\"foo\":\"bar\"}">>},
?assertEqual(#{req => Req1, json => #{<<"foo">> => <<"bar">>}},
json_request(#{req => Req1})),
Req2 =
#req{headers = [{<<"Content-Type">>, <<"application/json">>}],
body = <<"{\"foo\":\"bar}">>},
?assertEqual(#{req => Req2, resp => {500, [], <<"JSON Decoding Error">>}},
json_request(#{req => Req2})).
json_response_test() ->
?assertEqual(#{}, json_response(#{})),
?assertEqual({200,
[{<<"Content-Type">>, <<"application/json">>}],
<<"{\"foo\":\"bar\"}">>},
json_response(#{draft => #{<<"foo">> => <<"bar">>}})),
?assertEqual({500,
[{<<"Content-Type">>, <<"application/json">>}],
<<"{\"foo\":\"bar\"}">>},
json_response(#{draft => #{<<"foo">> => <<"bar">>}, status => 500})).
-endif.