Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP POST XML content from cucumber

I am trying to sending XML content through POST to a controller ('Parse') method ('index') in a simple Rails project. It is not RESTful as my model name is different, say, 'cars'. I have the following in a functional test that works:

def test_index
   ...
   data_file_path = File.dirname(__FILE__) + 
        '/../../app/views/layouts/index.xml.erb'

   message = ERB.new( File.read( data_file_path ) )
   xml_result = message.result( binding )
   doc = REXML::Document.new xml_result

   @request.env['RAW_POST_DATA'] = xml_result
   post :index
   assert_response :success
end

I am now trying cucumber (0.4.3), and would like to know as to how I can simulate the POST request in a "When" clause. I have only one controller method 'index', and I have the following in config/routes.rb:

ActionController::Routing::Routes.draw do |map|
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
end
  1. webrat within cucumber is only for HTML, and cannot do POST?
  2. @request variable is not available from cucumber environment?
  3. If I use something like 'visit index' (assuming it is Parse controller, index method) in features/step_definitions/car_steps.rb, I get the following error:

undefined method `index' for # (NoMethodError)

Appreciate any suggestions on how to do integration tests with Cucumber for HTTP POST with XML content.

like image 399
mbuf Avatar asked Nov 12 '09 13:11

mbuf


3 Answers

Patrick Ritchie's solution helped me out too, but I needed to make a slight modification to make it work with Rails 3.

post("/controller/index", xml_result, {"CONTENT_TYPE" => "text/xml"})

I think this is because, in v3, Rails is more tightly integrated with Rack.

like image 86
Louis Rose Avatar answered Oct 16 '22 19:10

Louis Rose


Webrat won't help you here, it's for browser based interactions so if you are specing an API it won't help.

You can use 'post' in Cucumber but you need to provide the full path to the action, not just the action. Also, pass in the Content-type header so Rails knows you are passing in XML.

post("/controller/index", xml_result, {"Content-type" => "text/xml"})

On the response side you can do the following:

response.should be_success
like image 30
Patrick Ritchie Avatar answered Oct 16 '22 18:10

Patrick Ritchie


Thanks a lot guys, I've spent all day swearing. I'll add an example with basic authentication and with json, if other people than me are looking for it. btw, both application/xml and text/xml works, but for json you need application/json.

post("/myresource.xml", 
     some_xml_string,
     {"CONTENT_TYPE" => "text/xml",
      "HTTP_AUTHORIZATION" => ActionController::HttpAuthentication::Basic.encode_credentials("user", "secret")})

and JSON

post("/myresource.json",
      some_json_string,
      {"CONTENT_TYPE" => "application/json",
       "HTTP_AUTHORIZATION" => ActionController::HttpAuthentication::Basic.encode_credentials("user", "secret")})

and I use these in spec/requests without any webrat or capybara browser stuff.

like image 1
oma Avatar answered Oct 16 '22 20:10

oma