solidus_easypost 1.0.3 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.circleci/config.yml +41 -0
- data/.gem_release.yml +5 -0
- data/.github/stale.yml +17 -0
- data/.github_changelog_generator +2 -0
- data/.gitignore +21 -0
- data/.rspec +2 -0
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +36 -0
- data/CHANGELOG.md +113 -0
- data/Gemfile +33 -0
- data/LICENSE +26 -0
- data/README.md +194 -0
- data/Rakefile +6 -0
- data/app/controllers/spree/admin/postage_labels_controller.rb +20 -0
- data/app/decorators/models/solidus_easypost/spree/carton_decorator.rb +38 -0
- data/app/decorators/models/solidus_easypost/spree/shipment_decorator.rb +47 -0
- data/app/decorators/models/solidus_easypost/spree/shipping_rate_decorator.rb +13 -0
- data/app/models/solidus_easypost/parcel_dimension.rb +34 -0
- data/app/models/solidus_easypost/return_authorization.rb +27 -0
- data/app/overrides/spree/admin/orders/_shipment/add_postage_label.html.erb.deface +10 -0
- data/bin/console +17 -0
- data/bin/rails +7 -0
- data/bin/rails-engine +13 -0
- data/bin/rails-sandbox +16 -0
- data/bin/rake +7 -0
- data/bin/sandbox +86 -0
- data/bin/setup +8 -0
- data/config/initializers/webhooks.rb +7 -0
- data/config/locales/en.yml +8 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20140515024440_add_easy_post_fields_to_shipping_rate.rb +9 -0
- data/db/migrate/20201025110912_add_tracker_id_to_cartons.rb +6 -0
- data/lib/generators/solidus_easypost/install/install_generator.rb +28 -0
- data/lib/generators/solidus_easypost/install/templates/initializer.rb +26 -0
- data/lib/solidus_easypost/address_builder.rb +45 -0
- data/lib/solidus_easypost/calculator/base_dimension_calculator.rb +28 -0
- data/lib/solidus_easypost/calculator/weight_dimension_calculator.rb +22 -0
- data/lib/solidus_easypost/configuration.rb +34 -0
- data/lib/solidus_easypost/engine.rb +19 -0
- data/lib/solidus_easypost/errors/unknown_partial_resource_error.rb +11 -0
- data/lib/solidus_easypost/estimator.rb +37 -0
- data/lib/solidus_easypost/parcel_builder.rb +27 -0
- data/lib/solidus_easypost/shipment_builder.rb +32 -0
- data/lib/solidus_easypost/shipping_method_selector.rb +17 -0
- data/lib/solidus_easypost/shipping_rate_calculator.rb +9 -0
- data/lib/solidus_easypost/testing_support/factories/address_factory.rb +10 -0
- data/lib/solidus_easypost/testing_support/factories/product_factory.rb +7 -0
- data/lib/solidus_easypost/testing_support/factories/shipment_factory.rb +30 -0
- data/lib/solidus_easypost/testing_support/factories/shipping_method_factory.rb +8 -0
- data/lib/solidus_easypost/testing_support/factories/stock_location_factory.rb +10 -0
- data/lib/solidus_easypost/testing_support/factories/variant_factory.rb +7 -0
- data/lib/solidus_easypost/testing_support/factories.rb +3 -0
- data/lib/solidus_easypost/tracker_webhook_handler.rb +14 -0
- data/lib/solidus_easypost/version.rb +5 -0
- data/lib/solidus_easypost.rb +32 -0
- data/solidus_easypost.gemspec +41 -0
- data/spec/cassettes/address_builder/from_address.yml +65 -0
- data/spec/cassettes/address_builder/from_stock_location.yml +65 -0
- data/spec/cassettes/estimator.yml +269 -0
- data/spec/cassettes/integration/checkout.yml +377 -0
- data/spec/cassettes/integration/order_shipping/with_purchase_labels.yml +373 -0
- data/spec/cassettes/integration/order_shipping/without_purchase_labels.yml +251 -0
- data/spec/cassettes/parcel_builder/from_package.yml +63 -0
- data/spec/cassettes/parcel_builder/from_return_authorization.yml +63 -0
- data/spec/cassettes/postage_labels/show.yml +72 -0
- data/spec/cassettes/return_authorization.yml +310 -0
- data/spec/cassettes/shipment_builder/from_package.yml +251 -0
- data/spec/cassettes/shipment_builder/from_return_authorization.yml +251 -0
- data/spec/cassettes/shipment_builder/from_shipment.yml +250 -0
- data/spec/controllers/spree/admin/postage_labels_controller_spec.rb +18 -0
- data/spec/features/admin/postage_labels_spec.rb +18 -0
- data/spec/integration/checkout_spec.rb +45 -0
- data/spec/integration/order_shipping_spec.rb +33 -0
- data/spec/models/solidus_easypost/parcel_dimension_spec.rb +80 -0
- data/spec/models/solidus_easypost/return_authorization_spec.rb +17 -0
- data/spec/models/spree/carton_spec.rb +57 -0
- data/spec/models/spree/shipment_spec.rb +69 -0
- data/spec/models/spree/shipping_rate_spec.rb +23 -0
- data/spec/solidus_easypost/address_builder_spec.rb +17 -0
- data/spec/solidus_easypost/calculator/weight_dimension_calculator_spec.rb +39 -0
- data/spec/solidus_easypost/estimator_spec.rb +52 -0
- data/spec/solidus_easypost/parcel_builder_spec.rb +113 -0
- data/spec/solidus_easypost/shipment_builder_spec.rb +28 -0
- data/spec/solidus_easypost/shipping_method_selector_spec.rb +33 -0
- data/spec/solidus_easypost/shipping_rate_calculator_spec.rb +12 -0
- data/spec/solidus_easypost/tracker_webhook_handler_spec.rb +58 -0
- data/spec/solidus_easypost_spec.rb +19 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/support/easypost.rb +5 -0
- data/spec/support/factory_bot.rb +3 -0
- data/spec/support/helpers/api_stubs.rb +40 -0
- data/spec/support/helpers/configuration.rb +28 -0
- data/spec/support/helpers/shipping_methods.rb +26 -0
- data/spec/support/solidus.rb +1 -0
- data/spec/support/vcr.rb +12 -0
- metadata +170 -142
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe SolidusEasypost::ParcelDimension do
|
6
|
+
describe '.new' do
|
7
|
+
subject(:instance) { described_class.new(params) }
|
8
|
+
|
9
|
+
let(:params) do
|
10
|
+
{ height: 3 }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when the weight is not passed' do
|
14
|
+
let(:params) do
|
15
|
+
{ height: 3 }
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'raises an argument error exception' do
|
19
|
+
expect {
|
20
|
+
instance
|
21
|
+
}.to raise_error(ArgumentError)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when the passed weight is zero' do
|
26
|
+
let(:params) do
|
27
|
+
{ height: 3, weight: 0 }
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'raises an argument error exception' do
|
31
|
+
expect {
|
32
|
+
instance
|
33
|
+
}.to raise_error(ArgumentError)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#to_h' do
|
39
|
+
subject(:instance_hash) { described_class.new(params).to_h }
|
40
|
+
|
41
|
+
context 'when the params contains zero values' do
|
42
|
+
let(:params) do
|
43
|
+
{ weight: 3, width: 0, height: 0, unknown: -1 }
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'returns the correct parcel dimension hash' do
|
47
|
+
expect(instance_hash).to eq({
|
48
|
+
weight: 3
|
49
|
+
})
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when the params contains the wrong params' do
|
54
|
+
let(:params) do
|
55
|
+
{ weight: 3, unknown: -1, another: 11 }
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'returns the correct parcel dimension hash' do
|
59
|
+
expect(instance_hash).to eq({
|
60
|
+
weight: 3
|
61
|
+
})
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when the params contains the correct params' do
|
66
|
+
let(:params) do
|
67
|
+
{ weight: 3, width: 1, depth: 6, height: 11 }
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'returns the correct parcel dimension hash' do
|
71
|
+
expect(instance_hash).to eq({
|
72
|
+
height: 11,
|
73
|
+
weight: 3,
|
74
|
+
width: 1,
|
75
|
+
length: 6,
|
76
|
+
})
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe SolidusEasypost::ReturnAuthorization, vcr: { cassette_name: 'return_authorization' } do
|
6
|
+
describe '#return_label' do
|
7
|
+
it 'returns a valid return label' do
|
8
|
+
return_authorization = create(:return_item).return_authorization
|
9
|
+
|
10
|
+
easypost_return_authorization = described_class.new(return_authorization)
|
11
|
+
selected_easypost_rate = easypost_return_authorization.easypost_shipment.rates.first
|
12
|
+
return_label = easypost_return_authorization.return_label(selected_easypost_rate)
|
13
|
+
|
14
|
+
expect(return_label).to have_attributes(object: 'PostageLabel')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
RSpec.describe Spree::Carton do
|
2
|
+
describe '.create' do
|
3
|
+
context 'when track_all_cartons is true' do
|
4
|
+
it 'tracks the package automatically' do
|
5
|
+
stub_easypost_config(track_all_cartons: true)
|
6
|
+
tracker = instance_double(EasyPost::Tracker, id: 'trk_test')
|
7
|
+
allow(EasyPost::Tracker).to receive(:create).and_return(tracker)
|
8
|
+
|
9
|
+
carton = create(:carton)
|
10
|
+
|
11
|
+
expect(carton.easy_post_tracker_id).to eq('trk_test')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when track_all_cartons is false' do
|
16
|
+
it 'does not track all packages automatically' do
|
17
|
+
stub_easypost_config(track_all_cartons: false)
|
18
|
+
|
19
|
+
carton = create(:carton)
|
20
|
+
|
21
|
+
expect(carton.easy_post_tracker_id).to eq(nil)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#easypost_tracker' do
|
27
|
+
context 'when a tracker was already created' do
|
28
|
+
it 'returns the existing tracker' do
|
29
|
+
carton = create(:carton, easy_post_tracker_id: 'trk_test')
|
30
|
+
tracker = instance_double(EasyPost::Tracker)
|
31
|
+
allow(EasyPost::Tracker).to receive(:retrieve).with('trk_test').and_return(tracker)
|
32
|
+
|
33
|
+
expect(carton.easypost_tracker).to eq(tracker)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when a tracker was not created' do
|
38
|
+
it 'creates a new tracker' do
|
39
|
+
carton = create(:carton, tracking: 'TESTTRACKING', shipping_method: create(:shipping_method, carrier: 'FedEx'))
|
40
|
+
tracker = instance_double(EasyPost::Tracker, id: 'trk_test')
|
41
|
+
allow(EasyPost::Tracker).to receive(:create).with(tracking_code: 'TESTTRACKING', carrier: 'FedEx').and_return(tracker)
|
42
|
+
|
43
|
+
expect(carton.easypost_tracker).to eq(tracker)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "sets the tracker's ID on the carton" do
|
47
|
+
carton = create(:carton)
|
48
|
+
tracker = instance_double(EasyPost::Tracker, id: 'trk_test')
|
49
|
+
allow(EasyPost::Tracker).to receive(:create).and_return(tracker)
|
50
|
+
|
51
|
+
carton.easypost_tracker
|
52
|
+
|
53
|
+
expect(carton.easy_post_tracker_id).to eq('trk_test')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Spree::Shipment do
|
6
|
+
describe '#easypost_shipment' do
|
7
|
+
context 'when no shipping rate was selected' do
|
8
|
+
it 'returns nil' do
|
9
|
+
shipment = create(:shipment)
|
10
|
+
|
11
|
+
expect(shipment.easypost_shipment).to be_nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when a shipping rate was selected' do
|
16
|
+
it 'returns the shipment associated with the shipping rate' do
|
17
|
+
easypost_shipment = stub_easypost_shipment
|
18
|
+
shipment = create(
|
19
|
+
:shipment,
|
20
|
+
:with_easypost,
|
21
|
+
easypost_shipment_id: easypost_shipment.id,
|
22
|
+
)
|
23
|
+
|
24
|
+
expect(shipment.easypost_shipment).to eq(easypost_shipment)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#ship!' do
|
30
|
+
context 'when purchase_labels is true' do
|
31
|
+
it 'buys the selected rate' do
|
32
|
+
stub_easypost_config(purchase_labels: true)
|
33
|
+
easypost_shipment = stub_easypost_shipment
|
34
|
+
selected_easypost_rate = easypost_shipment.rates.first
|
35
|
+
|
36
|
+
shipment = create(
|
37
|
+
:shipment,
|
38
|
+
:with_easypost,
|
39
|
+
state: 'ready',
|
40
|
+
easypost_shipment_id: easypost_shipment.id,
|
41
|
+
easypost_rate_id: selected_easypost_rate.id,
|
42
|
+
)
|
43
|
+
shipment.ship!
|
44
|
+
|
45
|
+
expect(easypost_shipment).to have_received(:buy).with(selected_easypost_rate)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when purchase_labels is false' do
|
50
|
+
it 'does not buy rates automatically' do
|
51
|
+
stub_easypost_config(purchase_labels: false)
|
52
|
+
easypost_shipment = stub_easypost_shipment
|
53
|
+
selected_easypost_rate = easypost_shipment.rates.first
|
54
|
+
|
55
|
+
shipment = create(
|
56
|
+
:shipment,
|
57
|
+
:with_easypost,
|
58
|
+
state: 'ready',
|
59
|
+
easypost_shipment_id: easypost_shipment.id,
|
60
|
+
easypost_rate_id: selected_easypost_rate.id,
|
61
|
+
)
|
62
|
+
|
63
|
+
shipment.ship!
|
64
|
+
|
65
|
+
expect(easypost_shipment).not_to have_received(:buy)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Spree::ShippingRate do
|
6
|
+
describe '#name' do
|
7
|
+
context 'when the shipping rate has its own name' do
|
8
|
+
it 'returns the name on the shipping rate' do
|
9
|
+
shipping_rate = build_stubbed(:shipping_rate, name: 'USPS Express')
|
10
|
+
|
11
|
+
expect(shipping_rate.name).to eq('USPS Express')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when the shipping rate does not have its own name' do
|
16
|
+
it 'returns the name on the shipping method' do
|
17
|
+
shipping_rate = build_stubbed(:shipping_rate, name: nil)
|
18
|
+
|
19
|
+
expect(shipping_rate.name).to eq(shipping_rate.shipping_method.name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
RSpec.describe SolidusEasypost::AddressBuilder do
|
2
|
+
describe '.from_address', vcr: { cassette_name: 'address_builder/from_address' } do
|
3
|
+
it 'builds an address with the correct attributes' do
|
4
|
+
address = described_class.from_address(build_stubbed(:address))
|
5
|
+
|
6
|
+
expect(address).to have_attributes(object: 'Address')
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '.from_stock_location', vcr: { cassette_name: 'address_builder/from_stock_location' } do
|
11
|
+
it 'builds an address with the correct attributes' do
|
12
|
+
address = described_class.from_stock_location(create(:stock_location))
|
13
|
+
|
14
|
+
expect(address).to have_attributes(object: 'Address')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe SolidusEasypost::Calculator::WeightDimensionCalculator do
|
4
|
+
describe '#compute' do
|
5
|
+
subject(:compute) { described_class.new.compute(resource) }
|
6
|
+
|
7
|
+
context 'when a wrong resource is passed' do
|
8
|
+
let(:resource) { create(:shipment) }
|
9
|
+
|
10
|
+
it 'raises an unknown partial resource error' do
|
11
|
+
expect { compute }.to raise_error(SolidusEasypost::Errors::UnknownPartialResourceError)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when a Spree::Stock::Package is passed' do
|
16
|
+
let(:resource) { create(:shipment).to_package }
|
17
|
+
|
18
|
+
before { allow(SolidusEasypost::ParcelDimension).to receive(:new) }
|
19
|
+
|
20
|
+
it 'build a parcel dimension' do
|
21
|
+
compute
|
22
|
+
|
23
|
+
expect(SolidusEasypost::ParcelDimension).to have_received(:new).with({ weight: 10.to_f })
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when a SolidusEasypost::ReturnAuthorization is passed' do
|
28
|
+
let(:resource) { SolidusEasypost::ReturnAuthorization.new(create(:return_authorization)) }
|
29
|
+
|
30
|
+
before { allow(SolidusEasypost::ParcelDimension).to receive(:new) }
|
31
|
+
|
32
|
+
it 'build a parcel dimension' do
|
33
|
+
compute
|
34
|
+
|
35
|
+
expect(SolidusEasypost::ParcelDimension).to have_received(:new).with({ weight: 0.to_f })
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe SolidusEasypost::Estimator, vcr: { cassette_name: 'estimator' } do
|
6
|
+
describe '#shipping_rates' do
|
7
|
+
context 'when the shipping methods are available to users' do
|
8
|
+
it 'returns the shipping rates' do
|
9
|
+
stub_shipping_method_selector(available_to_users: true)
|
10
|
+
|
11
|
+
rates = described_class.new.shipping_rates(create(:shipment).to_package)
|
12
|
+
|
13
|
+
hash = {
|
14
|
+
"USPS Express" => 22.74,
|
15
|
+
"USPS First" => 3.82,
|
16
|
+
"USPS ParcelSelect" => 6.85,
|
17
|
+
"USPS Priority" => 6.95,
|
18
|
+
}
|
19
|
+
|
20
|
+
expect(rates.sort_by(&:name).map { |r| [r.name, r.cost] }.to_h).to eq(hash)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when the shipping methods are not available to users' do
|
25
|
+
it 'returns no rates' do
|
26
|
+
stub_shipping_method_selector(available_to_users: false)
|
27
|
+
|
28
|
+
rates = described_class.new.shipping_rates(create(:shipment).to_package)
|
29
|
+
|
30
|
+
expect(rates).to be_empty
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def stub_shipping_method_selector(available_to_users:)
|
38
|
+
shipping_method_selector = Class.new.tap do |klass|
|
39
|
+
klass.define_method(:shipping_method_for) do |rate|
|
40
|
+
Spree::ShippingMethod.new(
|
41
|
+
name: "#{rate.carrier} #{rate.service}",
|
42
|
+
available_to_users: available_to_users,
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
stub_const('FakeShippingMethodSelector', shipping_method_selector)
|
48
|
+
|
49
|
+
allow(SolidusEasypost.configuration).to receive(:shipping_method_selector_class)
|
50
|
+
.and_return(FakeShippingMethodSelector)
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe SolidusEasypost::ParcelBuilder do
|
4
|
+
describe '.from_package', vcr: { cassette_name: 'parcel_builder/from_package' } do
|
5
|
+
let(:shipment) { create(:shipment) }
|
6
|
+
let(:package) { shipment.to_package }
|
7
|
+
let(:parcel_dimension_calculator) { instance_spy('SolidusEasypost.configuration.parcel_dimension_calculator_class') }
|
8
|
+
let(:parcel_dimension) { instance_spy('SolidusEasypost::ParcelDimension') }
|
9
|
+
|
10
|
+
before do
|
11
|
+
allow(SolidusEasypost.configuration.parcel_dimension_calculator_class)
|
12
|
+
.to receive(:new)
|
13
|
+
.and_return(parcel_dimension_calculator)
|
14
|
+
|
15
|
+
allow(parcel_dimension_calculator).to receive(:compute).and_return(parcel_dimension)
|
16
|
+
allow(parcel_dimension).to receive(:to_h).and_return(dimension_hash)
|
17
|
+
allow(EasyPost::Parcel).to receive(:create).and_call_original
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when there is only the weight set' do
|
21
|
+
let(:dimension_hash) { { weight: 10.to_f } }
|
22
|
+
|
23
|
+
it 'builds a parcel with the correct attributes' do
|
24
|
+
parcel = described_class.from_package(package)
|
25
|
+
|
26
|
+
expect(parcel_dimension_calculator)
|
27
|
+
.to have_received(:compute)
|
28
|
+
.with(package)
|
29
|
+
|
30
|
+
expect(EasyPost::Parcel)
|
31
|
+
.to have_received(:create)
|
32
|
+
.with({ weight: 10.to_f })
|
33
|
+
|
34
|
+
expect(parcel).to have_attributes(object: 'Parcel')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when all the properties are set' do
|
39
|
+
let(:dimension_hash) do
|
40
|
+
{ weight: 10.to_f, height: 2.to_f, width: 3.to_f, depth: 4.to_f }
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'builds a parcel with the correct attributes' do
|
44
|
+
parcel = described_class.from_package(package)
|
45
|
+
|
46
|
+
expect(parcel_dimension_calculator)
|
47
|
+
.to have_received(:compute)
|
48
|
+
.with(package)
|
49
|
+
|
50
|
+
expect(EasyPost::Parcel)
|
51
|
+
.to have_received(:create)
|
52
|
+
.with({ weight: 10.to_f, height: 2.to_f, width: 3.to_f, depth: 4.to_f })
|
53
|
+
|
54
|
+
expect(parcel).to have_attributes(object: 'Parcel')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe '.from_return_authorization', vcr: { cassette_name: 'parcel_builder/from_return_authorization' } do
|
60
|
+
let(:return_item) { create(:return_item) }
|
61
|
+
let(:return_authorization) { return_item.return_authorization }
|
62
|
+
let(:parcel_dimension_calculator) { instance_spy('SolidusEasypost.configuration.parcel_dimension_calculator_class') }
|
63
|
+
let(:parcel_dimension) { instance_spy('SolidusEasypost::ParcelDimension') }
|
64
|
+
|
65
|
+
before do
|
66
|
+
allow(SolidusEasypost.configuration.parcel_dimension_calculator_class)
|
67
|
+
.to receive(:new)
|
68
|
+
.and_return(parcel_dimension_calculator)
|
69
|
+
|
70
|
+
allow(parcel_dimension_calculator).to receive(:compute).and_return(parcel_dimension)
|
71
|
+
allow(parcel_dimension).to receive(:to_h).and_return(dimension_hash)
|
72
|
+
allow(EasyPost::Parcel).to receive(:create).and_call_original
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when there is only the weight set' do
|
76
|
+
let(:dimension_hash) { { weight: 10.to_f } }
|
77
|
+
|
78
|
+
it 'builds a parcel with the correct attributes' do
|
79
|
+
parcel = described_class.from_return_authorization(return_authorization)
|
80
|
+
|
81
|
+
expect(parcel_dimension_calculator)
|
82
|
+
.to have_received(:compute)
|
83
|
+
.with(return_authorization)
|
84
|
+
|
85
|
+
expect(EasyPost::Parcel)
|
86
|
+
.to have_received(:create)
|
87
|
+
.with({ weight: 10.to_f })
|
88
|
+
|
89
|
+
expect(parcel).to have_attributes(object: 'Parcel')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'when all the properties are set' do
|
94
|
+
let(:dimension_hash) do
|
95
|
+
{ weight: 10.to_f, height: 2.to_f, width: 3.to_f, depth: 4.to_f }
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'builds a parcel with the correct attributes' do
|
99
|
+
parcel = described_class.from_return_authorization(return_authorization)
|
100
|
+
|
101
|
+
expect(parcel_dimension_calculator)
|
102
|
+
.to have_received(:compute)
|
103
|
+
.with(return_authorization)
|
104
|
+
|
105
|
+
expect(EasyPost::Parcel)
|
106
|
+
.to have_received(:create)
|
107
|
+
.with({ weight: 10.to_f, height: 2.to_f, width: 3.to_f, depth: 4.to_f })
|
108
|
+
|
109
|
+
expect(parcel).to have_attributes(object: 'Parcel')
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe SolidusEasypost::ShipmentBuilder do
|
4
|
+
describe '.from_package', vcr: { cassette_name: 'shipment_builder/from_package' } do
|
5
|
+
it 'builds a shipment with the correct attributes' do
|
6
|
+
shipment = described_class.from_package(create(:shipment).to_package)
|
7
|
+
|
8
|
+
expect(shipment).to have_attributes(object: 'Shipment')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.from_shipment', vcr: { cassette_name: 'shipment_builder/from_shipment' } do
|
13
|
+
it 'builds a shipment with the correct attributes' do
|
14
|
+
shipment = described_class.from_shipment(create(:shipment))
|
15
|
+
|
16
|
+
expect(shipment).to have_attributes(object: 'Shipment')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '.from_return_authorization', vcr: { cassette_name: 'shipment_builder/from_return_authorization' } do
|
21
|
+
it 'builds a shipment with the correct attributes' do
|
22
|
+
solidus_return_authorization = create(:return_item).return_authorization
|
23
|
+
shipment = described_class.from_return_authorization(SolidusEasypost::ReturnAuthorization.new(solidus_return_authorization))
|
24
|
+
|
25
|
+
expect(shipment).to have_attributes(object: 'Shipment')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
RSpec.describe SolidusEasypost::ShippingMethodSelector do
|
2
|
+
describe '#shipping_method_for' do
|
3
|
+
context 'when a shipping method for the given carrier and service exists' do
|
4
|
+
it 'returns the existing shipping method' do
|
5
|
+
shipping_method = create(:shipping_method, carrier: 'USPS', service_level: 'Express')
|
6
|
+
easypost_rate = EasyPost::Rate.construct_from('carrier' => 'USPS', 'service' => 'Express')
|
7
|
+
|
8
|
+
selector = described_class.new
|
9
|
+
selected_shipping_method = selector.shipping_method_for(easypost_rate)
|
10
|
+
|
11
|
+
expect(selected_shipping_method).to eq(shipping_method)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when a shipping method for the given carrier and service does not exist' do
|
16
|
+
it 'creates a new shipping method' do
|
17
|
+
shipping_category = create(:shipping_category)
|
18
|
+
easypost_rate = EasyPost::Rate.construct_from('carrier' => 'USPS', 'service' => 'Express')
|
19
|
+
|
20
|
+
selector = described_class.new
|
21
|
+
selected_shipping_method = selector.shipping_method_for(easypost_rate)
|
22
|
+
|
23
|
+
expect(selected_shipping_method).to have_attributes(
|
24
|
+
name: 'USPS Express',
|
25
|
+
carrier: 'USPS',
|
26
|
+
service_level: 'Express',
|
27
|
+
shipping_categories: [shipping_category],
|
28
|
+
available_to_users: false,
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
RSpec.describe SolidusEasypost::ShippingRateCalculator do
|
2
|
+
describe '#compute' do
|
3
|
+
it 'returns the amount on the EasyPost rate' do
|
4
|
+
easypost_rate = EasyPost::Rate.construct_from('rate' => 25.0)
|
5
|
+
|
6
|
+
calculator = described_class.new
|
7
|
+
computed_rate = calculator.compute(easypost_rate)
|
8
|
+
|
9
|
+
expect(computed_rate).to eq(25.0)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
RSpec.describe SolidusEasypost::TrackerWebhookHandler do
|
2
|
+
describe '.call' do
|
3
|
+
context 'when the event is not tracker.updated' do
|
4
|
+
it 'does not process the event' do
|
5
|
+
stub_const('Spree::Event', class_spy(Spree::Event))
|
6
|
+
create(:carton, easy_post_tracker_id: 'trk_test')
|
7
|
+
|
8
|
+
payload = {
|
9
|
+
'description' => 'tracker.created',
|
10
|
+
'result' => {
|
11
|
+
'id' => 'trk_test',
|
12
|
+
},
|
13
|
+
}
|
14
|
+
described_class.call(payload)
|
15
|
+
|
16
|
+
expect(Spree::Event).not_to have_received(:fire)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when the tracker was not registered in Solidus' do
|
21
|
+
it 'does not process the event' do
|
22
|
+
stub_const('Spree::Event', class_spy(Spree::Event))
|
23
|
+
create(:carton, easy_post_tracker_id: 'trk_test')
|
24
|
+
|
25
|
+
payload = {
|
26
|
+
'description' => 'tracker.updated',
|
27
|
+
'result' => {
|
28
|
+
'id' => 'trk_test1',
|
29
|
+
},
|
30
|
+
}
|
31
|
+
described_class.call(payload)
|
32
|
+
|
33
|
+
expect(Spree::Event).not_to have_received(:fire)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when the event is a tracker update for a registered tracker' do
|
38
|
+
it 'forwards the event via the event bus' do
|
39
|
+
stub_const('Spree::Event', class_spy(Spree::Event))
|
40
|
+
carton = create(:carton, easy_post_tracker_id: 'trk_test')
|
41
|
+
|
42
|
+
payload = {
|
43
|
+
'description' => 'tracker.updated',
|
44
|
+
'result' => {
|
45
|
+
'id' => 'trk_test',
|
46
|
+
},
|
47
|
+
}
|
48
|
+
described_class.call(payload)
|
49
|
+
|
50
|
+
expect(Spree::Event).to have_received(:fire).with(
|
51
|
+
'solidus_easypost.tracker.updated',
|
52
|
+
carton: carton,
|
53
|
+
payload: payload,
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe SolidusEasypost do
|
6
|
+
describe '.configuration' do
|
7
|
+
it 'returns the configuration' do
|
8
|
+
expect(described_class.configuration).to be_instance_of(SolidusEasypost::Configuration)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.configure' do
|
13
|
+
it 'yields the configuration' do
|
14
|
+
expect { |b| described_class.configure(&b) }.to yield_with_args(
|
15
|
+
an_instance_of(SolidusEasypost::Configuration),
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Configure Rails Environment
|
4
|
+
ENV['RAILS_ENV'] = 'test'
|
5
|
+
|
6
|
+
# Run Coverage report
|
7
|
+
require 'solidus_dev_support/rspec/coverage'
|
8
|
+
|
9
|
+
# Create the dummy app if it's still missing.
|
10
|
+
dummy_env = "#{__dir__}/dummy/config/environment.rb"
|
11
|
+
system 'bin/rake extension:test_app' unless File.exist? dummy_env
|
12
|
+
require dummy_env
|
13
|
+
|
14
|
+
# Requires factories and other useful helpers defined in spree_core.
|
15
|
+
require 'solidus_dev_support/rspec/feature_helper'
|
16
|
+
|
17
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
18
|
+
# in spec/support/ and its subdirectories.
|
19
|
+
Dir["#{__dir__}/support/**/*.rb"].sort.each { |f| require f }
|
20
|
+
|
21
|
+
# Requires factories defined in lib/solidus_easypost/testing_support/factories.rb
|
22
|
+
require 'solidus_easypost/testing_support/factories'
|
23
|
+
|
24
|
+
RSpec.configure do |config|
|
25
|
+
config.infer_spec_type_from_file_location!
|
26
|
+
config.use_transactional_fixtures = false
|
27
|
+
|
28
|
+
if Spree.solidus_gem_version < Gem::Version.new('2.11')
|
29
|
+
config.extend Spree::TestingSupport::AuthorizationHelpers::Request, type: :system
|
30
|
+
end
|
31
|
+
end
|