Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improves test coverage on Orders and Distributors report #12790

21 changes: 21 additions & 0 deletions spec/support/reports_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,25 @@ def run_report
expect(page).not_to have_selector ".loading"
expect(page).to have_button "Go", disabled: false
end

def generate_report
run_report
click_on "Download Report"
wait_for_download
end

def load_file_txt(extension, downloaded_filename)
case extension
when "csv"
CSV.read(downloaded_filename).join(" ")
when "xlsx"
xlsx = Roo::Excelx.new(downloaded_filename)
xlsx.map(&:to_a).join(" ")
end
end

def table_headers
rows = find("table.report__table").all("thead tr")
rows.map { |r| r.all("th").map { |c| c.text.strip } }
end
Comment on lines +32 to +35
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be aware that this method name is in the global scope in specs. If another part of the specs wanted to read the table headers of a different table then someone may define a method with the same name and there would be a collision. It would be better to name this report_table_headers.

Also, do you need the find?

Suggested change
def table_headers
rows = find("table.report__table").all("thead tr")
rows.map { |r| r.all("th").map { |c| c.text.strip } }
end
def report_table_headers
rows = all("table.report__table thead tr")
rows.map { |r| r.all("th").map { |c| c.text.strip } }
end

end
10 changes: 10 additions & 0 deletions spec/support/request/web_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,16 @@ def click_on_select2(value, options)
find(:css, ".select2-result-label", text: options[:select_text] || value).click
end

def clear_select2(selector)
page.find(selector).scroll_to(page.find(selector))
.find(:css, '.select2-choice, .select2-search-field').click
page.find(selector).scroll_to(page.find(selector))
.find(:css, '.select2-choice, .select2-search-field').send_keys :backspace
page.find(selector).scroll_to(page.find(selector))
.find(:css, '.select2-choice, .select2-search-field').send_keys :backspace
find("body").send_keys(:escape)
end

def request_monitor_finished(controller = nil)
page.evaluate_script("#{angular_scope(controller)}.scope().RequestMonitor.loading == false")
end
Expand Down
72 changes: 35 additions & 37 deletions spec/system/admin/reports/enterprise_fee_summaries_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
RSpec.describe "enterprise fee summaries" do
include AuthenticationHelper
include WebHelper
include ReportsHelper

let!(:distributor) { create(:distributor_enterprise) }
let!(:other_distributor) { create(:distributor_enterprise) }
Expand Down Expand Up @@ -78,59 +79,48 @@
end
end

describe "csv downloads" do
describe "permissions" do
describe "smoke test for generation of report based on permissions" do
let!(:order) do
create(:completed_order_with_fees, order_cycle:,
distributor:)
end
let!(:other_order) do
create(:completed_order_with_fees, order_cycle: other_order_cycle,
distributor: other_distributor)
end
context "when logged in as admin" do
let!(:order) do
create(:completed_order_with_fees, order_cycle:,
distributor:)
end
let(:current_user) { create(:admin_user) }
let!(:current_user) { create(:admin_user) }

before do
visit main_app.admin_report_path(report_type: 'enterprise_fee_summary')
end

it "generates file with data for all enterprises" do
select "CSV"
run_report
click_on "Download Report"
expect(downloaded_filename).to include ".csv"
expect(downloaded_content).to have_content(distributor.name)
expect(page).to have_content(distributor.name)
expect(page).to have_content(other_distributor.name)
end
end

context "when logged in as enterprise user" do
let!(:order) do
create(:completed_order_with_fees, order_cycle:,
distributor:)
end
let!(:other_order) do
create(:completed_order_with_fees, order_cycle: other_order_cycle,
distributor: other_distributor)
end
let(:current_user) { distributor.owner }
let!(:current_user) { distributor.owner }

before do
visit main_app.admin_report_path(report_type: 'enterprise_fee_summary')
end

it "generates file with data for the enterprise" do
select "CSV"
run_report
click_on "Download Report"

expect(downloaded_filename).to include ".csv"
expect(downloaded_content).to have_content(distributor.name)
expect(downloaded_content).not_to have_content(other_distributor.name)
expect(page).to have_content(distributor.name)
expect(page).not_to have_content(other_distributor.name)
end
end
end

describe "smoke test for filtering report based on filters" do
describe "downloading the report" do
let!(:second_distributor) { create(:distributor_enterprise) }
let!(:second_order_cycle) { create(:simple_order_cycle, coordinator: second_distributor) }

let!(:order) do
create(:completed_order_with_fees, order_cycle:,
distributor:)
Expand All @@ -144,21 +134,29 @@

before do
visit main_app.admin_report_path(report_type: 'enterprise_fee_summary')
end

it "generates file with data for selected order cycle" do
find("#s2id_q_order_cycle_ids").click
select order_cycle.name
end

find("#report_format").click
select "CSV"
run_report
click_on "Download Report"
shared_examples "reports generated as" do |output_type, extension|
context output_type.to_s do
it "downloads the #{output_type} file" do
select output_type, from: "report_format"

expect(downloaded_filename).to include ".csv"
expect(downloaded_content).to have_content(distributor.name)
expect(downloaded_content).not_to have_content(second_distributor.name)
expect { generate_report }.to change { downloaded_filenames.length }.from(0).to(1)

expect(downloaded_filename).to match(/.*\.#{extension}/)

downloaded_file_txt = load_file_txt(extension, downloaded_filename)

expect(downloaded_file_txt).to have_content(distributor.name)
expect(downloaded_file_txt).not_to have_content(second_distributor.name)
end
end
end

it_behaves_like "reports generated as", "CSV", "csv"
it_behaves_like "reports generated as", "Spreadsheet", "xlsx"
end
end

Expand Down
188 changes: 188 additions & 0 deletions spec/system/admin/reports/orders_and_distributors_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# frozen_string_literal: true

require "system_helper"

RSpec.describe "Orders And Distributors" do
include AuthenticationHelper
include WebHelper
include ReportsHelper

describe "Orders And Distributors" do
let!(:report_url) { admin_report_path(report_type: :orders_and_distributors) }
let!(:distributor) { create(:distributor_enterprise, name: "By Bike") }
let!(:distributor2) { create(:distributor_enterprise, name: "By Moto") }
let!(:completed_at) { Time.zone.now.to_fs(:db) }

around do |example|
Timecop.travel(completed_at) { example.run }
end
Comment on lines +16 to +18
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not freezing time. It's just going to the beginning of the second, I guess. Therefore flakiness is less likely but not impossible.


let!(:order) {
create(:order_ready_to_ship, distributor_id: distributor.id, completed_at:)
}
let!(:order2) {
create(:order_ready_to_ship, distributor_id: distributor2.id, completed_at:)
}

context "as an enterprise user" do
let(:header) {
["Order date", "Order Id", "Customer Name", "Customer Email", "Customer Phone",
"Customer City", "SKU", "Item name", "Variant", "Quantity", "Max Quantity",
"Cost", "Shipping Cost", "Payment Method", "Distributor", "Distributor address",
"Distributor city", "Distributor postcode", "Shipping Method",
"Shipping instructions"]
}
let(:line_item1) {
[completed_at, order.id, "John Doe", order.email, "123-456-7890", "Herndon",
"ABC", Spree::Product.first.name.to_s, "1g", "1", "none", "10.0", "none", "Check",
"By Bike", "10 Lovely Street", "Herndon", "20170", "UPS Ground", "none"].join(" ")
}
let(:line_item2) {
[completed_at, order.id, "John Doe", order.email, "123-456-7890", "Herndon",
"ABC", Spree::Product.first.name.to_s, "1g", "1", "none", "10.0", "none", "Check",
"By Bike", "10 Lovely Street", "Herndon", "20170", "UPS Ground", "none"].join(" ")
}
let(:line_item3) {
[completed_at.to_s, order.id, "John Doe", order.email, "123-456-7890", "Herndon",
"ABC", Spree::Product.first.name.to_s, "1g", "1", "none", "10.0", "none", "Check",
"By Bike", "10 Lovely Street", "Herndon", "20170", "UPS Ground", "none"].join(" ")
}
let(:line_item4) {
[completed_at.to_s, order.id, "John Doe", order.email, "123-456-7890", "Herndon",
"ABC", Spree::Product.first.name.to_s, "1g", "1", "none", "10.0", "none", "Check",
"By Bike", "10 Lovely Street", "Herndon", "20170", "UPS Ground", "none"].join(" ")
}
let(:line_item5) {
[completed_at.to_s, order.id, "John Doe", order.email, "123-456-7890", "Herndon",
"ABC", Spree::Product.first.name.to_s, "1g", "1", "none", "10.0", "none", "Check",
"By Bike", "10 Lovely Street", "Herndon", "20170", "UPS Ground", "none"].join(" ")
}

before do
login_as(distributor.owner)
visit report_url
run_report
end

it "generates the report" do
expect(table_headers).to eq([header])

# Total rows should equal nr. of line items, per order
expect(all('table.report__table tbody tr').count).to eq(5)

# displays only orders from the hub it is managing
within ".report__table" do
expect(page).to have_content(distributor.name, count: 5)
end

# only sees line items from orders it manages
expect(page).not_to have_content(distributor2.name)

# displayes table contents correctly, per line item
table = page.find("table.report__table tbody")
expect(table).to have_content(line_item1)
expect(table).to have_content(line_item2)
expect(table).to have_content(line_item3)
expect(table).to have_content(line_item4)
expect(table).to have_content(line_item5)
end

describe "downloading the report" do
shared_examples "reports generated as" do |output_type, extension|
context output_type.to_s do
it "downloads the #{output_type} file" do
select output_type, from: "report_format"

expect { generate_report }.to change { downloaded_filenames.length }.from(0).to(1)

expect(downloaded_filename).to match(/.*\.#{extension}/)

downloaded_file_txt = load_file_txt(extension, downloaded_filename)

expect(downloaded_file_txt).to have_text header.join(" ")
expect(downloaded_file_txt).to have_text(
"By Bike 10 Lovely Street Herndon 20170 UPS Ground", count: 5
)
end
end
end

it_behaves_like "reports generated as", "CSV", "csv"
it_behaves_like "reports generated as", "Spreadsheet", "xlsx"
Comment on lines +110 to +111
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it be that, depending on the version of Chrome, the PDF is opened in the browser instead of downloaded? That would explain the error, seeing a timeout because the file is never saved, only displayed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PDF is opened in the browser instead of downloaded

I'm positive, that this is indeed the case - I've verified this in headless=false mode. But I have not found a way to download the file...

end
end

context "as admin" do
before do
login_as_admin
visit report_url
run_report
end

context "with two orders on the same day at different times" do
let(:completed_at1) { 1500.hours.ago } # 1500 hours in the past
let(:completed_at2) { 1700.hours.ago } # 1700 hours in the past
let(:datetime_start1) { 1600.hours.ago } # 1600 hours in the past
let(:datetime_start2) { 1800.hours.ago } # 1600 hours in the past
let(:datetime_end) { 1400.hours.ago } # 1400 hours in the past
let!(:order3) {
create(:order_ready_to_ship, distributor_id: distributor.id, completed_at: completed_at1)
}
let!(:order4) {
create(:order_ready_to_ship, distributor_id: distributor.id, completed_at: completed_at2)
}

context "applying time/date filters" do
it "is precise to time of day, not just date" do
# When I generate a customer report
# with a timeframe that includes one order but not the other
find("input.datepicker").click
select_dates_from_daterangepicker datetime_start1, datetime_end
find(".shortcut-buttons-flatpickr-button").click # closes flatpickr

run_report
# Then I should see the rows for the first order but not the second
# One row per line item - order3 only
within ".report__table" do
expect(page).to have_content(distributor.name, count: 5)
end
expect(page).to have_text(order3.email, count: 5)

# setting a time interval to include both orders
find("input.datepicker").click
select_dates_from_daterangepicker datetime_start2, Time.zone.now

run_report
# Then I should see the both orders
within ".report__table" do
expect(page).to have_content(distributor.name, count: 10)
end
expect(page).to have_text(order3.email, count: 5)
expect(page).to have_text(order4.email, count: 5)
end
end

context "applying distributor filters" do
it "displays line items from the correct distributors" do
# for one distributor
select2_select distributor.name, from: "q_distributor_id_in"
run_report

within ".report__table" do
expect(page).to have_content(distributor.name, count: 15)
end
clear_select2("#s2id_q_distributor_id_in")

# for another distributor
select2_select distributor2.name, from: "q_distributor_id_in"
run_report

within ".report__table" do
expect(page).to have_content(distributor2.name, count: 5)
end
end
end
end
end
end
end
Loading
Loading