spree_backend 3.0.5 → 3.0.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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -0
  3. data/Gemfile +6 -0
  4. data/Rakefile +29 -0
  5. data/app/assets/javascripts/spree/backend/admin.js +26 -0
  6. data/app/controllers/spree/admin/resource_controller.rb +4 -2
  7. data/app/helpers/spree/admin/navigation_helper.rb +10 -1
  8. data/app/views/spree/admin/images/new.html.erb +1 -1
  9. data/app/views/spree/admin/payments/_list.html.erb +1 -1
  10. data/app/views/spree/admin/products/_form.html.erb +1 -1
  11. data/app/views/spree/admin/shared/_index_table_options.html.erb +1 -11
  12. data/app/views/spree/admin/shared/sub_menu/_product.html.erb +1 -1
  13. data/script/rails +9 -0
  14. data/spec/controllers/spree/admin/base_controller_spec.rb +46 -0
  15. data/spec/controllers/spree/admin/customer_returns_controller_spec.rb +185 -0
  16. data/spec/controllers/spree/admin/general_settings_controller_spec.rb +41 -0
  17. data/spec/controllers/spree/admin/missing_products_controller_spec.rb +18 -0
  18. data/spec/controllers/spree/admin/orders/customer_details_controller_spec.rb +42 -0
  19. data/spec/controllers/spree/admin/orders_controller_spec.rb +247 -0
  20. data/spec/controllers/spree/admin/payment_methods_controller_spec.rb +49 -0
  21. data/spec/controllers/spree/admin/payments_controller_spec.rb +97 -0
  22. data/spec/controllers/spree/admin/products_controller_spec.rb +53 -0
  23. data/spec/controllers/spree/admin/promotion_actions_controller_spec.rb +21 -0
  24. data/spec/controllers/spree/admin/promotion_rules_controller_spec.rb +21 -0
  25. data/spec/controllers/spree/admin/promotions_controller_spec.rb +44 -0
  26. data/spec/controllers/spree/admin/refunds_controller_spec.rb +32 -0
  27. data/spec/controllers/spree/admin/reimbursements_controller_spec.rb +74 -0
  28. data/spec/controllers/spree/admin/reports_controller_spec.rb +42 -0
  29. data/spec/controllers/spree/admin/resource_controller_spec.rb +276 -0
  30. data/spec/controllers/spree/admin/return_authorizations_controller_spec.rb +225 -0
  31. data/spec/controllers/spree/admin/return_items_controller_spec.rb +27 -0
  32. data/spec/controllers/spree/admin/root_controller_spec.rb +35 -0
  33. data/spec/controllers/spree/admin/search_controller_spec.rb +56 -0
  34. data/spec/controllers/spree/admin/shipping_methods_controller_spec.rb +14 -0
  35. data/spec/controllers/spree/admin/stock_items_controller_spec.rb +19 -0
  36. data/spec/controllers/spree/admin/stock_locations_controller_spec.rb +41 -0
  37. data/spec/controllers/spree/admin/stock_transfers_controller_spec.rb +41 -0
  38. data/spec/controllers/spree/admin/tax_categories_controller_spec.rb +34 -0
  39. data/spec/controllers/spree/admin/users_controller_spec.rb +161 -0
  40. data/spec/controllers/spree/admin/variants_controller_spec.rb +32 -0
  41. data/spec/features/admin/configuration/analytics_tracker_spec.rb +46 -0
  42. data/spec/features/admin/configuration/countries_spec.rb +24 -0
  43. data/spec/features/admin/configuration/general_settings_spec.rb +43 -0
  44. data/spec/features/admin/configuration/payment_methods_spec.rb +63 -0
  45. data/spec/features/admin/configuration/roles_spec.rb +47 -0
  46. data/spec/features/admin/configuration/shipping_methods_spec.rb +62 -0
  47. data/spec/features/admin/configuration/states_spec.rb +68 -0
  48. data/spec/features/admin/configuration/stock_locations_spec.rb +48 -0
  49. data/spec/features/admin/configuration/tax_categories_spec.rb +56 -0
  50. data/spec/features/admin/configuration/tax_rates_spec.rb +18 -0
  51. data/spec/features/admin/configuration/zones_spec.rb +39 -0
  52. data/spec/features/admin/homepage_spec.rb +81 -0
  53. data/spec/features/admin/locale_spec.rb +31 -0
  54. data/spec/features/admin/orders/adjustments_promotions_spec.rb +53 -0
  55. data/spec/features/admin/orders/adjustments_spec.rb +129 -0
  56. data/spec/features/admin/orders/cancelling_and_resuming_spec.rb +47 -0
  57. data/spec/features/admin/orders/customer_details_spec.rb +182 -0
  58. data/spec/features/admin/orders/line_items_spec.rb +51 -0
  59. data/spec/features/admin/orders/listing_spec.rb +225 -0
  60. data/spec/features/admin/orders/log_entries_spec.rb +55 -0
  61. data/spec/features/admin/orders/new_order_spec.rb +161 -0
  62. data/spec/features/admin/orders/order_details_spec.rb +620 -0
  63. data/spec/features/admin/orders/payments_spec.rb +229 -0
  64. data/spec/features/admin/orders/risk_analysis_spec.rb +48 -0
  65. data/spec/features/admin/orders/shipments_spec.rb +64 -0
  66. data/spec/features/admin/orders/state_changes_spec.rb +21 -0
  67. data/spec/features/admin/products/edit/images_spec.rb +86 -0
  68. data/spec/features/admin/products/edit/products_spec.rb +64 -0
  69. data/spec/features/admin/products/edit/taxons_spec.rb +41 -0
  70. data/spec/features/admin/products/edit/variants_spec.rb +56 -0
  71. data/spec/features/admin/products/option_types_spec.rb +113 -0
  72. data/spec/features/admin/products/products_spec.rb +394 -0
  73. data/spec/features/admin/products/properties_spec.rb +140 -0
  74. data/spec/features/admin/products/prototypes_spec.rb +112 -0
  75. data/spec/features/admin/products/stock_management_spec.rb +123 -0
  76. data/spec/features/admin/products/taxonomies_spec.rb +52 -0
  77. data/spec/features/admin/products/variant_spec.rb +50 -0
  78. data/spec/features/admin/promotions/adjustments_spec.rb +255 -0
  79. data/spec/features/admin/promotions/option_value_rule_spec.rb +70 -0
  80. data/spec/features/admin/promotions/tiered_calculator_spec.rb +70 -0
  81. data/spec/features/admin/reports_spec.rb +61 -0
  82. data/spec/features/admin/stock_transfer_spec.rb +75 -0
  83. data/spec/features/admin/taxons_spec.rb +47 -0
  84. data/spec/features/admin/users_spec.rb +284 -0
  85. data/spec/helpers/admin/base_helper_spec.rb +24 -0
  86. data/spec/helpers/admin/navigation_helper_spec.rb +106 -0
  87. data/spec/helpers/admin/stock_movements_helper_spec.rb +30 -0
  88. data/spec/helpers/promotion_rules_helper_spec.rb +12 -0
  89. data/spec/models/spree/resource_spec.rb +48 -0
  90. data/spec/spec_helper.rb +133 -0
  91. data/spec/support/appear_before_matcher.rb +8 -0
  92. data/spec/support/ror_ringer.jpeg +0 -0
  93. data/spec/test_views/spree/admin/submodule/posts/edit.html.erb +1 -0
  94. data/spec/test_views/spree/admin/submodule/posts/new.html.erb +1 -0
  95. data/spec/test_views/spree/admin/widgets/edit.html.erb +1 -0
  96. data/spec/test_views/spree/admin/widgets/new.html.erb +1 -0
  97. data/spree_backend.gemspec +29 -0
  98. metadata +101 -14
@@ -0,0 +1,64 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe 'Product Details', type: :feature, js: true do
5
+ stub_authorization!
6
+
7
+ context 'editing a product' do
8
+ it 'should list the product details' do
9
+ create(:product, :name => 'Bún thịt nướng', :sku => 'A100',
10
+ :description => 'lorem ipsum', :available_on => '2013-08-14 01:02:03')
11
+
12
+ visit spree.admin_products_path
13
+ within_row(1) { click_icon :edit }
14
+
15
+ click_link 'Details'
16
+
17
+ expect(find('.content-header h1').text.strip).to eq('Products / Bún thịt nướng')
18
+ expect(find('input#product_name').value).to eq('Bún thịt nướng')
19
+ expect(find('input#product_slug').value).to eq('bun-th-t-n-ng')
20
+ expect(find('textarea#product_description').text.strip).to eq('lorem ipsum')
21
+ expect(find('input#product_price').value).to eq('19.99')
22
+ expect(find('input#product_cost_price').value).to eq('17.00')
23
+ expect(find('input#product_available_on').value).to eq("2013/08/14")
24
+ expect(find('input#product_sku').value).to eq('A100')
25
+ end
26
+
27
+ it "should handle slug changes" do
28
+ create(:product, name: 'Bún thịt nướng', sku: 'A100',
29
+ description: 'lorem ipsum', available_on: '2011-01-01 01:01:01')
30
+
31
+ visit spree.admin_products_path
32
+ within('table.table tbody tr:nth-child(1)') do
33
+ click_icon(:edit)
34
+ end
35
+
36
+ fill_in "product_slug", with: 'random-slug-value'
37
+ click_button "Update"
38
+ expect(page).to have_content("successfully updated!")
39
+
40
+ fill_in "product_slug", with: 'a'
41
+ click_button "Update"
42
+ within('#product_slug_field') { expect(page).to have_content("is too short") }
43
+
44
+ fill_in "product_slug", with: 'another-random-slug-value'
45
+ click_button "Update"
46
+ expect(page).to have_content("successfully updated!")
47
+ end
48
+ end
49
+
50
+ # Regression test for #3385
51
+ context "deleting a product" do
52
+ it "is still able to find the master variant" do
53
+ create(:product)
54
+
55
+ visit spree.admin_products_path
56
+ within_row(1) do
57
+ accept_alert do
58
+ click_icon :delete
59
+ end
60
+ end
61
+ wait_for_ajax
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Product Taxons", type: :feature, js: true do
4
+ stub_authorization!
5
+
6
+ after do
7
+ Capybara.ignore_hidden_elements = true
8
+ end
9
+
10
+ before do
11
+ Capybara.ignore_hidden_elements = false
12
+ end
13
+
14
+ context "managing taxons" do
15
+ def selected_taxons
16
+ find("#product_taxon_ids").value.split(',').map(&:to_i).uniq
17
+ end
18
+
19
+ it "should allow an admin to manage taxons" do
20
+ taxon_1 = create(:taxon)
21
+ taxon_2 = create(:taxon, name: 'Clothing')
22
+ product = create(:product)
23
+ product.taxons << taxon_1
24
+
25
+ visit spree.admin_products_path
26
+ within_row(1) { click_icon :edit }
27
+
28
+ expect(find(".select2-search-choice").text).to eq(taxon_1.name)
29
+ expect(selected_taxons).to match_array([taxon_1.id])
30
+
31
+ select2_search "Clothing", from: "Taxons"
32
+ click_button "Update"
33
+ expect(selected_taxons).to match_array([taxon_1.id, taxon_2.id])
34
+
35
+ # Regression test for #2139
36
+ sleep(1)
37
+ expect(first(".select2-search-choice", text: taxon_1.name)).to be_present
38
+ expect(first(".select2-search-choice", text: taxon_2.name)).to be_present
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Product Variants", type: :feature, js: true do
4
+ stub_authorization!
5
+
6
+ let!(:product) { create(:product) }
7
+
8
+ before(:each) do
9
+ visit spree.admin_products_path
10
+ end
11
+
12
+ context "editing variant option types" do
13
+ it "should allow an admin to create option types for a variant" do
14
+ within_row(1) { click_icon :edit }
15
+
16
+ within('#sidebar') { click_link "Variants" }
17
+ expect(page).to have_content("To add variants, you must first define")
18
+ end
19
+
20
+ it "allows admin to create a variant if there are option types" do
21
+ click_link "Products"
22
+ click_link "Option Types"
23
+ click_link "new_option_type_link"
24
+ fill_in "option_type_name", with: "shirt colors"
25
+ fill_in "option_type_presentation", with: "colors"
26
+ click_button "Create"
27
+ expect(page).to have_content("successfully created!")
28
+
29
+ page.find('#option_type_option_values_attributes_0_name').set('color')
30
+ page.find('#option_type_option_values_attributes_0_presentation').set('black')
31
+ click_button "Update"
32
+ expect(page).to have_content("successfully updated!")
33
+
34
+ visit spree.admin_products_path
35
+ within_row(1) { click_icon :edit }
36
+
37
+ select2_search "shirt", from: "Option Types"
38
+ click_button "Update"
39
+ expect(page).to have_content("successfully updated!")
40
+
41
+ within('#sidebar') { click_link "Variants" }
42
+ click_link "New Variant"
43
+
44
+ targetted_select2 "black", from: "#s2id_variant_option_value_ids"
45
+ fill_in "variant_sku", with: "A100"
46
+ click_button "Create"
47
+ expect(page).to have_content("successfully created!")
48
+
49
+ within(".table") do
50
+ expect(page).to have_content("19.99")
51
+ expect(page).to have_content("black")
52
+ expect(page).to have_content("A100")
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Option Types", type: :feature, js: true 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
+ click_link "Option Types"
16
+ within("table#listing_option_types") do
17
+ expect(page).to have_content("Color")
18
+ expect(page).to have_content("tshirt-color")
19
+ expect(page).to have_content("Size")
20
+ expect(page).to have_content("tshirt-size")
21
+ end
22
+ end
23
+ end
24
+
25
+ context "creating a new option type" do
26
+ it "should allow an admin to create a new option type" do
27
+ click_link "Option Types"
28
+ click_link "new_option_type_link"
29
+ expect(page).to have_content("New Option Type")
30
+ fill_in "option_type_name", with: "shirt colors"
31
+ fill_in "option_type_presentation", with: "colors"
32
+ click_button "Create"
33
+ expect(page).to have_content("successfully created!")
34
+
35
+ page.find('#option_type_option_values_attributes_0_name').set('color')
36
+ page.find('#option_type_option_values_attributes_0_presentation').set('black')
37
+
38
+ click_button "Update"
39
+ expect(page).to have_content("successfully updated!")
40
+ end
41
+ end
42
+
43
+ context "editing an existing option type" do
44
+ it "should allow an admin to update an existing option type" do
45
+ create(:option_type, name: "tshirt-color", presentation: "Color")
46
+ create(:option_type, name: "tshirt-size", presentation: "Size")
47
+ click_link "Option Types"
48
+ within('table#listing_option_types') { click_icon :edit }
49
+ fill_in "option_type_name", with: "foo-size 99"
50
+ click_button "Update"
51
+ expect(page).to have_content("successfully updated!")
52
+ expect(page).to have_content("foo-size 99")
53
+ end
54
+ end
55
+
56
+ # Regression test for #2277
57
+ it "can remove an option value from an option type" do
58
+ create(:option_value)
59
+ click_link "Option Types"
60
+ within('table#listing_option_types') { click_icon :edit }
61
+ expect(page).to have_content("Editing Option Type")
62
+ expect(all("tbody#option_values tr").count).to eq(1)
63
+ within("tbody#option_values") do
64
+ find('.spree_remove_fields').click
65
+ end
66
+ # Assert that the field is hidden automatically
67
+ expect(all("tbody#option_values tr").select(&:visible?).count).to eq(0)
68
+
69
+ # Then assert that on a page refresh that it's still not visible
70
+ visit page.current_url
71
+ # What *is* visible is a new option value field, with blank values
72
+ # Sometimes the page doesn't load before the all check is done
73
+ # lazily finding the element gives the page 10 seconds
74
+ expect(page).to have_css("tbody#option_values")
75
+ all("tbody#option_values tr input").all? { |input| input.value.blank? }
76
+ end
77
+
78
+ # Regression test for #3204
79
+ it "can remove a non-persisted option value from an option type" do
80
+ create(:option_type)
81
+ click_link "Option Types"
82
+ within('table#listing_option_types') { click_icon :edit }
83
+
84
+ wait_for_ajax
85
+ page.find("tbody#option_values", :visible => true)
86
+
87
+ expect(all("tbody#option_values tr").select(&:visible?).count).to eq(1)
88
+
89
+ # Add a new option type
90
+ click_link "Add Option Value"
91
+ expect(all("tbody#option_values tr").select(&:visible?).count).to eq(2)
92
+
93
+ # Remove default option type
94
+ within("tbody#option_values") do
95
+ click_icon :delete
96
+ end
97
+ # Check that there was no HTTP request
98
+ expect(all("div#progress[style]").count).to eq(0)
99
+ # Assert that the field is hidden automatically
100
+ expect(all("tbody#option_values tr").select(&:visible?).count).to eq(1)
101
+
102
+ # Remove added option type
103
+ within("tbody#option_values") do
104
+ click_icon :delete
105
+ end
106
+ # Check that there was no HTTP request
107
+ expect(all("div#progress[style]").count).to eq(0)
108
+ # Assert that the field is hidden automatically
109
+ expect(all("tbody#option_values tr").select(&:visible?).count).to eq(0)
110
+
111
+ end
112
+
113
+ end
@@ -0,0 +1,394 @@
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
+ def build_option_type_with_values(name, values)
9
+ ot = FactoryGirl.create(:option_type, name: name)
10
+ values.each do |val|
11
+ ot.option_values.create(name: val.downcase, presentation: val)
12
+ end
13
+ ot
14
+ end
15
+
16
+ context "listing products" do
17
+ context "sorting" do
18
+ before do
19
+ create(:product, name: 'apache baseball cap', price: 10)
20
+ create(:product, name: 'zomg shirt', price: 5)
21
+ end
22
+
23
+ it "should list existing products with correct sorting by name" do
24
+ visit spree.admin_products_path
25
+ # Name ASC
26
+ within_row(1) { expect(page).to have_content('apache baseball cap') }
27
+ within_row(2) { expect(page).to have_content("zomg shirt") }
28
+
29
+ # Name DESC
30
+ click_link "admin_products_listing_name_title"
31
+ within_row(1) { expect(page).to have_content("zomg shirt") }
32
+ within_row(2) { expect(page).to have_content('apache baseball cap') }
33
+ end
34
+
35
+ it "should list existing products with correct sorting by price" do
36
+ visit spree.admin_products_path
37
+ # Name ASC (default)
38
+ within_row(1) { expect(page).to have_content('apache baseball cap') }
39
+ within_row(2) { expect(page).to have_content("zomg shirt") }
40
+
41
+ # Price DESC
42
+ click_link "admin_products_listing_price_title"
43
+ within_row(1) { expect(page).to have_content("zomg shirt") }
44
+ within_row(2) { expect(page).to have_content('apache baseball cap') }
45
+ end
46
+ end
47
+
48
+ context "currency displaying" do
49
+ context "using Russian Rubles" do
50
+ before do
51
+ Spree::Config[:currency] = "RUB"
52
+ end
53
+
54
+ let!(:product) do
55
+ create(:product, name: "Just a product", price: 19.99)
56
+ end
57
+
58
+ # Regression test for #2737
59
+ context "uses руб as the currency symbol" do
60
+ it "on the products listing page" do
61
+ visit spree.admin_products_path
62
+ within_row(1) { expect(page).to have_content("19.99 ₽") }
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ context "searching products" do
70
+ it "should be able to search deleted products" do
71
+ create(:product, name: 'apache baseball cap', deleted_at: "2011-01-06 18:21:13")
72
+ create(:product, name: 'zomg shirt')
73
+
74
+ visit spree.admin_products_path
75
+ expect(page).to have_content("zomg shirt")
76
+ expect(page).not_to have_content("apache baseball cap")
77
+
78
+ check "Show Deleted"
79
+ click_on 'Search'
80
+
81
+ expect(page).to have_content("zomg shirt")
82
+ expect(page).to have_content("apache baseball cap")
83
+
84
+ uncheck "Show Deleted"
85
+ click_on 'Search'
86
+
87
+ expect(page).to have_content("zomg shirt")
88
+ expect(page).not_to have_content("apache baseball cap")
89
+ end
90
+
91
+ it "should be able to search products by their properties" do
92
+ create(:product, name: 'apache baseball cap', sku: "A100")
93
+ create(:product, name: 'apache baseball cap2', sku: "B100")
94
+ create(:product, name: 'zomg shirt')
95
+
96
+ visit spree.admin_products_path
97
+ fill_in "q_name_cont", with: "ap"
98
+ click_on 'Search'
99
+
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_on 'Search'
106
+
107
+ expect(page).to have_content("apache baseball cap")
108
+ expect(page).not_to have_content("apache baseball cap2")
109
+ expect(page).not_to have_content("zomg shirt")
110
+ end
111
+ end
112
+
113
+ context "creating a new product from a prototype", js: true do
114
+ def build_option_type_with_values(name, values)
115
+ ot = FactoryGirl.create(:option_type, name: name)
116
+ values.each do |val|
117
+ ot.option_values.create(name: val.downcase, presentation: val)
118
+ end
119
+ ot
120
+ end
121
+
122
+ let(:product_attributes) do
123
+ # FactoryGirl.attributes_for is un-deprecated!
124
+ # https://github.com/thoughtbot/factory_girl/issues/274#issuecomment-3592054
125
+ FactoryGirl.attributes_for(:simple_product)
126
+ end
127
+
128
+ let(:prototype) do
129
+ size = build_option_type_with_values("size", %w(Small Medium Large))
130
+ FactoryGirl.create(:prototype, name: "Size", option_types: [ size ])
131
+ end
132
+
133
+ let(:option_values_hash) do
134
+ hash = {}
135
+ prototype.option_types.each do |i|
136
+ hash[i.id.to_s] = i.option_value_ids
137
+ end
138
+ hash
139
+ end
140
+
141
+ before(:each) do
142
+ @option_type_prototype = prototype
143
+ @property_prototype = create(:prototype, name: "Random")
144
+ @shipping_category = create(:shipping_category)
145
+ visit spree.admin_products_path
146
+ click_link "admin_new_product"
147
+ within('#new_product') do
148
+ expect(page).to have_content("SKU")
149
+ end
150
+ end
151
+
152
+ it "should allow an admin to create a new product and variants from a prototype" do
153
+ fill_in "product_name", with: "Baseball Cap"
154
+ fill_in "product_sku", with: "B100"
155
+ fill_in "product_price", with: "100"
156
+ fill_in "product_available_on", with: "2012/01/24"
157
+ # Just so the datepicker gets out of poltergeists way.
158
+ page.execute_script("$('#ui-datepicker-div').hide();")
159
+ select "Size", from: "Prototype"
160
+ wait_for_ajax
161
+ check "Large"
162
+ select @shipping_category.name, from: "product_shipping_category_id"
163
+ click_button "Create"
164
+ expect(page).to have_content("successfully created!")
165
+ expect(Spree::Product.last.variants.length).to eq(1)
166
+ end
167
+
168
+ it "should not display variants when prototype does not contain option types" do
169
+ select "Random", from: "Prototype"
170
+
171
+ fill_in "product_name", with: "Baseball Cap"
172
+
173
+ expect(page).not_to have_content("Variants")
174
+ end
175
+
176
+ it "should keep option values selected if validation fails" do
177
+ fill_in "product_name", with: "Baseball Cap"
178
+ fill_in "product_sku", with: "B100"
179
+ fill_in "product_price", with: "100"
180
+ select "Size", from: "Prototype"
181
+ wait_for_ajax
182
+ check "Large"
183
+ click_button "Create"
184
+ expect(page).to have_content("Shipping category can't be blank")
185
+ expect(field_labeled("Size")).to be_checked
186
+ expect(field_labeled("Large")).to be_checked
187
+ expect(field_labeled("Small")).not_to be_checked
188
+ end
189
+ end
190
+
191
+ context "creating a new product" do
192
+ before(:each) do
193
+ @shipping_category = create(:shipping_category)
194
+ visit spree.admin_products_path
195
+ click_link "admin_new_product"
196
+ within('#new_product') do
197
+ expect(page).to have_content("SKU")
198
+ end
199
+ end
200
+
201
+ it "should allow an admin to create a new product" do
202
+ fill_in "product_name", with: "Baseball Cap"
203
+ fill_in "product_sku", with: "B100"
204
+ fill_in "product_price", with: "100"
205
+ fill_in "product_available_on", with: "2012/01/24"
206
+ select @shipping_category.name, from: "product_shipping_category_id"
207
+ click_button "Create"
208
+ expect(page).to have_content("successfully created!")
209
+ click_button "Update"
210
+ expect(page).to have_content("successfully updated!")
211
+ end
212
+
213
+ it "should show validation errors" do
214
+ fill_in "product_name", with: "Baseball Cap"
215
+ fill_in "product_sku", with: "B100"
216
+ fill_in "product_price", with: "100"
217
+ click_button "Create"
218
+ expect(page).to have_content("Shipping category can't be blank")
219
+ end
220
+
221
+ context "using a locale with a different decimal format " do
222
+ before do
223
+ # change English locale’s separator and delimiter to match 19,99 format
224
+ I18n.backend.store_translations(:en,
225
+ :number => {
226
+ :currency => {
227
+ :format => {
228
+ :separator => ",",
229
+ :delimiter => "."
230
+ }
231
+ }
232
+ })
233
+ end
234
+
235
+ after do
236
+ # revert changes to English locale
237
+ I18n.backend.store_translations(:en,
238
+ :number => {
239
+ :currency => {
240
+ :format => {
241
+ :separator => ".",
242
+ :delimiter => ","
243
+ }
244
+ }
245
+ })
246
+ end
247
+
248
+ it "should show localized price value on validation errors", :js => true do
249
+ fill_in "product_price", :with => "19,99"
250
+ click_button "Create"
251
+ expect(find('input#product_price').value).to eq('19,99')
252
+ end
253
+ end
254
+
255
+ # Regression test for #2097
256
+ it "can set the count on hand to a null value" do
257
+ fill_in "product_name", with: "Baseball Cap"
258
+ fill_in "product_price", with: "100"
259
+ select @shipping_category.name, from: "product_shipping_category_id"
260
+ click_button "Create"
261
+ expect(page).to have_content("successfully created!")
262
+ click_button "Update"
263
+ expect(page).to have_content("successfully updated!")
264
+ end
265
+ end
266
+
267
+
268
+ context "cloning a product", js: true do
269
+ it "should allow an admin to clone a product" do
270
+ create(:product)
271
+
272
+ visit spree.admin_products_path
273
+ within_row(1) do
274
+ click_icon :clone
275
+ end
276
+
277
+ expect(page).to have_content("Product has been cloned")
278
+ end
279
+
280
+ context "cloning a deleted product" do
281
+ it "should allow an admin to clone a deleted product" do
282
+ create(:product, name: "apache baseball cap")
283
+
284
+ visit spree.admin_products_path
285
+ click_on 'Filter'
286
+ check "Show Deleted"
287
+ click_on 'Search'
288
+
289
+ expect(page).to have_content("apache baseball cap")
290
+
291
+ within_row(1) do
292
+ click_icon :clone
293
+ end
294
+
295
+ expect(page).to have_content("Product has been cloned")
296
+ end
297
+ end
298
+ end
299
+
300
+ context 'updating a product' do
301
+ let(:product) { create(:product) }
302
+
303
+ let(:prototype) do
304
+ size = build_option_type_with_values("size", %w(Small Medium Large))
305
+ FactoryGirl.create(:prototype, name: "Size", option_types: [ size ])
306
+ end
307
+
308
+ before(:each) do
309
+ @option_type_prototype = prototype
310
+ @property_prototype = create(:prototype, name: "Random")
311
+ end
312
+
313
+ it 'should parse correctly available_on' do
314
+ visit spree.admin_product_path(product)
315
+ fill_in "product_available_on", with: "2012/12/25"
316
+ click_button "Update"
317
+ expect(page).to have_content("successfully updated!")
318
+ expect(Spree::Product.last.available_on.to_s).to eq("2012-12-25 00:00:00 UTC")
319
+ end
320
+
321
+ it 'should add option_types when selecting a prototype', js: true do
322
+ visit spree.admin_product_path(product)
323
+ click_link 'Properties'
324
+ click_link "Select From Prototype"
325
+
326
+ within("#prototypes tr#row_#{prototype.id}") do
327
+ click_link 'Select'
328
+ wait_for_ajax
329
+ end
330
+
331
+ within(:css, "tr.product_property:first-child") do
332
+ expect(first('input[type=text]').value).to eq('baseball_cap_color')
333
+ end
334
+ end
335
+ end
336
+
337
+ context 'deleting a product', :js => true do
338
+ let!(:product) { create(:product) }
339
+
340
+ it "is still viewable" do
341
+ visit spree.admin_products_path
342
+ accept_alert do
343
+ click_icon :delete
344
+ wait_for_ajax
345
+ end
346
+ click_on 'Filter'
347
+ # This will show our deleted product
348
+ check "Show Deleted"
349
+ click_on 'Search'
350
+ click_link product.name
351
+ expect(find("#product_price").value.to_f).to eq(product.price.to_f)
352
+ end
353
+ end
354
+ end
355
+
356
+ context 'with only product permissions' do
357
+
358
+ before do
359
+ allow_any_instance_of(Spree::Admin::BaseController).to receive(:spree_current_user).and_return(nil)
360
+ end
361
+
362
+ custom_authorization! do |user|
363
+ can [:admin, :update, :index, :read], Spree::Product
364
+ end
365
+ let!(:product) { create(:product) }
366
+
367
+ it "should only display accessible links on index" do
368
+ visit spree.admin_products_path
369
+
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
+ expect(page).not_to have_link('New Product')
375
+ expect(page).not_to have_css('.icon-clone')
376
+ expect(page).to have_css('.icon-edit')
377
+ expect(page).not_to have_css('.delete-resource')
378
+ end
379
+
380
+ it "should only display accessible links on edit" do
381
+ visit spree.admin_product_path(product)
382
+
383
+ # product tabs should be hidden
384
+ expect(page).to have_link('Details')
385
+ expect(page).not_to have_link('Images')
386
+ expect(page).not_to have_link('Variants')
387
+ expect(page).not_to have_link('Properties')
388
+ expect(page).not_to have_link('Stock Management')
389
+
390
+ # no create permission
391
+ expect(page).not_to have_link('New Product')
392
+ end
393
+ end
394
+ end