【问题标题】:Devise Logout - Cucumber step fails but application runs correctly设计注销 - Cucumber 步骤失败,但应用程序运行正常
【发布时间】:2015-01-26 20:49:45
【问题描述】:

Ruby-2.2.0 Rails-4.2 设计-3.4.1 Declarative_Authorization-0.5.7

我正在将 Rails-3.2 应用程序转换为 Rails-4。该应用程序同时使用设计身份验证和声明式授权。我正在使用默认的设计控制器。

此时,我已经通过了大部分身份验证方案。然而,我遇到的是我无法通过 Cucumber 注销,但我可以在浏览器中注销。有问题的步骤如下所示:

 When /select end the current session/ do
  selector_type = "#"
  selector_value = link = "session_end_action_id"
  selector = selector_type + selector_value
  click_button( selector_value )
end

路线如下所示:

. . .
                  new_user_session GET    /users/sign_in(.:format)                                        devise/sessions#new
                      user_session POST   /users/sign_in(.:format)                                        devise/sessions#create
              destroy_user_session DELETE /users/sign_out(.:format)                                       devise/sessions#destroy
                     user_password POST   /users/password(.:format)                                       devise/passwords#create
                 new_user_password GET    /users/password/new(.:format)                                   devise/passwords#new
                edit_user_password GET    /users/password/edit(.:format)                                  devise/passwords#edit
                                   PATCH  /users/password(.:format)                                       devise/passwords#update
                                   PUT    /users/password(.:format)                                       devise/passwords#update
                       user_unlock POST   /users/unlock(.:format)                                         devise/unlocks#create
                   new_user_unlock GET    /users/unlock/new(.:format)                                     devise/unlocks#new
                                   GET    /users/unlock(.:format)                                         devise/unlocks#show
                           account POST   /account(.:format)                                              users#create
                       new_account GET    /account/new(.:format)                                          users#new
                      edit_account GET    /account/edit(.:format)                                         users#edit
                                   GET    /account(.:format)                                              users#show
                                   PATCH  /account(.:format)                                              users#update
                                   PUT    /account(.:format)                                              users#update
                                   DELETE /account(.:format)                                              users#destroy
                      authenticate GET    /authenticate(.:format)                                         devise/sessions#new

. . .

                    users#index
                                   POST   /users(.:format)                                                users#create
                          new_user GET    /users/new(.:format)                                            users#new
                         edit_user GET    /users/:id/edit(.:format)                                       users#edit
                              user GET    /users/:id(.:format)                                            users#show
                                   PATCH  /users/:id(.:format)                                            users#update
                                   PUT    /users/:id(.:format)                                            users#update
                                   DELETE /users/:id(.:format)                                            users#destroy

. . .

视图中的代码如下所示:

  <%-if current_user-%>
  <span class="authenticated_session" id="authenticated_session">
  <%=button_to( I18n.t( :session_end ).strip.titleize, 
      :destroy_user_session, 
      :class => "button logout",
      :confirm => I18n.t( :session_end_confirm ).strip.titleize,
      :id => :session_end_action_id,
      :method => :delete, 
      :title => I18n.t( :session_end_logout ).strip.titleize )-%>
  </span
<%-else-%>
  <%=button_to( I18n.t( :session_start ).strip.titleize, 
      :new_user_session, 
      :class => "button login",
      :id => :session_start_action_id_top, 
      :method => :get, 
      :title => I18n.t( :session_start_login ).strip.titleize )-%>
<%-end-%>

当我通过身份验证并按下注销按钮时,我就会注销。当我运行黄瓜步骤时,我从声明式授权中收到授权错误。

  <p class='security classified' style='color: orangered'>
      you are not authorised to access the requested resource</p>    
  <br/>
  <!-- End of header section from layouts/application.html.erb -->

这是在应用程序控制器中生成的:

def permission_denied
  if current_user
    flash[:security_classified] =  I18n.t( :security_classified ).strip
  else
    flash[:security_restricted] =  I18n.t( :security_restricted ).strip
  end
  redirect_back_or_default( welcome_url )
end

这显然是从用户控制器调用的:

  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["id", 21]]

  Rendered public/hll_authorisation_notice.html (0.1ms)

  Rendered welcome/show.html.erb within layouts/application (3.6ms)
Completed 200 OK in 105ms (Views: 100.4ms | ActiveRecord: 0.6ms)

Started DELETE "/users/sign_out" for 127.0.0.1 at 2015-01-26 15:19:48 -0500

Processing by UsersController#destroy as HTML
  Parameters: {"id"=>"sign_out"}
   (0.2ms)  SELECT COUNT(*) FROM "users"
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["id", 21]]
  CACHE (0.0ms)  SELECT COUNT(*) FROM "users"
  Role Load (0.4ms)  SELECT "roles".* FROM "roles" INNER JOIN "clearances" ON "roles"."id" = "clearances"."role_id" WHERE "clearances"."user_id" = ?  [["user_id", 21]]
  CACHE (0.0ms)  SELECT COUNT(*) FROM "users"

Redirected to http://www.example.com/welcome
Filter chain halted as :filter_access_filter rendered or redirected
Completed 302 Found in 23ms (ActiveRecord: 1.0ms)

Started GET "/welcome" for 127.0.0.1 at 2015-01-26 15:19:48 -0500
Processing by WelcomeController#show as HTML
   (0.2ms)  SELECT COUNT(*) FROM "users"
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["id", 21]]

  Rendered public/hll_authorisation_notice.html (0.1ms)

  Rendered welcome/show.html.erb within layouts/application (1.5ms)
Completed 200 OK in 61ms (Views: 57.2ms | ActiveRecord: 0.4ms)
   (0.4ms)  rollback transaction

检查(为此目的重新格式化)permission_denied 方法中的对象揭示了这一点:

    #<UsersController:0x00000006ba52d8 @_action_has_layout=true,
 @_routes=nil, @_headers={"Content-Type"=>"text/html"}, @_status=200,
 @_request=#<ActionDispatch::Request:0x00000006ba51c0
 @env={"rack.version"=>[1, 3], "rack.input"=>#<StringIO:0x00000006c378e0>,
 "rack.errors"=>#<StringIO:0x00000006c379a8>, "rack.multithread"=>false,
 "rack.multiprocess"=>true, "rack.run_once"=>false,
 "REQUEST_METHOD"=>"DELETE", "SERVER_NAME"=>"www.example.com",
 "SERVER_PORT"=>"80", "QUERY_STRING"=>"", "PATH_INFO"=>"/users/sign_out",
 "rack.url_scheme"=>"http", "HTTPS"=>"off", "SCRIPT_NAME"=>"",
 "CONTENT_LENGTH"=>"14", "rack.test"=>true, "REMOTE_ADDR"=>"127.0.0.1",
 "HTTP_REFERER"=>"http://www.example.com/",
 "HTTP_HOST"=>"www.example.com",
 "CONTENT_TYPE"=>"application/x-www-form-urlencoded",
 "HTTP_COOKIE"=>"_proforma_session=. . .

所以,这绝对是用户控制器的问题。但是只有在 Cucumber 运行期间才会遇到错误。当我使用 Rails 服务器为应用程序提供服务并从浏览器访问它时,登录并注销,然后我会在没有任何错误的情况下注销,如下面的日志摘录所示。

Started DELETE "/users/sign_out" for ::1 at 2015-01-26 15:45:50 -0500
Processing by Devise::SessionsController#destroy as HTML
  Parameters: {"authenticity_token"=>"Xl9Ui1a6jt8gyjZOuh0lsefUqFI1eEunaXivaEdfwWhMofYhYbRumnZlsRQjwmjWiC1C7sI7O3FwDgEf9lJzJw=="}
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]
   (0.2ms)  SELECT COUNT(*) FROM "users"
   (0.1ms)  begin transaction
   (0.4ms)  UPDATE "users" SET "accessed_at" = '2015-01-26 20:45:50.179843', "changed_at" = '2015-01-26 20:45:50.180748', "lock_version" = 20 WHERE ("users"."id" = 1 AND "users"."lock_version" = 19)
   (103.2ms)  commit transaction
Redirected to http://localhost:3000/

有人对这里可能发生的事情有任何想法吗?浏览器sign_out中找到的token值重要吗?

附:如果我这样做:

visit('/users/sign_out')

然后步骤通过。我在这里进行了疯狂的猜测,但是在 RoR 中与 html 按钮一起使用的 javscript 是否有任何可能导致我看到的内容?

【问题讨论】:

  • 你有没有看到明显的,当你运行黄瓜步骤时你没有登录!
  • 是的,测试已登录。只有通过身份验证才能收到授权错误。

标签: ruby-on-rails-4 devise cucumber declarative-authorization


【解决方案1】:

我认为我发现了问题所在;在研究一个不同且不相关的问题时不小心。

我认为问题是 Capybara 使用的默认测试方法:

https://github.com/jnicklas/capybara#selecting-the-driver

默认情况下,Capybara 使用 :rack_test 驱动,速度快但 受限:不支持JavaScript,也无法访问HTTP Rack 应用程序之外的资源,例如远程 API 和 OAuth 服务。要绕过这些限制,您可以设置一个 您的功能的不同默认驱动程序。例如,如果你 更喜欢在 Selenium 中运行所有东西,你可以这样做:

Capybara.default_driver = :selenium

但是,如果您使用的是 RSpec 或 Cucumber,您可能希望改为 考虑将更快的:rack_test 保留为 default_driver,并且 仅标记那些需要支持 JavaScript 的驱动程序的测试 分别使用:js =&gt; true@javascript。默认情况下, JavaScript 测试使用:selenium driver 运行。你可以 通过设置 Capybara.javascript_driver 来改变它。

您也可以临时更改驱动程序(通常在 之前/设置和之后/拆卸块):

Capybara.current_driver = :webkit # temporarily select different driver ... tests ... Capybara.use_default_driver # switch back to default driver

注意:切换驱动程序会创建一个新会话,因此您可能不会 可以在测试过程中切换。

【讨论】:

    猜你喜欢
    • 2021-11-16
    • 2020-01-23
    • 2012-06-03
    • 1970-01-01
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多