在 rspec 支持文件的扩展 类 中获取当前设计用户
Get current devise user in extended classes in rspec support file
在我的 rails 应用程序中,我使用 devise 进行用户身份验证。我还在整个网站上使用 i18n,每个用户都可以在用户设置中选择她或他的特定语言。如果用户浏览具有给定语言环境设置的网站,或者它是访客并且使用默认语言环境,我不希望该语言环境显示在 url.
这是一个例子:
客人使用英语(默认)版本,因此 url 类似于 "anything.com/users/42",但如果她或他更改为法语(不是永久在设置中,而是通过单击 link 到法文版),url 变为 "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_controller
中的 default_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
现在我的问题是,当使用默认 i18n 语言环境设置(例如 en
)的登录用户访问联赛的编辑页面时,被重定向,因为她或他不被允许访问该页面。重定向考虑了 application_controller
中的 default_url_options
方法,并没有重定向到 /en/leagues/42
(如测试所期望的),而是重定向到 /leagues/42
.
我解决这个问题的方法是将 spec/support/fix_localization.rb
中的 default_url_options
方法更改为与 application_controller
中相同的方法,但我无法访问当前用户支持文件。
有没有人知道如何访问当前用户或解决我的问题的其他想法或解决方法?
提前致谢!
我找到了无需复制代码的解决方案。我刚刚将 spec/support/fix_localization.rb
文件更改为:
# 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
所以现在,使用从 ApplicationController
继承的当前使用的控制器 (subject
) 的 default_url_options
方法。
这在技术上并没有回答我的问题,但解决了根本问题。要获取当前用户(如最初要求的那样),也可以使用 subject
:
subject.current_user
但这仅在主题为控制器的支持文件中可用。
在我的 rails 应用程序中,我使用 devise 进行用户身份验证。我还在整个网站上使用 i18n,每个用户都可以在用户设置中选择她或他的特定语言。如果用户浏览具有给定语言环境设置的网站,或者它是访客并且使用默认语言环境,我不希望该语言环境显示在 url.
这是一个例子:
客人使用英语(默认)版本,因此 url 类似于 "anything.com/users/42",但如果她或他更改为法语(不是永久在设置中,而是通过单击 link 到法文版),url 变为 "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_controller
中的 default_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
现在我的问题是,当使用默认 i18n 语言环境设置(例如 en
)的登录用户访问联赛的编辑页面时,被重定向,因为她或他不被允许访问该页面。重定向考虑了 application_controller
中的 default_url_options
方法,并没有重定向到 /en/leagues/42
(如测试所期望的),而是重定向到 /leagues/42
.
我解决这个问题的方法是将 spec/support/fix_localization.rb
中的 default_url_options
方法更改为与 application_controller
中相同的方法,但我无法访问当前用户支持文件。
有没有人知道如何访问当前用户或解决我的问题的其他想法或解决方法?
提前致谢!
我找到了无需复制代码的解决方案。我刚刚将 spec/support/fix_localization.rb
文件更改为:
# 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
所以现在,使用从 ApplicationController
继承的当前使用的控制器 (subject
) 的 default_url_options
方法。
这在技术上并没有回答我的问题,但解决了根本问题。要获取当前用户(如最初要求的那样),也可以使用 subject
:
subject.current_user
但这仅在主题为控制器的支持文件中可用。