Skip to content

Commit

Permalink
Backport 'Fix webpacker crashes on missing icons' to v0.26 (#11045)
Browse files Browse the repository at this point in the history
Co-authored-by: Antti Hukkanen <antti.hukkanen@mainiotech.fi>
  • Loading branch information
alecslupu and ahukkanen committed Jun 19, 2023
1 parent 5c47cc4 commit a4fdc79
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 4 deletions.
16 changes: 12 additions & 4 deletions decidim-core/app/helpers/decidim/layout_helper.rb
Expand Up @@ -74,18 +74,26 @@ def external_icon(path, options = {})
classes = _icon_classes(options) + ["external-icon"]

if path.split(".").last == "svg"
icon_path = application_path(path)
return unless icon_path

attributes = { class: classes.join(" ") }.merge(options)
asset = File.read(application_path(path))
asset = File.read(icon_path)
asset.gsub("<svg ", "<svg#{tag_builder.tag_options(attributes)} ").html_safe
else
image_pack_tag(path, class: classes.join(" "), style: "display: none")
end
end

def application_path(path)
img_path = asset_pack_path(path)
img_path = URI(img_path).path if Decidim.cors_enabled
Rails.root.join("public/#{img_path}")
# Force the path to be returned without the protocol and host even when a
# custom asset host has been defined. The host parameter needs to be a
# non-nil because otherwise it will be set to the asset host at
# ActionView::Helpers::AssetUrlHelper#compute_asset_host.
img_path = asset_pack_path(path, host: "", protocol: :relative)
Rails.public_path.join(img_path.sub(%r{^/}, ""))
rescue ::Webpacker::Manifest::MissingEntryError
nil
end

# Allows to create role attribute according to accessibility rules
Expand Down
87 changes: 87 additions & 0 deletions decidim-core/spec/helpers/decidim/layout_helper_spec.rb
@@ -0,0 +1,87 @@
# frozen_string_literal: true

require "spec_helper"

module Decidim
describe LayoutHelper do
describe "#external_icon" do
subject { helper.external_icon(path) }

context "when the icon exists" do
let(:path) { "media/images/google.svg" }

it "returns the SVG element" do
expect(subject).to match(/^<svg.*/)
end
end

context "when the icon does not exist" do
let(:path) { "media/images/hooli.svg" }

it "returns nil" do
expect(subject).to be_nil
end
end

context "when using a custom host" do
let(:path) { "media/images/google.svg" }

before do
allow(helper.config).to receive(:asset_host).and_return("https://assets.example.org")
end

# Ensures the asset_path_pack would normally return the asset host in
# case there are any API changes in Rails.
it "works expectedly" do
expect(helper.asset_pack_path(path)).to match(%r{^https://assets\.example.org/packs-test})
end

it "returns the SVG element" do
expect(subject).to match(/^<svg.*/)
end
end
end

describe "#application_path" do
subject { helper.application_path(path) }

context "when the icon exists" do
let(:path) { "media/images/google.svg" }

it "returns the file path to the asset" do
expect(subject.to_s).to match(
%r{^#{Rails.public_path}/packs-test/media/images/google-[a-z0-9]+\.svg}
)
end
end

context "when the icon does not exist" do
let(:path) { "media/images/hooli.svg" }

it "returns nil" do
expect(subject).to be_nil
end
end

context "when using a custom host" do
let(:path) { "media/images/google.svg" }

before do
allow(helper.config).to receive(:asset_host).and_return("https://assets.example.org")
end

# Ensures the asset_path_pack would normally return the asset host in
# case there are any API changes in Rails.
it "works expectedly" do
expect(helper.asset_pack_path(path)).to match(%r{^https://assets\.example.org/packs-test})
end

it "returns the file path to the asset" do
expect(subject.to_s).to match(
%r{^#{Rails.public_path}/packs-test/media/images/google-[a-z0-9]+\.svg}
)
end
end
end
end
end

0 comments on commit a4fdc79

Please sign in to comment.