如何测试 before_filter 是否会重定向所有 Rails 控制器操作?

发布于 2024-10-19 06:21:40 字数 550 浏览 1 评论 0原文

我的一个控制器中有一个相当典型的 require_no_user 作为 before_filter 。我需要测试登录用户尝试访问任何控制器操作时是否会被此过滤器重定向。

有没有一种明智的方法可以做到这一点,而无需枚举我的测试用例中的所有控制器操作?

我试图避免:

context 'An authenticated user' do
  setup do
    activate_authlogic
    @user = Factory(:user)
    UserSession.create(@user)
  do

  should 'not be allowed to GET :new' do
    get :new
    assert_redirected_to(root_path)
  end

  should 'not be allowed to POST :create' do
    # same as above
  end

  # Repeat for every controller action
end

I have a fairly typical require_no_user as a before_filter in one of my controllers. I need to test that a logged in user is redirected by this filter if they try to access any of the controller's actions.

Is there a sensible way to do this without enumerating all of the controller's actions in my test case?

I'm trying to avoid:

context 'An authenticated user' do
  setup do
    activate_authlogic
    @user = Factory(:user)
    UserSession.create(@user)
  do

  should 'not be allowed to GET :new' do
    get :new
    assert_redirected_to(root_path)
  end

  should 'not be allowed to POST :create' do
    # same as above
  end

  # Repeat for every controller action
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

橘亓 2024-10-26 06:21:40

我不知道...尽管您可以通过将所有方法和操作打包到散列中来使其更短:

should "be redirected" do
  {
    :get => :new,
    :post => :create,
  }.each do |method, action|
    send(method, action)
    assert_redirected_to(root_path)
  end
end

编辑:所以是的,这可能有点矫枉过正,但这是另一种方式:

should "be redirected" do
  ActionController::Routing::Routes.named_routes.routes.each do |name, route|
    if route.requirements[:controller] == @controller.controller_name
      send(route.conditions[:method], route.requirements[:action])
      assert_redirected_to(root_path)
    end
  end
end

似乎如果您定义自定义路由中的多个 :methods 仍然只“找到”第一个,例如,

map.resources :foo, :collection => {
  :bar => [:get, :post]
}

上述路由将仅使用 GET 动词进行尝试。

此外,如果 URL 中有其他要求,例如存在记录 ID,我的简单示例会忽略该要求。我把这个留给你来破解:)

Not that I'm aware of... though you could make it a bit shorter by packing all the methods and actions into a hash:

should "be redirected" do
  {
    :get => :new,
    :post => :create,
  }.each do |method, action|
    send(method, action)
    assert_redirected_to(root_path)
  end
end

Edit: so yeah, this is probably overkill, but here's another way:

should "be redirected" do
  ActionController::Routing::Routes.named_routes.routes.each do |name, route|
    if route.requirements[:controller] == @controller.controller_name
      send(route.conditions[:method], route.requirements[:action])
      assert_redirected_to(root_path)
    end
  end
end

Seems though that if you define multiple :methods in custom routes that it still only "finds" the first, e.g.

map.resources :foo, :collection => {
  :bar => [:get, :post]
}

The above route will only be attempted with the GET verb.

Also if there are other requirements in the URL, such as presence of a record ID, my naive example ignores that requirement. I leave that up to you to hack out :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文