1

I'm running Ruby 1.9.3 and Rails 3.1. I can successfully manually test my usage of the Washout gem by sending myself XML payloads. I am trying to recreate the following bash command in a rails test:

curl -H "Content-Type: text/xml; charset=utf-8" -H "SOAPAction:soap_submit_contract" -d@test/fixtures/soap/success.xml http://localhost/soap/action

As you can see, it sets some header data and sends the data in the file test/fixtures/soap/success.xml

All the other examples I see for POSTs look like this:

post :parse_pdf,
  :terminal_key => @terminal_key,
  :contract_pdf => load_pdf(pdf)

But in my case the file data isn't a named parameter, and this doesn't seem to be setting the header information.

How can I submit a post exactly the same way the curl command does?

Our test suite is using the default ActionController::TestCase as such:

class SoapControllerTest < ActionController::TestCase
  fixtures :terminals

  test "soap_succeeds" do 
    # request.set_header_information ???
    post :action, # file data ???

    assert_match(/success/, @response.body)
  end

end
Devon Parsons
  • 1,234
  • 14
  • 23

2 Answers2

1

In request specs, you can pass your headers in hash as third argument of your request method, like this:

post :action, {}, {'YOUR_HEADER' => 'value'}

See the documentation for more information.

Update

To post XML data, try this way:

xml_data = File.read('test/fixtures/soap/success.xml')
post :action, xml_data, { 'CONTENT_TYPE' => 'application/xml' }
K M Rakibul Islam
  • 33,760
  • 12
  • 89
  • 110
0

In Rails 5, and based on this Gist and having a token based authentication, I had to do the following:

# auth_request_helper.rb
module AuthRequestHelper
  def http_login
    @env ||= {}
    User.create!(
      email: 'email', 
      password: 'pass', 
      password_confirmation: 'pass'
      )
     email = 'email'
     password = 'pass'
     # AuthenticateUser is a custom class which logs the user and returns a token
     @env['TOKEN'] = AuthenticateUser.call(user, pw).token
   end
end

Then, on the spec file:

# users_spec.rb

# login to http basic auth
before(:each) do
  http_login
end

describe 'POST /users' do
  let(:valid_attributes) { 
    { 
      email: 'some_email', 
      password: 'some_pass',
      password_confirmation: 'some_pass',        
      format: :json # Also useful for specifying format
     } 
   }

  context 'when the request is valid' do
    before { post '/users', params: valid_attributes, headers: {'Authorization': @env['TOKEN']} }

    it 'returns status code 201' do
      expect(response).to have_http_status(201) # Success
    end
  end
end