# frozen_string_literal: true require 'spec_helper' RSpec.describe Spree::OrderContents do let!(:order) { create(:order) } let!(:variant) { create(:variant) } subject { described_class.new(order) } context "#add" do context 'given quantity is not explicitly provided' do it 'should add one line item' do line_item = subject.add(variant) expect(line_item.quantity).to eq 1 expect(order.line_items.size).to eq 1 end end it 'should add line item if one does not exist' do line_item = subject.add(variant, 1) expect(line_item.quantity).to eq 1 expect(order.line_items.size).to eq 1 end it 'should update line item if one exists' do subject.add(variant, 1) line_item = subject.add(variant, 1) expect(line_item.quantity).to eq 2 expect(order.line_items.size).to eq 1 end it "should update order totals" do expect(order.item_total.to_f).to eq 0.00 expect(order.total.to_f).to eq 0.00 subject.add(variant, 1) expect(order.item_total.to_f).to eq 19.99 expect(order.total.to_f).to eq 19.99 end context "with a completed order" do let!(:order) { create(:completed_order_with_totals) } it "updates shipping fees" do expect(order).to receive(:update_shipping_fees!) subject.add(variant, 1) end end context "when passing a shipment" do let!(:order) { create(:order_with_line_items) } it "updates shipping fees" do shipment = order.shipments.first expect(order).to receive(:update_shipping_fees!) subject.add(variant, 1, shipment) end end end context "#remove" do context "given an invalid variant" do it "raises an exception" do expect { subject.remove(variant, 1) }.to raise_error(ActiveRecord::RecordNotFound) end end context 'given quantity is not explicitly provided' do it 'should remove line item' do subject.add(variant, 3) expect{ subject.remove(variant) }.to change { Spree::LineItem.count }.by(-1) end end it 'should reduce line_item quantity if quantity is less the line_item quantity' do line_item = subject.add(variant, 3) subject.remove(variant, 1) expect(line_item.reload.quantity).to eq 2 end it 'should remove line_item if quantity matches line_item quantity' do subject.add(variant, 1) subject.remove(variant, 1) expect(order.reload.find_line_item_by_variant(variant)).to be_nil end it "should update order totals" do expect(order.item_total.to_f).to eq 0.00 expect(order.total.to_f).to eq 0.00 subject.add(variant, 2) expect(order.item_total.to_f).to eq 39.98 expect(order.total.to_f).to eq 39.98 subject.remove(variant, 1) expect(order.item_total.to_f).to eq 19.99 expect(order.total.to_f).to eq 19.99 end context "with a completed order" do let!(:order) { create(:completed_order_with_totals) } it "updates shipping fees" do expect(order).to receive(:update_shipping_fees!) subject.remove(order.line_items.first.variant, 1) end end context "when passing a shipment" do let!(:order) { create(:order_with_line_items) } it "updates shipping fees" do shipment = order.reload.shipments.first expect(order).to receive(:update_shipping_fees!) subject.remove(order.line_items.first.variant, 1, shipment) end end end context "#update_cart" do let!(:line_item) { subject.add variant, 1 } let(:params) do { line_items_attributes: { "0" => { id: line_item.id, quantity: 3 } } } end it "changes item quantity" do subject.update_cart params expect(line_item.reload.quantity).to eq 3 end it "updates order totals" do expect { subject.update_cart params }.to change { subject.order.total } end context "submits item quantity 0" do let(:params) do { line_items_attributes: { "0" => { id: line_item.id, quantity: 0 } } } end it "removes item from order" do expect { subject.update_cart params }.to change { order.line_items.count } end end it "ensures updated shipments" do expect(subject.order).to receive(:ensure_updated_shipments) subject.update_cart params end context "with a completed order" do let!(:order) { create(:completed_order_with_totals) } it "updates shipping fees" do expect(order).to receive(:update_shipping_fees!) subject.update_cart params end end end describe "#update_item" do let!(:line_item) { subject.add variant, 1 } context "updating enterprise fees" do it "updates the line item's enterprise fees" do expect(order).to receive(:update_line_item_fees!).with(line_item) subject.update_item(line_item, { quantity: 3 }) end it "updates the order's enterprise fees if completed" do order.shipments << create(:shipment) allow(order).to receive(:completed?) { true } expect(order).to receive(:update_order_fees!) subject.update_item(line_item, { quantity: 3 }) end it "does not update the order's enterprise fees if not complete" do expect(order).not_to receive(:update_order_fees!) subject.update_item(line_item, { quantity: 3 }) end end it "ensures updated shipments" do expect(order).to receive(:ensure_updated_shipments) subject.update_item(line_item, { quantity: 3 }) end it "updates the order" do expect(order).to receive(:update_order!) subject.update_item(line_item, { quantity: 3 }) end context "with a completed order" do let!(:order) { create(:completed_order_with_totals) } it "updates shipping fees" do expect(order).to receive(:update_shipping_fees!) subject.update_item(order.line_items.first, { quantity: 3 }) end end end describe "#update_or_create" do describe "creating" do it "creates a new line item with given attributes" do subject.update_or_create(variant, { quantity: 2, max_quantity: 3 }) line_item = order.line_items.reload.first expect(line_item.quantity).to eq 2 expect(line_item.max_quantity).to eq 3 expect(line_item.price).to eq variant.price end it "ensures shipments are updated" do expect(order).to receive(:ensure_updated_shipments) subject.update_or_create(variant, { quantity: 2, max_quantity: 3 }) end context "with completed order" do let!(:order) { create(:completed_order_with_totals) } it "updates shipping fees" do expect(order).to receive(:update_shipping_fees!) subject.update_or_create(variant, { quantity: 2, max_quantity: 3 }) end end end describe "updating" do let!(:line_item) { subject.add variant, 2 } it "updates existing line item with given attributes" do subject.update_or_create(variant, { quantity: 3, max_quantity: 4 }) expect(line_item.reload.quantity).to eq 3 expect(line_item.max_quantity).to eq 4 end it "ensures shipments are updated" do expect(order).to receive(:ensure_updated_shipments) subject.update_or_create(variant, { quantity: 3, max_quantity: 4 }) end context "with completed order" do let!(:order) { create(:completed_order_with_totals) } it "updates shipping fees" do expect(order).to receive(:update_shipping_fees!) subject.update_or_create(variant, { quantity: 3, max_quantity: 4 }) end end end end end