【问题标题】:Testing authorization for associated ressources with rspec and factory Girl (has_many through relations)使用 rspec 和 factory Girl 测试关联资源的授权(has_many through 关系)
【发布时间】:2014-04-28 20:11:06
【问题描述】:

我想测试未登录的用户是否无法访问通常为特定客户保留的页面(他们的交易之一:只有他们可以看到交易的草稿页面)。它应该将他重定向到客户登录页面。

一个客户有很多交易

模型/customer.rb

class Customer < ActiveRecord::Base
  rolify

  has_many :customer_deals
  has_many :deals,                through: :customer_deals

models/deal.rb

class Deal < ActiveRecord::Base  
  belongs_to :admin_user,     :foreign_key => 'admin_user_id'
  belongs_to :partner,        :foreign_key => 'partner_id',       :counter_cache => true

  has_many   :customer_deals
  has_many   :customers,      through: :customer_deals      

  accepts_nested_attributes_for :customers #:reject_if     # needed for Active admin 

模型/customer_deal.rb

  belongs_to :customer,       :foreign_key => 'customer_id'
  belongs_to :deal,           :foreign_key => 'deal_id'

我的以下测试因此错误而失败:

 1) Customer Interface pages As NON SIGNED-IN visitor does not have access to prepare deal page 
     Failure/Error: let(:deal) { FactoryGirl.create(:deal, :customer => customer) }
     NoMethodError:
       undefined method `customer=' for #<Deal:0x007f4f34b3a788>
     # ./spec/requests/client_interface_pages_spec.rb:15:in `block (2 levels) in <top (required)>'
     # ./spec/requests/client_interface_pages_spec.rb:50:in `block (4 levels) in <top (required)>'

这里是 rspec 测试页面:client_interface_pages_spec.rb

require 'spec_helper'
require 'cancan/matchers'

describe "Customer pages" do

    subject { page }
    let(:user)          { FactoryGirl.create(:user) }
    let(:customer)      { FactoryGirl.create(:customer) }
    let(:prospect)      { FactoryGirl.create(:prospect) }
    let(:wrong_customer){ FactoryGirl.create(:customer, email: "wrong@example.com") }
    let(:non_admin)     { FactoryGirl.create(:customer) }
    let(:deal)          { FactoryGirl.create(:deal, :customer => customer) }



    context "As NON SIGNED-IN visitor" do 

    let(:customer) {FactoryGirl.create(:customer)}

      describe "does not have access to prepare deal page" do
        it "cannot access the deal preparation page" do
          get :draft_deal_page, :deal_id => deal.id, :customer_id => customer.id
          response.should redirect_to(new_customer_session_path)
          flash[:alert].should eql("You need to login or sign up before continuing.")
        end
      end    


  end

路线

match '/prepare/deal_:id/draft-deal-page',
    to:   'deals#draft_deal_page',
    via:  'get',
    as:   :draft_deal_page 

我不知道是否相关,但这里是我使用的主要工厂:

customer_deals.rb

FactoryGirl.define do
  factory :customer_deal do
    customer
    deal
  end
end

customers.rb

FactoryGirl.define do
  factory :customer do 
    sequence(:email) { |n| "person_#{n}@example.com"}   
    password "abcde"
    password_confirmation "abcde"
    # required if the Devise Confirmable module is used
     confirmed_at Time.now
     confirmation_token nil 
   partner_id 3 

    # give customer role to customers
    factory :customer_with_customer_status do
      after(:create) {|customer| customer.add_role(:customer)}
    end

  end

end

交易.rb

FactoryGirl.define do
  factory :deal do
     title "lorem ipsum"
    featured  true
    admin_user_id 1
    partner_id 3
    customer_id 3

  end
end  

【问题讨论】:

  • 您的交易模型是什么样的。这就是你正在创建的工厂。它有客户关系吗?
  • @Derek 添加了 Deal.rb 和 customer_deal.rb 模型。也许这是问题的根源,但我不明白为什么会这样。
  • 这是问题的根源。看我的回答。

标签: ruby ruby-on-rails-3 ruby-on-rails-4 rspec factory-bot


【解决方案1】:

一笔交易has_many :customers。您的deal 工厂正在尝试分配“customer_id”属性。交易没有这样的属性,因为交易有 许多 个客户。 customer_deal 工厂可能更适合在这里使用:

let(:customer) { FactoryGirl.create(:customer_deal).customer }

这将要求您摆脱 deal 工厂中的 customer_id。一般来说,我认为选择一个任意整数来代替工厂中的外键是一种糟糕的形式。如果工厂需要关系,则该关系应该由工厂创建。如果对象有效性不需要关系,那么我会完全将其从工厂中移除,如果您经常需要它,可能会将其添加到特征后面。

我建议阅读 GETTING STARTED 指南 - 整个内容,尤其是关于 has_many 关联、特征和关联的部分。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多