我手动向我在Active Admin面板上选择的客户授予某些交易的访问权限。 它正在工作"手动"但我不知道如何测试客户是否可以访问他的交易但无法访问其他客户的交易。
每个交易页面只能由与之关联的客户查看(如果您愿意,可以使用它们拥有):使用CanCan功能:
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
注意:客户和交易之间有很多关系(交易有很多客户/客户有很多交易)
这是我到目前为止的测试,但它不对,我认为我是TDD新手:)
require 'spec_helper'
require "cancan/matchers"
describe DealsController do
let(:customer) { FactoryGirl.create(:customer) }
let(:deal) { FactoryGirl.create(:deal, :customers => [customer]) } # in array as a deal has_many customers
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])
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(???????)
# WHAT TO DO HERE ??????
page.should have_content('here is your deal, dear customer')
end
end
describe "the customer can NOT read the page of a Deal he does not own =owned by other customers and is redirected his customer panel" do
it "can't access the page" do
get :deal_page, { :id => @deal.id }
expect(response).to redirect_to(customer_panel_path)
# WHAT TO DO HERE ??????
flash[:alert].should eql("Sorry but you could not access this page as it is not your Deal!")
end
end
end
问题是在客户应该有权访问交易页面的测试中,rspec说他不会被重定向到主页。我知道问题出在哪里:我觉得rspec并不知道这个创建的客户与这个创建的交易相关联。
这里是我定义交易页面的地方:controllers / deals_controller.rb
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
这似乎是一个非常基本的测试:我如何测试客户无法访问其他客户页面(与a_many关系客户/交易),但我不知道如何解决这个问题。
#编辑 如果它有助于解决这个问题:
appplication_controller.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_panel_path, :alert=> exception.message
end
end
def current_ability
@current_ability ||= case
when current_user
UserAbility.new(current_user)
when current_customer
CustomerAbility.new(current_customer)
end
end
编辑#2
这种失败的证据是以下测试成功时应该失败:
it "can access the deal page" do
get :deal_page, { :id => @deal.id }
expect(current_path).to eq(customer_panel_path)
end
编辑#3
使用Dave建议,写了
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])
sign_in_customer @customer
end
(...)
it "can access the DEAL he OWNS = HIS deals" do
get :deal_page, { :id => @deal.id }
expect(current_path).to eq(deal_page_path(@deal))
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_panel"
(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('person_1@example.com') 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"=>"person_1@example.com", "password"=>"[FILTERED]"}, "commit"=>"Log In"}
Customer Load (4.0ms) SELECT "customers".* FROM "customers" WHERE "customers"."email" = 'person_1@example.com' 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_panel**
Completed 302 Found in 33ms (ActiveRecord: 6.2ms)
Started GET "/customer_panel" 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
BOLD中的2行对我来说很奇怪:
为什么rspec发送到example.com/customer_panel(我在我的spec_helper文件中告诉rspec我在本地测试:Capybara.asset_host =&#39; http:// localhost:3000&#39;)?
为什么rspec最终在1ms内经历了#34;完成401未授权?
答案 0 :(得分:1)
在“客户可以阅读=查看交易HEWWNS的页面”,
expect(current_path).to eq(deal_path(@deal))
在“客户无法阅读他不拥有的交易页面......”中,您将以拥有该交易的客户身份登录。建立一个不同的客户并以该客户身份登录。
此外,您没有使用您在let
语句中定义的客户和交易,因此请删除它们。或者,最好删除@customer
和@deal
作业,并将@customer
和@deal
替换为customer
和deal
。