Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are people testing rails 3.1 + force_ssl?

The force_ssl function in rails 3.1 is hardcoded to ignore the development environment, but not test. This is giving me redirect errors in my (minitest) tests. Is the solution to set up my test server to support ssl (if so, how?). If not, should I monkey patch force_ssl to ignore requests in test?

 def force_ssl(options = {})
        host = options.delete(:host)
        before_filter(options) do
          if !request.ssl? && !Rails.env.development?
            redirect_options = {:protocol => 'https://', :status => :moved_permanently}
            redirect_options.merge!(:host => host) if host
            flash.keep
            redirect_to redirect_options
          end
        end
  end

EDIT Found this chain, which confirms other people think this an issue, but doesn't look like there's a committed fix yet: https://github.com/rails/rails/pull/2630

like image 386
spike Avatar asked Jan 24 '12 15:01

spike


4 Answers

Another option instead of monkey patching the entire application is to just override force_ssl in your test suite alone. For example, in test/test_helper.rb you can add this:

# We don't want SSL redirects in our test suite
module ActionController::ForceSSL::ClassMethods
  def force_ssl(options = {})
    # noop
  end
end
like image 71
Ryan McGeary Avatar answered Oct 18 '22 17:10

Ryan McGeary


Here's another approach, if you don't want to mess with monkey-patching... you can use a before filter. This is rspec, not minitest syntax, but you get the idea:

before(:each) do
  request.env["rack.url_scheme"] = "https"
end

This convinces your controller that it got an SSL request.

A benefit of taking this approach is that you can actually write a test to ensure your controller requires SSL. :)

like image 42
Benjamin Curtis Avatar answered Oct 18 '22 17:10

Benjamin Curtis


That's what I ended up doing after recently upgrading to Rails 3.1 and switching to the force_ssl filter. Monkey patch to the rescue!

In a new file at config/initializers/ignore_force_ssl_in_test.rb

module ActionController
  module ForceSSL
    module ClassMethods
      def force_ssl(options = {})
        before_filter(options) do
          if !request.ssl? && !Rails.env.development? && !Rails.env.test?
            redirect_to :protocol => 'https://', :status => :moved_permanently
          end
        end
      end
    end
  end
end
like image 4
Kelly Sutton Avatar answered Oct 18 '22 18:10

Kelly Sutton


If you are interested in testing with varying SSL, I did this on the setup of the functional test.

def setup
  @request.env['HTTPS'] = 'on'
end
like image 4
Carson Reinke Avatar answered Oct 18 '22 17:10

Carson Reinke