Created
February 21, 2018 21:16
-
-
Save cored/0388971a8ed841c9ecda61b0a4889b95 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# == Schema Information | |
# | |
# Table name: shipments | |
# | |
# id :integer not null, primary key | |
# number :string(255) | |
# order_number :string(255) | |
# shipping_address_id :integer | |
# status :string(255) | |
# tracking :string(255) | |
# tracking_info :jsonb | |
# shipped_at :datetime | |
# created_at :datetime | |
# updated_at :datetime | |
# warehouse_id :integer | |
# email :string(255) | |
# signature_required :boolean | |
# special_instructions :string(255) | |
# vip :boolean default(FALSE) | |
# order_completed_at :datetime | |
# intended_ship_date :date | |
# hold_for_arrival_on :date | |
# deleted_at :datetime | |
# shipment_batch_id :integer | |
# estimated_arrival_date :date | |
# actual_arrival_date :date | |
# hold_for_review :boolean | |
# delivery_availability :text | |
# order_admin_notes :text | |
# order_special_instructions :text | |
# admin_assigned :boolean | |
# courier_slot_id :integer | |
# text_message_number :string(255) | |
# carrier_service_option_id :integer | |
# box_sku :string | |
# third_party_fulfiller_id :string | |
# mattress_removal :boolean default(FALSE), not null | |
# originally_estimated_arrival_date :date | |
# easy_post_shipment_id :string | |
# messaged_ships_by :date | |
# selected_slot_window_start :datetime | |
# selected_slot_window_end :datetime | |
# shipping_preference :string | |
# shipment_timezone :string | |
# locale :string | |
# attempt_saturday_delivery :boolean default(FALSE), not null | |
# trading_partner_identifier :string | |
# tracking_status :string | |
# external_id_for_xpo :string | |
# | |
require 'rails_helper' | |
describe ShipmentSerializer do | |
describe '.to_json' do | |
let(:shipment) { build(:shipment) } | |
subject { ShipmentSerializer.new(shipment).to_json } | |
context 'the reserved at is set' do | |
before do | |
shipment.shipment_items.each do |item| | |
item.update_attributes(reserved_at: '2017-11-21 14:44:30 -0500') | |
end | |
end | |
it 'serializes the reserved at time' do | |
expect(JSON.parse(subject)['shipment']['reserved_at']).to eq('2017-11-21T14:44:30.000-05:00') | |
end | |
end | |
it "serializes the status" do | |
expect(JSON.parse(subject)['shipment']['status']).to include(shipment.status) | |
end | |
it "includes carrier_service_option id and name" do | |
expect(JSON.parse(subject)["shipment"]["carrier_service_option"]["id"]) | |
.to eq(shipment.carrier_service_option_id) | |
expect(JSON.parse(subject)["shipment"]["carrier_service_option"]["name"]) | |
.to eq(shipment.carrier_service_option.name) | |
end | |
context 'there is no warehouse node for the shipment' do | |
before do | |
WarehouseTradingPartnerInfo.create( | |
warehouse: shipment.warehouse, | |
trading_partner_identifier: '12NOTFORSHIPMENT', | |
) | |
end | |
it 'returns nil' do | |
expect(JSON.parse(subject)['shipment']['external_warehouse_identifier']).to be nil | |
end | |
end | |
context 'there is a warehouse node for the shipment' do | |
before do | |
WarehouseTradingPartnerInfo.create( | |
warehouse: shipment.warehouse, | |
trading_partner_identifier: shipment.trading_partner_identifier, | |
external_warehouse_identifier: 'TV05', | |
) | |
end | |
it 'returns nil' do | |
expect(JSON.parse(subject)['shipment']['external_warehouse_identifier']).to eq 'TV05' | |
end | |
end | |
context 'the shipment is not reserved' do | |
let(:shipment) { build(:shipment, reserve: false) } | |
it 'serializes the status' do | |
expect(JSON.parse(subject)['shipment']['reserved']).to be false | |
end | |
end | |
context 'when the shipment has mattress removal' do | |
before { shipment.mattress_removal = true } | |
it 'serializes mattress removal' do | |
expect(JSON.parse(subject)['shipment']['mattress_removal']).to be true | |
end | |
end | |
context 'the shipment is reserved' do | |
let(:shipment) { build(:shipment, reserve: true) } | |
it "serializes the status" do | |
expect(JSON.parse(subject)['shipment']['reserved']).to be true | |
end | |
end | |
context 'batch and purchase order information' do | |
let(:batch) { create(:shipment_batch) } | |
before { shipment.shipment_batch = batch } | |
it 'includes the batch ID' do | |
batch_id = JSON.parse(subject)['shipment']['shipment_batch_id'] | |
po_number = JSON.parse(subject)['shipment']['purchase_order_number'] | |
expect(batch_id).to eq(batch.id) | |
expect(po_number).to be_nil | |
end | |
context 'when the batch has a purchase order' do | |
let(:purchase_order) { create(:purchase_order) } | |
before { batch.purchase_order = purchase_order } | |
it 'purchase order information' do | |
batch_id = JSON.parse(subject)['shipment']['shipment_batch_id'] | |
po_number = JSON.parse(subject)['shipment']['purchase_order_number'] | |
expect(batch_id).to eq(batch.id) | |
expect(po_number).to eq("CS#{purchase_order.id}") | |
end | |
end | |
end | |
it 'includes the address' do | |
addr_in_json = JSON.parse(subject)['shipment']['shipping_address'] | |
expect(addr_in_json['address1']).to eq(shipment.shipping_address.address1) | |
expect(addr_in_json['address2']).to eq(shipment.shipping_address.address2) | |
expect(addr_in_json['city']).to eq(shipment.shipping_address.city) | |
expect(addr_in_json['zipcode']).to eq(shipment.shipping_address.zipcode) | |
expect(addr_in_json['state']).to eq(shipment.shipping_address.state) | |
expect(addr_in_json['country']).to eq(shipment.shipping_address.country_code) | |
end | |
it 'includes the email' do | |
expect(JSON.parse(subject)['shipment']['email']).to eq(shipment.email) | |
end | |
it "includes estimated_arrival_date" do | |
shipment = create(:shipment, estimated_arrival_date: Date.tomorrow) | |
json = ShipmentSerializer.new(shipment).to_json | |
expect(JSON.parse(json)["shipment"]["estimated_arrival_date"]).to eq(Date.tomorrow.strftime('%Y-%m-%d')) | |
end | |
it "does *not* include shipping_method" do | |
carrier_service_option = create(:carrier_service_option, carrier: create(:ups_carrier), | |
name: 'UPS 2nd Day Air', | |
service_code: '02') | |
create(:shipment, carrier_service_option: carrier_service_option) | |
shipment_hash = JSON.parse(subject)["shipment"] | |
expect(shipment_hash["shipping_method"]).to be_nil | |
end | |
it 'includes the order completed at date' do | |
placed_at_time = Time.zone.now.to_datetime | |
shipment = create :shipment, order_completed_at: placed_at_time | |
json = JSON.parse(ShipmentSerializer.new(shipment).to_json)['shipment'] | |
expect(json['order_completed_at']).to eq(shipment.order_completed_at.to_s) | |
end | |
it 'has no variations' do | |
variations = JSON.parse(subject)['shipment']['variations'] | |
expect(variations).to eq [] | |
end | |
context 'when a shipment has a tracking code' do | |
let(:tracking_code) { "ABC" } | |
let(:carrier) { create(:ups_carrier) } | |
let(:shipment) { create(:shipment, carrier: carrier, tracking: tracking_code) } | |
it 'includes tracking link' do | |
hash = JSON.parse(subject)["shipment"] | |
expect(hash["tracking_link"]) | |
.to eq("https://wwwapps.ups.com/WebTracking/track?track=yes&trackNums=ABC&loc=en_US") | |
end | |
end | |
context 'when a shipment does not have a tracking code' do | |
let(:carrier) { create(:ups_carrier) } | |
let(:shipment) { create(:shipment, carrier: carrier, tracking: nil) } | |
it 'does not include a tracking link' do | |
hash = JSON.parse(subject)["shipment"] | |
expect(hash["tracking_link"]).to be_blank | |
end | |
end | |
describe "tracking_info" do | |
let(:carrier) { create(:generic_courier, name: "Some Courier") } | |
let(:shipment) { create(:shipment, carrier_service_option: carrier.carrier_service_options.first) } | |
it "includes the scheduled_delivery_date" do | |
estimated_arrival_date = Time.zone.today + 4.days | |
shipment.estimated_arrival_date = estimated_arrival_date | |
json = ShipmentSerializer.new(shipment).to_json | |
date_str = JSON.parse(json)["shipment"]["tracking_info"]["scheduled_delivery_date"] | |
expect(Date.parse(date_str)).to eq estimated_arrival_date | |
end | |
it "includes the actual_delivery_date" do | |
actual_arrival_date = Time.zone.today + 5.days | |
shipment.actual_arrival_date = actual_arrival_date | |
json = ShipmentSerializer.new(shipment).to_json | |
date_str = JSON.parse(json)["shipment"]["tracking_info"]["actual_delivery_date"] | |
expect(Date.parse(date_str)).to eq actual_arrival_date | |
end | |
it "includes the carrier name" do | |
json = ShipmentSerializer.new(shipment).to_json | |
shipment_hash = JSON.parse(json)["shipment"] | |
expect(shipment_hash["tracking_info"]["carrier_name"]).to eq("Some Courier") | |
end | |
it "includes the carrier courier boolean" do | |
json = ShipmentSerializer.new(shipment).to_json | |
shipment_hash = JSON.parse(json)["shipment"] | |
expect(shipment_hash["tracking_info"]["courier"]).to eq(true) | |
end | |
it "does not include 'shipment_events'" do | |
shipment.update_attributes(tracking_info: {'shipment_events' => [{name: 'an event'}]}) | |
json = ShipmentSerializer.new(shipment).to_json | |
shipment_hash = JSON.parse(json)["shipment"] | |
expect(shipment_hash["tracking_info"].keys).to_not include('shipment_events') | |
end | |
context 'when the shipment is national courier', :vcr do | |
let(:shipment) { | |
create( | |
:shipment, | |
:national_courier, | |
carrier_service_option: carrier.carrier_service_options.first, | |
number: "NUMBER", | |
) | |
} | |
context 'when the shipment is canceled' do | |
before do | |
shipment.update_attributes(status: 'canceled') | |
end | |
context 'when the shipment has a courier leg', :vcr do | |
it 'includes an empty carrier name' do | |
json = ShipmentSerializer.new(shipment).to_json | |
shipment_hash = JSON.parse(json)["shipment"] | |
expect(shipment_hash["tracking_info"]["carrier_name"]).to eq('XPO') | |
end | |
end | |
context 'when the shipment has no courier leg' do | |
before do | |
shipment.transit_legs.courier.last.destroy | |
shipment.reload | |
end | |
it "includes the carrier name of the courier_leg" do | |
json = ShipmentSerializer.new(shipment).to_json | |
shipment_hash = JSON.parse(json)["shipment"] | |
expect(shipment_hash["tracking_info"]["carrier_name"]).to eq('') | |
end | |
end | |
end | |
context 'when the shipment has a courier leg' do | |
it "includes the carrier courier boolean" do | |
json = ShipmentSerializer.new(shipment).to_json | |
shipment_hash = JSON.parse(json)["shipment"] | |
expect(shipment_hash["tracking_info"]["courier"]).to eq(true) | |
end | |
end | |
end | |
end | |
describe 'items' do | |
subject(:items_payload) do | |
JSON.parse(ShipmentSerializer.new(shipment).to_json)['shipment']['items'] | |
end | |
let(:product_1) { build_stubbed(:product) } | |
let(:product_2) { build_stubbed(:product) } | |
let(:shipment) { build_stubbed(:shipment, products: [product_1, product_1, product_2]) } | |
context 'single package shipment' do | |
it "includes the products and their quantities" do | |
expect(items_payload).to match_array( | |
[ | |
{'product_id' => product_1.sku, 'quantity' => 2}, | |
{'product_id' => product_2.sku, 'quantity' => 1}, | |
] | |
) | |
end | |
end | |
context 'multi package shipment' do | |
subject(:specific_product) do | |
items_payload.select { |h| h['product_id'] == product_1.sku }.first | |
end | |
let(:product_1) { build_stubbed(:adjustable_bedframe_product) } | |
let(:shipment) { build_stubbed(:shipment, products: [product_1]) } | |
it 'sets the quantity to one' do | |
expect(specific_product['quantity']).to eq(1) | |
end | |
end | |
end | |
it "includes courier_status" do | |
expect(JSON.parse(subject)["shipment"]["courier_status"]).to eq("not_contacted") | |
end | |
context "when it has a warehouse" do | |
before do | |
shipment.warehouse = warehouse | |
shipment.save! | |
end | |
let(:warehouse) { create :warehouse } | |
subject { JSON.parse(ShipmentSerializer.new(shipment).to_json)['shipment'] } | |
it "includes the warehouse name" do | |
expect(subject['warehouse_name']).to eq warehouse.name | |
end | |
it "includes the warehouse id" do | |
expect(subject['warehouse_id']).to eq warehouse.id | |
end | |
end | |
context "when a shipment has been assigned inventory items" do | |
let(:shipment) { create(:shipment, reserve: true, products: products) } | |
let(:product) { create(:pillow_product) } | |
let(:products) { [product, product] } | |
let(:variation) { product.variations.first } | |
subject { JSON.parse(ShipmentSerializer.new(shipment).to_json)['shipment'] } | |
it "serializes the variations" do | |
expect(subject['variations']).to eq( | |
[{ | |
"sku" => variation.sku, | |
"variant_sku" => variation.product.sku, | |
"quantity" => 2, | |
"variant_quantity" => variation.product_quantity, | |
}] | |
) | |
end | |
context 'when there is a split variation product' do | |
let(:product) { create(:adjustable_bedframe_product) } | |
let(:products) { [product] } | |
it 'splits the variant_quantity by number of variations in product' do | |
expect(subject['variations']).to match_array( | |
product.variations.map do |variation| | |
{ | |
"sku" => variation.sku, | |
"variant_sku" => variation.product.sku, | |
"quantity" => 1, | |
"variant_quantity" => 0.5, | |
} | |
end | |
) | |
end | |
end | |
end | |
it 'serializes locale' do | |
expect(JSON.parse(subject)['shipment']['locale']).to eq shipment.locale | |
end | |
context 'when the shipment_timezone is set' do | |
before { shipment.shipment_timezone = 'Fake/Timezone' } | |
it 'serializes the shipment_timezone' do | |
expect(JSON.parse(subject)['shipment']['timezone']).to eq shipment.shipment_timezone | |
end | |
end | |
context 'when the shipment_timezone is nil' do | |
it 'serializes the shipping_address timezone' do | |
expect(JSON.parse(subject)['shipment']['timezone']).to eq shipment.shipping_address.timezone | |
end | |
end | |
describe 'send_shipped_notification' do | |
context 'when it is national courier', :vcr do | |
let(:shipment) { create(:shipped_shipment, :national_courier, number: "NUMBER") } | |
context 'when the shipment is NOT the first shipment in the order to ship' do | |
let!(:shipment2) { create(:shipped_shipment) } | |
it 'is false' do | |
expect(JSON.parse(subject)['shipment']['send_shipped_notification']).to be false | |
end | |
end | |
context 'when the shipment IS the first shipment in the order to ship', :vcr do | |
it 'is true' do | |
expect(JSON.parse(subject)['shipment']['send_shipped_notification']).to be true | |
end | |
end | |
end | |
context 'when it is not national courier' do | |
context 'when the shipment is NOT the first shipment in the order to ship' do | |
let!(:shipment2) { create(:shipped_shipment) } | |
it 'is true' do | |
expect(JSON.parse(subject)['shipment']['send_shipped_notification']).to be true | |
end | |
end | |
context 'when the shipment IS the first shipment in the order to ship' do | |
it 'is true' do | |
expect(JSON.parse(subject)['shipment']['send_shipped_notification']).to be true | |
end | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment