summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorAlessandro Desantis <desa.alessandro@gmail.com>2021-02-05 13:30:47 +0100
committerGitHub <noreply@github.com>2021-02-05 13:30:47 +0100
commit3a3657b79bd5d98025136da4b39751e6a43b7b9f (patch)
treeb7a57b183641d64d05e5e70e281fd78cb5e37ebd /spec
parent69f0ca038b66d0ca36971405e51c0d3aa916cf19 (diff)
parent4717d24c0e7203210efe8c23b55467c3e728cdc5 (diff)
Merge pull request #172 from solidusio-contrib/aldesantis/refactoring
Processor and Checkout refactoring
Diffstat (limited to 'spec')
-rw-r--r--spec/jobs/solidus_subscriptions/process_installment_job_spec.rb11
-rw-r--r--spec/jobs/solidus_subscriptions/process_installments_job_spec.rb28
-rw-r--r--spec/lib/solidus_subscriptions/checkout_spec.rb122
-rw-r--r--spec/lib/solidus_subscriptions/dispatcher/failure_dispatcher_spec.rb27
-rw-r--r--spec/lib/solidus_subscriptions/dispatcher/out_of_stock_dispatcher_spec.rb13
-rw-r--r--spec/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher_spec.rb42
-rw-r--r--spec/lib/solidus_subscriptions/dispatcher/success_dispatcher_spec.rb28
-rw-r--r--spec/lib/solidus_subscriptions/processor_spec.rb202
-rw-r--r--spec/lib/solidus_subscriptions/subscription_generator_spec.rb (renamed from spec/services/solidus_subscriptions/subscription_generator_spec.rb)0
-rw-r--r--spec/lib/solidus_subscriptions/subscription_order_promotion_rule_spec.rb (renamed from spec/services/solidus_subscriptions/subscription_order_promotion_rule_spec.rb)0
-rw-r--r--spec/lib/solidus_subscriptions/subscription_promotion_rule_spec.rb (renamed from spec/services/solidus_subscriptions/subscription_promotion_rule_spec.rb)0
-rw-r--r--spec/models/solidus_subscriptions/installment_spec.rb9
-rw-r--r--spec/models/solidus_subscriptions/line_item_spec.rb86
-rw-r--r--spec/models/solidus_subscriptions/subscription_spec.rb10
-rw-r--r--spec/services/solidus_subscriptions/checkout_spec.rb389
-rw-r--r--spec/services/solidus_subscriptions/dispatcher_spec.rb11
-rw-r--r--spec/services/solidus_subscriptions/failure_dispatcher_spec.rb27
-rw-r--r--spec/services/solidus_subscriptions/line_item_builder_spec.rb33
-rw-r--r--spec/services/solidus_subscriptions/order_builder_spec.rb53
-rw-r--r--spec/services/solidus_subscriptions/out_of_stock_dispatcher_spec.rb12
-rw-r--r--spec/services/solidus_subscriptions/payment_failed_dispatcher_spec.rb42
-rw-r--r--spec/services/solidus_subscriptions/success_dispatcher_spec.rb28
-rw-r--r--spec/subscribers/solidus_subscriptions/churn_buster_subscriber_spec.rb12
23 files changed, 334 insertions, 851 deletions
diff --git a/spec/jobs/solidus_subscriptions/process_installment_job_spec.rb b/spec/jobs/solidus_subscriptions/process_installment_job_spec.rb
new file mode 100644
index 0000000..4a33819
--- /dev/null
+++ b/spec/jobs/solidus_subscriptions/process_installment_job_spec.rb
@@ -0,0 +1,11 @@
+RSpec.describe SolidusSubscriptions::ProcessInstallmentJob do
+ it 'processes checkout for the installment' do
+ installment = build_stubbed(:installment)
+ checkout = instance_spy(SolidusSubscriptions::Checkout)
+ allow(SolidusSubscriptions::Checkout).to receive(:new).with(installment).and_return(checkout)
+
+ described_class.perform_now(installment)
+
+ expect(checkout).to have_received(:process)
+ end
+end
diff --git a/spec/jobs/solidus_subscriptions/process_installments_job_spec.rb b/spec/jobs/solidus_subscriptions/process_installments_job_spec.rb
deleted file mode 100644
index 111fc05..0000000
--- a/spec/jobs/solidus_subscriptions/process_installments_job_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-require 'spec_helper'
-
-RSpec.describe SolidusSubscriptions::ProcessInstallmentsJob do
- let(:root_order) { create :completed_order_with_pending_payment }
- let(:installments) do
- traits = {
- subscription_traits: [{
- user: root_order.user,
- line_item_traits: [{
- spree_line_item: root_order.line_items.first
- }]
- }]
- }
-
- create_list(:installment, 2, traits)
- end
-
- describe '#perform' do
- subject { described_class.new.perform(installments) }
-
- it 'processes the consolidated installment' do
- expect_any_instance_of(SolidusSubscriptions::Checkout).
- to receive(:process).once
-
- subject
- end
- end
-end
diff --git a/spec/lib/solidus_subscriptions/checkout_spec.rb b/spec/lib/solidus_subscriptions/checkout_spec.rb
new file mode 100644
index 0000000..2a83d9b
--- /dev/null
+++ b/spec/lib/solidus_subscriptions/checkout_spec.rb
@@ -0,0 +1,122 @@
+RSpec.describe SolidusSubscriptions::Checkout, :checkout do
+ context 'when the order can be created and paid' do
+ it 'creates and finalizes a new order for the installment' do
+ stub_spree_preferences(auto_capture: true)
+ installment = create(:installment, :actionable)
+
+ order = described_class.new(installment).process
+
+ expect(order).to be_complete
+ expect(order).to be_paid
+ end
+
+ # rubocop:disable RSpec/MultipleExpectations
+ it 'copies basic information from the subscription' do
+ stub_spree_preferences(auto_capture: true)
+ installment = create(:installment, :actionable)
+ subscription = installment.subscription
+
+ order = described_class.new(installment).process
+
+ expect(order.ship_address.value_attributes).to eq(subscription.shipping_address_to_use.value_attributes)
+ expect(order.bill_address.value_attributes).to eq(subscription.billing_address_to_use.value_attributes)
+ expect(order.payments.first.payment_method).to eq(subscription.payment_method_to_use)
+ expect(order.payments.first.source).to eq(subscription.payment_source_to_use)
+ expect(order.user).to eq(subscription.user)
+ expect(order.email).to eq(subscription.user.email)
+ end
+ # rubocop:enable RSpec/MultipleExpectations
+
+ it 'marks the order as a subscription order' do
+ stub_spree_preferences(auto_capture: true)
+ installment = create(:installment, :actionable)
+ subscription = installment.subscription
+
+ order = described_class.new(installment).process
+
+ expect(order.subscription).to eq(subscription)
+ expect(order.subscription_order).to eq(true)
+ end
+
+ it 'matches the total on the subscription' do
+ stub_spree_preferences(auto_capture: true)
+ installment = create(:installment, :actionable)
+ subscription = installment.subscription
+
+ order = described_class.new(installment).process
+
+ expect(order.item_total).to eq(subscription.line_items.first.subscribable.price)
+ end
+
+ it 'calls the success dispatcher' do
+ stub_spree_preferences(auto_capture: true)
+ installment = create(:installment, :actionable)
+ success_dispatcher = stub_dispatcher(SolidusSubscriptions::Dispatcher::SuccessDispatcher, installment)
+
+ described_class.new(installment).process
+
+ expect(success_dispatcher).to have_received(:dispatch)
+ end
+ end
+
+ context 'when payment of the order fails' do
+ it 'calls the payment failed dispatcher' do
+ stub_spree_preferences(auto_capture: true)
+ installment = create(:installment, :actionable).tap do |i|
+ i.subscription.update!(payment_source: create(:credit_card, number: '4111123412341234'))
+ end
+ payment_failed_dispatcher = stub_dispatcher(SolidusSubscriptions::Dispatcher::PaymentFailedDispatcher, installment)
+
+ described_class.new(installment).process
+
+ expect(payment_failed_dispatcher).to have_received(:dispatch)
+ end
+ end
+
+ context 'when an item is out of stock' do
+ it 'calls the out of stock dispatcher' do
+ stub_spree_preferences(auto_capture: true)
+ installment = create(:installment, :actionable).tap do |i|
+ i.subscription.line_items.first.subscribable.stock_items.each do |stock_item|
+ stock_item.update!(backorderable: false)
+ end
+ end
+ out_of_stock_dispatcher = stub_dispatcher(SolidusSubscriptions::Dispatcher::OutOfStockDispatcher, installment)
+
+ described_class.new(installment).process
+
+ expect(out_of_stock_dispatcher).to have_received(:dispatch)
+ end
+ end
+
+ context 'when a generic transition error happens during checkout' do
+ it 'calls the failure dispatcher' do
+ stub_spree_preferences(auto_capture: true)
+ installment = create(:installment, :actionable)
+ failure_dispatcher = stub_dispatcher(SolidusSubscriptions::Dispatcher::FailureDispatcher, installment)
+ # rubocop:disable RSpec/AnyInstance
+ allow_any_instance_of(Spree::Order).to receive(:next!)
+ .and_raise(StateMachines::InvalidTransition.new(
+ Spree::Order.new,
+ Spree::Order.state_machines[:state],
+ :next,
+ ))
+ # rubocop:enable RSpec/AnyInstance
+
+ described_class.new(installment).process
+
+ expect(failure_dispatcher).to have_received(:dispatch)
+ end
+ end
+
+ private
+
+ def stub_dispatcher(klass, installment)
+ instance_spy(klass).tap do |dispatcher|
+ allow(klass).to receive(:new).with(
+ installment,
+ an_instance_of(Spree::Order)
+ ).and_return(dispatcher)
+ end
+ end
+end
diff --git a/spec/lib/solidus_subscriptions/dispatcher/failure_dispatcher_spec.rb b/spec/lib/solidus_subscriptions/dispatcher/failure_dispatcher_spec.rb
new file mode 100644
index 0000000..f247237
--- /dev/null
+++ b/spec/lib/solidus_subscriptions/dispatcher/failure_dispatcher_spec.rb
@@ -0,0 +1,27 @@
+RSpec.describe SolidusSubscriptions::Dispatcher::FailureDispatcher do
+ describe '#dispatch' do
+ it 'marks the installment as failed' do
+ installment = instance_spy(SolidusSubscriptions::Installment)
+ order = create(:order_with_line_items)
+
+ dispatcher = described_class.new(installment, order)
+ dispatcher.dispatch
+
+ expect(installment).to have_received(:failed!).with(order)
+ end
+
+ it 'cancels the order' do
+ if Spree.solidus_gem_version > Gem::Version.new('2.10')
+ skip 'Orders in `cart` state cannot be canceled starting from Solidus 2.11.'
+ end
+
+ installment = instance_spy(SolidusSubscriptions::Installment)
+ order = create(:order_with_line_items)
+
+ dispatcher = described_class.new(installment, order)
+ dispatcher.dispatch
+
+ expect(order.state).to eq('canceled')
+ end
+ end
+end
diff --git a/spec/lib/solidus_subscriptions/dispatcher/out_of_stock_dispatcher_spec.rb b/spec/lib/solidus_subscriptions/dispatcher/out_of_stock_dispatcher_spec.rb
new file mode 100644
index 0000000..abb8343
--- /dev/null
+++ b/spec/lib/solidus_subscriptions/dispatcher/out_of_stock_dispatcher_spec.rb
@@ -0,0 +1,13 @@
+RSpec.describe SolidusSubscriptions::Dispatcher::OutOfStockDispatcher do
+ describe '#dispatch' do
+ it 'marks the installment as out of stock' do
+ installment = instance_spy(SolidusSubscriptions::Installment)
+ order = build_stubbed(:order)
+
+ dispatcher = described_class.new(installment, order)
+ dispatcher.dispatch
+
+ expect(installment).to have_received(:out_of_stock)
+ end
+ end
+end
diff --git a/spec/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher_spec.rb b/spec/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher_spec.rb
new file mode 100644
index 0000000..0a222d4
--- /dev/null
+++ b/spec/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher_spec.rb
@@ -0,0 +1,42 @@
+RSpec.describe SolidusSubscriptions::Dispatcher::PaymentFailedDispatcher do
+ describe '#dispatch' do
+ it 'marks the installment as payment_failed' do
+ installment = instance_spy(SolidusSubscriptions::Installment)
+ order = create(:order_with_line_items)
+
+ dispatcher = described_class.new(installment, order)
+ dispatcher.dispatch
+
+ expect(installment).to have_received(:payment_failed!).with(order)
+ end
+
+ it 'cancels the order' do
+ if Spree.solidus_gem_version > Gem::Version.new('2.10')
+ skip 'Orders in `cart` state cannot be canceled starting from Solidus 2.11.'
+ end
+
+ installment = instance_spy(SolidusSubscriptions::Installment)
+ order = create(:order_with_line_items)
+
+ dispatcher = described_class.new(installment, order)
+ dispatcher.dispatch
+
+ expect(order.state).to eq('canceled')
+ end
+
+ it 'fires an installments_failed_payment event' do
+ stub_const('Spree::Event', class_spy(Spree::Event))
+ installment = instance_spy(SolidusSubscriptions::Installment)
+ order = create(:order_with_line_items)
+
+ dispatcher = described_class.new(installment, order)
+ dispatcher.dispatch
+
+ expect(Spree::Event).to have_received(:fire).with(
+ 'solidus_subscriptions.installment_failed_payment',
+ installment: installment,
+ order: order,
+ )
+ end
+ end
+end
diff --git a/spec/lib/solidus_subscriptions/dispatcher/success_dispatcher_spec.rb b/spec/lib/solidus_subscriptions/dispatcher/success_dispatcher_spec.rb
new file mode 100644
index 0000000..6a71800
--- /dev/null
+++ b/spec/lib/solidus_subscriptions/dispatcher/success_dispatcher_spec.rb
@@ -0,0 +1,28 @@
+RSpec.describe SolidusSubscriptions::Dispatcher::SuccessDispatcher do
+ describe '#dispatch' do
+ it 'marks the installment as success' do
+ installment = instance_spy(SolidusSubscriptions::Installment)
+ order = create(:order_with_line_items)
+
+ dispatcher = described_class.new(installment, order)
+ dispatcher.dispatch
+
+ expect(installment).to have_received(:success!).with(order)
+ end
+
+ it 'fires an installments_succeeded event' do
+ stub_const('Spree::Event', class_spy(Spree::Event))
+ installment = instance_spy(SolidusSubscriptions::Installment)
+ order = create(:order_with_line_items)
+
+ dispatcher = described_class.new(installment, order)
+ dispatcher.dispatch
+
+ expect(Spree::Event).to have_received(:fire).with(
+ 'solidus_subscriptions.installment_succeeded',
+ installment: installment,
+ order: order,
+ )
+ end
+ end
+end
diff --git a/spec/lib/solidus_subscriptions/processor_spec.rb b/spec/lib/solidus_subscriptions/processor_spec.rb
index d3bb268..e82c0e9 100644
--- a/spec/lib/solidus_subscriptions/processor_spec.rb
+++ b/spec/lib/solidus_subscriptions/processor_spec.rb
@@ -1,156 +1,124 @@
-require 'spec_helper'
-
RSpec.describe SolidusSubscriptions::Processor, :checkout do
- include ActiveJob::TestHelper
- around { |e| perform_enqueued_jobs { e.run } }
-
- let!(:user) { create(:user, :subscription_user) }
- let!(:credit_card) {
- card = create(:credit_card, gateway_customer_profile_id: 'BGS-123', user: user)
- wallet_payment_source = user.wallet.add(card)
- user.wallet.default_wallet_payment_source = wallet_payment_source
- user.save
- card
- }
-
- let!(:actionable_subscriptions) { create_list(:subscription, 2, :actionable, user: user) }
- let!(:pending_cancellation_subscriptions) do
- create_list(:subscription, 2, :pending_cancellation, user: user)
- end
+ shared_examples 'processes the subscription' do
+ it 'resets the successive_skip_count' do
+ subscription
+ subscription.update_columns(successive_skip_count: 3)
- let!(:expiring_subscriptions) do
- create_list(
- :subscription,
- 2,
- :actionable,
- :with_line_item,
- user: user,
- end_date: Date.current.tomorrow,
- )
- end
+ described_class.run
- let!(:future_subscriptions) { create_list(:subscription, 2, :not_actionable) }
- let!(:canceled_subscriptions) { create_list(:subscription, 2, :canceled) }
- let!(:inactive) { create_list(:subscription, 2, :inactive) }
-
- let!(:successful_installments) { create_list :installment, 2, :success }
- let!(:failed_installments) do
- create_list(
- :installment,
- 2,
- :failed,
- subscription_traits: [{ user: user }]
- )
- end
+ expect(subscription.reload.successive_skip_count).to eq(0)
+ end
- # all subscriptions and previously failed installments belong to the same user
- let(:expected_orders) { 1 }
+ context 'with clear_past_installments set to true' do
+ it 'clears any past unfulfilled installments' do
+ stub_config(clear_past_installments: true)
+ subscription
+ installment = create(:installment, :actionable, subscription: subscription)
- shared_examples 'a subscription order' do
- let(:order_variant_ids) { Spree::Order.last.variant_ids }
- let(:expected_ids) do
- subs = actionable_subscriptions + pending_cancellation_subscriptions + expiring_subscriptions
- subs_ids = subs.flat_map { |s| s.line_items.pluck(:subscribable_id) }
- inst_ids = failed_installments.flat_map { |i| i.subscription.line_items.pluck(:subscribable_id) }
+ described_class.run
- subs_ids + inst_ids
+ expect(installment.reload.actionable_date).to eq(nil)
+ end
end
- it 'creates the correct number of orders' do
- expect { subject }.to change { Spree::Order.complete.count }.by expected_orders
- end
+ context 'with clear_past_installments set to false' do
+ it 'does not clear any past unfulfilled installments' do
+ stub_config(clear_past_installments: false)
+ subscription
+ installment = create(:installment, :actionable, subscription: subscription)
- it 'creates the correct order' do
- subject
- expect(order_variant_ids).to match_array expected_ids
+ described_class.run
+
+ expect(installment.reload.actionable_date).not_to be_nil
+ end
end
- it 'advances the subscription actionable dates' do
- subscription = actionable_subscriptions.first
+ it 'creates a new installment' do
+ subscription
- current_date = subscription.actionable_date
- expected_date = subscription.next_actionable_date
+ described_class.run
- expect { subject }.
- to change { subscription.reload.actionable_date }.
- from(current_date).to(expected_date)
+ expect(subscription.installments.count).to eq(1)
end
- it 'cancels subscriptions pending cancellation' do
- subs = pending_cancellation_subscriptions.first
- expect { subject }.
- to change { subs.reload.state }.
- from('pending_cancellation').to('canceled')
- end
+ it 'schedules the newly created installment for processing' do
+ subscription
+
+ described_class.run
- it 'resets the subscription successive skip count' do
- subs = pending_cancellation_subscriptions.first
- expect { subject }.
- to change { subs.reload.state }.
- from('pending_cancellation').to('canceled')
+ expect(SolidusSubscriptions::ProcessInstallmentJob).to have_been_enqueued
+ .with(subscription.installments.last)
end
- it 'deactivates expired subscriptions' do
- sub = expiring_subscriptions.first
+ it 'schedules other actionable installments for processing' do
+ actionable_installment = create(:installment, :actionable)
- expect { subject }.
- to change { sub.reload.state }.
- from('active').to('inactive')
+ described_class.run
+
+ expect(SolidusSubscriptions::ProcessInstallmentJob).to have_been_enqueued
+ .with(actionable_installment)
end
+ end
- context 'the subscriptions have different shipping addresses' do
- let!(:sub_to_different_address) do
- create(:subscription, :actionable, :with_shipping_address, user: user)
- end
+ shared_examples 'schedules the subscription for reprocessing' do
+ it 'advances the actionable_date' do
+ subscription
+ subscription.update_columns(interval_length: 1, interval_units: 'week')
+ old_actionable_date = subscription.actionable_date
- it 'creates an order for each shipping address' do
- expect { subject }.to change { Spree::Order.complete.count }.by 2
- end
+ described_class.run
+
+ expect(subscription.reload.actionable_date.to_date).to eq((old_actionable_date + 1.week).to_date)
end
+ end
- context "when the config 'clear_past_installments' is enabled" do
- it 'clears the past failed installments' do
- stub_config(clear_past_installments: true)
+ context 'with a regular subscription' do
+ let(:subscription) { create(:subscription, :actionable) }
- subject
+ include_examples 'processes the subscription'
+ include_examples 'schedules the subscription for reprocessing'
+ end
- failed_installments.each do |fi|
- expect(fi.reload.actionable_date).to eq(nil)
- end
- end
+ context 'with a subscription that is pending deactivation' do
+ let(:subscription) do
+ create(
+ :subscription,
+ :actionable,
+ interval_units: 'week',
+ interval_length: 2,
+ end_date: 3.days.from_now,
+ )
end
- context 'the subscriptions have different billing addresses' do
- let!(:sub_to_different_address) do
- create(:subscription, :actionable, :with_billing_address, user: user)
- end
+ include_examples 'processes the subscription'
+ include_examples 'schedules the subscription for reprocessing'
- it 'creates an order for each billing address' do
- expect { subject }.to change { Spree::Order.complete.count }.by 2
- end
- end
+ it 'deactivates the subscription' do
+ subscription
- context 'the subscription is cancelled with pending installments' do
- let!(:cancelled_installment) do
- installment = create(:installment, actionable_date: Time.zone.today)
- installment.subscription.cancel!
- end
+ described_class.run
- it 'does not process the installment' do
- expect { subject }.to change { Spree::Order.complete.count }.by expected_orders
- end
+ expect(subscription.reload.state).to eq('inactive')
end
end
- describe '.run' do
- subject { described_class.run }
+ context 'with a subscription that is pending cancellation' do
+ let(:subscription) do
+ create(
+ :subscription,
+ :actionable,
+ :pending_cancellation,
+ )
+ end
- it_behaves_like 'a subscription order'
- end
+ include_examples 'processes the subscription'
+
+ it 'cancels the subscription' do
+ subscription
- describe '#build_jobs' do
- subject { described_class.new([user]).build_jobs }
+ described_class.run
- it_behaves_like 'a subscription order'
+ expect(subscription.reload.state).to eq('canceled')
+ end
end
end
diff --git a/spec/services/solidus_subscriptions/subscription_generator_spec.rb b/spec/lib/solidus_subscriptions/subscription_generator_spec.rb
index b7d73b8..b7d73b8 100644
--- a/spec/services/solidus_subscriptions/subscription_generator_spec.rb
+++ b/spec/lib/solidus_subscriptions/subscription_generator_spec.rb
diff --git a/spec/services/solidus_subscriptions/subscription_order_promotion_rule_spec.rb b/spec/lib/solidus_subscriptions/subscription_order_promotion_rule_spec.rb
index bacbef2..bacbef2 100644
--- a/spec/services/solidus_subscriptions/subscription_order_promotion_rule_spec.rb
+++ b/spec/lib/solidus_subscriptions/subscription_order_promotion_rule_spec.rb
diff --git a/spec/services/solidus_subscriptions/subscription_promotion_rule_spec.rb b/spec/lib/solidus_subscriptions/subscription_promotion_rule_spec.rb
index f4c65cc..f4c65cc 100644
--- a/spec/services/solidus_subscriptions/subscription_promotion_rule_spec.rb
+++ b/spec/lib/solidus_subscriptions/subscription_promotion_rule_spec.rb
diff --git a/spec/models/solidus_subscriptions/installment_spec.rb b/spec/models/solidus_subscriptions/installment_spec.rb
index 4e4831e..399a7e6 100644
--- a/spec/models/solidus_subscriptions/installment_spec.rb
+++ b/spec/models/solidus_subscriptions/installment_spec.rb
@@ -5,15 +5,6 @@ RSpec.describe SolidusSubscriptions::Installment, type: :model do
it { is_expected.to validate_presence_of :subscription }
- describe '#line_item_builder' do
- subject { installment.line_item_builder }
-
- let(:line_items) { installment.subscription.line_items }
-
- it { is_expected.to be_a SolidusSubscriptions::LineItemBuilder }
- it { is_expected.to have_attributes(subscription_line_items: line_items) }
- end
-
describe '#out_of_stock' do
subject { installment.out_of_stock }
diff --git a/spec/models/solidus_subscriptions/line_item_spec.rb b/spec/models/solidus_subscriptions/line_item_spec.rb
index ad80384..aaa24a5 100644
--- a/spec/models/solidus_subscriptions/line_item_spec.rb
+++ b/spec/models/solidus_subscriptions/line_item_spec.rb
@@ -24,90 +24,4 @@ RSpec.describe SolidusSubscriptions::LineItem, type: :model do
expect(subject.from_now).to eq Date.parse("2016-10-22")
end
end
-
- describe '#as_json' do
- subject { line_item.as_json }
-
- around { |e| Timecop.freeze { e.run } }
-
- let(:line_item) { create(:subscription_line_item, :with_subscription) }
-
- let(:expected_hash) do
- hash = {
- "id" => line_item.id,
- "spree_line_item_id" => line_item.spree_line_item.id,
- "subscription_id" => line_item.subscription_id,
- "quantity" => line_item.quantity,
- "end_date" => line_item.end_date,
- "subscribable_id" => line_item.subscribable_id,
- "created_at" => line_item.created_at,
- "updated_at" => line_item.updated_at,
- "interval_units" => line_item.interval_units,
- "interval_length" => line_item.interval_length
- }
- Rails.gem_version >= Gem::Version.new('6.0.0') ? hash.as_json : hash
- end
-
- it 'includes the attribute values' do
- expect(subject).to match a_hash_including(expected_hash)
- end
-
- it 'includes the dummy lineitem' do
- expect(subject).to have_key('dummy_line_item')
- end
- end
-
- describe '#dummy_line_item' do
- subject { line_item.dummy_line_item }
-
- let(:line_item) { create(:subscription_line_item, :with_subscription) }
-
- it { is_expected.to be_a Spree::LineItem }
- it { is_expected.to be_frozen }
-
- it 'has the correct variant' do
- expect(subject.variant_id).to eq line_item.subscribable_id
- end
-
- context 'with no spree line item' do
- let(:line_item) { create(:subscription_line_item, :with_subscription, spree_line_item: nil) }
-
- it { is_expected.to be_a Spree::LineItem }
- it { is_expected.to be_frozen }
-
- it 'has the correct variant' do
- expect(subject.variant_id).to eq line_item.subscribable_id
- end
- end
-
- context 'with an associated subscription' do
- context 'the associated subscription has a shipping address' do
- let(:line_item) do
- create(:subscription_line_item, :with_subscription, subscription_traits: [:with_shipping_address])
- end
-
- it 'uses the subscription shipping address' do
- expect(subject.order.ship_address).to eq line_item.subscription.shipping_address
- end
-
- it 'uses the subscription users billing address' do
- expect(subject.order.bill_address).to eq line_item.subscription.user.bill_address
- end
- end
-
- context 'the associated subscription has a billing address' do
- let(:line_item) do
- create(:subscription_line_item, :with_subscription, subscription_traits: [:with_billing_address])
- end
-
- it 'uses the subscription users shipping address' do
- expect(subject.order.ship_address).to eq line_item.subscription.user.ship_address
- end
-
- it 'uses the subscription billing address' do
- expect(subject.order.bill_address).to eq line_item.subscription.billing_address
- end
- end
- end
- end
end
diff --git a/spec/models/solidus_subscriptions/subscription_spec.rb b/spec/models/solidus_subscriptions/subscription_spec.rb
index 5d855db..f305580 100644
--- a/spec/models/solidus_subscriptions/subscription_spec.rb
+++ b/spec/models/solidus_subscriptions/subscription_spec.rb
@@ -348,16 +348,6 @@ RSpec.describe SolidusSubscriptions::Subscription, type: :model do
end
end
- describe '#line_item_builder' do
- subject { subscription.line_item_builder }
-
- let(:subscription) { create :subscription, :with_line_item }
- let(:line_items) { subscription.line_items }
-
- it { is_expected.to be_a SolidusSubscriptions::LineItemBuilder }
- it { is_expected.to have_attributes(subscription_line_items: line_items) }
- end
-
describe '#processing_state' do
subject { subscription.processing_state }
diff --git a/spec/services/solidus_subscriptions/checkout_spec.rb b/spec/services/solidus_subscriptions/checkout_spec.rb
deleted file mode 100644
index 4b408dc..0000000
--- a/spec/services/solidus_subscriptions/checkout_spec.rb
+++ /dev/null
@@ -1,389 +0,0 @@
-require 'spec_helper'
-
-RSpec.describe SolidusSubscriptions::Checkout do
- let(:checkout) { described_class.new(installments) }
- let(:root_order) { create :completed_order_with_pending_payment, user: subscription_user }
- let(:subscription_user) { create(:user, :subscription_user) }
- let!(:credit_card) {
- card = create(:credit_card, user: subscription_user, gateway_customer_profile_id: 'BGS-123', payment_method: payment_method)
- wallet_payment_source = subscription_user.wallet.add(card)
- subscription_user.wallet.default_wallet_payment_source = wallet_payment_source
- card
- }
- let(:payment_method) { create(:payment_method) }
- let(:installments) { create_list(:installment, 2, installment_traits) }
-
- let(:installment_traits) do
- {
- subscription_traits: [{
- user: subscription_user,
- line_item_traits: [{
- spree_line_item: root_order.line_items.first
- }]
- }]
- }
- end
-
- before do
- Spree::Variant.all.each { |v| v.update(subscribable: true) }
- end
-
- context 'initialized with installments belonging to multiple users' do
- subject { checkout }
-
- let(:installments) { build_stubbed_list :installment, 2 }
-
- it 'raises an error' do
- expect { subject }.
- to raise_error SolidusSubscriptions::UserMismatchError, /must have the same user/
- end
- end
-
- describe '#process', :checkout do
- subject(:order) { checkout.process }
-
- let(:subscription_line_item) { installments.first.subscription.line_items.first }
-
- shared_examples 'a completed checkout' do
- it { is_expected.to be_a Spree::Order }
-
- let(:total) { 49.98 }
- let(:quantity) { installments.length }
-
- it 'has the correct number of line items' do
- count = order.line_items.length
- expect(count).to eq quantity
- end
-
- it 'the line items have the correct values' do
- line_item = order.line_items.first
- expect(line_item).to have_attributes(
- quantity: subscription_line_item.quantity,
- variant_id: subscription_line_item.subscribable_id
- )
- end
-
- it 'has a shipment' do
- expect(order.shipments).to be_present
- end
-
- it 'has a payment' do
- expect(order.payments.valid).to be_present
- end
-
- it 'has the correct totals' do
- expect(order).to have_attributes(
- total: total,
- shipment_total: 10
- )
- end
-
- it { is_expected.to be_complete }
-
- it 'associates the order to the installment detail' do
- order
- installment_orders = installments.flat_map { |i| i.details.map(&:order) }.compact
- expect(installment_orders).to all eq order
- end
-
- it 'creates an installment detail for each installment' do
- expect { subject }.
- to change { SolidusSubscriptions::InstallmentDetail.count }.
- by(installments.count)
- end
- end
-
- context 'no line items get added to the cart' do
- before do
- installments
- Spree::StockItem.update_all(count_on_hand: 0, backorderable: false)
- end
-
- it 'creates two failed installment details' do
- expect { order }.
- to change { SolidusSubscriptions::InstallmentDetail.count }.
- by(installments.length)
-
- details = SolidusSubscriptions::InstallmentDetail.last(installments.length)
- expect(details).to all be_failed
- end
-
- it { is_expected.to be_nil }
-
- it 'creates no order' do
- expect { subject }.not_to change { Spree::Order.count }
- end
- end
-
- if Gem::Specification.find_by_name('solidus').version >= Gem::Version.new('1.4.0')
- context 'Altered checkout flow' do
- before do
- @old_checkout_flow = Spree::Order.checkout_flow
- Spree::Order.remove_checkout_step(:delivery)
- end
-
- after do
- Spree::Order.checkout_flow(&@old_checkout_flow)
- end
-
- it 'has a payment' do
- expect(order.payments.valid).to be_present
- end
-
- it 'has the correct totals' do
- expect(order).to have_attributes(
- total: 39.98,
- shipment_total: 0
- )
- end
-
- it { is_expected.to be_complete }
- end
- end
-
- context 'the variant is out of stock' do
- let(:subscription_line_item) { installments.last.subscription.line_items.first }
- let(:expected_date) { Time.zone.today + SolidusSubscriptions.configuration.reprocessing_interval }
-
- # Remove stock for 1 variant in the consolidated installment
- before do
- subscribable_id = installments.first.subscription.line_items.first.subscribable_id
- variant = Spree::Variant.find(subscribable_id)
- variant.stock_items.update_all(count_on_hand: 0, backorderable: false)
- end
-
- it 'creates a failed installment detail' do
- subject
- detail = installments.first.details.last
-
- expect(detail).not_to be_successful
- expect(detail.message).
- to eq I18n.t('solidus_subscriptions.installment_details.out_of_stock')
- end
-
- it 'removes the installment from the list of installments' do
- expect { subject }.
- to change { checkout.installments.length }.
- by(-1)
- end
-
- it_behaves_like 'a completed checkout' do
- let(:total) { 29.99 }
- let(:quantity) { installments.length - 1 }
- end
- end
-
- context 'the payment fails' do
- let(:payment_method) { create(:payment_method) }
- let!(:credit_card) {
- card = create(:credit_card, user: checkout.user, payment_method: payment_method)
- wallet_payment_source = checkout.user.wallet.add(card)
- checkout.user.wallet.default_wallet_payment_source = wallet_payment_source
- card
- }
- let(:expected_date) { Time.zone.today + SolidusSubscriptions.configuration.reprocessing_interval }
-
- it { is_expected.to be_nil }
-
- it 'marks all of the installments as failed' do
- subject
-
- details = installments.map do |installments|
- installments.details.reload.last
- end
-
- expect(details).to all be_failed && have_attributes(
- message: I18n.t('solidus_subscriptions.installment_details.payment_failed')
- )
- end
-
- it 'marks the installment to be reprocessed' do
- subject
- actionable_dates = installments.map do |installment|
- installment.reload.actionable_date
- end
-
- expect(actionable_dates).to all eq expected_date
- end
- end
-
- context 'when there are cart promotions' do
- let!(:promo) do
- create(
- :promotion,
- :with_item_total_rule,
- :with_order_adjustment,
- promo_params
- )
- end
-
- # Promotions require the :apply_automatically flag to be auto applied in
- # solidus versions greater than 1.0
- let(:promo_params) do
- {}.tap do |params|
- if Spree::Promotion.new.respond_to?(:apply_automatically)
- params[:apply_automatically] = true
- end
- end
- end
-
- it_behaves_like 'a completed checkout' do
- let(:total) { 39.98 }
- end
-
- it 'applies the correct adjustments' do
- expect(subject.adjustments).to be_present
- end
- end
-
- context 'there is an aribitrary failure' do
- let(:expected_date) { Time.zone.today + SolidusSubscriptions.configuration.reprocessing_interval }
-
- before do
- allow(checkout).to receive(:populate).and_raise('arbitrary runtime error')
- end
-
- it 'advances the installment actionable dates', :aggregate_failures do
- expect { subject }.to raise_error('arbitrary runtime error')
-
- actionable_dates = installments.map do |installment|
- installment.reload.actionable_date
- end
-
- expect(actionable_dates).to all eq expected_date
- end
- end
-
- context 'the user has store credit' do
- let!(:store_credit) { create :store_credit, user: subscription_user }
- let!(:store_credit_payment_method) { create :store_credit_payment_method }
-
- it_behaves_like 'a completed checkout'
-
- it 'has a valid store credit payment' do
- expect(order.payments.valid.store_credits).to be_present
- end
- end
-
- context 'the subscription has a shipping address' do
- let(:installment_traits) do
- {
- subscription_traits: [{
- shipping_address: shipping_address,
- user: subscription_user,
- line_item_traits: [{ spree_line_item: root_order.line_items.first }]
- }]
- }
- end
- let(:shipping_address) { create :address }
-
- it_behaves_like 'a completed checkout'
-
- it 'ships to the subscription address' do
- expect(subject.ship_address).to eq shipping_address
- end
- end
-
- context 'the subscription has a billing address' do
- let(:installment_traits) do
- {
- subscription_traits: [{
- billing_address: billing_address,
- user: subscription_user,
- line_item_traits: [{ spree_line_item: root_order.line_items.first }]
- }]
- }
- end
- let(:billing_address) { create :address }
-
- it_behaves_like 'a completed checkout'
-
- it 'bills to the subscription address' do
- expect(subject.bill_address).to eq billing_address
- end
- end
-
- context 'the subscription has a payment method' do
- let(:installment_traits) do
- {
- subscription_traits: [{
- payment_method: payment_method,
- user: subscription_user,
- line_item_traits: [{ spree_line_item: root_order.line_items.first }]
- }]
- }
- end
- let(:payment_method) { create :check_payment_method }
-
- it_behaves_like 'a completed checkout'
-
- it 'pays with the payment method' do
- expect(subject.payments.valid.first.payment_method).to eq payment_method
- end
- end
-
- context 'the subscription has a payment method and a source' do
- let(:installment_traits) do
- {
- subscription_traits: [{
- payment_method: payment_method,
- payment_source: payment_source,
- user: subscription_user,
- line_item_traits: [{ spree_line_item: root_order.line_items.first }]
- }]
- }
- end
- let(:payment_source) { create :credit_card, payment_method: payment_method, user: subscription_user }
- let(:payment_method) { create :credit_card_payment_method }
-
- it_behaves_like 'a completed checkout'
-
- it 'pays with the payment method' do
- expect(subject.payments.valid.first.payment_method).to eq payment_method
- end
-
- it 'pays with the payment source' do
- expect(subject.payments.valid.first.source).to eq payment_source
- end
- end
-
- context 'there are multiple associated subscritpion line items' do
- it_behaves_like 'a completed checkout' do
- let(:quantity) { subscription_line_items.length }
- end
-
- let(:installments) { create_list(:installment, 1, installment_traits) }
- let(:subscription_line_items) { create_list(:subscription_line_item, 2, quantity: 1) }
-
- let(:installment_traits) do
- {
- subscription_traits: [{
- user: subscription_user,
- line_items: subscription_line_items
- }]
- }
- end
- end
- end
-
- describe '#order' do
- subject { checkout.order }
-
- let(:user) { installments.first.subscription.user }
-
- it { is_expected.to be_a Spree::Order }
-
- it 'has the correct attributes' do
- expect(subject).to have_attributes(
- user: user,
- email: user.email,
- store: installments.first.subscription.store
- )
- end
-
- it 'is the same instance any time its called' do
- order = checkout.order
- expect(subject).to equal order
- end
- end
-end
diff --git a/spec/services/solidus_subscriptions/dispatcher_spec.rb b/spec/services/solidus_subscriptions/dispatcher_spec.rb
deleted file mode 100644
index 49c3f4b..0000000
--- a/spec/services/solidus_subscriptions/dispatcher_spec.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-RSpec.describe SolidusSubscriptions::Dispatcher do
- describe '#dispatch' do
- it 'raises a NotImplementedError' do
- dispatcher = described_class.new([])
-
- expect {
- dispatcher.dispatch
- }.to raise_error(NotImplementedError)
- end
- end
-end
diff --git a/spec/services/solidus_subscriptions/failure_dispatcher_spec.rb b/spec/services/solidus_subscriptions/failure_dispatcher_spec.rb
deleted file mode 100644
index a7c18ea..0000000
--- a/spec/services/solidus_subscriptions/failure_dispatcher_spec.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-RSpec.describe SolidusSubscriptions::FailureDispatcher do
- describe '#dispatch' do
- it 'marks all the installments as failed' do
- installments = Array.new(2) { instance_spy(SolidusSubscriptions::Installment) }
- order = create(:order_with_line_items)
-
- dispatcher = described_class.new(installments, order)
- dispatcher.dispatch
-
- expect(installments).to all(have_received(:failed!).with(order).once)
- end
-
- it 'cancels the order' do
- if Spree.solidus_gem_version > Gem::Version.new('2.10')
- skip 'Orders in `cart` state cannot be canceled starting from Solidus 2.11.'
- end
-
- installments = Array.new(2) { instance_spy(SolidusSubscriptions::Installment) }
- order = create(:order_with_line_items)
-
- dispatcher = described_class.new(installments, order)
- dispatcher.dispatch
-
- expect(order.state).to eq('canceled')
- end
- end
-end
diff --git a/spec/services/solidus_subscriptions/line_item_builder_spec.rb b/spec/services/solidus_subscriptions/line_item_builder_spec.rb
deleted file mode 100644
index d1e041c..0000000
--- a/spec/services/solidus_subscriptions/line_item_builder_spec.rb
+++ /dev/null
@@ -1,33 +0,0 @@
-require 'spec_helper'
-
-RSpec.describe SolidusSubscriptions::LineItemBuilder do
- let(:builder) { described_class.new subscription_line_items }
- let(:variant) { create(:variant, subscribable: true) }
- let(:subscription_line_item) { subscription_line_items.first }
- let(:subscription_line_items) do
- build_stubbed_list(:subscription_line_item, 1, subscribable_id: variant.id)
- end
-
- describe '#spree_line_items' do
- subject { builder.spree_line_items }
-
- let(:expected_attributes) do
- {
- variant_id: subscription_line_item.subscribable_id,
- quantity: subscription_line_item.quantity
- }
- end
-
- it { is_expected.to be_a Array }
-
- it 'contains a line item with the correct attributes' do
- expect(subject.first).to have_attributes expected_attributes
- end
-
- context 'the variant is out of stock' do
- before { create :stock_location, backorderable_default: false }
-
- it { is_expected.to be_empty }
- end
- end
-end
diff --git a/spec/services/solidus_subscriptions/order_builder_spec.rb b/spec/services/solidus_subscriptions/order_builder_spec.rb
deleted file mode 100644
index 3463bd1..0000000
--- a/spec/services/solidus_subscriptions/order_builder_spec.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-require 'spec_helper'
-
-RSpec.describe SolidusSubscriptions::OrderBuilder do
- let(:builder) { described_class.new order }
-
- describe '#add_line_items' do
- subject { builder.add_line_items([line_item]) }
-
- let(:variant) { create :variant, subscribable: true }
- let(:order) do
- create :order, line_items_attributes: line_items_attributes
- end
-
- let(:line_item) { create(:line_item, quantity: 4, variant: variant) }
-
- context 'the line item doesnt already exist on the order' do
- let(:line_items_attributes) { [] }
-
- it 'adds a new line item to the order' do
- expect { subject }.
- to change { order.line_items.count }.
- from(0).to(1)
- end
-
- it 'has a line item with the correct values' do
- subject
- line_item = order.line_items.last
-
- expect(line_item).to have_attributes(
- variant_id: variant.id,
- quantity: line_item.quantity
- )
- end
- end
-
- context 'the line item already exists on the order' do
- let(:line_items_attributes) do
- [{
- variant: variant,
- quantity: 3
- }]
- end
-
- it 'increases the correct line item by the correct amount' do
- existing_line_item = order.line_items.first
-
- expect { subject }.
- to change { existing_line_item.reload.quantity }.
- by(line_item.quantity)
- end
- end
- end
-end
diff --git a/spec/services/solidus_subscriptions/out_of_stock_dispatcher_spec.rb b/spec/services/solidus_subscriptions/out_of_stock_dispatcher_spec.rb
deleted file mode 100644
index 6f3825c..0000000
--- a/spec/services/solidus_subscriptions/out_of_stock_dispatcher_spec.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-RSpec.describe SolidusSubscriptions::OutOfStockDispatcher do
- describe '#dispatch' do
- it 'marks all the installments as out of stock' do
- installments = Array.new(2) { instance_spy(SolidusSubscriptions::Installment) }
-
- dispatcher = described_class.new(installments)
- dispatcher.dispatch
-
- expect(installments).to all(have_received(:out_of_stock).once)
- end
- end
-end
diff --git a/spec/services/solidus_subscriptions/payment_failed_dispatcher_spec.rb b/spec/services/solidus_subscriptions/payment_failed_dispatcher_spec.rb
deleted file mode 100644
index a6a8a0c..0000000
--- a/spec/services/solidus_subscriptions/payment_failed_dispatcher_spec.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-RSpec.describe SolidusSubscriptions::PaymentFailedDispatcher do
- describe '#dispatch' do
- it 'marks all the installments as payment_failed' do
- installments = Array.new(2) { instance_spy(SolidusSubscriptions::Installment) }
- order = create(:order_with_line_items)
-
- dispatcher = described_class.new(installments, order)
- dispatcher.dispatch
-
- expect(installments).to all(have_received(:payment_failed!).with(order).once)
- end
-
- it 'cancels the order' do
- if Spree.solidus_gem_version > Gem::Version.new('2.10')
- skip 'Orders in `cart` state cannot be canceled starting from Solidus 2.11.'
- end
-
- installments = Array.new(2) { instance_spy(SolidusSubscriptions::Installment) }
- order = create(:order_with_line_items)
-
- dispatcher = described_class.new(installments, order)
- dispatcher.dispatch
-
- expect(order.state).to eq('canceled')
- end
-
- it 'fires an installments_failed_payment event' do
- stub_const('Spree::Event', class_spy(Spree::Event))
- installments = Array.new(2) { instance_spy(SolidusSubscriptions::Installment) }
- order = create(:order_with_line_items)
-
- dispatcher = described_class.new(installments, order)
- dispatcher.dispatch
-
- expect(Spree::Event).to have_received(:fire).with(
- 'solidus_subscriptions.installments_failed_payment',
- installments: installments,
- order: order,
- )
- end
- end
-end
diff --git a/spec/services/solidus_subscriptions/success_dispatcher_spec.rb b/spec/services/solidus_subscriptions/success_dispatcher_spec.rb
deleted file mode 100644
index ce41638..0000000
--- a/spec/services/solidus_subscriptions/success_dispatcher_spec.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-RSpec.describe SolidusSubscriptions::SuccessDispatcher do
- describe '#dispatch' do
- it 'marks all the installments as success' do
- installments = Array.new(2) { instance_spy(SolidusSubscriptions::Installment) }
- order = create(:order_with_line_items)
-
- dispatcher = described_class.new(installments, order)
- dispatcher.dispatch
-
- expect(installments).to all(have_received(:success!).with(order).once)
- end
-
- it 'fires an installments_succeeded event' do
- stub_const('Spree::Event', class_spy(Spree::Event))
- installments = Array.new(2) { instance_spy(SolidusSubscriptions::Installment) }
- order = create(:order_with_line_items)
-
- dispatcher = described_class.new(installments, order)
- dispatcher.dispatch
-
- expect(Spree::Event).to have_received(:fire).with(
- 'solidus_subscriptions.installments_succeeded',
- installments: installments,
- order: order,
- )
- end
- end
-end
diff --git a/spec/subscribers/solidus_subscriptions/churn_buster_subscriber_spec.rb b/spec/subscribers/solidus_subscriptions/churn_buster_subscriber_spec.rb
index 572913b..11ada2c 100644
--- a/spec/subscribers/solidus_subscriptions/churn_buster_subscriber_spec.rb
+++ b/spec/subscribers/solidus_subscriptions/churn_buster_subscriber_spec.rb
@@ -29,10 +29,10 @@ RSpec.describe SolidusSubscriptions::ChurnBusterSubscriber do
allow(SolidusSubscriptions).to receive(:churn_buster).and_return(churn_buster)
order = build_stubbed(:order)
- installments = build_list(:installment, 2)
+ installment = build_stubbed(:installment)
Spree::Event.fire(
- 'solidus_subscriptions.installments_succeeded',
- installments: installments,
+ 'solidus_subscriptions.installment_succeeded',
+ installment: installment,
order: order,
)
@@ -46,10 +46,10 @@ RSpec.describe SolidusSubscriptions::ChurnBusterSubscriber do
allow(SolidusSubscriptions).to receive(:churn_buster).and_return(churn_buster)
order = build_stubbed(:order)
- installments = build_list(:installment, 2)
+ installment = build_stubbed(:installment)
Spree::Event.fire(
- 'solidus_subscriptions.installments_failed_payment',
- installments: installments,
+ 'solidus_subscriptions.installment_failed_payment',
+ installment: installment,
order: order,
)