solidus_core 2.11.4 → 2.11.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/concerns/spree/active_storage_adapter.rb +2 -0
  3. data/app/models/concerns/spree/active_storage_adapter/attachment.rb +11 -11
  4. data/app/models/spree/address.rb +28 -5
  5. data/app/models/spree/base.rb +39 -13
  6. data/app/models/spree/calculator.rb +4 -0
  7. data/app/models/spree/image/active_storage_attachment.rb +10 -2
  8. data/app/models/spree/image/paperclip_attachment.rb +1 -1
  9. data/app/models/spree/order_merger.rb +1 -1
  10. data/app/models/spree/payment.rb +10 -3
  11. data/app/models/spree/payment_method.rb +3 -0
  12. data/app/models/spree/payment_method/bogus_credit_card.rb +13 -9
  13. data/app/models/spree/payment_method/simple_bogus_credit_card.rb +4 -4
  14. data/app/models/spree/product.rb +8 -2
  15. data/app/models/spree/promotion_action.rb +3 -0
  16. data/app/models/spree/promotion_rule.rb +4 -0
  17. data/app/models/spree/refund.rb +5 -3
  18. data/app/models/spree/shipping_method.rb +1 -1
  19. data/app/models/spree/stock/availability_validator.rb +2 -2
  20. data/app/models/spree/stock/inventory_validator.rb +2 -2
  21. data/app/models/spree/taxon/active_storage_attachment.rb +1 -2
  22. data/app/models/spree/taxon/paperclip_attachment.rb +1 -0
  23. data/db/migrate/20210122110141_add_name_to_spree_addresses.rb +13 -0
  24. data/lib/generators/solidus/install/install_generator.rb +1 -1
  25. data/lib/generators/spree/dummy/templates/rails/test.rb +3 -0
  26. data/lib/spree/app_configuration.rb +8 -0
  27. data/lib/spree/core.rb +0 -4
  28. data/lib/spree/core/engine.rb +6 -7
  29. data/lib/spree/core/version.rb +1 -1
  30. data/lib/spree/preferences/persistable.rb +23 -0
  31. data/lib/spree/testing_support.rb +19 -28
  32. data/lib/spree/testing_support/dummy_app.rb +4 -2
  33. data/lib/spree/testing_support/dummy_app/mailer_previews/test_mailer_preview.rb +4 -0
  34. data/lib/spree/testing_support/factories.rb +8 -2
  35. data/lib/spree/testing_support/factories/address_factory.rb +6 -2
  36. data/lib/spree/testing_support/factories/adjustment_factory.rb +10 -2
  37. data/lib/spree/testing_support/factories/adjustment_reason_factory.rb +4 -2
  38. data/lib/spree/testing_support/factories/calculator_factory.rb +4 -2
  39. data/lib/spree/testing_support/factories/carton_factory.rb +7 -2
  40. data/lib/spree/testing_support/factories/country_factory.rb +4 -2
  41. data/lib/spree/testing_support/factories/credit_card_factory.rb +4 -2
  42. data/lib/spree/testing_support/factories/customer_return_factory.rb +8 -2
  43. data/lib/spree/testing_support/factories/image_factory.rb +4 -2
  44. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +9 -2
  45. data/lib/spree/testing_support/factories/line_item_factory.rb +7 -2
  46. data/lib/spree/testing_support/factories/option_type_factory.rb +7 -2
  47. data/lib/spree/testing_support/factories/option_value_factory.rb +4 -2
  48. data/lib/spree/testing_support/factories/order_factory.rb +11 -2
  49. data/lib/spree/testing_support/factories/order_promotion_factory.rb +7 -2
  50. data/lib/spree/testing_support/factories/payment_factory.rb +9 -2
  51. data/lib/spree/testing_support/factories/payment_method_factory.rb +4 -2
  52. data/lib/spree/testing_support/factories/price_factory.rb +6 -2
  53. data/lib/spree/testing_support/factories/product_factory.rb +10 -2
  54. data/lib/spree/testing_support/factories/product_option_type_factory.rb +7 -2
  55. data/lib/spree/testing_support/factories/product_property_factory.rb +7 -2
  56. data/lib/spree/testing_support/factories/promotion_category_factory.rb +4 -2
  57. data/lib/spree/testing_support/factories/promotion_code_factory.rb +7 -2
  58. data/lib/spree/testing_support/factories/promotion_factory.rb +7 -2
  59. data/lib/spree/testing_support/factories/property_factory.rb +4 -2
  60. data/lib/spree/testing_support/factories/refund_factory.rb +7 -2
  61. data/lib/spree/testing_support/factories/refund_reason_factory.rb +4 -2
  62. data/lib/spree/testing_support/factories/reimbursement_factory.rb +6 -2
  63. data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +4 -2
  64. data/lib/spree/testing_support/factories/return_authorization_factory.rb +8 -2
  65. data/lib/spree/testing_support/factories/return_item_factory.rb +8 -2
  66. data/lib/spree/testing_support/factories/return_reason_factory.rb +4 -2
  67. data/lib/spree/testing_support/factories/role_factory.rb +4 -2
  68. data/lib/spree/testing_support/factories/shipment_factory.rb +9 -2
  69. data/lib/spree/testing_support/factories/shipping_category_factory.rb +4 -2
  70. data/lib/spree/testing_support/factories/shipping_method_factory.rb +8 -2
  71. data/lib/spree/testing_support/factories/shipping_rate_factory.rb +7 -2
  72. data/lib/spree/testing_support/factories/state_factory.rb +7 -2
  73. data/lib/spree/testing_support/factories/stock_item_factory.rb +7 -2
  74. data/lib/spree/testing_support/factories/stock_location_factory.rb +8 -2
  75. data/lib/spree/testing_support/factories/stock_movement_factory.rb +6 -2
  76. data/lib/spree/testing_support/factories/stock_package_factory.rb +7 -2
  77. data/lib/spree/testing_support/factories/store_credit_category_factory.rb +4 -2
  78. data/lib/spree/testing_support/factories/store_credit_event_factory.rb +7 -2
  79. data/lib/spree/testing_support/factories/store_credit_factory.rb +8 -2
  80. data/lib/spree/testing_support/factories/store_credit_reason_factory.rb +4 -2
  81. data/lib/spree/testing_support/factories/store_credit_type_factory.rb +4 -2
  82. data/lib/spree/testing_support/factories/store_factory.rb +4 -2
  83. data/lib/spree/testing_support/factories/tax_category_factory.rb +7 -2
  84. data/lib/spree/testing_support/factories/tax_rate_factory.rb +8 -2
  85. data/lib/spree/testing_support/factories/taxon_factory.rb +6 -2
  86. data/lib/spree/testing_support/factories/taxonomy_factory.rb +4 -2
  87. data/lib/spree/testing_support/factories/user_factory.rb +8 -2
  88. data/lib/spree/testing_support/factories/variant_factory.rb +9 -2
  89. data/lib/spree/testing_support/factories/variant_property_rule_condition_factory.rb +7 -2
  90. data/lib/spree/testing_support/factories/variant_property_rule_factory.rb +8 -2
  91. data/lib/spree/testing_support/factories/variant_property_rule_value_factory.rb +7 -2
  92. data/lib/spree/testing_support/factories/zone_factory.rb +7 -2
  93. data/lib/spree/testing_support/factory_bot.rb +68 -0
  94. data/lib/spree/testing_support/fixtures/file.txt +1 -0
  95. data/lib/spree/testing_support/order_walkthrough.rb +9 -9
  96. data/lib/spree/testing_support/sequences.rb +4 -1
  97. data/lib/tasks/migrations/migrate_address_names.rake +158 -0
  98. data/lib/tasks/migrations/migrate_default_billing_addresses_to_address_book.rake +26 -0
  99. data/lib/tasks/upgrade.rake +13 -0
  100. data/solidus_core.gemspec +23 -1
  101. metadata +32 -6
  102. data/lib/spree/awesome_nested_set_override.rb +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7c2f2034c2f239923f522b08eeb9e6da4925058e86026d70d69cccf42ea975b9
4
- data.tar.gz: c0f56fb7091eace3ef9a91a34846035a2f0bdffd248ad5ca9ae204a7d8faae68
3
+ metadata.gz: f6be99509f3f7cdd74113426927e8751493ea311563e4d2a4fbf57d5661da05d
4
+ data.tar.gz: e5124764c6cfadd679394db2f28d1a45171f5cf45caa571f679a567a985ac5b2
5
5
  SHA512:
6
- metadata.gz: a2e41a38b785af3e8da52ac03b86c9b1179cd2a92ec59a32c77ae6d54398115c99679ad8024b6f2988d95ddf515a9df2e0b118a687a239c2afb0920c17493b5f
7
- data.tar.gz: d023f2e92ee65585e76103d5a8921f3525965480984fc9f0f48e7f69c76d5671d98bdc4d388112ee52c8b3f1f68a1ae51a215be903ef66ee1d5958c1a2c64009
6
+ metadata.gz: '0093e9c554425147adf6bbeadf7a7f4ed91190b5a34664935103bfae6c0cb277d62bb44c974b8a625235a400cc91cf00736fceeb971229d56d97fa83eb5c3947'
7
+ data.tar.gz: bb18cd30482e0bcd1a8efaf671fba77279a04f3f1bf0cb06632fb9bc577af67544cbabcb14e5eae3347d71f74946fe86dd5ee60d4c49a0f130abe4153b45995a
@@ -107,6 +107,8 @@ module Spree
107
107
 
108
108
  def url(style = default_style)
109
109
  attachment.url(style)
110
+ rescue ActiveStorage::FileNotFoundError
111
+ "noimage/#{style}.png"
110
112
  end
111
113
 
112
114
  def destroy_attachment(_name)
@@ -9,11 +9,9 @@ module Spree
9
9
  class Attachment
10
10
  delegate_missing_to :@attachment
11
11
 
12
- DEFAULT_SIZE = '100%'
13
-
14
12
  def initialize(attachment, styles: {})
15
13
  @attachment = attachment
16
- @styles = styles
14
+ @styles = normalize_styles(styles)
17
15
  end
18
16
 
19
17
  def exists?
@@ -21,20 +19,18 @@ module Spree
21
19
  end
22
20
 
23
21
  def filename
24
- blob.filename.to_s
22
+ blob&.filename.to_s
25
23
  end
26
24
 
27
25
  def url(style = nil)
28
- variant(style).url
26
+ variant(style)&.url
29
27
  end
30
28
 
31
29
  def variant(style = nil)
32
- size = style_to_size(style&.to_sym)
30
+ size = style_to_size(style)
33
31
  @attachment.variant(
34
- resize: size,
35
- strip: true,
36
- 'auto-orient': true,
37
- colorspace: 'sRGB',
32
+ resize_to_limit: size,
33
+ strip: true
38
34
  ).processed
39
35
  end
40
36
 
@@ -61,8 +57,12 @@ module Spree
61
57
  @attachment.metadata
62
58
  end
63
59
 
60
+ def normalize_styles(styles)
61
+ styles.transform_values { |v| v.split('x') }
62
+ end
63
+
64
64
  def style_to_size(style)
65
- @styles.fetch(style) { DEFAULT_SIZE }
65
+ @styles.fetch(style&.to_sym) { [width, height] }
66
66
  end
67
67
  end
68
68
  end
@@ -92,6 +92,12 @@ module Spree
92
92
  if base['lastname'].presence || base['last_name'].presence
93
93
  base['lastname'] = name_from_attributes.last_name
94
94
  end
95
+
96
+ virtual_name = name_from_attributes.value
97
+ if base['name'].blank? && virtual_name.present?
98
+ base['name'] = virtual_name
99
+ end
100
+
95
101
  excluded_attributes = DB_ONLY_ATTRS + %w(first_name last_name)
96
102
 
97
103
  base.except(*excluded_attributes)
@@ -120,7 +126,11 @@ module Spree
120
126
  # @return [Boolean] true if the two addresses have the same address fields
121
127
  def ==(other_address)
122
128
  return false unless other_address && other_address.respond_to?(:value_attributes)
123
- value_attributes == other_address.value_attributes
129
+ if Spree::Config.use_combined_first_and_last_name_in_address
130
+ value_attributes.except(*LEGACY_NAME_ATTRS) == other_address.value_attributes.except(*LEGACY_NAME_ATTRS)
131
+ else
132
+ value_attributes == other_address.value_attributes
133
+ end
124
134
  end
125
135
 
126
136
  # @deprecated Do not use this. Use Address.== instead.
@@ -193,17 +203,30 @@ module Spree
193
203
  country && country.iso
194
204
  end
195
205
 
206
+ before_save :set_name_from_firstname_and_lastname
207
+
208
+ def set_name_from_firstname_and_lastname
209
+ name_from_firstname_and_lastname = Spree::Address::Name.from_attributes(attributes.except(:name, 'name'))
210
+
211
+ if read_attribute(:name).blank? && name_from_firstname_and_lastname.present?
212
+ write_attribute(:name, name_from_firstname_and_lastname)
213
+ end
214
+ end
215
+
196
216
  # @return [String] the full name on this address
197
217
  def name
198
- Spree::Address::Name.new(
199
- read_attribute(:firstname),
200
- read_attribute(:lastname)
201
- ).value
218
+ self[:name] || begin
219
+ Spree::Address::Name.new(
220
+ read_attribute(:firstname),
221
+ read_attribute(:lastname)
222
+ ).value
223
+ end
202
224
  end
203
225
 
204
226
  def name=(value)
205
227
  return if value.nil?
206
228
 
229
+ write_attribute(:name, value)
207
230
  name_from_value = Spree::Address::Name.new(value)
208
231
  write_attribute(:firstname, name_from_value.first_name)
209
232
  write_attribute(:lastname, name_from_value.last_name)
@@ -1,24 +1,50 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'spree/preferences/persistable'
4
+
3
5
  class Spree::Base < ActiveRecord::Base
4
- include Spree::Preferences::Preferable
5
6
  include Spree::Core::Permalinks
6
7
  include Spree::RansackableAttributes
7
8
 
8
- def initialize_preference_defaults
9
- if has_attribute?(:preferences)
10
- self.preferences = default_preferences.merge(preferences)
11
- end
9
+ def self.preference(*args)
10
+ Spree::Deprecation.warn <<~WARN
11
+ #{name} has a `preferences` column, but does not explicitly (de)serialize this column.
12
+ In order to make #{name} work with future versions of Solidus (and Rails), please add the
13
+ following line to your class:
14
+ ```
15
+ class #{name}
16
+ include Spree::Preferences::Persistable
17
+ ...
18
+ end
19
+ ```
20
+ WARN
21
+ include Spree::Preferences::Persistable
22
+ preference(*args)
12
23
  end
13
24
 
14
- # Only run preference initialization on models which requires it. Improves
15
- # performance of record initialization slightly.
16
- def self.preference(*args)
17
- # after_initialize can be called multiple times with the same symbol, it
18
- # will only be called once on initialization.
19
- serialize :preferences, Hash
20
- after_initialize :initialize_preference_defaults
21
- super
25
+ def preferences
26
+ value = read_attribute(:preferences)
27
+ if !value.is_a?(Hash)
28
+ Spree::Deprecation.warn <<~WARN
29
+ #{self.class.name} has a `preferences` column, but does not explicitly (de)serialize this column.
30
+ In order to make #{self.class.name} work with future versions of Solidus (and Rails), please add the
31
+ following lines to your class:
32
+ ```
33
+ class #{self.class.name}
34
+ include Spree::Preferences::Persistable
35
+ ...
36
+ end
37
+ ```
38
+ WARN
39
+ self.class.include Spree::Preferences::Persistable
40
+
41
+ ActiveRecord::Type::Serialized.new(
42
+ ActiveRecord::Type::Text.new,
43
+ ActiveRecord::Coders::YAMLColumn.new(:preferences, Hash)
44
+ ).deserialize(value)
45
+ else
46
+ value
47
+ end
22
48
  end
23
49
 
24
50
  if Kaminari.config.page_method_name != :page
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'spree/preferences/persistable'
4
+
3
5
  module Spree
4
6
  class Calculator < Spree::Base
7
+ include Spree::Preferences::Persistable
8
+
5
9
  belongs_to :calculable, polymorphic: true, optional: true
6
10
 
7
11
  # This method calls a compute_<computable> method. must be overriden in concrete calculator.
@@ -7,6 +7,10 @@ module Spree::Image::ActiveStorageAttachment
7
7
  delegate :width, :height, to: :attachment, prefix: true
8
8
 
9
9
  included do
10
+ validates :attachment, presence: true
11
+ validate :attachment_is_an_image
12
+ validate :supported_content_type
13
+
10
14
  has_attachment :attachment,
11
15
  styles: {
12
16
  mini: '48x48>',
@@ -15,7 +19,11 @@ module Spree::Image::ActiveStorageAttachment
15
19
  large: '1200x1200>'
16
20
  },
17
21
  default_style: :product
18
- validates :attachment, presence: true
19
- validate :attachment_is_an_image
22
+
23
+ def supported_content_type
24
+ unless attachment.content_type.in?(Spree::Config.allowed_image_mime_types)
25
+ errors.add(:attachment, :content_type_not_supported)
26
+ end
27
+ end
20
28
  end
21
29
  end
@@ -15,7 +15,7 @@ module Spree::Image::PaperclipAttachment
15
15
  convert_options: { all: '-strip -auto-orient -colorspace sRGB' }
16
16
  validates_attachment :attachment,
17
17
  presence: true,
18
- content_type: { content_type: %w[image/jpeg image/jpg image/png image/gif] }
18
+ content_type: { content_type: Spree::Config.allowed_image_mime_types }
19
19
 
20
20
  # save the w,h of the original image (from which others can be calculated)
21
21
  # we need to look at the write-queue for images which have not been saved yet
@@ -128,7 +128,7 @@ module Spree
128
128
  # @param [Spree::LineItem] line_item The line item which could not be saved
129
129
  # @return [void]
130
130
  def handle_error(line_item)
131
- order.errors[:base] << line_item.errors.full_messages
131
+ order.errors.add(:base, line_item.errors.full_messages)
132
132
  end
133
133
 
134
134
  # Save the order totals after merge
@@ -168,9 +168,16 @@ module Spree
168
168
 
169
169
  def validate_source
170
170
  if source && !source.valid?
171
- source.errors.each do |field, error|
172
- field_name = I18n.t("activerecord.attributes.#{source.class.to_s.underscore}.#{field}")
173
- errors.add(I18n.t(source.class.to_s.demodulize.underscore, scope: 'spree'), "#{field_name} #{error}")
171
+ if Gem::Requirement.new(">= 6.1").satisfied_by?(Rails.gem_version)
172
+ source.errors.each do |error|
173
+ field_name = I18n.t("activerecord.attributes.#{source.class.to_s.underscore}.#{error.attribute}")
174
+ errors.add(I18n.t(source.class.to_s.demodulize.underscore, scope: 'spree'), "#{field_name} #{error.message}")
175
+ end
176
+ else
177
+ source.errors.each do |field, error|
178
+ field_name = I18n.t("activerecord.attributes.#{source.class.to_s.underscore}.#{field}")
179
+ errors.add(I18n.t(source.class.to_s.demodulize.underscore, scope: 'spree'), "#{field_name} #{error}")
180
+ end
174
181
  end
175
182
  end
176
183
  if errors.any?
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'spree/preferences/persistable'
3
4
  require 'spree/preferences/statically_configurable'
4
5
 
5
6
  module Spree
@@ -11,6 +12,8 @@ module Spree
11
12
  # This class is not meant to be instantiated. Please create instances of concrete payment methods.
12
13
  #
13
14
  class PaymentMethod < Spree::Base
15
+ include Spree::Preferences::Persistable
16
+
14
17
  preference :server, :string, default: 'test'
15
18
  preference :test_mode, :boolean, default: true
16
19
 
@@ -9,6 +9,10 @@ module Spree
9
9
 
10
10
  VALID_CCS = ['1', TEST_VISA, TEST_MC, TEST_AMEX, TEST_DISC].flatten
11
11
 
12
+ AUTHORIZATION_CODE = '12345'
13
+ FAILURE_MESSAGE = 'Bogus Gateway: Forced failure'
14
+ SUCCESS_MESSAGE = 'Bogus Gateway: Forced success'
15
+
12
16
  attr_accessor :test
13
17
 
14
18
  def gateway_class
@@ -26,40 +30,40 @@ module Spree
26
30
  def authorize(_money, credit_card, _options = {})
27
31
  profile_id = credit_card.gateway_customer_profile_id
28
32
  if VALID_CCS.include?(credit_card.number) || (profile_id && profile_id.starts_with?('BGS-'))
29
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'D' })
33
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'D' })
30
34
  else
31
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', { message: 'Bogus Gateway: Forced failure' }, test: true)
35
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, { message: FAILURE_MESSAGE }, test: true)
32
36
  end
33
37
  end
34
38
 
35
39
  def purchase(_money, credit_card, _options = {})
36
40
  profile_id = credit_card.gateway_customer_profile_id
37
41
  if VALID_CCS.include?(credit_card.number) || (profile_id && profile_id.starts_with?('BGS-'))
38
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'M' })
42
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'M' })
39
43
  else
40
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', message: 'Bogus Gateway: Forced failure', test: true)
44
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, message: FAILURE_MESSAGE, test: true)
41
45
  end
42
46
  end
43
47
 
44
48
  def credit(_money, _credit_card, _response_code, _options = {})
45
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
49
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
46
50
  end
47
51
 
48
52
  def capture(_money, authorization, _gateway_options)
49
53
  if authorization == '12345'
50
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true)
54
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true)
51
55
  else
52
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', error: 'Bogus Gateway: Forced failure', test: true)
56
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, error: FAILURE_MESSAGE, test: true)
53
57
  end
54
58
  end
55
59
 
56
60
  def void(_response_code, _credit_card, _options = {})
57
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
61
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
58
62
  end
59
63
 
60
64
  # @see Spree::PaymentMethod#try_void
61
65
  def try_void(_payment)
62
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345')
66
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
63
67
  end
64
68
 
65
69
  def test?
@@ -9,17 +9,17 @@ module Spree
9
9
 
10
10
  def authorize(_money, credit_card, _options = {})
11
11
  if VALID_CCS.include? credit_card.number
12
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'A' })
12
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'A' })
13
13
  else
14
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', { message: 'Bogus Gateway: Forced failure' }, test: true)
14
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, { message: FAILURE_MESSAGE }, test: true)
15
15
  end
16
16
  end
17
17
 
18
18
  def purchase(_money, credit_card, _options = {})
19
19
  if VALID_CCS.include? credit_card.number
20
- ActiveMerchant::Billing::Response.new(true, 'Bogus Gateway: Forced success', {}, test: true, authorization: '12345', avs_result: { code: 'A' })
20
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'A' })
21
21
  else
22
- ActiveMerchant::Billing::Response.new(false, 'Bogus Gateway: Forced failure', message: 'Bogus Gateway: Forced failure', test: true)
22
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, message: FAILURE_MESSAGE, test: true)
23
23
  end
24
24
  end
25
25
  end
@@ -366,8 +366,14 @@ module Spree
366
366
  # If the master is invalid, the Product object will be assigned its errors
367
367
  def validate_master
368
368
  unless master.valid?
369
- master.errors.each do |att, error|
370
- errors.add(att, error)
369
+ if Gem::Requirement.new(">= 6.1").satisfied_by?(Rails.gem_version)
370
+ master.errors.each do |error|
371
+ errors.add(error.attribute, error.message)
372
+ end
373
+ else
374
+ master.errors.each do |att, error|
375
+ errors.add(att, error)
376
+ end
371
377
  end
372
378
  end
373
379
  end
@@ -1,11 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'spree/preferences/persistable'
4
+
3
5
  module Spree
4
6
  # Base class for all types of promotion action.
5
7
  #
6
8
  # PromotionActions perform the necessary tasks when a promotion is activated
7
9
  # by an event and determined to be eligible.
8
10
  class PromotionAction < Spree::Base
11
+ include Spree::Preferences::Persistable
9
12
  include Spree::SoftDeletable
10
13
 
11
14
  belongs_to :promotion, class_name: 'Spree::Promotion', inverse_of: :promotion_actions, optional: true
@@ -1,8 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'spree/preferences/persistable'
4
+
3
5
  module Spree
4
6
  # Base class for all promotion rules
5
7
  class PromotionRule < Spree::Base
8
+ include Spree::Preferences::Persistable
9
+
6
10
  belongs_to :promotion, class_name: 'Spree::Promotion', inverse_of: :promotion_rules, optional: true
7
11
 
8
12
  scope :of_type, ->(type) { where(type: type) }
@@ -48,6 +48,10 @@ module Spree
48
48
  return true if perform_after_create == false
49
49
  return true if transaction_id.present?
50
50
 
51
+ # This is needed otherwise set_perform_after_create_default callback
52
+ # will print a deprecation warning when save! creates a record
53
+ self.perform_after_create = false unless persisted?
54
+
51
55
  credit_cents = money.cents
52
56
 
53
57
  @perform_response = process!(credit_cents)
@@ -63,9 +67,7 @@ module Spree
63
67
  log_entries.build(details: perform_response.to_yaml)
64
68
 
65
69
  self.transaction_id = perform_response.authorization
66
- # This is needed otherwise set_perform_after_create_default callback
67
- # will print a deprecation warning when save! creates a record.
68
- self.perform_after_create = false unless persisted?
70
+
69
71
  save!
70
72
 
71
73
  update_order