mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
293 lines
12 KiB
Ruby
293 lines
12 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe Reporting::Reports::Customers::Base do
|
|
context "as a site admin" do
|
|
let(:user) { create(:admin_user) }
|
|
subject { described_class.new user, {} }
|
|
|
|
describe "addresses report" do
|
|
it "returns headers for addresses" do
|
|
expect(subject.table_headers).to eq(["First Name", "Last Name", "Billing Address",
|
|
"Email", "Phone", "Hub", "Hub Address",
|
|
"Shipping Method", "Total Number of Orders",
|
|
"Total incl. tax ($)",
|
|
"Last completed order date"])
|
|
end
|
|
|
|
it "builds a table from a list of variants" do
|
|
a = create(:address)
|
|
d = create(:distributor_enterprise)
|
|
o = create(:order, distributor: d, bill_address: a)
|
|
o.shipments << create(:shipment)
|
|
|
|
allow(subject).to receive(:query_result).and_return [[o]]
|
|
expect(subject.table_rows).to eq([[
|
|
a.firstname, a.lastname,
|
|
[a.address1, a.address2, a.city].join(" "),
|
|
o.email, a.phone, d.name,
|
|
[d.address.address1, d.address.address2,
|
|
d.address.city].join(" "),
|
|
o.shipping_method.name, 1, o.total, "none"
|
|
]])
|
|
end
|
|
|
|
context "when there are multiple orders for the same customer" do
|
|
let!(:a) { create(:bill_address) }
|
|
let!(:d){ create(:distributor_enterprise) }
|
|
let!(:sm) { create(:shipping_method, distributors: [d]) }
|
|
let!(:customer) { create(:customer) }
|
|
let!(:o1) {
|
|
create(:order_with_totals_and_distribution, :completed, distributor: d,
|
|
bill_address: a,
|
|
shipping_method: sm,
|
|
customer:)
|
|
}
|
|
let!(:o2) {
|
|
create(:order_with_totals_and_distribution, :completed, distributor: d,
|
|
bill_address: a,
|
|
shipping_method: sm,
|
|
customer:)
|
|
}
|
|
before do
|
|
o1.update(completed_at: "2023-01-01")
|
|
o2.update(completed_at: "2023-01-02")
|
|
[o1, o2].each do |order|
|
|
order.update!(email: "test@test.com")
|
|
end
|
|
end
|
|
|
|
it "returns only one row per customer with the right data" do
|
|
expect(subject.query_result).to match_array [[o1, o2]]
|
|
expect(subject.table_rows.size).to eq(1)
|
|
expect(subject.table_rows)
|
|
.to eq([[
|
|
a.firstname, a.lastname,
|
|
[a.address1, a.address2, a.city].join(" "),
|
|
o1.email, a.phone, d.name,
|
|
[d.address.address1, d.address.address2, d.address.city].join(" "),
|
|
o1.shipping_method.name, 2, o1.total + o2.total, "2023-01-02"
|
|
]])
|
|
end
|
|
|
|
context "orders from different hubs" do
|
|
let!(:d2) { create(:distributor_enterprise) }
|
|
let!(:sm2) { create(:shipping_method, distributors: [d2]) }
|
|
let!(:o2) {
|
|
create(:order_with_totals_and_distribution, :completed, distributor: d2,
|
|
bill_address: a,
|
|
shipping_method: sm2)
|
|
}
|
|
|
|
it "returns one row per customer per hub" do
|
|
expect(subject.query_result.size).to eq(2)
|
|
expect(subject.table_rows.size).to eq(2)
|
|
expect(subject.table_rows)
|
|
.to eq([[
|
|
a.firstname, a.lastname,
|
|
[a.address1, a.address2, a.city].join(" "),
|
|
o1.email, a.phone, d.name,
|
|
[d.address.address1, d.address.address2, d.address.city].join(" "),
|
|
o1.shipping_method.name, 1, o1.total, "2023-01-01"
|
|
], [
|
|
a.firstname, a.lastname,
|
|
[a.address1, a.address2, a.city].join(" "),
|
|
o2.email, a.phone, d2.name,
|
|
[d2.address.address1, d2.address.address2, d2.address.city].join(" "),
|
|
o2.shipping_method.name, 1, o2.total, "2023-01-02"
|
|
]])
|
|
end
|
|
end
|
|
|
|
context "orders with different shipping methods" do
|
|
let!(:sm2) { create(:shipping_method, distributors: [d], name: "Bike") }
|
|
let!(:o2) {
|
|
create(:order_with_totals_and_distribution, :completed, distributor: d,
|
|
bill_address: a,
|
|
shipping_method: sm2)
|
|
}
|
|
before do
|
|
o2.select_shipping_method(sm2.id)
|
|
end
|
|
|
|
context "when the shipping method column is being included" do
|
|
let(:fields_to_show) do
|
|
[:first_name, :last_name, :billing_address, :email, :phone, :hub, :hub_address,
|
|
:shipping_method, :total_orders, :total_incl_tax, :last_completed_order_date]
|
|
end
|
|
subject { described_class.new(user, { fields_to_show: }) }
|
|
|
|
it "returns one row per customer per shipping method" do
|
|
expect(subject.query_result.size).to eq(2)
|
|
expect(subject.table_rows.size).to eq(2)
|
|
expect(subject.table_rows).to eq(
|
|
[
|
|
[
|
|
a.firstname,
|
|
a.lastname,
|
|
[a.address1, a.address2, a.city].join(" "),
|
|
o1.email,
|
|
a.phone,
|
|
d.name,
|
|
[d.address.address1, d.address.address2, d.address.city].join(" "),
|
|
o1.shipping_method.name, 1, o1.total, o1.completed_at.strftime("%Y-%m-%d")
|
|
],
|
|
[
|
|
a.firstname,
|
|
a.lastname,
|
|
[a.address1, a.address2, a.city].join(" "),
|
|
o2.email,
|
|
a.phone,
|
|
d.name,
|
|
[d.address.address1, d.address.address2, d.address.city].join(" "),
|
|
sm2.name, 1, o2.total, o2.completed_at.strftime("%Y-%m-%d")
|
|
]
|
|
]
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when the shipping method column is not included in the report" do
|
|
let(:fields_to_show) do
|
|
[:first_name, :last_name, :billing_address, :email, :phone, :hub, :hub_address]
|
|
end
|
|
subject { described_class.new(user, { fields_to_show: }) }
|
|
|
|
it "returns a single row for the customer, otherwise it would return two identical
|
|
rows" do
|
|
expect(subject.query_result.size).to eq(2)
|
|
expect(subject.table_rows.size).to eq(1)
|
|
expect(subject.table_rows).to eq(
|
|
[[
|
|
a.firstname,
|
|
a.lastname,
|
|
[a.address1, a.address2, a.city].join(" "),
|
|
o1.email,
|
|
a.phone,
|
|
d.name,
|
|
[d.address.address1, d.address.address2, d.address.city].join(" ")
|
|
]]
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "fetching orders" do
|
|
it "fetches completed orders" do
|
|
o1 = create(:order)
|
|
o2 = create(:order, completed_at: 1.day.ago)
|
|
expect(subject.query_result).to eq([[o2]])
|
|
end
|
|
|
|
it "does not show cancelled orders" do
|
|
o1 = create(:order, state: "canceled", completed_at: 1.day.ago)
|
|
o2 = create(:order, completed_at: 1.day.ago)
|
|
expect(subject.query_result).to eq([[o2]])
|
|
end
|
|
end
|
|
end
|
|
|
|
context "as an enterprise user" do
|
|
let(:user) { create(:user) }
|
|
|
|
subject { described_class.new user, {} }
|
|
|
|
describe "fetching orders" do
|
|
let(:supplier) { create(:supplier_enterprise) }
|
|
let(:product) { create(:simple_product, supplier_id: supplier.id) }
|
|
let(:order) { create(:order, completed_at: 1.day.ago) }
|
|
|
|
it "only shows orders managed by the current user" do
|
|
d1 = create(:distributor_enterprise)
|
|
d1.enterprise_roles.build(user:).save
|
|
d2 = create(:distributor_enterprise)
|
|
d2.enterprise_roles.build(user: create(:user)).save
|
|
|
|
o1 = create(:order, distributor: d1, completed_at: 1.day.ago)
|
|
o2 = create(:order, distributor: d2, completed_at: 1.day.ago)
|
|
|
|
expect(subject).to receive(:filter).with([o1]).and_return([o1])
|
|
expect(subject.query_result).to eq([[o1]])
|
|
end
|
|
|
|
it "does not show orders through a hub that the current user does not manage" do
|
|
# Given a supplier enterprise with an order for one of its products
|
|
supplier.enterprise_roles.build(user:).save
|
|
order.line_items << create(:line_item_with_shipment, product:)
|
|
|
|
# When I fetch orders, I should see no orders
|
|
expect(subject).to receive(:filter).with([]).and_return([])
|
|
expect(subject.query_result).to eq([])
|
|
end
|
|
end
|
|
|
|
describe "filtering orders" do
|
|
let(:orders) { Spree::Order.where(nil) }
|
|
let(:supplier) { create(:supplier_enterprise) }
|
|
|
|
it "returns all orders sans-params" do
|
|
expect(subject.filter(orders)).to eq(orders)
|
|
end
|
|
|
|
describe "filters to a specific completed_at date range" do
|
|
let!(:o1) { create(:order, completed_at: 1.day.ago) }
|
|
let!(:o2) { create(:order, completed_at: 3.days.ago) }
|
|
let!(:o3) { create(:order, completed_at: 5.days.ago) }
|
|
|
|
it do
|
|
allow(subject).to receive(:params).and_return(
|
|
q: {
|
|
completed_at_gt: 1.day.before(o2.completed_at),
|
|
completed_at_lt: 1.day.after(o2.completed_at)
|
|
}
|
|
)
|
|
expect(subject.filter(orders)).to eq([o2])
|
|
end
|
|
|
|
it "when completed_at_gt param is missing" do
|
|
allow(subject).to receive(:params).and_return(
|
|
q: {
|
|
completed_at_gt: "",
|
|
completed_at_lt: 1.day.after(o2.completed_at)
|
|
}
|
|
)
|
|
expect(subject.filter(orders)).to match_array [o2, o3]
|
|
end
|
|
|
|
it "when completed_at_lt param is missing" do
|
|
allow(subject).to receive(:params).and_return(
|
|
q: {
|
|
completed_at_gt: 1.day.before(o2.completed_at),
|
|
completed_at_lt: ""
|
|
}
|
|
)
|
|
expect(subject.filter(orders)).to match_array [o1, o2]
|
|
end
|
|
end
|
|
|
|
it "filters to a specific distributor" do
|
|
d1 = create(:distributor_enterprise)
|
|
d2 = create(:distributor_enterprise)
|
|
order1 = create(:order, distributor: d1)
|
|
order2 = create(:order, distributor: d2)
|
|
|
|
allow(subject).to receive(:params).and_return(distributor_id: d1.id)
|
|
expect(subject.filter(orders)).to eq([order1])
|
|
end
|
|
|
|
it "filters to a specific cycle" do
|
|
oc1 = create(:simple_order_cycle)
|
|
oc2 = create(:simple_order_cycle)
|
|
order1 = create(:order, order_cycle: oc1)
|
|
order2 = create(:order, order_cycle: oc2)
|
|
|
|
allow(subject).to receive(:params).and_return(order_cycle_id: oc1.id)
|
|
expect(subject.filter(orders)).to eq([order1])
|
|
end
|
|
end
|
|
end
|
|
end
|