Files
openfoodnetwork/spec/features/admin/customers_spec.rb
Pau Perez 398467e7ed Hide new balance impl. under feature toggle
This makes it possible to deploy it without releasing it to users since
the toggle is not enabled for anyone.

It aims to make the balance calculation consistent across pages.
2021-01-11 15:50:19 +01:00

350 lines
13 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
feature 'Customers' do
include AdminHelper
include AuthenticationHelper
include WebHelper
context "as an enterprise user" do
let(:user) { create(:user, enterprise_limit: 10) }
let(:managed_distributor1) { create(:distributor_enterprise, owner: user) }
let(:managed_distributor2) { create(:distributor_enterprise, owner: user) }
let(:unmanaged_distributor) { create(:distributor_enterprise) }
describe "using the customers index", js: true do
let!(:customer1) { create(:customer, enterprise: managed_distributor1, code: nil) }
let!(:customer2) { create(:customer, enterprise: managed_distributor1, code: nil) }
let!(:customer3) { create(:customer, enterprise: unmanaged_distributor) }
let!(:customer4) { create(:customer, enterprise: managed_distributor2) }
before do
login_as user
visit admin_customers_path
end
it "passes the smoke test" do
# Prompts for a hub for a list of my managed enterprises
expect(page).to have_select2 "shop_id", with_options: [managed_distributor1.name, managed_distributor2.name], without_options: [unmanaged_distributor.name]
select2_select managed_distributor2.name, from: "shop_id"
# Loads the right customers
expect(page).to have_no_selector "tr#c_#{customer1.id}"
expect(page).to have_no_selector "tr#c_#{customer2.id}"
expect(page).to have_no_selector "tr#c_#{customer3.id}"
expect(page).to have_selector "tr#c_#{customer4.id}"
# Changing Shops
select2_select managed_distributor1.name, from: "shop_id"
# Loads the right customers
expect(page).to have_selector "tr#c_#{customer1.id}"
expect(page).to have_selector "tr#c_#{customer2.id}"
expect(page).to have_no_selector "tr#c_#{customer3.id}"
expect(page).to have_no_selector "tr#c_#{customer4.id}"
# Searching
fill_in "quick_search", with: customer2.email
expect(page).to have_no_selector "tr#c_#{customer1.id}"
expect(page).to have_selector "tr#c_#{customer2.id}"
fill_in "quick_search", with: ""
# Sorting when the header of a sortable column is clicked
customer_emails = [customer1.email, customer2.email].sort
within "#customers thead" do
click_on "Email"
end
expect(page).to have_selector("#customers .customer:nth-child(1) .email", text: customer_emails[0])
expect(page).to have_selector("#customers .customer:nth-child(2) .email", text: customer_emails[1])
# Then sorting in reverse when the header is clicked again
within "#customers thead" do
click_on "Email"
end
expect(page).to have_selector("#customers .customer:nth-child(1) .email", text: customer_emails[1])
expect(page).to have_selector("#customers .customer:nth-child(2) .email", text: customer_emails[0])
# Toggling columns
expect(page).to have_selector "th.email"
expect(page).to have_content customer1.email
toggle_columns "Email"
expect(page).to have_no_selector "th.email"
expect(page).to have_no_content customer1.email
# Deleting
create(:order, customer: customer1)
expect{
within "tr#c_#{customer1.id}" do
accept_alert do
find("a.delete-customer").click
end
end
expect(page).to have_selector "#info-dialog .text", text: I18n.t('admin.customers.destroy.has_associated_orders')
click_button "OK"
}.to_not change{ Customer.count }
expect{
within "tr#c_#{customer2.id}" do
accept_alert do
find("a.delete-customer").click
end
end
expect(page).to have_no_selector "tr#c_#{customer2.id}"
}.to change{ Customer.count }.by(-1)
end
describe "for a shop with multiple customers" do
before do
allow(OpenFoodNetwork::FeatureToggle)
.to receive(:enabled?).with(:customer_balance, user) { true }
create(
:order,
total: 0,
payment_total: 88,
distributor: managed_distributor1,
user: nil,
state: 'complete',
customer: customer1
)
create(
:order,
total: 99,
payment_total: 0,
distributor: managed_distributor1,
user: nil,
state: 'complete',
customer: customer2
)
create(
:order,
total: 0,
payment_total: 0,
distributor: managed_distributor1,
user: nil,
state: 'complete',
customer: customer4
)
customer4.update enterprise: managed_distributor1
end
it "displays customer balances" do
select2_select managed_distributor1.name, from: "shop_id"
within "tr#c_#{customer1.id}" do
expect(page).to have_content "CREDIT OWED"
expect(page).to have_content "$88.00"
end
within "tr#c_#{customer2.id}" do
expect(page).to have_content "BALANCE DUE"
expect(page).to have_content "$-99.00"
end
within "tr#c_#{customer4.id}" do
expect(page).to_not have_content "CREDIT OWED"
expect(page).to_not have_content "BALANCE DUE"
expect(page).to have_content "$0.00"
end
end
end
it "allows updating of attributes" do
select2_select managed_distributor1.name, from: "shop_id"
within "tr#c_#{customer1.id}" do
expect(find_field('name').value).to eq 'John Doe'
fill_in "code", with: "new-customer-code"
expect(page).to have_css "input[name=code].update-pending"
fill_in "name", with: "customer abc"
expect(page).to have_css "input[name=name].update-pending"
find(:css, "tags-input .tags input").set "awesome\n"
expect(page).to have_css ".tag_watcher.update-pending"
end
expect(page).to have_content I18n.t('admin.unsaved_changes')
click_button "Save Changes"
# Every says it updated
expect(page).to have_css "input[name=code].update-success"
expect(page).to have_css "input[name=name].update-success"
expect(page).to have_css ".tag_watcher.update-success"
# And it actually did
expect(customer1.reload.code).to eq "new-customer-code"
expect(customer1.reload.name).to eq "customer abc"
expect(customer1.tag_list).to eq ["awesome"]
# Clearing attributes
within "tr#c_#{customer1.id}" do
fill_in "code", with: ""
expect(page).to have_css "input[name=code].update-pending"
fill_in "name", with: ""
expect(page).to have_css "input[name=name].update-pending"
find("tags-input li.tag-item a.remove-button").click
expect(page).to have_css ".tag_watcher.update-pending"
end
click_button "Save Changes"
# Every says it updated
expect(page).to have_css "input[name=code].update-success"
expect(page).to have_css "input[name=name].update-success"
expect(page).to have_css ".tag_watcher.update-success"
# And it actually did
expect(customer1.reload.code).to be nil
expect(customer1.reload.name).to eq ''
expect(customer1.tag_list).to eq []
end
it "prevents duplicate codes from being saved" do
select2_select managed_distributor1.name, from: "shop_id"
within "tr#c_#{customer1.id}" do
fill_in "code", with: "new-customer-code"
expect(page).to have_css "input[name=code].update-pending"
end
click_button "Save Changes"
within "tr#c_#{customer1.id}" do
expect(page).to have_css "input[name=code].update-success"
end
within "tr#c_#{customer2.id}" do
fill_in "code", with: "new-customer-code"
expect(page).to have_content "This code is used already."
end
click_button "Save Changes"
within "tr#c_#{customer2.id}" do
expect(page).to have_css "input[name=code].update-error"
end
expect(page).to have_content "Oh no! I was unable to save your changes"
expect(customer1.reload.code).to eq "new-customer-code"
expect(customer2.reload.code).to be nil
end
describe 'updating a customer addresses' do
before do
select2_select managed_distributor2.name, from: "shop_id"
end
it 'updates the existing billing address' do
expect(page).to have_content 'BILLING ADDRESS'
first('#bill-address-link').click
wait_for_modal_fade_in
expect(page).to have_content 'Edit Billing Address'
expect(page).to have_select2 'country_id', selected: 'Australia'
expect(page).to have_select2 'state_id', selected: 'Victoria'
fill_in 'address1', with: ""
click_button 'Update Address'
expect(page).to have_content 'Please input all of the required fields'
fill_in 'address1', with: "New Address1"
click_button 'Update Address'
expect(page).to have_content 'Address updated successfully.'
expect(page).to have_link 'New Address1'
expect(customer4.reload.bill_address.address1).to eq 'New Address1'
first('#bill-address-link').click
expect(page).to have_content 'Edit Billing Address'
expect(page).to_not have_content 'Please input all of the required fields'
end
it 'creates a new shipping address' do
expect(page).to have_content 'SHIPPING ADDRESS'
first('#ship-address-link').click
wait_for_modal_fade_in
expect(page).to have_content 'Edit Shipping Address'
fill_in 'firstname', with: "First"
fill_in 'lastname', with: "Last"
fill_in 'address1', with: "New Address1"
fill_in 'phone', with: "12345678"
fill_in 'city', with: "Melbourne"
fill_in 'zipcode', with: "3000"
select2_select 'Australia', from: 'country_id'
select2_select 'Victoria', from: 'state_id'
click_button 'Update Address'
expect(page).to have_content 'Address updated successfully.'
expect(page).to have_link 'New Address1'
ship_address = customer4.reload.ship_address
expect(ship_address.firstname).to eq 'First'
expect(ship_address.lastname).to eq 'Last'
expect(ship_address.address1).to eq 'New Address1'
expect(ship_address.phone).to eq '12345678'
expect(ship_address.city).to eq 'Melbourne'
end
# Modal animations are defined in:
# app/assets/javascripts/admin/utils/services/dialog_defaults.js.coffee
#
# Without waiting, `fill_in` can fail randomly:
# https://github.com/teamcapybara/capybara/issues/1890
def wait_for_modal_fade_in(time = 0.4)
sleep time
end
end
describe "creating a new customer" do
context "when no shop has been selected" do
it "asks the user to select a shop" do
accept_alert 'Please select a shop first' do
click_link('New Customer')
end
end
end
context "when a shop is selected" do
before do
select2_select managed_distributor1.name, from: "shop_id"
end
it "creates customers when the email provided is valid" do
# When an invalid email is used
expect{
click_link('New Customer')
fill_in 'email', with: "not_an_email"
click_button 'Add Customer'
expect(page).to have_selector "#new-customer-dialog .error", text: "Please enter a valid email address"
}.to_not change{ Customer.of(managed_distributor1).count }
# When an existing email is used
expect{
fill_in 'email', with: customer1.email
click_button 'Add Customer'
expect(page).to have_selector "#new-customer-dialog .error", text: "Email is associated with an existing customer"
}.to_not change{ Customer.of(managed_distributor1).count }
# When a new valid email is used
expect{
fill_in 'email', with: "new@email.com"
click_button 'Add Customer'
expect(page).not_to have_selector "#new-customer-dialog"
}.to change{ Customer.of(managed_distributor1).count }.from(2).to(3)
end
end
end
end
end
end