Skip to content

Instantly share code, notes, and snippets.

@cored
Created February 21, 2018 21:16
Show Gist options
  • Save cored/0388971a8ed841c9ecda61b0a4889b95 to your computer and use it in GitHub Desktop.
Save cored/0388971a8ed841c9ecda61b0a4889b95 to your computer and use it in GitHub Desktop.
# == 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