The last time I was trying to specify RAW_POST_DATA in rspec was probably Rails 3 or 4, but I ran into a situation trying to test an edge case for error handling where I wanted that same functionality. I quickly found this issue [Unable to POST raw request body], but didn’t immediately figure out what wasn’t being set correctly.
In this case the test setup I was using was setting multipart/form-data
instead of application/xml
on the content types:
{:HTTP_ACCEPT=>"application/xml", :HTTP_CONTENT_TYPE=>"multipart/form-data", :CONTENT_TYPE=>"multipart/form-data"}
Because of this, the Rails controller tests that rspec hooks into was trying to break following malformed xml down to parameters:
<test>
<data
<![CDATA[THIS|IS|SENSITIVE|BUT|MALFORMED]]>
</data>
</test>
Minitest::Assertion:
Expected response to be a <400: bad_request>, but was a <422: Unprocessable Entity>
Response body: <errors>
<error>["<test>\n <data", "nbsp;\n <!"] are not permitted parameters</error>
</errors>
I finally noticed that the mime-type
might be involved. In this code, Content-Type
was also an issue, so:
- Removed
HTTP_CONTENT_TYPE
from the headers - Set
CONTENT_TYPE
header to'application/xml'
instead of'multipart/form-data'
to prevent automatic params parsing in this case. - Passed
as: :xml
into the test to get the'mime-type'
correct.
Ultimately, if your code hasn’t boxed you in, then the as: :xml
and passing raw data as a parameter should work:
post things_path, params: raw_xml_data, headers: non_form_data_headers, as: :xml
## replacement for the following:
# @request.env['RAW_POST_DATA'] = raw_xml_data
# post things_path