diff --git a/spec/features/admin/reports/enterprise_fee_summaries_spec.rb b/spec/features/admin/reports/enterprise_fee_summaries_spec.rb index be03f7d393..844eeadf03 100644 --- a/spec/features/admin/reports/enterprise_fee_summaries_spec.rb +++ b/spec/features/admin/reports/enterprise_fee_summaries_spec.rb @@ -1,6 +1,6 @@ require "spec_helper" -xfeature "enterprise fee summaries", js: true do +feature "enterprise fee summaries", js: true do include AuthenticationWorkflow include WebHelper @@ -86,8 +86,10 @@ xfeature "enterprise fee summaries", js: true do end context "when logged in as enterprise user" do - let!(:order) { create(:completed_order_with_fees, order_cycle: order_cycle, distributor: distributor) } - + let!(:order) do + create(:completed_order_with_fees, order_cycle: order_cycle, + distributor: distributor) + end let(:current_user) { distributor.owner } it "shows available options for the enterprise" do @@ -96,61 +98,85 @@ xfeature "enterprise fee summaries", js: true do end end - describe "smoke test for generation of report based on permissions" do - before do - visit spree.new_admin_reports_enterprise_fee_summary_path + describe "csv downloads" do + around do |example| + with_empty_downloads_folder { example.run } end - context "when logged in as admin" do - let!(:order) { create(:completed_order_with_fees, order_cycle: order_cycle, distributor: distributor) } + describe "smoke test for generation of report based on permissions" do + before do + visit spree.new_admin_reports_enterprise_fee_summary_path + end + + context "when logged in as admin" do + let!(:order) do + create(:completed_order_with_fees, order_cycle: order_cycle, + distributor: distributor) + end + let(:current_user) { create(:admin_user) } + + it "generates file with data for all enterprises" do + check I18n.t("filters.report_format_csv", scope: i18n_scope) + click_on I18n.t("filters.generate_report", scope: i18n_scope) + + expect(downloaded_filename).to include ".csv" + expect(downloaded_content).to have_content(distributor.name) + end + end + + context "when logged in as enterprise user" do + let!(:order) do + create(:completed_order_with_fees, order_cycle: order_cycle, + distributor: 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 } + + it "generates file with data for the enterprise" do + check I18n.t("filters.report_format_csv", scope: i18n_scope) + click_on I18n.t("filters.generate_report", scope: i18n_scope) + + expect(downloaded_filename).to include ".csv" + csv_content = downloaded_content + expect(csv_content).to have_content(distributor.name) + expect(csv_content).not_to have_content(other_distributor.name) + end + end + end + + describe "smoke test for filtering report based on filters" 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: order_cycle, + distributor: distributor) + end + let!(:second_order) do + create(:completed_order_with_fees, order_cycle: second_order_cycle, + distributor: second_distributor) + end let(:current_user) { create(:admin_user) } - it "generates file with data for all enterprises" do + before do + visit spree.new_admin_reports_enterprise_fee_summary_path + end + + it "generates file with data for selected order cycle" do + select order_cycle.name, from: "report_order_cycle_ids" check I18n.t("filters.report_format_csv", scope: i18n_scope) click_on I18n.t("filters.generate_report", scope: i18n_scope) - expect(page.response_headers['Content-Type']).to eq "text/csv" - expect(page.body).to have_content(distributor.name) + + expect(downloaded_filename).to include ".csv" + csv_content = downloaded_content + expect(csv_content).to have_content(distributor.name) + expect(csv_content).not_to have_content(second_distributor.name) end end - - context "when logged in as enterprise user" do - let!(:order) { create(:completed_order_with_fees, order_cycle: order_cycle, distributor: distributor) } - let!(:other_order) { create(:completed_order_with_fees, order_cycle: other_order_cycle, distributor: other_distributor) } - - let(:current_user) { distributor.owner } - - it "generates file with data for the enterprise" do - check I18n.t("filters.report_format_csv", scope: i18n_scope) - click_on I18n.t("filters.generate_report", scope: i18n_scope) - expect(page.response_headers['Content-Type']).to eq "text/csv" - expect(page.body).to have_content(distributor.name) - expect(page.body).not_to have_content(other_distributor.name) - end - end - end - - describe "smoke test for filtering report based on filters" do - let!(:second_distributor) { create(:distributor_enterprise) } - let!(:second_order_cycle) { create(:simple_order_cycle, coordinator: second_distributor) } - - let!(:order) { create(:completed_order_with_fees, order_cycle: order_cycle, distributor: distributor) } - let!(:second_order) { create(:completed_order_with_fees, order_cycle: second_order_cycle, distributor: second_distributor) } - - let(:current_user) { create(:admin_user) } - - before do - visit spree.new_admin_reports_enterprise_fee_summary_path - end - - it "generates file with data for selected order cycle" do - select order_cycle.name, from: "report_order_cycle_ids" - check I18n.t("filters.report_format_csv", scope: i18n_scope) - click_on I18n.t("filters.generate_report", scope: i18n_scope) - expect(page.response_headers['Content-Type']).to eq "text/csv" - expect(page.body).to have_content(distributor.name) - expect(page.body).not_to have_content(second_distributor.name) - end end def i18n_scope diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 68a523c4af..3b0ae37fb7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -46,7 +46,17 @@ Capybara.register_driver :chrome do |app| options = Selenium::WebDriver::Chrome::Options.new( args: %w[headless disable-gpu no-sandbox window-size=1280,768] ) - Capybara::Selenium::Driver.new(app, browser: :chrome, options: options) + driver = Capybara::Selenium::Driver.new(app, browser: :chrome, options: options) + + ### Allow file downloads in headless chrome + ### https://bugs.chromium.org/p/chromium/issues/detail?id=696481#c89 + bridge = driver.browser.send(:bridge) + path = '/session/:session_id/chromium/send_command' + path[':session_id'] = bridge.session_id + bridge.http.call(:post, path, cmd: 'Page.setDownloadBehavior', + params: { behavior: 'allow', downloadPath: DownloadsHelper.path.to_s }) + + driver end Capybara.default_max_wait_time = 30 @@ -145,6 +155,7 @@ RSpec.configure do |config| config.include ActionView::Helpers::DateHelper config.include OpenFoodNetwork::DelayedJobHelper config.include OpenFoodNetwork::PerformanceHelper + config.include DownloadsHelper, type: :feature # FactoryBot require 'factory_bot_rails' diff --git a/spec/support/downloads_helper.rb b/spec/support/downloads_helper.rb new file mode 100644 index 0000000000..2adb6fcbe5 --- /dev/null +++ b/spec/support/downloads_helper.rb @@ -0,0 +1,47 @@ +module DownloadsHelper + TIMEOUT = 10 + + def self.path + Rails.root.join("tmp", "downloads") + end + + def downloaded_filename + wait_for_download + downloaded_filenames.first + end + + def downloaded_content + wait_for_download + File.read(downloaded_filename) + end + + def with_empty_downloads_folder + remove_downloaded_files + yield + remove_downloaded_files + end + + private + + def downloaded_filenames + Dir[DownloadsHelper.path.join("*")] + end + + def wait_for_download + Timeout.timeout(TIMEOUT) do + sleep 0.1 until downloaded? + end + end + + def downloaded? + !downloading? && downloaded_filenames.any? + end + + def downloading? + downloaded_filenames.grep(/\.crdownload$/).any? + end + + def remove_downloaded_files + FileUtils.rm_f(downloaded_filenames) + end +end