solidus_shipstation 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.bundle/config +2 -0
- 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 +20 -0
- data/.rspec +2 -0
- data/.rubocop.yml +13 -0
- data/.rubocop_todo.yml +40 -0
- data/CHANGELOG.md +36 -0
- data/Gemfile +33 -0
- data/LICENSE +26 -0
- data/README.md +208 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/spree/backend/solidus_shipstation.js +2 -0
- data/app/assets/javascripts/spree/frontend/solidus_shipstation.js +2 -0
- data/app/assets/stylesheets/spree/backend/solidus_shipstation.css +4 -0
- data/app/assets/stylesheets/spree/frontend/solidus_shipstation.css +4 -0
- data/app/controllers/spree/shipstation_controller.rb +45 -0
- data/app/decorators/models/solidus_shipstation/spree/shipment_decorator.rb +33 -0
- data/app/helpers/solidus_shipstation/export_helper.rb +32 -0
- data/app/jobs/solidus_shipstation/api/schedule_shipment_syncs_job.rb +19 -0
- data/app/jobs/solidus_shipstation/api/sync_shipments_job.rb +41 -0
- data/app/queries/solidus_shipstation/shipment/between_query.rb +14 -0
- data/app/queries/solidus_shipstation/shipment/exportable_query.rb +24 -0
- data/app/queries/solidus_shipstation/shipment/pending_api_sync_query.rb +63 -0
- data/app/views/spree/shipstation/export.xml.builder +58 -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/locales/en.yml +5 -0
- data/config/routes.rb +6 -0
- data/db/migrate/20210220093010_add_shipstation_api_sync_fields.rb +9 -0
- data/lib/generators/solidus_shipstation/install/install_generator.rb +27 -0
- data/lib/generators/solidus_shipstation/install/templates/initializer.rb +62 -0
- data/lib/solidus_shipstation.rb +16 -0
- data/lib/solidus_shipstation/api/batch_syncer.rb +70 -0
- data/lib/solidus_shipstation/api/client.rb +38 -0
- data/lib/solidus_shipstation/api/rate_limited_error.rb +23 -0
- data/lib/solidus_shipstation/api/request_error.rb +33 -0
- data/lib/solidus_shipstation/api/request_runner.rb +50 -0
- data/lib/solidus_shipstation/api/shipment_serializer.rb +84 -0
- data/lib/solidus_shipstation/api/threshold_verifier.rb +28 -0
- data/lib/solidus_shipstation/configuration.rb +44 -0
- data/lib/solidus_shipstation/engine.rb +19 -0
- data/lib/solidus_shipstation/errors.rb +23 -0
- data/lib/solidus_shipstation/shipment_notice.rb +58 -0
- data/lib/solidus_shipstation/testing_support/factories.rb +4 -0
- data/lib/solidus_shipstation/version.rb +5 -0
- data/solidus_shipstation.gemspec +40 -0
- data/spec/controllers/spree/shipstation_controller_spec.rb +103 -0
- data/spec/fixtures/shipstation_xml_schema.xsd +171 -0
- data/spec/jobs/solidus_shipstation/api/schedule_shipment_syncs_job_spec.rb +32 -0
- data/spec/jobs/solidus_shipstation/api/sync_shipments_job_spec.rb +102 -0
- data/spec/lib/solidus_shipstation/api/batch_syncer_spec.rb +229 -0
- data/spec/lib/solidus_shipstation/api/client_spec.rb +120 -0
- data/spec/lib/solidus_shipstation/api/rate_limited_error_spec.rb +21 -0
- data/spec/lib/solidus_shipstation/api/request_error_spec.rb +20 -0
- data/spec/lib/solidus_shipstation/api/request_runner_spec.rb +64 -0
- data/spec/lib/solidus_shipstation/api/shipment_serializer_spec.rb +12 -0
- data/spec/lib/solidus_shipstation/api/threshold_verifier_spec.rb +61 -0
- data/spec/lib/solidus_shipstation/shipment_notice_spec.rb +111 -0
- data/spec/lib/solidus_shipstation_spec.rb +9 -0
- data/spec/models/spree/shipment_spec.rb +49 -0
- data/spec/queries/solidus_shipstation/shipment/between_query_spec.rb +53 -0
- data/spec/queries/solidus_shipstation/shipment/exportable_query_spec.rb +53 -0
- data/spec/queries/solidus_shipstation/shipment/pending_api_sync_query_spec.rb +37 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/support/configuration_helper.rb +13 -0
- data/spec/support/controllers.rb +1 -0
- data/spec/support/webmock.rb +3 -0
- data/spec/support/xsd.rb +5 -0
- metadata +248 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
RSpec.describe SolidusShipstation::Api::RateLimitedError do
|
2
|
+
describe '.from_response' do
|
3
|
+
it 'extracts the status code, body, headers and retry time from the response' do
|
4
|
+
response = instance_double(
|
5
|
+
'HTTParty::Response',
|
6
|
+
code: 429,
|
7
|
+
headers: { 'X-Rate-Limit-Reset' => 20 },
|
8
|
+
body: '{ "message": "Too Many Requests" }',
|
9
|
+
)
|
10
|
+
|
11
|
+
error = described_class.from_response(response)
|
12
|
+
|
13
|
+
expect(error).to have_attributes(
|
14
|
+
response_code: 429,
|
15
|
+
response_headers: { 'X-Rate-Limit-Reset' => 20 },
|
16
|
+
response_body: '{ "message": "Too Many Requests" }',
|
17
|
+
retry_in: 20.seconds,
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
RSpec.describe SolidusShipstation::Api::RequestError do
|
2
|
+
describe '.from_response' do
|
3
|
+
it 'extracts the status code, body and headers from the response' do
|
4
|
+
response = instance_double(
|
5
|
+
'HTTParty::Response',
|
6
|
+
code: 500,
|
7
|
+
headers: { 'Key' => 'Value' },
|
8
|
+
body: '{ "message": "Internal Server Error" }',
|
9
|
+
)
|
10
|
+
|
11
|
+
error = described_class.from_response(response)
|
12
|
+
|
13
|
+
expect(error).to have_attributes(
|
14
|
+
response_code: 500,
|
15
|
+
response_headers: { 'Key' => 'Value' },
|
16
|
+
response_body: '{ "message": "Internal Server Error" }',
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
RSpec.describe SolidusShipstation::Api::RequestRunner do
|
2
|
+
describe '.from_config' do
|
3
|
+
it 'builds a runner using credentials from the configuration' do
|
4
|
+
stub_configuration(api_key: 'user', api_secret: 'pass')
|
5
|
+
|
6
|
+
request_runner = described_class.from_config
|
7
|
+
|
8
|
+
expect(request_runner).to have_attributes(
|
9
|
+
username: 'user',
|
10
|
+
password: 'pass',
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#call' do
|
16
|
+
context 'when the response code is 2xx' do
|
17
|
+
it 'returns the parsed response' do
|
18
|
+
stub_request(:post, %r{ssapi.shipstation.com/test}).with(
|
19
|
+
basic_auth: %w[user pass],
|
20
|
+
headers: { 'Content-Type' => 'application/json', 'Accept' => 'application/json' },
|
21
|
+
body: '{"request_key":"request_value"}',
|
22
|
+
).to_return(
|
23
|
+
headers: { 'Content-Type' => 'application/json' },
|
24
|
+
body: '{"response_key":"response_value"}',
|
25
|
+
)
|
26
|
+
request_runner = described_class.new(username: 'user', password: 'pass')
|
27
|
+
|
28
|
+
response = request_runner.call(:post, '/test', request_key: 'request_value')
|
29
|
+
|
30
|
+
expect(response).to eq('response_key' => 'response_value')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when the response code is 429' do
|
35
|
+
it 'raises a RateLimitedError' do
|
36
|
+
stub_request(:post, %r{ssapi.shipstation.com/test}).to_return(
|
37
|
+
status: 429,
|
38
|
+
headers: { 'Content-Type' => 'application/json', 'X-Rate-Limit-Reset' => 20 },
|
39
|
+
body: '{"message":"Too Many Requests"}',
|
40
|
+
)
|
41
|
+
request_runner = described_class.new(username: 'user', password: 'pass')
|
42
|
+
|
43
|
+
expect {
|
44
|
+
request_runner.call(:post, '/test')
|
45
|
+
}.to raise_error(SolidusShipstation::Api::RateLimitedError)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when the response code is not 200 or 429' do
|
50
|
+
it 'raises a RequestError' do
|
51
|
+
stub_request(:post, %r{ssapi.shipstation.com/test}).to_return(
|
52
|
+
status: 500,
|
53
|
+
headers: { 'Content-Type' => 'application/json' },
|
54
|
+
body: '{"message":"Internal Server Error"}',
|
55
|
+
)
|
56
|
+
request_runner = described_class.new(username: 'user', password: 'pass')
|
57
|
+
|
58
|
+
expect {
|
59
|
+
request_runner.call(:post, '/test')
|
60
|
+
}.to raise_error(SolidusShipstation::Api::RequestError)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
RSpec.describe SolidusShipstation::Api::ShipmentSerializer do
|
2
|
+
describe '#call' do
|
3
|
+
it 'serializes the shipment' do
|
4
|
+
shipment = create(:order_ready_to_ship).shipments.first
|
5
|
+
|
6
|
+
serializer = described_class.new(store_id: '12345678')
|
7
|
+
result = serializer.call(shipment)
|
8
|
+
|
9
|
+
expect(result).to be_instance_of(Hash)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
RSpec.describe SolidusShipstation::Api::ThresholdVerifier do
|
2
|
+
context "when the shipment's order was completed" do
|
3
|
+
context 'when the shipment was never synced with ShipStation yet' do
|
4
|
+
it 'returns true when the shipment was never synced with ShipStation yet' do
|
5
|
+
stub_configuration(api_sync_threshold: 10.minutes)
|
6
|
+
shipment = create(:order_ready_to_ship).shipments.first
|
7
|
+
|
8
|
+
expect(described_class.call(shipment)).to eq(true)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns false when the shipment's order was created too far in the past" do
|
12
|
+
stub_configuration(api_sync_threshold: 10.minutes)
|
13
|
+
shipment = create(:order_ready_to_ship).shipments.first.tap do |s|
|
14
|
+
s.order.update_columns(updated_at: 11.minutes.ago)
|
15
|
+
end
|
16
|
+
|
17
|
+
expect(described_class.call(shipment)).to eq(false)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'when the shipment was already synced with ShipStation' do
|
22
|
+
it 'returns true when the shipment is pending a ShipStation re-sync' do
|
23
|
+
stub_configuration(api_sync_threshold: 10.minutes)
|
24
|
+
shipment = create(:order_ready_to_ship).shipments.first.tap do |s|
|
25
|
+
s.order.update_columns(updated_at: 4.minutes.ago)
|
26
|
+
s.update_columns(shipstation_synced_at: 5.minutes.ago)
|
27
|
+
end
|
28
|
+
|
29
|
+
expect(described_class.call(shipment)).to eq(true)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns false when the shipment is up-to-date in ShipStation' do
|
33
|
+
stub_configuration(api_sync_threshold: 10.minutes)
|
34
|
+
shipment = create(:order_ready_to_ship).shipments.first.tap do |s|
|
35
|
+
s.order.update_columns(updated_at: 6.minutes.ago)
|
36
|
+
s.update_columns(shipstation_synced_at: 5.minutes.ago)
|
37
|
+
end
|
38
|
+
|
39
|
+
expect(described_class.call(shipment)).to eq(false)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'returns false when the order was updated too far in the past' do
|
43
|
+
stub_configuration(api_sync_threshold: 10.minutes)
|
44
|
+
shipment = create(:order_ready_to_ship).shipments.first.tap do |s|
|
45
|
+
s.order.update_columns(updated_at: 11.minutes.ago)
|
46
|
+
s.update_columns(shipstation_synced_at: 12.minutes.ago)
|
47
|
+
end
|
48
|
+
|
49
|
+
expect(described_class.call(shipment)).to eq(false)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when the shipment's order was not completed" do
|
55
|
+
it 'returns false' do
|
56
|
+
shipment = create(:shipment)
|
57
|
+
|
58
|
+
expect(described_class.call(shipment)).to eq(false)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe SolidusShipstation::ShipmentNotice do
|
4
|
+
shared_examples 'ships or updates the shipment' do
|
5
|
+
context 'when the order was not shipped yet' do
|
6
|
+
# rubocop:disable RSpec/MultipleExpectations
|
7
|
+
it 'ships the order successfully' do
|
8
|
+
shipment_notice = build_shipment_notice(order.shipments.first, shipment_tracking: '1Z1231234')
|
9
|
+
shipment_notice.apply
|
10
|
+
|
11
|
+
order.reload
|
12
|
+
expect(order.shipments.first).to be_shipped
|
13
|
+
expect(order.shipments.first.shipped_at).not_to be_nil
|
14
|
+
expect(order.shipments.first.tracking).to eq('1Z1231234')
|
15
|
+
expect(order.cartons.first.tracking).to eq('1Z1231234')
|
16
|
+
end
|
17
|
+
# rubocop:enable RSpec/MultipleExpectations
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'when the order was already shipped' do
|
21
|
+
it 'updates the tracking number on the shipment' do
|
22
|
+
order.shipments.first.ship!
|
23
|
+
|
24
|
+
shipment_notice = build_shipment_notice(order.shipments.first, shipment_tracking: '1Z1231234')
|
25
|
+
shipment_notice.apply
|
26
|
+
|
27
|
+
expect(order.reload.shipments.first.tracking).to eq('1Z1231234')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when capture_at_notification is true' do
|
33
|
+
before { stub_configuration(capture_at_notification: true) }
|
34
|
+
|
35
|
+
context 'when the order is paid' do
|
36
|
+
let(:order) { create_order_ready_to_ship(paid: true) }
|
37
|
+
|
38
|
+
include_examples 'ships or updates the shipment'
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when the order is not paid' do
|
42
|
+
let(:order) { create_order_ready_to_ship(paid: false) }
|
43
|
+
|
44
|
+
context 'when the payment can be captured successfully' do
|
45
|
+
include_examples 'ships or updates the shipment'
|
46
|
+
|
47
|
+
it 'pays the order successfully' do
|
48
|
+
shipment_notice = build_shipment_notice(order.shipments.first, shipment_tracking: '1Z1231234')
|
49
|
+
shipment_notice.apply
|
50
|
+
|
51
|
+
order.reload
|
52
|
+
expect(order.payments).to all(be_completed)
|
53
|
+
expect(order.reload).to be_paid
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when the payment cannot be captured' do
|
58
|
+
it 'raises a PaymentError' do
|
59
|
+
allow_any_instance_of(Spree::Payment).to receive(:capture!).and_raise(Spree::Core::GatewayError)
|
60
|
+
|
61
|
+
shipment_notice = build_shipment_notice(order.shipments.first)
|
62
|
+
|
63
|
+
expect { shipment_notice.apply }.to raise_error(SolidusShipstation::PaymentError) do |e|
|
64
|
+
expect(e.cause).to be_instance_of(Spree::Core::GatewayError)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when capture_at_notification is false' do
|
72
|
+
before { stub_configuration(capture_at_notification: false) }
|
73
|
+
|
74
|
+
context 'when the order is paid' do
|
75
|
+
let(:order) { create_order_ready_to_ship(paid: true) }
|
76
|
+
|
77
|
+
include_examples 'ships or updates the shipment'
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'when the order is not paid' do
|
81
|
+
it 'raises an OrderNotPaidError' do
|
82
|
+
stub_configuration(capture_at_notification: false)
|
83
|
+
order = create_order_ready_to_ship(paid: false)
|
84
|
+
|
85
|
+
shipment_notice = build_shipment_notice(order.shipments.first)
|
86
|
+
|
87
|
+
expect { shipment_notice.apply }.to raise_error(SolidusShipstation::OrderNotPaidError)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def create_order_ready_to_ship(paid: true)
|
95
|
+
order = create(:order_ready_to_ship)
|
96
|
+
|
97
|
+
unless paid
|
98
|
+
order.payments.update_all(state: 'pending')
|
99
|
+
order.recalculate
|
100
|
+
end
|
101
|
+
|
102
|
+
order
|
103
|
+
end
|
104
|
+
|
105
|
+
def build_shipment_notice(shipment, shipment_tracking: '1Z1231234')
|
106
|
+
SolidusShipstation::ShipmentNotice.new(
|
107
|
+
shipment_number: shipment.number,
|
108
|
+
shipment_tracking: shipment_tracking,
|
109
|
+
)
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe Spree::Shipment do
|
4
|
+
describe '.between' do
|
5
|
+
it 'delegates to BetweenQuery' do
|
6
|
+
shipment = build_stubbed(:shipment)
|
7
|
+
allow(SolidusShipstation::Shipment::BetweenQuery).to receive(:apply).with(
|
8
|
+
any_args,
|
9
|
+
from: Time.zone.yesterday,
|
10
|
+
to: Time.zone.today,
|
11
|
+
).and_return([shipment])
|
12
|
+
|
13
|
+
result = Spree::Deprecation.silence do
|
14
|
+
described_class.between(Time.zone.yesterday, Time.zone.today)
|
15
|
+
end
|
16
|
+
|
17
|
+
expect(result).to eq([shipment])
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'prints a deprecation warning' do
|
21
|
+
allow(Spree::Deprecation).to receive(:warn)
|
22
|
+
|
23
|
+
described_class.between(Time.zone.yesterday, Time.zone.today)
|
24
|
+
|
25
|
+
expect(Spree::Deprecation).to have_received(:warn).with(/Spree::Shipment\.between/)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '.exportable' do
|
30
|
+
it 'delegates to ExportableQuery' do
|
31
|
+
shipment = build_stubbed(:shipment)
|
32
|
+
allow(SolidusShipstation::Shipment::ExportableQuery).to receive(:apply).and_return([shipment])
|
33
|
+
|
34
|
+
result = Spree::Deprecation.silence do
|
35
|
+
described_class.exportable
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(result).to eq([shipment])
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'prints a deprecation warning' do
|
42
|
+
allow(Spree::Deprecation).to receive(:warn)
|
43
|
+
|
44
|
+
described_class.exportable
|
45
|
+
|
46
|
+
expect(Spree::Deprecation).to have_received(:warn).with(/Spree::Shipment\.exportable/)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
RSpec.describe SolidusShipstation::Shipment::BetweenQuery do
|
2
|
+
describe '.apply' do
|
3
|
+
it 'returns shipments whose updated_at falls within the given time range' do
|
4
|
+
shipment = create(:shipment) { |s| s.update_column(:updated_at, Time.zone.now) }
|
5
|
+
|
6
|
+
result = described_class.apply(
|
7
|
+
Spree::Shipment.all,
|
8
|
+
from: Time.zone.yesterday,
|
9
|
+
to: Time.zone.tomorrow,
|
10
|
+
)
|
11
|
+
|
12
|
+
expect(result).to eq([shipment])
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns shipments whose order's updated_at falls within the given time range" do
|
16
|
+
order = create(:order) { |o| o.update_column(:updated_at, Time.zone.now) }
|
17
|
+
shipment = create(:shipment, order: order)
|
18
|
+
|
19
|
+
result = described_class.apply(
|
20
|
+
Spree::Shipment.all,
|
21
|
+
from: Time.zone.yesterday,
|
22
|
+
to: Time.zone.tomorrow,
|
23
|
+
)
|
24
|
+
|
25
|
+
expect(result).to eq([shipment])
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'does not return shipments whose updated_at does not fall within the given time range' do
|
29
|
+
create(:shipment) { |s| s.update_column(:updated_at, Time.zone.now) }
|
30
|
+
|
31
|
+
result = described_class.apply(
|
32
|
+
Spree::Shipment.all,
|
33
|
+
from: Time.zone.tomorrow,
|
34
|
+
to: Time.zone.tomorrow + 1.day,
|
35
|
+
)
|
36
|
+
|
37
|
+
expect(result).to eq([])
|
38
|
+
end
|
39
|
+
|
40
|
+
it "does not return shipments whose order's updated_at falls within the given time range" do
|
41
|
+
order = create(:order) { |o| o.update_column(:updated_at, Time.zone.now) }
|
42
|
+
create(:shipment, order: order)
|
43
|
+
|
44
|
+
result = described_class.apply(
|
45
|
+
Spree::Shipment.all,
|
46
|
+
from: Time.zone.tomorrow,
|
47
|
+
to: Time.zone.tomorrow + 1.day,
|
48
|
+
)
|
49
|
+
|
50
|
+
expect(result).to eq([])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
RSpec.describe SolidusShipstation::Shipment::ExportableQuery do
|
2
|
+
describe '.apply' do
|
3
|
+
context 'when capture_at_notification is false and export_canceled_shipments is false' do
|
4
|
+
it 'returns ready shipments from complete orders' do
|
5
|
+
stub_configuration(capture_at_notification: false, export_canceled_shipments: false)
|
6
|
+
|
7
|
+
ready_shipment = create(:order_ready_to_ship).shipments.first
|
8
|
+
create(:order_ready_to_ship) { |o| o.shipments.first.cancel! }
|
9
|
+
create(:shipped_order)
|
10
|
+
|
11
|
+
expect(described_class.apply(Spree::Shipment.all)).to eq([ready_shipment])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when capture_at_notification is true and export_canceled_shipments is false' do
|
16
|
+
it 'returns non-canceled shipments from complete orders' do
|
17
|
+
stub_configuration(capture_at_notification: true, export_canceled_shipments: false)
|
18
|
+
|
19
|
+
ready_shipment = create(:order_ready_to_ship).shipments.first
|
20
|
+
shipped_shipment = create(:shipped_order).shipments.first
|
21
|
+
create(:order_ready_to_ship) { |o| o.shipments.first.cancel! }
|
22
|
+
|
23
|
+
expect(described_class.apply(Spree::Shipment.all)).to eq([ready_shipment, shipped_shipment])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when capture_at_notification is false and export_canceled_shipments is true' do
|
28
|
+
it 'returns ready and canceled shipments from complete orders' do
|
29
|
+
stub_configuration(capture_at_notification: false, export_canceled_shipments: true)
|
30
|
+
|
31
|
+
ready_shipment = create(:order_ready_to_ship).shipments.first
|
32
|
+
canceled_shipment = create(:order_ready_to_ship).shipments.first
|
33
|
+
canceled_shipment.cancel!
|
34
|
+
create(:shipped_order)
|
35
|
+
|
36
|
+
expect(described_class.apply(Spree::Shipment.all)).to eq([ready_shipment, canceled_shipment])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when capture_at_notification is true and export_canceled_shipments is true' do
|
41
|
+
it 'returns all shipments from complete orders' do
|
42
|
+
stub_configuration(capture_at_notification: true, export_canceled_shipments: true)
|
43
|
+
|
44
|
+
ready_shipment = create(:order_ready_to_ship).shipments.first
|
45
|
+
canceled_shipment = create(:order_ready_to_ship).shipments.first
|
46
|
+
canceled_shipment.cancel!
|
47
|
+
shipped_shipment = create(:shipped_order).shipments.first
|
48
|
+
|
49
|
+
expect(described_class.apply(Spree::Shipment.all)).to eq([ready_shipment, canceled_shipment, shipped_shipment])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|