require 'spec_helper' describe Spree::Api::ShipmentsController, :type => :controller do render_views let!(:shipment) { create(:shipment) } let!(:attributes) { [:id, :tracking, :number, :cost, :shipped_at, :stock_location_name, :order_id, :shipping_rates, :shipping_methods] } before do stub_authentication! end let!(:resource_scoping) { { id: shipment.to_param, shipment: { order_id: shipment.order.to_param } } } context "as a non-admin" do it "cannot make a shipment ready" do api_put :ready assert_not_found! end it "cannot make a shipment shipped" do api_put :ship assert_not_found! end end context "as an admin" do let!(:order) { shipment.order } let!(:stock_location) { create(:stock_location_with_items) } let!(:variant) { create(:variant) } sign_in_as_admin! # Start writing this spec a bit differently than before.... describe 'POST #create' do let(:params) do { variant_id: stock_location.stock_items.first.variant.to_param, shipment: { order_id: order.number }, stock_location_id: stock_location.to_param } end subject do api_post :create, params end [:variant_id, :stock_location_id].each do |field| context "when #{field} is missing" do before do params.delete(field) end it 'should return proper error' do subject expect(response.status).to eq(422) expect(json_response['exception']).to eq("param is missing or the value is empty: #{field.to_s}") end end end it 'should create a new shipment' do expect(subject).to be_ok expect(json_response).to have_attributes(attributes) end end it 'can update a shipment' do params = { shipment: { stock_location_id: stock_location.to_param } } api_put :update, params expect(response.status).to eq(200) expect(json_response['stock_location_name']).to eq(stock_location.name) end it "can make a shipment ready" do allow_any_instance_of(Spree::Order).to receive_messages(:paid? => true, :complete? => true) api_put :ready expect(json_response).to have_attributes(attributes) expect(json_response["state"]).to eq("ready") expect(shipment.reload.state).to eq("ready") end it "cannot make a shipment ready if the order is unpaid" do allow_any_instance_of(Spree::Order).to receive_messages(:paid? => false) api_put :ready expect(json_response["error"]).to eq("Cannot ready shipment.") expect(response.status).to eq(422) end context 'for completed shipments' do let(:order) { create :completed_order_with_totals } let!(:resource_scoping) { { id: order.shipments.first.to_param, shipment: { order_id: order.to_param } } } it 'adds a variant to a shipment' do api_put :add, { variant_id: variant.to_param, quantity: 2 } expect(response.status).to eq(200) expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"]).to eq(2) end it 'removes a variant from a shipment' do order.contents.add(variant, 2) api_put :remove, { variant_id: variant.to_param, quantity: 1 } expect(response.status).to eq(200) expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"]).to eq(1) end it 'removes a destroyed variant from a shipment' do order.contents.add(variant, 2) variant.destroy api_put :remove, { variant_id: variant.to_param, quantity: 1 } expect(response.status).to eq(200) expect(json_response['manifest'].detect { |h| h['variant']['id'] == variant.id }["quantity"]).to eq(1) end end context "can transition a shipment from ready to ship" do before do allow_any_instance_of(Spree::Order).to receive_messages(:paid? => true, :complete? => true) # For the shipment notification email Spree::Config[:mails_from] = "spree@example.com" shipment.update!(shipment.order) expect(shipment.state).to eq("ready") allow_any_instance_of(Spree::ShippingRate).to receive_messages(:cost => 5) end it "can transition a shipment from ready to ship" do shipment.reload api_put :ship, id: shipment.to_param, shipment: { tracking: "123123", order_id: shipment.order.to_param } expect(json_response).to have_attributes(attributes) expect(json_response["state"]).to eq("shipped") end end end end