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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +57 -9
- data/.github/dependabot.yml +7 -0
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +201 -169
- data/Gemfile +14 -1
- data/README.md +17 -7
- data/app/controllers/solidus_subscriptions/api/v1/subscriptions_controller.rb +24 -0
- data/app/controllers/spree/admin/subscriptions_controller.rb +32 -4
- data/app/decorators/models/solidus_subscriptions/spree/wallet_payment_source/report_default_change_to_subscriptions.rb +2 -2
- data/app/jobs/solidus_subscriptions/create_subscription_job.rb +11 -0
- data/app/jobs/solidus_subscriptions/process_installment_job.rb +1 -1
- data/app/models/solidus_subscriptions/subscription.rb +75 -31
- data/app/subscribers/solidus_subscriptions/churn_buster_subscriber.rb +1 -0
- data/app/subscribers/solidus_subscriptions/event_storage_subscriber.rb +1 -0
- data/app/subscribers/solidus_subscriptions/order_subscriber.rb +16 -0
- data/app/views/spree/admin/shared/_subscription_actions.html.erb +27 -8
- data/app/views/spree/admin/shared/_subscription_sidebar.html.erb +2 -0
- data/app/views/spree/admin/subscriptions/_state_pill.html.erb +3 -2
- data/app/views/spree/admin/subscriptions/index.html.erb +50 -13
- data/bin/sandbox +1 -6
- data/config/locales/en.yml +16 -0
- data/config/routes.rb +9 -3
- data/db/migrate/20210905145955_add_paused_to_subscriptions.rb +5 -0
- data/lib/decorators/api/controllers/solidus_subscriptions/spree/api/line_items_controller/create_subscription_line_items.rb +14 -0
- data/lib/generators/solidus_subscriptions/install/install_generator.rb +16 -0
- data/lib/generators/solidus_subscriptions/install/templates/app/controllers/concerns/create_subscription.rb +17 -0
- data/lib/generators/solidus_subscriptions/install/templates/app/views/cart_line_items/_subscription_fields.html.erb +30 -0
- data/lib/generators/solidus_subscriptions/install/templates/initializer.rb +3 -1
- data/lib/solidus_subscriptions/configuration.rb +29 -6
- data/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher.rb +2 -2
- data/lib/solidus_subscriptions/dispatcher/success_dispatcher.rb +2 -2
- data/lib/solidus_subscriptions/engine.rb +28 -0
- data/lib/solidus_subscriptions/permission_sets/default_customer.rb +1 -1
- data/lib/solidus_subscriptions/processing_error_handlers/rails_logger.rb +25 -0
- data/lib/solidus_subscriptions/subscription_generator.rb +6 -0
- data/lib/solidus_subscriptions/version.rb +1 -1
- data/solidus_subscriptions.gemspec +6 -6
- data/spec/controllers/spree/api/line_items_controller_spec.rb +63 -28
- data/spec/controllers/spree/api/users_controller_spec.rb +3 -0
- data/spec/decorators/controllers/solidus_subscriptions/spree/orders_controller/create_subscription_line_items_spec.rb +4 -4
- data/spec/decorators/models/solidus_subscriptions/spree/variant/auto_delete_from_subscriptions_spec.rb +2 -2
- data/spec/features/admin/subscriptions_spec.rb +13 -3
- data/spec/jobs/solidus_subscriptions/create_subscription_job_spec.rb +20 -0
- data/spec/jobs/solidus_subscriptions/process_installment_job_spec.rb +17 -0
- data/spec/lib/solidus_subscriptions/dispatcher/payment_failed_dispatcher_spec.rb +3 -3
- data/spec/lib/solidus_subscriptions/dispatcher/success_dispatcher_spec.rb +3 -3
- data/spec/lib/solidus_subscriptions/subscription_generator_spec.rb +1 -1
- data/spec/models/solidus_subscriptions/installment_spec.rb +1 -1
- data/spec/models/solidus_subscriptions/subscription_spec.rb +893 -16
- data/spec/models/spree/wallet_payment_source_spec.rb +3 -3
- data/spec/requests/api/v1/subscriptions_spec.rb +229 -0
- data/spec/subscribers/solidus_subscriptions/churn_buster_subscriber_spec.rb +8 -8
- data/spec/subscribers/solidus_subscriptions/order_subscriber_spec.rb +13 -0
- metadata +24 -17
- data/app/decorators/models/solidus_subscriptions/spree/order/finalize_creates_subscriptions.rb +0 -25
- data/config/initializers/subscribers.rb +0 -9
- data/spec/decorators/models/solidus_subscriptions/spree/order/finalize_creates_subscriptions_spec.rb +0 -32
- /data/{app → lib}/views/spree/frontend/products/_subscription_line_item_fields.html.erb +0 -0
@@ -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
|
-
#
|
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
|
-
:
|
7
|
-
:churn_buster_api_key,
|
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
|
-
:
|
12
|
-
:
|
13
|
-
:minimum_cancellation_notice,
|
14
|
-
:
|
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
|
-
::
|
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
|
-
::
|
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
|
#
|
@@ -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
|
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
|
18
|
-
spec.metadata['changelog_uri'] = 'https://github.com/solidusio
|
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('
|
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.
|
36
|
-
spec.add_dependency 'solidus_support', '~> 0.
|
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
|
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
|
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(:
|
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
|
-
|
76
|
-
{
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
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
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
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(
|
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
|
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
|
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
|
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
|
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
|
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.
|
56
|
+
select variant.pretty_name, from: 'Subscribable'
|
57
57
|
fill_in 'Quantity', with: 1
|
58
58
|
|
59
|
-
expect
|
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('
|
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(
|
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('
|
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(
|
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.
|
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
|
49
|
+
to change(SolidusSubscriptions::InstallmentDetail, :count).
|
50
50
|
by(1)
|
51
51
|
end
|
52
52
|
|