mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-25 20:46:48 +00:00
Capybara helpers already wait for the content to show up (and we already have a default of 10 seconds configured), so I don't think waiting more is actually the problem in these specs. But if we wanted to wait more, I think it's better to pass the `:wait` option to capybara matchers, because that's a "maximum waiting value" but we'll still proceed earlier if the content shows up. Using the same idea, I changed the positive assertions to happen first, because negative assertions do spend "max wait time" waiting, while positive assertions only wait until the content shows up.
951 lines
41 KiB
Ruby
951 lines
41 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'system_helper'
|
|
|
|
RSpec.describe '
|
|
As an administrator
|
|
I want to manage simple order cycles
|
|
' do
|
|
include AdminHelper
|
|
include AuthenticationHelper
|
|
include WebHelper
|
|
|
|
it "updating many order cycle opening/closing times at once" do
|
|
# Given three order cycles
|
|
oc1 = create(:simple_order_cycle,
|
|
orders_open_at: Time.zone.local(2000, 12, 12, 12, 12, 0),
|
|
orders_close_at: Time.zone.local(2041, 12, 12, 12, 12, 1))
|
|
oc2 = create(:simple_order_cycle,
|
|
orders_open_at: Time.zone.local(2000, 12, 12, 12, 12, 2),
|
|
orders_close_at: Time.zone.local(2041, 12, 12, 12, 12, 3))
|
|
oc3 = create(:simple_order_cycle,
|
|
orders_open_at: Time.zone.local(2040, 12, 12, 12, 12, 4),
|
|
orders_close_at: Time.zone.local(2041, 12, 12, 12, 12, 5))
|
|
|
|
# When I go to the order cycles page
|
|
login_as_admin
|
|
visit admin_order_cycles_path
|
|
|
|
## -- OC1
|
|
find("input#oc#{oc1.id}_name").set ""
|
|
fill_in("oc#{oc1.id}_name", with: "Updated Order Cycle 1")
|
|
|
|
## -- OC2
|
|
fill_in("oc#{oc2.id}_name", with: "Updated Order Cycle 2")
|
|
within("tr.order-cycle-#{oc2.id} .orders_open_at") do
|
|
find('input.datetimepicker', match: :first).click
|
|
end
|
|
|
|
within(".flatpickr-calendar.open") do
|
|
# Then select first of month
|
|
find('.dayContainer .flatpickr-day', text: "1").click
|
|
end
|
|
|
|
within("tr.order-cycle-#{oc2.id}") do
|
|
# Then that date/time should appear on the form
|
|
expect(find("input#oc#{oc2.id}_orders_open_at").value).to eq "2000-12-01 12:12"
|
|
end
|
|
|
|
# -- OC3
|
|
fill_in("oc#{oc3.id}_name", with: "Updated Order Cycle 3")
|
|
within("tr.order-cycle-#{oc3.id} .orders_close_at") do
|
|
find('input.datetimepicker', match: :first).click
|
|
end
|
|
|
|
within(".flatpickr-calendar.open") do
|
|
# Then select first of month
|
|
find('.dayContainer .flatpickr-day', text: "1").click
|
|
end
|
|
|
|
within("tr.order-cycle-#{oc3.id}") do
|
|
expect(find("input#oc#{oc3.id}_orders_close_at").value).to eq "2041-12-01 12:12"
|
|
end
|
|
|
|
click_button 'Save Changes'
|
|
|
|
# Then my details should have been saved
|
|
expect(page).to have_selector "#save-bar", text: "Order cycles have been updated."
|
|
order_cycles = OrderCycle.order("id ASC")
|
|
expect(order_cycles.map(&:name)).to eq ["Updated Order Cycle 1", "Updated Order Cycle 2",
|
|
"Updated Order Cycle 3"]
|
|
expect(order_cycles.map { |oc| oc.orders_open_at.sec }).to eq [0, 0, 4]
|
|
expect(order_cycles.map { |oc| oc.orders_close_at.sec }).to eq [1, 3, 0]
|
|
end
|
|
|
|
it "cloning an order cycle" do
|
|
# Given an order cycle
|
|
oc = create(:simple_order_cycle)
|
|
|
|
# When I clone it
|
|
login_as_admin
|
|
visit admin_order_cycles_path
|
|
within "tr.order-cycle-#{oc.id}" do
|
|
find('a.clone-order-cycle').click
|
|
end
|
|
expect(flash_message).to eq "Your order cycle #{oc.name} has been cloned."
|
|
|
|
# Then I should have clone of the order cycle
|
|
occ = OrderCycle.last
|
|
expect(occ.name).to eq "COPY OF #{oc.name}"
|
|
end
|
|
|
|
describe "ensuring that hubs in order cycles have valid shipping and payment methods" do
|
|
context "when they don't" do
|
|
let(:hub) { create(:distributor_enterprise) }
|
|
let!(:oc) { create(:simple_order_cycle, distributors: [hub]) }
|
|
|
|
it "displays a warning on the dashboard" do
|
|
login_to_admin_section
|
|
expect(page).to have_content(
|
|
"The hub #{hub.name} is listed in an active order cycle, but does not have valid " \
|
|
"shipping and payment methods. Until you set these up, customers will not be able " \
|
|
"to shop at this hub."
|
|
)
|
|
end
|
|
|
|
it "displays a warning on the order cycles screen" do
|
|
login_as_admin
|
|
visit admin_order_cycles_path
|
|
expect(page).to have_content(
|
|
"The hub #{hub.name} is listed in an active order cycle, " \
|
|
"but does not have valid shipping and payment methods. Until you set these up, " \
|
|
"customers will not be able to shop at this hub."
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when they do" do
|
|
let(:hub) { create(:distributor_enterprise, with_payment_and_shipping: true) }
|
|
let!(:oc) { create(:simple_order_cycle, distributors: [hub]) }
|
|
|
|
it "does not display the warning on the dashboard" do
|
|
login_to_admin_section
|
|
expect(page).not_to have_content "does not have valid shipping and payment methods"
|
|
end
|
|
end
|
|
end
|
|
|
|
context "as an enterprise user" do
|
|
let!(:supplier_managed) { create(:supplier_enterprise, name: 'Managed supplier') }
|
|
let!(:supplier_unmanaged) { create(:supplier_enterprise, name: 'Unmanaged supplier') }
|
|
let!(:supplier_permitted) { create(:supplier_enterprise, name: 'Permitted supplier') }
|
|
let!(:distributor_managed) { create(:distributor_enterprise, name: 'Managed distributor') }
|
|
let!(:other_distributor_managed) {
|
|
create(:distributor_enterprise, name: 'Other Managed distributor')
|
|
}
|
|
let!(:distributor_unmanaged) { create(:distributor_enterprise, name: 'Unmanaged Distributor') }
|
|
let!(:distributor_permitted) { create(:distributor_enterprise, name: 'Permitted distributor') }
|
|
let!(:distributor_managed_fee) {
|
|
create(:enterprise_fee, enterprise: distributor_managed, name: 'Managed distributor fee')
|
|
}
|
|
let!(:supplier_permitted_fee1) {
|
|
create(:enterprise_fee, :per_item, enterprise: supplier_permitted,
|
|
name: 'Supplier distributor fee1')
|
|
}
|
|
let!(:supplier_permitted_fee2) {
|
|
create(:enterprise_fee, :flat_rate, enterprise: supplier_permitted,
|
|
name: 'Supplier distributor fee2')
|
|
}
|
|
let!(:supplier_permitted_fee3) {
|
|
create(:enterprise_fee, :per_item, enterprise: supplier_permitted,
|
|
name: 'Supplier distributor fee3')
|
|
}
|
|
let!(:supplier_permitted_fee4) {
|
|
create(:enterprise_fee, :flat_rate, enterprise: supplier_permitted,
|
|
name: 'Supplier distributor fee4')
|
|
}
|
|
let!(:distributor_permitted_fee1) {
|
|
create(:enterprise_fee, :per_item, enterprise: distributor_permitted,
|
|
name: 'Distributor distributor fee1')
|
|
}
|
|
let!(:distributor_permitted_fee2) {
|
|
create(:enterprise_fee, :flat_rate, enterprise: distributor_permitted,
|
|
name: 'Distributor distributor fee2')
|
|
}
|
|
let!(:distributor_permitted_fee3) {
|
|
create(:enterprise_fee, :per_item, enterprise: distributor_permitted,
|
|
name: 'Distributor distributor fee3')
|
|
}
|
|
let!(:distributor_permitted_fee4) {
|
|
create(:enterprise_fee, :flat_rate, enterprise: distributor_permitted,
|
|
name: 'Distributor distributor fee4')
|
|
}
|
|
let!(:shipping_method) {
|
|
create(:shipping_method,
|
|
distributors: [distributor_managed, distributor_unmanaged, distributor_permitted])
|
|
}
|
|
let!(:payment_method) {
|
|
create(:payment_method,
|
|
distributors: [distributor_managed, distributor_unmanaged, distributor_permitted])
|
|
}
|
|
let!(:variant_managed) { create(:variant, supplier: supplier_managed) }
|
|
let!(:variant_permitted) { create(:variant, supplier: supplier_permitted) }
|
|
let!(:schedule) {
|
|
create(:schedule, name: 'Schedule1',
|
|
order_cycles: [
|
|
create(:simple_order_cycle, coordinator: distributor_managed)
|
|
])
|
|
}
|
|
let!(:schedule_of_other_managed_distributor) {
|
|
create(:schedule, name: 'Other Schedule',
|
|
order_cycles: [
|
|
create(:simple_order_cycle, coordinator: other_distributor_managed)
|
|
])
|
|
}
|
|
|
|
before do
|
|
# Relationships required for interface to work
|
|
# Both suppliers allow both managed distributor to distribute their products
|
|
# (and add them to the order cycle)
|
|
create(:enterprise_relationship, parent: supplier_managed, child: distributor_managed,
|
|
permissions_list: [:add_to_order_cycle])
|
|
create(:enterprise_relationship, parent: supplier_permitted, child: distributor_managed,
|
|
permissions_list: [:add_to_order_cycle])
|
|
|
|
# Both suppliers allow permitted distributor to distribute their products
|
|
create(:enterprise_relationship, parent: supplier_managed, child: distributor_permitted,
|
|
permissions_list: [:add_to_order_cycle])
|
|
create(:enterprise_relationship, parent: supplier_permitted, child: distributor_permitted,
|
|
permissions_list: [:add_to_order_cycle])
|
|
|
|
# Permitted distributor can be added to the order cycle
|
|
create(:enterprise_relationship, parent: distributor_permitted, child: distributor_managed,
|
|
permissions_list: [:add_to_order_cycle])
|
|
end
|
|
|
|
context "that is a manager of the coordinator" do
|
|
before do
|
|
new_user = create(:user)
|
|
new_user.enterprise_roles.build(enterprise: supplier_managed).save
|
|
new_user.enterprise_roles.build(enterprise: distributor_managed).save
|
|
new_user.enterprise_roles.build(enterprise: other_distributor_managed).save
|
|
|
|
login_as new_user
|
|
end
|
|
|
|
it "viewing a list of order cycles I am coordinating" do
|
|
oc_user_coordinating = create(:simple_order_cycle,
|
|
suppliers: [supplier_managed, supplier_unmanaged],
|
|
coordinator: distributor_managed,
|
|
distributors: [distributor_managed, distributor_unmanaged],
|
|
name: 'Order Cycle 1')
|
|
oc_for_other_user = create(:simple_order_cycle, coordinator: supplier_unmanaged,
|
|
name: 'Order Cycle 2' )
|
|
|
|
visit spree.admin_dashboard_path
|
|
click_link "Order cycles"
|
|
|
|
# I should see only the order cycle I am coordinating
|
|
expect(page).to have_selector "tr.order-cycle-#{oc_user_coordinating.id}"
|
|
expect(page).not_to have_selector "tr.order-cycle-#{oc_for_other_user.id}"
|
|
|
|
toggle_columns "Producers", "Shops"
|
|
|
|
# The order cycle should show all enterprises in the order cycle
|
|
expect(page).to have_selector 'td.producers', text: supplier_managed.name
|
|
expect(page).to have_selector 'td.shops', text: distributor_managed.name
|
|
expect(page).to have_selector 'td.producers', text: supplier_unmanaged.name
|
|
expect(page).to have_selector 'td.shops', text: distributor_unmanaged.name
|
|
end
|
|
|
|
it "creating a new order cycle" do
|
|
distributor_managed.update_attribute(:enable_subscriptions, true)
|
|
visit admin_order_cycles_path
|
|
click_link 'New Order Cycle'
|
|
|
|
[distributor_unmanaged.name, supplier_managed.name,
|
|
supplier_unmanaged.name].each do |enterprise_name|
|
|
expect(page).not_to have_select 'coordinator_id', with_options: [enterprise_name]
|
|
end
|
|
select2_select 'Managed distributor', from: 'coordinator_id'
|
|
click_button "Continue >"
|
|
|
|
fill_in 'order_cycle_name', with: 'My order cycle'
|
|
fill_in 'order_cycle_orders_open_at', with: '2040-11-06 06:00:00'
|
|
fill_in 'order_cycle_orders_close_at', with: '2040-11-13 17:00:00'
|
|
expect(page).not_to have_select2 'schedule_ids',
|
|
with_options: [schedule_of_other_managed_distributor.name]
|
|
select2_select schedule.name, from: 'schedule_ids'
|
|
|
|
click_button 'Add coordinator fee'
|
|
select 'Managed distributor fee', from: 'order_cycle_coordinator_fee_0_id'
|
|
|
|
click_button 'Create'
|
|
expect(page).to have_content 'Your order cycle has been created.'
|
|
click_button "Dismiss"
|
|
|
|
expect(page).to have_select 'new_supplier_id', with_options: [
|
|
"Managed supplier",
|
|
"Permitted supplier",
|
|
]
|
|
expect(page).not_to have_select 'new_supplier_id', with_options: [
|
|
"Unmanaged supplier",
|
|
]
|
|
select 'Managed supplier', from: 'new_supplier_id'
|
|
click_button 'Add supplier'
|
|
select 'Permitted supplier', from: 'new_supplier_id'
|
|
click_button 'Add supplier'
|
|
expect(page).to have_content "Permitted supplier"
|
|
|
|
within("tr.supplier-#{supplier_permitted.id}") { click_button 'Add fee' }
|
|
expect(page).to have_select(
|
|
"order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_id", minimum: 1
|
|
)
|
|
select "Permitted supplier",
|
|
from: "order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_id"
|
|
expect(page).to have_select(
|
|
"order_cycle_incoming_exchange_1_enterprise_fees_0_enterprise_fee_id",
|
|
options: ["", supplier_permitted_fee1.name, supplier_permitted_fee3.name]
|
|
)
|
|
|
|
select_incoming_variant supplier_managed, 0, variant_managed
|
|
select_incoming_variant supplier_permitted, 1, variant_permitted
|
|
|
|
click_button 'Save and Next'
|
|
expect(page).to have_content 'Your order cycle has been updated.'
|
|
expect(page).not_to have_content "Loading..."
|
|
|
|
expect(page).to have_select 'new_distributor_id'
|
|
expect(page).not_to have_select 'new_distributor_id',
|
|
with_options: [distributor_unmanaged.name]
|
|
select 'Managed distributor', from: 'new_distributor_id'
|
|
click_button 'Add distributor'
|
|
select 'Permitted distributor', from: 'new_distributor_id'
|
|
click_button 'Add distributor'
|
|
expect(page).to have_content "Permitted distributor"
|
|
|
|
within("tr.distributor-#{distributor_permitted.id}") { click_button 'Add fee' }
|
|
expect(page).to have_select(
|
|
"order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_id", minimum: 1
|
|
)
|
|
select "Permitted distributor",
|
|
from: "order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_id"
|
|
expect(page).to have_select(
|
|
"order_cycle_outgoing_exchange_1_enterprise_fees_0_enterprise_fee_id",
|
|
options: ["", distributor_permitted_fee1.name, distributor_permitted_fee2.name,
|
|
distributor_permitted_fee3.name, distributor_permitted_fee4.name]
|
|
)
|
|
|
|
expect(page).to have_input 'order_cycle_outgoing_exchange_0_pickup_time'
|
|
fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time'
|
|
fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions'
|
|
|
|
expect(page).to have_input 'order_cycle_outgoing_exchange_1_pickup_time'
|
|
fill_in 'order_cycle_outgoing_exchange_1_pickup_time', with: 'pickup time 2'
|
|
fill_in 'order_cycle_outgoing_exchange_1_pickup_instructions', with: 'pickup instructions'
|
|
|
|
page.find("table.exchanges tr.distributor-#{distributor_managed.id} td.tags").click
|
|
within ".exchange-tags" do
|
|
find(:css, "tags-input .tags input").set "wholesale\n"
|
|
end
|
|
|
|
click_button 'Save and Next'
|
|
|
|
expect_shipping_methods_to_be_checked_for(distributor_managed)
|
|
expect_shipping_methods_to_be_checked_for(distributor_permitted)
|
|
expect_payment_methods_to_be_checked_for(distributor_managed)
|
|
expect_payment_methods_to_be_checked_for(distributor_permitted)
|
|
|
|
click_button 'Save and Back to List'
|
|
order_cycle = OrderCycle.find_by(name: 'My order cycle')
|
|
expect(page).to have_input "oc#{order_cycle.id}[name]", value: order_cycle.name
|
|
|
|
expect(order_cycle.suppliers).to match_array [supplier_managed, supplier_permitted]
|
|
expect(order_cycle.coordinator).to eq(distributor_managed)
|
|
expect(order_cycle.distributors)
|
|
.to match_array [distributor_managed, distributor_permitted]
|
|
expect(order_cycle.schedules).to eq([schedule])
|
|
exchange = order_cycle.exchanges.outgoing.to_enterprise(distributor_managed).first
|
|
expect(exchange.tag_list).to eq(["wholesale"])
|
|
expect(order_cycle.distributor_shipping_methods).to match_array(
|
|
order_cycle.attachable_distributor_shipping_methods
|
|
)
|
|
expect(order_cycle.distributor_payment_methods).to match_array(
|
|
order_cycle.attachable_distributor_payment_methods
|
|
)
|
|
end
|
|
|
|
context "editing an order cycle" do
|
|
let(:oc) do
|
|
create(:simple_order_cycle, suppliers: [
|
|
supplier_managed, supplier_permitted, supplier_unmanaged
|
|
],
|
|
coordinator: distributor_managed,
|
|
distributors: [
|
|
distributor_managed,
|
|
distributor_permitted,
|
|
distributor_unmanaged
|
|
],
|
|
name: 'Order Cycle 1' )
|
|
end
|
|
|
|
before { distributor_managed.update_attribute(:enable_subscriptions, true) }
|
|
|
|
it "shows if notifications have been sent" do
|
|
oc.update_columns mails_sent: true
|
|
|
|
visit edit_admin_order_cycle_path(oc)
|
|
|
|
expect(page).to have_content "Re notify producers"
|
|
end
|
|
|
|
it "allows removing exchanges" do
|
|
visit edit_admin_order_cycle_path(oc)
|
|
|
|
expect(page).to have_field 'order_cycle_name', with: oc.name
|
|
select2_select schedule.name, from: 'schedule_ids'
|
|
expect(page)
|
|
.not_to have_select2 'schedule_ids',
|
|
with_options: [schedule_of_other_managed_distributor.name]
|
|
|
|
click_button 'Save and Next'
|
|
|
|
# When I remove all incoming exchanges
|
|
page.find("tr.supplier-#{supplier_managed.id} a.remove-exchange").click
|
|
page.find("tr.supplier-#{supplier_permitted.id} a.remove-exchange").click
|
|
click_button 'Save and Next'
|
|
|
|
# And I remove all outgoing exchanges
|
|
page.find("tr.distributor-#{distributor_managed.id} a.remove-exchange").click
|
|
page.find("tr.distributor-#{distributor_permitted.id} a.remove-exchange").click
|
|
click_button 'Save and Next'
|
|
click_button 'Save and Back to List'
|
|
expect(page).to have_input "oc#{oc.id}[name]", value: oc.name
|
|
|
|
oc.reload
|
|
expect(oc.suppliers).to eq([supplier_unmanaged])
|
|
expect(oc.coordinator).to eq(distributor_managed)
|
|
expect(oc.distributors).to eq([distributor_unmanaged])
|
|
expect(oc.schedules).to eq([schedule])
|
|
end
|
|
end
|
|
|
|
context "when variants are hidden via inventory settings" do
|
|
let(:oc) do
|
|
create(:simple_order_cycle, suppliers: [supplier_managed],
|
|
coordinator: distributor_managed,
|
|
distributors: [distributor_managed],
|
|
name: 'Order Cycle 1' )
|
|
end
|
|
let(:v1) { create(:variant, supplier: supplier_managed) }
|
|
let(:inventory_item_v1) {
|
|
create(:inventory_item, enterprise: distributor_managed, variant: v1, visible: false)
|
|
}
|
|
before do
|
|
# Incoming exchange
|
|
ex_in = oc.exchanges.where(sender_id: supplier_managed, receiver_id: distributor_managed,
|
|
incoming: true).first
|
|
ex_in.update(variant_ids: [v1.id])
|
|
ex_in.save!
|
|
|
|
# Outgoing exchange
|
|
ex_out = oc.exchanges.where(sender_id: distributor_managed,
|
|
receiver_id: distributor_managed, incoming: false).first
|
|
ex_out.update(variant_ids: [v1.id,])
|
|
v1.inventory_items = [inventory_item_v1]
|
|
ex_out.save!
|
|
|
|
# hide via inventory settings variant v1
|
|
distributor_managed.update preferred_product_selection_from_inventory_only: true
|
|
oc.update prefers_product_selection_from_coordinator_inventory_only: false
|
|
end
|
|
|
|
it "shows a warning when going to 'outgoing products' tab" do
|
|
# hides/displays variant within coordinator's inventory
|
|
inventory_item_v1.update!(visible: false)
|
|
# changes coordinator's inventory preferences
|
|
supplier_managed.update preferred_product_selection_from_inventory_only: true
|
|
|
|
visit edit_admin_order_cycle_path(oc)
|
|
click_link "Outgoing Products"
|
|
expect(page).to have_content "Managed distributor"
|
|
within "tr.distributor-#{distributor_managed.id}" do
|
|
page.find("td.products").click
|
|
end
|
|
|
|
# we need this assertion here to assure there is enough time to
|
|
# toggle the variant box and evaluate the following assertion
|
|
expect(page).to have_content v1.product.name
|
|
end
|
|
|
|
it "doesn't show a warning when going to 'outgoing products' tab" do
|
|
pending("#11851")
|
|
|
|
# hides/displays variant within coordinator's inventory
|
|
inventory_item_v1.update!(visible: false)
|
|
# changes coordinator's inventory preferences
|
|
supplier_managed.update preferred_product_selection_from_inventory_only: false
|
|
|
|
visit edit_admin_order_cycle_path(oc)
|
|
click_link "Outgoing Products"
|
|
within "tr.distributor-#{distributor_managed.id}" do
|
|
page.find("td.products").click
|
|
end
|
|
|
|
# we need this assertion here to assure there is enough time to
|
|
# toggle the variant box and evaluate the following assertion
|
|
expect(page).to have_content v1.product.name
|
|
|
|
expect(page).not_to have_content "No variant available for this product"
|
|
expect(page).to have_content "(Some variants might be hidden via inventory settings)"
|
|
end
|
|
end
|
|
|
|
it "cloning an order cycle" do
|
|
oc = create(:simple_order_cycle, coordinator: distributor_managed)
|
|
|
|
visit admin_order_cycles_path
|
|
within "tr.order-cycle-#{oc.id}" do
|
|
find('a.clone-order-cycle').click
|
|
end
|
|
expect(flash_message).to eq "Your order cycle #{oc.name} has been cloned."
|
|
|
|
# Then I should have clone of the order cycle
|
|
occ = OrderCycle.last
|
|
expect(occ.name).to eq("COPY OF #{oc.name}")
|
|
end
|
|
end
|
|
|
|
context "that is a manager of a participating producer" do
|
|
let(:new_user) { create(:user) }
|
|
|
|
before do
|
|
new_user.enterprise_roles.build(enterprise: supplier_managed).save
|
|
login_as new_user
|
|
end
|
|
|
|
it "editing an order cycle" do
|
|
oc = create(:simple_order_cycle,
|
|
suppliers: [supplier_managed, supplier_permitted, supplier_unmanaged],
|
|
coordinator: distributor_managed, distributors: [
|
|
distributor_managed,
|
|
distributor_permitted,
|
|
distributor_unmanaged
|
|
], name: 'Order Cycle 1')
|
|
v1 = create(:variant, supplier: supplier_managed)
|
|
v2 = create(:variant, supplier: supplier_managed)
|
|
|
|
# Incoming exchange
|
|
ex_in = oc.exchanges.where(sender_id: supplier_managed, receiver_id: distributor_managed,
|
|
incoming: true).first
|
|
ex_in.update(variant_ids: [v1.id, v2.id])
|
|
|
|
# Outgoing exchange
|
|
ex_out = oc.exchanges.where(sender_id: distributor_managed,
|
|
receiver_id: distributor_managed, incoming: false).first
|
|
ex_out.update(variant_ids: [v1.id, v2.id])
|
|
|
|
# Stub editable_variants_for_outgoing_exchanges method so we can test permissions
|
|
serializer = Api::Admin::OrderCycleSerializer.new(oc, current_user: new_user)
|
|
allow(Api::Admin::OrderCycleSerializer).to receive(:new) { serializer }
|
|
allow(serializer).to receive(:editable_variants_for_outgoing_exchanges) do
|
|
{ distributor_managed.id.to_s => [v1.id] }
|
|
end
|
|
|
|
# I should only see exchanges for supplier_managed AND
|
|
# distributor_managed and distributor_permitted (who I have given permission to) AND
|
|
# and distributor_unmanaged (who distributes my products)
|
|
visit admin_order_cycle_incoming_path(oc)
|
|
expect(page).to have_selector "tr.supplier-#{supplier_managed.id}"
|
|
expect(page).to have_selector 'tr.supplier', count: 1
|
|
|
|
visit admin_order_cycle_outgoing_path(oc)
|
|
expect(page).to have_selector "tr.distributor-#{distributor_managed.id}"
|
|
expect(page).to have_selector "tr.distributor-#{distributor_permitted.id}"
|
|
expect(page).to have_selector 'tr.distributor', count: 2
|
|
|
|
# Toggling all products displays the css section of the distributed products
|
|
click_link "Expand all"
|
|
expect(page).to have_css ".exchange-distributed-products", count: 2
|
|
|
|
# Colapsing all products hides the css section of the distributed products
|
|
click_link "Collapse all"
|
|
expect(page).not_to have_css ".exchange-distributed-products"
|
|
|
|
# Open the products list for managed_supplier's incoming exchange
|
|
within "tr.distributor-#{distributor_managed.id}" do
|
|
page.find("td.products").click
|
|
end
|
|
|
|
# I should be able to see and toggle v1
|
|
expect(page).to have_checked_field("order_cycle_outgoing_exchange_0_variants_#{v1.id}",
|
|
disabled: false)
|
|
uncheck "order_cycle_outgoing_exchange_0_variants_#{v1.id}"
|
|
|
|
# I should be able to see but not toggle v2, because I don't have permission
|
|
expect(page).to have_checked_field("order_cycle_outgoing_exchange_0_variants_#{v2.id}",
|
|
disabled: true)
|
|
|
|
expect(page).not_to have_selector(
|
|
"table.exchanges tr.distributor-#{distributor_managed.id} td.tags"
|
|
)
|
|
|
|
click_button "Save"
|
|
expect(page).to have_content "Your order cycle has been updated."
|
|
|
|
oc.reload
|
|
expect(oc.suppliers).to match_array [supplier_managed, supplier_permitted,
|
|
supplier_unmanaged]
|
|
expect(oc.coordinator).to eq(distributor_managed)
|
|
expect(oc.distributors).to match_array [distributor_managed, distributor_permitted,
|
|
distributor_unmanaged]
|
|
end
|
|
end
|
|
|
|
context "that is the manager of a participating hub" do
|
|
let(:my_distributor) { create(:distributor_enterprise) }
|
|
let(:new_user) { create(:user) }
|
|
|
|
before do
|
|
create(:enterprise_relationship, parent: supplier_managed, child: my_distributor,
|
|
permissions_list: [:add_to_order_cycle])
|
|
|
|
new_user.enterprise_roles.build(enterprise: my_distributor).save
|
|
login_as new_user
|
|
end
|
|
|
|
it "editing an order cycle" do
|
|
oc = create(:simple_order_cycle,
|
|
suppliers: [supplier_managed, supplier_permitted, supplier_unmanaged],
|
|
coordinator: distributor_managed, distributors: [
|
|
my_distributor,
|
|
distributor_managed,
|
|
distributor_permitted,
|
|
distributor_unmanaged
|
|
], name: 'Order Cycle 1')
|
|
v1 = create(:variant, supplier: supplier_managed)
|
|
v2 = create(:variant, supplier: supplier_managed)
|
|
|
|
# Incoming exchange
|
|
ex_in = oc.exchanges.where(sender_id: supplier_managed, receiver_id: distributor_managed,
|
|
incoming: true).first
|
|
ex_in.update(variant_ids: [v1.id, v2.id])
|
|
|
|
# Outgoing exchange
|
|
ex_out = oc.exchanges.where(sender_id: distributor_managed, receiver_id: my_distributor,
|
|
incoming: false).first
|
|
ex_out.update(variant_ids: [v1.id, v2.id])
|
|
|
|
# Stub editable_variants_for_incoming_exchanges method so we can test permissions
|
|
serializer = Api::Admin::OrderCycleSerializer.new(oc, current_user: new_user)
|
|
allow(Api::Admin::OrderCycleSerializer).to receive(:new) { serializer }
|
|
allow(serializer).to receive(:editable_variants_for_incoming_exchanges) do
|
|
{ supplier_managed.id.to_s => [v1.id] }
|
|
end
|
|
|
|
# I should see exchanges for my_distributor,
|
|
# and the incoming exchanges supplying the variants in it
|
|
visit admin_order_cycle_outgoing_path(oc)
|
|
expect(page).to have_selector "tr.distributor-#{my_distributor.id}"
|
|
expect(page).to have_selector 'tr.distributor', count: 1
|
|
|
|
visit admin_order_cycle_incoming_path(oc)
|
|
expect(page).to have_selector "tr.supplier-#{supplier_managed.id}"
|
|
expect(page).to have_selector 'tr.supplier', count: 1
|
|
|
|
expect(page).not_to have_content "Loading..."
|
|
|
|
# Open the products list for managed_supplier's incoming exchange
|
|
within "tr.supplier-#{supplier_managed.id}" do
|
|
page.find("td.products").click
|
|
end
|
|
|
|
# I should be able to see and toggle v1
|
|
expect(page).to have_selector ".exchange-product-variant"
|
|
expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{v1.id}",
|
|
disabled: false
|
|
uncheck "order_cycle_incoming_exchange_0_variants_#{v1.id}"
|
|
|
|
# I should be able to see but not toggle v2, because I don't have permission
|
|
expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{v2.id}",
|
|
disabled: true
|
|
|
|
# When I save, any exchange that I can't manage remains
|
|
click_button 'Save and Next'
|
|
expect(page).to have_content "Your order cycle has been updated."
|
|
|
|
expect(page).to have_selector "table.exchanges tr.distributor-#{my_distributor.id} td.tags"
|
|
|
|
oc.reload
|
|
expect(oc.suppliers).to match_array [supplier_managed, supplier_permitted,
|
|
supplier_unmanaged]
|
|
expect(oc.coordinator).to eq(distributor_managed)
|
|
expect(oc.distributors).to match_array [my_distributor, distributor_managed,
|
|
distributor_permitted, distributor_unmanaged]
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "simplified interface for enterprise users selling only their own produce" do
|
|
let(:user) { create(:user) }
|
|
let(:enterprise) { create(:enterprise, is_primary_producer: true, sells: 'own') }
|
|
let!(:p1) { create(:product, supplier_id: enterprise.id) }
|
|
let!(:p2) { create(:product, supplier_id: enterprise.id) }
|
|
let!(:p3) { create(:product, supplier_id: enterprise.id) }
|
|
let!(:v1) { p1.variants.first }
|
|
let!(:v2) { p2.variants.first }
|
|
let!(:v3) { p3.variants.first }
|
|
let!(:fee) { create(:enterprise_fee, enterprise:, name: 'Coord fee') }
|
|
|
|
before do
|
|
user.enterprise_roles.create!(enterprise:)
|
|
login_as user
|
|
end
|
|
|
|
it "shows me an index of order cycles without enterprise columns" do
|
|
create(:simple_order_cycle, coordinator: enterprise)
|
|
visit admin_order_cycles_path
|
|
expect(page).not_to have_selector 'th', text: 'SUPPLIERS'
|
|
expect(page).not_to have_selector 'th', text: 'COORDINATOR'
|
|
expect(page).not_to have_selector 'th', text: 'DISTRIBUTORS'
|
|
end
|
|
|
|
it "creates order cycles" do
|
|
# When I go to the new order cycle page
|
|
visit admin_order_cycles_path
|
|
click_link 'New Order Cycle'
|
|
|
|
# I cannot save without the required fields
|
|
expect(page).to have_button('Create', disabled: true)
|
|
|
|
# The Create button is enabled once the mandatory fields are entered
|
|
fill_in 'order_cycle_name', with: 'Plums & Avos'
|
|
fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time'
|
|
expect(page).to have_button('Create', disabled: false)
|
|
|
|
# If I fill in the basic fields
|
|
find('#order_cycle_orders_open_at').click
|
|
select_datetime_from_datepicker Time.zone.at(Time.zone.local(2040, 10, 17, 0o6, 0o0, 0o0))
|
|
# hide the datetimepicker
|
|
find("body").send_keys(:escape)
|
|
find('#order_cycle_orders_close_at').click
|
|
select_datetime_from_datepicker Time.zone.at(Time.zone.local(2040, 10, 24, 17, 0o0, 0o0))
|
|
# hide the datetimepicker
|
|
find("body").send_keys(:escape)
|
|
fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'pickup instructions'
|
|
|
|
# Then my products / variants should already be selected
|
|
expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{v1.id}"
|
|
expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{v2.id}"
|
|
expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{v3.id}"
|
|
|
|
# When I unselect a product
|
|
uncheck "order_cycle_incoming_exchange_0_variants_#{v2.id}"
|
|
|
|
# And I add a fee and save
|
|
scroll_to(page.find("save-bar"))
|
|
click_button 'Add coordinator fee'
|
|
scroll_to(page.find("save-bar"))
|
|
click_button 'Add coordinator fee'
|
|
click_link 'order_cycle_coordinator_fee_1_remove'
|
|
expect(page).to have_select 'order_cycle_coordinator_fee_0_id'
|
|
expect(page).not_to have_select 'order_cycle_coordinator_fee_1_id'
|
|
|
|
select 'Coord fee', from: 'order_cycle_coordinator_fee_0_id'
|
|
click_button 'Create'
|
|
|
|
# Then my order cycle should have been created
|
|
expect(page).to have_content 'Your order cycle has been created.'
|
|
|
|
oc = OrderCycle.last
|
|
|
|
expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos"
|
|
expect(page)
|
|
.to have_input "oc#{oc.id}[orders_open_at]",
|
|
value: Time.zone.local(2040, 10, 17, 0o6, 0o0, 0o0).strftime("%F %T %z"),
|
|
visible: false
|
|
expect(page)
|
|
.to have_input "oc#{oc.id}[orders_close_at]",
|
|
value: Time.zone.local(2040, 10, 24, 17, 0o0, 0o0).strftime("%F %T %z"),
|
|
visible: false
|
|
|
|
# And it should have some variants selected
|
|
expect(oc.exchanges.incoming.first.variants.count).to eq(2)
|
|
expect(oc.exchanges.outgoing.first.variants.count).to eq(2)
|
|
|
|
# And it should have the fee
|
|
expect(oc.coordinator_fees).to eq([fee])
|
|
|
|
# And my pickup time and instructions should have been saved
|
|
ex = oc.exchanges.outgoing.first
|
|
expect(ex.pickup_time).to eq('pickup time')
|
|
expect(ex.pickup_instructions).to eq('pickup instructions')
|
|
end
|
|
|
|
it "editing an order cycle" do
|
|
# Given an order cycle with pickup time and instructions
|
|
fee = create(:enterprise_fee, name: 'my fee', enterprise:)
|
|
oc = create(:simple_order_cycle, suppliers: [enterprise], coordinator: enterprise,
|
|
distributors: [enterprise], variants: [v1],
|
|
coordinator_fees: [fee])
|
|
ex = oc.exchanges.outgoing.first
|
|
ex.update! pickup_time: 'pickup time', pickup_instructions: 'pickup instructions'
|
|
|
|
# When I edit it
|
|
login_as_admin
|
|
visit admin_order_cycles_path
|
|
within "tr.order-cycle-#{oc.id}" do
|
|
find("a.edit-order-cycle").click
|
|
end
|
|
|
|
wait_for_edit_form_to_load_order_cycle(oc)
|
|
|
|
# Then I should see the basic settings
|
|
expect(page).to have_field 'order_cycle_name', with: oc.name
|
|
expect(page).to have_field 'order_cycle_orders_open_at',
|
|
with: oc.orders_open_at.strftime("%Y-%m-%d %H:%M")
|
|
expect(page).to have_field 'order_cycle_orders_close_at',
|
|
with: oc.orders_close_at.strftime("%Y-%m-%d %H:%M")
|
|
expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_time', with: 'pickup time'
|
|
expect(page).to have_field 'order_cycle_outgoing_exchange_0_pickup_instructions',
|
|
with: 'pickup instructions'
|
|
|
|
# And I should see the products
|
|
expect(page).to have_checked_field "order_cycle_incoming_exchange_0_variants_#{v1.id}"
|
|
expect(page).to have_unchecked_field "order_cycle_incoming_exchange_0_variants_#{v2.id}"
|
|
expect(page).to have_unchecked_field "order_cycle_incoming_exchange_0_variants_#{v3.id}"
|
|
|
|
# And I should see the coordinator fees
|
|
expect(page).to have_select 'order_cycle_coordinator_fee_0_id', selected: 'my fee'
|
|
end
|
|
|
|
it "updating an order cycle" do
|
|
# Given an order cycle with pickup time and instructions
|
|
fee1 = create(:enterprise_fee, name: 'my fee', enterprise:)
|
|
fee2 = create(:enterprise_fee, name: 'that fee', enterprise:)
|
|
oc = create(:simple_order_cycle, suppliers: [enterprise], coordinator: enterprise,
|
|
distributors: [enterprise], variants: [v1],
|
|
coordinator_fees: [fee1])
|
|
ex = oc.exchanges.outgoing.first
|
|
ex.update! pickup_time: 'pickup time', pickup_instructions: 'pickup instructions'
|
|
|
|
# When I edit it
|
|
login_as_admin
|
|
visit edit_admin_order_cycle_path oc
|
|
|
|
wait_for_edit_form_to_load_order_cycle(oc)
|
|
|
|
# And I fill in the basic fields
|
|
fill_in 'order_cycle_name', with: 'Plums & Avos'
|
|
fill_in 'order_cycle_orders_open_at', with: '2040-10-17 06:00:00'
|
|
fill_in 'order_cycle_orders_close_at', with: '2040-10-24 17:00:00'
|
|
fill_in 'order_cycle_outgoing_exchange_0_pickup_time', with: 'xy'
|
|
fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'zzy'
|
|
|
|
# And I make some product selections
|
|
uncheck "order_cycle_incoming_exchange_0_variants_#{v1.id}"
|
|
check "order_cycle_incoming_exchange_0_variants_#{v2.id}"
|
|
check "order_cycle_incoming_exchange_0_variants_#{v3.id}"
|
|
uncheck "order_cycle_incoming_exchange_0_variants_#{v3.id}"
|
|
|
|
# Add tags
|
|
expect(page).to have_content "Tags"
|
|
|
|
within "tags-with-translation" do
|
|
find(:css, "tags-input .tags input").set "wholesale\n"
|
|
end
|
|
|
|
# And I select some fees and update
|
|
scroll_to(page.find_button("Add coordinator fee"))
|
|
click_link 'order_cycle_coordinator_fee_0_remove'
|
|
expect(page).not_to have_select 'order_cycle_coordinator_fee_0_id'
|
|
click_button 'Add coordinator fee'
|
|
select 'that fee', from: 'order_cycle_coordinator_fee_0_id'
|
|
|
|
# Click dismiss on distributor warning
|
|
click_button 'Dismiss'
|
|
|
|
# When I update, or update and close, both work
|
|
click_button 'Save'
|
|
expect(page).to have_content 'Your order cycle has been updated.'
|
|
|
|
fill_in 'order_cycle_outgoing_exchange_0_pickup_instructions', with: 'yyz'
|
|
|
|
scroll_to(:bottom)
|
|
click_button 'Save and Back to List'
|
|
|
|
# Then my order cycle should have been updated
|
|
expect(page).to have_content 'Your order cycle has been updated.'
|
|
oc = OrderCycle.last
|
|
|
|
expect(page).to have_input "oc#{oc.id}[name]", value: "Plums & Avos"
|
|
expect(page)
|
|
.to have_input "oc#{oc.id}[orders_open_at]",
|
|
value: Time.zone.local(2040, 10, 17, 0o6, 0o0, 0o0).strftime("%F %T %z"),
|
|
visible: false
|
|
expect(page)
|
|
.to have_input "oc#{oc.id}[orders_close_at]",
|
|
value: Time.zone.local(2040, 10, 24, 17, 0o0, 0o0).strftime("%F %T %z"),
|
|
visible: false
|
|
|
|
# And it should have a variant selected
|
|
expect(oc.exchanges.incoming.first.variants).to eq([v2])
|
|
expect(oc.exchanges.outgoing.first.variants).to eq([v2])
|
|
|
|
# And it should have the fee
|
|
expect(oc.coordinator_fees).to eq([fee2])
|
|
|
|
# And my pickup time and instructions should have been saved
|
|
ex = oc.exchanges.outgoing.first
|
|
expect(ex.pickup_time).to eq('xy')
|
|
expect(ex.pickup_instructions).to eq('yyz')
|
|
|
|
# And it should have the tags
|
|
expect(ex.tag_list).to eq ['wholesale']
|
|
end
|
|
end
|
|
|
|
it "modify the minute of a order cycle with the keyboard, " \
|
|
"check that the modifications are taken into account" do
|
|
order_cycle = create(:simple_order_cycle, name: "Translusent Berries")
|
|
login_as_admin
|
|
visit admin_order_cycles_path
|
|
find("#oc#{order_cycle.id}_orders_close_at").click
|
|
input = find(".flatpickr-calendar.open .flatpickr-minute")
|
|
input.send_keys :up
|
|
input.send_keys :enter
|
|
within "#save-bar" do
|
|
expect(page).to have_content "You have unsaved changes"
|
|
end
|
|
end
|
|
|
|
it "deleting an order cycle" do
|
|
order_cycle = create(:simple_order_cycle, name: "Translusent Berries")
|
|
login_as_admin
|
|
visit admin_order_cycles_path
|
|
expect(page).to have_selector "tr.order-cycle-#{order_cycle.id}"
|
|
accept_alert do
|
|
first('a.delete-order-cycle').click
|
|
end
|
|
expect(page).not_to have_selector "tr.order-cycle-#{order_cycle.id}"
|
|
end
|
|
|
|
private
|
|
|
|
def expect_payment_methods_to_be_checked_for(distributor)
|
|
distributor.distributor_payment_method_ids.each do |distributor_payment_method_id|
|
|
expect(page).to have_checked_field(
|
|
"order_cycle_selected_distributor_payment_method_ids_#{distributor_payment_method_id}"
|
|
)
|
|
end
|
|
end
|
|
|
|
def expect_shipping_methods_to_be_checked_for(distributor)
|
|
distributor.distributor_shipping_method_ids.each do |distributor_shipping_method_id|
|
|
expect(page).to have_checked_field(
|
|
"order_cycle_selected_distributor_shipping_method_ids_#{distributor_shipping_method_id}"
|
|
)
|
|
end
|
|
end
|
|
|
|
def wait_for_edit_form_to_load_order_cycle(order_cycle)
|
|
expect(page).to have_field "order_cycle_name", with: order_cycle.name
|
|
end
|
|
|
|
def select_incoming_variant(supplier, exchange_no, variant)
|
|
expect(page).to have_selector "table.exchanges tr.supplier-#{supplier.id} td.products"
|
|
page.find("table.exchanges tr.supplier-#{supplier.id} td.products").click
|
|
check "order_cycle_incoming_exchange_#{exchange_no}_variants_#{variant.id}"
|
|
end
|
|
end
|