Проверка авторизации для связанных ресурсов с rspec и фабрикой Girl (has_many через отношения)

Я хотел бы проверить, что не вошедший в систему пользователь не может получить доступ к странице, обычно зарезервированной для определенных клиентов (одно из их предложений: только они могут видеть черновик страницы соглашения). Следует перенаправить его на страницу входа клиента.

У клиента много сделок

Модели /customer.rb

class Customer < ActiveRecord::Base
  rolify

  has_many :customer_deals
  has_many :deals,                through: :customer_deals

модели /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: "[email protected]") }
    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

deals.rb

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

  end
end  

1 ответ

Решение

Сделка has_many :customers, Ваш deal Фабрика пытается присвоить атрибут customer_id. В сделке нет такого атрибута, потому что у сделки много клиентов. Фабрика customer_deal может быть более подходящей для использования здесь:

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

Это потребует от вас избавления от customer_id в вашем deal завод. В общем, я считаю, что выбирать произвольное целое число вместо внешнего ключа на ваших фабриках - плохая форма. Если фабрика требует отношений, то эти отношения должны быть созданы фабрикой. Если отношения не требуются для достоверности объекта, то я бы вообще оставил их вне фабрики, возможно, добавив их за чертой, если это то, что вам часто нужно.

Я бы посоветовал прочитать руководство " НАЧАЛО РАБОТЫ" - все это, но особенно части, касающиеся ассоциаций, черт и ассоциаций has_many.

Другие вопросы по тегам