47

I was doing this before in a rails 2 app in a ActionController::IntegrationTest with

get '/', {}, {:user_agent => "Googlebot"}

but this seems to not work anymore in Rails 3.

What should I do?

John Bachir
  • 22,495
  • 29
  • 154
  • 227

7 Answers7

48

If you use request.user_agent in your application, you can write the following code:

get '/', headers: { "HTTP_USER_AGENT" => "Googlebot" }
shanet
  • 7,246
  • 3
  • 34
  • 46
Noé
  • 621
  • 5
  • 6
  • Awesome - do you know of any way to set this for all requests made during integration tests? – Brian Armstrong Jan 19 '11 at 22:09
  • Can you elaborate why passing symbols doesn't work anymore? This seems to be a step back from a syntactic point of view, and an unnecessary migration hassle when porting from 2.x. – mxk May 23 '12 at 14:36
  • Also, passing the header as HTTP_* didn't work for me either. I had to pass it as CONTENT_TYPE instead of HTTP_CONTENT_TYPE. If I passed XML as the request body, only CONTENT_TYPE => application/xml would make Rails parse it into the params hash. – mxk May 23 '12 at 14:38
  • 3
    This doesn't work with Rails 3.1. The third argument to `get` specifies a session hash, not HTTP headers. – John Sep 19 '12 at 17:31
  • You won't be able to set `remote_ip` that way – Green Jun 02 '13 at 16:48
15

None of the above answers worked for me, the following is what finally worked in an rspec controller test:

@request.user_agent = "a MobileDevice/User-Agent"
post :endpoint, param: 2354
Alex Pretzlav
  • 15,505
  • 9
  • 57
  • 55
13

I was able to get it working on Rails 5.2.1 using this:

get '/path', headers: { 'HTTP_USER_AGENT' => 'Mozilla/5.0 (blah blah)' }

I looked here for the acceptable keywords to the method.

tddrmllr
  • 459
  • 4
  • 12
7

I fixed this behavior and with Rails 4.0 you will be able to specify actual HTTP Headers like "User-Agent" and "Content-Type" in integration and functional tests. There no longer a need to specify them as CGI variables.

If you are interested you can have a look at the change: https://github.com/rails/rails/pull/9700

Yves Senn
  • 2,006
  • 16
  • 13
4

For myself, in a controller test in rspec3, I used

request.env["HTTP_USER_AGENT"] = "Hello"

Before making the request

lucianosousa
  • 8,144
  • 4
  • 21
  • 25
Michael Baldry
  • 1,990
  • 2
  • 14
  • 28
3

If you have a collection of specs which all require a specific user agent, you may find the following helps to DRY up your specs:

Define this somewhere (e.g. spec_helper.rb):

module DefaultUserAgent

  def post(uri, params = {}, session = {})
    super uri, params, {'HTTP_USER_AGENT' => MY_USER_AGENT}.merge(session)
  end

  def get(uri, params = {}, session = {})
    super uri, params, {'HTTP_USER_AGENT' => MY_USER_AGENT}.merge(session)
  end

end

Then just include DefaultUserAgent when you need it.

davetapley
  • 17,000
  • 12
  • 60
  • 86
0

A user agent is just an http header, so you should be able to use the methods here: http://guides.rubyonrails.org/testing.html#helpers-available-for-integration-tests

And pass in the user agent to the headers (I didn't test this):

headers = {"User-Agent" => "Googlebot"}
request_via_redirect(:get, '/', {}, headers)
zsalzbank
  • 9,685
  • 1
  • 26
  • 39