Merge ability and ability decorator

This commit is contained in:
Luis Ramos
2020-09-04 10:28:28 +01:00
parent 22eac6200c
commit 405b317726
5 changed files with 934 additions and 1048 deletions

View File

@@ -1,32 +1,11 @@
# frozen_string_literal: true
# Implementation class for Cancan gem.
# Instead of overriding this class, consider adding new permissions
# using the special +register_ability+ method which allows extensions to add their own abilities.
#
# See http://github.com/ryanb/cancan for more details on cancan.
require 'cancan'
module Spree
class Ability
include CanCan::Ability
class_attribute :abilities
self.abilities = Set.new
# Allows us to go beyond the standard cancan initialize method
# which makes it difficult for engines to modify the default +Ability+ of an application.
# The +ability+ argument must be a class that includes the +CanCan::Ability+ module.
# The registered ability should behave properly as a stand-alone class
# and therefore should be easy to test in isolation.
def self.register_ability(ability)
abilities.add(ability)
end
def self.remove_ability(ability)
abilities.delete(ability)
end
def initialize(user)
clear_aliased_actions
@@ -67,11 +46,309 @@ module Spree
can [:index, :read], Zone
end
# Include any abilities registered by extensions, etc.
Ability.abilities.each do |clazz|
ability = clazz.__send__(:new, user)
@rules = rules + ability.__send__(:rules)
add_shopping_abilities user
add_base_abilities user if is_new_user? user
add_enterprise_management_abilities user if can_manage_enterprises? user
add_group_management_abilities user if can_manage_groups? user
add_product_management_abilities user if can_manage_products? user
add_order_cycle_management_abilities user if can_manage_order_cycles? user
add_order_management_abilities user if can_manage_orders? user
add_relationship_management_abilities user if can_manage_relationships? user
end
# New users have no enterprises.
def is_new_user?(user)
user.enterprises.blank?
end
# Users can manage an enterprise if they have one.
def can_manage_enterprises?(user)
user.enterprises.present?
end
# Users can manage a group if they have one.
def can_manage_groups?(user)
user.owned_groups.present?
end
# Users can manage products if they have an enterprise that is not a profile.
def can_manage_products?(user)
can_manage_enterprises?(user) &&
user.enterprises.any? { |e| e.category != :hub_profile && e.producer_profile_only != true }
end
# Users can manage order cycles if they manage a sells own/any enterprise
# OR if they manage a producer which is included in any order cycles
def can_manage_order_cycles?(user)
can_manage_orders?(user) ||
OrderCycle.visible_by(user).any?
end
# Users can manage orders if they have a sells own/any enterprise.
def can_manage_orders?(user)
( user.enterprises.map(&:sells) & %w(own any) ).any?
end
def can_manage_relationships?(user)
can_manage_enterprises? user
end
def add_shopping_abilities(user)
can [:destroy], Spree::LineItem do |item|
user == item.order.user &&
item.order.changes_allowed?
end
can [:cancel], Spree::Order do |order|
order.user == user
end
can [:update, :destroy], Spree::CreditCard do |credit_card|
credit_card.user == user
end
can [:update], Customer do |customer|
customer.user == user
end
end
# New users can create an enterprise, and gain other permissions from doing this.
def add_base_abilities(_user)
can [:create], Enterprise
end
def add_group_management_abilities(user)
can [:admin, :index], :overview
can [:admin, :index], EnterpriseGroup
can [:read, :edit, :update], EnterpriseGroup do |group|
user.owned_groups.include? group
end
end
def add_enterprise_management_abilities(user)
# Spree performs authorize! on (:create, nil) when creating a new order from admin, and also (:search, nil)
# when searching for variants to add to the order
can [:create, :search], nil
can [:admin, :index], :overview
can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], ProducerProperty
can [:admin, :map_by_tag, :destroy], TagRule do |tag_rule|
user.enterprises.include? tag_rule.enterprise
end
can [:admin, :index, :create], Enterprise
can [:read, :edit, :update,
:remove_logo, :remove_promo_image, :remove_terms_and_conditions,
:bulk_update, :resend_confirmation], Enterprise do |enterprise|
OpenFoodNetwork::Permissions.new(user).editable_enterprises.include? enterprise
end
can [:welcome, :register], Enterprise do |enterprise|
enterprise.owner == user
end
can [:manage_payment_methods, :manage_shipping_methods, :manage_enterprise_fees], Enterprise do |enterprise|
user.enterprises.include? enterprise
end
# All enterprises can have fees, though possibly suppliers don't need them?
can [:index, :create], EnterpriseFee
can [:admin, :read, :edit, :bulk_update, :destroy], EnterpriseFee do |enterprise_fee|
user.enterprises.include? enterprise_fee.enterprise
end
can [:admin, :known_users, :customers], :search
can [:admin, :show], :account
# For printing own account invoice orders
can [:print], Spree::Order do |order|
order.user == user
end
can [:admin, :bulk_update], ColumnPreference do |column_preference|
column_preference.user == user
end
can [:admin, :connect, :status, :destroy], StripeAccount do |stripe_account|
user.enterprises.include? stripe_account.enterprise
end
can [:admin, :create], :manager_invitation
end
def add_product_management_abilities(user)
# Enterprise User can only access products that they are a supplier for
can [:create], Spree::Product
can [:admin, :read, :index, :update,
:seo, :group_buy_options,
:bulk_update, :clone, :delete,
:destroy], Spree::Product do |product|
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? product.supplier
end
can [:create], Spree::Variant
can [:admin, :index, :read, :edit, :update, :search, :delete, :destroy], Spree::Variant do |variant|
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? variant.product.supplier
end
can [:admin, :index, :read, :update, :bulk_update, :bulk_reset], VariantOverride do |vo|
next false unless vo.hub.present? && vo.variant.andand.product.andand.supplier.present?
hub_auth = OpenFoodNetwork::Permissions.new(user).
variant_override_hubs.
include? vo.hub
producer_auth = OpenFoodNetwork::Permissions.new(user).
variant_override_producers.
include? vo.variant.product.supplier
hub_auth && producer_auth
end
can [:admin, :create, :update], InventoryItem do |ii|
next false unless ii.enterprise.present? && ii.variant.andand.product.andand.supplier.present?
hub_auth = OpenFoodNetwork::Permissions.new(user).
variant_override_hubs.
include? ii.enterprise
producer_auth = OpenFoodNetwork::Permissions.new(user).
variant_override_producers.
include? ii.variant.product.supplier
hub_auth && producer_auth
end
can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], Spree::ProductProperty
can [:admin, :index, :read, :create, :edit, :update, :destroy], Spree::Image
can [:admin, :index, :read, :search], Spree::Taxon
can [:admin, :index, :read, :create, :edit], Spree::Classification
can [:admin, :index, :guide, :import, :save, :save_data, :validate_data, :reset_absent_products], ProductImport::ProductImporter
# Reports page
can [:admin, :index, :customers, :orders_and_distributors, :group_buys, :payments,
:orders_and_fulfillment, :products_and_inventory, :order_cycle_management, :packing],
Spree::Admin::ReportsController
add_bulk_coop_abilities
add_enterprise_fee_summary_abilities
end
def add_order_cycle_management_abilities(user)
can [:admin, :index, :read, :edit, :update, :incoming, :outgoing], OrderCycle do |order_cycle|
OrderCycle.visible_by(user).include? order_cycle
end
can [:admin, :index, :create], Schedule
can [:admin, :update, :destroy], Schedule do |schedule|
OpenFoodNetwork::Permissions.new(user).editable_schedules.include? schedule
end
can [:bulk_update, :clone, :destroy, :notify_producers], OrderCycle do |order_cycle|
user.enterprises.include? order_cycle.coordinator
end
can [:for_order_cycle], Enterprise
can [:for_order_cycle], EnterpriseFee
end
def add_order_management_abilities(user)
can [:index, :create], Spree::Order
can [:read, :update, :fire, :resend, :invoice, :print, :print_ticket], Spree::Order do |order|
# We allow editing orders with a nil distributor as this state occurs
# during the order creation process from the admin backend
order.distributor.nil? ||
# Enterprise User can access orders that they are a distributor for
user.enterprises.include?(order.distributor) ||
# Enterprise User can access orders that are placed inside a OC they coordinate
order.order_cycle.andand.coordinated_by?(user)
end
can [:admin, :bulk_management, :managed], Spree::Order do
user.admin? || user.enterprises.any?(&:is_distributor)
end
can [:admin, :create, :show, :poll], :invoice
can [:admin, :visible], Enterprise
can [:admin, :index, :create, :update, :destroy], :line_item
can [:admin, :index, :create], Spree::LineItem
can [:destroy, :update], Spree::LineItem do |item|
order = item.order
user.admin? || user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user)
end
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Payment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Shipment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Adjustment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::ReturnAuthorization
can [:destroy], Spree::Adjustment do |adjustment|
# Sharing code with destroying a line item. This should be unified and probably applied for other actions as well.
if user.admin?
true
elsif adjustment.adjustable.instance_of? Spree::Order
order = adjustment.adjustable
user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user)
elsif adjustment.adjustable.instance_of? Spree::LineItem
order = adjustment.adjustable.order
user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user)
end
end
can [:create], OrderCycle
can [:admin, :index, :read, :create, :edit, :update], ExchangeVariant
can [:admin, :index, :read, :create, :edit, :update], Exchange
can [:admin, :index, :read, :create, :edit, :update], ExchangeFee
# Enterprise user can only access payment and shipping methods for their distributors
can [:index, :create], Spree::PaymentMethod
can [:admin, :read, :update, :fire, :resend, :destroy, :show_provider_preferences], Spree::PaymentMethod do |payment_method|
(user.enterprises & payment_method.distributors).any?
end
can [:index, :create], Spree::ShippingMethod
can [:admin, :read, :update, :destroy], Spree::ShippingMethod do |shipping_method|
(user.enterprises & shipping_method.distributors).any?
end
# Reports page
can [:admin, :index, :customers, :group_buys, :sales_tax, :payments,
:orders_and_distributors, :orders_and_fulfillment, :products_and_inventory,
:order_cycle_management, :xero_invoices], Spree::Admin::ReportsController
add_bulk_coop_abilities
add_enterprise_fee_summary_abilities
can [:create], Customer
can [:admin, :index, :update, :destroy, :show], Customer, enterprise_id: Enterprise.managed_by(user).pluck(:id)
can [:admin, :new, :index], Subscription
can [:create, :edit, :update, :cancel, :pause, :unpause], Subscription do |subscription|
user.enterprises.include?(subscription.shop)
end
can [:admin, :build], SubscriptionLineItem
can [:destroy], SubscriptionLineItem do |subscription_line_item|
user.enterprises.include?(subscription_line_item.subscription.shop)
end
can [:admin, :edit, :cancel, :resume], ProxyOrder do |proxy_order|
user.enterprises.include?(proxy_order.subscription.shop)
end
end
def add_relationship_management_abilities(user)
can [:admin, :index, :create], EnterpriseRelationship
can [:destroy], EnterpriseRelationship do |enterprise_relationship|
user.enterprises.include? enterprise_relationship.parent
end
end
def add_bulk_coop_abilities
# Reveal the report link in spree/admin/reports#index
can [:bulk_coop], Spree::Admin::ReportsController
# Allow direct access to the report resource
can [:admin, :new, :create], :bulk_coop
end
def add_enterprise_fee_summary_abilities
# Reveal the report link in spree/admin/reports#index
can [:enterprise_fee_summary], Spree::Admin::ReportsController
# Allow direct access to the report resource
can [:admin, :new, :create], :enterprise_fee_summary
end
end
end

View File

@@ -1,313 +0,0 @@
class AbilityDecorator
include CanCan::Ability
# All abilites are allocated from this initialiser.
# Spree also defines other abilities.
def initialize(user)
add_shopping_abilities user
add_base_abilities user if is_new_user? user
add_enterprise_management_abilities user if can_manage_enterprises? user
add_group_management_abilities user if can_manage_groups? user
add_product_management_abilities user if can_manage_products? user
add_order_cycle_management_abilities user if can_manage_order_cycles? user
add_order_management_abilities user if can_manage_orders? user
add_relationship_management_abilities user if can_manage_relationships? user
end
# New users have no enterprises.
def is_new_user?(user)
user.enterprises.blank?
end
# Users can manage an enterprise if they have one.
def can_manage_enterprises?(user)
user.enterprises.present?
end
# Users can manage a group if they have one.
def can_manage_groups?(user)
user.owned_groups.present?
end
# Users can manage products if they have an enterprise that is not a profile.
def can_manage_products?(user)
can_manage_enterprises?(user) &&
user.enterprises.any? { |e| e.category != :hub_profile && e.producer_profile_only != true }
end
# Users can manage order cycles if they manage a sells own/any enterprise
# OR if they manage a producer which is included in any order cycles
def can_manage_order_cycles?(user)
can_manage_orders?(user) ||
OrderCycle.visible_by(user).any?
end
# Users can manage orders if they have a sells own/any enterprise.
def can_manage_orders?(user)
( user.enterprises.map(&:sells) & %w(own any) ).any?
end
def can_manage_relationships?(user)
can_manage_enterprises? user
end
def add_shopping_abilities(user)
can [:destroy], Spree::LineItem do |item|
user == item.order.user &&
item.order.changes_allowed?
end
can [:cancel], Spree::Order do |order|
order.user == user
end
can [:update, :destroy], Spree::CreditCard do |credit_card|
credit_card.user == user
end
can [:update], Customer do |customer|
customer.user == user
end
end
# New users can create an enterprise, and gain other permissions from doing this.
def add_base_abilities(_user)
can [:create], Enterprise
end
def add_group_management_abilities(user)
can [:admin, :index], :overview
can [:admin, :index], EnterpriseGroup
can [:read, :edit, :update], EnterpriseGroup do |group|
user.owned_groups.include? group
end
end
def add_enterprise_management_abilities(user)
# Spree performs authorize! on (:create, nil) when creating a new order from admin, and also (:search, nil)
# when searching for variants to add to the order
can [:create, :search], nil
can [:admin, :index], :overview
can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], ProducerProperty
can [:admin, :map_by_tag, :destroy], TagRule do |tag_rule|
user.enterprises.include? tag_rule.enterprise
end
can [:admin, :index, :create], Enterprise
can [:read, :edit, :update,
:remove_logo, :remove_promo_image, :remove_terms_and_conditions,
:bulk_update, :resend_confirmation], Enterprise do |enterprise|
OpenFoodNetwork::Permissions.new(user).editable_enterprises.include? enterprise
end
can [:welcome, :register], Enterprise do |enterprise|
enterprise.owner == user
end
can [:manage_payment_methods, :manage_shipping_methods, :manage_enterprise_fees], Enterprise do |enterprise|
user.enterprises.include? enterprise
end
# All enterprises can have fees, though possibly suppliers don't need them?
can [:index, :create], EnterpriseFee
can [:admin, :read, :edit, :bulk_update, :destroy], EnterpriseFee do |enterprise_fee|
user.enterprises.include? enterprise_fee.enterprise
end
can [:admin, :known_users, :customers], :search
can [:admin, :show], :account
# For printing own account invoice orders
can [:print], Spree::Order do |order|
order.user == user
end
can [:admin, :bulk_update], ColumnPreference do |column_preference|
column_preference.user == user
end
can [:admin, :connect, :status, :destroy], StripeAccount do |stripe_account|
user.enterprises.include? stripe_account.enterprise
end
can [:admin, :create], :manager_invitation
end
def add_product_management_abilities(user)
# Enterprise User can only access products that they are a supplier for
can [:create], Spree::Product
can [:admin, :read, :index, :update,
:seo, :group_buy_options,
:bulk_update, :clone, :delete,
:destroy], Spree::Product do |product|
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? product.supplier
end
can [:create], Spree::Variant
can [:admin, :index, :read, :edit, :update, :search, :delete, :destroy], Spree::Variant do |variant|
OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? variant.product.supplier
end
can [:admin, :index, :read, :update, :bulk_update, :bulk_reset], VariantOverride do |vo|
next false unless vo.hub.present? && vo.variant.andand.product.andand.supplier.present?
hub_auth = OpenFoodNetwork::Permissions.new(user).
variant_override_hubs.
include? vo.hub
producer_auth = OpenFoodNetwork::Permissions.new(user).
variant_override_producers.
include? vo.variant.product.supplier
hub_auth && producer_auth
end
can [:admin, :create, :update], InventoryItem do |ii|
next false unless ii.enterprise.present? && ii.variant.andand.product.andand.supplier.present?
hub_auth = OpenFoodNetwork::Permissions.new(user).
variant_override_hubs.
include? ii.enterprise
producer_auth = OpenFoodNetwork::Permissions.new(user).
variant_override_producers.
include? ii.variant.product.supplier
hub_auth && producer_auth
end
can [:admin, :index, :read, :create, :edit, :update_positions, :destroy], Spree::ProductProperty
can [:admin, :index, :read, :create, :edit, :update, :destroy], Spree::Image
can [:admin, :index, :read, :search], Spree::Taxon
can [:admin, :index, :read, :create, :edit], Spree::Classification
can [:admin, :index, :guide, :import, :save, :save_data, :validate_data, :reset_absent_products], ProductImport::ProductImporter
# Reports page
can [:admin, :index, :customers, :orders_and_distributors, :group_buys, :payments,
:orders_and_fulfillment, :products_and_inventory, :order_cycle_management, :packing],
Spree::Admin::ReportsController
add_bulk_coop_abilities
add_enterprise_fee_summary_abilities
end
def add_order_cycle_management_abilities(user)
can [:admin, :index, :read, :edit, :update, :incoming, :outgoing], OrderCycle do |order_cycle|
OrderCycle.visible_by(user).include? order_cycle
end
can [:admin, :index, :create], Schedule
can [:admin, :update, :destroy], Schedule do |schedule|
OpenFoodNetwork::Permissions.new(user).editable_schedules.include? schedule
end
can [:bulk_update, :clone, :destroy, :notify_producers], OrderCycle do |order_cycle|
user.enterprises.include? order_cycle.coordinator
end
can [:for_order_cycle], Enterprise
can [:for_order_cycle], EnterpriseFee
end
def add_order_management_abilities(user)
can [:index, :create], Spree::Order
can [:read, :update, :fire, :resend, :invoice, :print, :print_ticket], Spree::Order do |order|
# We allow editing orders with a nil distributor as this state occurs
# during the order creation process from the admin backend
order.distributor.nil? ||
# Enterprise User can access orders that they are a distributor for
user.enterprises.include?(order.distributor) ||
# Enterprise User can access orders that are placed inside a OC they coordinate
order.order_cycle.andand.coordinated_by?(user)
end
can [:admin, :bulk_management, :managed], Spree::Order do
user.admin? || user.enterprises.any?(&:is_distributor)
end
can [:admin, :create, :show, :poll], :invoice
can [:admin, :visible], Enterprise
can [:admin, :index, :create, :update, :destroy], :line_item
can [:admin, :index, :create], Spree::LineItem
can [:destroy, :update], Spree::LineItem do |item|
order = item.order
user.admin? || user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user)
end
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Payment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Shipment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::Adjustment
can [:admin, :index, :read, :create, :edit, :update, :fire], Spree::ReturnAuthorization
can [:destroy], Spree::Adjustment do |adjustment|
# Sharing code with destroying a line item. This should be unified and probably applied for other actions as well.
if user.admin?
true
elsif adjustment.adjustable.instance_of? Spree::Order
order = adjustment.adjustable
user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user)
elsif adjustment.adjustable.instance_of? Spree::LineItem
order = adjustment.adjustable.order
user.enterprises.include?(order.distributor) || order.order_cycle.andand.coordinated_by?(user)
end
end
can [:create], OrderCycle
can [:admin, :index, :read, :create, :edit, :update], ExchangeVariant
can [:admin, :index, :read, :create, :edit, :update], Exchange
can [:admin, :index, :read, :create, :edit, :update], ExchangeFee
# Enterprise user can only access payment and shipping methods for their distributors
can [:index, :create], Spree::PaymentMethod
can [:admin, :read, :update, :fire, :resend, :destroy, :show_provider_preferences], Spree::PaymentMethod do |payment_method|
(user.enterprises & payment_method.distributors).any?
end
can [:index, :create], Spree::ShippingMethod
can [:admin, :read, :update, :destroy], Spree::ShippingMethod do |shipping_method|
(user.enterprises & shipping_method.distributors).any?
end
# Reports page
can [:admin, :index, :customers, :group_buys, :sales_tax, :payments,
:orders_and_distributors, :orders_and_fulfillment, :products_and_inventory,
:order_cycle_management, :xero_invoices], Spree::Admin::ReportsController
add_bulk_coop_abilities
add_enterprise_fee_summary_abilities
can [:create], Customer
can [:admin, :index, :update, :destroy, :show], Customer, enterprise_id: Enterprise.managed_by(user).pluck(:id)
can [:admin, :new, :index], Subscription
can [:create, :edit, :update, :cancel, :pause, :unpause], Subscription do |subscription|
user.enterprises.include?(subscription.shop)
end
can [:admin, :build], SubscriptionLineItem
can [:destroy], SubscriptionLineItem do |subscription_line_item|
user.enterprises.include?(subscription_line_item.subscription.shop)
end
can [:admin, :edit, :cancel, :resume], ProxyOrder do |proxy_order|
user.enterprises.include?(proxy_order.subscription.shop)
end
end
def add_relationship_management_abilities(user)
can [:admin, :index, :create], EnterpriseRelationship
can [:destroy], EnterpriseRelationship do |enterprise_relationship|
user.enterprises.include? enterprise_relationship.parent
end
end
def add_bulk_coop_abilities
# Reveal the report link in spree/admin/reports#index
can [:bulk_coop], Spree::Admin::ReportsController
# Allow direct access to the report resource
can [:admin, :new, :create], :bulk_coop
end
def add_enterprise_fee_summary_abilities
# Reveal the report link in spree/admin/reports#index
can [:enterprise_fee_summary], Spree::Admin::ReportsController
# Allow direct access to the report resource
can [:admin, :new, :create], :enterprise_fee_summary
end
end
Spree::Ability.register_ability(AbilityDecorator)

View File

@@ -1,607 +0,0 @@
require 'spec_helper'
require "cancan/matchers"
require 'support/cancan_helper'
module Spree
describe User do
describe "broad permissions" do
subject { AbilityDecorator.new(user) }
include ::AbilityHelper
let(:user) { create(:user) }
let(:enterprise_any) { create(:enterprise, sells: 'any') }
let(:enterprise_own) { create(:enterprise, sells: 'own') }
let(:enterprise_none) { create(:enterprise, sells: 'none') }
let(:enterprise_any_producer) { create(:enterprise, sells: 'any', is_primary_producer: true) }
let(:enterprise_own_producer) { create(:enterprise, sells: 'own', is_primary_producer: true) }
let(:enterprise_none_producer) { create(:enterprise, sells: 'none', is_primary_producer: true) }
context "as manager of an enterprise who sells 'any'" do
before do
user.enterprise_roles.create! enterprise: enterprise_any
end
it { expect(subject.can_manage_products?(user)).to be true }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be true }
it { expect(subject.can_manage_order_cycles?(user)).to be true }
end
context "as manager of an enterprise who sell 'own'" do
before do
user.enterprise_roles.create! enterprise: enterprise_own
end
it { expect(subject.can_manage_products?(user)).to be true }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be true }
it { expect(subject.can_manage_order_cycles?(user)).to be true }
end
context "as manager of an enterprise who sells 'none'" do
before do
user.enterprise_roles.create! enterprise: enterprise_none
end
it { expect(subject.can_manage_products?(user)).to be false }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be false }
it { expect(subject.can_manage_order_cycles?(user)).to be false }
end
context "as manager of a producer enterprise who sells 'any'" do
before do
user.enterprise_roles.create! enterprise: enterprise_any_producer
end
it { expect(subject.can_manage_products?(user)).to be true }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be true }
it { expect(subject.can_manage_order_cycles?(user)).to be true }
end
context "as manager of a producer enterprise who sell 'own'" do
before do
user.enterprise_roles.create! enterprise: enterprise_own_producer
end
it { expect(subject.can_manage_products?(user)).to be true }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be true }
it { expect(subject.can_manage_order_cycles?(user)).to be true }
end
context "as manager of a producer enterprise who sells 'none'" do
before do
user.enterprise_roles.create! enterprise: enterprise_none_producer
end
context "as a non profile" do
before do
enterprise_none_producer.is_primary_producer = true
enterprise_none_producer.producer_profile_only = false
enterprise_none_producer.save!
end
it { expect(subject.can_manage_products?(user)).to be true }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be false }
it { expect(subject.can_manage_order_cycles?(user)).to be false }
end
context "as a profile" do
before do
enterprise_none_producer.is_primary_producer = true
enterprise_none_producer.producer_profile_only = true
enterprise_none_producer.save!
end
it { expect(subject.can_manage_products?(user)).to be false }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be false }
it { expect(subject.can_manage_order_cycles?(user)).to be false }
end
end
context "as a new user with no enterprises" do
it { expect(subject.can_manage_products?(user)).to be false }
it { expect(subject.can_manage_enterprises?(user)).to be false }
it { expect(subject.can_manage_orders?(user)).to be false }
it { expect(subject.can_manage_order_cycles?(user)).to be false }
it "can create enterprises straight off the bat" do
expect(subject.is_new_user?(user)).to be true
expect(user).to have_ability :create, for: Enterprise
end
end
end
describe 'Roles' do
# create enterprises
let(:s1) { create(:supplier_enterprise) }
let(:s2) { create(:supplier_enterprise) }
let(:s_related) { create(:supplier_enterprise) }
let(:d1) { create(:distributor_enterprise) }
let(:d2) { create(:distributor_enterprise) }
let(:p1) { create(:product, supplier: s1) }
let(:p2) { create(:product, supplier: s2) }
let(:p_related) { create(:product, supplier: s_related) }
let(:er1) { create(:enterprise_relationship, parent: s1, child: d1) }
let(:er2) { create(:enterprise_relationship, parent: d1, child: s1) }
let(:er_ps) { create(:enterprise_relationship, parent: s_related, child: s1, permissions_list: [:manage_products]) }
subject { user }
let(:user) { nil }
context "when is a supplier enterprise user" do
# create supplier_enterprise1 user without full admin access
let(:user) do
user = create(:user)
user.spree_roles = []
s1.enterprise_roles.build(user: user).save
user
end
let(:order) { create(:order) }
it "should be able to read/write their enterprises' products and variants" do
is_expected.to have_ability([:admin, :read, :update, :bulk_update, :clone, :destroy], for: p1)
is_expected.to have_ability([:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p1.master)
end
it "should be able to read/write related enterprises' products and variants with manage_products permission" do
er_ps
is_expected.to have_ability([:admin, :read, :update, :bulk_update, :clone, :destroy], for: p_related)
is_expected.to have_ability([:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p_related.master)
end
it "should not be able to read/write other enterprises' products and variants" do
is_expected.not_to have_ability([:admin, :read, :update, :bulk_update, :clone, :destroy], for: p2)
is_expected.not_to have_ability([:admin, :index, :read, :edit, :update, :search, :destroy], for: p2.master)
end
it "should not be able to access admin actions on orders" do
is_expected.not_to have_ability([:admin], for: Spree::Order)
end
it "should be able to create a new product" do
is_expected.to have_ability(:create, for: Spree::Product)
end
it "should be able to read/write their enterprises' product variants" do
is_expected.to have_ability([:create], for: Spree::Variant)
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :search, :update, :destroy, :delete], for: p1.master)
end
it "should not be able to read/write other enterprises' product variants" do
is_expected.not_to have_ability([:admin, :index, :read, :create, :edit, :search, :update, :destroy], for: p2.master)
end
it "should be able to read/write their enterprises' product properties" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update_positions, :destroy], for: Spree::ProductProperty)
end
it "should be able to read/write their enterprises' product images" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update, :destroy], for: Spree::Image)
end
it "should be able to read Taxons (in order to create classifications)" do
is_expected.to have_ability([:admin, :index, :read, :search], for: Spree::Taxon)
end
it "should be able to read/write Classifications on a product" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit], for: Spree::Classification)
end
it "should be able to read/write their enterprises' producer properties" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update_positions, :destroy], for: ProducerProperty)
end
it "should be able to read and create enterprise relationships" do
is_expected.to have_ability([:admin, :index, :create], for: EnterpriseRelationship)
end
it "should be able to destroy enterprise relationships for its enterprises" do
is_expected.to have_ability(:destroy, for: er1)
end
it "should not be able to destroy enterprise relationships for other enterprises" do
is_expected.not_to have_ability(:destroy, for: er2)
end
it "should be able to read some reports" do
is_expected.to have_ability([:admin, :index, :customers, :bulk_coop, :orders_and_fulfillment, :products_and_inventory, :order_cycle_management], for: Spree::Admin::ReportsController)
end
include_examples "allows access to Enterprise Fee Summary"
it "should not be able to read other reports" do
is_expected.not_to have_ability([:group_buys, :payments, :orders_and_distributors, :users_and_enterprises, :xero_invoices], for: Spree::Admin::ReportsController)
end
it "should not be able to access customer actions" do
is_expected.not_to have_ability([:admin, :index, :update], for: Customer)
end
describe "order_cycles abilities" do
context "where the enterprise is not in an order_cycle" do
let!(:order_cycle) { create(:simple_order_cycle) }
it "should not be able to access read/update order_cycle actions" do
is_expected.not_to have_ability([:admin, :index, :read, :edit, :update], for: order_cycle)
end
it "should not be able to access bulk_update, clone order cycle actions" do
is_expected.not_to have_ability([:bulk_update, :clone], for: order_cycle)
end
it "cannot request permitted enterprises for an order cycle" do
is_expected.not_to have_ability([:for_order_cycle], for: Enterprise)
end
it "cannot request permitted enterprise fees for an order cycle" do
is_expected.not_to have_ability([:for_order_cycle], for: EnterpriseFee)
end
end
context "where the enterprise is in an order_cycle" do
let!(:order_cycle) { create(:simple_order_cycle) }
let!(:exchange){ create(:exchange, incoming: true, order_cycle: order_cycle, receiver: order_cycle.coordinator, sender: s1) }
it "should be able to access read/update order cycle actions" do
is_expected.to have_ability([:admin, :index, :read, :edit, :update], for: order_cycle)
end
it "should not be able to access bulk/update, clone order cycle actions" do
is_expected.not_to have_ability([:bulk_update, :clone], for: order_cycle)
end
it "can request permitted enterprises for an order cycle" do
is_expected.to have_ability([:for_order_cycle], for: Enterprise)
end
it "can request permitted enterprise fees for an order cycle" do
is_expected.to have_ability([:for_order_cycle], for: EnterpriseFee)
end
end
end
end
context "when is a distributor enterprise user" do
# create distributor_enterprise1 user without full admin access
let(:user) do
user = create(:user)
user.spree_roles = []
d1.enterprise_roles.build(user: user).save
user
end
# create order for each enterprise
let(:o1) do
o = create(:order, distributor: d1, bill_address: create(:address))
create(:line_item, order: o, product: p1)
o
end
let(:o2) do
o = create(:order, distributor: d2, bill_address: create(:address))
create(:line_item, order: o, product: p1)
o
end
let(:o3) do
o = create(:order, distributor: nil, bill_address: create(:address))
create(:line_item, order: o, product: p1)
o
end
describe "editing enterprises" do
let!(:d_related) { create(:distributor_enterprise) }
let!(:er_pd) { create(:enterprise_relationship, parent: d_related, child: d1, permissions_list: [:edit_profile]) }
it "should be able to edit enterprises it manages" do
is_expected.to have_ability([:read, :edit, :update, :remove_logo, :remove_promo_image, :remove_terms_and_conditions, :bulk_update, :resend_confirmation], for: d1)
end
it "should be able to edit enterprises it has permission to" do
is_expected.to have_ability([:read, :edit, :update, :remove_logo, :remove_promo_image, :remove_terms_and_conditions, :bulk_update, :resend_confirmation], for: d_related)
end
it "should be able to manage shipping methods, payment methods and enterprise fees for enterprises it manages" do
is_expected.to have_ability([:manage_shipping_methods, :manage_payment_methods, :manage_enterprise_fees], for: d1)
end
it "should not be able to manage shipping methods, payment methods and enterprise fees for enterprises it has edit profile permission to" do
is_expected.not_to have_ability([:manage_shipping_methods, :manage_payment_methods, :manage_enterprise_fees], for: d_related)
end
end
describe "variant overrides" do
let(:vo1) { create(:variant_override, hub: d1, variant: p1.master) }
let(:vo2) { create(:variant_override, hub: d1, variant: p2.master) }
let(:vo3) { create(:variant_override, hub: d2, variant: p1.master) }
let(:vo4) { create(:variant_override, hub: d2, variant: p2.master) }
let!(:er1) { create(:enterprise_relationship, parent: s1, child: d1, permissions_list: [:create_variant_overrides]) }
it "should be able to access variant overrides page" do
is_expected.to have_ability([:admin, :index, :bulk_update, :bulk_reset], for: VariantOverride)
end
it "should be able to read/write their own variant overrides" do
is_expected.to have_ability([:admin, :index, :read, :update], for: vo1)
end
it "should not be able to read/write variant overrides when producer of product hasn't granted permission" do
is_expected.not_to have_ability([:admin, :index, :read, :update], for: vo2)
end
it "should not be able to read/write variant overrides when we can't add hub to order cycle" do
is_expected.not_to have_ability([:admin, :index, :read, :update], for: vo3)
end
it "should not be able to read/write other enterprises' variant overrides" do
is_expected.not_to have_ability([:admin, :index, :read, :update], for: vo4)
end
end
it "should be able to read/write their enterprises' orders" do
is_expected.to have_ability([:admin, :index, :read, :edit], for: o1)
end
it "should not be able to read/write other enterprises' orders" do
is_expected.not_to have_ability([:admin, :index, :read, :edit], for: o2)
end
it "should be able to read/write orders that are in the process of being created" do
is_expected.to have_ability([:admin, :index, :read, :edit], for: o3)
end
it "should be able to create and search on nil (required for creating an order)" do
is_expected.to have_ability([:create, :search], for: nil)
end
it "should be able to create a new order" do
is_expected.to have_ability([:admin, :index, :read, :create, :update], for: Spree::Order)
end
it "should be able to create a new line item" do
is_expected.to have_ability([:admin, :create], for: Spree::LineItem)
end
it "should be able to read/write Payments on a product" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::Payment)
end
it "should be able to read/write Shipments on a product" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::Shipment)
end
it "should be able to read/write Adjustments on a product" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::Adjustment)
end
it "should be able to read/write ReturnAuthorizations on a product" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::ReturnAuthorization)
end
it "should be able to read/write PaymentMethods" do
is_expected.to have_ability([:admin, :index, :create, :update, :destroy], for: Spree::PaymentMethod)
end
it "should be able to read/write ShippingMethods" do
is_expected.to have_ability([:admin, :index, :create, :update, :destroy], for: Spree::ShippingMethod)
end
it "should be able to read and create enterprise relationships" do
is_expected.to have_ability([:admin, :index, :create], for: EnterpriseRelationship)
end
it "should be able to destroy enterprise relationships for its enterprises" do
is_expected.to have_ability(:destroy, for: er2)
end
it "should not be able to destroy enterprise relationships for other enterprises" do
is_expected.not_to have_ability(:destroy, for: er1)
end
it "should be able to read some reports" do
is_expected.to have_ability([:admin, :index, :customers, :sales_tax, :group_buys, :bulk_coop, :payments, :orders_and_distributors, :orders_and_fulfillment, :products_and_inventory, :order_cycle_management, :xero_invoices], for: Spree::Admin::ReportsController)
end
include_examples "allows access to Enterprise Fee Summary"
it "should not be able to read other reports" do
is_expected.not_to have_ability([:users_and_enterprises], for: Spree::Admin::ReportsController)
end
it "should be able to access customer actions" do
is_expected.to have_ability([:admin, :index, :update], for: Customer)
end
context "for a given order_cycle" do
let!(:order_cycle) { create(:simple_order_cycle) }
let!(:exchange){ create(:exchange, incoming: false, order_cycle: order_cycle, receiver: d1, sender: order_cycle.coordinator) }
it "should be able to access read and update order cycle actions" do
is_expected.to have_ability([:admin, :index, :read, :edit, :update], for: order_cycle)
end
it "should not be able to access bulk_update, clone order cycle actions" do
is_expected.not_to have_ability([:bulk_update, :clone], for: order_cycle)
end
end
it "can request permitted enterprises for an order cycle" do
is_expected.to have_ability([:for_order_cycle], for: Enterprise)
end
it "can request permitted enterprise fees for an order cycle" do
is_expected.to have_ability([:for_order_cycle], for: EnterpriseFee)
end
end
context 'Order Cycle co-ordinator, distributor enterprise manager' do
let(:user) do
user = create(:user)
user.spree_roles = []
d1.enterprise_roles.build(user: user).save
user
end
let(:oc1) { create(:simple_order_cycle, coordinator: d1) }
let(:oc2) { create(:simple_order_cycle) }
it "should be able to read/write OrderCycles they are the co-ordinator of" do
is_expected.to have_ability([:admin, :index, :read, :edit, :update, :bulk_update, :clone, :destroy], for: oc1)
end
it "should not be able to read/write OrderCycles they are not the co-ordinator of" do
should_not have_ability([:admin, :index, :read, :create, :edit, :update, :bulk_update, :clone, :destroy], for: oc2)
end
it "should be able to create OrderCycles" do
is_expected.to have_ability([:create], for: OrderCycle)
end
it "should be able to read/write EnterpriseFees" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :bulk_update, :destroy, :for_order_cycle], for: EnterpriseFee)
end
it "should be able to add enterprises to order cycles" do
is_expected.to have_ability([:admin, :index, :for_order_cycle, :create], for: Enterprise)
end
end
context 'enterprise manager' do
let(:user) do
user = create(:user)
user.spree_roles = []
s1.enterprise_roles.build(user: user).save
user
end
it 'should have the ability to view the admin account page' do
is_expected.to have_ability([:admin, :show], for: :account)
end
it 'should have the ability to read and edit enterprises that I manage' do
is_expected.to have_ability([:read, :edit, :update, :bulk_update], for: s1)
end
it 'should not have the ability to read and edit enterprises that I do not manage' do
is_expected.not_to have_ability([:read, :edit, :update, :bulk_update], for: s2)
end
it 'should not have the ability to welcome and register enterprises that I do not own' do
is_expected.not_to have_ability([:welcome, :register], for: s1)
end
it 'should have the ability administrate and create enterpises' do
is_expected.to have_ability([:admin, :index, :create], for: Enterprise)
end
it "should have the ability to search for users which share management of its enterprises" do
is_expected.to have_ability([:admin, :known_users, :customers], for: :search)
is_expected.not_to have_ability([:users], for: :search)
end
end
context 'enterprise owner' do
let(:user) { s1.owner }
it 'should have the ability to welcome and register enterprises that I own' do
is_expected.to have_ability([:welcome, :register], for: s1)
end
it 'should have the ability to view the admin account page' do
is_expected.to have_ability([:admin, :show], for: :account)
end
end
end
describe "permissions for variant overrides" do
let!(:distributor) { create(:distributor_enterprise) }
let!(:producer) { create(:supplier_enterprise) }
let!(:product) { create(:product, supplier: producer) }
let!(:variant) { create(:variant, product: product) }
let!(:variant_override) { create(:variant_override, hub: distributor, variant: variant) }
subject { user }
let(:manage_actions) { [:admin, :index, :read, :update, :bulk_update, :bulk_reset] }
describe "when admin" do
let(:user) { create(:admin_user) }
it "should have permission" do
is_expected.to have_ability(manage_actions, for: variant_override)
end
end
describe "when user of the producer" do
let(:user) { producer.owner }
it "should not have permission" do
is_expected.not_to have_ability(manage_actions, for: variant_override)
end
end
describe "when user of the distributor" do
let(:user) { distributor.owner }
it "should not have permission" do
is_expected.not_to have_ability(manage_actions, for: variant_override)
end
end
describe "when user of the distributor which is also the producer" do
let(:user) { distributor.owner }
let!(:distributor) { create(:distributor_enterprise, is_primary_producer: true, sells: "any") }
let!(:producer) { distributor }
it "should have permission" do
is_expected.to have_ability(manage_actions, for: variant_override)
end
end
describe "when owner of the distributor with add_to_order_cycle permission to the producer" do
let!(:unauthorized_enterprise) do
create(:enterprise, sells: "any").tap do |record|
create(:enterprise_relationship, parent: producer, child: record, permissions_list: [:add_to_order_cycle])
end
end
let(:user) { unauthorized_enterprise.owner }
it "should not have permission" do
is_expected.not_to have_ability(manage_actions, for: variant_override)
end
end
describe "when owner of the enterprise with create_variant_overrides permission to the producer" do
let!(:authorized_enterprise) do
create(:enterprise, sells: "any").tap do |record|
create(:enterprise_relationship, parent: producer, child: record, permissions_list: [:create_variant_overrides])
end
end
let(:user) { authorized_enterprise.owner }
it "should not have permission" do
is_expected.not_to have_ability(manage_actions, for: variant_override)
end
describe "when the enterprise is not a distributor" do
let!(:authorized_enterprise) do
create(:enterprise, sells: "none").tap do |record|
create(:enterprise_relationship, parent: producer, child: record, permissions_list: [:create_variant_overrides])
end
end
it "should not have permission" do
is_expected.not_to have_ability(manage_actions, for: variant_override)
end
end
end
end
end
end

View File

@@ -2,23 +2,11 @@ require 'spec_helper'
require 'cancan/matchers'
require 'support/ability_helpers'
# Fake ability for testing registration of additional abilities
class FooAbility
include CanCan::Ability
def initialize(_user)
# allow anyone to perform index on Order
can :index, Spree::Order
# allow anyone to update an Order with id of 1
can :update, Spree::Order do |order|
order.id == 1
end
end
end
describe Spree::Ability do
include ::AbilityHelper
let(:user) { create(:user) }
let(:ability) { Spree::Ability.new(user) }
let(:subject) { Spree::Ability.new(user) }
let(:token) { nil }
before do
@@ -28,22 +16,9 @@ describe Spree::Ability do
TOKEN = 'token123'.freeze
after(:each) {
Spree::Ability.abilities = Set.new
user.spree_roles = []
}
context 'register_ability' do
it 'should add the ability to the list of abilties' do
Spree::Ability.register_ability(FooAbility)
expect(Spree::Ability.new(user).abilities).to_not be_empty
end
it 'should apply the registered abilities permissions' do
Spree::Ability.register_ability(FooAbility)
expect(Spree::Ability.new(user).can?(:update, build(:order, id: 1))).to be_truthy
end
end
context 'for general resource' do
let(:resource) { Object.new }
@@ -71,61 +46,19 @@ describe Spree::Ability do
context 'with admin user' do
it 'should be able to admin' do
user.spree_roles << Spree::Role.find_or_create_by(name: 'admin')
expect(ability).to be_able_to :admin, resource
expect(ability).to be_able_to :index, resource_order
expect(ability).to be_able_to :show, resource_product
expect(ability).to be_able_to :create, resource_user
end
end
context 'with fakedispatch user' do
class BarAbility
include CanCan::Ability
def initialize(user)
user ||= Spree::User.new
return unless user.has_spree_role?('bar')
can [:admin, :index, :show], Spree::Order
end
end
it 'should be able to admin on the order and shipment pages' do
user.spree_roles << Spree::Role.find_or_create_by(name: 'bar')
Spree::Ability.register_ability(BarAbility)
expect(ability).to_not be_able_to :admin, resource
expect(ability).to be_able_to :admin, resource_order
expect(ability).to be_able_to :index, resource_order
expect(ability).to_not be_able_to :update, resource_order
expect(ability).to be_able_to :admin, resource_shipment
expect(ability).to be_able_to :index, resource_shipment
expect(ability).to be_able_to :create, resource_shipment
expect(ability).to_not be_able_to :admin, resource_product
expect(ability).to_not be_able_to :update, resource_product
expect(ability).to_not be_able_to :admin, resource_user
expect(ability).to_not be_able_to :update, resource_user
expect(ability).to be_able_to :update, user
# It can create new users if is has access to the :admin, User!!
# TODO change the Ability class so only users and customers get the extra premissions?
Spree::Ability.remove_ability(BarAbility)
expect(subject).to be_able_to :admin, resource
expect(subject).to be_able_to :index, resource_order
expect(subject).to be_able_to :show, resource_product
expect(subject).to be_able_to :create, resource_user
end
end
context 'with customer' do
it 'should not be able to admin' do
expect(ability).to_not be_able_to :admin, resource
expect(ability).to_not be_able_to :admin, resource_order
expect(ability).to_not be_able_to :admin, resource_product
expect(ability).to_not be_able_to :admin, resource_user
expect(subject).to_not be_able_to :admin, resource
expect(subject).to_not be_able_to :admin, resource_order
expect(subject).to_not be_able_to :admin, resource_product
expect(subject).to_not be_able_to :admin, resource_user
end
end
end
@@ -269,4 +202,600 @@ describe Spree::Ability do
end
end
end
describe "broad permissions" do
let(:user) { create(:user) }
let(:enterprise_any) { create(:enterprise, sells: 'any') }
let(:enterprise_own) { create(:enterprise, sells: 'own') }
let(:enterprise_none) { create(:enterprise, sells: 'none') }
let(:enterprise_any_producer) { create(:enterprise, sells: 'any', is_primary_producer: true) }
let(:enterprise_own_producer) { create(:enterprise, sells: 'own', is_primary_producer: true) }
let(:enterprise_none_producer) { create(:enterprise, sells: 'none', is_primary_producer: true) }
context "as manager of an enterprise who sells 'any'" do
before do
user.enterprise_roles.create! enterprise: enterprise_any
end
it { expect(subject.can_manage_products?(user)).to be true }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be true }
it { expect(subject.can_manage_order_cycles?(user)).to be true }
end
context "as manager of an enterprise who sell 'own'" do
before do
user.enterprise_roles.create! enterprise: enterprise_own
end
it { expect(subject.can_manage_products?(user)).to be true }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be true }
it { expect(subject.can_manage_order_cycles?(user)).to be true }
end
context "as manager of an enterprise who sells 'none'" do
before do
user.enterprise_roles.create! enterprise: enterprise_none
end
it { expect(subject.can_manage_products?(user)).to be false }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be false }
it { expect(subject.can_manage_order_cycles?(user)).to be false }
end
context "as manager of a producer enterprise who sells 'any'" do
before do
user.enterprise_roles.create! enterprise: enterprise_any_producer
end
it { expect(subject.can_manage_products?(user)).to be true }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be true }
it { expect(subject.can_manage_order_cycles?(user)).to be true }
end
context "as manager of a producer enterprise who sell 'own'" do
before do
user.enterprise_roles.create! enterprise: enterprise_own_producer
end
it { expect(subject.can_manage_products?(user)).to be true }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be true }
it { expect(subject.can_manage_order_cycles?(user)).to be true }
end
context "as manager of a producer enterprise who sells 'none'" do
before do
user.enterprise_roles.create! enterprise: enterprise_none_producer
end
context "as a non profile" do
before do
enterprise_none_producer.is_primary_producer = true
enterprise_none_producer.producer_profile_only = false
enterprise_none_producer.save!
end
it { expect(subject.can_manage_products?(user)).to be true }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be false }
it { expect(subject.can_manage_order_cycles?(user)).to be false }
end
context "as a profile" do
before do
enterprise_none_producer.is_primary_producer = true
enterprise_none_producer.producer_profile_only = true
enterprise_none_producer.save!
end
it { expect(subject.can_manage_products?(user)).to be false }
it { expect(subject.can_manage_enterprises?(user)).to be true }
it { expect(subject.can_manage_orders?(user)).to be false }
it { expect(subject.can_manage_order_cycles?(user)).to be false }
end
end
context "as a new user with no enterprises" do
it { expect(subject.can_manage_products?(user)).to be false }
it { expect(subject.can_manage_enterprises?(user)).to be false }
it { expect(subject.can_manage_orders?(user)).to be false }
it { expect(subject.can_manage_order_cycles?(user)).to be false }
it "can create enterprises straight off the bat" do
expect(subject.is_new_user?(user)).to be true
expect(user).to have_ability :create, for: Enterprise
end
end
end
describe 'Roles' do
# create enterprises
let(:s1) { create(:supplier_enterprise) }
let(:s2) { create(:supplier_enterprise) }
let(:s_related) { create(:supplier_enterprise) }
let(:d1) { create(:distributor_enterprise) }
let(:d2) { create(:distributor_enterprise) }
let(:p1) { create(:product, supplier: s1) }
let(:p2) { create(:product, supplier: s2) }
let(:p_related) { create(:product, supplier: s_related) }
let(:er1) { create(:enterprise_relationship, parent: s1, child: d1) }
let(:er2) { create(:enterprise_relationship, parent: d1, child: s1) }
let(:er_ps) { create(:enterprise_relationship, parent: s_related, child: s1, permissions_list: [:manage_products]) }
subject { user }
let(:user) { nil }
context "when is a supplier enterprise user" do
# create supplier_enterprise1 user without full admin access
let(:user) do
user = create(:user)
user.spree_roles = []
s1.enterprise_roles.build(user: user).save
user
end
let(:order) { create(:order) }
it "should be able to read/write their enterprises' products and variants" do
is_expected.to have_ability([:admin, :read, :update, :bulk_update, :clone, :destroy], for: p1)
is_expected.to have_ability([:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p1.master)
end
it "should be able to read/write related enterprises' products and variants with manage_products permission" do
er_ps
is_expected.to have_ability([:admin, :read, :update, :bulk_update, :clone, :destroy], for: p_related)
is_expected.to have_ability([:admin, :index, :read, :edit, :update, :search, :destroy, :delete], for: p_related.master)
end
it "should not be able to read/write other enterprises' products and variants" do
is_expected.not_to have_ability([:admin, :read, :update, :bulk_update, :clone, :destroy], for: p2)
is_expected.not_to have_ability([:admin, :index, :read, :edit, :update, :search, :destroy], for: p2.master)
end
it "should not be able to access admin actions on orders" do
is_expected.not_to have_ability([:admin], for: Spree::Order)
end
it "should be able to create a new product" do
is_expected.to have_ability(:create, for: Spree::Product)
end
it "should be able to read/write their enterprises' product variants" do
is_expected.to have_ability([:create], for: Spree::Variant)
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :search, :update, :destroy, :delete], for: p1.master)
end
it "should not be able to read/write other enterprises' product variants" do
is_expected.not_to have_ability([:admin, :index, :read, :create, :edit, :search, :update, :destroy], for: p2.master)
end
it "should be able to read/write their enterprises' product properties" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update_positions, :destroy], for: Spree::ProductProperty)
end
it "should be able to read/write their enterprises' product images" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update, :destroy], for: Spree::Image)
end
it "should be able to read Taxons (in order to create classifications)" do
is_expected.to have_ability([:admin, :index, :read, :search], for: Spree::Taxon)
end
it "should be able to read/write Classifications on a product" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit], for: Spree::Classification)
end
it "should be able to read/write their enterprises' producer properties" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update_positions, :destroy], for: ProducerProperty)
end
it "should be able to read and create enterprise relationships" do
is_expected.to have_ability([:admin, :index, :create], for: EnterpriseRelationship)
end
it "should be able to destroy enterprise relationships for its enterprises" do
is_expected.to have_ability(:destroy, for: er1)
end
it "should not be able to destroy enterprise relationships for other enterprises" do
is_expected.not_to have_ability(:destroy, for: er2)
end
it "should be able to read some reports" do
is_expected.to have_ability([:admin, :index, :customers, :bulk_coop, :orders_and_fulfillment, :products_and_inventory, :order_cycle_management], for: Spree::Admin::ReportsController)
end
include_examples "allows access to Enterprise Fee Summary"
it "should not be able to read other reports" do
is_expected.not_to have_ability([:group_buys, :payments, :orders_and_distributors, :users_and_enterprises, :xero_invoices], for: Spree::Admin::ReportsController)
end
it "should not be able to access customer actions" do
is_expected.not_to have_ability([:admin, :index, :update], for: Customer)
end
describe "order_cycles abilities" do
context "where the enterprise is not in an order_cycle" do
let!(:order_cycle) { create(:simple_order_cycle) }
it "should not be able to access read/update order_cycle actions" do
is_expected.not_to have_ability([:admin, :index, :read, :edit, :update], for: order_cycle)
end
it "should not be able to access bulk_update, clone order cycle actions" do
is_expected.not_to have_ability([:bulk_update, :clone], for: order_cycle)
end
it "cannot request permitted enterprises for an order cycle" do
is_expected.not_to have_ability([:for_order_cycle], for: Enterprise)
end
it "cannot request permitted enterprise fees for an order cycle" do
is_expected.not_to have_ability([:for_order_cycle], for: EnterpriseFee)
end
end
context "where the enterprise is in an order_cycle" do
let!(:order_cycle) { create(:simple_order_cycle) }
let!(:exchange){ create(:exchange, incoming: true, order_cycle: order_cycle, receiver: order_cycle.coordinator, sender: s1) }
it "should be able to access read/update order cycle actions" do
is_expected.to have_ability([:admin, :index, :read, :edit, :update], for: order_cycle)
end
it "should not be able to access bulk/update, clone order cycle actions" do
is_expected.not_to have_ability([:bulk_update, :clone], for: order_cycle)
end
it "can request permitted enterprises for an order cycle" do
is_expected.to have_ability([:for_order_cycle], for: Enterprise)
end
it "can request permitted enterprise fees for an order cycle" do
is_expected.to have_ability([:for_order_cycle], for: EnterpriseFee)
end
end
end
end
context "when is a distributor enterprise user" do
# create distributor_enterprise1 user without full admin access
let(:user) do
user = create(:user)
user.spree_roles = []
d1.enterprise_roles.build(user: user).save
user
end
# create order for each enterprise
let(:o1) do
o = create(:order, distributor: d1, bill_address: create(:address))
create(:line_item, order: o, product: p1)
o
end
let(:o2) do
o = create(:order, distributor: d2, bill_address: create(:address))
create(:line_item, order: o, product: p1)
o
end
let(:o3) do
o = create(:order, distributor: nil, bill_address: create(:address))
create(:line_item, order: o, product: p1)
o
end
describe "editing enterprises" do
let!(:d_related) { create(:distributor_enterprise) }
let!(:er_pd) { create(:enterprise_relationship, parent: d_related, child: d1, permissions_list: [:edit_profile]) }
it "should be able to edit enterprises it manages" do
is_expected.to have_ability([:read, :edit, :update, :remove_logo, :remove_promo_image, :remove_terms_and_conditions, :bulk_update, :resend_confirmation], for: d1)
end
it "should be able to edit enterprises it has permission to" do
is_expected.to have_ability([:read, :edit, :update, :remove_logo, :remove_promo_image, :remove_terms_and_conditions, :bulk_update, :resend_confirmation], for: d_related)
end
it "should be able to manage shipping methods, payment methods and enterprise fees for enterprises it manages" do
is_expected.to have_ability([:manage_shipping_methods, :manage_payment_methods, :manage_enterprise_fees], for: d1)
end
it "should not be able to manage shipping methods, payment methods and enterprise fees for enterprises it has edit profile permission to" do
is_expected.not_to have_ability([:manage_shipping_methods, :manage_payment_methods, :manage_enterprise_fees], for: d_related)
end
end
describe "variant overrides" do
let(:vo1) { create(:variant_override, hub: d1, variant: p1.master) }
let(:vo2) { create(:variant_override, hub: d1, variant: p2.master) }
let(:vo3) { create(:variant_override, hub: d2, variant: p1.master) }
let(:vo4) { create(:variant_override, hub: d2, variant: p2.master) }
let!(:er1) { create(:enterprise_relationship, parent: s1, child: d1, permissions_list: [:create_variant_overrides]) }
it "should be able to access variant overrides page" do
is_expected.to have_ability([:admin, :index, :bulk_update, :bulk_reset], for: VariantOverride)
end
it "should be able to read/write their own variant overrides" do
is_expected.to have_ability([:admin, :index, :read, :update], for: vo1)
end
it "should not be able to read/write variant overrides when producer of product hasn't granted permission" do
is_expected.not_to have_ability([:admin, :index, :read, :update], for: vo2)
end
it "should not be able to read/write variant overrides when we can't add hub to order cycle" do
is_expected.not_to have_ability([:admin, :index, :read, :update], for: vo3)
end
it "should not be able to read/write other enterprises' variant overrides" do
is_expected.not_to have_ability([:admin, :index, :read, :update], for: vo4)
end
end
it "should be able to read/write their enterprises' orders" do
is_expected.to have_ability([:admin, :index, :read, :edit], for: o1)
end
it "should not be able to read/write other enterprises' orders" do
is_expected.not_to have_ability([:admin, :index, :read, :edit], for: o2)
end
it "should be able to read/write orders that are in the process of being created" do
is_expected.to have_ability([:admin, :index, :read, :edit], for: o3)
end
it "should be able to create and search on nil (required for creating an order)" do
is_expected.to have_ability([:create, :search], for: nil)
end
it "should be able to create a new order" do
is_expected.to have_ability([:admin, :index, :read, :create, :update], for: Spree::Order)
end
it "should be able to create a new line item" do
is_expected.to have_ability([:admin, :create], for: Spree::LineItem)
end
it "should be able to read/write Payments on a product" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::Payment)
end
it "should be able to read/write Shipments on a product" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::Shipment)
end
it "should be able to read/write Adjustments on a product" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::Adjustment)
end
it "should be able to read/write ReturnAuthorizations on a product" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :update, :fire], for: Spree::ReturnAuthorization)
end
it "should be able to read/write PaymentMethods" do
is_expected.to have_ability([:admin, :index, :create, :update, :destroy], for: Spree::PaymentMethod)
end
it "should be able to read/write ShippingMethods" do
is_expected.to have_ability([:admin, :index, :create, :update, :destroy], for: Spree::ShippingMethod)
end
it "should be able to read and create enterprise relationships" do
is_expected.to have_ability([:admin, :index, :create], for: EnterpriseRelationship)
end
it "should be able to destroy enterprise relationships for its enterprises" do
is_expected.to have_ability(:destroy, for: er2)
end
it "should not be able to destroy enterprise relationships for other enterprises" do
is_expected.not_to have_ability(:destroy, for: er1)
end
it "should be able to read some reports" do
is_expected.to have_ability([:admin, :index, :customers, :sales_tax, :group_buys, :bulk_coop, :payments, :orders_and_distributors, :orders_and_fulfillment, :products_and_inventory, :order_cycle_management, :xero_invoices], for: Spree::Admin::ReportsController)
end
include_examples "allows access to Enterprise Fee Summary"
it "should not be able to read other reports" do
is_expected.not_to have_ability([:users_and_enterprises], for: Spree::Admin::ReportsController)
end
it "should be able to access customer actions" do
is_expected.to have_ability([:admin, :index, :update], for: Customer)
end
context "for a given order_cycle" do
let!(:order_cycle) { create(:simple_order_cycle) }
let!(:exchange){ create(:exchange, incoming: false, order_cycle: order_cycle, receiver: d1, sender: order_cycle.coordinator) }
it "should be able to access read and update order cycle actions" do
is_expected.to have_ability([:admin, :index, :read, :edit, :update], for: order_cycle)
end
it "should not be able to access bulk_update, clone order cycle actions" do
is_expected.not_to have_ability([:bulk_update, :clone], for: order_cycle)
end
end
it "can request permitted enterprises for an order cycle" do
is_expected.to have_ability([:for_order_cycle], for: Enterprise)
end
it "can request permitted enterprise fees for an order cycle" do
is_expected.to have_ability([:for_order_cycle], for: EnterpriseFee)
end
end
context 'Order Cycle co-ordinator, distributor enterprise manager' do
let(:user) do
user = create(:user)
user.spree_roles = []
d1.enterprise_roles.build(user: user).save
user
end
let(:oc1) { create(:simple_order_cycle, coordinator: d1) }
let(:oc2) { create(:simple_order_cycle) }
it "should be able to read/write OrderCycles they are the co-ordinator of" do
is_expected.to have_ability([:admin, :index, :read, :edit, :update, :bulk_update, :clone, :destroy], for: oc1)
end
it "should not be able to read/write OrderCycles they are not the co-ordinator of" do
should_not have_ability([:admin, :index, :read, :create, :edit, :update, :bulk_update, :clone, :destroy], for: oc2)
end
it "should be able to create OrderCycles" do
is_expected.to have_ability([:create], for: OrderCycle)
end
it "should be able to read/write EnterpriseFees" do
is_expected.to have_ability([:admin, :index, :read, :create, :edit, :bulk_update, :destroy, :for_order_cycle], for: EnterpriseFee)
end
it "should be able to add enterprises to order cycles" do
is_expected.to have_ability([:admin, :index, :for_order_cycle, :create], for: Enterprise)
end
end
context 'enterprise manager' do
let(:user) do
user = create(:user)
user.spree_roles = []
s1.enterprise_roles.build(user: user).save
user
end
it 'should have the ability to view the admin account page' do
is_expected.to have_ability([:admin, :show], for: :account)
end
it 'should have the ability to read and edit enterprises that I manage' do
is_expected.to have_ability([:read, :edit, :update, :bulk_update], for: s1)
end
it 'should not have the ability to read and edit enterprises that I do not manage' do
is_expected.not_to have_ability([:read, :edit, :update, :bulk_update], for: s2)
end
it 'should not have the ability to welcome and register enterprises that I do not own' do
is_expected.not_to have_ability([:welcome, :register], for: s1)
end
it 'should have the ability administrate and create enterpises' do
is_expected.to have_ability([:admin, :index, :create], for: Enterprise)
end
it "should have the ability to search for users which share management of its enterprises" do
is_expected.to have_ability([:admin, :known_users, :customers], for: :search)
is_expected.not_to have_ability([:users], for: :search)
end
end
context 'enterprise owner' do
let(:user) { s1.owner }
it 'should have the ability to welcome and register enterprises that I own' do
is_expected.to have_ability([:welcome, :register], for: s1)
end
it 'should have the ability to view the admin account page' do
is_expected.to have_ability([:admin, :show], for: :account)
end
end
end
describe "permissions for variant overrides" do
let!(:distributor) { create(:distributor_enterprise) }
let!(:producer) { create(:supplier_enterprise) }
let!(:product) { create(:product, supplier: producer) }
let!(:variant) { create(:variant, product: product) }
let!(:variant_override) { create(:variant_override, hub: distributor, variant: variant) }
subject { user }
let(:manage_actions) { [:admin, :index, :read, :update, :bulk_update, :bulk_reset] }
describe "when admin" do
let(:user) { create(:admin_user) }
it "should have permission" do
is_expected.to have_ability(manage_actions, for: variant_override)
end
end
describe "when user of the producer" do
let(:user) { producer.owner }
it "should not have permission" do
is_expected.not_to have_ability(manage_actions, for: variant_override)
end
end
describe "when user of the distributor" do
let(:user) { distributor.owner }
it "should not have permission" do
is_expected.not_to have_ability(manage_actions, for: variant_override)
end
end
describe "when user of the distributor which is also the producer" do
let(:user) { distributor.owner }
let!(:distributor) { create(:distributor_enterprise, is_primary_producer: true, sells: "any") }
let!(:producer) { distributor }
it "should have permission" do
is_expected.to have_ability(manage_actions, for: variant_override)
end
end
describe "when owner of the distributor with add_to_order_cycle permission to the producer" do
let!(:unauthorized_enterprise) do
create(:enterprise, sells: "any").tap do |record|
create(:enterprise_relationship, parent: producer, child: record, permissions_list: [:add_to_order_cycle])
end
end
let(:user) { unauthorized_enterprise.owner }
it "should not have permission" do
is_expected.not_to have_ability(manage_actions, for: variant_override)
end
end
describe "when owner of the enterprise with create_variant_overrides permission to the producer" do
let!(:authorized_enterprise) do
create(:enterprise, sells: "any").tap do |record|
create(:enterprise_relationship, parent: producer, child: record, permissions_list: [:create_variant_overrides])
end
end
let(:user) { authorized_enterprise.owner }
it "should not have permission" do
is_expected.not_to have_ability(manage_actions, for: variant_override)
end
describe "when the enterprise is not a distributor" do
let!(:authorized_enterprise) do
create(:enterprise, sells: "none").tap do |record|
create(:enterprise_relationship, parent: producer, child: record, permissions_list: [:create_variant_overrides])
end
end
it "should not have permission" do
is_expected.not_to have_ability(manage_actions, for: variant_override)
end
end
end
end
end

View File

@@ -2,106 +2,106 @@
shared_examples_for 'access granted' do
it 'should allow read' do
expect(ability).to be_able_to(:read, resource, token) if token
expect(ability).to be_able_to(:read, resource) unless token
expect(subject).to be_able_to(:read, resource, token) if token
expect(subject).to be_able_to(:read, resource) unless token
end
it 'should allow create' do
expect(ability).to be_able_to(:create, resource, token) if token
expect(ability).to be_able_to(:create, resource) unless token
expect(subject).to be_able_to(:create, resource, token) if token
expect(subject).to be_able_to(:create, resource) unless token
end
it 'should allow update' do
expect(ability).to be_able_to(:update, resource, token) if token
expect(ability).to be_able_to(:update, resource) unless token
expect(subject).to be_able_to(:update, resource, token) if token
expect(subject).to be_able_to(:update, resource) unless token
end
end
shared_examples_for 'access denied' do
it 'should not allow read' do
expect(ability).to_not be_able_to(:read, resource)
expect(subject).to_not be_able_to(:read, resource)
end
it 'should not allow create' do
expect(ability).to_not be_able_to(:create, resource)
expect(subject).to_not be_able_to(:create, resource)
end
it 'should not allow update' do
expect(ability).to_not be_able_to(:update, resource)
expect(subject).to_not be_able_to(:update, resource)
end
end
shared_examples_for 'admin granted' do
it 'should allow admin' do
expect(ability).to be_able_to(:admin, resource, token) if token
expect(ability).to be_able_to(:admin, resource) unless token
expect(subject).to be_able_to(:admin, resource, token) if token
expect(subject).to be_able_to(:admin, resource) unless token
end
end
shared_examples_for 'admin denied' do
it 'should not allow admin' do
expect(ability).to_not be_able_to(:admin, resource)
expect(subject).to_not be_able_to(:admin, resource)
end
end
shared_examples_for 'index allowed' do
it 'should allow index' do
expect(ability).to be_able_to(:index, resource)
expect(subject).to be_able_to(:index, resource)
end
end
shared_examples_for 'no index allowed' do
it 'should not allow index' do
expect(ability).to_not be_able_to(:index, resource)
expect(subject).to_not be_able_to(:index, resource)
end
end
shared_examples_for 'create only' do
it 'should allow create' do
expect(ability).to be_able_to(:create, resource)
expect(subject).to be_able_to(:create, resource)
end
it 'should not allow read' do
expect(ability).to_not be_able_to(:read, resource)
expect(subject).to_not be_able_to(:read, resource)
end
it 'should not allow update' do
expect(ability).to_not be_able_to(:update, resource)
expect(subject).to_not be_able_to(:update, resource)
end
it 'should not allow index' do
expect(ability).to_not be_able_to(:index, resource)
expect(subject).to_not be_able_to(:index, resource)
end
end
shared_examples_for 'read only' do
it 'should not allow create' do
expect(ability).to_not be_able_to(:create, resource)
expect(subject).to_not be_able_to(:create, resource)
end
it 'should not allow update' do
expect(ability).to_not be_able_to(:update, resource)
expect(subject).to_not be_able_to(:update, resource)
end
it 'should allow index' do
expect(ability).to be_able_to(:index, resource)
expect(subject).to be_able_to(:index, resource)
end
end
shared_examples_for 'update only' do
it 'should not allow create' do
expect(ability).to_not be_able_to(:create, resource)
expect(subject).to_not be_able_to(:create, resource)
end
it 'should not allow read' do
expect(ability).to_not be_able_to(:read, resource)
expect(subject).to_not be_able_to(:read, resource)
end
it 'should allow update' do
expect(ability).to be_able_to(:update, resource)
expect(subject).to be_able_to(:update, resource)
end
it 'should not allow index' do
expect(ability).to_not be_able_to(:index, resource)
expect(subject).to_not be_able_to(:index, resource)
end
end