From c1aeb2e9a37cc829b79d362351b9107033af0643 Mon Sep 17 00:00:00 2001 From: luisramos0 Date: Fri, 14 Dec 2018 14:02:32 +0000 Subject: [PATCH] Improve naming in availability_validator_decorator and cover it with tests --- .../stock/availability_validator_decorator.rb | 12 +-- .../stock/availability_validator_spec.rb | 75 +++++++++++++++++++ 2 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 spec/models/spree/stock/availability_validator_spec.rb diff --git a/app/models/spree/stock/availability_validator_decorator.rb b/app/models/spree/stock/availability_validator_decorator.rb index 790778f181..29f9d0413c 100644 --- a/app/models/spree/stock/availability_validator_decorator.rb +++ b/app/models/spree/stock/availability_validator_decorator.rb @@ -3,10 +3,10 @@ Spree::Stock::AvailabilityValidator.class_eval do # OFN specific check for in-memory :skip_stock_check attribute return if line_item.skip_stock_check - quantity = adapt_line_item_quantity_to_inventory_units(line_item) - return if quantity == 0 + quantity_to_validate = line_item.quantity - quantity_in_shipment(line_item) + return if quantity_to_validate < 1 - validate_quantity(line_item, quantity) + validate_quantity(line_item, quantity_to_validate) end private @@ -14,12 +14,12 @@ Spree::Stock::AvailabilityValidator.class_eval do # This is an adapted version of a fix to the inventory_units not being considered here. # See #3090 for details. # This can be removed after upgrading to Spree 2.4. - def adapt_line_item_quantity_to_inventory_units(line_item) + def quantity_in_shipment(line_item) shipment = line_item_shipment(line_item) - return line_item.quantity unless shipment + return 0 unless shipment units = shipment.inventory_units_for(line_item.variant) - line_item.quantity - units.count + units.count end def line_item_shipment(line_item) diff --git a/spec/models/spree/stock/availability_validator_spec.rb b/spec/models/spree/stock/availability_validator_spec.rb new file mode 100644 index 0000000000..8eb29fbe0f --- /dev/null +++ b/spec/models/spree/stock/availability_validator_spec.rb @@ -0,0 +1,75 @@ +require 'spec_helper' + +module Spree + module Stock + describe AvailabilityValidator do + let(:validator) { AvailabilityValidator.new({}) } + + context "line item without existing inventory units" do + let(:order) { create(:order_with_line_items) } + let(:line_item) { order.line_items.first } + + before do + expect(order.shipment.inventory_units).to be_empty + expect(line_item.target_shipment).to be_nil + end + + context "available quantity when variant.on_hand > line_item.quantity" do + it "suceeds" do + line_item.quantity = line_item.variant.on_hand - 1 + validator.validate(line_item) + expect(line_item.errors[:quantity].size).to eq(0) + end + end + + context "unavailable quantity when variant.on_hand < line_item.quantity" do + it "fails" do + line_item.quantity = line_item.variant.on_hand + 1 + validator.validate(line_item) + expect_product_out_of_stock_error + end + + it "succeeds with line_item skip_stock_check" do + line_item.skip_stock_check = true + line_item.quantity = line_item.variant.on_hand + 1 + validator.validate(line_item) + expect(line_item.errors[:quantity].size).to eq(0) + end + end + end + + describe "line item with existing inventory units" do + let(:order) { create(:completed_order_with_totals) } + let(:line_item) { order.line_items.first } + + before do + expect(line_item.quantity).to eq(1) + expect(line_item.variant.on_hand).to eq(4) + + expect(order.shipment.inventory_units).to_not be_empty + expect(order.shipment.inventory_units_for(line_item.variant).size).to eq(1) + end + + context "when adding all variant.on_hand quantity to existing line_item quantity" do + it "succeeds because it excludes existing inventory units from the validation" do + line_item.quantity += line_item.variant.on_hand + validator.validate(line_item) + expect(line_item.errors[:quantity].size).to eq(0) + end + + it "fails if one more item is added" do + line_item.quantity += line_item.variant.on_hand + 1 + validator.validate(line_item) + expect_product_out_of_stock_error + end + end + end + + def expect_product_out_of_stock_error + quantity_error = line_item.errors[:quantity].first + expect(quantity_error).to include(line_item.variant.product.name) + expect(quantity_error).to include("out of stock") + end + end + end +end