Using default_url_options in RSpec with Rails 5 

There's a [long](https://rails.lighthouseapp.com/projects/8994/tickets/5998-actionviewtestcase-does-not-honor-default_url_options-set-in-application_controllerrb)-[standing](https://github.com/rspec/rspec-rails/issues/255) [bug](https://github.com/rspec/rspec-rails/issues/1275) in the integration of controller testing into RSpec that prevents you from easily setting `default_url_options` for your controller specs. As far as I can tell, it doesn't get fixed because the RSpec teams considers the problem a bug in Rails, and the Rails team does not care if RSpec breaks.

I'm talking about the issue you run into when you're trying to work with locale settings passed into your application as namespace variables in `routes.rb` like this:

```ruby
scope "/:locale" do
    devise_for :users,  #...and so on
```

Today I learned that the inability to set a default `:locale` parameter can be maddening. Your specs will fail with `ActionView::Template::Error: No route matches` errors:

```
1) Devise::RegistrationsController POST /users should allow registration
     Failure/Error: %p= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token)

     ActionView::Template::Error:
       No route matches {"action":"show","confirmation_token":"pcyw_izS8GchnT-R3EGz","controller":"devise/confirmations"} missing required keys: [:locale]
```

The reason is that `ActionController::TestCase` ignores normal settings of `default_url_options` in `ApplicationController` or your `config/environments/test.rb`. No other intuitive attempt at a workaround worked either. Frustratingly, it took me around an hour to debug and come up with a monkeypatch-style workaround. The existing workarounds that I could find online are all broken in Rails 5.

So here it is:

```ruby
# spec/support/fix_locales.rb
ActionController::TestCase::Behavior.module_eval do
  alias_method :process_old, :process

  def process(action, *args)
    if params = args.first[:params]
      params["locale"] = I18n.default_locale
    end
    process_old(action, *args)
  end
end
```

Note the assumption that you are passing params in your spec using a symbol key and not the string `"params"`.

obie-fernandez
March 22, 2017
