Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send raw post data in a Rails functional test?

I'm looking to send raw post data (e.g. unparamaterized JSON) to one of my controllers for testing:

class LegacyOrderUpdateControllerTest < ActionController::TestCase   test "sending json" do     post :index, '{"foo":"bar", "bool":true}'   end end 

but this gives me a NoMethodError: undefined method `symbolize_keys' for #<String:0x00000102cb6080> error.

What is the correct way to send raw post data in ActionController::TestCase?

Here is some controller code:

def index   post_data = request.body.read   req = JSON.parse(post_data) end 
like image 998
brian Avatar asked Jan 20 '10 18:01

brian


2 Answers

I ran across the same issue today and found a solution.

In your test_helper.rb define the following method inside of ActiveSupport::TestCase:

def raw_post(action, params, body)   @request.env['RAW_POST_DATA'] = body   response = post(action, params)   @request.env.delete('RAW_POST_DATA')   response end 

In your functional test, use it just like the post method but pass the raw post body as the third argument.

class LegacyOrderUpdateControllerTest < ActionController::TestCase   test "sending json" do     raw_post :index, {}, {:foo => "bar", :bool => true}.to_json   end end 

I tested this on Rails 2.3.4 when reading the raw post body using

request.raw_post 

instead of

request.body.read 

If you look at the source code you'll see that raw_post just wraps request.body.read with a check for this RAW_POST_DATA in the request env hash.

like image 87
bbrowning Avatar answered Sep 18 '22 02:09

bbrowning


I actually solved the same issues just adding one line before simulating the rspec post request. What you do is to populate the "RAW_POST_DATA". I tried to remove the attributes var on the post :create, but if I do so, it do not find the action.

Here my solution.

 def do_create(attributes)   request.env['RAW_POST_DATA'] = attributes.to_json   post :create, attributes end  

In the controller the code you need to read the JSON is something similar to this

   @property = Property.new(JSON.parse(request.body.read)) 
like image 22
Andrea Reginato Avatar answered Sep 19 '22 02:09

Andrea Reginato