solidus_backend 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +6 -0
  3. data/Rakefile +15 -0
  4. data/script/rails +9 -0
  5. data/solidus_backend.gemspec +30 -0
  6. data/spec/controllers/spree/admin/base_controller_spec.rb +24 -0
  7. data/spec/controllers/spree/admin/cancellations_controller_spec.rb +77 -0
  8. data/spec/controllers/spree/admin/customer_returns_controller_spec.rb +234 -0
  9. data/spec/controllers/spree/admin/general_settings_controller_spec.rb +41 -0
  10. data/spec/controllers/spree/admin/missing_products_controller_spec.rb +18 -0
  11. data/spec/controllers/spree/admin/orders/customer_details_controller_spec.rb +80 -0
  12. data/spec/controllers/spree/admin/orders_controller_spec.rb +460 -0
  13. data/spec/controllers/spree/admin/payment_methods_controller_spec.rb +49 -0
  14. data/spec/controllers/spree/admin/payments_controller_spec.rb +175 -0
  15. data/spec/controllers/spree/admin/product_properties_controller_spec.rb +69 -0
  16. data/spec/controllers/spree/admin/products_controller_spec.rb +162 -0
  17. data/spec/controllers/spree/admin/promotion_actions_controller_spec.rb +21 -0
  18. data/spec/controllers/spree/admin/promotion_codes_controller_spec.rb +18 -0
  19. data/spec/controllers/spree/admin/promotion_rules_controller_spec.rb +21 -0
  20. data/spec/controllers/spree/admin/promotions_controller_spec.rb +122 -0
  21. data/spec/controllers/spree/admin/refunds_controller_spec.rb +32 -0
  22. data/spec/controllers/spree/admin/reimbursements_controller_spec.rb +124 -0
  23. data/spec/controllers/spree/admin/reports_controller_spec.rb +134 -0
  24. data/spec/controllers/spree/admin/resource_controller_spec.rb +166 -0
  25. data/spec/controllers/spree/admin/return_authorizations_controller_spec.rb +240 -0
  26. data/spec/controllers/spree/admin/return_items_controller_spec.rb +27 -0
  27. data/spec/controllers/spree/admin/root_controller_spec.rb +41 -0
  28. data/spec/controllers/spree/admin/search_controller_spec.rb +104 -0
  29. data/spec/controllers/spree/admin/shipping_methods_controller_spec.rb +14 -0
  30. data/spec/controllers/spree/admin/stock_items_controller_spec.rb +50 -0
  31. data/spec/controllers/spree/admin/stock_locations_controller_spec.rb +41 -0
  32. data/spec/controllers/spree/admin/stock_transfers_controller_spec.rb +351 -0
  33. data/spec/controllers/spree/admin/store_credits_controller_spec.rb +309 -0
  34. data/spec/controllers/spree/admin/users_controller_spec.rb +257 -0
  35. data/spec/controllers/spree/admin/variants_controller_spec.rb +32 -0
  36. data/spec/features/admin/configuration/analytics_tracker_spec.rb +50 -0
  37. data/spec/features/admin/configuration/countries_spec.rb +22 -0
  38. data/spec/features/admin/configuration/general_settings_spec.rb +45 -0
  39. data/spec/features/admin/configuration/payment_methods_spec.rb +124 -0
  40. data/spec/features/admin/configuration/shipping_methods_spec.rb +64 -0
  41. data/spec/features/admin/configuration/states_spec.rb +64 -0
  42. data/spec/features/admin/configuration/stock_locations_spec.rb +50 -0
  43. data/spec/features/admin/configuration/tax_categories_spec.rb +56 -0
  44. data/spec/features/admin/configuration/tax_rates_spec.rb +30 -0
  45. data/spec/features/admin/configuration/taxonomies_spec.rb +52 -0
  46. data/spec/features/admin/configuration/zones_spec.rb +39 -0
  47. data/spec/features/admin/homepage_spec.rb +78 -0
  48. data/spec/features/admin/locale_spec.rb +30 -0
  49. data/spec/features/admin/orders/adjustments_promotions_spec.rb +53 -0
  50. data/spec/features/admin/orders/adjustments_spec.rb +126 -0
  51. data/spec/features/admin/orders/cancelling_and_resuming_spec.rb +48 -0
  52. data/spec/features/admin/orders/cancelling_inventory_spec.rb +48 -0
  53. data/spec/features/admin/orders/customer_details_spec.rb +163 -0
  54. data/spec/features/admin/orders/line_items_spec.rb +50 -0
  55. data/spec/features/admin/orders/listing_spec.rb +130 -0
  56. data/spec/features/admin/orders/log_entries_spec.rb +55 -0
  57. data/spec/features/admin/orders/new_order_spec.rb +185 -0
  58. data/spec/features/admin/orders/order_details_spec.rb +533 -0
  59. data/spec/features/admin/orders/payments_spec.rb +234 -0
  60. data/spec/features/admin/orders/risk_analysis_spec.rb +47 -0
  61. data/spec/features/admin/orders/shipments_spec.rb +65 -0
  62. data/spec/features/admin/payments/store_credits_spec.rb +21 -0
  63. data/spec/features/admin/products/edit/images_spec.rb +87 -0
  64. data/spec/features/admin/products/edit/products_spec.rb +66 -0
  65. data/spec/features/admin/products/edit/taxons_spec.rb +43 -0
  66. data/spec/features/admin/products/edit/variants_spec.rb +61 -0
  67. data/spec/features/admin/products/option_types_spec.rb +114 -0
  68. data/spec/features/admin/products/products_spec.rb +395 -0
  69. data/spec/features/admin/products/properties_spec.rb +139 -0
  70. data/spec/features/admin/products/prototypes_spec.rb +110 -0
  71. data/spec/features/admin/products/stock_management_spec.rb +82 -0
  72. data/spec/features/admin/products/variant_spec.rb +51 -0
  73. data/spec/features/admin/promotion_adjustments_spec.rb +220 -0
  74. data/spec/features/admin/promotions/option_value_rule_spec.rb +65 -0
  75. data/spec/features/admin/promotions/tiered_calculator_spec.rb +69 -0
  76. data/spec/features/admin/reports_spec.rb +61 -0
  77. data/spec/features/admin/stock_transfer_spec.rb +104 -0
  78. data/spec/features/admin/store_credits_spec.rb +82 -0
  79. data/spec/features/admin/taxons_spec.rb +31 -0
  80. data/spec/features/admin/users_spec.rb +275 -0
  81. data/spec/helpers/admin/base_helper_spec.rb +18 -0
  82. data/spec/helpers/admin/navigation_helper_spec.rb +73 -0
  83. data/spec/helpers/admin/reimbursements_helper_spec.rb +34 -0
  84. data/spec/helpers/admin/stock_movements_helper_spec.rb +29 -0
  85. data/spec/helpers/admin/store_credit_events_helper_spec.rb +95 -0
  86. data/spec/helpers/promotion_rules_helper_spec.rb +12 -0
  87. data/spec/spec_helper.rb +116 -0
  88. data/spec/support/appear_before_matcher.rb +8 -0
  89. data/spec/support/ror_ringer.jpeg +0 -0
  90. data/spec/test_views/spree/admin/widgets/edit.html.erb +1 -0
  91. data/spec/test_views/spree/admin/widgets/new.html.erb +1 -0
  92. metadata +96 -6
@@ -0,0 +1,114 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Option Types", :type => :feature do
4
+ stub_authorization!
5
+
6
+ before(:each) do
7
+ visit spree.admin_path
8
+ click_link "Products"
9
+ end
10
+
11
+ context "listing option types" do
12
+ it "should list existing option types" do
13
+ create(:option_type, :name => "tshirt-color", :presentation => "Color")
14
+ create(:option_type, :name => "tshirt-size", :presentation => "Size")
15
+
16
+ click_link "Option Types"
17
+ within("table#listing_option_types") do
18
+ expect(page).to have_content("Color")
19
+ expect(page).to have_content("tshirt-color")
20
+ expect(page).to have_content("Size")
21
+ expect(page).to have_content("tshirt-size")
22
+ end
23
+ end
24
+ end
25
+
26
+ context "creating a new option type" do
27
+ it "should allow an admin to create a new option type", :js => true do
28
+ click_link "Option Types"
29
+ click_link "new_option_type_link"
30
+ expect(page).to have_content("NEW OPTION TYPE")
31
+ fill_in "option_type_name", :with => "shirt colors"
32
+ fill_in "option_type_presentation", :with => "colors"
33
+ click_button "Create"
34
+ expect(page).to have_content("successfully created!")
35
+
36
+ page.find('#option_type_option_values_attributes_0_name').set('color')
37
+ page.find('#option_type_option_values_attributes_0_presentation').set('black')
38
+
39
+ click_button "Update"
40
+ expect(page).to have_content("successfully updated!")
41
+ end
42
+ end
43
+
44
+ context "editing an existing option type" do
45
+ it "should allow an admin to update an existing option type" do
46
+ create(:option_type, :name => "tshirt-color", :presentation => "Color")
47
+ create(:option_type, :name => "tshirt-size", :presentation => "Size")
48
+ click_link "Option Types"
49
+ within('table#listing_option_types') { click_link "Edit" }
50
+ fill_in "option_type_name", :with => "foo-size 99"
51
+ click_button "Update"
52
+ expect(page).to have_content("successfully updated!")
53
+ expect(page).to have_content("foo-size 99")
54
+ end
55
+ end
56
+
57
+ # Regression test for #2277
58
+ it "can remove an option value from an option type", :js => true do
59
+ create(:option_value)
60
+ click_link "Option Types"
61
+ within('table#listing_option_types') { click_icon :edit }
62
+ expect(page).to have_content("Editing Option Type")
63
+ expect(all("tbody#option_values tr").count).to eq(1)
64
+ within("tbody#option_values") do
65
+ find('.spree_remove_fields').click
66
+ end
67
+ # Assert that the field is hidden automatically
68
+ expect(all("tbody#option_values tr").select(&:visible?).count).to eq(0)
69
+
70
+ # Then assert that on a page refresh that it's still not visible
71
+ visit page.current_url
72
+ # What *is* visible is a new option value field, with blank values
73
+ # Sometimes the page doesn't load before the all check is done
74
+ # lazily finding the element gives the page 10 seconds
75
+ expect(page).to have_css("tbody#option_values")
76
+ all("tbody#option_values tr input").all? { |input| input.value.blank? }
77
+ end
78
+
79
+ # Regression test for #3204
80
+ it "can remove a non-persisted option value from an option type", :js => true do
81
+ create(:option_type)
82
+ click_link "Option Types"
83
+ within('table#listing_option_types') { click_icon :edit }
84
+
85
+ wait_for_ajax
86
+ page.find("tbody#option_values", :visible => true)
87
+
88
+ expect(all("tbody#option_values tr").select(&:visible?).count).to eq(1)
89
+
90
+ # Add a new option type
91
+ click_link "Add Option Value"
92
+ expect(all("tbody#option_values tr").select(&:visible?).count).to eq(2)
93
+
94
+ # Remove default option type
95
+ within("tbody#option_values") do
96
+ find('.fa-trash').click
97
+ end
98
+ # Check that there was no HTTP request
99
+ expect(all("div#progress[style]").count).to eq(0)
100
+ # Assert that the field is hidden automatically
101
+ expect(all("tbody#option_values tr").select(&:visible?).count).to eq(1)
102
+
103
+ # Remove added option type
104
+ within("tbody#option_values") do
105
+ find('.fa-trash').click
106
+ end
107
+ # Check that there was no HTTP request
108
+ expect(all("div#progress[style]").count).to eq(0)
109
+ # Assert that the field is hidden automatically
110
+ expect(all("tbody#option_values tr").select(&:visible?).count).to eq(0)
111
+
112
+ end
113
+
114
+ end
@@ -0,0 +1,395 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe "Products", :type => :feature do
5
+ context "as admin user" do
6
+ stub_authorization!
7
+
8
+ before(:each) do
9
+ visit spree.admin_path
10
+ end
11
+
12
+ def build_option_type_with_values(name, values)
13
+ ot = FactoryGirl.create(:option_type, :name => name)
14
+ values.each do |val|
15
+ ot.option_values.create(:name => val.downcase, :presentation => val)
16
+ end
17
+ ot
18
+ end
19
+
20
+ context "listing products" do
21
+ context "sorting" do
22
+ before do
23
+ create(:product, :name => 'apache baseball cap', :price => 10)
24
+ create(:product, :name => 'zomg shirt', :price => 5)
25
+ end
26
+
27
+ it "should list existing products with correct sorting by name" do
28
+ click_link "Products"
29
+ # Name ASC
30
+ within_row(1) { expect(page).to have_content('apache baseball cap') }
31
+ within_row(2) { expect(page).to have_content("zomg shirt") }
32
+
33
+ # Name DESC
34
+ click_link "admin_products_listing_name_title"
35
+ within_row(1) { expect(page).to have_content("zomg shirt") }
36
+ within_row(2) { expect(page).to have_content('apache baseball cap') }
37
+ end
38
+
39
+ it "should list existing products with correct sorting by price" do
40
+ click_link "Products"
41
+
42
+ # Name ASC (default)
43
+ within_row(1) { expect(page).to have_content('apache baseball cap') }
44
+ within_row(2) { expect(page).to have_content("zomg shirt") }
45
+
46
+ # Price DESC
47
+ click_link "admin_products_listing_price_title"
48
+ within_row(1) { expect(page).to have_content("zomg shirt") }
49
+ within_row(2) { expect(page).to have_content('apache baseball cap') }
50
+ end
51
+ end
52
+
53
+ context "currency displaying" do
54
+ context "using Russian Rubles" do
55
+ before do
56
+ Spree::Config[:currency] = "RUB"
57
+ end
58
+
59
+ let!(:product) do
60
+ create(:product, :name => "Just a product", :price => 19.99)
61
+ end
62
+
63
+ # Regression test for #2737
64
+ context "uses руб as the currency symbol" do
65
+ it "on the products listing page" do
66
+ visit spree.admin_products_path
67
+ within_row(1) { expect(page).to have_content("19.99 ₽") }
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ context "searching products" do
75
+ it "should be able to search deleted products", :js => true do
76
+ create(:product, :name => 'apache baseball cap', :deleted_at => "2011-01-06 18:21:13")
77
+ create(:product, :name => 'zomg shirt')
78
+
79
+ click_link "Products"
80
+ expect(page).to have_content("zomg shirt")
81
+ expect(page).not_to have_content("apache baseball cap")
82
+ check "Show Deleted"
83
+ click_icon :search
84
+ expect(page).to have_content("zomg shirt")
85
+ expect(page).to have_content("apache baseball cap")
86
+ uncheck "Show Deleted"
87
+ click_icon :search
88
+ expect(page).to have_content("zomg shirt")
89
+ expect(page).not_to have_content("apache baseball cap")
90
+ end
91
+
92
+ it "should be able to search products by their properties" do
93
+ create(:product, :name => 'apache baseball cap', :sku => "A100")
94
+ create(:product, :name => 'apache baseball cap2', :sku => "B100")
95
+ create(:product, :name => 'zomg shirt')
96
+
97
+ click_link "Products"
98
+ fill_in "q_name_cont", :with => "ap"
99
+ click_icon :search
100
+ expect(page).to have_content("apache baseball cap")
101
+ expect(page).to have_content("apache baseball cap2")
102
+ expect(page).not_to have_content("zomg shirt")
103
+
104
+ fill_in "q_variants_including_master_sku_cont", :with => "A1"
105
+ click_icon :search
106
+ expect(page).to have_content("apache baseball cap")
107
+ expect(page).not_to have_content("apache baseball cap2")
108
+ expect(page).not_to have_content("zomg shirt")
109
+ end
110
+ end
111
+
112
+ context "creating a new product from a prototype" do
113
+ def build_option_type_with_values(name, values)
114
+ ot = FactoryGirl.create(:option_type, :name => name)
115
+ values.each do |val|
116
+ ot.option_values.create(:name => val.downcase, :presentation => val)
117
+ end
118
+ ot
119
+ end
120
+
121
+ let(:product_attributes) do
122
+ # FactoryGirl.attributes_for is un-deprecated!
123
+ # https://github.com/thoughtbot/factory_girl/issues/274#issuecomment-3592054
124
+ FactoryGirl.attributes_for(:simple_product)
125
+ end
126
+
127
+ let(:prototype) do
128
+ size = build_option_type_with_values("size", %w(Small Medium Large))
129
+ FactoryGirl.create(:prototype, :name => "Size", :option_types => [ size ])
130
+ end
131
+
132
+ let(:option_values_hash) do
133
+ hash = {}
134
+ prototype.option_types.each do |i|
135
+ hash[i.id.to_s] = i.option_value_ids
136
+ end
137
+ hash
138
+ end
139
+
140
+ before(:each) do
141
+ @option_type_prototype = prototype
142
+ @property_prototype = create(:prototype, :name => "Random")
143
+ @shipping_category = create(:shipping_category)
144
+ click_link "Products"
145
+ click_link "admin_new_product"
146
+ within('#new_product') do
147
+ expect(page).to have_content("SKU")
148
+ end
149
+ end
150
+
151
+ it "should allow an admin to create a new product and variants from a prototype", :js => true do
152
+ fill_in "product_name", :with => "Baseball Cap"
153
+ fill_in "product_sku", :with => "B100"
154
+ fill_in "product_price", :with => "100"
155
+ fill_in "product_available_on", :with => "2012/01/24"
156
+ select "Size", :from => "Prototype"
157
+ check "Large"
158
+ select @shipping_category.name, from: "product_shipping_category_id"
159
+ click_button "Create"
160
+ expect(page).to have_content("successfully created!")
161
+ expect(Spree::Product.last.variants.length).to eq(1)
162
+ end
163
+
164
+ it "should not display variants when prototype does not contain option types", :js => true do
165
+ select "Random", :from => "Prototype"
166
+
167
+ fill_in "product_name", :with => "Baseball Cap"
168
+
169
+ expect(page).not_to have_content("Variants")
170
+ end
171
+
172
+ it "should keep option values selected if validation fails", :js => true do
173
+ fill_in "product_name", :with => "Baseball Cap"
174
+ fill_in "product_sku", :with => "B100"
175
+ fill_in "product_price", :with => "100"
176
+ select "Size", :from => "Prototype"
177
+ check "Large"
178
+ click_button "Create"
179
+ expect(page).to have_content("Shipping category can't be blank")
180
+ expect(field_labeled("Size")).to be_checked
181
+ expect(field_labeled("Large")).to be_checked
182
+ expect(field_labeled("Small")).not_to be_checked
183
+ end
184
+ end
185
+
186
+ context "creating a new product" do
187
+ before(:each) do
188
+ @shipping_category = create(:shipping_category)
189
+ click_link "Products"
190
+ click_link "admin_new_product"
191
+ within('#new_product') do
192
+ expect(page).to have_content("SKU")
193
+ end
194
+ end
195
+
196
+ it "should allow an admin to create a new product", :js => true do
197
+ fill_in "product_name", :with => "Baseball Cap"
198
+ fill_in "product_sku", :with => "B100"
199
+ fill_in "product_price", :with => "100"
200
+ fill_in "product_available_on", :with => "2012/01/24"
201
+ select @shipping_category.name, from: "product_shipping_category_id"
202
+ click_button "Create"
203
+ expect(page).to have_content("successfully created!")
204
+ click_button "Update"
205
+ expect(page).to have_content("successfully updated!")
206
+ end
207
+
208
+ it "should show validation errors", :js => true do
209
+ fill_in "product_name", :with => "Baseball Cap"
210
+ fill_in "product_sku", :with => "B100"
211
+ fill_in "product_price", :with => "100"
212
+ click_button "Create"
213
+ expect(page).to have_content("Shipping category can't be blank")
214
+ end
215
+
216
+ context "using a locale with a different decimal format " do
217
+ before do
218
+ # change English locale’s separator and delimiter to match 19,99 format
219
+ I18n.backend.store_translations(:en,
220
+ :number => {
221
+ :currency => {
222
+ :format => {
223
+ :separator => ",",
224
+ :delimiter => "."
225
+ }
226
+ }
227
+ })
228
+ end
229
+
230
+ after do
231
+ # revert changes to English locale
232
+ I18n.backend.store_translations(:en,
233
+ :number => {
234
+ :currency => {
235
+ :format => {
236
+ :separator => ".",
237
+ :delimiter => ","
238
+ }
239
+ }
240
+ })
241
+ end
242
+
243
+ it "should show localized price value on validation errors", :js => true do
244
+ fill_in "product_price", :with => "19,99"
245
+ click_button "Create"
246
+ expect(find('input#product_price').value).to eq('19,99')
247
+ end
248
+ end
249
+
250
+ # Regression test for #2097
251
+ it "can set the count on hand to a null value", :js => true do
252
+ fill_in "product_name", :with => "Baseball Cap"
253
+ fill_in "product_price", :with => "100"
254
+ select @shipping_category.name, from: "product_shipping_category_id"
255
+ click_button "Create"
256
+ expect(page).to have_content("successfully created!")
257
+ click_button "Update"
258
+ expect(page).to have_content("successfully updated!")
259
+ end
260
+ end
261
+
262
+
263
+ context "cloning a product", :js => true do
264
+ it "should allow an admin to clone a product" do
265
+ create(:product)
266
+
267
+ click_link "Products"
268
+ within_row(1) do
269
+ click_icon :copy
270
+ end
271
+
272
+ expect(page).to have_content("Product has been cloned")
273
+ end
274
+
275
+ context "cloning a deleted product" do
276
+ it "should allow an admin to clone a deleted product" do
277
+ create(:product, :name => "apache baseball cap")
278
+
279
+ click_link "Products"
280
+ check "Show Deleted"
281
+ click_button "Search"
282
+
283
+ expect(page).to have_content("apache baseball cap")
284
+
285
+ within_row(1) do
286
+ click_icon :copy
287
+ end
288
+
289
+ expect(page).to have_content("Product has been cloned")
290
+ end
291
+ end
292
+ end
293
+
294
+ context 'updating a product', :js => true do
295
+ let(:product) { create(:product) }
296
+
297
+ let(:prototype) do
298
+ size = build_option_type_with_values("size", %w(Small Medium Large))
299
+ FactoryGirl.create(:prototype, :name => "Size", :option_types => [ size ])
300
+ end
301
+
302
+ before(:each) do
303
+ @option_type_prototype = prototype
304
+ @property_prototype = create(:prototype, :name => "Random")
305
+ end
306
+
307
+ it 'should parse correctly available_on' do
308
+ visit spree.admin_product_path(product)
309
+ fill_in "product_available_on", :with => "2012/12/25"
310
+ click_button "Update"
311
+ expect(page).to have_content("successfully updated!")
312
+ expect(Spree::Product.last.available_on).to eq('Tue, 25 Dec 2012 00:00:00 UTC +00:00')
313
+ end
314
+
315
+ it 'should add option_types when selecting a prototype' do
316
+ visit spree.admin_product_path(product)
317
+ click_link 'Product Properties'
318
+ expect(page).to have_content("SELECT FROM PROTOTYPE")
319
+ click_link "Select From Prototype"
320
+
321
+ row = find('#prototypes tr', text: 'Size')
322
+ row.click_link 'Select'
323
+
324
+ # The following is unfortunate.
325
+ # It is tough to distinguish between the different fields, so we assert
326
+ # that there are two rows (ensuring one has been added) and then
327
+ # inspect the first one.
328
+ expect(page).to have_css('#product_properties .product_property', count: 2)
329
+ within('#product_properties .product_property:nth-child(1)') do
330
+ expect(find('input[type=text]').value).to eq('baseball_cap_color')
331
+ end
332
+ end
333
+ end
334
+
335
+ context 'deleting a product', :js => true do
336
+ let!(:product) { create(:product) }
337
+
338
+ it "is still viewable" do
339
+ visit spree.admin_products_path
340
+
341
+ expect(page).to have_content(product.name)
342
+ accept_alert do
343
+ click_icon :trash
344
+ end
345
+
346
+ expect(page).to have_no_content(product.name)
347
+
348
+ # This will show our deleted product
349
+ check "Show Deleted"
350
+ click_icon :search
351
+ click_link product.name
352
+ expect(page).to have_field('Master Price', with: product.price.to_f)
353
+ end
354
+ end
355
+ end
356
+
357
+ context 'with only product permissions' do
358
+
359
+ before do
360
+ allow_any_instance_of(Spree::Admin::BaseController).to receive(:spree_current_user).and_return(nil)
361
+ end
362
+
363
+ custom_authorization! do |user|
364
+ can [:admin, :update, :index, :read], Spree::Product
365
+ end
366
+ let!(:product) { create(:product) }
367
+
368
+ it "should only display accessible links on index" do
369
+ visit spree.admin_products_path
370
+ expect(page).to have_link('Products')
371
+ expect(page).not_to have_link('Option Types')
372
+ expect(page).not_to have_link('Properties')
373
+ expect(page).not_to have_link('Prototypes')
374
+
375
+ expect(page).not_to have_link('New Product')
376
+ expect(page).not_to have_css('a.clone')
377
+ expect(page).to have_css('a.edit')
378
+ expect(page).not_to have_css('a.delete-resource')
379
+ end
380
+
381
+ it "should only display accessible links on edit" do
382
+ visit spree.admin_product_path(product)
383
+
384
+ # product tabs should be hidden
385
+ expect(page).to have_link('Product Details')
386
+ expect(page).not_to have_link('Images')
387
+ expect(page).not_to have_link('Variants')
388
+ expect(page).not_to have_link('Product Properties')
389
+ expect(page).not_to have_link('Stock Management')
390
+
391
+ # no create permission
392
+ expect(page).not_to have_link('New Product')
393
+ end
394
+ end
395
+ end
@@ -0,0 +1,139 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Properties", :type => :feature do
4
+ stub_authorization!
5
+
6
+ before(:each) do
7
+ visit spree.admin_path
8
+ click_link "Products"
9
+ end
10
+
11
+ context "Property index" do
12
+ before do
13
+ create(:property, :name => 'shirt size', :presentation => 'size')
14
+ create(:property, :name => 'shirt fit', :presentation => 'fit')
15
+ click_link "Properties"
16
+ end
17
+
18
+ context "listing product properties" do
19
+ it "should list the existing product properties" do
20
+ within_row(1) do
21
+ expect(column_text(1)).to eq("shirt size")
22
+ expect(column_text(2)).to eq("size")
23
+ end
24
+
25
+ within_row(2) do
26
+ expect(column_text(1)).to eq("shirt fit")
27
+ expect(column_text(2)).to eq("fit")
28
+ end
29
+ end
30
+ end
31
+
32
+ context "searching properties" do
33
+ it 'should list properties matching search query', :js => true do
34
+ fill_in "q_name_cont", :with => "size"
35
+ click_icon :search
36
+
37
+ expect(page).to have_content("shirt size")
38
+ expect(page).not_to have_content("shirt fit")
39
+ end
40
+ end
41
+ end
42
+
43
+ context "creating a property" do
44
+ it "should allow an admin to create a new product property", :js => true do
45
+ click_link "Properties"
46
+ click_link "new_property_link"
47
+ within('#new_property') { expect(page).to have_content("NEW PROPERTY") }
48
+
49
+ fill_in "property_name", :with => "color of band"
50
+ fill_in "property_presentation", :with => "color"
51
+ click_button "Create"
52
+ expect(page).to have_content("successfully created!")
53
+ end
54
+ end
55
+
56
+ context "editing a property" do
57
+ before(:each) do
58
+ create(:property)
59
+ click_link "Properties"
60
+ within_row(1) { click_icon :edit }
61
+ end
62
+
63
+ it "should allow an admin to edit an existing product property" do
64
+ fill_in "property_name", :with => "model 99"
65
+ click_button "Update"
66
+ expect(page).to have_content("successfully updated!")
67
+ expect(page).to have_content("model 99")
68
+ end
69
+
70
+ it "should show validation errors" do
71
+ fill_in "property_name", :with => ""
72
+ click_button "Update"
73
+ expect(page).to have_content("Name can't be blank")
74
+ end
75
+ end
76
+
77
+ context "linking a property to a product", :js => true do
78
+ before do
79
+ create(:product)
80
+ visit spree.admin_products_path
81
+ click_icon :edit
82
+ click_link "Product Properties"
83
+ end
84
+
85
+ # Regression test for #2279
86
+ it "successfully create and then remove product property" do
87
+ fill_in_property
88
+
89
+ check_property_row_count(2)
90
+
91
+ delete_product_property
92
+
93
+ check_property_row_count(1)
94
+ end
95
+
96
+ # Regression test for #4466
97
+ it "successfully remove and create a product property at the same time" do
98
+ fill_in_property
99
+
100
+ expect(page).to have_css('tr.product_property', count: 2)
101
+
102
+ within '#spree_new_product_property' do
103
+ find('[id$=_property_name]').set("New Property")
104
+ find('[id$=_value]').set("New Value")
105
+ end
106
+
107
+ delete_product_property
108
+
109
+ # Give fadeOut time to complete
110
+ expect(page).to have_css('tr.product_property', count: 1)
111
+
112
+ click_button "Update"
113
+
114
+ expect(page).not_to have_content("Product is not found")
115
+
116
+ check_property_row_count(2)
117
+ end
118
+
119
+ def fill_in_property
120
+ expect(page).to have_content('Editing Product')
121
+ fill_in "product_product_properties_attributes_0_property_name", :with => "A Property"
122
+ fill_in "product_product_properties_attributes_0_value", :with => "A Value"
123
+ click_button "Update"
124
+ click_link "Product Properties"
125
+ end
126
+
127
+ def delete_product_property
128
+ accept_alert do
129
+ click_icon :trash
130
+ end
131
+ expect(page).to have_content 'successfully removed'
132
+ end
133
+
134
+ def check_property_row_count(expected_row_count)
135
+ click_link "Product Properties"
136
+ expect(page).to have_css("tbody#product_properties tr", count: expected_row_count)
137
+ end
138
+ end
139
+ end