当用户应该有权访问他拥有的交易时,Rspec 测试失败,用户被重定向

2024-04-29

在我的应用程序中,借助 Cancan,我允许客户访问他自己的优惠。

当我用浏览器“手动”尝试时它有效但我未能实施 rspec 测试。客户无法访问其他客户的交易,只能访问他自己的交易(管理员通过 Active Admin 界面授予他访问权限)。

就像我没有设法让 rspec 理解我为测试创建的客户(通过 FactoryGirl)应该被允许/与我为测试创建的交易(再次通过 FactoryGirl)相关联。

测试:/spec/controllers/deals_controller_spec.rb

require 'spec_helper'
require "cancan/matchers"

describe DealsController do      

  context "As signed-in CUSTOMER" do 

    before do
      @customer = FactoryGirl.create(:customer) #the factory builds a basic customer i.e with 'prospect role' attributed by default
      @deal     = FactoryGirl.create(:deal, :customers => [@customer]) # in array as a deal has_many customers    
      sign_in_customer @customer
    end

    describe "the customer can read=view the page of a Deal HE OWNS " do
      it "can access the page" do
        get :deal_page, { :id => @deal.id }
        expect(current_path).to eq(deal_page_path(@deal))
        page.should have_content('Here is one of your deals, dear customer')
      end 
    end 

 end

这是我得到的错误:

DealsController As signed-in CUSTOMER with access to the deal page
 Failure/Error: expect(current_path).to eq(deal_page_path(@deal))

       expected: "/deals_page/2"
            got: "/customer_interface_homepage"

       (compared using ==)

这是详细的测试日志

Deal Exists (0.8ms)  SELECT 1 AS one FROM "deals" WHERE LOWER("deals"."deal_code") = LOWER('CHA1FR001') LIMIT 1      
  SQL (2.1ms)  INSERT INTO "deals" ("admin_user_id", "client_contact_point_name", blabla") VALUES ($1, $2, blabla...) RETURNING "id"  [["admin_user_id", 1], ["client_contact_point_name", "henri Cool"], ["client_contact_point_profile_url", "http://example.com"], ....blabla...]
  (...blabla)
  Customer Exists (0.6ms)  SELECT 1 AS one FROM "customers" WHERE (LOWER("customers"."email") = LOWER('[email protected] /cdn-cgi/l/email-protection') AND "customers"."id" != 1) LIMIT 1
  (...blabla)
Started GET "/customers/signin" for 127.0.0.1 at 2014-05-28 18:37:05 +0200
Processing by Customers::SessionsController#new as HTML
  Rendered customers/sessions/new.html.erb within layouts/lightbox (40.0ms)
  Rendered layouts/_metas.html.erb (0.4ms)
  Rendered layouts/_messages.html.erb (0.7ms)
  Rendered layouts/_footer.html.erb (1.2ms)
Completed 200 OK in 77ms (Views: 51.5ms | ActiveRecord: 0.0ms)
Started POST "/customers/signin" for 127.0.0.1 at 2014-05-28 18:37:05 +0200
Processing by Customers::SessionsController#create as HTML
  Parameters: {"utf8"=>"✓", "customer"=>{"email"=>"[email protected] /cdn-cgi/l/email-protection", "password"=>"[FILTERED]"}, "commit"=>"Log In"}
  Customer Load (4.0ms)  SELECT "customers".* FROM "customers" WHERE "customers"."email" = '[email protected] /cdn-cgi/l/email-protection' ORDER BY "customers"."id" ASC LIMIT 1
  SQL (1.0ms)  UPDATE "customers" SET "remember_created_at" = $1, "updated_at" = $2 WHERE "customers"."id" = 1  [["remember_created_at", 2014-05-28 16:37:05 UTC], ["updated_at", 2014-05-28 18:37:05 +0200]]
  SQL (1.2ms)  UPDATE "customers" SET "last_sign_in_at" = $1, "current_sign_in_at" = $2, "last_sign_in_ip" = $3, "current_sign_in_ip" = $4, "sign_in_count" = $5, "updated_at" = $6 WHERE "customers"."id" = 1  [["last_sign_in_at", 2014-05-28 16:37:05 UTC], ["current_sign_in_at", 2014-05-28 16:37:05 UTC], ["last_sign_in_ip", "127.0.0.1"], ["current_sign_in_ip", "127.0.0.1"], ["sign_in_count", 1], ["updated_at", 2014-05-28 18:37:05 +0200]]
**Redirected to http://www.example.com/customer_interface_homepage**
Completed 302 Found in 33ms (ActiveRecord: 6.2ms)
Started GET "/customer_interface_homepage" for 127.0.0.1 at 2014-05-28 18:37:05 +0200
Processing by ClientreportingPagesController#index as HTML
  Customer Load (0.5ms)  SELECT "customers".* FROM "customers" WHERE "customers"."id" = 1 ORDER BY "customers"."id" ASC LIMIT 1
   (1.2ms)  SELECT COUNT(*) FROM "roles" INNER JOIN "customers_roles" ON "roles"."id" = "customers_roles"."role_id" WHERE "customers_roles"."customer_id" = $1 AND (((roles.name = 'prospect') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))  [["customer_id", 1]]      
  Rendered layouts/_metas.html.erb (0.2ms)
   (0.8ms)  SELECT COUNT(*) FROM "roles" INNER JOIN "customers_roles" ON "roles"."id" = "customers_roles"."role_id" WHERE "customers_roles"."customer_id" = $1 AND (((roles.name = 'superadmin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))  [["customer_id", 1]]
  Rendered layouts/client_interface_partials
Completed 200 OK in 34ms (Views: 27.7ms | ActiveRecord: 2.4ms)
Processing by DealsController#deal_page as HTML
  Parameters: {"id"=>"2"}
**Completed 401 Unauthorized in 1ms**
  Rendered text template (0.1ms)
   (0.5ms)  ROLLBACK TO SAVEPOINT active_record_2
   (0.3ms)  ROLLBACK TO SAVEPOINT active_record_1
   (0.3ms)  ROLLBACK

我不确定这是问题的根本原因,但此日志中有两件事对我来说似乎很奇怪:

  • 为什么 rspec 发送到 example.com/customer_interface_homepage (我在 spec_helper 文件中告诉 rspec 我在本地测试:Capybara.asset_host = 'http:// localhost:3000')?

  • 为什么 rspec 最后会遇到“Completed 401 Unauthorized in 1ms”?


一些可能对解决问题有用的文件:

/app/models/customer_ability.rb

class CustomerAbility
  include CanCan::Ability


  def initialize(customer)
    alias_action :show, :to => :read #this will have no change on the alias :read!

    customer ||= Customer.new # guest customer (not logged in)
    if customer.has_role? :superadmin 
      Log.info "Ability: customer is superadmin"
      can :manage, :all     
    else
      can :read, Deal do |deal|
        # Only customers who have been granted access in Active Admin to a deal can read 
        deal.customers.include? customer 
      end
    end
  end

end

控制器/deals_controller.rb

class DealsController < ApplicationController

 before_filter :authenticate_customer!, 
    :only => [ :deal_page ]

 def deal_page
    @deal = Deal.find(params[:id])
    authorize! :read, @deal # only allow customers with authorized access in AA; sends to customer_ability

    respond_to do |format|
      format.html 
      format.json { render json: @deal }
    end
  end

应用程序控制器.rb

class ApplicationController < ActionController::Base

  protect_from_forgery

  # handle Cancan authorization exception
  rescue_from CanCan::AccessDenied do |exception|
    exception.default_message = t("errors.application_controller_exception_messages.only_open_to_admin")
    if current_user # if it's user redirect to main HP
      redirect_to root_path, :alert => exception.message
    else # if it's a Customer redirect him to client interface HP
      redirect_to customer_interface_homepage_path, :alert=> exception.message
    end
  end

  def current_ability #inspired by http://mikepackdev.com/blog_posts/12-managing-devise-s-current-user-current-admin-and-current-troll-with-cancan
    @current_ability ||= case
                         when current_user
                           UserAbility.new(current_user)
                         when current_customer 
                           CustomerAbility.new(current_customer)
                         end
  end

/spec/support/utilities.rb

include ApplicationHelper

def sign_in_customer(customer)
    customer.confirm!
    visit new_customer_session_path
    fill_in "Email", with: customer.email
    fill_in "Password", with: customer.password
    click_on "Log In"
    #populate cookie when not using capybara
    cookies[:authentication_token] = customer.authentication_token

end

/spec/factories/deals.rb

FactoryGirl.define do
  factory :deal do
    # id    i don't here any id
sequence(:deal_campaign_code) { |n| "CHA#{n}FR001" }        
    featured  true
    admin_user_id   1   
    end    
end    

/spec/factories/customers.rb

FactoryGirl.define do
  factory :customer do # we use prospect as by definition a visitor signing in gets 'prospect status'
    sequence(:email) { |n| "person_#{n}@example.com"}   
    password "bet(8a3#"
    password_confirmation "bet(8a3#"
    # required if the Devise Confirmable module is used
     confirmed_at Time.now
     confirmation_token nil     

    # create deals connected to the Customer
    after(:create) do |customer|
      customer.deals << FactoryGirl.create(:deal)
    end

  end

end

/app/models/customer.rb

class Customer < ActiveRecord::Base
  rolify

  # -- Relationships --------------------------------------------------------
  has_many :customer_deals,       dependent: :destroy
  has_many :deals,                through: :customer_deals

/app/models/deal.rb

class Deal < ActiveRecord::Base

  # -- Relationships --------------------------------------------------------
  belongs_to :admin_user,     :foreign_key => 'admin_user_id'
  has_many   :customer_deals, dependent: :destroy
  has_many   :customers,      through: :customer_deals      

/app/models/customer_deal.rb

class CustomerDeal < ActiveRecord::Base

  # -- Relationships --------------------------------------------------------
  belongs_to :customer,       :foreign_key => 'customer_id'
  belongs_to :deal,           :foreign_key => 'deal_id'

我认为会话信息没有传递到您在规范中提出的请求中。看本指南介绍如何将设备与控制器测试一起使用 https://github.com/plataformatec/devise/wiki/How-To%3a-Controllers-tests-with-Rails-3-%28and-rspec%29.

作为一种替代方法,我建议将其作为功能规格 https://www.relishapp.com/rspec/rspec-rails/docs/feature-specs/feature-spec而不是控制器规格。注意让水豚与设计很好地玩耍遵循本指南 https://github.com/plataformatec/devise/wiki/How-To%3a-Test-with-Capybara.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当用户应该有权访问他拥有的交易时,Rspec 测试失败,用户被重定向 的相关文章

  • 强参数不起作用

    使用 Ruby 1 9 3 Rails 3 2 13 Strong parameters 0 2 1 我遵循了教程和railscasts中的每一个指示 但我无法让strong parameters工作 这应该是非常简单的事情 但我看不出错误
  • 如何从模型调用辅助方法?

    我使用 MongoDB 作为我的 Rails 应用程序中的数据库和 MongoID gem 我想从模型中调用辅助方法after create回调方法 这怎么可能 我的模型代码是 class Department include Applic
  • Googlebot 收到现有模板缺少模板错误

    在过去的几天里 当谷歌机器人尝试访问我们的主页 欢迎 索引 时 我们开始收到缺少模板的错误 我已经盯着这个看了几个小时 知道我只是错过了一些简单的东西 A ActionView MissingTemplate occurred in wel
  • rvm编译安装ruby 2.5.0出错

    我正在尝试使用 rvm 安装 ruby 2 5 0 但出现错误 我在 Ubuntu 18 16 和现在的 Linux Mint Cinnamon 上尝试过 基本上我在运行安装 ruby 的代码之前所做的是 打开 GPG 密钥https rv
  • 如何覆盖 Ruby Ranges 的 .. 和 ... 运算符以接受 Float::INFINITY?

    我想覆盖 and Ruby 中的运算符Range 原因是 我正在处理数据库中的无限日期范围 如果你拉一个infinty从 Postgres 中取出日期时间 你会得到一个Float INFINITY在红宝石中 问题是 我无法使用Float I
  • SSL_connect 返回=1 errno=0 状态=SSLv3 读取服务器证书 B:证书验证仅在代理时失败

    这篇文章几乎重复了许多其他帖子 包括Rails 4 和 Ruby 2 Net HTTP SSL 请求 OpenSSL SSL SSLError SSL connect returned 1 errno 0 state SSLv2 v3 re
  • 我们能否知道回形针下载何时完成?

    我有一个应用程序 我需要知道用户的 Rails Paperclip 文件下载时间complete 我的应用程序设置为与 Amazon S3 交互 当用户收到完整的文件时 我需要运行 JavaScript 函数 我怎样才能做到这一点 跟踪天气
  • 渲染:带参数的动作

    我有一个有 2 种方法的类 第一个方法由视图使用一些 GET 参数 params page 调用 我想保存这些参数并通过渲染操作将它们发送到我的第二个方法 class exemple def first sql save of params
  • sleep 0 有特殊含义吗?

    我看到很多用法sleep 0在我的一个客户项目中 代码看起来像这样 while true sleep 0 end 阅读一些像这样的答案this https stackoverflow com questions 3727420 signif
  • 如何使 Rails 3 资源预编译速度更快?

    我有一个正在运行的 Rails 3 2 1 应用程序 我正在通过 Capistrano 进行部署deploy assets它运行deploy assets precompile task 一切工作都很好 除了编译本身非常慢 我没有那么多 C
  • ApplicationController 的未定义方法“helper_method”,Rails 5

    我正在尝试使用doorkeeper 将oAuth2 0 集成到我的仅rails api 应用程序中 但我不断收到此错误 ApplicationController 的未定义方法 helper method 但无法找到解决该问题的明确解决方案
  • 如何在 Rails 3.2.1 版本中注释 Rails 模型

    我正在尝试遵循一些在线教程来在 Rails 中注释我的模型 然而 似乎所有教程都在谈论过时的注释版本或不正确的安装 这真是一团糟 到目前为止我已经尝试过以下方法 1 在 Gemfile 中添加此内容 gem annotate 2 4 0 2
  • Rails:format.js 或 format.json,或两者?

    可能很明显 但我仍然缺乏基本知识 那么在控制器内部 两者都可以使用 还是总是 Javascript 所以两者是相同的 json and js是两种不同类型的响应 它们在 Rails 中被定义为不同的 MIME 类型 Mime Type re
  • 多态控制器和调用对象

    我的地址具有多态关系 可以由成员或依赖者拥有 一切看起来都很棒 直到我意识到除非我遗漏了一些东西 否则我不知道创建它的对象是什么类型 有没有办法告诉路由文件包含对象的类型 Models class Member lt ActiveRecor
  • Ruby 中的并行赋值运算符

    我正在查看 Ruby 编程 书中的一个示例 def fib up to max i1 i2 1 1 parallel assignment i1 1 and i2 1 while i1 lt max yield i1 i1 i2 i2 i1
  • 可以覆盖/实现的 ruby​​ 运算符列表

    是否有可以覆盖的所有 ruby 运算符的列表 不是那些不能的 Here s Ruby 运算符表 http phrogz net programmingruby language html table 18 4 方法和可重载的有 Elemen
  • 为什么 mongrel 没有在 Rails 3.2.rc 中启动?

    启动 mongrel 的 GEMFILE gem rails 3 1 0 gem mongrel gt 1 2 0 pre2 启动 WEBrick 的 GEMFILE 不是杂种 gem rails 3 2 0 rc2 gem mongrel
  • 使用 Fetch 和 FormData API 上传多个文件

    我正在尝试使用本机Fetch https developer mozilla org en US docs Web API Fetch API and FormData https developer mozilla org en US d
  • Rails:CSRF 令牌不工作但已设置

    我在 Heroku 上有我的 Rails 3 应用程序 当我发送银行信息时 我得到 WARNING Can t verify CSRF token authenticity但我的 CSRF 令牌已设置 https gist github c
  • 在rails中,如何将记录作为csv文件返回

    我有一个名为 Entries 的简单数据库表 class CreateEntries lt ActiveRecord Migration def self up create table entries do t t string firs

随机推荐