spree_core 3.1.5 → 3.1.6

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 (215) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/concerns/spree/ransackable_attributes.rb +6 -1
  3. data/app/models/concerns/spree/user_methods.rb +10 -0
  4. data/app/models/spree/legacy_user.rb +0 -8
  5. data/app/models/spree/order.rb +1 -1
  6. data/app/models/spree/product.rb +8 -0
  7. data/app/models/spree/product/scopes.rb +7 -3
  8. data/app/models/spree/stock_transfer.rb +1 -1
  9. data/config/locales/en.yml +2 -0
  10. data/lib/spree/core/version.rb +1 -1
  11. data/spree_core.gemspec +2 -2
  12. metadata +11 -208
  13. data/spec/fixtures/microdata.html +0 -22
  14. data/spec/fixtures/microdata_itemref.html +0 -15
  15. data/spec/fixtures/microdata_no_itemscope.html +0 -20
  16. data/spec/fixtures/thinking-cat.jpg +0 -0
  17. data/spec/helpers/base_helper_spec.rb +0 -200
  18. data/spec/helpers/products_helper_spec.rb +0 -296
  19. data/spec/lib/calculated_adjustments_spec.rb +0 -7
  20. data/spec/lib/i18n_spec.rb +0 -123
  21. data/spec/lib/search/base_spec.rb +0 -86
  22. data/spec/lib/spree/core/controller_helpers/auth_spec.rb +0 -103
  23. data/spec/lib/spree/core/controller_helpers/order_spec.rb +0 -110
  24. data/spec/lib/spree/core/controller_helpers/search_spec.rb +0 -17
  25. data/spec/lib/spree/core/controller_helpers/store_spec.rb +0 -72
  26. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +0 -39
  27. data/spec/lib/spree/core/delegate_belongs_to_spec.rb +0 -22
  28. data/spec/lib/spree/core/importer/order_spec.rb +0 -605
  29. data/spec/lib/spree/core/number_generator_spec.rb +0 -175
  30. data/spec/lib/spree/core/token_generator_spec.rb +0 -24
  31. data/spec/lib/spree/core/validators/email_spec.rb +0 -53
  32. data/spec/lib/spree/core_spec.rb +0 -23
  33. data/spec/lib/spree/localized_number_spec.rb +0 -48
  34. data/spec/lib/spree/migrations_spec.rb +0 -36
  35. data/spec/lib/spree/money_spec.rb +0 -122
  36. data/spec/lib/tasks/exchanges_spec.rb +0 -136
  37. data/spec/mailers/order_mailer_spec.rb +0 -122
  38. data/spec/mailers/reimbursement_mailer_spec.rb +0 -47
  39. data/spec/mailers/shipment_mailer_spec.rb +0 -81
  40. data/spec/mailers/test_mailer_spec.rb +0 -38
  41. data/spec/models/option_type_prototype_spec.rb +0 -9
  42. data/spec/models/spree/ability_spec.rb +0 -251
  43. data/spec/models/spree/address_spec.rb +0 -291
  44. data/spec/models/spree/adjustable/adjuster/base_spec.rb +0 -10
  45. data/spec/models/spree/adjustable/adjuster/promotion_spec.rb +0 -211
  46. data/spec/models/spree/adjustable/adjuster/tax_spec.rb +0 -86
  47. data/spec/models/spree/adjustable/adjustments_updater_spec.rb +0 -26
  48. data/spec/models/spree/adjustment_spec.rb +0 -189
  49. data/spec/models/spree/app_configuration_spec.rb +0 -26
  50. data/spec/models/spree/asset_spec.rb +0 -28
  51. data/spec/models/spree/calculator/default_tax_spec.rb +0 -152
  52. data/spec/models/spree/calculator/flat_percent_item_total_spec.rb +0 -25
  53. data/spec/models/spree/calculator/flat_rate_spec.rb +0 -47
  54. data/spec/models/spree/calculator/flexi_rate_spec.rb +0 -41
  55. data/spec/models/spree/calculator/percent_on_line_item_spec.rb +0 -15
  56. data/spec/models/spree/calculator/price_sack_spec.rb +0 -30
  57. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +0 -51
  58. data/spec/models/spree/calculator/shipping.rb +0 -8
  59. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +0 -23
  60. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +0 -13
  61. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +0 -52
  62. data/spec/models/spree/calculator/shipping/per_item_spec.rb +0 -20
  63. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +0 -29
  64. data/spec/models/spree/calculator/tiered_flat_rate_spec.rb +0 -40
  65. data/spec/models/spree/calculator/tiered_percent_spec.rb +0 -51
  66. data/spec/models/spree/calculator_spec.rb +0 -69
  67. data/spec/models/spree/classification_spec.rb +0 -93
  68. data/spec/models/spree/concerns/display_money_spec.rb +0 -43
  69. data/spec/models/spree/concerns/user_methods_spec.rb +0 -55
  70. data/spec/models/spree/concerns/vat_price_calculation_spec.rb +0 -66
  71. data/spec/models/spree/country_spec.rb +0 -55
  72. data/spec/models/spree/credit_card_spec.rb +0 -328
  73. data/spec/models/spree/customer_return_spec.rb +0 -240
  74. data/spec/models/spree/exchange_spec.rb +0 -75
  75. data/spec/models/spree/gateway/bogus_simple.rb +0 -20
  76. data/spec/models/spree/gateway/bogus_spec.rb +0 -13
  77. data/spec/models/spree/gateway_spec.rb +0 -61
  78. data/spec/models/spree/image_spec.rb +0 -8
  79. data/spec/models/spree/inventory_unit_spec.rb +0 -225
  80. data/spec/models/spree/line_item_spec.rb +0 -327
  81. data/spec/models/spree/option_type_spec.rb +0 -14
  82. data/spec/models/spree/option_value_spec.rb +0 -18
  83. data/spec/models/spree/order/address_spec.rb +0 -50
  84. data/spec/models/spree/order/adjustments_spec.rb +0 -29
  85. data/spec/models/spree/order/callbacks_spec.rb +0 -42
  86. data/spec/models/spree/order/checkout_spec.rb +0 -782
  87. data/spec/models/spree/order/currency_updater_spec.rb +0 -32
  88. data/spec/models/spree/order/finalizing_spec.rb +0 -114
  89. data/spec/models/spree/order/helpers_spec.rb +0 -5
  90. data/spec/models/spree/order/payment_spec.rb +0 -214
  91. data/spec/models/spree/order/risk_assessment_spec.rb +0 -84
  92. data/spec/models/spree/order/shipments_spec.rb +0 -43
  93. data/spec/models/spree/order/state_machine_spec.rb +0 -211
  94. data/spec/models/spree/order/store_credit_spec.rb +0 -426
  95. data/spec/models/spree/order/tax_spec.rb +0 -84
  96. data/spec/models/spree/order/totals_spec.rb +0 -24
  97. data/spec/models/spree/order/updating_spec.rb +0 -18
  98. data/spec/models/spree/order/validations_spec.rb +0 -15
  99. data/spec/models/spree/order_contents_spec.rb +0 -297
  100. data/spec/models/spree/order_inventory_spec.rb +0 -238
  101. data/spec/models/spree/order_merger_spec.rb +0 -135
  102. data/spec/models/spree/order_spec.rb +0 -967
  103. data/spec/models/spree/order_updater_spec.rb +0 -305
  104. data/spec/models/spree/payment/gateway_options_spec.rb +0 -127
  105. data/spec/models/spree/payment/store_credit_spec.rb +0 -60
  106. data/spec/models/spree/payment_method/store_credit_spec.rb +0 -291
  107. data/spec/models/spree/payment_method_spec.rb +0 -103
  108. data/spec/models/spree/payment_spec.rb +0 -919
  109. data/spec/models/spree/preference_spec.rb +0 -80
  110. data/spec/models/spree/preferences/configuration_spec.rb +0 -30
  111. data/spec/models/spree/preferences/preferable_spec.rb +0 -348
  112. data/spec/models/spree/preferences/scoped_store_spec.rb +0 -58
  113. data/spec/models/spree/preferences/store_spec.rb +0 -46
  114. data/spec/models/spree/price_spec.rb +0 -128
  115. data/spec/models/spree/product/scopes_spec.rb +0 -183
  116. data/spec/models/spree/product_duplicator_spec.rb +0 -103
  117. data/spec/models/spree/product_filter_spec.rb +0 -26
  118. data/spec/models/spree/product_option_type_spec.rb +0 -9
  119. data/spec/models/spree/product_promotion_rule_spec.rb +0 -9
  120. data/spec/models/spree/product_property_spec.rb +0 -22
  121. data/spec/models/spree/product_spec.rb +0 -540
  122. data/spec/models/spree/promotion/actions/create_adjustment_spec.rb +0 -50
  123. data/spec/models/spree/promotion/actions/create_item_adjustments_spec.rb +0 -148
  124. data/spec/models/spree/promotion/actions/create_line_items_spec.rb +0 -86
  125. data/spec/models/spree/promotion/actions/free_shipping_spec.rb +0 -36
  126. data/spec/models/spree/promotion/rules/first_order_spec.rb +0 -75
  127. data/spec/models/spree/promotion/rules/item_total_spec.rb +0 -282
  128. data/spec/models/spree/promotion/rules/one_use_per_user_spec.rb +0 -42
  129. data/spec/models/spree/promotion/rules/option_value_spec.rb +0 -90
  130. data/spec/models/spree/promotion/rules/product_spec.rb +0 -143
  131. data/spec/models/spree/promotion/rules/taxon_spec.rb +0 -102
  132. data/spec/models/spree/promotion/rules/user_logged_in_spec.rb +0 -27
  133. data/spec/models/spree/promotion/rules/user_spec.rb +0 -45
  134. data/spec/models/spree/promotion_action_spec.rb +0 -10
  135. data/spec/models/spree/promotion_category_spec.rb +0 -17
  136. data/spec/models/spree/promotion_handler/cart_spec.rb +0 -102
  137. data/spec/models/spree/promotion_handler/coupon_spec.rb +0 -323
  138. data/spec/models/spree/promotion_handler/free_shipping_spec.rb +0 -48
  139. data/spec/models/spree/promotion_handler/page_spec.rb +0 -44
  140. data/spec/models/spree/promotion_rule_spec.rb +0 -29
  141. data/spec/models/spree/promotion_rule_taxon_spec.rb +0 -9
  142. data/spec/models/spree/promotion_rule_user_spec.rb +0 -9
  143. data/spec/models/spree/promotion_spec.rb +0 -644
  144. data/spec/models/spree/property_prototype_spec.rb +0 -9
  145. data/spec/models/spree/property_spec.rb +0 -5
  146. data/spec/models/spree/prototype_spec.rb +0 -5
  147. data/spec/models/spree/prototype_taxon_spec.rb +0 -9
  148. data/spec/models/spree/refund_reason_spec.rb +0 -7
  149. data/spec/models/spree/refund_spec.rb +0 -195
  150. data/spec/models/spree/reimbursement/credit_spec.rb +0 -36
  151. data/spec/models/spree/reimbursement/reimbursement_type_engine_spec.rb +0 -140
  152. data/spec/models/spree/reimbursement/reimbursement_type_validator_spec.rb +0 -83
  153. data/spec/models/spree/reimbursement_performer_spec.rb +0 -30
  154. data/spec/models/spree/reimbursement_spec.rb +0 -188
  155. data/spec/models/spree/reimbursement_tax_calculator_spec.rb +0 -63
  156. data/spec/models/spree/reimbursement_type/credit_spec.rb +0 -53
  157. data/spec/models/spree/reimbursement_type/exchange_spec.rb +0 -46
  158. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +0 -55
  159. data/spec/models/spree/reimbursement_type/store_credit_spec.rb +0 -101
  160. data/spec/models/spree/return_authorization_reason_spec.rb +0 -7
  161. data/spec/models/spree/return_authorization_spec.rb +0 -230
  162. data/spec/models/spree/return_item/eligibility_validator/default_spec.rb +0 -77
  163. data/spec/models/spree/return_item/eligibility_validator/inventory_shipped_spec.rb +0 -58
  164. data/spec/models/spree/return_item/eligibility_validator/no_reimbursements_spec.rb +0 -61
  165. data/spec/models/spree/return_item/eligibility_validator/order_completed_spec.rb +0 -32
  166. data/spec/models/spree/return_item/eligibility_validator/rma_required_spec.rb +0 -29
  167. data/spec/models/spree/return_item/eligibility_validator/time_since_purchase_spec.rb +0 -35
  168. data/spec/models/spree/return_item/exchange_variant_eligibility/same_option_value_spec.rb +0 -65
  169. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +0 -43
  170. data/spec/models/spree/return_item_spec.rb +0 -731
  171. data/spec/models/spree/returns_calculator_spec.rb +0 -14
  172. data/spec/models/spree/role_spec.rb +0 -7
  173. data/spec/models/spree/shipment_spec.rb +0 -740
  174. data/spec/models/spree/shipping_calculator_spec.rb +0 -45
  175. data/spec/models/spree/shipping_category_spec.rb +0 -19
  176. data/spec/models/spree/shipping_method_spec.rb +0 -95
  177. data/spec/models/spree/shipping_rate_spec.rb +0 -140
  178. data/spec/models/spree/state_spec.rb +0 -29
  179. data/spec/models/spree/stock/availability_validator_spec.rb +0 -36
  180. data/spec/models/spree/stock/content_item_spec.rb +0 -31
  181. data/spec/models/spree/stock/coordinator_spec.rb +0 -51
  182. data/spec/models/spree/stock/differentiator_spec.rb +0 -39
  183. data/spec/models/spree/stock/estimator_spec.rb +0 -202
  184. data/spec/models/spree/stock/inventory_unit_builder_spec.rb +0 -38
  185. data/spec/models/spree/stock/package_spec.rb +0 -194
  186. data/spec/models/spree/stock/packer_spec.rb +0 -70
  187. data/spec/models/spree/stock/prioritizer_spec.rb +0 -125
  188. data/spec/models/spree/stock/quantifier_spec.rb +0 -126
  189. data/spec/models/spree/stock/splitter/backordered_spec.rb +0 -29
  190. data/spec/models/spree/stock/splitter/base_spec.rb +0 -21
  191. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +0 -47
  192. data/spec/models/spree/stock/splitter/weight_spec.rb +0 -32
  193. data/spec/models/spree/stock_item_spec.rb +0 -428
  194. data/spec/models/spree/stock_location_spec.rb +0 -243
  195. data/spec/models/spree/stock_movement_spec.rb +0 -56
  196. data/spec/models/spree/stock_transfer_spec.rb +0 -50
  197. data/spec/models/spree/store_credit_event_spec.rb +0 -101
  198. data/spec/models/spree/store_credit_spec.rb +0 -786
  199. data/spec/models/spree/store_spec.rb +0 -78
  200. data/spec/models/spree/tax_category_spec.rb +0 -32
  201. data/spec/models/spree/tax_rate_spec.rb +0 -542
  202. data/spec/models/spree/taxon_spec.rb +0 -74
  203. data/spec/models/spree/taxonomy_spec.rb +0 -18
  204. data/spec/models/spree/tracker_spec.rb +0 -21
  205. data/spec/models/spree/user_spec.rb +0 -203
  206. data/spec/models/spree/variant_spec.rb +0 -795
  207. data/spec/models/spree/zone_member_spec.rb +0 -38
  208. data/spec/models/spree/zone_spec.rb +0 -470
  209. data/spec/spec_helper.rb +0 -77
  210. data/spec/support/big_decimal.rb +0 -5
  211. data/spec/support/concerns/adjustment_source.rb +0 -23
  212. data/spec/support/concerns/default_price.rb +0 -37
  213. data/spec/support/rake.rb +0 -13
  214. data/spec/support/test_gateway.rb +0 -2
  215. data/spec/validators/db_maximum_length_validator_spec.rb +0 -22
@@ -1,26 +0,0 @@
1
- require 'spec_helper'
2
- require 'spree/core/product_filters'
3
-
4
- describe 'product filters', :type => :model do
5
- # Regression test for #1709
6
- context 'finds products filtered by brand' do
7
- let(:product) { create(:product) }
8
- before do
9
- property = Spree::Property.create!(:name => "brand", :presentation => "brand")
10
- product.set_property("brand", "Nike")
11
- end
12
-
13
- it "does not attempt to call value method on Arel::Table" do
14
- expect { Spree::Core::ProductFilters.brand_filter }.not_to raise_error
15
- end
16
-
17
- it "can find products in the 'Nike' brand" do
18
- expect(Spree::Product.brand_any("Nike")).to include(product)
19
- end
20
- it "sorts products without brand specified" do
21
- product.set_property("brand", "Nike")
22
- create(:product).set_property("brand", nil)
23
- expect { Spree::Core::ProductFilters.brand_filter[:labels] }.not_to raise_error
24
- end
25
- end
26
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Spree::ProductOptionType do
4
- describe 'Validations' do
5
- it { is_expected.to validate_presence_of(:product) }
6
- it { is_expected.to validate_presence_of(:option_type) }
7
- it { is_expected.to validate_uniqueness_of(:product_id).scoped_to(:option_type_id).allow_nil }
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Spree::ProductPromotionRule do
4
- describe 'Validations' do
5
- it { is_expected.to validate_presence_of(:product) }
6
- it { is_expected.to validate_presence_of(:promotion_rule) }
7
- it { is_expected.to validate_uniqueness_of(:product_id).scoped_to(:promotion_rule_id).allow_nil }
8
- end
9
- end
@@ -1,22 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Spree::ProductProperty, :type => :model do
4
- context "touching" do
5
- it "should update product" do
6
- pp = create(:product_property)
7
- expect(pp.product).to receive(:touch)
8
- pp.touch
9
- end
10
- end
11
-
12
- context 'property_name=' do
13
- before do
14
- @pp = create(:product_property)
15
- end
16
-
17
- it "should assign property" do
18
- @pp.property_name = "Size"
19
- expect(@pp.property.name).to eq('Size')
20
- end
21
- end
22
- end
@@ -1,540 +0,0 @@
1
- # coding: UTF-8
2
-
3
- require 'spec_helper'
4
-
5
- module ThirdParty
6
- class Extension < Spree::Base
7
- # nasty hack so we don't have to create a table to back this fake model
8
- self.table_name = 'spree_products'
9
- end
10
- end
11
-
12
- describe Spree::Product, :type => :model do
13
-
14
- describe 'Associations' do
15
- it 'should have many promotions' do
16
- is_expected.to have_many(:promotions).
17
- class_name('Spree::Promotion').through(:promotion_rules)
18
- end
19
-
20
- it 'should have many possible_promotions' do
21
- is_expected.to have_many(:possible_promotions).
22
- class_name('Spree::Promotion').through(:promotion_rules).source(:promotion)
23
- end
24
-
25
- it do
26
- is_expected.to have_many(:variants).
27
- class_name('Spree::Variant').
28
- inverse_of(:product).
29
- conditions(is_master: false).
30
- order(:position)
31
- end
32
-
33
- it do
34
- is_expected.to have_many(:variants_including_master).
35
- class_name('Spree::Variant').
36
- inverse_of(:product).
37
- order(:position)
38
- end
39
- end
40
-
41
- context 'product instance' do
42
- let(:product) { create(:product) }
43
- let(:variant) { create(:variant, :product => product) }
44
-
45
- context '#duplicate' do
46
- before do
47
- allow(product).to receive_messages :taxons => [create(:taxon)]
48
- end
49
-
50
- it 'duplicates product' do
51
- clone = product.duplicate
52
- expect(clone.name).to eq('COPY OF ' + product.name)
53
- expect(clone.master.sku).to eq('COPY OF ' + product.master.sku)
54
- expect(clone.taxons).to eq(product.taxons)
55
- expect(clone.images.size).to eq(product.images.size)
56
- end
57
-
58
- it 'calls #duplicate_extra' do
59
- expect_any_instance_of(Spree::Product).to receive(:duplicate_extra)
60
- .with(product)
61
- expect(product).to_not receive(:duplicate_extra)
62
- product.duplicate
63
- end
64
- end
65
-
66
- context "master variant" do
67
-
68
- context "when master variant changed" do
69
- before do
70
- product.master.sku = "Something changed"
71
- end
72
-
73
- it "saves the master" do
74
- expect(product.master).to receive(:save!)
75
- product.save
76
- end
77
- end
78
-
79
- context "when master default price changed" do
80
- before do
81
- master = product.master
82
- master.default_price.price = 11
83
- master.save!
84
- product.master.default_price.price = 12
85
- end
86
-
87
- it "saves the master" do
88
- expect(product.master).to receive(:save!)
89
- product.save
90
- end
91
-
92
- it "saves the default price" do
93
- expect(product.master.default_price).to receive(:save)
94
- product.save
95
- end
96
- end
97
-
98
- context "when master variant and price haven't changed" do
99
- it "does not save the master" do
100
- expect(product.master).not_to receive(:save!)
101
- product.save
102
- end
103
- end
104
- end
105
-
106
- context "product has no variants" do
107
- context "#destroy" do
108
- it "should set deleted_at value" do
109
- product.destroy
110
- expect(product.deleted_at).not_to be_nil
111
- expect(product.master.reload.deleted_at).not_to be_nil
112
- end
113
- end
114
- end
115
-
116
- context "product has variants" do
117
- before do
118
- create(:variant, :product => product)
119
- end
120
-
121
- context "#destroy" do
122
- it "should set deleted_at value" do
123
- product.destroy
124
- expect(product.deleted_at).not_to be_nil
125
- expect(product.variants_including_master.all? { |v| !v.deleted_at.nil? }).to be true
126
- end
127
- end
128
- end
129
-
130
- context "#price" do
131
- # Regression test for #1173
132
- it 'strips non-price characters' do
133
- product.price = "$10"
134
- expect(product.price).to eq(10.0)
135
- end
136
- end
137
-
138
- context "#display_price" do
139
- before { product.price = 10.55 }
140
-
141
- it "shows the amount" do
142
- expect(product.display_price.to_s).to eq("$10.55")
143
- end
144
-
145
- context "with currency set to JPY" do
146
- before do
147
- product.master.default_price.currency = 'JPY'
148
- product.master.default_price.save!
149
- Spree::Config[:currency] = 'JPY'
150
- end
151
-
152
- it "displays the currency in yen" do
153
- expect(product.display_price.to_s).to eq("¥11")
154
- end
155
- end
156
- end
157
-
158
- context "#available?" do
159
- it "should be available if date is in the past" do
160
- product.available_on = 1.day.ago
161
- expect(product).to be_available
162
- end
163
-
164
- it "should not be available if date is nil or in the future" do
165
- product.available_on = nil
166
- expect(product).not_to be_available
167
-
168
- product.available_on = 1.day.from_now
169
- expect(product).not_to be_available
170
- end
171
-
172
- it "should not be available if destroyed" do
173
- product.destroy
174
- expect(product).not_to be_available
175
- end
176
- end
177
-
178
- context "#can_supply?" do
179
- it "should be true" do
180
- expect(product.can_supply?).to be(true)
181
- end
182
-
183
- it "should be false" do
184
- product.variants_including_master.each { |v| v.stock_items.update_all count_on_hand: 0, backorderable: false }
185
- expect(product.can_supply?).to be(false)
186
- end
187
- end
188
-
189
- context "variants_and_option_values" do
190
- let!(:high) { create(:variant, product: product) }
191
- let!(:low) { create(:variant, product: product) }
192
-
193
- before { high.option_values.destroy_all }
194
-
195
- it "returns only variants with option values" do
196
- expect(product.variants_and_option_values).to eq([low])
197
- end
198
- end
199
-
200
- context "has stock movements" do
201
- let(:variant) { product.master }
202
- let(:stock_item) { variant.stock_items.first }
203
-
204
- it "doesnt raise ReadOnlyRecord error" do
205
- Spree::StockMovement.create!(stock_item: stock_item, quantity: 1)
206
- expect { product.destroy }.not_to raise_error
207
- end
208
- end
209
-
210
- # Regression test for #3737
211
- context "has stock items" do
212
- it "can retrieve stock items" do
213
- expect(product.master.stock_items.first).not_to be_nil
214
- expect(product.stock_items.first).not_to be_nil
215
- end
216
- end
217
-
218
- context "slugs" do
219
-
220
- it "normalizes slug on update validation" do
221
- product.slug = "hey//joe"
222
- product.valid?
223
- expect(product.slug).not_to match "/"
224
- end
225
-
226
- context "when product destroyed" do
227
-
228
- it "renames slug" do
229
- expect { product.destroy }.to change { product.slug }
230
- end
231
-
232
- context "when slug is already at or near max length" do
233
-
234
- before do
235
- product.slug = "x" * 255
236
- product.save!
237
- end
238
-
239
- it "truncates renamed slug to ensure it remains within length limit" do
240
- product.destroy
241
- expect(product.slug.length).to eq 255
242
- end
243
-
244
- end
245
-
246
- end
247
-
248
- it "validates slug uniqueness" do
249
- existing_product = product
250
- new_product = create(:product)
251
- new_product.slug = existing_product.slug
252
-
253
- expect(new_product.valid?).to eq false
254
- end
255
-
256
- it "falls back to 'name-sku' for slug if regular name-based slug already in use" do
257
- product1 = build(:product)
258
- product1.name = "test"
259
- product1.sku = "123"
260
- product1.save!
261
-
262
- product2 = build(:product)
263
- product2.name = "test"
264
- product2.sku = "456"
265
- product2.save!
266
-
267
- expect(product2.slug).to eq 'test-456'
268
- end
269
- end
270
-
271
- context "hard deletion" do
272
- it "doesnt raise ActiveRecordError error" do
273
- expect { product.really_destroy! }.to_not raise_error
274
- end
275
- end
276
-
277
- context 'history' do
278
- before(:each) do
279
- @product = create(:product)
280
- end
281
-
282
- it 'should keep the history when the product is destroyed' do
283
- @product.destroy
284
-
285
- expect(@product.slugs.with_deleted).to_not be_empty
286
- end
287
-
288
- it 'should update the history when the product is restored' do
289
- @product.destroy
290
-
291
- @product.restore(recursive: true)
292
-
293
- latest_slug = @product.slugs.find_by slug: @product.slug
294
- expect(latest_slug).to_not be_nil
295
- end
296
- end
297
- end
298
-
299
- context "properties" do
300
- let(:product) { create(:product) }
301
-
302
- it "should properly assign properties" do
303
- product.set_property('the_prop', 'value1')
304
- expect(product.property('the_prop')).to eq('value1')
305
-
306
- product.set_property('the_prop', 'value2')
307
- expect(product.property('the_prop')).to eq('value2')
308
- end
309
-
310
- it "should not create duplicate properties when set_property is called" do
311
- expect {
312
- product.set_property('the_prop', 'value2')
313
- product.save
314
- product.reload
315
- }.not_to change(product.properties, :length)
316
-
317
- expect {
318
- product.set_property('the_prop_new', 'value')
319
- product.save
320
- product.reload
321
- expect(product.property('the_prop_new')).to eq('value')
322
- }.to change { product.properties.length }.by(1)
323
- end
324
-
325
- context 'optional property_presentation' do
326
- subject { Spree::Property.where(name: 'foo').first.presentation }
327
- let(:name) { 'foo' }
328
- let(:presentation) { 'baz' }
329
-
330
- describe 'is not used' do
331
- before { product.set_property(name, 'bar') }
332
- it { is_expected.to eq name }
333
- end
334
-
335
- describe 'is used' do
336
- before { product.set_property(name, 'bar', presentation) }
337
- it { is_expected.to eq presentation }
338
- end
339
- end
340
-
341
- # Regression test for #2455
342
- it "should not overwrite properties' presentation names" do
343
- Spree::Property.where(:name => 'foo').first_or_create!(:presentation => "Foo's Presentation Name")
344
- product.set_property('foo', 'value1')
345
- product.set_property('bar', 'value2')
346
- expect(Spree::Property.where(:name => 'foo').first.presentation).to eq("Foo's Presentation Name")
347
- expect(Spree::Property.where(:name => 'bar').first.presentation).to eq("bar")
348
- end
349
-
350
- # Regression test for #4416
351
- context "#possible_promotions" do
352
- let!(:possible_promotion) { create(:promotion, advertise: true, starts_at: 1.day.ago) }
353
- let!(:unadvertised_promotion) { create(:promotion, advertise: false, starts_at: 1.day.ago) }
354
- let!(:inactive_promotion) { create(:promotion, advertise: true, starts_at: 1.day.since) }
355
-
356
- before do
357
- product.promotion_rules.create!(promotion: possible_promotion)
358
- product.promotion_rules.create!(promotion: unadvertised_promotion)
359
- product.promotion_rules.create!(promotion: inactive_promotion)
360
- end
361
-
362
- it "lists the promotion as a possible promotion" do
363
- expect(product.possible_promotions).to include(possible_promotion)
364
- expect(product.possible_promotions).to_not include(unadvertised_promotion)
365
- expect(product.possible_promotions).to_not include(inactive_promotion)
366
- end
367
- end
368
- end
369
-
370
- context '#create' do
371
- let!(:prototype) { create(:prototype) }
372
- let!(:product) { Spree::Product.new(name: "Foo", price: 1.99, shipping_category_id: create(:shipping_category).id) }
373
-
374
- before { product.prototype_id = prototype.id }
375
-
376
- context "when prototype is supplied" do
377
- it "should create properties based on the prototype" do
378
- product.save
379
- expect(product.properties.count).to eq(1)
380
- end
381
- end
382
-
383
- context "when prototype with option types is supplied" do
384
- def build_option_type_with_values(name, values)
385
- values.each_with_object(create :option_type, name: name) do |val, ot|
386
- ot.option_values.create(name: val.downcase, presentation: val)
387
- end
388
- end
389
-
390
- let(:prototype) do
391
- size = build_option_type_with_values("size", %w(Small Medium Large))
392
- create(:prototype, :name => "Size", :option_types => [ size ])
393
- end
394
-
395
- let(:option_values_hash) do
396
- hash = {}
397
- prototype.option_types.each do |i|
398
- hash[i.id.to_s] = i.option_value_ids
399
- end
400
- hash
401
- end
402
-
403
- it "should create option types based on the prototype" do
404
- product.save
405
- expect(product.option_type_ids.length).to eq(1)
406
- expect(product.option_type_ids).to eq(prototype.option_type_ids)
407
- end
408
-
409
- it "should create product option types based on the prototype" do
410
- product.save
411
- expect(product.product_option_types.pluck(:option_type_id)).to eq(prototype.option_type_ids)
412
- end
413
-
414
- it "should create variants from an option values hash with one option type" do
415
- product.option_values_hash = option_values_hash
416
- product.save
417
- expect(product.variants.length).to eq(3)
418
- end
419
-
420
- it "should still create variants when option_values_hash is given but prototype id is nil" do
421
- product.option_values_hash = option_values_hash
422
- product.prototype_id = nil
423
- product.save
424
- expect(product.option_type_ids.length).to eq(1)
425
- expect(product.option_type_ids).to eq(prototype.option_type_ids)
426
- expect(product.variants.length).to eq(3)
427
- end
428
-
429
- it "should create variants from an option values hash with multiple option types" do
430
- color = build_option_type_with_values("color", %w(Red Green Blue))
431
- logo = build_option_type_with_values("logo", %w(Ruby Rails Nginx))
432
- option_values_hash[color.id.to_s] = color.option_value_ids
433
- option_values_hash[logo.id.to_s] = logo.option_value_ids
434
- product.option_values_hash = option_values_hash
435
- product.save
436
- product.reload
437
- expect(product.option_type_ids.length).to eq(3)
438
- expect(product.variants.length).to eq(27)
439
- end
440
- end
441
- end
442
-
443
- context "#images" do
444
- let(:product) { create(:product) }
445
- let(:image) { File.open(File.expand_path('../../../fixtures/thinking-cat.jpg', __FILE__)) }
446
- let(:params) { {:viewable_id => product.master.id, :viewable_type => 'Spree::Variant', :attachment => image, :alt => "position 2", :position => 2} }
447
-
448
- before do
449
- Spree::Image.create(params)
450
- Spree::Image.create(params.merge({:alt => "position 1", :position => 1}))
451
- Spree::Image.create(params.merge({:viewable_type => 'ThirdParty::Extension', :alt => "position 1", :position => 2}))
452
- end
453
-
454
- it "only looks for variant images" do
455
- expect(product.images.size).to eq(2)
456
- end
457
-
458
- it "should be sorted by position" do
459
- expect(product.images.pluck(:alt)).to eq(["position 1", "position 2"])
460
- end
461
- end
462
-
463
- # Regression tests for #2352
464
- context "classifications and taxons" do
465
- it "is joined through classifications" do
466
- reflection = Spree::Product.reflect_on_association(:taxons)
467
- expect(reflection.options[:through]).to eq(:classifications)
468
- end
469
-
470
- it "will delete all classifications" do
471
- reflection = Spree::Product.reflect_on_association(:classifications)
472
- expect(reflection.options[:dependent]).to eq(:delete_all)
473
- end
474
- end
475
-
476
- context '#total_on_hand' do
477
- let(:product) { create(:product) }
478
-
479
- it 'should be infinite if track_inventory_levels is false' do
480
- Spree::Config[:track_inventory_levels] = false
481
- expect(build(:product, :variants_including_master => [build(:master_variant)]).total_on_hand).to eql(Float::INFINITY)
482
- end
483
-
484
- it 'should be infinite if variant is on demand' do
485
- Spree::Config[:track_inventory_levels] = true
486
- expect(build(:product, :variants_including_master => [build(:on_demand_master_variant)]).total_on_hand).to eql(Float::INFINITY)
487
- end
488
-
489
- it 'should return sum of stock items count_on_hand' do
490
- product.stock_items.first.set_count_on_hand 5
491
- product.variants_including_master(true) # force load association
492
- expect(product.total_on_hand).to eql(5)
493
- end
494
-
495
- it 'should return sum of stock items count_on_hand when variants_including_master is not loaded' do
496
- product.stock_items.first.set_count_on_hand 5
497
- expect(product.reload.total_on_hand).to eql(5)
498
- end
499
- end
500
-
501
- # Regression spec for https://github.com/spree/spree/issues/5588
502
- context '#validate_master when duplicate SKUs entered' do
503
- let!(:first_product) { create(:product, sku: 'a-sku') }
504
- let(:second_product) { build(:product, sku: 'a-sku') }
505
-
506
- subject { second_product }
507
- it { is_expected.to be_invalid }
508
- end
509
-
510
- it "initializes a master variant when building a product" do
511
- product = Spree::Product.new
512
- expect(product.master.is_master).to be true
513
- end
514
-
515
- context "#discontinue!" do
516
- let(:product) { create(:product, sku: 'a-sku') }
517
-
518
- it "sets the discontinued" do
519
- product.discontinue!
520
- product.reload
521
- expect(product.discontinued?).to be(true)
522
- end
523
-
524
- it "changes updated_at" do
525
- expect { product.discontinue! }.to change { product.updated_at }
526
- end
527
- end
528
-
529
- context "#discontinued?" do
530
- let(:product_live) { build(:product, sku: "a-sku") }
531
- it "should be false" do
532
- expect(product_live.discontinued?).to be(false)
533
- end
534
-
535
- let(:product_discontinued) { build(:product, sku: "a-sku", discontinue_on: Time.now - 1.day) }
536
- it "should be true" do
537
- expect(product_discontinued.discontinued?).to be(true)
538
- end
539
- end
540
- end