diff --git a/Makefile b/Makefile index 06259916ed7..059005d688f 100644 --- a/Makefile +++ b/Makefile @@ -195,9 +195,9 @@ normalize_yaml: ## Normalizes YAML files (alphabetizes keys, fixes line length, config/country_dialing_codes.yml optimize_svg: ## Optimizes SVG images - # Without disabling minifyStyles, keyframes are removed (e.g. `app/assets/images/id-card.svg`). - # See: https://github.com/svg/svgo/issues/888 - find app/assets/images public -name '*.svg' -not -name 'sprite.svg' | xargs ./node_modules/.bin/svgo + # Exclusions: + # - `login-icon-bimi.svg` is hand-optimized and includes required metadata that would be stripped by SVGO + find app/assets/images public -name '*.svg' -not -name 'login-icon-bimi.svg' | xargs ./node_modules/.bin/svgo optimize_assets: optimize_svg ## Optimizes all assets diff --git a/public/images/login-icon-bimi.svg b/public/images/login-icon-bimi.svg new file mode 100644 index 00000000000..13b94e54649 --- /dev/null +++ b/public/images/login-icon-bimi.svg @@ -0,0 +1 @@ +Login.govLogin.gov logo, a red badge with a keyhole \ No newline at end of file diff --git a/spec/requests/bimi_logo_spec.rb b/spec/requests/bimi_logo_spec.rb new file mode 100644 index 00000000000..d889f5eb63a --- /dev/null +++ b/spec/requests/bimi_logo_spec.rb @@ -0,0 +1,70 @@ +require 'rails_helper' + +RSpec.describe 'BIMI logo' do + let(:image_response) do + get '/images/login-icon-bimi.svg' + response + end + subject(:image) { Nokogiri::XML(image_response.body) } + + it 'is available' do + # If you're troubleshooting this spec, there's a good chance you're trying to remove a file that + # appears to be unused. This comment is here to assure you that it is in-fact used, referenced + # as part of the BIMI DMARC records associated with the Login.gov domain. The image should not + # be removed as long as it's referenced by those records. + expect(image_response.status).to eq(200) + end + + describe 'validity' do + # Test cases in this block reference best practices documentation from BIMI group: + # See: https://bimigroup.org/creating-bimi-svg-logo-files/ + + it 'is no larger than 32kb' do + # "The SVG document should be as small as possible and should not exceed 32 kilobytes." + size_in_kilobytes = image_response.content_length.to_f / 1024 + + expect(size_in_kilobytes).to be <= 32 + end + + it 'has expected root attributes' do + # "When building your SVG there are a number of required elements in the structure of the + # file:" + + # "The “baseProfile” attribute set to “tiny-ps”" + expect(image.css('svg[baseProfile="tiny-ps"]')).to be_present + + # "The “version” attribute set to “1.2”" + expect(image.css('svg[version="1.2"]')).to be_present + + # "A element must be included that reflects the company name, though there are no + # strict requirements for the content of the element." + expect(image.css('title').text).to be_present + end + + it 'does not include forbidden elements' do + # "The SVG document must not include any of the following in order to be valid under the + # tiny-ps designation:" + + # "Any external links or references (other than to the specified XML namespaces)" + # expect(image.css('[xlink\\:href]')).to be_blank + expect(image.xpath('//*[@href]')).to be_blank + + # "Any scripts, animation, or other interactive elements" + expect(image.css('animate')).to be_blank + expect(image.css('script')).to be_blank + + # "“x=” or “y=” attributes within the <svg> root element" + expect(image.css('[x]')).to be_blank + expect(image.css('[y]')).to be_blank + end + + it 'is square' do + # "The image should be a square aspect ratio" + root = image.css('svg') + width = root.attr('width').value + height = root.attr('height').value + + expect(width).to eq(height) + end + end +end