2016-09-14 53 views
1

在我的rails应用程序中,我使用devise进行用户验证。我也为整个网站使用i18n,每个用户都有可能在用户设置中选择她或他的特定语言。如果用户使用给定的语言环境集浏览网站,或者它是一个访客并使用默认语言环境,我不希望该语言环境显示在URL中。在rspec支持文件的扩展类中获取当前设计用户

下面是一个例子:

一位客人使用英语(默认)版本,所以该网址是一样的东西“anything.com/users/42”,但如果他或她在永久更改为法语(未设置,但通过点击法国版本的链接),网址变为“anything.com/fr/users/42”。如果该用户已登录并选择法语作为默认语言,则反过来。

这是通过以下行中我application_controller

# app/controllers/application_controller.rb 
def default_locale 
    current_user ? current_user.locale : I18n.default_locale 
end 
helper_method :default_locale 

def default_url_options options={} 
    (I18n.locale.to_s.eql?(default_locale.to_s) ? { locale: nil } : { locale: I18n.locale }).merge options 
end 

此作品在我的应用程序完美无瑕的实现。

但是我在测试时遇到问题。在某些测试中,我有这样的表述名为League现有的模型:

visit edit_league_path(@league) 
expect(page.current_path).to eq league_path(@league) 

检查重定向。联盟的动作edit只允许管理员使用。

因为我使用下面的方法之前制定我已经在用户登录(谁是不是管理员):

# spec/support/controller_macros.rb 
module ControllerMacros 
    def login_user *user_roles 
    before(:each) do 
     @request.env['devise.mapping'] = Devise.mappings[:user] 
     user = FactoryGirl.create(:user, *user_roles) 
     user.confirmed_at = Time.zone.now 
     user.save 
     sign_in user 
    end 
    end 
end 

厂家为用户创建随机用户随机的语言环境。

我也有一个支持文件,即修复了RSpec的测试本地化,因为从application_controllerdefault_url_options在RSpec的测试忽略(如讨论here):

# spec/support/fix_localization.rb 
# workaround, to set default locale for ALL spec 
class ActionView::TestCase::TestController 
    def default_url_options options={} 
    { locale: I18n.locale }.merge options 
    end 
end 

class ActionDispatch::Routing::RouteSet 
    def default_url_options options={} 
    { locale: I18n.locale }.merge options 
    end 
end 

现在我的问题是,当使用默认国际化语言环境设置(例如en)的登录用户访问联盟的编辑页面时,将被重定向,因为他或他不允许访问该页面。重定向考虑从application_controllerdefault_url_options方法,并且不会重定向到/en/leagues/42(如测试期望的那样),而是重定向到/leagues/42

我对此问题的解决方案是将spec/support/fix_localization.rb中的default_url_options方法更改为与application_controller中的方法相同,但我无法访问支持文件中的当前用户。

有没有人有关如何访问当前用户或其他想法或我的问题的解决方法的想法?

在此先感谢!

回答

0

我找到了一个没有重复代码的解决方案。从从ApplicationController继承使用当前使用的控制器(subject

# spec/support/fix_localization.rb 
# workaround, to set default locale for ALL spec 
class ActionView::TestCase::TestController 
    def default_url_options options={} 
    subject.default_url_options options 
    end 
end 

所以,现在的default_url_options方法:我只是改变了我的spec/support/fix_localization.rb文件。

这在技术上不回答我的问题,但解决了根本问题。为了获得当前用户(如最初要求),可以使用subject还有:

subject.current_user 

但这只是在支持文件,其中标的是控制器可用。