Refresh products cache when exchange is changed or destroyed

This commit is contained in:
Rohan Mitchell
2016-02-05 10:37:05 +11:00
parent 146797ea61
commit 8af6866ae4
4 changed files with 120 additions and 8 deletions

View File

@@ -13,6 +13,9 @@ class Exchange < ActiveRecord::Base
validates_presence_of :order_cycle, :sender, :receiver
validates_uniqueness_of :sender_id, :scope => [:order_cycle_id, :receiver_id, :incoming]
after_save :refresh_products_cache
after_destroy :refresh_products_cache_from_destroy
accepts_nested_attributes_for :variants
scope :in_order_cycle, lambda { |order_cycle| where(order_cycle_id: order_cycle) }
@@ -75,4 +78,11 @@ class Exchange < ActiveRecord::Base
end
end
def refresh_products_cache
OpenFoodNetwork::ProductsCache.exchange_changed self
end
def refresh_products_cache_from_destroy
OpenFoodNetwork::ProductsCache.exchange_destroyed self
end
end

View File

@@ -50,6 +50,20 @@ module OpenFoodNetwork
end
def self.exchange_changed(exchange)
if exchange.incoming
refresh_incoming_exchanges(Exchange.where(id: exchange))
else
refresh_outgoing_exchange(exchange)
end
end
def self.exchange_destroyed(exchange)
exchange_changed exchange
end
def self.enterprise_fee_changed(enterprise_fee)
refresh_supplier_fee enterprise_fee
refresh_coordinator_fee enterprise_fee
@@ -73,19 +87,27 @@ module OpenFoodNetwork
end
def self.refresh_supplier_fee(enterprise_fee)
outgoing_exchanges = Set.new
incoming_exchanges(enterprise_fee.exchanges).each do |exchange|
outgoing_exchanges.merge outgoing_exchanges_with_variants(exchange.order_cycle, exchange.variant_ids)
end
outgoing_exchanges.each do |exchange|
def self.refresh_incoming_exchanges(exchanges)
incoming_exchanges(exchanges).map do |exchange|
outgoing_exchanges_with_variants(exchange.order_cycle, exchange.variant_ids)
end.flatten.uniq.each do |exchange|
refresh_cache exchange.receiver, exchange.order_cycle
end
end
def self.refresh_outgoing_exchange(exchange)
if exchange.order_cycle.dated? && !exchange.order_cycle.closed?
refresh_cache exchange.receiver, exchange.order_cycle
end
end
def self.refresh_supplier_fee(enterprise_fee)
refresh_incoming_exchanges(enterprise_fee.exchanges)
end
def self.refresh_coordinator_fee(enterprise_fee)
enterprise_fee.order_cycles.each do |order_cycle|
order_cycle_changed order_cycle

View File

@@ -164,6 +164,71 @@ module OpenFoodNetwork
end
describe "when an exchange is changed" do
let(:s) { create(:supplier_enterprise) }
let(:c) { create(:distributor_enterprise) }
let(:d1) { create(:distributor_enterprise) }
let(:d2) { create(:distributor_enterprise) }
let(:v) { create(:variant) }
let(:oc) { create(:open_order_cycle, coordinator: c) }
describe "incoming exchanges" do
let!(:ex1) { create(:exchange, order_cycle: oc, sender: s, receiver: c, incoming: true, variants: [v]) }
let!(:ex2) { create(:exchange, order_cycle: oc, sender: c, receiver: d1, incoming: false, variants: [v]) }
let!(:ex3) { create(:exchange, order_cycle: oc, sender: c, receiver: d2, incoming: false, variants: []) }
before { oc.reload }
it "updates distributions that include one of the supplier's variants" do
expect(ProductsCache).to receive(:refresh_cache).with(d1, oc).once
ProductsCache.exchange_changed ex1
end
it "doesn't update distributions that don't include any of the supplier's variants" do
expect(ProductsCache).to receive(:refresh_cache).with(d2, oc).never
ProductsCache.exchange_changed ex1
end
end
describe "outgoing exchanges" do
let!(:ex) { create(:exchange, order_cycle: oc, sender: c, receiver: d1, incoming: false) }
it "does not update for undated order cycles" do
oc.update_attributes! orders_open_at: nil, orders_close_at: nil
expect(ProductsCache).to receive(:refresh_cache).with(d1, oc).never
ProductsCache.exchange_changed ex
end
it "updates for upcoming order cycles" do
oc.update_attributes! orders_open_at: 1.week.from_now, orders_close_at: 2.weeks.from_now
expect(ProductsCache).to receive(:refresh_cache).with(d1, oc).once
ProductsCache.exchange_changed ex
end
it "updates for open order cycles" do
expect(ProductsCache).to receive(:refresh_cache).with(d1, oc).once
ProductsCache.exchange_changed ex
end
it "does not update for closed order cycles" do
oc.update_attributes! orders_open_at: 2.weeks.ago, orders_close_at: 1.week.ago
expect(ProductsCache).to receive(:refresh_cache).with(d1, oc).never
ProductsCache.exchange_changed ex
end
end
end
describe "when an exchange is destroyed" do
let(:exchange) { double(:exchange) }
it "triggers the same update as a change to the exchange" do
expect(ProductsCache).to receive(:exchange_changed).with(exchange)
ProductsCache.exchange_destroyed exchange
end
end
describe "when an enterprise fee is changed" do
let(:s) { create(:supplier_enterprise) }
let(:c) { create(:distributor_enterprise) }

View File

@@ -91,6 +91,21 @@ describe Exchange do
end
end
describe "products caching" do
let!(:exchange) { create(:exchange) }
it "refreshes the products cache on change" do
expect(OpenFoodNetwork::ProductsCache).to receive(:exchange_changed).with(exchange)
exchange.pickup_time = 'asdf'
exchange.save
end
it "refreshes the products cache on destruction" do
expect(OpenFoodNetwork::ProductsCache).to receive(:exchange_destroyed).with(exchange)
exchange.destroy
end
end
describe "scopes" do
let(:supplier) { create(:supplier_enterprise) }
let(:coordinator) { create(:distributor_enterprise, is_primary_producer: true) }