Moving order cycle permissions to their own permissions class

This commit is contained in:
Rob Harrington
2015-04-11 21:11:10 +10:00
parent 02f8f293da
commit 26d55baa35
13 changed files with 1078 additions and 1063 deletions

View File

@@ -79,7 +79,7 @@ module Admin
order_cycle = OrderCycle.find_by_id(params[:order_cycle_id]) if params[:order_cycle_id]
coordinator = Enterprise.find_by_id(params[:coordinator_id]) if params[:coordinator_id]
order_cycle = OrderCycle.new(coordinator: coordinator) if order_cycle.nil? && coordinator.present?
enterprises = OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises_for(order_cycle)
enterprises = OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user, order_cycle).order_cycle_enterprises_for
return EnterpriseFee.for_enterprises(enterprises).order('enterprise_id', 'fee_type', 'name')
else
collection = EnterpriseFee.managed_by(spree_current_user).order('enterprise_id', 'fee_type', 'name')

View File

@@ -108,7 +108,7 @@ module Admin
order_cycle = OrderCycle.find_by_id(params[:order_cycle_id]) if params[:order_cycle_id]
coordinator = Enterprise.find_by_id(params[:coordinator_id]) if params[:coordinator_id]
order_cycle = OrderCycle.new(coordinator: coordinator) if order_cycle.nil? && coordinator.present?
return OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises_for(order_cycle)
return OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user, order_cycle).order_cycle_enterprises_for
else
# TODO was ordered with is_distributor DESC as well, not sure why or how we want to sort this now
OpenFoodNetwork::Permissions.new(spree_current_user).

View File

@@ -4,7 +4,7 @@ module OrderCyclesHelper
end
def permitted_enterprises_for(order_cycle)
OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises_for(order_cycle)
OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user, order_cycle).order_cycle_enterprises_for
end
def permitted_producer_enterprises_for(order_cycle)

View File

@@ -6,11 +6,11 @@ class Api::Admin::ExchangeSerializer < ActiveModel::Serializer
def variants
permitted = Spree::Variant.where("1=0")
if object.incoming
permitted = OpenFoodNetwork::Permissions.new(options[:current_user]).
visible_variants_for_incoming_exchanges_between(object.sender, object.receiver, order_cycle: object.order_cycle)
permitted = OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object.order_cycle).
visible_variants_for_incoming_exchanges_from(object.sender)
else
permitted = OpenFoodNetwork::Permissions.new(options[:current_user]).
visible_variants_for_outgoing_exchanges_between(object.sender, object.receiver, order_cycle: object.order_cycle)
permitted = OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object.order_cycle).
visible_variants_for_outgoing_exchanges_to(object.receiver)
end
Hash[ object.variants.merge(permitted).map { |v| [v.id, true] } ]
end

View File

@@ -19,7 +19,7 @@ class Api::Admin::OrderCycleSerializer < ActiveModel::Serializer
end
def exchanges
scoped_exchanges = OpenFoodNetwork::Permissions.new(options[:current_user]).order_cycle_exchanges(object).order('id ASC')
scoped_exchanges = OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object).order_cycle_exchanges.order('id ASC')
ActiveModel::ArraySerializer.new(scoped_exchanges, {each_serializer: Api::Admin::ExchangeSerializer, current_user: options[:current_user] })
end
@@ -27,10 +27,10 @@ class Api::Admin::OrderCycleSerializer < ActiveModel::Serializer
# For each enterprise that the current user is able to see in this order cycle,
# work out which variants should be editable within incoming exchanges from that enterprise
editable = {}
permissions = OpenFoodNetwork::Permissions.new(options[:current_user])
enterprises = permissions.order_cycle_enterprises_for(object)
permissions = OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object)
enterprises = permissions.order_cycle_enterprises_for
enterprises.each do |enterprise|
variants = permissions.editable_variants_for_incoming_exchanges_between(enterprise, object.coordinator, order_cycle: object).pluck(:id)
variants = permissions.editable_variants_for_incoming_exchanges_from(enterprise).pluck(:id)
editable[enterprise.id] = variants if variants.any?
end
editable
@@ -40,10 +40,10 @@ class Api::Admin::OrderCycleSerializer < ActiveModel::Serializer
# For each enterprise that the current user is able to see in this order cycle,
# work out which variants should be editable within incoming exchanges from that enterprise
editable = {}
permissions = OpenFoodNetwork::Permissions.new(options[:current_user])
enterprises = permissions.order_cycle_enterprises_for(object)
permissions = OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object)
enterprises = permissions.order_cycle_enterprises_for
enterprises.each do |enterprise|
variants = permissions.editable_variants_for_outgoing_exchanges_between(object.coordinator, enterprise, order_cycle: object).pluck(:id)
variants = permissions.editable_variants_for_outgoing_exchanges_to(enterprise).pluck(:id)
editable[enterprise.id] = variants if variants.any?
end
editable
@@ -53,10 +53,10 @@ class Api::Admin::OrderCycleSerializer < ActiveModel::Serializer
# For each enterprise that the current user is able to see in this order cycle,
# work out which variants should be visible within outgoing exchanges from that enterprise
visible = {}
permissions = OpenFoodNetwork::Permissions.new(options[:current_user])
enterprises = permissions.order_cycle_enterprises_for(object)
permissions = OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object)
enterprises = permissions.order_cycle_enterprises_for
enterprises.each do |enterprise|
variants = permissions.visible_variants_for_outgoing_exchanges_between(object.coordinator, enterprise, order_cycle: object).pluck(:id)
variants = permissions.visible_variants_for_outgoing_exchanges_to(enterprise).pluck(:id)
visible[enterprise.id] = variants if variants.any?
end
visible

View File

@@ -8,7 +8,7 @@
- unless order_cycles_simple_index
%td.suppliers
- suppliers = order_cycle.suppliers.merge(OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises_for(order_cycle))
- suppliers = order_cycle.suppliers.merge(OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user, order_cycle).order_cycle_enterprises_for)
- supplier_list = suppliers.map(&:name).sort.join ', '
- if suppliers.count > 3
%span.with-tip{'data-powertip' => supplier_list}
@@ -18,7 +18,7 @@
= supplier_list
%td= order_cycle.coordinator.name
%td.distributors
- distributors = order_cycle.distributors.merge(OpenFoodNetwork::Permissions.new(spree_current_user).order_cycle_enterprises_for(order_cycle))
- distributors = order_cycle.distributors.merge(OpenFoodNetwork::OrderCyclePermissions.new(spree_current_user, order_cycle).order_cycle_enterprises_for)
- distributor_list = distributors.map(&:name).sort.join ', '
- if distributors.count > 3
%span.with-tip{'data-powertip' => distributor_list}

View File

@@ -102,8 +102,8 @@ module OpenFoodNetwork
def permitted_enterprises
return @permitted_enterprises unless @permitted_enterprises.nil?
@permitted_enterprises = OpenFoodNetwork::Permissions.new(@spree_current_user).
order_cycle_enterprises_for(@order_cycle)
@permitted_enterprises = OpenFoodNetwork::OrderCyclePermissions.
new(@spree_current_user, @order_cycle).order_cycle_enterprises_for
end
def manages_coordinator?
@@ -112,15 +112,13 @@ module OpenFoodNetwork
end
def editable_variant_ids_for_incoming_exchange_between(sender, receiver)
OpenFoodNetwork::Permissions.new(@spree_current_user).
editable_variants_for_incoming_exchanges_between(sender, receiver, order_cycle: @order_cycle).
pluck(:id)
OpenFoodNetwork::OrderCyclePermissions.new(@spree_current_user, @order_cycle).
editable_variants_for_incoming_exchanges_from(sender).pluck(:id)
end
def editable_variant_ids_for_outgoing_exchange_between(sender, receiver)
OpenFoodNetwork::Permissions.new(@spree_current_user).
editable_variants_for_outgoing_exchanges_between(sender, receiver, order_cycle: @order_cycle).
pluck(:id)
OpenFoodNetwork::OrderCyclePermissions.new(@spree_current_user, @order_cycle).
editable_variants_for_outgoing_exchanges_to(receiver).pluck(:id)
end
def find_incoming_exchange(attrs)

View File

@@ -0,0 +1,240 @@
module OpenFoodNetwork
# Class which is used for determining the permissions around a single order cycle and user
# both of which are set at initialization
class OrderCyclePermissions < Permissions
def initialize(user, order_cycle)
super(user)
@order_cycle = order_cycle
@coordinator = order_cycle.andand.coordinator
end
# List of any enterprises whose exchanges I should be able to see in order_cycle
# NOTE: the enterprises a given user can see actually in the OC interface depend on the relationships
# of their enterprises to the coordinator of the order cycle, rather than on the order cycle itself
def order_cycle_enterprises_for
return Enterprise.where("1=0") unless @coordinator.present?
if managed_enterprises.include? @coordinator
coordinator_permitted = [@coordinator]
all_active = []
if @coordinator.sells == "any"
# If the coordinator sells any, relationships come into play
granting(:add_to_order_cycle, to: [@coordinator]).pluck(:id).each do |enterprise_id|
coordinator_permitted << enterprise_id
end
# As a safety net, we should load all of the enterprises invloved in existing exchanges in this order cycle
all_active = @order_cycle.suppliers.pluck(:id) | @order_cycle.distributors.pluck(:id)
end
Enterprise.where(id: coordinator_permitted | all_active)
else
# Any enterprises that I manage directly, which have granted P-OC to the coordinator
managed_permitted = granting(:add_to_order_cycle, to: [@coordinator], scope: managed_enterprises_in(@order_cycle) ).pluck(:id)
# Any hubs in this OC that have been granted P-OC by producers I manage in this OC
hubs_permitted = granted(:add_to_order_cycle, by: managed_producers_in(@order_cycle), scope: @order_cycle.distributors).pluck(:id)
# Any hubs in this OC that have granted P-OC to producers I manage in this OC
hubs_permitting = granting(:add_to_order_cycle, to: managed_producers_in(@order_cycle), scope: @order_cycle.distributors).pluck(:id)
# Any producers in this OC that have been granted P-OC by hubs I manage in this OC
producers_permitted = granted(:add_to_order_cycle, by: managed_hubs_in(@order_cycle), scope: @order_cycle.suppliers).pluck(:id)
# Any producers in this OC that have granted P-OC to hubs I manage in this OC
producers_permitting = granting(:add_to_order_cycle, to: managed_hubs_in(@order_cycle), scope: @order_cycle.suppliers).pluck(:id)
managed_active = []
hubs_active = []
producers_active = []
if @order_cycle
# TODO: Remove this when all P-OC are sorted out
# Any enterprises that I manage that are already in the order_cycle
managed_active = managed_enterprises_in(@order_cycle).pluck(:id)
# TODO: Remove this when all P-OC are sorted out
# Any hubs that currently have outgoing exchanges distributing variants of producers I manage
variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', managed_enterprises.is_primary_producer)
active_exchanges = @order_cycle.exchanges.outgoing.with_any_variant(variants)
hubs_active = active_exchanges.map(&:receiver_id)
# TODO: Remove this when all P-OC are sorted out
# Any producers of variants that hubs I manage are currently distributing in this OC
variants = Spree::Variant.joins(:exchanges).where("exchanges.receiver_id IN (?) AND exchanges.order_cycle_id = (?) AND exchanges.incoming = 'f'", managed_hubs_in(@order_cycle), @order_cycle).pluck(:id).uniq
products = Spree::Product.joins(:variants_including_master).where("spree_variants.id IN (?)", variants).pluck(:id).uniq
producers_active = Enterprise.joins(:supplied_products).where("spree_products.id IN (?)", products).pluck(:id).uniq
end
ids = managed_permitted | hubs_permitted | hubs_permitting | producers_permitted | producers_permitting | managed_active | hubs_active | producers_active
Enterprise.where(id: ids.sort )
end
end
# Find the exchanges of an order cycle that an admin can manage
def order_cycle_exchanges
ids = order_cycle_exchange_ids_involving_my_enterprises |
order_cycle_exchange_ids_distributing_my_variants |
order_cycle_exchange_ids_with_distributable_variants
Exchange.where(id: ids, order_cycle_id: @order_cycle)
end
# Find the variants that a user can POTENTIALLY see within incoming exchanges
def visible_variants_for_incoming_exchanges_from(producer)
return Spree::Variant.where("1=0") unless @order_cycle
if managed_enterprises.pluck(:id).include?(producer.id) || managed_enterprises.pluck(:id).include?(@coordinator.id)
# All variants belonging to the producer
Spree::Variant.joins(:product).where('spree_products.supplier_id = (?)', producer)
else
# All variants of the producer if it has granted P-OC to any of my managed hubs that are in this order cycle
permitted = EnterpriseRelationship.permitting(managed_hubs_in(@order_cycle)).
permitted_by(producer).with_permission(:add_to_order_cycle).present?
if permitted
Spree::Variant.joins(:product).where('spree_products.supplier_id = (?)', producer)
else
Spree::Variant.where("1=0")
end
end
end
# Find the variants that a user can edit within incoming exchanges
def editable_variants_for_incoming_exchanges_from(producer)
return Spree::Variant.where("1=0") unless @order_cycle
if managed_enterprises.pluck(:id).include?(producer.id) || managed_enterprises.pluck(:id).include?(@coordinator.id)
# All variants belonging to the producer
Spree::Variant.joins(:product).where('spree_products.supplier_id = (?)', producer)
else
Spree::Variant.where("1=0")
end
end
# Find the variants that a user is permitted see within outgoing exchanges
# Note that this does not determine whether they actually appear in outgoing exchanges
# as this requires first that the variant is included in an incoming exchange
def visible_variants_for_outgoing_exchanges_to(hub)
return Spree::Variant.where("1=0") unless @order_cycle
if managed_enterprises.pluck(:id).include?(hub.id) || managed_enterprises.pluck(:id).include?(@coordinator.id)
# Any variants produced by the coordinator, for outgoing exchanges with itself
coordinator_variants = []
if hub == @coordinator
coordinator_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id = (?)', @coordinator)
end
# Any variants of any producers that have granted the hub P-OC
producers = granting(:add_to_order_cycle, to: [hub], scope: Enterprise.is_primary_producer)
permitted_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', producers)
# PLUS any variants that are already in an outgoing exchange of this hub, so things don't break
# TODO: Remove this when all P-OC are sorted out
active_variants = []
@order_cycle.exchanges.outgoing.where(receiver_id: hub).limit(1).each do |exchange|
active_variants = exchange.variants
end
Spree::Variant.where(id: coordinator_variants | permitted_variants | active_variants)
else
# Any variants produced by MY PRODUCERS that are in this order cycle, where my producer has granted P-OC to the hub
producers = granting(:add_to_order_cycle, to: [hub], scope: managed_producers_in(@order_cycle))
permitted_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', producers)
# PLUS any of my incoming producers' variants that are already in an outgoing exchange of this hub, so things don't break
# TODO: Remove this when all P-OC are sorted out
active_variants = Spree::Variant.joins(:exchanges, :product).
where("exchanges.receiver_id = (?) AND spree_products.supplier_id IN (?) AND incoming = 'f'", hub, managed_enterprises.is_primary_producer)
Spree::Variant.where(id: permitted_variants | active_variants)
end
end
# Find the variants that a user is permitted edit within outgoing exchanges
def editable_variants_for_outgoing_exchanges_to(hub)
return Spree::Variant.where("1=0") unless @order_cycle
if managed_enterprises.pluck(:id).include?(hub.id) || managed_enterprises.pluck(:id).include?(@coordinator.id)
# Any variants produced by the coordinator, for outgoing exchanges with itself
coordinator_variants = []
if hub == @coordinator
coordinator_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id = (?)', @coordinator)
end
# Any variants of any producers that have granted the hub P-OC
producers = granting(:add_to_order_cycle, to: [hub], scope: Enterprise.is_primary_producer)
permitted_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', producers)
# PLUS any variants that are already in an outgoing exchange of this hub, so things don't break
# TODO: Remove this when all P-OC are sorted out
active_variants = []
@order_cycle.exchanges.outgoing.where(receiver_id: hub).limit(1).each do |exchange|
active_variants = exchange.variants
end
Spree::Variant.where(id: coordinator_variants | permitted_variants | active_variants)
else
# Any of my managed producers in this order cycle granted P-OC by the hub
granted_producers = granted(:add_to_order_cycle, by: [hub], scope: managed_producers_in(@order_cycle))
# Any variants produced by MY PRODUCERS that are in this order cycle, where my producer has granted P-OC to the hub
granting_producers = granting(:add_to_order_cycle, to: [hub], scope: granted_producers)
permitted_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', granting_producers)
Spree::Variant.where(id: permitted_variants)
end
end
private
def managed_enterprises_in(order_cycle)
managed_enterprises.where(id: order_cycle.suppliers | order_cycle.distributors)
end
def managed_hubs_in(order_cycle)
managed_enterprises_in(order_cycle).is_hub
end
def managed_producers_in(order_cycle)
managed_enterprises_in(order_cycle).is_primary_producer
end
def order_cycle_exchange_ids_involving_my_enterprises
# Any exchanges that my managed enterprises are involved in directly
@order_cycle.exchanges.involving(managed_enterprises).pluck :id
end
def order_cycle_exchange_ids_with_distributable_variants
# Find my managed hubs in this order cycle
hubs = managed_hubs_in(@order_cycle)
# Any incoming exchange where the producer has granted P-OC to one or more of those hubs
producers = granting(:add_to_order_cycle, to: hubs, scope: Enterprise.is_primary_producer).pluck :id
permitted_exchanges = @order_cycle.exchanges.incoming.where(sender_id: producers).pluck :id
# TODO: remove active_exchanges when we think it is safe to do so
# active_exchanges is for backward compatability, before we restricted variants in each
# outgoing exchange to those where the producer had granted P-OC to the distributor
# For any of my managed hubs in this OC, any incoming exchanges supplying variants in my outgoing exchanges
variants = Spree::Variant.joins(:exchanges).where("exchanges.receiver_id IN (?) AND exchanges.order_cycle_id = (?) AND exchanges.incoming = 'f'", hubs, @order_cycle).pluck(:id).uniq
products = Spree::Product.joins(:variants_including_master).where("spree_variants.id IN (?)", variants).pluck(:id).uniq
producers = Enterprise.joins(:supplied_products).where("spree_products.id IN (?)", products).pluck(:id).uniq
active_exchanges = @order_cycle.exchanges.incoming.where(sender_id: producers).pluck :id
permitted_exchanges | active_exchanges
end
def order_cycle_exchange_ids_distributing_my_variants
# Find my producers in this order cycle
producers = managed_producers_in(@order_cycle).pluck :id
# Any outgoing exchange where the distributor has been granted P-OC by one or more of those producers
hubs = granted(:add_to_order_cycle, by: producers, scope: Enterprise.is_hub)
permitted_exchanges = @order_cycle.exchanges.outgoing.where(receiver_id: hubs).pluck :id
# TODO: remove active_exchanges when we think it is safe to do so
# active_exchanges is for backward compatability, before we restricted variants in each
# outgoing exchange to those where the producer had granted P-OC to the distributor
# For any of my managed producers, any outgoing exchanges with their variants
variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', producers)
active_exchanges = @order_cycle.exchanges.outgoing.with_any_variant(variants).pluck :id
permitted_exchanges | active_exchanges
end
end
end

View File

@@ -15,73 +15,6 @@ module OpenFoodNetwork
managed_and_related_enterprises_with :add_to_order_cycle
end
# List of any enterprises whose exchanges I should be able to see in order_cycle
# NOTE: the enterprises a given user can see actually in the OC interface depend on the relationships
# of their enterprises to the coordinator of the order cycle, rather than on the order cycle itself
# (until such time as we implement friends of friends)
def order_cycle_enterprises_for(order_cycle)
return Enterprise.where("1=0") unless order_cycle.andand.coordinator.present?
coordinator = order_cycle.coordinator
if managed_enterprises.include? coordinator
coordinator_permitted = [coordinator]
all_active = []
if coordinator.sells == "any"
# If I manage the coordinator (or possibly in the future, if coordinator has made order cycle a friends of friend OC)
# Any hubs that have granted the coordinator P-OC (or any enterprises that have granted mine P-OC if we do friends of friends)
# If the coordinator sells any, relationships come into play
granting(:add_to_order_cycle, to: [coordinator]).pluck(:id).each do |enterprise_id|
coordinator_permitted << enterprise_id
end
all_active = order_cycle.suppliers.pluck(:id) | order_cycle.distributors.pluck(:id)
end
Enterprise.where(id: coordinator_permitted | all_active)
else
# Any enterprises that I manage directly, which have granted P-OC to the coordinator
managed_permitted = granting(:add_to_order_cycle, to: [coordinator], scope: managed_enterprises_in(order_cycle) ).pluck(:id)
# Any hubs in this OC that have been granted P-OC by producers I manage in this OC
hubs_permitted = granted(:add_to_order_cycle, by: managed_producers_in(order_cycle), scope: order_cycle.distributors).pluck(:id)
# Any hubs in this OC that have granted P-OC to producers I manage in this OC
hubs_permitting = granting(:add_to_order_cycle, to: managed_producers_in(order_cycle), scope: order_cycle.distributors).pluck(:id)
# Any producers in this OC that have been granted P-OC by hubs I manage in this OC
producers_permitted = granted(:add_to_order_cycle, by: managed_hubs_in(order_cycle), scope: order_cycle.suppliers).pluck(:id)
# Any producers in this OC that have granted P-OC to hubs I manage in this OC
producers_permitting = granting(:add_to_order_cycle, to: managed_hubs_in(order_cycle), scope: order_cycle.suppliers).pluck(:id)
managed_active = []
hubs_active = []
producers_active = []
if order_cycle
# TODO: Remove this when all P-OC are sorted out
# Any enterprises that I manage that are already in the order_cycle
managed_active = managed_enterprises_in(order_cycle).pluck(:id)
# TODO: Remove this when all P-OC are sorted out
# Any hubs that currently have outgoing exchanges distributing variants of producers I manage
variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', managed_enterprises.is_primary_producer)
active_exchanges = order_cycle.exchanges.outgoing.with_any_variant(variants)
hubs_active = active_exchanges.map(&:receiver_id)
# TODO: Remove this when all P-OC are sorted out
# Any producers of variants that hubs I manage are currently distributing in this OC
variants = Spree::Variant.joins(:exchanges).where("exchanges.receiver_id IN (?) AND exchanges.order_cycle_id = (?) AND exchanges.incoming = 'f'", managed_hubs_in(order_cycle), order_cycle).pluck(:id).uniq
products = Spree::Product.joins(:variants_including_master).where("spree_variants.id IN (?)", variants).pluck(:id).uniq
producers_active = Enterprise.joins(:supplied_products).where("spree_products.id IN (?)", products).pluck(:id).uniq
end
ids = managed_permitted | hubs_permitted | hubs_permitting | producers_permitted | producers_permitting | managed_active | hubs_active | producers_active
Enterprise.where(id: ids.sort )
end
end
# Find enterprises for which an admin is allowed to edit their profile
def editable_enterprises
managed_and_related_enterprises_with :edit_profile
@@ -123,116 +56,6 @@ module OpenFoodNetwork
permissions
end
# Find the exchanges of an order cycle that an admin can manage
def order_cycle_exchanges(order_cycle)
ids = order_cycle_exchange_ids_involving_my_enterprises(order_cycle) |
order_cycle_exchange_ids_distributing_my_variants(order_cycle) |
order_cycle_exchange_ids_with_distributable_variants(order_cycle)
Exchange.where(id: ids, order_cycle_id: order_cycle)
end
# Find the variants that a user can POTENTIALLY see within incoming exchanges
def visible_variants_for_incoming_exchanges_between(producer, coordinator, options={})
return Spree::Variant.where("1=0") unless options[:order_cycle]
if managed_enterprises.pluck(:id).include?(producer.id) || managed_enterprises.pluck(:id).include?(coordinator.id)
# All variants belonging to the producer
Spree::Variant.joins(:product).where('spree_products.supplier_id = (?)', producer)
else
# All variants of the producer if it has granted P-OC to any of my managed hubs that are in this order cycle
permitted = EnterpriseRelationship.permitting(managed_hubs_in(options[:order_cycle])).
permitted_by(producer).with_permission(:add_to_order_cycle).present?
if permitted
Spree::Variant.joins(:product).where('spree_products.supplier_id = (?)', producer)
else
Spree::Variant.where("1=0")
end
end
end
# Find the variants that a user can edit within incoming exchanges
def editable_variants_for_incoming_exchanges_between(producer, coordinator, options={})
return Spree::Variant.where("1=0") unless options[:order_cycle]
if managed_enterprises.pluck(:id).include?(producer.id) || managed_enterprises.pluck(:id).include?(coordinator.id)
# All variants belonging to the producer
Spree::Variant.joins(:product).where('spree_products.supplier_id = (?)', producer)
else
Spree::Variant.where("1=0")
end
end
# Find the variants that a user is permitted see within outgoing exchanges
# Note that this does not determine whether they actually appear in outgoing exchanges
# as this requires first that the variant is included in an incoming exchange
def visible_variants_for_outgoing_exchanges_between(coordinator, hub, options={})
return Spree::Variant.where("1=0") unless options[:order_cycle]
if managed_enterprises.pluck(:id).include?(hub.id) || managed_enterprises.pluck(:id).include?(coordinator.id)
# Any variants produced by the coordinator, for outgoing exchanges with itself
coordinator_variants = []
if hub == coordinator
coordinator_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id = (?)', coordinator)
end
# Any variants of any producers that have granted the hub P-OC
producers = granting(:add_to_order_cycle, to: [hub], scope: Enterprise.is_primary_producer)
permitted_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', producers)
# PLUS any variants that are already in an outgoing exchange of this hub, so things don't break
# TODO: Remove this when all P-OC are sorted out
active_variants = []
options[:order_cycle].exchanges.outgoing.where(receiver_id: hub).limit(1).each do |exchange|
active_variants = exchange.variants
end
Spree::Variant.where(id: coordinator_variants | permitted_variants | active_variants)
else
# Any variants produced by MY PRODUCERS that are in this order cycle, where my producer has granted P-OC to the hub
producers = granting(:add_to_order_cycle, to: [hub], scope: managed_producers_in(options[:order_cycle]))
permitted_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', producers)
# PLUS any of my incoming producers' variants that are already in an outgoing exchange of this hub, so things don't break
# TODO: Remove this when all P-OC are sorted out
active_variants = Spree::Variant.joins(:exchanges, :product).
where("exchanges.receiver_id = (?) AND spree_products.supplier_id IN (?) AND incoming = 'f'", hub, managed_enterprises.is_primary_producer)
Spree::Variant.where(id: permitted_variants | active_variants)
end
end
# Find the variants that a user is permitted edit within outgoing exchanges
def editable_variants_for_outgoing_exchanges_between(coordinator, hub, options={})
return Spree::Variant.where("1=0") unless options[:order_cycle]
if managed_enterprises.pluck(:id).include?(hub.id) || managed_enterprises.pluck(:id).include?(coordinator.id)
# Any variants produced by the coordinator, for outgoing exchanges with itself
coordinator_variants = []
if hub == coordinator
coordinator_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id = (?)', coordinator)
end
# Any variants of any producers that have granted the hub P-OC
producers = granting(:add_to_order_cycle, to: [hub], scope: Enterprise.is_primary_producer)
permitted_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', producers)
# PLUS any variants that are already in an outgoing exchange of this hub, so things don't break
# TODO: Remove this when all P-OC are sorted out
active_variants = []
options[:order_cycle].exchanges.outgoing.where(receiver_id: hub).limit(1).each do |exchange|
active_variants = exchange.variants
end
Spree::Variant.where(id: coordinator_variants | permitted_variants | active_variants)
else
# Any of my managed producers in this order cycle granted P-OC by the hub
granted_producers = granted(:add_to_order_cycle, by: [hub], scope: managed_producers_in(options[:order_cycle]))
# Any variants produced by MY PRODUCERS that are in this order cycle, where my producer has granted P-OC to the hub
granting_producers = granting(:add_to_order_cycle, to: [hub], scope: granted_producers)
permitted_variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', granting_producers)
Spree::Variant.where(id: permitted_variants )
end
end
def managed_products
managed_enterprise_products_ids = managed_enterprise_products.pluck :id
permitted_enterprise_products_ids = related_enterprise_products.pluck :id
@@ -261,18 +84,6 @@ module OpenFoodNetwork
Enterprise.managed_by(@user)
end
def managed_enterprises_in(order_cycle)
managed_enterprises.where(id: order_cycle.suppliers | order_cycle.distributors)
end
def managed_hubs_in(order_cycle)
managed_enterprises_in(order_cycle).is_hub
end
def managed_producers_in(order_cycle)
managed_enterprises_in(order_cycle).is_primary_producer
end
def related_enterprises_with(permission)
parent_ids = EnterpriseRelationship.
permitting(managed_enterprises).
@@ -307,46 +118,5 @@ module OpenFoodNetwork
def related_enterprise_products
Spree::Product.where('supplier_id IN (?)', related_enterprises_with(:manage_products))
end
def order_cycle_exchange_ids_involving_my_enterprises(order_cycle)
# Any exchanges that my managed enterprises are involved in directly
order_cycle.exchanges.involving(managed_enterprises).pluck :id
end
def order_cycle_exchange_ids_with_distributable_variants(order_cycle)
# Find my managed hubs in this order cycle
hubs = managed_hubs_in(order_cycle)
# Any incoming exchange where the producer has granted P-OC to one or more of those hubs
producers = granting(:add_to_order_cycle, to: hubs, scope: Enterprise.is_primary_producer).pluck :id
permitted_exchanges = order_cycle.exchanges.incoming.where(sender_id: producers).pluck :id
# TODO: remove active_exchanges when we think it is safe to do so
# active_exchanges is for backward compatability, before we restricted variants in each
# outgoing exchange to those where the producer had granted P-OC to the distributor
# For any of my managed hubs in this OC, any incoming exchanges supplying variants in my outgoing exchanges
variants = Spree::Variant.joins(:exchanges).where("exchanges.receiver_id IN (?) AND exchanges.order_cycle_id = (?) AND exchanges.incoming = 'f'", hubs, order_cycle).pluck(:id).uniq
products = Spree::Product.joins(:variants_including_master).where("spree_variants.id IN (?)", variants).pluck(:id).uniq
producers = Enterprise.joins(:supplied_products).where("spree_products.id IN (?)", products).pluck(:id).uniq
active_exchanges = order_cycle.exchanges.incoming.where(sender_id: producers).pluck :id
permitted_exchanges | active_exchanges
end
def order_cycle_exchange_ids_distributing_my_variants(order_cycle)
# Find my producers in this order cycle
producers = managed_producers_in(order_cycle).pluck :id
# Any outgoing exchange where the distributor has been granted P-OC by one or more of those producers
hubs = granted(:add_to_order_cycle, by: producers, scope: Enterprise.is_hub)
permitted_exchanges = order_cycle.exchanges.outgoing.where(receiver_id: hubs).pluck :id
# TODO: remove active_exchanges when we think it is safe to do so
# active_exchanges is for backward compatability, before we restricted variants in each
# outgoing exchange to those where the producer had granted P-OC to the distributor
# For any of my managed producers, any outgoing exchanges with their variants
variants = Spree::Variant.joins(:product).where('spree_products.supplier_id IN (?)', producers)
active_exchanges = order_cycle.exchanges.outgoing.with_any_variant(variants).pluck :id
permitted_exchanges | active_exchanges
end
end
end

View File

@@ -1,4 +1,5 @@
require 'spec_helper'
require 'open_food_network/order_cycle_permissions'
module Admin
describe EnterprisesController do
@@ -418,36 +419,36 @@ module Admin
Enterprise.stub find_by_id: "existing Enterprise"
OrderCycle.stub new: "new OrderCycle"
OpenFoodNetwork::Permissions.stub(:new) { permission_mock }
allow(permission_mock).to receive(:order_cycle_enterprises_for)
allow(OpenFoodNetwork::OrderCyclePermissions).to receive(:new) { permission_mock }
allow(permission_mock).to receive(:order_cycle_enterprises_for) { [] }
allow(ActiveModel::ArraySerializer).to receive(:new) { "" }
end
context "when no order_cycle or coordinator is provided in params" do
before { spree_get :for_order_cycle, format: :json }
it "returns an empty scope" do
expect(permission_mock).to have_received(:order_cycle_enterprises_for).with(nil)
it "initializes permissions with nil" do
expect(OpenFoodNetwork::OrderCyclePermissions).to have_received(:new).with(user, nil)
end
end
context "when an order_cycle_id is provided in params" do
before { spree_get :for_order_cycle, format: :json, order_cycle_id: 1 }
it "calls order_cycle_enterprises_for() with the existing OrderCycle" do
expect(permission_mock).to have_received(:order_cycle_enterprises_for).with("existing OrderCycle")
it "initializes permissions with the existing OrderCycle" do
expect(OpenFoodNetwork::OrderCyclePermissions).to have_received(:new).with(user, "existing OrderCycle")
end
end
context "when a coordinator is provided in params" do
before { spree_get :for_order_cycle, format: :json, coordinator_id: 1 }
it "calls order_cycle_enterprises_for() with a new OrderCycle" do
expect(permission_mock).to have_received(:order_cycle_enterprises_for).with("new OrderCycle")
it "initializes permissions with a new OrderCycle" do
expect(OpenFoodNetwork::OrderCyclePermissions).to have_received(:new).with(user, "new OrderCycle")
end
end
context "when both an order cycle and a coordinator are provided in params" do
before { spree_get :for_order_cycle, format: :json, order_cycle_id: 1, coordinator_id: 1 }
it "calls order_cycle_enterprises_for() with the existing OrderCycle" do
expect(permission_mock).to have_received(:order_cycle_enterprises_for).with("existing OrderCycle")
it "initializes permissions with the existing OrderCycle" do
expect(OpenFoodNetwork::OrderCyclePermissions).to have_received(:new).with(user, "existing OrderCycle")
end
end
end

View File

@@ -0,0 +1,797 @@
require 'open_food_network/order_cycle_permissions'
module OpenFoodNetwork
describe OrderCyclePermissions do
let(:coordinator) { create(:distributor_enterprise) }
let(:hub) { create(:distributor_enterprise) }
let(:producer) { create(:supplier_enterprise) }
let(:user) { double(:user) }
let(:oc) { create(:simple_order_cycle, coordinator: coordinator) }
let(:permissions) { OrderCyclePermissions.new(user, oc) }
describe "finding enterprises that can be viewed in the order cycle interface" do
context "when permissions are initialized without an order_cycle" do
let(:permissions) { OrderCyclePermissions.new(user, nil) }
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [coordinator]) }
end
it "returns an empty scope" do
expect(permissions.order_cycle_enterprises_for).to be_empty
end
end
context "as a manager of the coordinator" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [coordinator]) }
end
it "returns the coordinator itself" do
expect(permissions.order_cycle_enterprises_for).to include coordinator
end
context "where P-OC has been granted to the coordinator by other enterprises" do
before do
create(:enterprise_relationship, parent: hub, child: coordinator, permissions_list: [:add_to_order_cycle])
end
context "where the coordinator sells any" do
it "returns enterprises which have granted P-OC to the coordinator" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include hub
expect(enterprises).to_not include producer
end
end
context "where the coordinator sells 'own'" do
before { coordinator.stub(:sells) { 'own' } }
it "returns just the coordinator" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to_not include hub, producer
end
end
end
context "where P-OC has not been granted to the coordinator by other enterprises" do
context "where the other enterprise are already in the order cycle" do
let!(:ex_incoming) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
let!(:ex_outgoing) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
context "where the coordinator sells any" do
it "returns enterprises which have granted P-OC to the coordinator" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include hub, producer
end
end
context "where the coordinator sells 'own'" do
before { coordinator.stub(:sells) { 'own' } }
it "returns just the coordinator" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to_not include hub, producer
end
end
end
context "where the other enterprises are not in the order cycle" do
it "returns just the coordinator" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to_not include hub, producer
end
end
end
end
context "as a manager of a hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [hub]) }
end
context "that has granted P-OC to the coordinator" do
before do
create(:enterprise_relationship, parent: hub, child: coordinator, permissions_list: [:add_to_order_cycle])
end
context "where my hub is in the order cycle" do
let!(:ex_outgoing) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
it "returns my hub" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include hub
expect(enterprises).to_not include producer, coordinator
end
context "and has been granted P-OC by a producer" do
before do
create(:enterprise_relationship, parent: producer, child: hub, permissions_list: [:add_to_order_cycle])
end
context "where the producer is in the order cycle" do
let!(:ex_incoming) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
it "returns the producer" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include producer, hub
end
end
context "where the producer is not in the order cycle" do
# No incoming exchange
it "does not return the producer" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to_not include producer
end
end
end
context "and has granted P-OC to a producer" do
before do
create(:enterprise_relationship, parent: hub, child: producer, permissions_list: [:add_to_order_cycle])
end
context "where the producer is in the order cycle" do
let!(:ex_incoming) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
it "returns the producer" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include producer, hub
end
end
context "where the producer is not in the order cycle" do
# No incoming exchange
it "does not return the producer" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to_not include producer
end
end
end
end
context "where my hub is not in the order cycle" do
# No outgoing exchange for my hub
it "does not return my hub" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to_not include hub, producer, coordinator
end
end
end
context "that has not granted P-OC to the coordinator" do
it "does not return my hub" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to_not include hub, producer, coordinator
end
context "but is already in the order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
it "returns my hub" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include hub
expect(enterprises).to_not include producer, coordinator
end
context "and distributes variants distributed by an unmanaged and unpermitted producer" do
before { ex.variants << create(:variant, product: create(:product, supplier: producer)) }
# TODO: update this when we are confident about P-OCs
it "returns that producer as well" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include producer, hub
expect(enterprises).to_not include coordinator
end
end
end
end
end
context "as a manager of a producer" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer]) }
end
context "which has granted P-OC to the coordinator" do
before do
create(:enterprise_relationship, parent: producer, child: coordinator, permissions_list: [:add_to_order_cycle])
end
context "where my producer is in the order cycle" do
let!(:ex_incoming) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
it "returns my producer" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include producer
expect(enterprises).to_not include hub, coordinator
end
context "and has been granted P-OC by a hub" do
before do
create(:enterprise_relationship, parent: hub, child: producer, permissions_list: [:add_to_order_cycle])
end
context "where the hub is also in the order cycle" do
let!(:ex_outgoing) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
it "returns the hub as well" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include producer, hub
expect(enterprises).to_not include coordinator
end
end
context "where the hub is not in the order cycle" do
# No outgoing exchange
it "does not return the hub" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to_not include hub
end
end
end
context "and has granted P-OC to a hub" do
before do
create(:enterprise_relationship, parent: producer, child: hub, permissions_list: [:add_to_order_cycle])
end
context "where the hub is also in the order cycle" do
let!(:ex_outgoing) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
it "returns the hub as well" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include producer, hub
expect(enterprises).to_not include coordinator
end
end
context "where the hub is not in the order cycle" do
# No outgoing exchange
it "does not return the hub" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to_not include hub
end
end
end
end
context "where my producer is not in the order cycle" do
# No incoming exchange for producer
it "does not return my producer" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to_not include hub, producer, coordinator
end
end
end
context "which has not granted P-OC to the coordinator" do
it "does not return my producer" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to_not include producer
end
context "but is already in the order cycle" do
let!(:ex_incoming) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
# TODO: update this when we are confident about P-OCs
it "returns my producer" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include producer
expect(enterprises).to_not include hub, coordinator
end
context "and has variants distributed by an outgoing hub" do
let!(:ex_outgoing) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
before { ex_outgoing.variants << create(:variant, product: create(:product, supplier: producer)) }
# TODO: update this when we are confident about P-OCs
it "returns that hub as well" do
enterprises = permissions.order_cycle_enterprises_for
expect(enterprises).to include producer, hub
expect(enterprises).to_not include coordinator
end
end
end
end
end
end
describe "finding exchanges of an order cycle that an admin can manage" do
describe "as the manager of the coordinator" do
let!(:ex_in) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
let!(:ex_out) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [coordinator]) }
end
it "returns all exchanges in the order cycle, regardless of hubE permissions" do
permissions.order_cycle_exchanges.should include ex_in, ex_out
end
end
describe "as the manager of a hub" do
let!(:ex_in) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [hub]) }
end
context "where my hub is in the order cycle" do
let!(:ex_out) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
it "returns my hub's outgoing exchange" do
permissions.order_cycle_exchanges.should == [ex_out]
end
context "where my hub has been granted P-OC by an incoming producer" do
before do
create(:enterprise_relationship, parent: producer, child: hub, permissions_list: [:add_to_order_cycle])
end
it "returns the producer's incoming exchange" do
permissions.order_cycle_exchanges.should include ex_in
end
end
context "where my hub has not been granted P-OC by an incoming producer" do
it "returns the producers's incoming exchange, and my own outhoing exchange" do
permissions.order_cycle_exchanges.should_not include ex_in
end
end
end
context "where my hub isn't in the order cycle" do
it "does not return the producer's incoming exchanges" do
permissions.order_cycle_exchanges.should == []
end
end
# TODO: this is testing legacy behaviour for backwards compatability, remove when behaviour no longer required
describe "legacy compatability" do
context "where my hub's outgoing exchange contains variants of a producer I don't manage and has not given my hub P-OC" do
let!(:product) { create(:product, supplier: producer) }
let!(:variant) { create(:variant, product: product) }
let!(:ex_out) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: true) }
before { ex_out.variants << variant }
it "returns incoming exchanges supplying the variants in my outgoing exchange" do
permissions.order_cycle_exchanges.should include ex_out
end
end
end
end
describe "as the manager of a producer" do
let!(:ex_out) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer]) }
end
context "where my producer supplies to the order cycle" do
let!(:ex_in) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
it "returns my producer's incoming exchange" do
permissions.order_cycle_exchanges.should == [ex_in]
end
context "my producer has granted P-OC to an outgoing hub" do
before do
create(:enterprise_relationship, parent: producer, child: hub, permissions_list: [:add_to_order_cycle])
end
it "returns the hub's outgoing exchange" do
permissions.order_cycle_exchanges.should include ex_out
end
end
context "my producer has not granted P-OC to an outgoing hub" do
it "does not return the hub's outgoing exchange" do
permissions.order_cycle_exchanges.should_not include ex_out
end
end
end
context "where my producer doesn't supply the order cycle" do
it "does not return the hub's outgoing exchanges" do
permissions.order_cycle_exchanges.should == []
end
end
# TODO: this is testing legacy behaviour for backwards compatability, remove when behaviour no longer required
describe "legacy compatability" do
context "where an outgoing exchange contains variants of a producer I manage" do
let!(:product) { create(:product, supplier: producer) }
let!(:variant) { create(:variant, product: product) }
before { ex_out.variants << variant }
context "where my producer supplies to the order cycle" do
let!(:ex_in) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
it "returns the outgoing exchange" do
permissions.order_cycle_exchanges.should include ex_out
end
end
context "where my producer doesn't supply to the order cycle" do
it "does not return the outgoing exchange" do
permissions.order_cycle_exchanges.should_not include ex_out
end
end
end
end
end
end
describe "finding the variants within a hypothetical exchange between two enterprises which are visible to a user" do
let!(:producer1) { create(:supplier_enterprise) }
let!(:producer2) { create(:supplier_enterprise) }
let!(:v1) { create(:variant, product: create(:simple_product, supplier: producer1)) }
let!(:v2) { create(:variant, product: create(:simple_product, supplier: producer2)) }
describe "incoming exchanges" do
context "as a manager of the coordinator" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [coordinator]) }
end
it "returns all variants belonging to the sending producer" do
visible = permissions.visible_variants_for_incoming_exchanges_from(producer1)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "as a manager of the producer" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer1]) }
end
it "returns all variants belonging to the sending producer" do
visible = permissions.visible_variants_for_incoming_exchanges_from(producer1)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "as a manager of a hub which has been granted P-OC by the producer" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [hub]) }
create(:enterprise_relationship, parent: producer1, child: hub, permissions_list: [:add_to_order_cycle])
end
context "where the hub is in the order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
it "returns variants produced by that producer only" do
visible = permissions.visible_variants_for_incoming_exchanges_from(producer1)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "where the hub is not in the order cycle" do
# No outgoing exchange
it "does not return variants produced by that producer" do
visible = permissions.visible_variants_for_incoming_exchanges_from(producer1)
expect(visible).to_not include v1, v2
end
end
end
end
describe "outgoing exchanges" do
context "as a manager of the coordinator" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [coordinator]) }
create(:enterprise_relationship, parent: producer1, child: hub, permissions_list: [:add_to_order_cycle])
end
it "returns all variants of any producer which has granted the outgoing hub P-OC" do
visible = permissions.visible_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1
expect(visible).to_not include v2
end
context "where the coordinator produces products" do
let!(:v3) { create(:variant, product: create(:simple_product, supplier: coordinator)) }
it "returns any variants produced by the coordinator itself for exchanges with 'self'" do
visible = permissions.visible_variants_for_outgoing_exchanges_to(coordinator)
expect(visible).to include v3
expect(visible).to_not include v1, v2
end
it "does not return coordinator's variants for exchanges with other hubs, when permission has not been granted" do
visible = permissions.visible_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1
expect(visible).to_not include v2, v3
end
end
# TODO: for backwards compatability, remove later
context "when an exchange exists between the coordinator and the hub within this order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
# producer2 produces v2 and has not granted P-OC to hub (or coordinator for that matter)
before { ex.variants << v2 }
it "returns those variants that are in the exchange" do
visible = permissions.visible_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1, v2
end
end
end
context "as manager of an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [hub]) }
create(:enterprise_relationship, parent: producer1, child: hub, permissions_list: [:add_to_order_cycle])
end
it "returns all variants of any producer which has granted the outgoing hub P-OC" do
visible = permissions.visible_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1
expect(visible).to_not include v2
end
# TODO: for backwards compatability, remove later
context "when an exchange exists between the coordinator and the hub within this order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
# producer2 produces v2 and has not granted P-OC to hub
before { ex.variants << v2 }
it "returns those variants that are in the exchange" do
visible = permissions.visible_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1, v2
end
end
end
context "as the manager of a producer which has granted P-OC to an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer1]) }
create(:enterprise_relationship, parent: producer1, child: hub, permissions_list: [:add_to_order_cycle])
end
context "where my producer is in the order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: producer1, receiver: coordinator, incoming: true) }
it "returns all of my produced variants" do
visible = permissions.visible_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "where my producer isn't in the order cycle" do
# No incoming exchange
it "does not return my variants" do
visible = permissions.visible_variants_for_outgoing_exchanges_to(hub)
expect(visible).to_not include v1, v2
end
end
end
context "as the manager of a producer which has not granted P-OC to an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer2]) }
create(:enterprise_relationship, parent: producer1, child: hub, permissions_list: [:add_to_order_cycle])
end
it "returns an empty array" do
expect(permissions.visible_variants_for_outgoing_exchanges_to(hub)).to eq []
end
# TODO: for backwards compatability, remove later
context "but which has variants already in the exchange" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
# This one won't be in the exchange, and so shouldn't be visible
let!(:v3) { create(:variant, product: create(:simple_product, supplier: producer2)) }
before { ex.variants << v2 }
it "returns those variants that are in the exchange" do
visible = permissions.visible_variants_for_outgoing_exchanges_to(hub)
expect(visible).to_not include v1, v3
expect(visible).to include v2
end
end
end
end
end
describe "finding the variants within a hypothetical exchange between two enterprises which are editable by a user" do
let!(:producer1) { create(:supplier_enterprise) }
let!(:producer2) { create(:supplier_enterprise) }
let!(:v1) { create(:variant, product: create(:simple_product, supplier: producer1)) }
let!(:v2) { create(:variant, product: create(:simple_product, supplier: producer2)) }
describe "incoming exchanges" do
context "as a manager of the coordinator" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [coordinator]) }
end
it "returns all variants belonging to the sending producer" do
visible = permissions.editable_variants_for_incoming_exchanges_from(producer1)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "as a manager of the producer" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer1]) }
end
it "returns all variants belonging to the sending producer" do
visible = permissions.editable_variants_for_incoming_exchanges_from(producer1)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "as a manager of a hub which has been granted P-OC by the producer" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [hub]) }
create(:enterprise_relationship, parent: producer1, child: hub, permissions_list: [:add_to_order_cycle])
end
it "does not return variants produced by that producer" do
visible = permissions.editable_variants_for_incoming_exchanges_from(producer1)
expect(visible).to_not include v1, v2
end
end
end
describe "outgoing exchanges" do
context "as a manager of the coordinator" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [coordinator]) }
create(:enterprise_relationship, parent: producer1, child: hub, permissions_list: [:add_to_order_cycle])
end
it "returns all variants of any producer which has granted the outgoing hub P-OC" do
visible = permissions.editable_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1
expect(visible).to_not include v2
end
context "where the coordinator produces products" do
let!(:v3) { create(:variant, product: create(:simple_product, supplier: coordinator)) }
it "returns any variants produced by the coordinator itself for exchanges with 'self'" do
visible = permissions.editable_variants_for_outgoing_exchanges_to(coordinator)
expect(visible).to include v3
expect(visible).to_not include v1, v2
end
it "does not return coordinator's variants for exchanges with other hubs, when permission has not been granted" do
visible = permissions.editable_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1
expect(visible).to_not include v2, v3
end
end
# TODO: for backwards compatability, remove later
context "when an exchange exists between the coordinator and the hub within this order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
# producer2 produces v2 and has not granted P-OC to hub (or coordinator for that matter)
before { ex.variants << v2 }
it "returns those variants that are in the exchange" do
visible = permissions.editable_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1, v2
end
end
end
context "as manager of an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [hub]) }
create(:enterprise_relationship, parent: producer1, child: hub, permissions_list: [:add_to_order_cycle])
end
it "returns all variants of any producer which has granted the outgoing hub P-OC" do
visible = permissions.editable_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1
expect(visible).to_not include v2
end
# TODO: for backwards compatability, remove later
context "when an exchange exists between the coordinator and the hub within this order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
# producer2 produces v2 and has not granted P-OC to hub
before { ex.variants << v2 }
it "returns those variants that are in the exchange" do
visible = permissions.editable_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1, v2
end
end
end
context "as the manager of a producer which has granted P-OC to an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer1]) }
create(:enterprise_relationship, parent: producer1, child: hub, permissions_list: [:add_to_order_cycle])
end
context "where my producer is in the order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: producer1, receiver: coordinator, incoming: true) }
context "where the outgoing hub has granted P-OC to my producer" do
before do
create(:enterprise_relationship, parent: hub, child: producer1, permissions_list: [:add_to_order_cycle])
end
it "returns all of my produced variants" do
visible = permissions.editable_variants_for_outgoing_exchanges_to(hub)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "where the outgoing hub has not granted P-OC to my producer" do
# No permission granted
it "does not return my variants" do
visible = permissions.editable_variants_for_outgoing_exchanges_to(hub)
expect(visible).to_not include v1, v2
end
end
end
context "where my producer isn't in the order cycle" do
# No incoming exchange
it "does not return my variants" do
visible = permissions.editable_variants_for_outgoing_exchanges_to(hub)
expect(visible).to_not include v1, v2
end
end
end
context "as the manager of a producer which has not granted P-OC to an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer2]) }
create(:enterprise_relationship, parent: producer1, child: hub, permissions_list: [:add_to_order_cycle])
end
it "returns an empty array" do
expect(permissions.editable_variants_for_outgoing_exchanges_to(hub)).to eq []
end
# TODO: for backwards compatability, remove later
context "but which has variants already in the exchange" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
# This one won't be in the exchange, and so shouldn't be visible
let!(:v3) { create(:variant, product: create(:simple_product, supplier: producer2)) }
before { ex.variants << v2 }
it "does not return my variants" do
visible = permissions.editable_variants_for_outgoing_exchanges_to(hub)
expect(visible).to_not include v1, v2, v3
end
end
end
end
end
end
end

View File

@@ -21,302 +21,6 @@ module OpenFoodNetwork
end
end
describe "finding enterprises that can be viewed in the order cycle interface" do
let(:coordinator) { create(:distributor_enterprise) }
let(:hub) { create(:distributor_enterprise) }
let(:producer) { create(:supplier_enterprise) }
let(:oc) { create(:simple_order_cycle, coordinator: coordinator) }
context "when no order_cycle or coordinator are provided for reference" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [coordinator]) }
end
it "returns an empty scope" do
expect(permissions.order_cycle_enterprises_for(nil)).to be_empty
end
end
context "as a manager of the coordinator" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [coordinator]) }
end
it "returns the coordinator itself" do
expect(permissions.order_cycle_enterprises_for(oc)).to include coordinator
end
context "where P-OC has been granted to the coordinator by other enterprises" do
before do
create(:enterprise_relationship, parent: hub, child: coordinator, permissions_list: [:add_to_order_cycle])
end
context "where the coordinator sells any" do
it "returns enterprises which have granted P-OC to the coordinator" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include hub
expect(enterprises).to_not include producer
end
end
context "where the coordinator sells 'own'" do
before { coordinator.stub(:sells) { 'own' } }
it "returns just the coordinator" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to_not include hub, producer
end
end
end
context "where P-OC has not been granted to the coordinator by other enterprises" do
context "where the other enterprise are already in the order cycle" do
let!(:ex_incoming) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
let!(:ex_outgoing) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
context "where the coordinator sells any" do
it "returns enterprises which have granted P-OC to the coordinator" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include hub, producer
end
end
context "where the coordinator sells 'own'" do
before { coordinator.stub(:sells) { 'own' } }
it "returns just the coordinator" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to_not include hub, producer
end
end
end
context "where the other enterprises are not in the order cycle" do
it "returns just the coordinator" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to_not include hub, producer
end
end
end
end
context "as a manager of a hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [hub]) }
end
context "that has granted P-OC to the coordinator" do
before do
create(:enterprise_relationship, parent: hub, child: coordinator, permissions_list: [:add_to_order_cycle])
end
context "where my hub is in the order cycle" do
let!(:ex_outgoing) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
it "returns my hub" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include hub
expect(enterprises).to_not include producer, coordinator
end
context "and has been granted P-OC by a producer" do
before do
create(:enterprise_relationship, parent: producer, child: hub, permissions_list: [:add_to_order_cycle])
end
context "where the producer is in the order cycle" do
let!(:ex_incoming) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
it "returns the producer" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include producer, hub
end
end
context "where the producer is not in the order cycle" do
# No incoming exchange
it "does not return the producer" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to_not include producer
end
end
end
context "and has granted P-OC to a producer" do
before do
create(:enterprise_relationship, parent: hub, child: producer, permissions_list: [:add_to_order_cycle])
end
context "where the producer is in the order cycle" do
let!(:ex_incoming) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
it "returns the producer" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include producer, hub
end
end
context "where the producer is not in the order cycle" do
# No incoming exchange
it "does not return the producer" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to_not include producer
end
end
end
end
context "where my hub is not in the order cycle" do
# No outgoing exchange for my hub
it "does not return my hub" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to_not include hub, producer, coordinator
end
end
end
context "that has not granted P-OC to the coordinator" do
it "does not return my hub" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to_not include hub, producer, coordinator
end
context "but is already in the order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
it "returns my hub" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include hub
expect(enterprises).to_not include producer, coordinator
end
context "and distributes variants distributed by an unmanaged and unpermitted producer" do
before { ex.variants << create(:variant, product: create(:product, supplier: producer)) }
# TODO: update this when we are confident about P-OCs
it "returns that producer as well" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include producer, hub
expect(enterprises).to_not include coordinator
end
end
end
end
end
context "as a manager of a producer" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer]) }
end
context "which has granted P-OC to the coordinator" do
before do
create(:enterprise_relationship, parent: producer, child: coordinator, permissions_list: [:add_to_order_cycle])
end
context "where my producer is in the order cycle" do
let!(:ex_incoming) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
it "returns my producer" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include producer
expect(enterprises).to_not include hub, coordinator
end
context "and has been granted P-OC by a hub" do
before do
create(:enterprise_relationship, parent: hub, child: producer, permissions_list: [:add_to_order_cycle])
end
context "where the hub is also in the order cycle" do
let!(:ex_outgoing) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
it "returns the hub as well" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include producer, hub
expect(enterprises).to_not include coordinator
end
end
context "where the hub is not in the order cycle" do
# No outgoing exchange
it "does not return the hub" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to_not include hub
end
end
end
context "and has granted P-OC to a hub" do
before do
create(:enterprise_relationship, parent: producer, child: hub, permissions_list: [:add_to_order_cycle])
end
context "where the hub is also in the order cycle" do
let!(:ex_outgoing) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
it "returns the hub as well" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include producer, hub
expect(enterprises).to_not include coordinator
end
end
context "where the hub is not in the order cycle" do
# No outgoing exchange
it "does not return the hub" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to_not include hub
end
end
end
end
context "where my producer is not in the order cycle" do
# No incoming exchange for producer
it "does not return my producer" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to_not include hub, producer, coordinator
end
end
end
context "which has not granted P-OC to the coordinator" do
it "does not return my producer" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to_not include producer
end
context "but is already in the order cycle" do
let!(:ex_incoming) { create(:exchange, order_cycle: oc, sender: producer, receiver: coordinator, incoming: true) }
# TODO: update this when we are confident about P-OCs
it "returns my producer" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include producer
expect(enterprises).to_not include hub, coordinator
end
context "and has variants distributed by an outgoing hub" do
let!(:ex_outgoing) { create(:exchange, order_cycle: oc, sender: coordinator, receiver: hub, incoming: false) }
before { ex_outgoing.variants << create(:variant, product: create(:product, supplier: producer)) }
# TODO: update this when we are confident about P-OCs
it "returns that hub as well" do
enterprises = permissions.order_cycle_enterprises_for(oc)
expect(enterprises).to include producer, hub
expect(enterprises).to_not include coordinator
end
end
end
end
end
end
describe "finding enterprises whose profiles can be edited" do
let(:e) { double(:enterprise) }
@@ -404,502 +108,6 @@ module OpenFoodNetwork
end
end
describe "finding exchanges of an order cycle that an admin can manage" do
let!(:producer) { create(:supplier_enterprise) }
let(:oc) { create(:simple_order_cycle) }
describe "as the manager of the coordinator" do
let!(:ex_in) { create(:exchange, order_cycle: oc, sender: producer, receiver: e1, incoming: true) }
let!(:ex_out) { create(:exchange, order_cycle: oc, sender: e1, receiver: e2, incoming: false) }
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [e1]) }
end
it "returns all exchanges in the order cycle, regardless of E2E permissions" do
permissions.order_cycle_exchanges(oc).should include ex_in, ex_out
end
end
describe "as the manager of a hub" do
let!(:ex_in) { create(:exchange, order_cycle: oc, sender: producer, receiver: e1, incoming: true) }
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [e2]) }
end
context "where my hub is in the order cycle" do
let!(:ex_out) { create(:exchange, order_cycle: oc, sender: e1, receiver: e2, incoming: false) }
it "returns my hub's outgoing exchange" do
permissions.order_cycle_exchanges(oc).should == [ex_out]
end
context "where my hub has been granted P-OC by an incoming producer" do
before do
create(:enterprise_relationship, parent: producer, child: e2, permissions_list: [:add_to_order_cycle])
end
it "returns the producer's incoming exchange" do
permissions.order_cycle_exchanges(oc).should include ex_in
end
end
context "where my hub has not been granted P-OC by an incoming producer" do
it "returns the producers's incoming exchange, and my own outhoing exchange" do
permissions.order_cycle_exchanges(oc).should_not include ex_in
end
end
end
context "where my hub isn't in the order cycle" do
it "does not return the producer's incoming exchanges" do
permissions.order_cycle_exchanges(oc).should == []
end
end
# TODO: this is testing legacy behaviour for backwards compatability, remove when behaviour no longer required
describe "legacy compatability" do
context "where my hub's outgoing exchange contains variants of a producer I don't manage and has not given my hub P-OC" do
let!(:product) { create(:product, supplier: producer) }
let!(:variant) { create(:variant, product: product) }
let!(:ex_out) { create(:exchange, order_cycle: oc, sender: e1, receiver: e2, incoming: true) }
before { ex_out.variants << variant }
it "returns incoming exchanges supplying the variants in my outgoing exchange" do
permissions.order_cycle_exchanges(oc).should include ex_out
end
end
end
end
describe "as the manager of a producer" do
let!(:ex_out) { create(:exchange, order_cycle: oc, sender: e1, receiver: e2, incoming: false) }
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer]) }
end
context "where my producer supplies to the order cycle" do
let!(:ex_in) { create(:exchange, order_cycle: oc, sender: producer, receiver: e1, incoming: true) }
it "returns my producer's incoming exchange" do
permissions.order_cycle_exchanges(oc).should == [ex_in]
end
context "my producer has granted P-OC to an outgoing hub" do
before do
create(:enterprise_relationship, parent: producer, child: e2, permissions_list: [:add_to_order_cycle])
end
it "returns the hub's outgoing exchange" do
permissions.order_cycle_exchanges(oc).should include ex_out
end
end
context "my producer has not granted P-OC to an outgoing hub" do
it "does not return the hub's outgoing exchange" do
permissions.order_cycle_exchanges(oc).should_not include ex_out
end
end
end
context "where my producer doesn't supply the order cycle" do
it "does not return the hub's outgoing exchanges" do
permissions.order_cycle_exchanges(oc).should == []
end
end
# TODO: this is testing legacy behaviour for backwards compatability, remove when behaviour no longer required
describe "legacy compatability" do
context "where an outgoing exchange contains variants of a producer I manage" do
let!(:product) { create(:product, supplier: producer) }
let!(:variant) { create(:variant, product: product) }
before { ex_out.variants << variant }
context "where my producer supplies to the order cycle" do
let!(:ex_in) { create(:exchange, order_cycle: oc, sender: producer, receiver: e1, incoming: true) }
it "returns the outgoing exchange" do
permissions.order_cycle_exchanges(oc).should include ex_out
end
end
context "where my producer doesn't supply to the order cycle" do
it "does not return the outgoing exchange" do
permissions.order_cycle_exchanges(oc).should_not include ex_out
end
end
end
end
end
end
describe "finding the variants within a hypothetical exchange between two enterprises which are visible to a user" do
let!(:producer1) { create(:supplier_enterprise) }
let!(:producer2) { create(:supplier_enterprise) }
let!(:v1) { create(:variant, product: create(:simple_product, supplier: producer1)) }
let!(:v2) { create(:variant, product: create(:simple_product, supplier: producer2)) }
let(:oc) { create(:simple_order_cycle) }
describe "incoming exchanges" do
context "as a manager of the coordinator" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [e1]) }
end
it "returns all variants belonging to the sending producer" do
visible = permissions.visible_variants_for_incoming_exchanges_between(producer1, e1, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "as a manager of the producer" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer1]) }
end
it "returns all variants belonging to the sending producer" do
visible = permissions.visible_variants_for_incoming_exchanges_between(producer1, e1, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "as a manager of a hub which has been granted P-OC by the producer" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [e2]) }
create(:enterprise_relationship, parent: producer1, child: e2, permissions_list: [:add_to_order_cycle])
end
context "where the hub is in the order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: e1, receiver: e2, incoming: false) }
it "returns variants produced by that producer only" do
visible = permissions.visible_variants_for_incoming_exchanges_between(producer1, e1, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "where the hub is not in the order cycle" do
# No outgoing exchange
it "does not return variants produced by that producer" do
visible = permissions.visible_variants_for_incoming_exchanges_between(producer1, e1, order_cycle: oc)
expect(visible).to_not include v1, v2
end
end
end
end
describe "outgoing exchanges" do
context "as a manager of the coordinator" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [e1]) }
create(:enterprise_relationship, parent: producer1, child: e2, permissions_list: [:add_to_order_cycle])
end
it "returns all variants of any producer which has granted the outgoing hub P-OC" do
visible = permissions.visible_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2
end
context "where the coordinator produces products" do
let!(:v3) { create(:variant, product: create(:simple_product, supplier: e1)) }
it "returns any variants produced by the coordinator itself for exchanges with 'self'" do
visible = permissions.visible_variants_for_outgoing_exchanges_between(e1, e1, order_cycle: oc)
expect(visible).to include v3
expect(visible).to_not include v1, v2
end
it "does not return coordinator's variants for exchanges with other hubs, when permission has not been granted" do
visible = permissions.visible_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2, v3
end
end
# TODO: for backwards compatability, remove later
context "when an exchange exists between the coordinator and the hub within this order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: e1, receiver: e2, incoming: false) }
# producer2 produces v2 and has not granted P-OC to e2 (or e1 for that matter)
before { ex.variants << v2 }
it "returns those variants that are in the exchange" do
visible = permissions.visible_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1, v2
end
end
end
context "as manager of an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [e2]) }
create(:enterprise_relationship, parent: producer1, child: e2, permissions_list: [:add_to_order_cycle])
end
it "returns all variants of any producer which has granted the outgoing hub P-OC" do
visible = permissions.visible_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2
end
# TODO: for backwards compatability, remove later
context "when an exchange exists between the coordinator and the hub within this order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: e1, receiver: e2, incoming: false) }
# producer2 produces v2 and has not granted P-OC to e2
before { ex.variants << v2 }
it "returns those variants that are in the exchange" do
visible = permissions.visible_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1, v2
end
end
end
context "as the manager of a producer which has granted P-OC to an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer1]) }
create(:enterprise_relationship, parent: producer1, child: e2, permissions_list: [:add_to_order_cycle])
end
context "where my producer is in the order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: producer1, receiver: e1, incoming: true) }
it "returns all of my produced variants" do
visible = permissions.visible_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "where my producer isn't in the order cycle" do
# No incoming exchange
it "does not return my variants" do
visible = permissions.visible_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to_not include v1, v2
end
end
end
context "as the manager of a producer which has not granted P-OC to an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer2]) }
create(:enterprise_relationship, parent: producer1, child: e2, permissions_list: [:add_to_order_cycle])
end
it "returns an empty array" do
expect(permissions.visible_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)).to eq []
end
# TODO: for backwards compatability, remove later
context "but which has variants already in the exchange" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: e1, receiver: e2, incoming: false) }
# This one won't be in the exchange, and so shouldn't be visible
let!(:v3) { create(:variant, product: create(:simple_product, supplier: producer2)) }
before { ex.variants << v2 }
it "returns those variants that are in the exchange" do
visible = permissions.visible_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to_not include v1, v3
expect(visible).to include v2
end
end
end
end
end
describe "finding the variants within a hypothetical exchange between two enterprises which are editable by a user" do
let!(:producer1) { create(:supplier_enterprise) }
let!(:producer2) { create(:supplier_enterprise) }
let!(:v1) { create(:variant, product: create(:simple_product, supplier: producer1)) }
let!(:v2) { create(:variant, product: create(:simple_product, supplier: producer2)) }
let(:oc) { create(:simple_order_cycle) }
describe "incoming exchanges" do
context "as a manager of the coordinator" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [e1]) }
end
it "returns all variants belonging to the sending producer" do
visible = permissions.editable_variants_for_incoming_exchanges_between(producer1, e1, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "as a manager of the producer" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer1]) }
end
it "returns all variants belonging to the sending producer" do
visible = permissions.editable_variants_for_incoming_exchanges_between(producer1, e1, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "as a manager of a hub which has been granted P-OC by the producer" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [e2]) }
create(:enterprise_relationship, parent: producer1, child: e2, permissions_list: [:add_to_order_cycle])
end
it "does not return variants produced by that producer" do
visible = permissions.editable_variants_for_incoming_exchanges_between(producer1, e1, order_cycle: oc)
expect(visible).to_not include v1, v2
end
end
end
describe "outgoing exchanges" do
context "as a manager of the coordinator" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [e1]) }
create(:enterprise_relationship, parent: producer1, child: e2, permissions_list: [:add_to_order_cycle])
end
it "returns all variants of any producer which has granted the outgoing hub P-OC" do
visible = permissions.editable_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2
end
context "where the coordinator produces products" do
let!(:v3) { create(:variant, product: create(:simple_product, supplier: e1)) }
it "returns any variants produced by the coordinator itself for exchanges with 'self'" do
visible = permissions.editable_variants_for_outgoing_exchanges_between(e1, e1, order_cycle: oc)
expect(visible).to include v3
expect(visible).to_not include v1, v2
end
it "does not return coordinator's variants for exchanges with other hubs, when permission has not been granted" do
visible = permissions.editable_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2, v3
end
end
# TODO: for backwards compatability, remove later
context "when an exchange exists between the coordinator and the hub within this order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: e1, receiver: e2, incoming: false) }
# producer2 produces v2 and has not granted P-OC to e2 (or e1 for that matter)
before { ex.variants << v2 }
it "returns those variants that are in the exchange" do
visible = permissions.editable_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1, v2
end
end
end
context "as manager of an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [e2]) }
create(:enterprise_relationship, parent: producer1, child: e2, permissions_list: [:add_to_order_cycle])
end
it "returns all variants of any producer which has granted the outgoing hub P-OC" do
visible = permissions.editable_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2
end
# TODO: for backwards compatability, remove later
context "when an exchange exists between the coordinator and the hub within this order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: e1, receiver: e2, incoming: false) }
# producer2 produces v2 and has not granted P-OC to e2
before { ex.variants << v2 }
it "returns those variants that are in the exchange" do
visible = permissions.editable_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1, v2
end
end
end
context "as the manager of a producer which has granted P-OC to an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer1]) }
create(:enterprise_relationship, parent: producer1, child: e2, permissions_list: [:add_to_order_cycle])
end
context "where my producer is in the order cycle" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: producer1, receiver: e1, incoming: true) }
context "where the outgoing hub has granted P-OC to my producer" do
before do
create(:enterprise_relationship, parent: e2, child: producer1, permissions_list: [:add_to_order_cycle])
end
it "returns all of my produced variants" do
visible = permissions.editable_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to include v1
expect(visible).to_not include v2
end
end
context "where the outgoing hub has not granted P-OC to my producer" do
# No permission granted
it "does not return my variants" do
visible = permissions.editable_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to_not include v1, v2
end
end
end
context "where my producer isn't in the order cycle" do
# No incoming exchange
it "does not return my variants" do
visible = permissions.editable_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to_not include v1, v2
end
end
end
context "as the manager of a producer which has not granted P-OC to an outgoing hub" do
before do
permissions.stub(:managed_enterprises) { Enterprise.where(id: [producer2]) }
create(:enterprise_relationship, parent: producer1, child: e2, permissions_list: [:add_to_order_cycle])
end
it "returns an empty array" do
expect(permissions.editable_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)).to eq []
end
# TODO: for backwards compatability, remove later
context "but which has variants already in the exchange" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: e1, receiver: e2, incoming: false) }
# This one won't be in the exchange, and so shouldn't be visible
let!(:v3) { create(:variant, product: create(:simple_product, supplier: producer2)) }
before { ex.variants << v2 }
it "does not return my variants" do
visible = permissions.editable_variants_for_outgoing_exchanges_between(e1, e2, order_cycle: oc)
expect(visible).to_not include v1, v2, v3
end
end
end
end
end
describe "finding managed products" do
let!(:p1) { create(:simple_product) }
let!(:p2) { create(:simple_product) }

View File

@@ -1,3 +1,5 @@
require 'open_food_network/order_cycle_permissions'
describe Api::Admin::ExchangeSerializer do
let(:v1) { create(:variant) }
let(:v2) { create(:variant) }
@@ -7,8 +9,8 @@ describe Api::Admin::ExchangeSerializer do
before do
allow(OpenFoodNetwork::Permissions).to receive(:new) { permissions_mock }
allow(permissions_mock).to receive(:visible_variants_for_outgoing_exchanges_between) do
allow(OpenFoodNetwork::OrderCyclePermissions).to receive(:new) { permissions_mock }
allow(permissions_mock).to receive(:visible_variants_for_outgoing_exchanges_to) do
# This is the permitted list of variants
Spree::Variant.where(id: [v1] )
end
@@ -16,8 +18,7 @@ describe Api::Admin::ExchangeSerializer do
it "filters variants within the exchange based on permissions" do
visible_variants = serializer.variants
expect(permissions_mock).to have_received(:visible_variants_for_outgoing_exchanges_between).
with(exchange.sender, exchange.receiver, order_cycle: exchange.order_cycle)
expect(permissions_mock).to have_received(:visible_variants_for_outgoing_exchanges_to).with(exchange.receiver)
expect(exchange.variants).to include v1, v2
expect(visible_variants.keys).to include v1.id
expect(visible_variants.keys).to_not include v2.id