Update cart by applying differences rather than clear-and-readd every time

This commit is contained in:
Rohan Mitchell
2015-11-10 11:22:57 +11:00
parent 7fffa03d8d
commit 178e5f59e6
3 changed files with 67 additions and 14 deletions

View File

@@ -11,13 +11,19 @@ Spree::OrderPopulator.class_eval do
if valid?
@order.with_lock do
@order.empty! if overwrite
variants = read_products_hash(from_hash) +
read_variants_hash(from_hash)
variants.each do |v|
attempt_cart_add(v[:variant_id], v[:quantity], v[:max_quantity])
if varies_from_cart(v)
attempt_cart_add(v[:variant_id], v[:quantity], v[:max_quantity])
end
end
if overwrite
variants_removed(variants).each do |id|
cart_remove(id)
end
end
end
end
@@ -54,6 +60,11 @@ Spree::OrderPopulator.class_eval do
end
end
def cart_remove(variant_id)
variant = Spree::Variant.find(variant_id)
@order.remove_variant(variant)
end
private

View File

@@ -206,18 +206,29 @@ feature "As a consumer I want to shop with a distributor", js: true do
end
end
describe "adding products to cart" do
describe "adding and removing products from cart" do
let(:exchange) { Exchange.find(oc1.exchanges.to_enterprises(distributor).outgoing.first.id) }
let(:product) { create(:simple_product) }
let(:variant) { create(:variant, product: product) }
before do
add_product_and_variant_to_order_cycle(exchange, product, variant)
set_order_cycle(order, oc1)
visit shop_path
end
it "should let us add products to our cart" do
fill_in "variants[#{variant.id}]", with: "1"
it "lets us add and remove products from our cart" do
fill_in "variants[#{variant.id}]", with: '1'
page.should have_in_cart product.name
wait_until { !cart_dirty }
li = Spree::Order.order(:created_at).last.line_items.order(:created_at).last
li.quantity.should == 1
fill_in "variants[#{variant.id}]", with: '0'
within('li.cart') { page.should_not have_content product.name }
wait_until { !cart_dirty }
Spree::LineItem.where(id: li).should be_empty
end
end

View File

@@ -9,11 +9,49 @@ module Spree
let(:order_cycle) { double(:order_cycle) }
let(:op) { OrderPopulator.new(order, currency) }
context "end-to-end" do
let(:order) { create(:order, distributor: distributor, order_cycle: order_cycle) }
let(:distributor) { create(:distributor_enterprise) }
let(:order_cycle) { create(:simple_order_cycle, distributors: [distributor], variants: [v]) }
let(:op) { OrderPopulator.new(order, nil) }
let(:v) { create(:variant) }
describe "populate" do
it "adds a variant" do
op.populate({variants: {v.id.to_s => {quantity: '1', max_quantity: '2'}}}, true)
li = order.find_line_item_by_variant(v)
li.should be
li.quantity.should == 1
li.max_quantity.should == 2
end
it "updates a variant's quantity and max quantity" do
order.add_variant v, 1, 2
op.populate({variants: {v.id.to_s => {quantity: '2', max_quantity: '3'}}}, true)
li = order.find_line_item_by_variant(v)
li.should be
li.quantity.should == 2
li.max_quantity.should == 3
end
it "removes a variant" do
order.add_variant v, 1, 2
op.populate({variants: {}}, true)
order.line_items(:reload)
li = order.find_line_item_by_variant(v)
li.should_not be
end
end
end
describe "populate" do
before do
op.should_receive(:distributor_and_order_cycle).
and_return([distributor, order_cycle])
end
it "checks that distribution can supply all products in the cart" do
op.should_receive(:distribution_can_supply_products_in_cart).
with(distributor, order_cycle).and_return(false)
@@ -22,13 +60,6 @@ module Spree
op.errors.to_a.should == ["That distributor or order cycle can't supply all the products in your cart. Please choose another."]
end
it "empties the order if override is true" do
op.stub(:distribution_can_supply_products_in_cart).and_return true
order.stub(:with_lock).and_yield
order.should_receive(:empty!)
op.populate(params, true)
end
it "locks the order" do
op.stub(:distribution_can_supply_products_in_cart).and_return(true)
order.should_receive(:with_lock)
@@ -37,9 +68,9 @@ module Spree
it "attempts cart add with max_quantity" do
op.stub(:distribution_can_supply_products_in_cart).and_return true
order.should_receive(:empty!)
params = {variants: {"1" => {quantity: 1, max_quantity: 2}}}
order.stub(:with_lock).and_yield
op.stub(:varies_from_cart) { true }
op.should_receive(:attempt_cart_add).with("1", 1, 2).and_return true
op.populate(params, true)
end