solidus_backend 1.0.2 → 1.0.3
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 +15 -0
- data/script/rails +9 -0
- data/solidus_backend.gemspec +28 -0
- data/spec/controllers/spree/admin/base_controller_spec.rb +24 -0
- data/spec/controllers/spree/admin/cancellations_controller_spec.rb +77 -0
- data/spec/controllers/spree/admin/customer_returns_controller_spec.rb +234 -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 +80 -0
- data/spec/controllers/spree/admin/orders_controller_spec.rb +472 -0
- data/spec/controllers/spree/admin/payment_methods_controller_spec.rb +49 -0
- data/spec/controllers/spree/admin/payments_controller_spec.rb +175 -0
- data/spec/controllers/spree/admin/products_controller_spec.rb +45 -0
- data/spec/controllers/spree/admin/promotion_actions_controller_spec.rb +21 -0
- data/spec/controllers/spree/admin/promotion_codes_controller_spec.rb +18 -0
- data/spec/controllers/spree/admin/promotion_rules_controller_spec.rb +21 -0
- data/spec/controllers/spree/admin/promotions_controller_spec.rb +122 -0
- data/spec/controllers/spree/admin/refunds_controller_spec.rb +32 -0
- data/spec/controllers/spree/admin/reimbursements_controller_spec.rb +75 -0
- data/spec/controllers/spree/admin/reports_controller_spec.rb +134 -0
- data/spec/controllers/spree/admin/resource_controller_spec.rb +166 -0
- data/spec/controllers/spree/admin/return_authorizations_controller_spec.rb +226 -0
- data/spec/controllers/spree/admin/return_items_controller_spec.rb +27 -0
- data/spec/controllers/spree/admin/root_controller_spec.rb +41 -0
- data/spec/controllers/spree/admin/search_controller_spec.rb +104 -0
- data/spec/controllers/spree/admin/shipping_methods_controller_spec.rb +14 -0
- data/spec/controllers/spree/admin/stock_items_controller_spec.rb +50 -0
- data/spec/controllers/spree/admin/stock_locations_controller_spec.rb +41 -0
- data/spec/controllers/spree/admin/stock_transfers_controller_spec.rb +331 -0
- data/spec/controllers/spree/admin/store_credits_controller_spec.rb +309 -0
- data/spec/controllers/spree/admin/users_controller_spec.rb +236 -0
- data/spec/controllers/spree/admin/variants_controller_spec.rb +32 -0
- data/spec/features/admin/configuration/analytics_tracker_spec.rb +54 -0
- data/spec/features/admin/configuration/countries_spec.rb +22 -0
- data/spec/features/admin/configuration/general_settings_spec.rb +45 -0
- data/spec/features/admin/configuration/payment_methods_spec.rb +125 -0
- data/spec/features/admin/configuration/shipping_methods_spec.rb +64 -0
- data/spec/features/admin/configuration/states_spec.rb +64 -0
- data/spec/features/admin/configuration/stock_locations_spec.rb +50 -0
- data/spec/features/admin/configuration/tax_categories_spec.rb +56 -0
- data/spec/features/admin/configuration/tax_rates_spec.rb +30 -0
- data/spec/features/admin/configuration/taxonomies_spec.rb +52 -0
- data/spec/features/admin/configuration/zones_spec.rb +39 -0
- data/spec/features/admin/homepage_spec.rb +78 -0
- data/spec/features/admin/locale_spec.rb +30 -0
- data/spec/features/admin/orders/adjustments_promotions_spec.rb +53 -0
- data/spec/features/admin/orders/adjustments_spec.rb +126 -0
- data/spec/features/admin/orders/cancelling_and_resuming_spec.rb +48 -0
- data/spec/features/admin/orders/cancelling_inventory_spec.rb +48 -0
- data/spec/features/admin/orders/customer_details_spec.rb +163 -0
- data/spec/features/admin/orders/line_items_spec.rb +50 -0
- data/spec/features/admin/orders/listing_spec.rb +130 -0
- data/spec/features/admin/orders/log_entries_spec.rb +55 -0
- data/spec/features/admin/orders/new_order_spec.rb +185 -0
- data/spec/features/admin/orders/order_details_spec.rb +533 -0
- data/spec/features/admin/orders/payments_spec.rb +228 -0
- data/spec/features/admin/orders/risk_analysis_spec.rb +47 -0
- data/spec/features/admin/orders/shipments_spec.rb +65 -0
- data/spec/features/admin/payments/store_credits_spec.rb +21 -0
- data/spec/features/admin/products/edit/images_spec.rb +87 -0
- data/spec/features/admin/products/edit/products_spec.rb +66 -0
- data/spec/features/admin/products/edit/taxons_spec.rb +43 -0
- data/spec/features/admin/products/edit/variants_spec.rb +61 -0
- data/spec/features/admin/products/option_types_spec.rb +114 -0
- data/spec/features/admin/products/products_spec.rb +392 -0
- data/spec/features/admin/products/properties_spec.rb +139 -0
- data/spec/features/admin/products/prototypes_spec.rb +110 -0
- data/spec/features/admin/products/stock_management_spec.rb +82 -0
- data/spec/features/admin/products/variant_spec.rb +51 -0
- data/spec/features/admin/promotion_adjustments_spec.rb +220 -0
- data/spec/features/admin/promotions/tiered_calculator_spec.rb +69 -0
- data/spec/features/admin/reports_spec.rb +61 -0
- data/spec/features/admin/stock_transfer_spec.rb +86 -0
- data/spec/features/admin/store_credits_spec.rb +82 -0
- data/spec/features/admin/taxons_spec.rb +31 -0
- data/spec/features/admin/users_spec.rb +270 -0
- data/spec/helpers/admin/base_helper_spec.rb +24 -0
- data/spec/helpers/admin/navigation_helper_spec.rb +73 -0
- data/spec/helpers/admin/reimbursements_helper_spec.rb +34 -0
- data/spec/helpers/admin/stock_movements_helper_spec.rb +29 -0
- data/spec/helpers/admin/store_credit_events_helper_spec.rb +95 -0
- data/spec/helpers/promotion_rules_helper_spec.rb +12 -0
- data/spec/spec_helper.rb +108 -0
- data/spec/support/appear_before_matcher.rb +8 -0
- data/spec/support/ror_ringer.jpeg +0 -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
- metadata +95 -6
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe 'Product Details', :type => :feature 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_path
|
|
13
|
+
click_link 'Products'
|
|
14
|
+
within_row(1) { click_icon :edit }
|
|
15
|
+
|
|
16
|
+
click_link 'Product Details'
|
|
17
|
+
|
|
18
|
+
expect(find('.page-title').text.strip).to eq('Editing Product “Bún thịt nướng”')
|
|
19
|
+
expect(find('input#product_name').value).to eq('Bún thịt nướng')
|
|
20
|
+
expect(find('input#product_slug').value).to eq('bun-th-t-n-ng')
|
|
21
|
+
expect(find('textarea#product_description').text.strip).to eq('lorem ipsum')
|
|
22
|
+
expect(find('input#product_price').value).to eq('19.99')
|
|
23
|
+
expect(find('input#product_cost_price').value).to eq('17.00')
|
|
24
|
+
expect(find('input#product_available_on').value).to eq("2013/08/14")
|
|
25
|
+
expect(find('input#product_sku').value).to eq('A100')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should handle slug changes" do
|
|
29
|
+
create(:product, :name => 'Bún thịt nướng', :sku => 'A100',
|
|
30
|
+
:description => 'lorem ipsum', :available_on => '2011-01-01 01:01:01')
|
|
31
|
+
|
|
32
|
+
visit spree.admin_path
|
|
33
|
+
click_link 'Products'
|
|
34
|
+
within('table.index tbody tr:nth-child(1)') do
|
|
35
|
+
click_icon(:edit)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
fill_in "product_slug", :with => 'random-slug-value'
|
|
39
|
+
click_button "Update"
|
|
40
|
+
expect(page).to have_content("successfully updated!")
|
|
41
|
+
|
|
42
|
+
fill_in "product_slug", :with => ''
|
|
43
|
+
click_button "Update"
|
|
44
|
+
within('#product_slug_field') { expect(page).to have_content("is too short") }
|
|
45
|
+
|
|
46
|
+
fill_in "product_slug", :with => 'another-random-slug-value'
|
|
47
|
+
click_button "Update"
|
|
48
|
+
expect(page).to have_content("successfully updated!")
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Regression test for #3385
|
|
53
|
+
context "deleting a product", :js => true do
|
|
54
|
+
it "is still able to find the master variant" do
|
|
55
|
+
create(:product)
|
|
56
|
+
|
|
57
|
+
visit spree.admin_products_path
|
|
58
|
+
within_row(1) do
|
|
59
|
+
accept_alert do
|
|
60
|
+
click_icon :trash
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
wait_for_ajax
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Product Taxons", :type => :feature 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", :js => true 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_path
|
|
26
|
+
click_link "Products"
|
|
27
|
+
within("table.index") do
|
|
28
|
+
click_icon :edit
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
expect(find(".select2-search-choice").text).to eq(taxon_1.name)
|
|
32
|
+
expect(selected_taxons).to match_array([taxon_1.id])
|
|
33
|
+
|
|
34
|
+
select2_search "Clothing", :from => "Taxons"
|
|
35
|
+
click_button "Update"
|
|
36
|
+
expect(selected_taxons).to match_array([taxon_1.id, taxon_2.id])
|
|
37
|
+
|
|
38
|
+
# Regression test for #2139
|
|
39
|
+
expect(page).to have_css(".select2-search-choice", text: taxon_1.name)
|
|
40
|
+
expect(page).to have_css(".select2-search-choice", text: taxon_2.name)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Product Variants", :type => :feature do
|
|
4
|
+
stub_authorization!
|
|
5
|
+
|
|
6
|
+
before(:each) do
|
|
7
|
+
visit spree.admin_path
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context "editing variant option types", :js => true do
|
|
11
|
+
let!(:product) { create(:product) }
|
|
12
|
+
|
|
13
|
+
it "should allow an admin to create option types for a variant" do
|
|
14
|
+
click_link "Products"
|
|
15
|
+
|
|
16
|
+
within_row(1) { click_icon :edit }
|
|
17
|
+
|
|
18
|
+
within('#sidebar') { click_link "Variants" }
|
|
19
|
+
expect(page).to have_content("TO ADD VARIANTS, YOU MUST FIRST DEFINE")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "allows admin to create a variant if there are option types" do
|
|
23
|
+
click_link "Products"
|
|
24
|
+
click_link "Option Types"
|
|
25
|
+
click_link "new_option_type_link"
|
|
26
|
+
fill_in "option_type_name", :with => "shirt colors"
|
|
27
|
+
fill_in "option_type_presentation", :with => "colors"
|
|
28
|
+
click_button "Create"
|
|
29
|
+
expect(page).to have_content("successfully created!")
|
|
30
|
+
|
|
31
|
+
page.find('#option_type_option_values_attributes_0_name').set('color')
|
|
32
|
+
page.find('#option_type_option_values_attributes_0_presentation').set('black')
|
|
33
|
+
click_button "Update"
|
|
34
|
+
expect(page).to have_content("successfully updated!")
|
|
35
|
+
|
|
36
|
+
visit spree.admin_path
|
|
37
|
+
click_link "Products"
|
|
38
|
+
within('table.index tbody tr:nth-child(1)') do
|
|
39
|
+
click_icon :edit
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
select2_search "shirt", :from => "Option Types"
|
|
43
|
+
click_button "Update"
|
|
44
|
+
expect(page).to have_content("successfully updated!")
|
|
45
|
+
|
|
46
|
+
within('#sidebar') { click_link "Variants" }
|
|
47
|
+
click_link "New Variant"
|
|
48
|
+
|
|
49
|
+
targetted_select2 "black", :from => "#s2id_variant_option_value_ids"
|
|
50
|
+
fill_in "variant_sku", :with => "A100"
|
|
51
|
+
click_button "Create"
|
|
52
|
+
expect(page).to have_content("successfully created!")
|
|
53
|
+
|
|
54
|
+
within(".index") do
|
|
55
|
+
expect(page).to have_content("19.99")
|
|
56
|
+
expect(page).to have_content("black")
|
|
57
|
+
expect(page).to have_content("A100")
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -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,392 @@
|
|
|
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
|
+
within(:css, "#prototypes tr#row_1") do
|
|
322
|
+
click_link 'Select'
|
|
323
|
+
wait_for_ajax
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
within(:css, "tr.product_property:first-child") do
|
|
327
|
+
expect(first('input[type=text]').value).to eq('baseball_cap_color')
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
context 'deleting a product', :js => true do
|
|
333
|
+
let!(:product) { create(:product) }
|
|
334
|
+
|
|
335
|
+
it "is still viewable" do
|
|
336
|
+
visit spree.admin_products_path
|
|
337
|
+
|
|
338
|
+
expect(page).to have_content(product.name)
|
|
339
|
+
accept_alert do
|
|
340
|
+
click_icon :trash
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
expect(page).to have_no_content(product.name)
|
|
344
|
+
|
|
345
|
+
# This will show our deleted product
|
|
346
|
+
check "Show Deleted"
|
|
347
|
+
click_icon :search
|
|
348
|
+
click_link product.name
|
|
349
|
+
expect(page).to have_field('Master Price', with: product.price.to_f)
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
context 'with only product permissions' do
|
|
355
|
+
|
|
356
|
+
before do
|
|
357
|
+
allow_any_instance_of(Spree::Admin::BaseController).to receive(:spree_current_user).and_return(nil)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
custom_authorization! do |user|
|
|
361
|
+
can [:admin, :update, :index, :read], Spree::Product
|
|
362
|
+
end
|
|
363
|
+
let!(:product) { create(:product) }
|
|
364
|
+
|
|
365
|
+
it "should only display accessible links on index" do
|
|
366
|
+
visit spree.admin_products_path
|
|
367
|
+
expect(page).to have_link('Products')
|
|
368
|
+
expect(page).not_to have_link('Option Types')
|
|
369
|
+
expect(page).not_to have_link('Properties')
|
|
370
|
+
expect(page).not_to have_link('Prototypes')
|
|
371
|
+
|
|
372
|
+
expect(page).not_to have_link('New Product')
|
|
373
|
+
expect(page).not_to have_css('a.clone')
|
|
374
|
+
expect(page).to have_css('a.edit')
|
|
375
|
+
expect(page).not_to have_css('a.delete-resource')
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
it "should only display accessible links on edit" do
|
|
379
|
+
visit spree.admin_product_path(product)
|
|
380
|
+
|
|
381
|
+
# product tabs should be hidden
|
|
382
|
+
expect(page).to have_link('Product Details')
|
|
383
|
+
expect(page).not_to have_link('Images')
|
|
384
|
+
expect(page).not_to have_link('Variants')
|
|
385
|
+
expect(page).not_to have_link('Product Properties')
|
|
386
|
+
expect(page).not_to have_link('Stock Management')
|
|
387
|
+
|
|
388
|
+
# no create permission
|
|
389
|
+
expect(page).not_to have_link('New Product')
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
end
|