diff --git a/lib/atex/xrpc.ex b/lib/atex/xrpc.ex --- a/lib/atex/xrpc.ex +++ b/lib/atex/xrpc.ex @@ -168,10 +168,35 @@ end def post(client, %{__struct__: module} = procedure, opts) do + has_raw_input? = + if raw_input = procedure.raw_input do + opts = Keyword.put(opts, :body, raw_input) + + if Code.ensure_loaded?(module) and function_exported?(module, :content_type, 0) do + headers = Keyword.get(opts, :headers, []) + has_content_type? = Enum.any?(headers, fn {k, _} -> String.downcase(k) == "content-type" end) + + unless has_content_type? do + raise """ + content-type header is required when sending raw_input for #{module.id()}. + Expected: #{module.content_type()} + """ + end + end + + true + else + false + end + opts = - opts - |> put_params(procedure) - |> put_body(procedure) + if has_raw_input? do + put_params(opts, procedure) + else + opts + |> put_params(procedure) + |> put_body(procedure) + end output_struct = Module.concat(module, Output) output_exists = Code.ensure_loaded?(output_struct) diff --git a/test/atex/lexicon_test.exs b/test/atex/lexicon_test.exs --- a/test/atex/lexicon_test.exs +++ b/test/atex/lexicon_test.exs @@ -196,6 +196,8 @@ end test "error structs have from_json/1" do + Code.ensure_loaded!(Lexicon.Test.DoThing.Errors.SomethingBroke) + Code.ensure_loaded!(Lexicon.Test.DoThing.Errors.DoesNotCompute) assert function_exported?(Lexicon.Test.DoThing.Errors.SomethingBroke, :from_json, 1) assert function_exported?(Lexicon.Test.DoThing.Errors.DoesNotCompute, :from_json, 1) end @@ -232,6 +234,7 @@ end test "root module exports coerce_error/1" do + Code.ensure_loaded!(Lexicon.Test.DoThing) assert function_exported?(Lexicon.Test.DoThing, :coerce_error, 1) end @@ -269,7 +272,7 @@ end test "error structs have from_json/1" do - Code.ensure_loaded!(Lexicon.Test.DoOtherThing) + Code.ensure_loaded!(Lexicon.Test.DoOtherThing.Errors.ValidationFailed) assert function_exported?(Lexicon.Test.DoOtherThing.Errors.ValidationFailed, :from_json, 1) end