From f4973498bee6ceba412404484aa521ef98bd9b6b Mon Sep 17 00:00:00 2001 From: karim-semmoud Date: Tue, 13 Jun 2023 11:47:22 +0200 Subject: [PATCH 1/4] Add budget image to Budget and image factories and model --- spec/factories/files.rb | 4 ++++ spec/models/budget_spec.rb | 1 + spec/models/image_spec.rb | 1 + 3 files changed, 6 insertions(+) diff --git a/spec/factories/files.rb b/spec/factories/files.rb index 5876c90c8..5aa2a9295 100644 --- a/spec/factories/files.rb +++ b/spec/factories/files.rb @@ -8,6 +8,10 @@ FactoryBot.define do association :imageable, factory: :proposal end + trait :budget_image do + association :imageable, factory: :budget + end + trait :budget_investment_image do association :imageable, factory: :budget_investment end diff --git a/spec/models/budget_spec.rb b/spec/models/budget_spec.rb index 79415f512..ff1ae010e 100644 --- a/spec/models/budget_spec.rb +++ b/spec/models/budget_spec.rb @@ -6,6 +6,7 @@ describe Budget do it_behaves_like "sluggable", updatable_slug_trait: :drafting it_behaves_like "reportable" it_behaves_like "globalizable", :budget + it_behaves_like "acts as imageable", :budget_image describe "scopes" do describe ".open" do diff --git a/spec/models/image_spec.rb b/spec/models/image_spec.rb index 6b4603923..dc1a908bc 100644 --- a/spec/models/image_spec.rb +++ b/spec/models/image_spec.rb @@ -2,6 +2,7 @@ require "rails_helper" describe Image do it_behaves_like "image validations", "budget_investment_image" + it_behaves_like "image validations", "budget_image" it_behaves_like "image validations", "proposal_image" it "stores attachments with Active Storage" do From 5630a24d7aebf33c79bd8bdf4fc60a6afce531bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Mon, 19 Dec 2022 14:38:10 +0100 Subject: [PATCH 2/4] Render budget images with special chars their names Images with brackets weren't being rendered properly, so we're now enclosing the URL in single quotes. In order to render images with single quotes, we're also using the `j` method. Since the tests were written by a different developer, we're adding them in the next commit. --- app/components/budgets/budget_component.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/components/budgets/budget_component.html.erb b/app/components/budgets/budget_component.html.erb index d0855c9db..2563ee70d 100644 --- a/app/components/budgets/budget_component.html.erb +++ b/app/components/budgets/budget_component.html.erb @@ -1,6 +1,6 @@ <% if budget.image.present? %>
+ style="background-image: url('<%= j polymorphic_path(budget.image.variant(:large)) %>');"> <% else %>
<% end %> From 3a623c070f1612be4a05a1a584993228802dae21 Mon Sep 17 00:00:00 2001 From: karim-semmoud Date: Tue, 13 Jun 2023 11:38:27 +0200 Subject: [PATCH 3/4] Add tests for budget images with brackets / quotes --- .../budgets/budget_component_spec.rb | 39 ++++++++++++++++++ spec/factories/budgets.rb | 4 ++ spec/fixtures/files/clippy(with_brackets).jpg | Bin 0 -> 12394 bytes spec/fixtures/files/clippy_with_'quotes'.jpg | Bin 0 -> 12394 bytes 4 files changed, 43 insertions(+) create mode 100644 spec/fixtures/files/clippy(with_brackets).jpg create mode 100644 spec/fixtures/files/clippy_with_'quotes'.jpg diff --git a/spec/components/budgets/budget_component_spec.rb b/spec/components/budgets/budget_component_spec.rb index 02d94bc6a..7e46693d0 100644 --- a/spec/components/budgets/budget_component_spec.rb +++ b/spec/components/budgets/budget_component_spec.rb @@ -36,4 +36,43 @@ describe Budgets::BudgetComponent do end end end + + describe "budget image" do + it "does not show a background image when the budget has no image" do + render_inline Budgets::BudgetComponent.new(budget) + + expect(page).to have_css ".budget-header" + expect(page).not_to have_css ".with-background-image" + expect(page).not_to have_css ".budget-header[style*='background-image:']" + end + + it "shows a background image when the bugdet image is defined" do + budget = create(:budget, :with_image) + + render_inline Budgets::BudgetComponent.new(budget) + + expect(page).to have_css ".budget-header.with-background-image" + expect(page).to have_css ".budget-header[style*='background-image:'][style*='clippy.jpg']" + end + + it "quotes the background image filename so it works with filenames with brackets" do + budget.update!(image: create(:image, attachment: fixture_file_upload("clippy(with_brackets).jpg"))) + + render_inline Budgets::BudgetComponent.new(budget) + + expect(page).to have_css ".budget-header.with-background-image" + expect(page).to have_css ".budget-header[style*='background-image:']"\ + "[style*='url(\\''][style*='clippy(with_brackets).jpg\\'']" + end + + it "escapes single quotes in the background image filename" do + budget.update!(image: create(:image, attachment: fixture_file_upload("clippy_with_'quotes'.jpg"))) + + render_inline Budgets::BudgetComponent.new(budget) + + expect(page).to have_css ".budget-header.with-background-image" + expect(page).to have_css ".budget-header[style*='background-image:']"\ + "[style*='url(\\''][style*='clippy_with_\\\\\'quotes\\\\\'.jpg']" + end + end end diff --git a/spec/factories/budgets.rb b/spec/factories/budgets.rb index 2e57a920b..57beb8737 100644 --- a/spec/factories/budgets.rb +++ b/spec/factories/budgets.rb @@ -65,6 +65,10 @@ FactoryBot.define do voting_style { "approval" } end + trait :with_image do + after(:create) { |budget| create(:image, imageable: budget) } + end + trait :with_winner do after(:create) { |budget| create(:budget_investment, :winner, budget: budget) } end diff --git a/spec/fixtures/files/clippy(with_brackets).jpg b/spec/fixtures/files/clippy(with_brackets).jpg new file mode 100644 index 0000000000000000000000000000000000000000..1edb6659b1e4e4010486dd35aa5bdf914acaa654 GIT binary patch literal 12394 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 Date: Tue, 27 Jun 2023 14:53:58 +0200 Subject: [PATCH 4/4] Fix background images with special characters Just like we did for budgets, we're doing the same thing in all the places where we render background images attached by either regular users or administrators. This way we correctly render background images with characters like brackets or quotes. --- app/components/budgets/budget_component.html.erb | 2 +- app/components/budgets/budget_component.rb | 1 + app/helpers/images_helper.rb | 4 ++++ app/views/dashboard/poster/index.html.erb | 2 +- app/views/dashboard/poster/index.pdf.erb | 2 +- app/views/layouts/devise.html.erb | 2 +- spec/helpers/images_helper_spec.rb | 13 +++++++++++++ 7 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 spec/helpers/images_helper_spec.rb diff --git a/app/components/budgets/budget_component.html.erb b/app/components/budgets/budget_component.html.erb index 2563ee70d..332920b2e 100644 --- a/app/components/budgets/budget_component.html.erb +++ b/app/components/budgets/budget_component.html.erb @@ -1,6 +1,6 @@ <% if budget.image.present? %>
+ style="<%= attached_background_css polymorphic_path(budget.image.variant(:large)) %>"> <% else %>
<% end %> diff --git a/app/components/budgets/budget_component.rb b/app/components/budgets/budget_component.rb index b11ebce85..4b842a3fd 100644 --- a/app/components/budgets/budget_component.rb +++ b/app/components/budgets/budget_component.rb @@ -1,5 +1,6 @@ class Budgets::BudgetComponent < ApplicationComponent attr_reader :budget + delegate :attached_background_css, to: :helpers def initialize(budget) @budget = budget diff --git a/app/helpers/images_helper.rb b/app/helpers/images_helper.rb index 06d63e9f8..787f8cf25 100644 --- a/app/helpers/images_helper.rb +++ b/app/helpers/images_helper.rb @@ -14,4 +14,8 @@ module ImagesHelper version: (version if image.persisted?), show_caption: show_caption end + + def attached_background_css(path) + "background-image: url('#{j path}');" + end end diff --git a/app/views/dashboard/poster/index.html.erb b/app/views/dashboard/poster/index.html.erb index e1cddb5d4..bbd988356 100644 --- a/app/views/dashboard/poster/index.html.erb +++ b/app/views/dashboard/poster/index.html.erb @@ -18,7 +18,7 @@

<% if proposal.image.present? %> -
+
<% else %>
);">
<% end %> diff --git a/app/views/dashboard/poster/index.pdf.erb b/app/views/dashboard/poster/index.pdf.erb index c762156d2..7c4eaebe1 100644 --- a/app/views/dashboard/poster/index.pdf.erb +++ b/app/views/dashboard/poster/index.pdf.erb @@ -23,7 +23,7 @@

<% if proposal.image.present? %> -
+
<% else %>
');">
<% end %> diff --git a/app/views/layouts/devise.html.erb b/app/views/layouts/devise.html.erb index 7ed3b55b1..26943bf56 100644 --- a/app/views/layouts/devise.html.erb +++ b/app/views/layouts/devise.html.erb @@ -10,7 +10,7 @@ <%= raw setting["html.per_page_code_body"] %>
)"> + style="<%= attached_background_css asset_url(image_path_for("auth_bg.jpg")) %>">

<%= link_to root_path do %> <%= image_tag(image_path_for("logo_header.png"), class: "float-left", alt: setting["org_name"]) %> diff --git a/spec/helpers/images_helper_spec.rb b/spec/helpers/images_helper_spec.rb new file mode 100644 index 000000000..f115a84f3 --- /dev/null +++ b/spec/helpers/images_helper_spec.rb @@ -0,0 +1,13 @@ +require "rails_helper" + +describe ImagesHelper do + describe "#attached_background_css" do + it "adds quotes around the path" do + expect(attached_background_css("myurl")).to eq "background-image: url('myurl');" + end + + it "escapes quotes inside the path" do + expect(attached_background_css("url_'quotes'")).to eq "background-image: url('url_\\'quotes\\'');" + end + end +end