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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1 -0
- data/Gemfile +6 -0
- data/Rakefile +29 -0
- data/app/assets/javascripts/spree/backend/admin.js +26 -0
- data/app/controllers/spree/admin/resource_controller.rb +4 -2
- data/app/helpers/spree/admin/navigation_helper.rb +10 -1
- data/app/views/spree/admin/images/new.html.erb +1 -1
- data/app/views/spree/admin/payments/_list.html.erb +1 -1
- data/app/views/spree/admin/products/_form.html.erb +1 -1
- data/app/views/spree/admin/shared/_index_table_options.html.erb +1 -11
- data/app/views/spree/admin/shared/sub_menu/_product.html.erb +1 -1
- data/script/rails +9 -0
- data/spec/controllers/spree/admin/base_controller_spec.rb +46 -0
- data/spec/controllers/spree/admin/customer_returns_controller_spec.rb +185 -0
- data/spec/controllers/spree/admin/general_settings_controller_spec.rb +41 -0
- data/spec/controllers/spree/admin/missing_products_controller_spec.rb +18 -0
- data/spec/controllers/spree/admin/orders/customer_details_controller_spec.rb +42 -0
- data/spec/controllers/spree/admin/orders_controller_spec.rb +247 -0
- data/spec/controllers/spree/admin/payment_methods_controller_spec.rb +49 -0
- data/spec/controllers/spree/admin/payments_controller_spec.rb +97 -0
- data/spec/controllers/spree/admin/products_controller_spec.rb +53 -0
- data/spec/controllers/spree/admin/promotion_actions_controller_spec.rb +21 -0
- data/spec/controllers/spree/admin/promotion_rules_controller_spec.rb +21 -0
- data/spec/controllers/spree/admin/promotions_controller_spec.rb +44 -0
- data/spec/controllers/spree/admin/refunds_controller_spec.rb +32 -0
- data/spec/controllers/spree/admin/reimbursements_controller_spec.rb +74 -0
- data/spec/controllers/spree/admin/reports_controller_spec.rb +42 -0
- data/spec/controllers/spree/admin/resource_controller_spec.rb +276 -0
- data/spec/controllers/spree/admin/return_authorizations_controller_spec.rb +225 -0
- data/spec/controllers/spree/admin/return_items_controller_spec.rb +27 -0
- data/spec/controllers/spree/admin/root_controller_spec.rb +35 -0
- data/spec/controllers/spree/admin/search_controller_spec.rb +56 -0
- data/spec/controllers/spree/admin/shipping_methods_controller_spec.rb +14 -0
- data/spec/controllers/spree/admin/stock_items_controller_spec.rb +19 -0
- data/spec/controllers/spree/admin/stock_locations_controller_spec.rb +41 -0
- data/spec/controllers/spree/admin/stock_transfers_controller_spec.rb +41 -0
- data/spec/controllers/spree/admin/tax_categories_controller_spec.rb +34 -0
- data/spec/controllers/spree/admin/users_controller_spec.rb +161 -0
- data/spec/controllers/spree/admin/variants_controller_spec.rb +32 -0
- data/spec/features/admin/configuration/analytics_tracker_spec.rb +46 -0
- data/spec/features/admin/configuration/countries_spec.rb +24 -0
- data/spec/features/admin/configuration/general_settings_spec.rb +43 -0
- data/spec/features/admin/configuration/payment_methods_spec.rb +63 -0
- data/spec/features/admin/configuration/roles_spec.rb +47 -0
- data/spec/features/admin/configuration/shipping_methods_spec.rb +62 -0
- data/spec/features/admin/configuration/states_spec.rb +68 -0
- data/spec/features/admin/configuration/stock_locations_spec.rb +48 -0
- data/spec/features/admin/configuration/tax_categories_spec.rb +56 -0
- data/spec/features/admin/configuration/tax_rates_spec.rb +18 -0
- data/spec/features/admin/configuration/zones_spec.rb +39 -0
- data/spec/features/admin/homepage_spec.rb +81 -0
- data/spec/features/admin/locale_spec.rb +31 -0
- data/spec/features/admin/orders/adjustments_promotions_spec.rb +53 -0
- data/spec/features/admin/orders/adjustments_spec.rb +129 -0
- data/spec/features/admin/orders/cancelling_and_resuming_spec.rb +47 -0
- data/spec/features/admin/orders/customer_details_spec.rb +182 -0
- data/spec/features/admin/orders/line_items_spec.rb +51 -0
- data/spec/features/admin/orders/listing_spec.rb +225 -0
- data/spec/features/admin/orders/log_entries_spec.rb +55 -0
- data/spec/features/admin/orders/new_order_spec.rb +161 -0
- data/spec/features/admin/orders/order_details_spec.rb +620 -0
- data/spec/features/admin/orders/payments_spec.rb +229 -0
- data/spec/features/admin/orders/risk_analysis_spec.rb +48 -0
- data/spec/features/admin/orders/shipments_spec.rb +64 -0
- data/spec/features/admin/orders/state_changes_spec.rb +21 -0
- data/spec/features/admin/products/edit/images_spec.rb +86 -0
- data/spec/features/admin/products/edit/products_spec.rb +64 -0
- data/spec/features/admin/products/edit/taxons_spec.rb +41 -0
- data/spec/features/admin/products/edit/variants_spec.rb +56 -0
- data/spec/features/admin/products/option_types_spec.rb +113 -0
- data/spec/features/admin/products/products_spec.rb +394 -0
- data/spec/features/admin/products/properties_spec.rb +140 -0
- data/spec/features/admin/products/prototypes_spec.rb +112 -0
- data/spec/features/admin/products/stock_management_spec.rb +123 -0
- data/spec/features/admin/products/taxonomies_spec.rb +52 -0
- data/spec/features/admin/products/variant_spec.rb +50 -0
- data/spec/features/admin/promotions/adjustments_spec.rb +255 -0
- data/spec/features/admin/promotions/option_value_rule_spec.rb +70 -0
- data/spec/features/admin/promotions/tiered_calculator_spec.rb +70 -0
- data/spec/features/admin/reports_spec.rb +61 -0
- data/spec/features/admin/stock_transfer_spec.rb +75 -0
- data/spec/features/admin/taxons_spec.rb +47 -0
- data/spec/features/admin/users_spec.rb +284 -0
- data/spec/helpers/admin/base_helper_spec.rb +24 -0
- data/spec/helpers/admin/navigation_helper_spec.rb +106 -0
- data/spec/helpers/admin/stock_movements_helper_spec.rb +30 -0
- data/spec/helpers/promotion_rules_helper_spec.rb +12 -0
- data/spec/models/spree/resource_spec.rb +48 -0
- data/spec/spec_helper.rb +133 -0
- data/spec/support/appear_before_matcher.rb +8 -0
- data/spec/support/ror_ringer.jpeg +0 -0
- data/spec/test_views/spree/admin/submodule/posts/edit.html.erb +1 -0
- data/spec/test_views/spree/admin/submodule/posts/new.html.erb +1 -0
- data/spec/test_views/spree/admin/widgets/edit.html.erb +1 -0
- data/spec/test_views/spree/admin/widgets/new.html.erb +1 -0
- data/spree_backend.gemspec +29 -0
- 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
|