require 'test_helper' class ShipmentPackerTest < Minitest::Test def setup @dimensions = [5.1, 15.2, 30.5] end def test_pack_divide_order_into_a_single_package items = [{:grams => 1, :quantity => 1, :price => 1.0}] packages = ShipmentPacker.pack(items, @dimensions, 1, 'USD') assert_equal 1, packages.size package = packages.first assert_equal 1, package.weight end def test_divide_order_with_multiple_lines_into_a_single_package items = [{:grams => 1, :quantity => 2, :price => 1.0}] packages = ShipmentPacker.pack(items, @dimensions, 2, 'USD') assert_equal 1, packages.size package = packages.first assert_equal 2, package.weight end def test_divide_order_with_single_line_into_two_packages items = [{:grams => 1, :quantity => 2, :price => 1.0}] packages = ShipmentPacker.pack(items, @dimensions, 1, 'USD') assert_equal 2, packages.size packages.each do |package| assert_equal 1, package.weight end end def test_divide_order_with_multiple_lines_into_two_packages items = [ {:grams => 1, :quantity => 1, :price => 1.0}, {:grams => 1, :quantity => 1, :price => 1.0} ] packages = ShipmentPacker.pack(items, @dimensions, 1, 'USD') assert_equal 2, packages.size packages.each do |package| assert_equal 1, package.weight end end def test_divide_order_into_two_packages_mixing_line_items items = [ {:grams => 1, :quantity => 1, :price => 1.0}, {:grams => 1, :quantity => 1, :price => 1.0}, {:grams => 1, :quantity => 1, :price => 1.0} ] packages = ShipmentPacker.pack(items, @dimensions, 2, 'USD') assert_equal 2, packages.size assert_equal 2, packages[0].weight assert_equal 1, packages[1].weight end def test_raise_overweight_exception_when_a_single_item_exceeds_the_maximum_weight_of_a_package assert_raises(ShipmentPacker::OverweightItem) do items = [{:grams => 2, :quantity => 1, :price => 1.0}] ShipmentPacker.pack(items, @dimensions, 1, 'USD') end end def test_raise_over_weight_exceptions_before_over_package_limit_exceptions assert_raises(ShipmentPacker::OverweightItem) do items = [{:grams => 5, :quantity => ShipmentPacker::EXCESS_PACKAGE_QUANTITY_THRESHOLD + 1, :price => 1.0}] ShipmentPacker.pack(items, @dimensions, 4, 'USD') end end def test_returns_an_empty_list_when_no_items_provided assert_equal [], ShipmentPacker.pack([], @dimensions, 1, 'USD') end def test_add_summarized_prices_for_all_items_and_currency_to_package items = [ {:grams => 1, :quantity => 3, :price => 1.0}, {:grams => 2, :quantity => 1, :price => 2.0} ] packages = ShipmentPacker.pack(items, @dimensions, 5, 'USD') assert_equal 1, packages.size assert_equal 500, packages.first.value assert_equal 'USD', packages.first.currency end def test_divide_items_and_prices_accordingly_when_splitting_into_two_packages items = [ {:grams => 1, :quantity => 1, :price => 1.0}, {:grams => 1, :quantity => 1, :price => 1.0}, {:grams => 1, :quantity => 1, :price => 1.0} ] packages = ShipmentPacker.pack(items, @dimensions, 2, 'USD') assert_equal 2, packages.size assert_equal 200, packages[0].value assert_equal 100, packages[1].value assert_equal 'USD', packages[0].currency assert_equal 'USD', packages[1].currency end def test_symbolize_item_keys string_key_items = [{'grams' => 1, 'quantity' => 1, 'price' => 1.0}] indifferent_access_items = [{'grams' => 1, 'quantity' => 1, 'price' => 1.0}.with_indifferent_access] [string_key_items, indifferent_access_items].each do |items| packages = ShipmentPacker.pack(items, @dimensions, 1, 'USD') assert_equal 1, packages.size package = packages.first assert_equal 1, package.weight assert_equal 100, package.value end end def test_cast_quantity_and_grams_to_int items = [{:grams => '1', :quantity => '1', :price => '1.0'}] packages = ShipmentPacker.pack(items, @dimensions, 1, 'USD') package = packages.first assert_equal 1, package.weight assert_equal 100, package.value end def test_excess_packages assert_raises(ShipmentPacker::ExcessPackageQuantity) do items = [{:grams => 1, :quantity => ShipmentPacker::EXCESS_PACKAGE_QUANTITY_THRESHOLD + 1, :price => 1.0}] ShipmentPacker.pack(items, @dimensions, 1, 'USD') end end def test_lots_of_zero_weight_items items = [{:grams => 0, :quantity => 1_000_000, :price => 1.0}] packages = ShipmentPacker.pack(items, @dimensions, 1, 'USD') assert_equal 1, packages.size assert_equal 0, packages[0].grams assert_equal 100_000_000, packages[0].value end def test_dont_destroy_input_items items = [{:grams => 1, :quantity => 5, :price => 1.0}] packages = ShipmentPacker.pack(items, @dimensions, 10, 'USD') assert_equal 1, items.size assert_equal 1, packages.size end def test_dont_modify_input_item_quantities items = [{:grams => 1, :quantity => 5, :price => 1.0}] ShipmentPacker.pack(items, @dimensions, 10, 'USD') assert_equal 5, items.first[:quantity] end def test_items_with_negative_weight items = [{:grams => -1, :quantity => 5, :price => 1.0}] ShipmentPacker.pack(items, @dimensions, 10, 'USD') assert_equal 5, items.first[:quantity] end end