mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Replace proxies with modules
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
require 'open_food_network/variant_proxy'
|
||||
require 'open_food_network/scope_variant_to_hub'
|
||||
|
||||
class Api::ProductSerializer < ActiveModel::Serializer
|
||||
# TODO
|
||||
@@ -43,9 +43,13 @@ class Api::CachedProductSerializer < ActiveModel::Serializer
|
||||
has_one :master, serializer: Api::VariantSerializer
|
||||
|
||||
def variants
|
||||
# We use the in_stock? method here instead of the in_stock scope because we need to
|
||||
# look up the stock as overridden by VariantOverrides, and the scope method is not affected
|
||||
# by them.
|
||||
|
||||
object.variants.
|
||||
for_distribution(options[:current_order_cycle], options[:current_distributor]).
|
||||
in_stock.
|
||||
map { |v| OpenFoodNetwork::VariantProxy.new(v, options[:current_distributor]) }
|
||||
each { |v| v.scope_to_hub options[:current_distributor] }.
|
||||
select(&:in_stock?)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
require 'open_food_network/variant_proxy'
|
||||
|
||||
module OpenFoodNetwork
|
||||
# Variants can have several fields overridden on a per-enterprise basis by the
|
||||
# VariantOverride model. These overrides can be applied to variants by wrapping their
|
||||
# products in this proxy, which wraps the product's variants in VariantProxy.
|
||||
class ProductProxy
|
||||
instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$)/ }
|
||||
|
||||
def initialize(product, hub)
|
||||
@product = product
|
||||
@hub = hub
|
||||
end
|
||||
|
||||
def variants
|
||||
@product.variants.map { |v| VariantProxy.new(v, @hub) }
|
||||
end
|
||||
|
||||
def method_missing(name, *args, &block)
|
||||
@product.send(name, *args, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
18
lib/open_food_network/scope_variant_to_hub.rb
Normal file
18
lib/open_food_network/scope_variant_to_hub.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
module OpenFoodNetwork
|
||||
module ScopeVariantToHub
|
||||
def price
|
||||
VariantOverride.price_for(@hub, self) || super
|
||||
end
|
||||
|
||||
def count_on_hand
|
||||
VariantOverride.count_on_hand_for(@hub, self) || super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Spree::Variant.class_eval do
|
||||
def scope_to_hub(hub)
|
||||
extend OpenFoodNetwork::ScopeVariantToHub
|
||||
@hub = hub
|
||||
end
|
||||
end
|
||||
@@ -1,27 +0,0 @@
|
||||
module OpenFoodNetwork
|
||||
# Variants can have several fields overridden on a per-enterprise basis by the
|
||||
# VariantOverride model. These overrides can be applied to variants by wrapping in an
|
||||
# instance of the VariantProxy class. This class proxies most methods back to the wrapped
|
||||
# variant, but checks for overrides when fetching some properties.
|
||||
class VariantProxy
|
||||
instance_methods.each { |m| undef_method m unless m =~ /(^__|^send$|^object_id$)/ }
|
||||
|
||||
def initialize(variant, hub)
|
||||
@variant = variant
|
||||
@hub = hub
|
||||
end
|
||||
|
||||
def price
|
||||
VariantOverride.price_for(@hub, @variant) || @variant.price
|
||||
end
|
||||
|
||||
def price_with_fees(distributor, order_cycle)
|
||||
price + @variant.fees_for(distributor, order_cycle)
|
||||
end
|
||||
|
||||
|
||||
def method_missing(name, *args, &block)
|
||||
@variant.send(name, *args, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,27 +0,0 @@
|
||||
require 'open_food_network/product_proxy'
|
||||
require 'open_food_network/variant_proxy'
|
||||
|
||||
module OpenFoodNetwork
|
||||
describe ProductProxy do
|
||||
let(:hub) { double(:hub) }
|
||||
let(:p) { double(:product, name: 'name') }
|
||||
let(:pp) { ProductProxy.new(p, hub) }
|
||||
|
||||
describe "delegating calls to proxied product" do
|
||||
it "delegates name" do
|
||||
pp.name.should == 'name'
|
||||
end
|
||||
end
|
||||
|
||||
describe "fetching the variants" do
|
||||
let(:v1) { double(:variant) }
|
||||
let(:v2) { double(:variant) }
|
||||
let(:p) { double(:product, variants: [v1, v2]) }
|
||||
|
||||
it "returns variants wrapped in VariantProxy" do
|
||||
# #class is proxied too, so we test that it worked by #object_id
|
||||
pp.variants.map(&:object_id).sort.should_not == [v1.object_id, v2.object_id].sort
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
35
spec/lib/open_food_network/scope_variant_to_hub_spec.rb
Normal file
35
spec/lib/open_food_network/scope_variant_to_hub_spec.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
require 'open_food_network/scope_variant_to_hub'
|
||||
|
||||
module OpenFoodNetwork
|
||||
describe ScopeVariantToHub do
|
||||
let(:hub) { create(:distributor_enterprise) }
|
||||
let(:v) { create(:variant, price: 11.11, count_on_hand: 1) }
|
||||
let(:vo) { create(:variant_override, hub: hub, variant: v, price: 22.22, count_on_hand: 2) }
|
||||
|
||||
describe "overriding price" do
|
||||
it "returns the overridden price when one is present" do
|
||||
vo
|
||||
v.scope_to_hub hub
|
||||
v.price.should == 22.22
|
||||
end
|
||||
|
||||
it "returns the variant's price otherwise" do
|
||||
v.scope_to_hub hub
|
||||
v.price.should == 11.11
|
||||
end
|
||||
end
|
||||
|
||||
describe "overriding stock levels" do
|
||||
it "returns the overridden stock level when one is present" do
|
||||
vo
|
||||
v.scope_to_hub hub
|
||||
v.count_on_hand.should == 2
|
||||
end
|
||||
|
||||
it "returns the variant's stock level otherwise" do
|
||||
v.scope_to_hub hub
|
||||
v.count_on_hand.should == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,27 +0,0 @@
|
||||
require 'open_food_network/variant_proxy'
|
||||
|
||||
module OpenFoodNetwork
|
||||
describe VariantProxy do
|
||||
let(:hub) { double(:hub) }
|
||||
let(:v) { double(:variant, sku: 'sku123', price: 'global price') }
|
||||
let(:vp) { VariantProxy.new(v, hub) }
|
||||
|
||||
describe "delegating calls to proxied variant" do
|
||||
it "delegates sku" do
|
||||
vp.sku.should == 'sku123'
|
||||
end
|
||||
end
|
||||
|
||||
describe "looking up the price" do
|
||||
it "returns the override price when there is one" do
|
||||
VariantOverride.stub(:price_for) { 'override price' }
|
||||
vp.price.should == 'override price'
|
||||
end
|
||||
|
||||
it "returns the global price otherwise" do
|
||||
VariantOverride.stub(:price_for) { nil }
|
||||
vp.price.should == 'global price'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user