jesse reiss
jesse reiss

Reputation: 4579

Rspec passing GET params to a PUT action

I'm trying to test a PUT request to a controller, but I need to send GET and POST body params to the action. The params cannot be mashed together, as certain parts of the code access the GET params explicitly.

How do you pass GET params to a put action?

I have this test :

it "updates the account password to the provided value" do
  put(:update, @params)
  @account.reload.crypted_password.should == PasswordAccount.encrypt(@newpass, @account.password_salt)
end    

How can i add a "token" param to the query string sent to the action?

Upvotes: 3

Views: 3818

Answers (2)

jesse reiss
jesse reiss

Reputation: 4579

UPDATE :

After investigating the rails testing source code I came up with the following :

def process_with_query(action, query_string="", parameters = nil, session = nil, flash = nil, http_method = 'GET')
  # Sanity check for required instance variables so we can give an
  # understandable error message.
  %w(@routes @controller @request @response).each do |iv_name|
    if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil?
      raise "#{iv_name} is nil: make sure you set it in your test's setup method."
    end
  end

  @request.recycle!
  @response.recycle!
  @controller.response_body = nil
  @controller.formats = nil
  @controller.params = nil

  @html_document = nil
  @request.env['REQUEST_METHOD'] = http_method

  parameters ||= {}
  @request.assign_parameters(@routes, @controller.class.name.underscore.sub(/_controller$/, ''), action.to_s, parameters)

  @request.session = ActionController::TestSession.new(session) unless session.nil?
  @request.session["flash"] = @request.flash.update(flash || {})
  @request.session["flash"].sweep

  @controller.request = @request
  @controller.params.merge!(parameters)
  build_request_uri(action, parameters)
  @request.env["QUERY_STRING"] = query_string.kind_of?(Hash) ? query_string.to_param : query_string
  @request.env["action_dispatch.request.query_parameters"] = Rack::Utils.parse_query(@request.env["QUERY_STRING"])
  ActionController::Base.class_eval { include ActionController::Testing }
  @controller.process_with_new_base_test(@request, @response)
  @request.session.delete('flash') if @request.session['flash'].blank?
  @response
end

def put_with_query(action, query_string="", parameters=nil, session=nil, flash=nil)
  process_with_query(action, query_string, parameters, session, flash, 'PUT')
end

def post_with_query(action, query_string="", parameters=nil, session=nil, flash=nil)
  process_with_query(action, query_string, parameters, session, flash, 'POST')
end

Any comments?

Upvotes: 1

David Chelimsky
David Chelimsky

Reputation: 9000

The put method is defined in Rails' ActionController::TestCase::Behavior:

http://api.rubyonrails.org/classes/ActionController/TestCase/Behavior.html#method-i-put

From what I can see there is no support for separating the different get/post params, but why not just include it in the @params variable?

put(:update, @params.merge(:token => 'gobbledygook'))

By the time your code sees the params, Rails has already merged the get/post params for you anyhow.

HTH, David

Upvotes: 3

Related Questions