FIX: SVG Sprite version hash should be based on bundle result

This version hash is used for the filename, and so browsers/CDNs cache based on it. Previously the version hash was based only on the list of requested icons. This can cause issues in a couple of situations, most commonly when developing themes with custom icons:

- A requested icon does not exist, and then later is added to the theme. The bundle output changes, but the hash did not
- The SVG content of an icon changes, but the name of the icon does not. The bundle output changes, but the hash did not
This commit is contained in:
David Taylor 2019-11-14 13:20:16 +00:00
parent fe01099a38
commit f2da630c19
2 changed files with 32 additions and 1 deletions

View File

@ -239,7 +239,7 @@ module SvgSprite
def self.version(theme_ids = [])
get_set_cache("version_#{Theme.transform_ids(theme_ids).join(',')}") do
Digest::SHA1.hexdigest(all_icons(theme_ids).join('|'))
Digest::SHA1.hexdigest(bundle(theme_ids))
end
end

View File

@ -49,6 +49,37 @@ describe SvgSprite do
expect(version1).not_to eq(version2)
end
it 'version should be based on bundled output, not requested icons' do
theme = Fabricate(:theme)
fname = "custom-theme-icon-sprite.svg"
upload = UploadCreator.new(file_from_fixtures(fname), fname, for_theme: true).create_for(-1)
version1 = SvgSprite.version([theme.id])
bundle1 = SvgSprite.bundle([theme.id])
SiteSetting.svg_icon_subset = "my-custom-theme-icon"
version2 = SvgSprite.version([theme.id])
bundle2 = SvgSprite.bundle([theme.id])
# The contents of the bundle should not change, because the icon does not actually exist
expect(bundle1).to eq(bundle2)
# Therefore the version hash should not change
expect(version1).to eq(version2)
# Now add the icon to the theme
theme.set_field(target: :common, name: SvgSprite.theme_sprite_variable_name, upload_id: upload.id, type: :theme_upload_var)
theme.save!
version3 = SvgSprite.version([theme.id])
bundle3 = SvgSprite.bundle([theme.id])
# The version/bundle should be updated
expect(bundle3).not_to match(bundle2)
expect(version3).not_to match(version2)
expect(bundle3).to match(/my-custom-theme-icon/)
end
it 'strips whitespace when processing icons' do
Fabricate(:badge, name: 'Custom Icon Badge', icon: ' fab fa-facebook-messenger ')
expect(SvgSprite.all_icons).to include("fab-facebook-messenger")