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