diff --git a/app/__init__.py b/app/__init__.py index ec0ce3771..20f0bc430 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,4 +1,5 @@ import os +import pathlib import re import urllib from datetime import datetime, timedelta, timezone @@ -202,6 +203,11 @@ def init_app(application): application.before_request(load_organisation_before_request) application.before_request(request_helper.check_proxy_header_before_request) + font_paths = [ + str(item)[len(asset_fingerprinter._filesystem_path):] + for item in pathlib.Path(asset_fingerprinter._filesystem_path).glob('fonts/*.woff2') + ] + @application.context_processor def _attach_current_service(): return {'current_service': current_service} @@ -228,7 +234,8 @@ def init_app(application): return { 'asset_path': application.config['ASSET_PATH'], 'header_colour': application.config['HEADER_COLOUR'], - 'asset_url': asset_fingerprinter.get_url + 'asset_url': asset_fingerprinter.get_url, + 'font_paths': font_paths, } application.url_map.converters['uuid'].to_python = lambda self, value: value diff --git a/app/asset_fingerprinter.py b/app/asset_fingerprinter.py index 228b9d512..c6fa3859c 100644 --- a/app/asset_fingerprinter.py +++ b/app/asset_fingerprinter.py @@ -24,7 +24,9 @@ class AssetFingerprinter(object): self._asset_root = asset_root self._filesystem_path = filesystem_path - def get_url(self, asset_path): + def get_url(self, asset_path, with_querystring_hash=True): + if not with_querystring_hash: + return self._asset_root + asset_path if asset_path not in self._cache: self._cache[asset_path] = ( self._asset_root + diff --git a/app/templates/admin_template.html b/app/templates/admin_template.html index 4d5f1c006..a492c9716 100644 --- a/app/templates/admin_template.html +++ b/app/templates/admin_template.html @@ -12,6 +12,9 @@ {% endblock %} {% block head %} + {%- for font in font_paths %} + + {%- endfor %} {% block extra_stylesheets %} diff --git a/tests/app/main/test_asset_fingerprinter.py b/tests/app/main/test_asset_fingerprinter.py index 581294dbd..50513dd4f 100644 --- a/tests/app/main/test_asset_fingerprinter.py +++ b/tests/app/main/test_asset_fingerprinter.py @@ -89,6 +89,16 @@ class TestAssetFingerprint(object): 'app/static/application.css' ) + def test_without_hash_if_requested(self, mocker): + fingerprinter = AssetFingerprinter() + assert fingerprinter.get_url( + 'application.css', + with_querystring_hash=False, + ) == ( + '/static/application.css' + ) + assert fingerprinter._cache == {} + class TestAssetFingerprintWithUnicode(object): def test_can_read_self(self): diff --git a/tests/app/main/views/test_index.py b/tests/app/main/views/test_index.py index 4067452bc..3615b1c65 100644 --- a/tests/app/main/views/test_index.py +++ b/tests/app/main/views/test_index.py @@ -331,3 +331,19 @@ def test_letter_spec_redirect_with_non_logged_in_user(client_request): '/documentation/images/notify-pdf-letter-spec-v2.4.pdf' ), ) + + +def test_font_preload( + client_request, + mock_get_service_and_organisation_counts, +): + client_request.logout() + page = client_request.get('main.index', _test_page_title=False) + + preload_tags = page.select('link[rel=preload][as=font][type="font/woff2"][crossorigin]') + + assert len(preload_tags) == 4, 'Run `npm build` to copy fonts into app/static/fonts/' + + for element in preload_tags: + assert element['href'].startswith('https://static.example.com/fonts/') + assert element['href'].endswith('.woff2')