solidus_core 3.1.5 → 3.2.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/products_helper.rb +1 -1
  3. data/app/models/concerns/spree/active_storage_adapter/attachment.rb +26 -11
  4. data/app/models/concerns/spree/active_storage_adapter.rb +1 -1
  5. data/app/models/concerns/spree/user_address_book.rb +11 -1
  6. data/app/models/concerns/spree/user_methods.rb +20 -1
  7. data/app/models/spree/adjustment.rb +1 -0
  8. data/app/models/spree/carton.rb +1 -1
  9. data/app/models/spree/log_entry.rb +74 -1
  10. data/app/models/spree/option_value.rb +9 -0
  11. data/app/models/spree/order.rb +68 -29
  12. data/app/models/spree/order_contents.rb +2 -1
  13. data/app/models/spree/order_inventory.rb +1 -1
  14. data/app/models/spree/order_merger.rb +2 -2
  15. data/app/models/spree/order_shipping.rb +6 -9
  16. data/app/models/spree/order_taxation.rb +6 -4
  17. data/app/models/spree/order_updater.rb +4 -3
  18. data/app/models/spree/payment_method.rb +11 -0
  19. data/app/models/spree/product/scopes.rb +21 -3
  20. data/app/models/spree/product.rb +2 -1
  21. data/app/models/spree/promotion/actions/create_adjustment.rb +4 -0
  22. data/app/models/spree/promotion/actions/create_item_adjustments.rb +5 -6
  23. data/app/models/spree/promotion/rules/product.rb +20 -8
  24. data/app/models/spree/promotion/rules/store.rb +4 -0
  25. data/app/models/spree/promotion/rules/taxon.rb +4 -0
  26. data/app/models/spree/promotion/rules/user.rb +4 -0
  27. data/app/models/spree/promotion.rb +34 -23
  28. data/app/models/spree/promotion_action.rb +4 -0
  29. data/app/models/spree/promotion_code.rb +10 -6
  30. data/app/models/spree/promotion_handler/cart.rb +26 -6
  31. data/app/models/spree/promotion_rule.rb +5 -0
  32. data/app/models/spree/refund.rb +8 -0
  33. data/app/models/spree/reimbursement.rb +2 -2
  34. data/app/models/spree/return_item.rb +1 -2
  35. data/app/models/spree/stock/allocator/on_hand_first.rb +2 -2
  36. data/app/models/spree/stock/quantifier.rb +12 -8
  37. data/app/models/spree/stock/simple_coordinator.rb +2 -1
  38. data/app/models/spree/store_credit.rb +8 -0
  39. data/app/models/spree/tax/item_tax.rb +3 -2
  40. data/app/models/spree/tax/order_tax.rb +3 -1
  41. data/app/models/spree/tax/tax_location.rb +4 -7
  42. data/app/models/spree/tax_rate.rb +2 -0
  43. data/app/models/spree/variant.rb +1 -1
  44. data/app/subscribers/spree/mailer_subscriber.rb +4 -0
  45. data/app/subscribers/spree/order_mailer_subscriber.rb +35 -0
  46. data/config/locales/en.yml +9 -2
  47. data/db/migrate/20201127212108_add_type_before_removal_to_spree_payment_methods.rb +7 -0
  48. data/db/migrate/20220317165036_set_promotions_with_any_policy_to_all_if_possible.rb +20 -0
  49. data/lib/generators/solidus/install/install_generator/bundler_context.rb +97 -0
  50. data/lib/generators/solidus/install/install_generator/install_frontend.rb +50 -0
  51. data/lib/generators/solidus/install/install_generator/support_solidus_frontend_extraction.rb +48 -0
  52. data/lib/generators/solidus/install/install_generator.rb +58 -50
  53. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +6 -16
  54. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/backend/all.js +2 -2
  55. data/lib/spree/app_configuration.rb +43 -0
  56. data/lib/spree/bus.rb +20 -0
  57. data/lib/spree/core/controller_helpers/auth.rb +9 -1
  58. data/lib/spree/core/controller_helpers/current_host.rb +1 -3
  59. data/lib/spree/core/controller_helpers/order.rb +10 -10
  60. data/lib/spree/core/controller_helpers/search.rb +1 -1
  61. data/lib/spree/core/engine.rb +39 -8
  62. data/lib/spree/core/state_machines/order.rb +1 -1
  63. data/lib/spree/core/stock_configuration.rb +18 -0
  64. data/lib/spree/core/validators/email.rb +3 -1
  65. data/lib/spree/core/version.rb +1 -1
  66. data/lib/spree/core.rb +20 -0
  67. data/lib/spree/event/subscriber_registry.rb +4 -6
  68. data/lib/spree/event.rb +1 -1
  69. data/lib/spree/migrations.rb +1 -1
  70. data/lib/spree/permission_sets/default_customer.rb +8 -1
  71. data/lib/spree/permitted_attributes.rb +4 -4
  72. data/lib/spree/preferences/configuration.rb +34 -12
  73. data/lib/spree/preferences/preferable_class_methods.rb +1 -1
  74. data/lib/spree/preferences/preference_differentiator.rb +2 -1
  75. data/lib/spree/preferences/static_model_preferences.rb +0 -2
  76. data/lib/spree/rails_compatibility.rb +99 -0
  77. data/lib/spree/testing_support/bus_helpers.rb +101 -0
  78. data/lib/spree/testing_support/common_rake.rb +47 -19
  79. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/backend/all.js +1 -1
  80. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/frontend/all.js +1 -1
  81. data/lib/spree/testing_support/dummy_app.rb +6 -1
  82. data/lib/spree/testing_support/factories/address_factory.rb +7 -2
  83. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
  84. data/lib/spree/testing_support/factories/order_factory.rb +8 -4
  85. data/lib/spree/testing_support/factories/product_factory.rb +4 -1
  86. data/lib/spree/testing_support/factories/store_credit_factory.rb +4 -4
  87. data/lib/spree/testing_support/factories/user_factory.rb +6 -0
  88. data/lib/spree/testing_support/factory_bot.rb +1 -1
  89. data/lib/spree/testing_support/order_walkthrough.rb +5 -4
  90. data/lib/spree/testing_support/silence_deprecations.rb +9 -0
  91. data/lib/tasks/payment_method.rake +29 -0
  92. data/lib/tasks/solidus/delete_prices_with_nil_amount.rake +2 -2
  93. data/lib/tasks/solidus/split_promotions_with_any_match_policy.rake +33 -0
  94. data/solidus_core.gemspec +7 -2
  95. metadata +88 -23
  96. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -10
  97. data/lib/generators/solidus/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -9
@@ -15,6 +15,12 @@ module Spree
15
15
  generator.test_framework :rspec
16
16
  end
17
17
 
18
+ if ActiveRecord.respond_to?(:yaml_column_permitted_classes) || ActiveRecord::Base.respond_to?(:yaml_column_permitted_classes)
19
+ config.active_record.yaml_column_permitted_classes ||= []
20
+ config.active_record.yaml_column_permitted_classes |=
21
+ [Symbol, BigDecimal, ActiveSupport::HashWithIndifferentAccess]
22
+ end
23
+
18
24
  initializer "spree.environment", before: :load_config_initializers do |app|
19
25
  app.config.spree = Spree::Config.environment
20
26
  end
@@ -40,18 +46,33 @@ module Spree
40
46
  ]
41
47
  end
42
48
 
43
- initializer "spree.core.checking_migrations", before: :load_config_initializers do |_app|
49
+ initializer "spree.core.checking_migrations", after: :load_config_initializers do |_app|
44
50
  Migrations.new(config, engine_name).check
45
51
  end
46
52
 
47
- # Setup Event Subscribers
48
- initializer 'spree.core.initialize_subscribers' do |app|
49
- app.reloader.to_prepare do
50
- Spree::Event.activate_autoloadable_subscribers
51
- end
53
+ # Setup pub/sub
54
+ initializer 'spree.core.pub_sub' do |app|
55
+ if Spree::Config.use_legacy_events
56
+ app.reloader.to_prepare do
57
+ Spree::Event.activate_autoloadable_subscribers
58
+ end
59
+
60
+ app.reloader.before_class_unload do
61
+ Spree::Event.deactivate_all_subscribers
62
+ end
63
+ else
64
+ app.reloader.to_prepare do
65
+ Spree::Bus.clear
66
+
67
+ %i[
68
+ order_finalized
69
+ order_recalculated
70
+ reimbursement_reimbursed
71
+ reimbursement_errored
72
+ ].each { |event_name| Spree::Bus.register(event_name) }
52
73
 
53
- app.reloader.before_class_unload do
54
- Spree::Event.deactivate_all_subscribers
74
+ Spree::OrderMailerSubscriber.new.subscribe_to(Spree::Bus)
75
+ end
55
76
  end
56
77
  end
57
78
 
@@ -75,6 +96,16 @@ module Spree
75
96
  Spree::UsersController.protect_from_forgery with: :exception
76
97
  end
77
98
  end
99
+
100
+ config.after_initialize do
101
+ if Spree::Config.use_legacy_events && !ENV['CI']
102
+ Spree::Deprecation.warn <<~MSG
103
+ Your Solidus store is using the legacy event system. You're
104
+ encouraged to switch to the new event bus. After you're done, you
105
+ can remove the `use_legacy_events` setting from `spree.rb`.
106
+ MSG
107
+ end
108
+ end
78
109
  end
79
110
  end
80
111
  end
@@ -119,7 +119,7 @@ module Spree
119
119
  before_transition to: :complete, do: :process_payments_before_complete
120
120
  end
121
121
 
122
- after_transition to: :complete, do: :finalize!
122
+ after_transition to: :complete, do: :finalize
123
123
  after_transition to: :resumed, do: :after_resume
124
124
  after_transition to: :canceled, do: :after_cancel
125
125
 
@@ -8,6 +8,9 @@ module Spree
8
8
  attr_writer :location_filter_class
9
9
  attr_writer :location_sorter_class
10
10
  attr_writer :allocator_class
11
+ attr_writer :inventory_unit_builder_class
12
+ attr_writer :availability_validator_class
13
+ attr_writer :inventory_validator_class
11
14
 
12
15
  def coordinator_class
13
16
  @coordinator_class ||= '::Spree::Stock::SimpleCoordinator'
@@ -33,6 +36,21 @@ module Spree
33
36
  @allocator_class ||= '::Spree::Stock::Allocator::OnHandFirst'
34
37
  @allocator_class.constantize
35
38
  end
39
+
40
+ def inventory_unit_builder_class
41
+ @inventory_unit_builder_class ||= '::Spree::Stock::InventoryUnitBuilder'
42
+ @inventory_unit_builder_class.constantize
43
+ end
44
+
45
+ def availability_validator_class
46
+ @availability_validator_class ||= '::Spree::Stock::AvailabilityValidator'
47
+ @availability_validator_class.constantize
48
+ end
49
+
50
+ def inventory_validator_class
51
+ @inventory_validator_class ||= '::Spree::Stock::InventoryValidator'
52
+ @inventory_validator_class.constantize
53
+ end
36
54
  end
37
55
  end
38
56
  end
@@ -13,9 +13,11 @@ module Spree
13
13
  #
14
14
  class EmailValidator < ActiveModel::EachValidator
15
15
  EMAIL_REGEXP = URI::MailTo::EMAIL_REGEXP
16
+ # Use Spree::Config.default_email_regexp instead
17
+ deprecate_constant :EMAIL_REGEXP
16
18
 
17
19
  def validate_each(record, attribute, value)
18
- unless EMAIL_REGEXP.match? value
20
+ unless Spree::Config.default_email_regexp.match? value
19
21
  record.errors.add(attribute, :invalid, **{ value: value }.merge!(options))
20
22
  end
21
23
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Spree
4
- VERSION = "3.1.5"
4
+ VERSION = "3.2.0.alpha"
5
5
 
6
6
  def self.solidus_version
7
7
  VERSION
data/lib/spree/core.rb CHANGED
@@ -21,6 +21,7 @@ require 'ransack'
21
21
  require 'state_machines-activerecord'
22
22
 
23
23
  require 'spree/deprecation'
24
+ require 'spree/rails_compatibility'
24
25
 
25
26
  # This is required because ActiveModel::Validations#invalid? conflicts with the
26
27
  # invalid state of a Payment. In the future this should be removed.
@@ -84,6 +85,24 @@ module Spree
84
85
  end
85
86
  end
86
87
 
88
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.7")
89
+ Spree::Deprecation.warn <<~HEREDOC
90
+ Ruby 2.5 & Ruby 2.6 (both EOL) are deprecated and will not be supported anymore from the next Solidus version.
91
+ Please, upgrade to a more recent Ruby version.
92
+ Read more on the release notes for different Ruby versions here:
93
+ https://www.ruby-lang.org/en/downloads/releases/
94
+ HEREDOC
95
+ end
96
+
97
+ if Gem::Version.new(Rails.version) < Gem::Version.new('6.0')
98
+ Spree::Deprecation.warn <<~HEREDOC
99
+ Rails 5.2 (EOL) is deprecated and will not be supported anymore from the next Solidus version.
100
+ Please, upgrade to a more recent Rails version.
101
+ Read more on upgrading from Rails 5.2 to Rails 6.0 here:
102
+ https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-5-2-to-rails-6-0
103
+ HEREDOC
104
+ end
105
+
87
106
  require 'spree/core/version'
88
107
 
89
108
  require 'spree/core/active_merchant_dependencies'
@@ -95,6 +114,7 @@ require 'spree/core/environment'
95
114
  require 'spree/migrations'
96
115
  require 'spree/migration_helpers'
97
116
  require 'spree/event'
117
+ require 'spree/bus'
98
118
  require 'spree/core/engine'
99
119
 
100
120
  require 'spree/i18n'
@@ -64,13 +64,11 @@ module Spree
64
64
  # Loading the files has the side effect of adding their module to the
65
65
  # list in Spree::Event.subscribers.
66
66
  def require_subscriber_files
67
- pattern = "app/subscribers/**/*_subscriber.rb"
67
+ require_dependency(
68
+ Spree::Core::Engine.root.join('app', 'subscribers', 'spree', 'mailer_subscriber.rb')
69
+ )
68
70
 
69
- # Load Solidus subscribers
70
- # rubocop:disable Rails/DynamicFindBy
71
- solidus_core_dir = Gem::Specification.find_by_name('solidus_core').gem_dir
72
- # rubocop:enable Rails/DynamicFindBy
73
- Dir.glob(File.join(solidus_core_dir, pattern)) { |c| require_dependency(c.to_s) }
71
+ pattern = "app/subscribers/**/*_subscriber.rb"
74
72
 
75
73
  # Load application subscribers, only when the flag is set to true:
76
74
  if Spree::Config.events.autoload_subscribers
data/lib/spree/event.rb CHANGED
@@ -21,7 +21,7 @@ module Spree
21
21
  #
22
22
  # @example Trigger an event named 'order_finalized'
23
23
  # Spree::Event.fire 'order_finalized', order: @order do
24
- # @order.finalize!
24
+ # @order.complete!
25
25
  # end
26
26
  def fire(event_name, opts = {})
27
27
  adapter.fire normalize_name(event_name), opts do
@@ -66,7 +66,7 @@ module Spree
66
66
  end
67
67
 
68
68
  def app_dir
69
- "#{Rails.root}/db/migrate"
69
+ Spree::Config.migration_path
70
70
  end
71
71
 
72
72
  def engine_dir
@@ -7,7 +7,14 @@ module Spree
7
7
  can :read, Country
8
8
  can :read, OptionType
9
9
  can :read, OptionValue
10
- can :create, Order
10
+ can :create, Order do |order, token|
11
+ # same user, or both nil
12
+ order.user == user ||
13
+ # guest checkout order
14
+ order.email.present? ||
15
+ # via API, just like with show and update
16
+ (order.guest_token.present? && token == order.guest_token)
17
+ end
11
18
  can [:show, :update], Order, Order.where(user: user) do |order, token|
12
19
  order.user == user || (order.guest_token.present? && token == order.guest_token)
13
20
  end
@@ -65,10 +65,10 @@ module Spree
65
65
 
66
66
  @@line_item_attributes = [:id, :variant_id, :quantity]
67
67
 
68
- @@option_type_attributes = [:name, :presentation, :option_values_attributes]
69
-
70
68
  @@option_value_attributes = [:name, :presentation]
71
69
 
70
+ @@option_type_attributes = [:name, :presentation, option_values_attributes: option_value_attributes]
71
+
72
72
  @@payment_attributes = [:amount, :payment_method_id, :payment_method]
73
73
 
74
74
  @@product_properties_attributes = [:property_name, :value, :position]
@@ -131,8 +131,8 @@ module Spree
131
131
  @@variant_attributes = [
132
132
  :name, :presentation, :cost_price, :lock_version,
133
133
  :position, :track_inventory,
134
- :product_id, :product, :option_values_attributes, :price,
135
- :weight, :height, :width, :depth, :sku, :cost_currency, option_value_ids: [], options: [:name, :value]
134
+ :product_id, :product, :price,
135
+ :weight, :height, :width, :depth, :sku, :cost_currency, :tax_category_id, option_value_ids: [], options: [:name, :value]
136
136
  ]
137
137
 
138
138
  @@checkout_address_attributes = [
@@ -38,6 +38,7 @@ module Spree::Preferences
38
38
  # defaults. Set via {#load_defaults}
39
39
  attr_reader :loaded_defaults
40
40
 
41
+ # @api private
41
42
  attr_reader :load_defaults_called
42
43
 
43
44
  def initialize
@@ -45,9 +46,9 @@ module Spree::Preferences
45
46
  @load_defaults_called = false
46
47
  end
47
48
 
48
- # @param [String] Solidus version from which take defaults when not
49
- # overriden.
50
- # @see #load_defaults
49
+ # @param [String] Solidus version from which take defaults when preferences
50
+ # are not overriden by the user.
51
+ # @see #loaded_defaults
51
52
  def load_defaults(version)
52
53
  @loaded_defaults = version
53
54
  @load_defaults_called = true
@@ -118,21 +119,35 @@ module Spree::Preferences
118
119
  end
119
120
  end
120
121
 
121
- # Generates a different preference default depending on {#version_defaults}
122
+ def self.inherited(klass)
123
+ klass.instance_variable_set(:@versioned_preferences, [])
124
+ class << klass
125
+ attr_reader :versioned_preferences
126
+ end
127
+ end
128
+
129
+ # Adds a preference with different default depending on {#loaded_defaults}
122
130
  #
123
- # This method is meant to be used in the `default:` keyword argument for
124
- # {.preference}. For instance, in the example, `foo`'s default was `true`
125
- # until version 3.0.0.alpha, when it became `false`:
131
+ # This method is a specialized version of {.preference} that generates a
132
+ # different default value for different Solidus versions. For instance, in
133
+ # the example, `foo`'s default was `true` until version 3.0.0.alpha, when it
134
+ # became `false`:
126
135
  #
127
136
  # @example
128
- # preference :foo, :boolean, default: by_version(true, "3.0.0.alpha" => false)
137
+ # versioned_preference :foo, :boolean, initial_value: true, boundaries: { "3.0.0.alpha" => false }
129
138
  #
139
+ # @see .preference
130
140
  # @see #loaded_defaults
131
141
  # @see Spree::Core::VersionedValue
132
- def self.by_version(*args)
133
- proc do |loaded_defaults|
134
- Spree::Core::VersionedValue.new(*args).call(loaded_defaults)
135
- end
142
+ def self.versioned_preference(name, type, initial_value:, boundaries:, **options)
143
+ @versioned_preferences << name
144
+ preference(
145
+ name,
146
+ type,
147
+ options.merge(
148
+ default: by_version(initial_value, boundaries)
149
+ )
150
+ )
136
151
  end
137
152
 
138
153
  def self.preference(name, type, options = {})
@@ -160,6 +175,13 @@ module Spree::Preferences
160
175
  end
161
176
  end
162
177
 
178
+ def self.by_version(*args)
179
+ proc do |loaded_defaults|
180
+ Spree::Core::VersionedValue.new(*args).call(loaded_defaults)
181
+ end
182
+ end
183
+ private_class_method :by_version
184
+
163
185
  private
164
186
 
165
187
  def context_for_default
@@ -49,7 +49,7 @@ module Spree::Preferences
49
49
 
50
50
  If you want to branch on the provided Solidus version, you can do like the following:
51
51
 
52
- preference :foo, :string, default: by_version(true, "3.2.0" => false)
52
+ versioned_preference :foo, :string, initial_value: true, boundaries: { "3.2.0" => false }
53
53
 
54
54
  MSG
55
55
  ->(_default_context) { given.call }
@@ -12,7 +12,8 @@ module Spree
12
12
  def call(from:, to:)
13
13
  preferences_from = config_class.new.load_defaults(from)
14
14
  preferences_to = config_class.new.load_defaults(to)
15
- preferences_from.reduce({}) do |changes, (pref_key, value_from)|
15
+ config_class.versioned_preferences.reduce({}) do |changes, pref_key|
16
+ value_from = preferences_from[pref_key]
16
17
  value_to = preferences_to[pref_key]
17
18
  if value_from == value_to
18
19
  changes
@@ -36,8 +36,6 @@ module Spree
36
36
  end
37
37
 
38
38
  def add(klass, name, preferences)
39
- # We use class name instead of class to allow reloading in dev
40
- raise "Static model preference '#{name}' on #{klass} is already defined" if @store[klass.to_s][name]
41
39
  @store[klass.to_s][name] = Definition.new(klass, preferences)
42
40
  end
43
41
 
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ # Supported Rails versions compatibility
5
+ #
6
+ # This module is meant to wrap some Rails API changes between supported
7
+ # versions. It's also meant to contain compatibility for features that we use
8
+ # internally in the Solidus code base.
9
+ module RailsCompatibility
10
+ # Method `#to_fs`
11
+ #
12
+ # Available since Rails 7.0, substitutes `#to_s(format)`
13
+ #
14
+ # It includes:
15
+ #
16
+ # ActiveSupport::NumericWithFormat
17
+ # ActiveSupport::RangeWithFormat
18
+ # ActiveSupport::TimeWithZone
19
+ # Array
20
+ # Date
21
+ # DateTime
22
+ # Time
23
+ #
24
+ # See https://github.com/rails/rails/pull/43772 &
25
+ # https://github.com/rails/rails/pull/44354
26
+ #
27
+ # TODO: Remove when deprecating Rails 6.1
28
+ def self.to_fs(value, *args, **kwargs, &block)
29
+ if version_gte?('7.0')
30
+ value.to_fs(*args, **kwargs, &block)
31
+ else
32
+ value.to_s(*args, **kwargs, &block)
33
+ end
34
+ end
35
+
36
+ # `raise_on_missing_translations` config option
37
+ #
38
+ # Changed from ActionView to I18n on Rails 6.1
39
+ #
40
+ # See https://github.com/rails/rails/pull/31571
41
+ #
42
+ # TODO: Remove when deprecating Rails 6.0
43
+ def self.raise_on_missing_translations(value)
44
+ if version_gte?('6.1')
45
+ Rails.application.config.i18n.raise_on_missing_translations = value
46
+ else
47
+ Rails.application.config.action_view.raise_on_missing_translations = value
48
+ end
49
+ end
50
+
51
+ # Set current host for ActiveStorage in a controller
52
+ #
53
+ # Changed from `#host` to including a module in Rails 6
54
+ #
55
+ # See https://github.com/rails/rails/commit/e33c3cd8ccbecaca6c6af0438956431b02cb3fb2
56
+ #
57
+ # TODO: Remove when deprecating Rails 5.2
58
+ def self.active_storage_set_current(controller)
59
+ if version_gte?('6')
60
+ controller.include ActiveStorage::SetCurrent
61
+ else
62
+ controller.before_action do
63
+ ActiveStorage::Current.host = request.base_url
64
+ end
65
+ end
66
+ end
67
+
68
+ # Set current host for ActiveStorage
69
+ #
70
+ # Changed from `#host` to `#url_options` on Rails 7
71
+ #
72
+ # See https://github.com/rails/rails/issues/41388
73
+ #
74
+ # TODO: Remove when deprecating Rails 6.1
75
+ def self.active_storage_url_options_host(value)
76
+ if version_gte?('7')
77
+ ActiveStorage::Current.url_options = { host: value }
78
+ else
79
+ ActiveStorage::Current.host = value
80
+ end
81
+ end
82
+
83
+ # Default ActiveStorage variant processor
84
+ #
85
+ # Changed from `:mini_magick` to `vips` on Rails 7
86
+ #
87
+ # See https://github.com/rails/rails/issues/42744
88
+ #
89
+ # TODO: Remove when deprecating Rails 6.1
90
+ def self.variant_processor
91
+ version_gte?('7') ? :vips : :mini_magick
92
+ end
93
+
94
+ def self.version_gte?(version)
95
+ ::Rails.gem_version >= Gem::Version.new(version)
96
+ end
97
+ private_class_method :version_gte?
98
+ end
99
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spree/bus'
4
+
5
+ module Spree
6
+ module TestingSupport
7
+ # RSpec test helpers for the event bus
8
+ #
9
+ # If you want to use the methods defined in this module, include it in your
10
+ # specs:
11
+ #
12
+ # @example
13
+ # require 'rails_helper'
14
+ # require 'spree/testing_support/bus_helpers'
15
+ #
16
+ # RSpec.describe MyClass do
17
+ # include Spree::TestingSupport::BusHelpers
18
+ # end
19
+ #
20
+ # or, globally, in your `spec_helper.rb`:
21
+ #
22
+ # @example
23
+ # require 'spree/testing_support/bus_helpers'
24
+ #
25
+ # RSpec.configure do |config|
26
+ # config.include Spree::TestingSupport::BusHelpers
27
+ # end
28
+ module BusHelpers
29
+ extend RSpec::Matchers::DSL
30
+
31
+ # Stubs {Spree::Bus}
32
+ #
33
+ # After you have called this method in an example, {Spree::Bus} will no
34
+ # longer publish any event for the duration of that example. All the
35
+ # method invocations on it will be stubbed.
36
+ #
37
+ # Internally, it stubs {Spree::Bus#publish}.
38
+ #
39
+ # After you call this method, probably you'll want to call some of the
40
+ # matchers defined in this module.
41
+ def stub_spree_bus
42
+ allow(Spree::Bus).to receive(:publish)
43
+ end
44
+
45
+ # @!method have_been_published(event_name)
46
+ # Matcher to test that an event has been published via {Spree::Bus#publish}
47
+ #
48
+ # Before using this matcher, you need to call {#stub_spree_bus}.
49
+ #
50
+ # Remember that the event listeners won't be performed.
51
+ #
52
+ # @example
53
+ # it 'publishes foo event' do
54
+ # stub_spree_bus
55
+ #
56
+ # Spree::Bus.publish 'foo'
57
+ #
58
+ # expect('foo').to have_been_published
59
+ # end
60
+ #
61
+ # It can be chain through `with` to match with the published payload:
62
+ #
63
+ # @example
64
+ # it 'publishes foo event with the expected payload' do
65
+ # stub_spree_bus
66
+ #
67
+ # Spree::Bus.publish 'foo', bar: :baz, qux: :quux
68
+ #
69
+ # expect('foo').to have_been_published.with(a_hash_including(bar: :baz))
70
+ # end
71
+ #
72
+ # @param [Symbol] event_name
73
+ matcher :have_been_published do
74
+ chain :with, :payload
75
+
76
+ match do |expected_event|
77
+ expected_event = normalize_name(expected_event)
78
+ arguments = payload ? [expected_event, payload] : [expected_event, any_args]
79
+ expect(Spree::Bus).to have_received(:publish).with(*arguments)
80
+ end
81
+
82
+ failure_message do |expected_event|
83
+ <<~MSG
84
+ expected #{expected_event.inspect} to have been published.
85
+ Make sure that provided payload, if any, also matches.
86
+ MSG
87
+ end
88
+
89
+ def normalize_name(event_name)
90
+ if event_name.is_a?(Symbol)
91
+ eq(event_name)
92
+ else
93
+ raise ArgumentError, <<~MSG
94
+ "#{event_name.inspect} is not a valid event name. It must be a Symbol."
95
+ MSG
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -6,33 +6,61 @@ end
6
6
 
7
7
  require 'generators/spree/dummy/dummy_generator'
8
8
 
9
- namespace :common do
10
- task :test_app, :user_class do |_t, args|
11
- args.with_defaults(user_class: "Spree::LegacyUser")
12
- require ENV['LIB_NAME']
9
+ class CommonRakeTasks
10
+ include Rake::DSL
13
11
 
14
- ENV["RAILS_ENV"] = 'test'
12
+ def initialize
13
+ namespace :common do
14
+ task :test_app, :user_class do |_t, args|
15
+ args.with_defaults(user_class: "Spree::LegacyUser")
16
+ require ENV['LIB_NAME']
17
+
18
+ force_rails_environment_to_test
19
+
20
+ Spree::DummyGenerator.start ["--lib_name=#{ENV['LIB_NAME']}", "--quiet"]
21
+ Solidus::InstallGenerator.start ["--lib_name=#{ENV['LIB_NAME']}", "--auto-accept", "--with-authentication=false", "--payment-method=none", "--migrate=false", "--seed=false", "--sample=false", "--quiet", "--user_class=#{args[:user_class]}"]
22
+
23
+ puts "Setting up dummy database..."
15
24
 
16
- Spree::DummyGenerator.start ["--lib_name=#{ENV['LIB_NAME']}", "--quiet"]
17
- Solidus::InstallGenerator.start ["--lib_name=#{ENV['LIB_NAME']}", "--auto-accept", "--with-authentication=false", "--payment-method=none", "--migrate=false", "--seed=false", "--sample=false", "--quiet", "--user_class=#{args[:user_class]}"]
25
+ sh "bin/rails db:environment:set RAILS_ENV=test"
26
+ sh "bin/rails db:drop db:create db:migrate VERBOSE=false RAILS_ENV=test"
18
27
 
19
- puts "Setting up dummy database..."
28
+ if extension_installation_generator_exists?
29
+ puts 'Running extension installation generator...'
30
+ sh "bin/rails generate #{rake_generator_namespace}:install --auto-run-migrations"
31
+ end
32
+ end
20
33
 
21
- sh "bin/rails db:environment:set RAILS_ENV=test"
22
- sh "bin/rails db:drop db:create db:migrate VERBOSE=false RAILS_ENV=test"
34
+ task :seed do |_t, _args|
35
+ puts "Seeding ..."
23
36
 
24
- begin
25
- require "generators/#{ENV['LIB_NAME']}/install/install_generator"
26
- puts 'Running extension installation generator...'
27
- "#{ENV['LIB_NAMESPACE'] || ENV['LIB_NAME'].camelize}::Generators::InstallGenerator".constantize.start(["--auto-run-migrations"])
28
- rescue LoadError
29
- # No extension generator to run
37
+ sh "bundle exec rake db:seed RAILS_ENV=test"
38
+ end
30
39
  end
31
40
  end
32
41
 
33
- task :seed do |_t, _args|
34
- puts "Seeding ..."
42
+ private
35
43
 
36
- sh "bundle exec rake db:seed RAILS_ENV=test"
44
+ def force_rails_environment_to_test
45
+ ENV["RAILS_ENV"] = 'test'
46
+ Rails.env = 'test'
47
+ end
48
+
49
+ def extension_installation_generator_exists?
50
+ require "generators/#{generator_namespace}/install/install_generator"
51
+
52
+ true
53
+ rescue LoadError
54
+ false
55
+ end
56
+
57
+ def generator_namespace
58
+ "#{ENV['LIB_NAMESPACE']&.underscore || ENV['LIB_NAME']}"
59
+ end
60
+
61
+ def rake_generator_namespace
62
+ generator_namespace.gsub("/", ":")
37
63
  end
38
64
  end
65
+
66
+ CommonRakeTasks.new
@@ -1,5 +1,5 @@
1
1
  // This is a manifest file that'll be compiled into including all the files listed below.
2
- // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
2
+ // Add new JavaScript code in separate files in this directory and they'll automatically
3
3
  // be included in the compiled file accessible from http://example.com/assets/application.js
4
4
  // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
5
  // the compiled file.
@@ -1,5 +1,5 @@
1
1
  // This is a manifest file that'll be compiled into including all the files listed below.
2
- // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
2
+ // Add new JavaScript code in separate files in this directory and they'll automatically
3
3
  // be included in the compiled file accessible from http://example.com/assets/application.js
4
4
  // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
5
  // the compiled file.