2

I want Rspec to request the root using https. This is what I currently have:

it "requesting root (/) with HTTPS should return 200" do
  get "https://test.host/"
  last_response.should be_ok
end

Attempting the solution proposed in Test an HTTPS (SSL) request in RSpec Rails returns the following error:

wrong number of arguments (0 for 1)

I would assume I could do something like:

get "/", :https => "on"

Is there a way to request the root without specifying the host?

Community
  • 1
  • 1
Brett Hardin
  • 4,012
  • 2
  • 19
  • 22
  • I'm not sure, but the point made in the comments of the link you posted give the solution I'd use, which is to make the whole site require SSL the whole time. Then you don't need to do a special check like this. – ian Jan 31 '13 at 18:25
  • Unfortunately I can't do that. Certain sections need to be tested for HTTP and others for HTTPS. – Brett Hardin Jan 31 '13 at 18:30
  • Are you trying to test that it will only accept a secure connection? The functionality will be the same regardless, so perhaps you could test the functionality by turning off the requirement for SSL, and then to check the secure connection is used, turn the SSL requirement back on and then check that a 301 redirect is given when you make an non-SSL call? – ian Jan 31 '13 at 23:46
  • I'm already checking for a 301 redirect on a non-ssl call. I now want to make sure a 200 is received when the ssl request is made. – Brett Hardin Feb 01 '13 at 19:33
  • But you're not checking either Sinatra or the server (Thin or whatever) because they don't handle the SSL. It's just a tunnel, if you get a 200 via HTTP then you'll get it via HTTPS as long as the server handling the HTTPS is set up correctly. I'm assuming that would be Apache or Nginx etc. – ian Feb 02 '13 at 03:03
  • I'm using Nginx. To test this code, where would you suggest it be? – Brett Hardin Feb 02 '13 at 17:52
  • You could request the non-secure page and then follow the redirect and _then_ test for the 200. I don't really see the point though, if your application presents a 301 with the correct location on a non-secure request then you've done enough. Anything more is testing the network set up, which, if it returns even one secure connection is correct (barring some craziness in the configuration). – ian Feb 03 '13 at 19:32

2 Answers2

5

When using Sinatra and RSpec, you are using the #get/#post methods provided by Rack::Test, so I suggest you look there to see how they work: https://github.com/brynary/rack-test/blob/master/lib/rack/test.rb

As you can see, they take an optional env Hash, where you can set "HTTPS" to "on", like this:

get '/', {}, {'HTTPS' => 'on'}

If you want to set it by default for all your requests, you need to override the Rack::Test::Session#default_env method, and had 'HTTPS' => 'on' to it (I suggest doing it in your spec_helper.rb), like this:

class Rack::Test::Session
  def default_env
    { "rack.test" => true, "REMOTE_ADDR" => "127.0.0.1", "HTTPS" => 'on' }.merge(headers_for_env)
  end
end
nbarraille
  • 9,926
  • 14
  • 65
  • 92
  • 1
    Thanks. I didn't want to mess with the usual defaults so I used `super.merge("HTTPS" => 'on')` with `Rack::Test::Session.prepend MyEnvModule` – James EJ Jul 06 '15 at 21:45
  • the `default_env` method is no longer available. `DEFAULT_ENV` is now a private constant. – lobati Dec 16 '22 at 06:04
4

The previous answer with the Rack::Test:Session change did not work for me in rails 4.1.1. Instead I am now using the Rails RSpec bindings to force force all integration tests into https. To do this add the following code to spec_helper.rb:

class ActionDispatch::Integration::Session
  def https?
    true
  end
end
TikiTDO
  • 63
  • 7
  • I have been using the above for about 8 years, I think to force the tests to be ssl (tls; now). Is this still needed? Did rails to to tsl as a default at some point? – codenoob Feb 16 '22 at 01:50