From 405b31772613f1bd7c4ba1506245d596d5216fc3 Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Fri, 4 Sep 2020 10:28:28 +0100 Subject: [PATCH] Merge ability and ability decorator --- app/models/spree/ability.rb | 327 +++++++++- app/models/spree/ability_decorator.rb | 313 --------- spec/models/spree/ability_decorator_spec.rb | 607 ----------------- spec/models/spree/ability_spec.rb | 685 +++++++++++++++++--- spec/support/ability_helpers.rb | 50 +- 5 files changed, 934 insertions(+), 1048 deletions(-) delete mode 100644 app/models/spree/ability_decorator.rb delete mode 100644 spec/models/spree/ability_decorator_spec.rb diff --git a/app/models/spree/ability.rb b/app/models/spree/ability.rb index 25aee521fd..4b9bd1d057 100644 --- a/app/models/spree/ability.rb +++ b/app/models/spree/ability.rb @@ -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 diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb deleted file mode 100644 index 325d93839a..0000000000 --- a/app/models/spree/ability_decorator.rb +++ /dev/null @@ -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) diff --git a/spec/models/spree/ability_decorator_spec.rb b/spec/models/spree/ability_decorator_spec.rb deleted file mode 100644 index 355c5d2935..0000000000 --- a/spec/models/spree/ability_decorator_spec.rb +++ /dev/null @@ -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 diff --git a/spec/models/spree/ability_spec.rb b/spec/models/spree/ability_spec.rb index 5b64660e95..00850efdb8 100644 --- a/spec/models/spree/ability_spec.rb +++ b/spec/models/spree/ability_spec.rb @@ -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 diff --git a/spec/support/ability_helpers.rb b/spec/support/ability_helpers.rb index 0d42bbf7c2..4dcb840fe7 100644 --- a/spec/support/ability_helpers.rb +++ b/spec/support/ability_helpers.rb @@ -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