solidus_subscriptions 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +57 -9
  3. data/.github/dependabot.yml +7 -0
  4. data/.rubocop.yml +3 -0
  5. data/CHANGELOG.md +201 -169
  6. data/Gemfile +14 -1
  7. data/README.md +17 -7
  8. data/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb +24 -0
  9. data/app/controllers/spree/admin/subscriptions_controller.rb +32 -4
  10. data/app/decorators/models/solidus_subscriptions/spree/wallet_payment_source/report_default_change_to_subscriptions.rb +2 -2
  11. data/app/jobs/solidus_subscriptions/create_subscription_job.rb +11 -0
  12. data/app/jobs/solidus_subscriptions/process_installment_job.rb +1 -1
  13. data/app/models/solidus_subscriptions/subscription.rb +75 -31
  14. data/app/subscribers/solidus_subscriptions/churn_buster_subscriber.rb +1 -0
  15. data/app/subscribers/solidus_subscriptions/event_storage_subscriber.rb +1 -0
  16. data/app/subscribers/solidus_subscriptions/order_subscriber.rb +16 -0
  17. data/app/views/spree/admin/shared/_subscription_actions.html.erb +27 -8
  18. data/app/views/spree/admin/shared/_subscription_sidebar.html.erb +2 -0
  19. data/app/views/spree/admin/subscriptions/_state_pill.html.erb +3 -2
  20. data/app/views/spree/admin/subscriptions/index.html.erb +50 -13
  21. data/bin/sandbox +1 -6
  22. data/config/locales/en.yml +16 -0
  23. data/config/routes.rb +9 -3
  24. data/db/migrate/20210905145955_add_paused_to_subscriptions.rb +5 -0
  25. data/lib/decorators/api/controllers/solidus_subscriptions/spree/api/line_items_controller/create_subscription_line_items.rb +14 -0
  26. data/lib/generators/solidus_subscriptions/install/install_generator.rb +16 -0
  27. data/lib/generators/solidus_subscriptions/install/templates/app/controllers/concerns/create_subscription.rb +17 -0
  28. data/lib/generators/solidus_subscriptions/install/templates/app/views/cart_line_items/_subscription_fields.html.erb +30 -0
  29. data/lib/generators/solidus_subscriptions/install/templates/initializer.rb +3 -1
  30. data/lib/solidus_subscriptions/configuration.rb +29 -6
  31. data/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher.rb +2 -2
  32. data/lib/solidus_subscriptions/dispatcher/success_dispatcher.rb +2 -2
  33. data/lib/solidus_subscriptions/engine.rb +28 -0
  34. data/lib/solidus_subscriptions/permission_sets/default_customer.rb +1 -1
  35. data/lib/solidus_subscriptions/processing_error_handlers/rails_logger.rb +25 -0
  36. data/lib/solidus_subscriptions/subscription_generator.rb +6 -0
  37. data/lib/solidus_subscriptions/version.rb +1 -1
  38. data/solidus_subscriptions.gemspec +6 -6
  39. data/spec/controllers/spree/api/line_items_controller_spec.rb +63 -28
  40. data/spec/controllers/spree/api/users_controller_spec.rb +3 -0
  41. data/spec/decorators/controllers/solidus_subscriptions/spree/orders_controller/create_subscription_line_items_spec.rb +4 -4
  42. data/spec/decorators/models/solidus_subscriptions/spree/variant/auto_delete_from_subscriptions_spec.rb +2 -2
  43. data/spec/features/admin/subscriptions_spec.rb +13 -3
  44. data/spec/jobs/solidus_subscriptions/create_subscription_job_spec.rb +20 -0
  45. data/spec/jobs/solidus_subscriptions/process_installment_job_spec.rb +17 -0
  46. data/spec/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher_spec.rb +3 -3
  47. data/spec/lib/solidus_subscriptions/dispatcher/success_dispatcher_spec.rb +3 -3
  48. data/spec/lib/solidus_subscriptions/subscription_generator_spec.rb +1 -1
  49. data/spec/models/solidus_subscriptions/installment_spec.rb +1 -1
  50. data/spec/models/solidus_subscriptions/subscription_spec.rb +893 -16
  51. data/spec/models/spree/wallet_payment_source_spec.rb +3 -3
  52. data/spec/requests/api/v1/subscriptions_spec.rb +229 -0
  53. data/spec/subscribers/solidus_subscriptions/churn_buster_subscriber_spec.rb +8 -8
  54. data/spec/subscribers/solidus_subscriptions/order_subscriber_spec.rb +13 -0
  55. metadata +24 -17
  56. data/app/decorators/models/solidus_subscriptions/spree/order/finalize_creates_subscriptions.rb +0 -25
  57. data/config/initializers/subscribers.rb +0 -9
  58. data/spec/decorators/models/solidus_subscriptions/spree/order/finalize_creates_subscriptions_spec.rb +0 -32
  59. /data/{app → lib}/views/spree/frontend/products/_subscription_line_item_fields.html.erb +0 -0
@@ -0,0 +1,5 @@
1
+ class AddPausedToSubscriptions < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_column :solidus_subscriptions_subscriptions, :paused, :boolean, default: false
4
+ end
5
+ end
@@ -27,6 +27,20 @@ module SolidusSubscriptions
27
27
  def handle_subscription_line_items
28
28
  create_subscription_line_item(@line_item)
29
29
  end
30
+
31
+ def line_items_attributes
32
+ super.tap do |attrs|
33
+ if params[:subscription_line_items_attributes]
34
+ attrs[:line_items_attributes].merge!(
35
+ subscription_line_items_attributes: subscription_line_item_params
36
+ )
37
+ end
38
+ end
39
+ end
40
+
41
+ def subscription_line_item_params
42
+ params[:subscription_line_items_attributes].permit(SolidusSubscriptions::PermittedAttributes.subscription_line_item_attributes)
43
+ end
30
44
  end
31
45
  end
32
46
  end
@@ -6,6 +6,7 @@ module SolidusSubscriptions
6
6
  source_root File.expand_path('templates', __dir__)
7
7
 
8
8
  class_option :auto_run_migrations, type: :boolean, default: false
9
+ class_option :frontend, type: :string, default: 'classic'
9
10
 
10
11
  def copy_initializer
11
12
  template 'initializer.rb', 'config/initializers/solidus_subscriptions.rb'
@@ -15,6 +16,21 @@ module SolidusSubscriptions
15
16
  append_file 'vendor/assets/javascripts/spree/backend/all.js', "//= require spree/backend/solidus_subscriptions\n"
16
17
  end
17
18
 
19
+ def copy_starter_frontend_files
20
+ return if options[:frontend] != 'starter'
21
+
22
+ copy_file 'app/views/cart_line_items/_subscription_fields.html.erb'
23
+ prepend_to_file 'app/views/cart_line_items/_product_submit.html.erb', "<%= render 'cart_line_items/subscription_fields' %>\n"
24
+
25
+ copy_file 'app/controllers/concerns/create_subscription.rb'
26
+ insert_into_file 'app/controllers/cart_line_items_controller.rb', after: "class CartLineItemsController < StoreController\n" do
27
+ <<~RUBY.indent(2)
28
+ include CreateSubscription
29
+
30
+ RUBY
31
+ end
32
+ end
33
+
18
34
  def add_migrations
19
35
  run 'bin/rails railties:install:migrations FROM=solidus_subscriptions'
20
36
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CreateSubscription
4
+ extend ActiveSupport::Concern
5
+ include SolidusSubscriptions::SubscriptionLineItemBuilder
6
+
7
+ included do
8
+ after_action :handle_subscription_line_items, only: :create, if: ->{ params[:subscription_line_item] }
9
+ end
10
+
11
+ private
12
+
13
+ def handle_subscription_line_items
14
+ line_item = @current_order.line_items.find_by(variant_id: params[:variant_id])
15
+ create_subscription_line_item(line_item)
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ <%= content_tag :h3, t('.subscription_fields') %>
2
+ <%= fields_for :'subscription_line_item', SolidusSubscriptions::LineItem.new do |ff| %>
3
+ <div>
4
+ <%= ff.label :quantity, t('.quantity') %>
5
+ <%= ff.number_field :quantity %>
6
+ <%= ff.label :quantity, t('.quantity_suffix') %>
7
+ </div>
8
+
9
+ <div>
10
+ <%= ff.label :interval_length, t('.interval_length') %>
11
+ <%= ff.number_field :interval_length %>
12
+
13
+ <%= ff.collection_radio_buttons :interval_units, SolidusSubscriptions::LineItem.interval_units.to_a, :first, :first %>
14
+ </div>
15
+
16
+ <%= ff.hidden_field :subscribable_id %>
17
+ <% end %>
18
+
19
+ <script>
20
+ document.addEventListener("DOMContentLoaded", function(e) {
21
+ var cartForm = document.querySelector('.product-page__info form');
22
+ cartForm.addEventListener('submit', function(e) {
23
+ var quantityInput = e.target.querySelector('[name*="quantity"]');
24
+ var subscriptionQuantityInput = e.target.querySelector('[name*="subscribable_id"]');
25
+
26
+ subscriptionQuantityInput.value = quantityInput.value;
27
+ return true;
28
+ });
29
+ });
30
+ </script>
@@ -31,7 +31,9 @@ SolidusSubscriptions.configure do |config|
31
31
  # on an error tracking system.
32
32
  # Though not recommended due to the retry mechanisms built into this gem, the error can be
33
33
  # re-raised if the default retry behaviour is required in ActiveJob.
34
- # config.processing_error_handler = nil
34
+ #
35
+ # By default, it only logs the error message using Rails.logger.error.
36
+ # config.processing_error_handler = SolidusSubscriptions::ProcessingErrorHandlers::RailsLogger
35
37
 
36
38
  # ========================================= Dispatchers ==========================================
37
39
  #
@@ -3,17 +3,35 @@
3
3
  module SolidusSubscriptions
4
4
  class Configuration
5
5
  attr_accessor(
6
- :maximum_total_skips, :maximum_reprocessing_time, :churn_buster_account_id,
7
- :churn_buster_api_key, :clear_past_installments, :processing_error_handler
6
+ :churn_buster_account_id,
7
+ :churn_buster_api_key,
8
+ :clear_past_installments,
9
+ :maximum_reprocessing_time,
10
+ :maximum_total_skips,
8
11
  )
9
12
 
10
13
  attr_writer(
11
- :success_dispatcher_class, :failure_dispatcher_class, :payment_failed_dispatcher_class,
12
- :out_of_stock_dispatcher, :maximum_successive_skips, :reprocessing_interval,
13
- :minimum_cancellation_notice, :processing_queue, :subscription_line_item_attributes,
14
- :subscription_attributes, :subscribable_class, :order_creator_class
14
+ :failure_dispatcher_class,
15
+ :maximum_successive_skips,
16
+ :minimum_cancellation_notice,
17
+ :order_creator_class,
18
+ :out_of_stock_dispatcher,
19
+ :payment_failed_dispatcher_class,
20
+ :processing_error_handler,
21
+ :processing_queue,
22
+ :reprocessing_interval,
23
+ :subscribable_class,
24
+ :subscription_attributes,
25
+ :subscription_generator_class,
26
+ :subscription_line_item_attributes,
27
+ :success_dispatcher_class,
15
28
  )
16
29
 
30
+ def subscription_generator_class
31
+ @subscription_generator_class ||= 'SolidusSubscriptions::SubscriptionGenerator'
32
+ @subscription_generator_class.constantize
33
+ end
34
+
17
35
  def success_dispatcher_class
18
36
  @success_dispatcher_class ||= 'SolidusSubscriptions::Dispatcher::SuccessDispatcher'
19
37
  @success_dispatcher_class.constantize
@@ -34,6 +52,11 @@ module SolidusSubscriptions
34
52
  @out_of_stock_dispatcher_class.constantize
35
53
  end
36
54
 
55
+ def processing_error_handler
56
+ @processing_error_handler ||= 'SolidusSubscriptions::ProcessingErrorHandlers::RailsLogger'
57
+ @processing_error_handler.constantize
58
+ end
59
+
37
60
  def maximum_successive_skips
38
61
  @maximum_successive_skips ||= 1
39
62
  end
@@ -8,8 +8,8 @@ module SolidusSubscriptions
8
8
  order.cancel
9
9
  installment.payment_failed!(order)
10
10
 
11
- ::Spree::Event.fire(
12
- 'solidus_subscriptions.installment_failed_payment',
11
+ ::SolidusSupport::LegacyEventCompat::Bus.publish(
12
+ :'solidus_subscriptions.installment_failed_payment',
13
13
  installment: installment,
14
14
  order: order,
15
15
  )
@@ -6,8 +6,8 @@ module SolidusSubscriptions
6
6
  def dispatch
7
7
  installment.success!(order)
8
8
 
9
- ::Spree::Event.fire(
10
- 'solidus_subscriptions.installment_succeeded',
9
+ ::SolidusSupport::LegacyEventCompat::Bus.publish(
10
+ :'solidus_subscriptions.installment_succeeded',
11
11
  installment: installment,
12
12
  order: order,
13
13
  )
@@ -6,6 +6,7 @@ require 'solidus_subscriptions'
6
6
  require 'solidus_subscriptions/permitted_attributes'
7
7
  require 'solidus_subscriptions/configuration'
8
8
  require 'solidus_subscriptions/processor'
9
+ require 'solidus_subscriptions/processing_error_handlers/rails_logger'
9
10
 
10
11
  module SolidusSubscriptions
11
12
  class Engine < Rails::Engine
@@ -48,6 +49,33 @@ module SolidusSubscriptions
48
49
  )
49
50
  end
50
51
  end
52
+
53
+ initializer 'solidus_subscriptions.pub_sub' do |app|
54
+ unless SolidusSupport::LegacyEventCompat.using_legacy?
55
+ app.reloader.to_prepare do
56
+ %i[
57
+ subscription_created
58
+ subscription_activated
59
+ subscription_canceled
60
+ subscription_ended
61
+ subscription_skipped
62
+ subscription_resumed
63
+ subscription_paused
64
+ subscription_frequency_changed
65
+ subscription_shipping_address_changed
66
+ subscription_billing_address_changed
67
+ installment_succeeded
68
+ installment_failed_payment
69
+ subscription_payment_method_changed
70
+ ].each do |event_name|
71
+ ::Spree::Bus.register(:"solidus_subscriptions.#{event_name}")
72
+ end
73
+ SolidusSubscriptions::ChurnBusterSubscriber.omnes_subscriber.subscribe_to(::Spree::Bus)
74
+ SolidusSubscriptions::EventStorageSubscriber.omnes_subscriber.subscribe_to(::Spree::Bus)
75
+ SolidusSubscriptions::OrderSubscriber.omnes_subscriber.subscribe_to(::Spree::Bus)
76
+ end
77
+ end
78
+ end
51
79
  end
52
80
 
53
81
  def self.table_name_prefix
@@ -4,7 +4,7 @@ module SolidusSubscriptions
4
4
  module PermissionSets
5
5
  class DefaultCustomer < ::Spree::PermissionSets::Base
6
6
  def activate!
7
- can [:show, :display, :update, :skip, :cancel], Subscription, ['user_id = ?', user.id] do |subscription, guest_token|
7
+ can [:show, :display, :update, :skip, :cancel, :pause, :resume], Subscription, ['user_id = ?', user.id] do |subscription, guest_token|
8
8
  (subscription.guest_token.present? && subscription.guest_token == guest_token) ||
9
9
  (subscription.user && subscription.user == user)
10
10
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusSubscriptions
4
+ module ProcessingErrorHandlers
5
+ class RailsLogger
6
+ def self.call(exception, installment = nil)
7
+ new(exception, installment).call
8
+ end
9
+
10
+ def initialize(exception, installment = nil)
11
+ @exception = exception
12
+ @installment = installment
13
+ end
14
+
15
+ def call
16
+ Rails.logger.error("Error processing installment with ID=#{installment.id}:") if installment
17
+ Rails.logger.error(exception.message)
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :exception, :installment
23
+ end
24
+ end
25
+ end
@@ -8,6 +8,12 @@ module SolidusSubscriptions
8
8
 
9
9
  SubscriptionConfiguration = Struct.new(:interval_length, :interval_units, :end_date)
10
10
 
11
+ def call(order)
12
+ group(order.subscription_line_items).each { |line_items| activate(line_items) }
13
+
14
+ order.reload
15
+ end
16
+
11
17
  # Create and persist a subscription for a collection of subscription
12
18
  # line items
13
19
  #
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SolidusSubscriptions
4
- VERSION = '1.0.0'
4
+ VERSION = '1.0.1'
5
5
  end
@@ -10,14 +10,14 @@ Gem::Specification.new do |spec|
10
10
 
11
11
  spec.summary = 'Add subscription support to Solidus'
12
12
  spec.description = 'Add subscription support to Solidus'
13
- spec.homepage = 'https://github.com/solidusio-contrib/solidus_subscriptions'
13
+ spec.homepage = 'https://github.com/solidusio/solidus_subscriptions'
14
14
  spec.license = 'BSD-3-Clause'
15
15
 
16
16
  spec.metadata['homepage_uri'] = spec.homepage
17
- spec.metadata['source_code_uri'] = 'https://github.com/solidusio-contrib/solidus_subscriptions'
18
- spec.metadata['changelog_uri'] = 'https://github.com/solidusio-contrib/solidus_subscriptions/blob/master/CHANGELOG.md'
17
+ spec.metadata['source_code_uri'] = 'https://github.com/solidusio/solidus_subscriptions'
18
+ spec.metadata['changelog_uri'] = 'https://github.com/solidusio/solidus_subscriptions/blob/master/CHANGELOG.md'
19
19
 
20
- spec.required_ruby_version = Gem::Requirement.new('~> 2.5')
20
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.5')
21
21
 
22
22
  # Specify which files should be added to the gem when it is released.
23
23
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -32,8 +32,8 @@ Gem::Specification.new do |spec|
32
32
  spec.add_dependency 'deface'
33
33
  spec.add_dependency 'httparty', '~> 0.18'
34
34
  spec.add_dependency 'i18n'
35
- spec.add_dependency 'solidus_core', '>= 2.0.0', '< 4'
36
- spec.add_dependency 'solidus_support', '~> 0.7'
35
+ spec.add_dependency 'solidus_core', '>= 2.11', '< 4'
36
+ spec.add_dependency 'solidus_support', '~> 0.9'
37
37
  spec.add_dependency 'state_machines'
38
38
 
39
39
  spec.add_development_dependency 'rspec-activemodel-mocks'
@@ -31,7 +31,7 @@ RSpec.describe Spree::Api::LineItemsController, type: :controller do
31
31
 
32
32
  it 'creates a line item' do
33
33
  expect { post_create }.
34
- to change { Spree::LineItem.count }.
34
+ to change(Spree::LineItem, :count).
35
35
  from(0).to(1)
36
36
  end
37
37
  end
@@ -54,7 +54,7 @@ RSpec.describe Spree::Api::LineItemsController, type: :controller do
54
54
 
55
55
  it 'creates a new subscription line item' do
56
56
  expect { post_create }.
57
- to change { SolidusSubscriptions::LineItem.count }.
57
+ to change(SolidusSubscriptions::LineItem, :count).
58
58
  from(0).to(1)
59
59
  end
60
60
  end
@@ -65,39 +65,74 @@ RSpec.describe Spree::Api::LineItemsController, type: :controller do
65
65
  end
66
66
 
67
67
  describe 'patch :update' do
68
- subject(:patch_create) { patch :create, params: params }
68
+ subject(:patch_update) { patch :update, params: params }
69
69
 
70
70
  let(:params) { line_item_params }
71
- let!(:variant) { create :variant }
72
- let!(:order) { create :order }
73
- let!(:line_item) { create :line_item, order: order, variant: variant }
74
71
 
75
- let(:line_item_params) do
76
- {
77
- id: line_item.id,
78
- order_id: order.number,
79
- order_token: order.guest_token,
80
- format: 'json',
81
- line_item: {
82
- quantity: 1,
83
- variant_id: variant.id
84
- },
85
- subscription_line_item: {
86
- quantity: 2,
87
- end_date: '1990/10/12',
88
- subscribable_id: variant.id,
89
- interval_length: 30,
90
- interval_units: "day"
72
+ context 'when adding subscription information' do
73
+ let(:variant) { create :variant }
74
+ let(:order) { create :order }
75
+ let(:line_item) { create :line_item, order: order, variant: variant }
76
+ let(:line_item_params) do
77
+ {
78
+ id: line_item.id,
79
+ order_id: order.number,
80
+ order_token: order.guest_token,
81
+ format: 'json',
82
+ line_item: {
83
+ quantity: 1,
84
+ variant_id: variant.id
85
+ },
86
+ subscription_line_item: {
87
+ quantity: 2,
88
+ end_date: '1990/10/12',
89
+ subscribable_id: variant.id,
90
+ interval_length: 30,
91
+ interval_units: "day"
92
+ }
91
93
  }
92
- }
94
+ end
95
+
96
+ it { is_expected.to be_successful }
97
+
98
+ it 'creates a new subscription line item' do
99
+ expect { patch_update }.
100
+ to change(SolidusSubscriptions::LineItem, :count).
101
+ from(0).to(1)
102
+ end
93
103
  end
94
104
 
95
- it { is_expected.to be_successful }
105
+ context 'when updating subscription information' do
106
+ let!(:line_item) { create :subscription_line_item, interval_length: 30 }
107
+ let(:variant) { line_item.spree_line_item.variant }
108
+ let(:order) { line_item.spree_line_item.order }
109
+ let(:line_item_params) do
110
+ {
111
+ id: line_item.spree_line_item.id,
112
+ order_id: order.number,
113
+ order_token: order.guest_token,
114
+ format: 'json',
115
+ line_item: {
116
+ quantity: 1,
117
+ },
118
+ subscription_line_items_attributes: {
119
+ id: line_item.id,
120
+ interval_length: 15,
121
+ }
122
+ }
123
+ end
96
124
 
97
- it 'creates a new subscription line item' do
98
- expect { patch_create }.
99
- to change { SolidusSubscriptions::LineItem.count }.
100
- from(0).to(1)
125
+ it { is_expected.to be_successful }
126
+
127
+ it 'does not create a new subscription line item' do
128
+ expect { patch_update }.
129
+ not_to change(SolidusSubscriptions::LineItem, :count)
130
+ end
131
+
132
+ it 'updates a new subscription line item' do
133
+ expect { patch_update }.
134
+ to change { line_item.reload.interval_length }.from(30).to(15)
135
+ end
101
136
  end
102
137
  end
103
138
  end
@@ -39,6 +39,9 @@ RSpec.describe Spree::Api::UsersController, type: :controller do
39
39
  end
40
40
 
41
41
  it 'updates the subscription line items' do
42
+ allow(::Spree::Deprecation).to receive(:warn).with(a_string_matching(
43
+ 'Creating or updating subscriptions through Spree::User nested attributes is deprecated'
44
+ ))
42
45
  update_user
43
46
  line_item = subscription.line_items.reload.first
44
47
 
@@ -9,7 +9,7 @@ RSpec.describe SolidusSubscriptions::Spree::OrdersController::CreateSubscription
9
9
  let!(:user) { create :user }
10
10
 
11
11
  before do
12
- allow(controller).to receive_messages(try_spree_current_user: user)
12
+ allow(controller).to receive_messages(spree_current_user: user)
13
13
  create :store
14
14
  end
15
15
 
@@ -30,13 +30,13 @@ RSpec.describe SolidusSubscriptions::Spree::OrdersController::CreateSubscription
30
30
 
31
31
  it 'creates an order' do
32
32
  expect { populate }.
33
- to change { Spree::Order.count }.
33
+ to change(Spree::Order, :count).
34
34
  from(0).to(1)
35
35
  end
36
36
 
37
37
  it 'creates a line item' do
38
38
  expect { populate }.
39
- to change { Spree::LineItem.count }.
39
+ to change(Spree::LineItem, :count).
40
40
  from(0).to(1)
41
41
  end
42
42
  end
@@ -59,7 +59,7 @@ RSpec.describe SolidusSubscriptions::Spree::OrdersController::CreateSubscription
59
59
 
60
60
  it 'creates a new subscription line item' do
61
61
  expect { populate }.
62
- to change { SolidusSubscriptions::LineItem.count }.
62
+ to change(SolidusSubscriptions::LineItem, :count).
63
63
  from(0).to(1)
64
64
  end
65
65
 
@@ -10,7 +10,7 @@ RSpec.describe SolidusSubscriptions::Spree::Variant::AutoDeleteFromSubscriptions
10
10
  subscription = create(:subscription)
11
11
  create(:subscription_line_item, subscription: subscription, subscribable: subject)
12
12
 
13
- expect { subject.discard }.to change { SolidusSubscriptions::LineItem.count }.by(-1)
13
+ expect { subject.discard }.to change(SolidusSubscriptions::LineItem, :count).by(-1)
14
14
  end
15
15
  end
16
16
 
@@ -19,7 +19,7 @@ RSpec.describe SolidusSubscriptions::Spree::Variant::AutoDeleteFromSubscriptions
19
19
  subscription = create(:subscription)
20
20
  create(:subscription_line_item, subscription: subscription, subscribable: subject)
21
21
 
22
- expect { subject.destroy }.to change { SolidusSubscriptions::LineItem.count }.by(-1)
22
+ expect { subject.destroy }.to change(SolidusSubscriptions::LineItem, :count).by(-1)
23
23
  end
24
24
  end
25
25
  end
@@ -25,7 +25,7 @@ RSpec.describe 'Subscriptions admin' do
25
25
  expect(subscription.billing_address.zipcode).to eq('33167')
26
26
  end
27
27
 
28
- it 'Creates a subscription' do
28
+ it 'Creates a subscription' do # rubocop:disable RSpec/MultipleExpectations
29
29
  variant = create(:variant, subscribable: true)
30
30
  create(:user)
31
31
  create(:store)
@@ -53,10 +53,20 @@ RSpec.describe 'Subscriptions admin' do
53
53
  end
54
54
  end
55
55
 
56
- select variant.name, from: 'Subscribable'
56
+ select variant.pretty_name, from: 'Subscribable'
57
57
  fill_in 'Quantity', with: 1
58
58
 
59
- expect { click_on 'Create' }.to change { SolidusSubscriptions::Subscription.count }.by(1)
59
+ expect(SolidusSubscriptions::Subscription.count).to eq(0)
60
+
61
+ # The State field is controlled by JS, so we need to set it at the last moment
62
+ # available.
63
+ state_id = Spree::State.last.id.to_s
64
+ find('input#subscription_shipping_address_attributes_state_id', visible: :all).set(state_id)
65
+ find('input#subscription_billing_address_attributes_state_id', visible: :all).set(state_id)
66
+
67
+ click_on 'Create'
68
+
69
+ expect(SolidusSubscriptions::Subscription.count).to eq(1)
60
70
 
61
71
  expect(page).to have_text('Subscription has been successfully created!')
62
72
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe SolidusSubscriptions::CreateSubscriptionJob do
4
+ describe '#perform' do
5
+ it 'creates new subscriptions for an order' do
6
+ order = create(:order, :with_subscription_line_items)
7
+ subscription_line_item = order.subscription_line_items.last
8
+
9
+ described_class.perform_now(order)
10
+
11
+ expect(SolidusSubscriptions::Subscription.count).to eq(order.subscription_line_items.count)
12
+ subscription = SolidusSubscriptions::Subscription.last
13
+ expect(subscription).to have_attributes(
14
+ user_id: order.user_id,
15
+ actionable_date: Time.zone.today + subscription.interval,
16
+ line_items: [subscription_line_item]
17
+ )
18
+ end
19
+ end
20
+ end
@@ -12,7 +12,24 @@ RSpec.describe SolidusSubscriptions::ProcessInstallmentJob do
12
12
  end
13
13
 
14
14
  context 'when handling #perform errors' do
15
+ it 'by default logs exception data without raising exceptions' do # rubocop:disable RSpec/MultipleExpectations
16
+ installment = build_stubbed(:installment)
17
+ checkout = instance_double(SolidusSubscriptions::Checkout).tap do |c|
18
+ allow(c).to receive(:process).and_raise('test error')
19
+ end
20
+ allow(SolidusSubscriptions::Checkout).to receive(:new).and_return(checkout)
21
+ allow(Rails.logger).to receive(:error)
22
+
23
+ expect {
24
+ described_class.perform_now(installment)
25
+ }.not_to raise_error
26
+
27
+ expect(Rails.logger).to have_received(:error).with("Error processing installment with ID=#{installment.id}:").ordered
28
+ expect(Rails.logger).to have_received(:error).with("test error").ordered
29
+ end
30
+
15
31
  it 'swallows error when a proc is not configured' do
32
+ stub_config(processing_error_handler: nil )
16
33
  checkout = instance_double(SolidusSubscriptions::Checkout).tap do |c|
17
34
  allow(c).to receive(:process).and_raise('test error')
18
35
  end
@@ -27,15 +27,15 @@ RSpec.describe SolidusSubscriptions::Dispatcher::PaymentFailedDispatcher do
27
27
  end
28
28
 
29
29
  it 'fires an installments_failed_payment event' do
30
- stub_const('Spree::Event', class_spy(Spree::Event))
30
+ stub_const('SolidusSupport::LegacyEventCompat::Bus', class_spy(SolidusSupport::LegacyEventCompat::Bus))
31
31
  installment = instance_spy(SolidusSubscriptions::Installment)
32
32
  order = create(:order_with_line_items)
33
33
 
34
34
  dispatcher = described_class.new(installment, order)
35
35
  dispatcher.dispatch
36
36
 
37
- expect(Spree::Event).to have_received(:fire).with(
38
- 'solidus_subscriptions.installment_failed_payment',
37
+ expect(SolidusSupport::LegacyEventCompat::Bus).to have_received(:publish).with(
38
+ :'solidus_subscriptions.installment_failed_payment',
39
39
  installment: installment,
40
40
  order: order,
41
41
  )
@@ -13,15 +13,15 @@ RSpec.describe SolidusSubscriptions::Dispatcher::SuccessDispatcher do
13
13
  end
14
14
 
15
15
  it 'fires an installments_succeeded event' do
16
- stub_const('Spree::Event', class_spy(Spree::Event))
16
+ stub_const('SolidusSupport::LegacyEventCompat::Bus', class_spy(SolidusSupport::LegacyEventCompat::Bus))
17
17
  installment = instance_spy(SolidusSubscriptions::Installment)
18
18
  order = create(:order_with_line_items)
19
19
 
20
20
  dispatcher = described_class.new(installment, order)
21
21
  dispatcher.dispatch
22
22
 
23
- expect(Spree::Event).to have_received(:fire).with(
24
- 'solidus_subscriptions.installment_succeeded',
23
+ expect(SolidusSupport::LegacyEventCompat::Bus).to have_received(:publish).with(
24
+ :'solidus_subscriptions.installment_succeeded',
25
25
  installment: installment,
26
26
  order: order,
27
27
  )
@@ -75,7 +75,7 @@ RSpec.describe SolidusSubscriptions::SubscriptionGenerator do
75
75
  weekly_subscriptions,
76
76
  expiring_subscriptions,
77
77
  ]
78
- grouping_result = described_class.group(subscriptions.sum)
78
+ grouping_result = described_class.group(subscriptions.flatten)
79
79
 
80
80
  expect(grouping_result).to match_array(subscriptions)
81
81
  end
@@ -46,7 +46,7 @@ RSpec.describe SolidusSubscriptions::Installment, type: :model do
46
46
 
47
47
  it 'creates a new installment detail' do
48
48
  expect { success }.
49
- to change { SolidusSubscriptions::InstallmentDetail.count }.
49
+ to change(SolidusSubscriptions::InstallmentDetail, :count).
50
50
  by(1)
51
51
  end
52
52