Files
openfoodnetwork/spec/archive/features/consumer/checkout_spec.rb
2014-03-26 12:17:49 +11:00

545 lines
23 KiB
Ruby

require "spec_helper"
feature %q{
As a consumer
I want to select a distributor for collection
So that I can pick up orders from the closest possible location
}, skip: true do
include AuthenticationWorkflow
include WebHelper
before :all do
@default_wait_time = Capybara.default_wait_time
Capybara.default_wait_time = 5
end
after :all do
Capybara.default_wait_time = @default_wait_time
end
background do
set_feature_toggle :order_cycles, true
Spree::Product.destroy_all
Spree::Order.destroy_all
Spree::LineItem.destroy_all
@distributor = create(:distributor_enterprise, :name => 'Edible garden',
:address => create(:address,
:address1 => '12 Bungee Rd',
:city => 'Carion',
:zipcode => 3056,
:state => Spree::State.find_by_name('Victoria'),
:country => Spree::Country.find_by_name('Australia')),
:pickup_times => 'Tuesday, 4 PM')
@distributor_alternative = create(:distributor_enterprise, :name => 'Alternative Distributor',
:address => create(:address,
:address1 => '1600 Rathdowne St',
:city => 'Carlton North',
:zipcode => 3054,
:state => Spree::State.find_by_name('Victoria'),
:country => Spree::Country.find_by_name('Australia')),
:pickup_times => 'Tuesday, 4 PM')
@enterprise_fee_1 = create(:enterprise_fee, :name => 'Enterprise Fee One', :calculator => Spree::Calculator::PerItem.new)
@enterprise_fee_1.calculator.set_preference :amount, 1
@enterprise_fee_1.calculator.save!
@enterprise_fee_2 = create(:enterprise_fee, :name => 'Enterprise Fee Two', :calculator => Spree::Calculator::PerItem.new)
@enterprise_fee_2.calculator.set_preference :amount, 2
@enterprise_fee_2.calculator.save!
@product_1 = create(:product, :name => 'Fuji apples')
@product_1.product_distributions.create(:distributor => @distributor, :enterprise_fee => @enterprise_fee_1)
@product_1.product_distributions.create(:distributor => @distributor_alternative, :enterprise_fee => @enterprise_fee_1)
@product_1a = create(:product, :name => 'Sundowner apples')
@product_1a.product_distributions.create(:distributor => @distributor, :enterprise_fee => @enterprise_fee_1)
@product_1a.product_distributions.create(:distributor => @distributor_alternative, :enterprise_fee => @enterprise_fee_1)
@product_2 = create(:product, :name => 'Garlic')
@product_2.product_distributions.create(:distributor => @distributor, :enterprise_fee => @enterprise_fee_2)
@product_2.product_distributions.create(:distributor => @distributor_alternative, :enterprise_fee => @enterprise_fee_2)
# -- Shipping
@zone = create(:zone)
c = Spree::Country.find_by_name('Australia')
Spree::ZoneMember.create(:zoneable => c, :zone => @zone)
sm = create(:shipping_method, zone: @zone, calculator: Spree::Calculator::FlatRate.new, require_ship_address: false)
sm.calculator.set_preference(:amount, 0); sm.calculator.save!
@payment_method_distributor = create(:payment_method, :name => 'Edible Garden payment method', :distributors => [@distributor])
@payment_method_alternative = create(:payment_method, :name => 'Alternative Distributor payment method', :distributors => [@distributor_alternative])
supplier = create(:supplier_enterprise)
@order_cycle = create(:simple_order_cycle, suppliers: [supplier], distributors: [@distributor], variants: [@product_1.master, @product_1a.master, @product_2.master])
@order_cycle.coordinator_fees << create(:enterprise_fee, enterprise: @order_cycle.coordinator)
end
scenario "viewing delivery fees for product distribution", :js => true, :to_figure_out => true do
# Given I am logged in
login_to_consumer_section
click_link 'Edible garden'
make_order_cycle
select_by_value @order_cycle.id, :from => 'order_order_cycle_id'
# When I add some apples and some garlic to my cart
click_link 'Fuji apples'
click_button 'Add To Cart'
visit enterprise_path @distributor1
click_link 'Garlic'
click_button 'Add To Cart'
# Then I should see a breakdown of my delivery fees:
checkout_fees_table.should ==
[['Fuji apples - sales fee by coordinator Edible garden', '$1.00', ''],
['Garlic - sales fee by coordinator Edible garden', '$1.00', '']]
page.should have_selector 'span.distribution-total', :text => '$2.00'
end
scenario "viewing delivery fees for order cycle distribution", :js => true do
# Given an order cycle
make_order_cycle
# And I am logged in
login_to_consumer_section
click_link "FruitAndVeg"
visit enterprise_path @distributor1
# When I add some bananas and zucchini to my cart
click_link 'Bananas'
click_button 'Add To Cart'
visit enterprise_path @distributor1
click_link 'Zucchini'
click_button 'Add To Cart'
# Then I should see a breakdown of my delivery fees:
checkout_fees_table.should ==
[["Bananas - packing fee by supplier Supplier 1", "$3.00", ""],
["Bananas - transport fee by supplier Supplier 1", "$4.00", ""],
["Bananas - packing fee by distributor FruitAndVeg", "$7.00", ""],
["Bananas - transport fee by distributor FruitAndVeg", "$8.00", ""],
["Zucchini - admin fee by supplier Supplier 2", "$5.00", ""],
["Zucchini - sales fee by supplier Supplier 2", "$6.00", ""],
["Zucchini - packing fee by distributor FruitAndVeg", "$7.00", ""],
["Zucchini - transport fee by distributor FruitAndVeg", "$8.00", ""],
["Whole order - admin fee by coordinator My coordinator", "$1.00", ""],
["Whole order - sales fee by coordinator My coordinator", "$2.00", ""]]
page.should have_selector 'span.distribution-total', :text => '$51.00'
end
scenario "attempting to purchase products that mix product and order cycle distribution", future: true do
# Given some products, one with product distribution only, (@product1)
# one with order cycle distribution only, (@product_oc)
supplier = create(:supplier_enterprise)
product_oc = create(:simple_product, name: 'Feijoas')
@order_cycle = create(:simple_order_cycle, suppliers: [supplier], distributors: [@distributor], variants: [product_oc.master], orders_close_at: Time.zone.now + 2.weeks)
@order_cycle.coordinator_fees << create(:enterprise_fee, enterprise: @order_cycle.coordinator)
# And I am logged in
login_to_consumer_section
click_link "Edible garden"
select_by_value @order_cycle.id, :from => 'order_order_cycle_id'
# When I add the first to my cart
click_link 'Fuji apples'
click_button 'Add To Cart'
click_link 'Continue shopping'
# And I attempt to add another
click_link 'Feijoas'
# Then I should see an error about changing order cycle
page.should have_content 'Please complete your order from your current order cycle before shopping in a different order cycle.'
end
scenario "removing a product from cart removes its fees", js: true, to_figure_out: true do
# Given I am logged in
login_to_consumer_section
click_link "Edible garden"
select_by_value @order_cycle.id, :from => 'order_order_cycle_id'
# When I add some apples and some garlic to my cart
click_link 'Fuji apples'
click_button 'Add To Cart'
click_link 'Continue shopping'
click_link 'Garlic'
click_button 'Add To Cart'
# And I remove the applies
line_item = Spree::Order.last.line_items.first
page.find("a#delete_line_item_#{line_item.id}").click
# Then I should see fees for only the garlic
checkout_fees_table.should ==
[['Garlic - transport fee by coordinator Edible garden', '$3.00', '']]
page.should have_selector 'span.distribution-total', :text => '$3.00'
end
scenario "adding products with differing quantities produces correct fees", js: true, :to_figure_out => true do
# Given I am logged in
login_to_consumer_section
click_link "Edible garden"
select_by_value @order_cycle.id, :from => 'order_order_cycle_id'
# When I add two products to my cart that share the same enterprise fee
click_link 'Fuji apples'
click_button 'Add To Cart'
click_link 'Continue shopping'
click_link 'Sundowner apples'
click_button 'Add To Cart'
# Then I should have some delivery fees
checkout_fees_table.should ==
[['Fuji apples - packing fee by coordinator Edible garden', '$4.00', ''],
['Sundowner apples - packing fee by coordinator Edible garden', '$4.00', '']]
page.should have_selector 'span.distribution-total', :text => '$8.00'
# And I update the quantity of one of them
fill_in 'order_line_items_attributes_0_quantity', with: 2
click_button 'Update'
# Then I should see updated delivery fees
checkout_fees_table.should ==
[['Fuji apples - packing fee by coordinator Edible garden', '$8.00', ''],
['Sundowner apples - packing fee by coordinator Edible garden', '$4.00', '']]
page.should have_selector 'span.distribution-total', :text => '$12.00'
end
scenario "changing distributor updates delivery fees", :future => true do
# Given two distributors and enterprise fees
d1 = create(:distributor_enterprise, :name => "FruitAndVeg")
create_enterprise_group_for d1
d2 = create(:distributor_enterprise)
ef1 = create(:enterprise_fee, calculator: Spree::Calculator::PerItem.new)
ef1.calculator.set_preference :amount, 1.23; ef1.calculator.save!
ef2 = create(:enterprise_fee, calculator: Spree::Calculator::PerItem.new)
ef2.calculator.set_preference :amount, 2.34; ef2.calculator.save!
# And two products both available from both distributors
p1 = create(:product)
create(:product_distribution, product: p1, distributor: d1, enterprise_fee: ef1)
create(:product_distribution, product: p1, distributor: d2, enterprise_fee: ef2)
p2 = create(:product)
create(:product_distribution, product: p2, distributor: d1, enterprise_fee: ef1)
create(:product_distribution, product: p2, distributor: d2, enterprise_fee: ef2)
# When I add the first product to my cart with the first distributor
#visit spree.root_path
login_to_consumer_section
click_link "FruitAndVeg"
click_link p1.name
click_button 'Add To Cart'
# Then I should see shipping costs for the first distributor
page.should have_selector 'span.distribution-total', text: '$1.23'
# When add the second with the second distributor
click_link 'Continue shopping'
click_link p2.name
click_button 'Add To Cart'
# Then I should see shipping costs for the second distributor
page.should have_selector 'span.distribution-total', text: '$4.68'
end
scenario "adding a product to cart after emptying cart shows correct delivery fees", js: true, :to_figure_out => true do
# When I add a product to my cart
login_to_consumer_section
click_link "Edible garden"
select_by_value @order_cycle.id, :from => 'order_order_cycle_id'
click_link @product_1.name
click_button 'Add To Cart'
# Then I should see the correct delivery fee
page.should have_selector 'span.grand-total', text: '$24.99'
# When I empty my cart and add the product again
click_button 'Empty Cart'
click_link 'Continue shopping'
click_link @product_1.name
click_button 'Add To Cart'
# Then I should see the correct delivery fee
page.should have_selector 'span.grand-total', text: '$24.99'
end
scenario "buying a product", :js => true, :to_figure_out => true do
login_to_consumer_section
click_link 'Edible garden'
select_by_value @order_cycle.id, :from => 'order_order_cycle_id'
click_link 'Fuji apples'
click_button 'Add To Cart'
click_link 'Continue shopping'
click_link 'Garlic'
click_button 'Add To Cart'
find('#checkout-link').click
# -- Checkout: Address
fill_in_fields('order_bill_address_attributes_firstname' => 'Joe',
'order_bill_address_attributes_lastname' => 'Luck',
'order_bill_address_attributes_address1' => '19 Sycamore Lane',
'order_bill_address_attributes_city' => 'Horse Hill',
'order_bill_address_attributes_zipcode' => '3213',
'order_bill_address_attributes_phone' => '12999911111')
select('Australia', :from => 'order_bill_address_attributes_country_id')
select('Victoria', :from => 'order_bill_address_attributes_state_id')
# Distributor details should be displayed
within('fieldset#shipping') do
[@distributor.name,
@distributor.distributor_info,
@distributor.next_collection_at
].each do |value|
page.should have_content value
end
end
# Disabled until this form takes order cycles into account
# page.should have_selector "select#order_distributor_id option[value='#{@distributor_alternative.id}']"
click_checkout_continue_button
# -- Checkout: Delivery
order_charges = page.all("tbody#summary-order-charges tr").map {|row| row.all('td').map(&:text)}.take(2)
order_charges.should == [["Shipping:", "$0.00"],
["Distribution:", "$12.00"]]
click_checkout_continue_button
# -- Checkout: Payment
# Given the distributor I have selected for my order, I should only see payment methods valid for that distributor
page.should have_selector 'label', :text => @payment_method_distributor.name
page.should_not have_selector 'label', :text => @payment_method_alternative.name
click_checkout_continue_button
# -- Checkout: Order complete
page.should have_content 'Your order has been processed successfully'
page.should have_content @payment_method_distributor.description
page.should have_selector 'tfoot#order-charges tr.total td', text: 'Distribution'
page.should have_selector 'tfoot#order-charges tr.total td', text: '12.00'
# -- Checkout: Email
email = ActionMailer::Base.deliveries.last
email.body.should =~ /Distribution[\s+]\$12.00/
end
scenario "buying a product from an order cycle", :js => true do
make_order_cycle
login_to_consumer_section
click_link 'FruitAndVeg'
visit enterprise_path @distributor1
click_link 'Bananas'
click_button 'Add To Cart'
visit enterprise_path @distributor1
click_link 'Zucchini'
click_button 'Add To Cart'
find('#checkout-link').click
# And manually visit the old checkout
visit "/checkout"
# -- Checkout: Address
fill_in_fields('order_bill_address_attributes_firstname' => 'Joe',
'order_bill_address_attributes_lastname' => 'Luck',
'order_bill_address_attributes_address1' => '19 Sycamore Lane',
'order_bill_address_attributes_city' => 'Horse Hill',
'order_bill_address_attributes_zipcode' => '3213',
'order_bill_address_attributes_phone' => '12999911111')
select('Australia', :from => 'order_bill_address_attributes_country_id')
select('Victoria', :from => 'order_bill_address_attributes_state_id')
# Distributor details should be displayed
within('fieldset#shipping') do
[@distributor_oc.name,
@distributor_oc.distributor_info,
@distributor_oc.next_collection_at
].each do |value|
page.should have_content value
end
end
# Disabled until this form takes order cycles into account
# page.should have_selector "select#order_distributor_id option[value='#{@distributor_alternative.id}']"
click_checkout_continue_button
# -- Checkout: Delivery
page.should have_content "DELIVERY METHOD"
order_charges = page.all("tbody#summary-order-charges tr").map {|row| row.all('td').map(&:text)}.take(2)
order_charges.should == [["Distribution:", "$51.00"]]
click_checkout_continue_button
# -- Checkout: Payment
# Given the distributor I have selected for my order, I should only see payment methods valid for that distributor
page.should have_content "PAYMENT INFORMATION"
page.should have_selector 'label', :text => @payment_method_distributor_oc.name
page.should_not have_selector 'label', :text => @payment_method_alternative.name
click_checkout_continue_button
# -- Checkout: Order complete
page.should have_content 'Your order has been processed successfully'
page.should have_content @payment_method_distributor_oc.description
page.should have_content @distributor_oc.name
page.should have_selector 'tfoot#order-charges tr.total td', text: 'Distribution'
page.should have_selector 'tfoot#order-charges tr.total td', text: '51.00'
# -- Checkout: Email
email = ActionMailer::Base.deliveries.last
email.reply_to.include?(@distributor_oc.email).should == true
email.body.should =~ /Distribution[\s+]\$51.00/
end
scenario "when I have past orders, it fills in my address", :js => true do
make_order_cycle
login_to_consumer_section
user = Spree::User.find_by_email 'someone@ofn.org'
o = create(:completed_order_with_totals, user: user,
bill_address: create(:address, firstname: 'Joe', lastname: 'Luck',
address1: '19 Sycamore Lane', city: 'Horse Hill',
zipcode: '3213', phone: '12999911111',
state: Spree::State.find_by_name('Victoria'),
country: Spree::Country.find_by_name('Australia')))
click_link 'FruitAndVeg'
click_link 'Sign Out'
click_link 'FruitAndVeg'
visit enterprise_path @distributor1
click_link 'Bananas'
click_button 'Add To Cart'
visit enterprise_path @distributor1
click_link 'Zucchini'
click_button 'Add To Cart'
find('#checkout-link').click
visit "/checkout" # Force to old checkout
# -- Login
# We perform login inline because:
# a) It's a common user flow
# b) It has been known to trigger errors with spree_last_address
fill_in 'spree_user_email', :with => 'someone@ofn.org'
fill_in 'spree_user_password', :with => 'passw0rd'
click_button 'Login'
visit "/checkout" # Force to old checkout
# -- Checkout: Address
page.should have_field 'order_bill_address_attributes_firstname', with: 'Joe'
page.should have_field 'order_bill_address_attributes_lastname', with: 'Luck'
page.should have_field 'order_bill_address_attributes_address1', with: '19 Sycamore Lane'
page.should have_field 'order_bill_address_attributes_city', with: 'Horse Hill'
page.should have_field 'order_bill_address_attributes_zipcode', with: '3213'
page.should have_field 'order_bill_address_attributes_phone', with: '12999911111'
page.should have_select 'order_bill_address_attributes_state_id', selected: 'Victoria'
page.should have_select 'order_bill_address_attributes_country_id', selected: 'Australia'
end
private
def make_order_cycle
@order_cycle = oc = create(:simple_order_cycle, coordinator: create(:distributor_enterprise, name: 'My coordinator'))
# Coordinator
coordinator_fee1 = create(:enterprise_fee, enterprise: oc.coordinator, fee_type: 'admin', calculator: Spree::Calculator::FlatRate.new(preferred_amount: 1))
coordinator_fee2 = create(:enterprise_fee, enterprise: oc.coordinator, fee_type: 'sales', calculator: Spree::Calculator::FlatRate.new(preferred_amount: 2))
oc.coordinator_fees << coordinator_fee1
oc.coordinator_fees << coordinator_fee2
# Suppliers
supplier1 = create(:supplier_enterprise, name: 'Supplier 1')
supplier2 = create(:supplier_enterprise, name: 'Supplier 2')
supplier_fee1 = create(:enterprise_fee, enterprise: supplier1, fee_type: 'packing', amount: 3)
supplier_fee2 = create(:enterprise_fee, enterprise: supplier1, fee_type: 'transport', amount: 4)
supplier_fee3 = create(:enterprise_fee, enterprise: supplier2, fee_type: 'admin', amount: 5)
supplier_fee4 = create(:enterprise_fee, enterprise: supplier2, fee_type: 'sales', amount: 6)
ex1 = create(:exchange, order_cycle: oc, sender: supplier1, receiver: oc.coordinator, incoming: true)
ex2 = create(:exchange, order_cycle: oc, sender: supplier2, receiver: oc.coordinator, incoming: true)
ExchangeFee.create!(exchange: ex1, enterprise_fee: supplier_fee1)
ExchangeFee.create!(exchange: ex1, enterprise_fee: supplier_fee2)
ExchangeFee.create!(exchange: ex2, enterprise_fee: supplier_fee3)
ExchangeFee.create!(exchange: ex2, enterprise_fee: supplier_fee4)
# Distributors
distributor1 = FactoryGirl.create(:distributor_enterprise, name: "FruitAndVeg")
@distributor1 = distributor1
distributor2 = FactoryGirl.create(:distributor_enterprise, name: "MoreFreshStuff")
create_enterprise_group_for distributor1
distributor_fee1 = create(:enterprise_fee, enterprise: distributor1, fee_type: 'packing', amount: 7)
distributor_fee2 = create(:enterprise_fee, enterprise: distributor1, fee_type: 'transport', amount: 8)
distributor_fee3 = create(:enterprise_fee, enterprise: distributor2, fee_type: 'admin', amount: 9)
distributor_fee4 = create(:enterprise_fee, enterprise: distributor2, fee_type: 'sales', amount: 10)
ex3 = create(:exchange, order_cycle: oc, incoming: false,
sender: oc.coordinator, receiver: distributor1,
pickup_time: 'time 0', pickup_instructions: 'instructions 0')
ex4 = create(:exchange, order_cycle: oc, incoming: false,
sender: oc.coordinator, receiver: distributor2,
pickup_time: 'time 1', pickup_instructions: 'instructions 1')
ExchangeFee.create!(exchange: ex3, enterprise_fee: distributor_fee1)
ExchangeFee.create!(exchange: ex3, enterprise_fee: distributor_fee2)
ExchangeFee.create!(exchange: ex4, enterprise_fee: distributor_fee3)
ExchangeFee.create!(exchange: ex4, enterprise_fee: distributor_fee4)
# Products
@distributor_oc = distributor1
@product_3 = create(:simple_product, name: 'Bananas', supplier: supplier1)
ex1.variants << @product_3.master
ex3.variants << @product_3.master
ex4.variants << @product_3.master
@product_4 = create(:simple_product, name: 'Zucchini', supplier: supplier2)
ex2.variants << @product_4.master
ex3.variants << @product_4.master
ex4.variants << @product_4.master
# Shipping method and payment method
sm = create(:shipping_method, zone: @zone, calculator: Spree::Calculator::FlatRate.new, distributors: [@distributor_oc], require_ship_address: false)
sm.calculator.set_preference(:amount, 0); sm.calculator.save!
@payment_method_distributor_oc = create(:payment_method, :name => 'FruitAndVeg payment method', :distributors => [@distributor_oc])
end
def checkout_fees_table
table = page.find 'tbody#cart_adjustments'
rows = table.all 'tr'
rows.map { |row| row.all('td').map { |cell| cell.text.strip } }
end
end