From 630169f8bba1507ec48c25d28f1a80b62a56de7f Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 28 Apr 2023 16:36:04 +1000 Subject: [PATCH] Preserve encoding of stored reports Active Storage reads stored strings as ASCII and that can clash with Rails' default UTF-8 encoding when special characters are present. --- app/models/report_blob.rb | 2 +- spec/models/report_blob_spec.rb | 15 +++++++++++++++ spec/system/admin/reports_spec.rb | 25 +++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 spec/models/report_blob_spec.rb diff --git a/app/models/report_blob.rb b/app/models/report_blob.rb index 4ace9d4a7af..08cac98bf4c 100644 --- a/app/models/report_blob.rb +++ b/app/models/report_blob.rb @@ -31,6 +31,6 @@ def content_stored? end def result - @result ||= download + @result ||= download.force_encoding(Encoding::UTF_8) end end diff --git a/spec/models/report_blob_spec.rb b/spec/models/report_blob_spec.rb new file mode 100644 index 00000000000..d16acc8fe04 --- /dev/null +++ b/spec/models/report_blob_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: false + +require 'spec_helper' + +describe ReportBlob, type: :model do + it "preserves UTF-8 content" do + blob = ReportBlob.create_for_upload_later!("customers.html") + content = "This works. ✓" + + expect do + blob.store(content) + content = blob.result + end.to_not change { content.encoding }.from(Encoding::UTF_8) + end +end diff --git a/spec/system/admin/reports_spec.rb b/spec/system/admin/reports_spec.rb index 9b4cf530235..0020d5bfbea 100644 --- a/spec/system/admin/reports_spec.rb +++ b/spec/system/admin/reports_spec.rb @@ -46,6 +46,31 @@ expect(page).to have_content "EMAIL FIRST NAME" end + it "renders UTF-8 characters" do + # We had a problem when UTF-8 was in the page and the report because + # ActiveStorage read ASCII. + # - https://github.com/openfoodfoundation/openfoodnetwork/issues/10758 + # + # Create order to inject special characters: + order = create(:completed_order_with_totals) + + # Render special characters in the page (filter option): + order.distributor.update!(name: "Späti") + + # Render special character within the report: + order.billing_address.update!(lastname: "Müller") + + # Run the report: + login_as_admin + visit admin_report_path( + report_type: :customers, report_subtype: :mailing_list + ) + click_button "Go" + expect(page).to have_content "Späti" + expect(page).to have_content "EMAIL FIRST NAME" + expect(page).to have_content "Müller" + end + it "displays a friendly timeout message and offers download" do ActiveJob::Base.queue_adapter.perform_enqueued_jobs = false login_as_admin