solidus_subscriptions 1.0.0 → 1.0.1

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.
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