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,110 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Prototypes", :type => :feature do
|
|
4
|
+
stub_authorization!
|
|
5
|
+
|
|
6
|
+
context "listing prototypes" do
|
|
7
|
+
it "should be able to list existing prototypes" do
|
|
8
|
+
create(:property, name: "model", presentation: "Model")
|
|
9
|
+
create(:property, name: "brand", presentation: "Brand")
|
|
10
|
+
create(:property, name: "shirt_fabric", presentation: "Fabric")
|
|
11
|
+
create(:property, name: "shirt_sleeve_length", presentation: "Sleeve")
|
|
12
|
+
create(:property, name: "mug_type", presentation: "Type")
|
|
13
|
+
create(:property, name: "bag_type", presentation: "Type")
|
|
14
|
+
create(:property, name: "manufacturer", presentation: "Manufacturer")
|
|
15
|
+
create(:property, name: "bag_size", presentation: "Size")
|
|
16
|
+
create(:property, name: "mug_size", presentation: "Size")
|
|
17
|
+
create(:property, name: "gender", presentation: "Gender")
|
|
18
|
+
create(:property, name: "shirt_fit", presentation: "Fit")
|
|
19
|
+
create(:property, name: "bag_material", presentation: "Material")
|
|
20
|
+
create(:property, name: "shirt_type", presentation: "Type")
|
|
21
|
+
p = create(:prototype, :name => "Shirt")
|
|
22
|
+
%w( brand gender manufacturer model shirt_fabric shirt_fit shirt_sleeve_length shirt_type ).each do |prop|
|
|
23
|
+
p.properties << Spree::Property.find_by_name(prop)
|
|
24
|
+
end
|
|
25
|
+
p = create(:prototype, name: "Mug")
|
|
26
|
+
%w( mug_size mug_type ).each do |prop|
|
|
27
|
+
p.properties << Spree::Property.find_by_name(prop)
|
|
28
|
+
end
|
|
29
|
+
p = create(:prototype, name: "Bag")
|
|
30
|
+
%w( bag_type bag_material ).each do |prop|
|
|
31
|
+
p.properties << Spree::Property.find_by_name(prop)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
visit spree.admin_path
|
|
35
|
+
click_link "Products"
|
|
36
|
+
click_link "Prototypes"
|
|
37
|
+
|
|
38
|
+
within_row(1) { expect(column_text(1)).to eq "Shirt" }
|
|
39
|
+
within_row(2) { expect(column_text(1)).to eq "Mug" }
|
|
40
|
+
within_row(3) { expect(column_text(1)).to eq "Bag" }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "creating a prototype" do
|
|
45
|
+
it "should allow an admin to create a new product prototype", :js => true do
|
|
46
|
+
visit spree.admin_path
|
|
47
|
+
click_link "Products"
|
|
48
|
+
click_link "Prototypes"
|
|
49
|
+
click_link "new_prototype_link"
|
|
50
|
+
within('#new_prototype') do
|
|
51
|
+
expect(page).to have_content("NEW PROTOTYPE")
|
|
52
|
+
end
|
|
53
|
+
fill_in "prototype_name", with: "male shirts"
|
|
54
|
+
click_button "Create"
|
|
55
|
+
expect(page).to have_content("successfully created!")
|
|
56
|
+
click_link "Prototypes"
|
|
57
|
+
within_row(1) { click_icon :edit }
|
|
58
|
+
fill_in "prototype_name", with: "Shirt 99"
|
|
59
|
+
click_button "Update"
|
|
60
|
+
expect(page).to have_content("successfully updated!")
|
|
61
|
+
expect(page).to have_content("Shirt 99")
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "editing a prototype" do
|
|
66
|
+
it "should allow to empty its properties" do
|
|
67
|
+
model_property = create(:property, name: "model", presentation: "Model")
|
|
68
|
+
brand_property = create(:property, name: "brand", presentation: "Brand")
|
|
69
|
+
|
|
70
|
+
shirt_prototype = create(:prototype, name: "Shirt", properties: [])
|
|
71
|
+
%w( brand model ).each do |prop|
|
|
72
|
+
shirt_prototype.properties << Spree::Property.find_by_name(prop)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
visit spree.admin_path
|
|
76
|
+
click_link "Products"
|
|
77
|
+
click_link "Prototypes"
|
|
78
|
+
|
|
79
|
+
click_on "Edit"
|
|
80
|
+
property_ids = find_field("prototype_property_ids").value.map(&:to_i)
|
|
81
|
+
expect(property_ids).to match_array [model_property.id, brand_property.id]
|
|
82
|
+
|
|
83
|
+
unselect "Brand", from: "prototype_property_ids"
|
|
84
|
+
unselect "Model", from: "prototype_property_ids"
|
|
85
|
+
|
|
86
|
+
click_button 'Update'
|
|
87
|
+
|
|
88
|
+
click_on "Edit"
|
|
89
|
+
|
|
90
|
+
expect(find_field("prototype_property_ids").value).to be_empty
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'should be deletable', js: true do
|
|
95
|
+
shirt_prototype = create(:prototype, name: "Shirt", properties: [])
|
|
96
|
+
shirt_prototype.taxons << create(:taxon)
|
|
97
|
+
|
|
98
|
+
visit spree.admin_path
|
|
99
|
+
click_link "Products"
|
|
100
|
+
click_link "Prototypes"
|
|
101
|
+
|
|
102
|
+
within("#spree_prototype_#{shirt_prototype.id}") do
|
|
103
|
+
page.find('.delete-resource').click
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
page.evaluate_script('window.confirm = function() { return true; }')
|
|
107
|
+
|
|
108
|
+
expect(page).to have_content("Prototype \"#{shirt_prototype.name}\" has been successfully removed!")
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Stock Management", :type => :feature do
|
|
4
|
+
stub_authorization!
|
|
5
|
+
|
|
6
|
+
before(:each) do
|
|
7
|
+
visit spree.admin_path
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context "given a product with a variant and a stock location" do
|
|
11
|
+
let!(:stock_location) { create(:stock_location, name: 'Default') }
|
|
12
|
+
let!(:product) { create(:product, name: 'apache baseball cap', price: 10) }
|
|
13
|
+
let!(:variant) { create(:variant, product: product) }
|
|
14
|
+
let(:stock_item) { variant.stock_items.find_by(stock_location: stock_location) }
|
|
15
|
+
|
|
16
|
+
before do
|
|
17
|
+
stock_location.stock_item(variant).update_column(:count_on_hand, 10)
|
|
18
|
+
|
|
19
|
+
click_link "Products"
|
|
20
|
+
within_row(1) { click_icon :edit }
|
|
21
|
+
click_link "Stock Management"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Regression test for #3304
|
|
25
|
+
# It is OK to still render the stock page, ensure no errors in this case
|
|
26
|
+
context "with no stock location" do
|
|
27
|
+
before do
|
|
28
|
+
@product = create(:product, name: 'apache baseball cap', price: 10)
|
|
29
|
+
v = @product.variants.create!(sku: 'FOOBAR')
|
|
30
|
+
Spree::StockLocation.destroy_all
|
|
31
|
+
click_link "Products"
|
|
32
|
+
within_row(1) do
|
|
33
|
+
click_icon :edit
|
|
34
|
+
end
|
|
35
|
+
click_link "Stock Management"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "renders" do
|
|
39
|
+
expect(page).to have_content(Spree.t(:editing_product))
|
|
40
|
+
expect(page.current_url).to match("admin/products/apache-baseball-cap/stock")
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "can create a positive stock adjustment", js: true do
|
|
45
|
+
adjust_count_on_hand('14')
|
|
46
|
+
stock_item.reload
|
|
47
|
+
expect(stock_item.count_on_hand).to eq 14
|
|
48
|
+
expect(stock_item.stock_movements.count).to eq 1
|
|
49
|
+
expect(stock_item.stock_movements.first.quantity).to eq 4
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "can create a negative stock adjustment", js: true do
|
|
53
|
+
adjust_count_on_hand('4')
|
|
54
|
+
stock_item.reload
|
|
55
|
+
expect(stock_item.count_on_hand).to eq 4
|
|
56
|
+
expect(stock_item.stock_movements.count).to eq 1
|
|
57
|
+
expect(stock_item.stock_movements.first.quantity).to eq -6
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def adjust_count_on_hand(count_on_hand)
|
|
61
|
+
find(:css, ".fa-edit[data-id='#{stock_item.id}']").click
|
|
62
|
+
find(:css, "[data-variant-id='#{variant.id}'] input[type='number']").set(count_on_hand)
|
|
63
|
+
find(:css, ".fa-check[data-id='#{stock_item.id}']").click
|
|
64
|
+
expect(page).to have_content('Updated successfully')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context "with multiple stock locations" do
|
|
68
|
+
before do
|
|
69
|
+
create(:stock_location, name: 'Other location', propagate_all_variants: false)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "can add stock items to other stock locations", js: true do
|
|
73
|
+
visit current_url
|
|
74
|
+
fill_in "variant-count-on-hand-#{variant.id}", with: '3'
|
|
75
|
+
targetted_select2_search "Other location", from: "#s2id_variant-stock-location-#{variant.id}"
|
|
76
|
+
find(:css, ".fa-plus[data-variant-id='#{variant.id}']").click
|
|
77
|
+
wait_for_ajax
|
|
78
|
+
expect(page).to have_content('Created successfully')
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe "Variants", :type => :feature do
|
|
5
|
+
stub_authorization!
|
|
6
|
+
|
|
7
|
+
let(:product) { create(:product_with_option_types, :price => "1.99", :cost_price => "1.00", :weight => "2.5", :height => "3.0", :width => "1.0", :depth => "1.5") }
|
|
8
|
+
|
|
9
|
+
context "creating a new variant" do
|
|
10
|
+
it "should allow an admin to create a new variant" do
|
|
11
|
+
product.options.each do |option|
|
|
12
|
+
create(:option_value, :option_type => option.option_type)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
visit spree.admin_path
|
|
16
|
+
click_link "Products"
|
|
17
|
+
within_row(1) { click_icon :edit }
|
|
18
|
+
click_link "Variants"
|
|
19
|
+
click_on "New Variant"
|
|
20
|
+
expect(find('input#variant_price').value).to eq("1.99")
|
|
21
|
+
expect(find('input#variant_cost_price').value).to eq("1.00")
|
|
22
|
+
expect(find('input#variant_weight').value).to eq("2.50")
|
|
23
|
+
expect(find('input#variant_height').value).to eq("3.00")
|
|
24
|
+
expect(find('input#variant_width').value).to eq("1.00")
|
|
25
|
+
expect(find('input#variant_depth').value).to eq("1.50")
|
|
26
|
+
expect(page).to have_select('variant[tax_category_id]')
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context "listing variants" do
|
|
31
|
+
context "currency displaying" do
|
|
32
|
+
context "using Russian Rubles" do
|
|
33
|
+
before do
|
|
34
|
+
Spree::Config[:currency] = "RUB"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
let!(:variant) do
|
|
38
|
+
create(:variant, :product => product, :price => 19.99)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Regression test for #2737
|
|
42
|
+
context "uses руб as the currency symbol" do
|
|
43
|
+
it "on the products listing page" do
|
|
44
|
+
visit spree.admin_product_variants_path(product)
|
|
45
|
+
within_row(1) { expect(page).to have_content("19.99 ₽") }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Promotion Adjustments", :type => :feature do
|
|
4
|
+
stub_authorization!
|
|
5
|
+
|
|
6
|
+
context "coupon promotions", :js => true do
|
|
7
|
+
before(:each) do
|
|
8
|
+
visit spree.admin_path
|
|
9
|
+
click_link "Promotions"
|
|
10
|
+
click_link "New Promotion"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should allow an admin to create a flat rate discount coupon promo" do
|
|
14
|
+
fill_in "Name", :with => "Promotion"
|
|
15
|
+
fill_in "Base code", :with => "order"
|
|
16
|
+
fill_in "Number of codes", :with => "1"
|
|
17
|
+
click_button "Create"
|
|
18
|
+
expect(page).to have_content("Editing Promotion")
|
|
19
|
+
|
|
20
|
+
select2 "Item total", :from => "Add rule of type"
|
|
21
|
+
within('#rule_fields') { click_button "Add" }
|
|
22
|
+
|
|
23
|
+
find('[id$=_preferred_amount]').set(30)
|
|
24
|
+
within('#rule_fields') { click_button "Update" }
|
|
25
|
+
|
|
26
|
+
select2 "Create whole-order adjustment", :from => "Add action of type"
|
|
27
|
+
within('#action_fields') { click_button "Add" }
|
|
28
|
+
select2 "Flat Rate", :from => "Calculator"
|
|
29
|
+
within('#actions_container') { click_button "Update" }
|
|
30
|
+
|
|
31
|
+
within('.calculator-fields') { fill_in "Amount", :with => 5 }
|
|
32
|
+
within('#actions_container') { click_button "Update" }
|
|
33
|
+
|
|
34
|
+
promotion = Spree::Promotion.find_by_name("Promotion")
|
|
35
|
+
expect(promotion.codes.first.value).to eq("order")
|
|
36
|
+
|
|
37
|
+
first_rule = promotion.rules.first
|
|
38
|
+
expect(first_rule.class).to eq(Spree::Promotion::Rules::ItemTotal)
|
|
39
|
+
expect(first_rule.preferred_amount).to eq(30)
|
|
40
|
+
|
|
41
|
+
first_action = promotion.actions.first
|
|
42
|
+
expect(first_action.class).to eq(Spree::Promotion::Actions::CreateAdjustment)
|
|
43
|
+
first_action_calculator = first_action.calculator
|
|
44
|
+
expect(first_action_calculator.class).to eq(Spree::Calculator::FlatRate)
|
|
45
|
+
expect(first_action_calculator.preferred_amount).to eq(5)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should allow an admin to create a single user coupon promo with flat rate discount" do
|
|
49
|
+
fill_in "Name", :with => "Promotion"
|
|
50
|
+
fill_in "promotion[usage_limit]", :with => "1"
|
|
51
|
+
fill_in "Base code", :with => "single_use"
|
|
52
|
+
fill_in "Number of codes", :with => "1"
|
|
53
|
+
click_button "Create"
|
|
54
|
+
expect(page).to have_content("Editing Promotion")
|
|
55
|
+
|
|
56
|
+
select2 "Create whole-order adjustment", :from => "Add action of type"
|
|
57
|
+
within('#action_fields') { click_button "Add" }
|
|
58
|
+
select2 "Flat Rate", :from => "Calculator"
|
|
59
|
+
within('#actions_container') { click_button "Update" }
|
|
60
|
+
within('#action_fields') { fill_in "Amount", :with => "5" }
|
|
61
|
+
within('#actions_container') { click_button "Update" }
|
|
62
|
+
|
|
63
|
+
promotion = Spree::Promotion.find_by_name("Promotion")
|
|
64
|
+
expect(promotion.usage_limit).to eq(1)
|
|
65
|
+
expect(promotion.codes.first.value).to eq("single_use")
|
|
66
|
+
|
|
67
|
+
first_action = promotion.actions.first
|
|
68
|
+
expect(first_action.class).to eq(Spree::Promotion::Actions::CreateAdjustment)
|
|
69
|
+
first_action_calculator = first_action.calculator
|
|
70
|
+
expect(first_action_calculator.class).to eq(Spree::Calculator::FlatRate)
|
|
71
|
+
expect(first_action_calculator.preferred_amount).to eq(5)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "should allow an admin to create an automatic promo with flat percent discount" do
|
|
75
|
+
fill_in "Name", :with => "Promotion"
|
|
76
|
+
click_button "Create"
|
|
77
|
+
expect(page).to have_content("Editing Promotion")
|
|
78
|
+
|
|
79
|
+
select2 "Item total", :from => "Add rule of type"
|
|
80
|
+
within('#rule_fields') { click_button "Add" }
|
|
81
|
+
|
|
82
|
+
find('[id$=_preferred_amount]').set(30)
|
|
83
|
+
within('#rule_fields') { click_button "Update" }
|
|
84
|
+
|
|
85
|
+
select2 "Create whole-order adjustment", :from => "Add action of type"
|
|
86
|
+
within('#action_fields') { click_button "Add" }
|
|
87
|
+
select2 "Flat Percent", :from => "Calculator"
|
|
88
|
+
within('#actions_container') { click_button "Update" }
|
|
89
|
+
within('.calculator-fields') { fill_in "Flat Percent", :with => "10" }
|
|
90
|
+
within('#actions_container') { click_button "Update" }
|
|
91
|
+
|
|
92
|
+
promotion = Spree::Promotion.find_by_name("Promotion")
|
|
93
|
+
expect(promotion.codes.first).to be_nil
|
|
94
|
+
|
|
95
|
+
first_rule = promotion.rules.first
|
|
96
|
+
expect(first_rule.class).to eq(Spree::Promotion::Rules::ItemTotal)
|
|
97
|
+
expect(first_rule.preferred_amount).to eq(30)
|
|
98
|
+
|
|
99
|
+
first_action = promotion.actions.first
|
|
100
|
+
expect(first_action.class).to eq(Spree::Promotion::Actions::CreateAdjustment)
|
|
101
|
+
first_action_calculator = first_action.calculator
|
|
102
|
+
expect(first_action_calculator.class).to eq(Spree::Calculator::FlatPercentItemTotal)
|
|
103
|
+
expect(first_action_calculator.preferred_flat_percent).to eq(10)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "should allow an admin to create an product promo with percent per item discount" do
|
|
107
|
+
create(:product, :name => "RoR Mug")
|
|
108
|
+
|
|
109
|
+
fill_in "Name", :with => "Promotion"
|
|
110
|
+
click_button "Create"
|
|
111
|
+
expect(page).to have_content("Editing Promotion")
|
|
112
|
+
|
|
113
|
+
select2 "Product(s)", :from => "Add rule of type"
|
|
114
|
+
within("#rule_fields") { click_button "Add" }
|
|
115
|
+
select2_search "RoR Mug", :from => "Choose products"
|
|
116
|
+
within('#rule_fields') { click_button "Update" }
|
|
117
|
+
|
|
118
|
+
select2 "Create per-line-item adjustment", :from => "Add action of type"
|
|
119
|
+
within('#action_fields') { click_button "Add" }
|
|
120
|
+
select2 "Percent Per Item", :from => "Calculator"
|
|
121
|
+
within('#actions_container') { click_button "Update" }
|
|
122
|
+
within('.calculator-fields') { fill_in "Percent", :with => "10" }
|
|
123
|
+
within('#actions_container') { click_button "Update" }
|
|
124
|
+
|
|
125
|
+
promotion = Spree::Promotion.find_by_name("Promotion")
|
|
126
|
+
expect(promotion.codes.first).to be_nil
|
|
127
|
+
|
|
128
|
+
first_rule = promotion.rules.first
|
|
129
|
+
expect(first_rule.class).to eq(Spree::Promotion::Rules::Product)
|
|
130
|
+
expect(first_rule.products.map(&:name)).to include("RoR Mug")
|
|
131
|
+
|
|
132
|
+
first_action = promotion.actions.first
|
|
133
|
+
expect(first_action.class).to eq(Spree::Promotion::Actions::CreateItemAdjustments)
|
|
134
|
+
first_action_calculator = first_action.calculator
|
|
135
|
+
expect(first_action_calculator.class).to eq(Spree::Calculator::PercentOnLineItem)
|
|
136
|
+
expect(first_action_calculator.preferred_percent).to eq(10)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
xit "should allow an admin to create an automatic promotion with free shipping (no code)" do
|
|
140
|
+
fill_in "Name", :with => "Promotion"
|
|
141
|
+
click_button "Create"
|
|
142
|
+
expect(page).to have_content("Editing Promotion")
|
|
143
|
+
|
|
144
|
+
select2 "Item total", :from => "Add rule of type"
|
|
145
|
+
within('#rule_fields') { click_button "Add" }
|
|
146
|
+
find('[id$=_preferred_amount]').set(30)
|
|
147
|
+
within('#rule_fields') { click_button "Update" }
|
|
148
|
+
|
|
149
|
+
select2 "Create whole-order adjustment", :from => "Add action of type"
|
|
150
|
+
within('#action_fields') { click_button "Add" }
|
|
151
|
+
select2 "Free Shipping", :from => "Calculator"
|
|
152
|
+
within('#actions_container') { click_button "Update" }
|
|
153
|
+
|
|
154
|
+
promotion = Spree::Promotion.find_by_name("Promotion")
|
|
155
|
+
expect(promotion.code.first.value).to be_blank
|
|
156
|
+
|
|
157
|
+
first_rule = promotion.rules.first
|
|
158
|
+
expect(first_rule.class).to eq(Spree::Promotion::Rules::ItemTotal)
|
|
159
|
+
|
|
160
|
+
first_action = promotion.actions.first
|
|
161
|
+
expect(first_action.class).to eq(Spree::Promotion::Actions::CreateAdjustment)
|
|
162
|
+
first_action_calculator = first_action.calculator
|
|
163
|
+
expect(first_action_calculator.class).to eq(Spree::Calculator::FreeShipping)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "should allow an admin to create an automatic promo requiring a landing page to be visited" do
|
|
167
|
+
fill_in "Name", :with => "Promotion"
|
|
168
|
+
fill_in "Path", :with => "content/cvv"
|
|
169
|
+
click_button "Create"
|
|
170
|
+
expect(page).to have_content("Editing Promotion")
|
|
171
|
+
|
|
172
|
+
select2 "Create whole-order adjustment", :from => "Add action of type"
|
|
173
|
+
within('#action_fields') { click_button "Add" }
|
|
174
|
+
select2 "Flat Rate", :from => "Calculator"
|
|
175
|
+
within('#actions_container') { click_button "Update" }
|
|
176
|
+
within('.calculator-fields') { fill_in "Amount", :with => "4" }
|
|
177
|
+
within('#actions_container') { click_button "Update" }
|
|
178
|
+
|
|
179
|
+
promotion = Spree::Promotion.find_by_name("Promotion")
|
|
180
|
+
expect(promotion.path).to eq("content/cvv")
|
|
181
|
+
expect(promotion.codes.first).to be_nil
|
|
182
|
+
expect(promotion.rules).to be_blank
|
|
183
|
+
|
|
184
|
+
first_action = promotion.actions.first
|
|
185
|
+
expect(first_action.class).to eq(Spree::Promotion::Actions::CreateAdjustment)
|
|
186
|
+
first_action_calculator = first_action.calculator
|
|
187
|
+
expect(first_action_calculator.class).to eq(Spree::Calculator::FlatRate)
|
|
188
|
+
expect(first_action_calculator.preferred_amount).to eq(4)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "ceasing to be eligible for a promotion with item total rule then becoming eligible again" do
|
|
192
|
+
fill_in "Name", :with => "Promotion"
|
|
193
|
+
click_button "Create"
|
|
194
|
+
expect(page).to have_content("Editing Promotion")
|
|
195
|
+
|
|
196
|
+
select2 "Item total", :from => "Add rule of type"
|
|
197
|
+
within('#rule_fields') { click_button "Add" }
|
|
198
|
+
find('[id$=_preferred_amount]').set(50)
|
|
199
|
+
within('#rule_fields') { click_button "Update" }
|
|
200
|
+
|
|
201
|
+
select2 "Create whole-order adjustment", :from => "Add action of type"
|
|
202
|
+
within('#action_fields') { click_button "Add" }
|
|
203
|
+
select2 "Flat Rate", :from => "Calculator"
|
|
204
|
+
within('#actions_container') { click_button "Update" }
|
|
205
|
+
within('.calculator-fields') { fill_in "Amount", :with => "5" }
|
|
206
|
+
within('#actions_container') { click_button "Update" }
|
|
207
|
+
|
|
208
|
+
promotion = Spree::Promotion.find_by_name("Promotion")
|
|
209
|
+
|
|
210
|
+
first_rule = promotion.rules.first
|
|
211
|
+
expect(first_rule.class).to eq(Spree::Promotion::Rules::ItemTotal)
|
|
212
|
+
expect(first_rule.preferred_amount).to eq(50)
|
|
213
|
+
|
|
214
|
+
first_action = promotion.actions.first
|
|
215
|
+
expect(first_action.class).to eq(Spree::Promotion::Actions::CreateAdjustment)
|
|
216
|
+
expect(first_action.calculator.class).to eq(Spree::Calculator::FlatRate)
|
|
217
|
+
expect(first_action.calculator.preferred_amount).to eq(5)
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
feature 'Promotion with option value rule' do
|
|
4
|
+
stub_authorization!
|
|
5
|
+
|
|
6
|
+
given(:variant) { create :variant }
|
|
7
|
+
given!(:product) { variant.product }
|
|
8
|
+
given!(:option_value) { variant.option_values.first }
|
|
9
|
+
|
|
10
|
+
given(:promotion) { create :promotion }
|
|
11
|
+
|
|
12
|
+
background do
|
|
13
|
+
visit spree.edit_admin_promotion_path(promotion)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
scenario "adding an option value rule", js: true do
|
|
17
|
+
select2 "Option Value(s)", from: "Add rule of type"
|
|
18
|
+
within("#rules_container") { click_button "Add" }
|
|
19
|
+
|
|
20
|
+
within("#rules_container .promotion-block") do
|
|
21
|
+
expect(page).to have_content("PRODUCT")
|
|
22
|
+
expect(page).to have_content("OPTION VALUES")
|
|
23
|
+
|
|
24
|
+
click_button "Add"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
within('.promo-rule-option-value') do
|
|
28
|
+
targetted_select2_search product.name, from: '.js-promo-rule-option-value-product-select'
|
|
29
|
+
targetted_select2_search option_value.name, from: '.js-promo-rule-option-value-option-values-select'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
within('#rules_container') { click_button "Update" }
|
|
33
|
+
|
|
34
|
+
first_rule = promotion.rules(true).first
|
|
35
|
+
expect(first_rule.class).to eq Spree::Promotion::Rules::OptionValue
|
|
36
|
+
expect(first_rule.preferred_eligible_values).to eq Hash[product.id => [option_value.id]]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "with an existing option value rule" do
|
|
40
|
+
given(:variant1) { create :variant }
|
|
41
|
+
given(:variant2) { create :variant }
|
|
42
|
+
background do
|
|
43
|
+
rule = Spree::Promotion::Rules::OptionValue.new
|
|
44
|
+
rule.promotion = promotion
|
|
45
|
+
rule.preferred_eligible_values = Hash[
|
|
46
|
+
variant1.product_id => variant1.option_values.pluck(:id),
|
|
47
|
+
variant2.product_id => variant2.option_values.pluck(:id)
|
|
48
|
+
]
|
|
49
|
+
rule.save!
|
|
50
|
+
|
|
51
|
+
visit spree.edit_admin_promotion_path(promotion)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
scenario "deleting a product", js: true do
|
|
55
|
+
within(".promo-rule-option-value:last-child") do
|
|
56
|
+
find(".remove").click
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
within('#rules_container') { click_button "Update" }
|
|
60
|
+
|
|
61
|
+
first_rule = promotion.rules(true).first
|
|
62
|
+
expect(first_rule.preferred_eligible_values).to eq Hash[variant1.product_id => variant1.option_values.pluck(:id)]
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
feature "Tiered Calculator Promotions" do
|
|
4
|
+
stub_authorization!
|
|
5
|
+
|
|
6
|
+
let(:promotion) { create :promotion }
|
|
7
|
+
|
|
8
|
+
background do
|
|
9
|
+
visit spree.edit_admin_promotion_path(promotion)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
scenario "adding a tiered percent calculator", js: true do
|
|
13
|
+
select2 "Create whole-order adjustment", from: "Add action of type"
|
|
14
|
+
within('#action_fields') { click_button "Add" }
|
|
15
|
+
|
|
16
|
+
select2 "Tiered Percent", from: "Calculator"
|
|
17
|
+
within('#actions_container') { click_button "Update" }
|
|
18
|
+
|
|
19
|
+
within("#actions_container .settings") do
|
|
20
|
+
expect(page).to have_content("BASE PERCENT")
|
|
21
|
+
expect(page).to have_content("TIERS")
|
|
22
|
+
|
|
23
|
+
click_button "Add"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
fill_in "Base Percent", with: 5
|
|
27
|
+
|
|
28
|
+
within(".tier") do
|
|
29
|
+
find("input:last-child").set(100)
|
|
30
|
+
find("input:first-child").set(10)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
within('#actions_container') { click_button "Update" }
|
|
34
|
+
|
|
35
|
+
first_action = promotion.actions.first
|
|
36
|
+
expect(first_action.class).to eq Spree::Promotion::Actions::CreateAdjustment
|
|
37
|
+
|
|
38
|
+
first_action_calculator = first_action.calculator
|
|
39
|
+
expect(first_action_calculator.class).to eq Spree::Calculator::TieredPercent
|
|
40
|
+
expect(first_action_calculator.preferred_base_percent).to eq 5
|
|
41
|
+
expect(first_action_calculator.preferred_tiers).to eq Hash[100.0 => 10.0]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "with an existing tiered flat rate calculator" do
|
|
45
|
+
let(:promotion) { create :promotion, :with_order_adjustment }
|
|
46
|
+
|
|
47
|
+
background do
|
|
48
|
+
action = promotion.actions.first
|
|
49
|
+
|
|
50
|
+
action.calculator = Spree::Calculator::TieredFlatRate.new
|
|
51
|
+
action.calculator.preferred_base_amount = 5
|
|
52
|
+
action.calculator.preferred_tiers = Hash[100 => 10, 200 => 15, 300 => 20]
|
|
53
|
+
action.calculator.save!
|
|
54
|
+
|
|
55
|
+
visit spree.edit_admin_promotion_path(promotion)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
scenario "deleting a tier", js: true do
|
|
59
|
+
within(".tier:nth-child(2)") do
|
|
60
|
+
find(".remove").click
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
within('#actions_container') { click_button "Update" }
|
|
64
|
+
|
|
65
|
+
calculator = promotion.actions.first.calculator
|
|
66
|
+
expect(calculator.preferred_tiers).to eq Hash[100.0 => 10.0, 300.0 => 20.0]
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe "Reports", :type => :feature do
|
|
4
|
+
stub_authorization!
|
|
5
|
+
|
|
6
|
+
context "visiting the admin reports page" do
|
|
7
|
+
it "should have the right content" do
|
|
8
|
+
visit spree.admin_path
|
|
9
|
+
click_link "Reports"
|
|
10
|
+
click_link "Sales Total"
|
|
11
|
+
|
|
12
|
+
expect(page).to have_content("Sales Totals")
|
|
13
|
+
expect(page).to have_content("Item Total")
|
|
14
|
+
expect(page).to have_content("Adjustment Total")
|
|
15
|
+
expect(page).to have_content("Sales Total")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context "searching the admin reports page" do
|
|
20
|
+
before do
|
|
21
|
+
order = create(:order)
|
|
22
|
+
order.update_columns({:adjustment_total => 100})
|
|
23
|
+
order.completed_at = Time.now
|
|
24
|
+
order.save!
|
|
25
|
+
|
|
26
|
+
order = create(:order)
|
|
27
|
+
order.update_columns({:adjustment_total => 200})
|
|
28
|
+
order.completed_at = Time.now
|
|
29
|
+
order.save!
|
|
30
|
+
|
|
31
|
+
#incomplete order
|
|
32
|
+
order = create(:order)
|
|
33
|
+
order.update_columns({:adjustment_total => 50})
|
|
34
|
+
order.save!
|
|
35
|
+
|
|
36
|
+
order = create(:order)
|
|
37
|
+
order.update_columns({:adjustment_total => 200})
|
|
38
|
+
order.completed_at = 3.years.ago
|
|
39
|
+
order.created_at = 3.years.ago
|
|
40
|
+
order.save!
|
|
41
|
+
|
|
42
|
+
order = create(:order)
|
|
43
|
+
order.update_columns({:adjustment_total => 200})
|
|
44
|
+
order.completed_at = 3.years.from_now
|
|
45
|
+
order.created_at = 3.years.from_now
|
|
46
|
+
order.save!
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "should allow me to search for reports" do
|
|
50
|
+
visit spree.admin_path
|
|
51
|
+
click_link "Reports"
|
|
52
|
+
click_link "Sales Total"
|
|
53
|
+
|
|
54
|
+
fill_in "q_completed_at_gt", :with => 1.week.ago
|
|
55
|
+
fill_in "q_completed_at_lt", :with => 1.week.from_now
|
|
56
|
+
click_button "Search"
|
|
57
|
+
|
|
58
|
+
expect(page).to have_content("$300.00")
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|