mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-27 21:06:49 +00:00
149 lines
5.8 KiB
Ruby
149 lines
5.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
describe Spree::OrderInventory do
|
|
let(:order) { create :completed_order_with_totals }
|
|
let(:line_item) { order.line_items.first }
|
|
subject { described_class.new(order) }
|
|
|
|
it 'inventory_units_for should return array of units for a given variant' do
|
|
units = subject.inventory_units_for(line_item.variant)
|
|
expect(units.map(&:variant_id)).to eq [line_item.variant.id]
|
|
end
|
|
|
|
context "when order is missing inventory units" do
|
|
before do
|
|
line_item.update_column(:quantity, 2)
|
|
end
|
|
|
|
it 'should be a messed up order' do
|
|
expect(order.shipments.first.inventory_units_for(line_item.variant).size).to eq 1
|
|
expect(line_item.reload.quantity).to eq 2
|
|
end
|
|
|
|
it 'should increase the number of inventory units' do
|
|
subject.verify(line_item)
|
|
expect(order.reload.shipments.first.inventory_units_for(line_item.variant).size).to eq 2
|
|
end
|
|
end
|
|
|
|
context "#add_to_shipment" do
|
|
let(:shipment) { order.shipments.first }
|
|
let(:variant) { create :variant }
|
|
|
|
context "order is not completed" do
|
|
before { allow(order).to receive_messages completed?: false }
|
|
|
|
it "doesn't unstock items" do
|
|
expect(shipment.stock_location).not_to receive(:unstock)
|
|
expect(subject.send(:add_to_shipment, shipment, variant, 5)).to eq 5
|
|
end
|
|
end
|
|
|
|
it 'should create inventory_units in the necessary states' do
|
|
expect(shipment.stock_location).to receive(:fill_status).with(variant, 5).and_return([3, 2])
|
|
|
|
expect(subject.send(:add_to_shipment, shipment, variant, 5)).to eq 5
|
|
|
|
units = shipment.inventory_units.group_by(&:variant_id)
|
|
units = units[variant.id].group_by(&:state)
|
|
expect(units['backordered'].size).to eq 2
|
|
expect(units['on_hand'].size).to eq 3
|
|
end
|
|
|
|
it 'should create stock_movement' do
|
|
expect(subject.send(:add_to_shipment, shipment, variant, 5)).to eq 5
|
|
|
|
stock_item = shipment.stock_location.stock_item(variant)
|
|
movement = stock_item.stock_movements.last
|
|
expect(movement.quantity).to eq(-5)
|
|
end
|
|
end
|
|
|
|
context 'when order has too many inventory units' do
|
|
before do
|
|
line_item.quantity = 3
|
|
line_item.save!
|
|
|
|
line_item.update_column(:quantity, 2)
|
|
order.reload
|
|
end
|
|
|
|
it 'should be a messed up order' do
|
|
expect(order.shipments.first.inventory_units_for(line_item.variant).size).to eq 3
|
|
expect(line_item.quantity).to eq 2
|
|
end
|
|
|
|
it 'should decrease the number of inventory units' do
|
|
subject.verify(line_item)
|
|
expect(order.reload.shipments.first.inventory_units_for(line_item.variant).size).to eq 2
|
|
end
|
|
|
|
context '#remove_from_shipment' do
|
|
let(:shipment) { order.shipments.first }
|
|
let(:variant) { order.line_items.first.variant }
|
|
|
|
context "order is not completed" do
|
|
before { allow(order).to receive_messages completed?: false }
|
|
|
|
it "doesn't restock items" do
|
|
expect(shipment.stock_location).not_to receive(:restock)
|
|
expect(subject.send(:remove_from_shipment, shipment, variant, 1)).to eq 1
|
|
end
|
|
end
|
|
|
|
it 'should create stock_movement' do
|
|
expect(subject.send(:remove_from_shipment, shipment, variant, 1)).to eq 1
|
|
|
|
stock_item = shipment.stock_location.stock_item(variant)
|
|
movement = stock_item.stock_movements.last
|
|
expect(movement.quantity).to eq 1
|
|
end
|
|
|
|
it 'should destroy backordered units first' do
|
|
allow(shipment).to receive_messages(inventory_units_for: [build(:inventory_unit, variant_id: variant.id, state: 'backordered'),
|
|
build(:inventory_unit,
|
|
variant_id: variant.id, state: 'on_hand'),
|
|
build(:inventory_unit,
|
|
variant_id: variant.id, state: 'backordered')])
|
|
|
|
expect(shipment.inventory_units_for[0]).to receive(:destroy)
|
|
expect(shipment.inventory_units_for[1]).not_to receive(:destroy)
|
|
expect(shipment.inventory_units_for[2]).to receive(:destroy)
|
|
|
|
expect(subject.send(:remove_from_shipment, shipment, variant, 2)).to eq 2
|
|
end
|
|
|
|
it 'should destroy unshipped units first' do
|
|
allow(shipment).to receive_messages(inventory_units_for: [build(:inventory_unit, variant_id: variant.id, state: 'shipped'),
|
|
build(:inventory_unit,
|
|
variant_id: variant.id, state: 'on_hand')] )
|
|
|
|
expect(shipment.inventory_units_for[0]).not_to receive(:destroy)
|
|
expect(shipment.inventory_units_for[1]).to receive(:destroy)
|
|
|
|
expect(subject.send(:remove_from_shipment, shipment, variant, 1)).to eq 1
|
|
end
|
|
|
|
it 'only attempts to destroy as many units as are eligible, and return amount destroyed' do
|
|
allow(shipment).to receive_messages(inventory_units_for: [build(:inventory_unit, variant_id: variant.id, state: 'shipped'),
|
|
build(:inventory_unit,
|
|
variant_id: variant.id, state: 'on_hand')] )
|
|
|
|
expect(shipment.inventory_units_for[0]).not_to receive(:destroy)
|
|
expect(shipment.inventory_units_for[1]).to receive(:destroy)
|
|
|
|
expect(subject.send(:remove_from_shipment, shipment, variant, 1)).to eq 1
|
|
end
|
|
|
|
it 'should destroy self if not inventory units remain' do
|
|
allow(shipment.inventory_units).to receive_messages(count: 0)
|
|
expect(shipment).to receive(:destroy)
|
|
|
|
expect(subject.send(:remove_from_shipment, shipment, variant, 1)).to eq 1
|
|
end
|
|
end
|
|
end
|
|
end
|