spree_backend 3.0.5 → 3.0.6

Sign up to get free protection for your applications and to get access to all the features.
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