Reputation: 235
I localized my Rails app recently and added a default locale of 'en' (I followed the directions here for adding locales into my URLs). This broke most of my specs; I've been able to figure out solutions/workarounds for all of them except for my View specs.
Here's an example of a basic view spec that is broken, my articles view spec:
RSpec.describe 'articles/index', type: :view do
before(:each) do
assign(:articles, [
FactoryGirl.create(:article, number: '11.22.33'),
FactoryGirl.create(:article, number: '22.33.44')
])
end
it 'renders a list of articles' do
render
end
end
This spec results in the following error:
1) articles/index renders a list of articles
Failure/Error: render
ActionView::Template::Error:
No route matches {:action=>"show", :controller=>"articles", :id=>nil, :locale=>#<Article id: 2, number: "11.22.33", criminal_code_id: 3, description: nil, created_at: "2015-05-25 08:58:56", updated_at: "2015-05-25 08:58:56">} missing required keys: [:id, :locale]
Seems like there are three problems:
Here are my relevant routes:
Rails.application.routes.draw do
scope ':locale', locale: /#{I18n.available_locales.join("|")}/ do
resources :articles do
collection do
get 'custom_json', constraints: { format: :json }, defaults: { format: :json }
end
end
get "*path", to: redirect("/#{I18n.default_locale}") # handles /en/fake/path/whatever
end
get '', to: redirect("/#{I18n.default_locale}") # handles /
get '*path', to: redirect("/#{I18n.default_locale}/%{path}") # handles /not-a-locale/anything
end
Here's the relevant part of my application controller:
before_action :set_locale
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
def default_url_options(options = {})
{ locale: I18n.locale }.merge options
end
And my article view is at app/views/articles/index.html.erb (there's nothing out of the ordinary about it).
Anybody have an idea on how to get View specs to play nice with locales?
Upvotes: 2
Views: 1521
Reputation: 13195
The following may help you:
# Set locale for view specs, see https://github.com/rspec/rspec-rails/issues/255#issuecomment-2865917
class ActionView::TestCase::TestController
def default_url_options(options = {})
{locale: I18n.default_locale}
end
end
# Set locale for feature specs, see https://github.com/rspec/rspec-rails/issues/255#issuecomment-24698753
RSpec.configure do |config|
config.before(:each, type: :feature) do
default_url_options[:locale] = I18n.default_locale
end
end
It helped in my case. Still, I find it quite awkward that after so many years of Rails I18n one still has to care about such things oneself.
Upvotes: 9
Reputation: 724
Here is a potential workaround while you wait for someone to post a better answer:
Looks like you are doing a link_to in your index page for each of your articles. The url helper call in the link_to, e.g. article_path is where your spec may be breaking. I was having a similar problem and could not solve it. The url_helper methods did not work the same way for me in test env as they did in dev or prod env. More specifically, in test env they did not work unless I explicitly declared the locale in the url_helper call using locale: 'en'.
I looked around for a long time and could not work out why.
So I decided just to stub out the calls to url_helpers in my view spec like this
allow(view).to receive(:conversation_transmission_path).and_return("/")
allow(view).to receive(:edit_conversation_transmission_path).and_return("/")
that is rspec 3.2 syntax
Upvotes: 0