Проверка авторизации для связанных ресурсов с 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.