Files
notifications-admin/tests/app/main/test_asset_fingerprinter.py

117 lines
4.0 KiB
Python
Raw Permalink Normal View History

# coding=utf-8
from app.asset_fingerprinter import AssetFingerprinter
class TestAssetFingerprint(object):
2017-07-07 14:16:18 +01:00
def test_url_format(self, mocker):
get_file_content_mock = mocker.patch.object(
AssetFingerprinter, "get_asset_file_contents"
)
get_file_content_mock.return_value = """
body {
font-family: nta;
}
""".encode(
"utf-8"
)
asset_fingerprinter = AssetFingerprinter(asset_root="/suppliers/static/")
assert (
asset_fingerprinter.get_url("application.css")
== "/suppliers/static/application.css?418e6f4a6cdf1142e45c072ed3e1c90a"
)
assert (
asset_fingerprinter.get_url("application-ie6.css")
== "/suppliers/static/application-ie6.css?418e6f4a6cdf1142e45c072ed3e1c90a"
)
2017-07-07 14:16:18 +01:00
def test_building_file_path(self, mocker):
get_file_content_mock = mocker.patch.object(
AssetFingerprinter, "get_asset_file_contents"
)
get_file_content_mock.return_value = """
document.write('Hello world!');
""".encode(
"utf-8"
)
fingerprinter = AssetFingerprinter()
fingerprinter.get_url("javascripts/application.js")
fingerprinter.get_asset_file_contents.assert_called_with(
"app/static/javascripts/application.js"
)
2017-07-07 14:16:18 +01:00
def test_hashes_are_consistent(self, mocker):
get_file_content_mock = mocker.patch.object(
AssetFingerprinter, "get_asset_file_contents"
)
get_file_content_mock.return_value = """
body {
font-family: nta;
}
""".encode(
"utf-8"
)
asset_fingerprinter = AssetFingerprinter()
assert asset_fingerprinter.get_asset_fingerprint(
"application.css"
) == asset_fingerprinter.get_asset_fingerprint("same_contents.css")
def test_hashes_are_different_for_different_files(self, mocker):
get_file_content_mock = mocker.patch.object(
AssetFingerprinter, "get_asset_file_contents"
)
asset_fingerprinter = AssetFingerprinter()
get_file_content_mock.return_value = """
body {
font-family: nta;
}
""".encode(
"utf-8"
)
css_hash = asset_fingerprinter.get_asset_fingerprint("application.css")
get_file_content_mock.return_value = """
document.write('Hello world!');
""".encode(
"utf-8"
)
js_hash = asset_fingerprinter.get_asset_fingerprint("application.js")
assert js_hash != css_hash
2017-07-07 14:16:18 +01:00
def test_hash_gets_cached(self, mocker):
get_file_content_mock = mocker.patch.object(
AssetFingerprinter, "get_asset_file_contents"
)
get_file_content_mock.return_value = """
body {
font-family: nta;
}
""".encode(
"utf-8"
)
fingerprinter = AssetFingerprinter()
assert (
fingerprinter.get_url("application.css")
== "/static/application.css?418e6f4a6cdf1142e45c072ed3e1c90a"
)
fingerprinter._cache["application.css"] = "a1a1a1"
assert fingerprinter.get_url("application.css") == "a1a1a1"
fingerprinter.get_asset_file_contents.assert_called_once_with(
"app/static/application.css"
)
Tell browsers to preload fonts When looking at Google’s PageSpeed Insights tool as part of the compression work I noticed a suggestion that we preload our font files. The tool suggests this should save about 300ms on first page load time. *** Our font files are referenced from our CSS. This means that the browser has to download and parse the CSS before it knows where to find the font files. This means the requests happen in sequence. We can make the requests happen in parallel by using a `<link>` tag with `rel=preload`. This tells the browser to start downloading the fonts before it’s even started downloading the CSS (the CSS will be the next thing to start downloading, since it’s the next `<link>` element in the head of the HTML). Downloading fonts before things like images is important because once the font is downloaded it causes the layout to repaint, and shift everything around. So the page doesn’t feel stable until after the fonts have loaded. Google call this [cumulative layout shift](https://web.dev/cls/) which is a score for how much the page moves around. A lower score means a better experience (and, less importantly for us, means the page might rank higher in search results) We’re only preloading the WOFF2 fonts because only modern browsers support preload, and these browsers also all support WOFF2. We set an empty `crossorigin` attribute (which means anonymous-mode) because the preload request needs to match the origin’s CORS mode. See https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content#CORS-enabled_fetches for more details. We set `as=font` because this helps the browser use the correct content security policy, and prioritise which requests to make first.
2020-12-29 13:38:27 +00:00
def test_without_hash_if_requested(self, mocker):
fingerprinter = AssetFingerprinter()
assert fingerprinter.get_url(
"application.css",
Tell browsers to preload fonts When looking at Google’s PageSpeed Insights tool as part of the compression work I noticed a suggestion that we preload our font files. The tool suggests this should save about 300ms on first page load time. *** Our font files are referenced from our CSS. This means that the browser has to download and parse the CSS before it knows where to find the font files. This means the requests happen in sequence. We can make the requests happen in parallel by using a `<link>` tag with `rel=preload`. This tells the browser to start downloading the fonts before it’s even started downloading the CSS (the CSS will be the next thing to start downloading, since it’s the next `<link>` element in the head of the HTML). Downloading fonts before things like images is important because once the font is downloaded it causes the layout to repaint, and shift everything around. So the page doesn’t feel stable until after the fonts have loaded. Google call this [cumulative layout shift](https://web.dev/cls/) which is a score for how much the page moves around. A lower score means a better experience (and, less importantly for us, means the page might rank higher in search results) We’re only preloading the WOFF2 fonts because only modern browsers support preload, and these browsers also all support WOFF2. We set an empty `crossorigin` attribute (which means anonymous-mode) because the preload request needs to match the origin’s CORS mode. See https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content#CORS-enabled_fetches for more details. We set `as=font` because this helps the browser use the correct content security policy, and prioritise which requests to make first.
2020-12-29 13:38:27 +00:00
with_querystring_hash=False,
) == ("/static/application.css")
Tell browsers to preload fonts When looking at Google’s PageSpeed Insights tool as part of the compression work I noticed a suggestion that we preload our font files. The tool suggests this should save about 300ms on first page load time. *** Our font files are referenced from our CSS. This means that the browser has to download and parse the CSS before it knows where to find the font files. This means the requests happen in sequence. We can make the requests happen in parallel by using a `<link>` tag with `rel=preload`. This tells the browser to start downloading the fonts before it’s even started downloading the CSS (the CSS will be the next thing to start downloading, since it’s the next `<link>` element in the head of the HTML). Downloading fonts before things like images is important because once the font is downloaded it causes the layout to repaint, and shift everything around. So the page doesn’t feel stable until after the fonts have loaded. Google call this [cumulative layout shift](https://web.dev/cls/) which is a score for how much the page moves around. A lower score means a better experience (and, less importantly for us, means the page might rank higher in search results) We’re only preloading the WOFF2 fonts because only modern browsers support preload, and these browsers also all support WOFF2. We set an empty `crossorigin` attribute (which means anonymous-mode) because the preload request needs to match the origin’s CORS mode. See https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content#CORS-enabled_fetches for more details. We set `as=font` because this helps the browser use the correct content security policy, and prioritise which requests to make first.
2020-12-29 13:38:27 +00:00
assert fingerprinter._cache == {}
class TestAssetFingerprintWithUnicode(object):
def test_can_read_self(self):
"Ralphs apostrophe is a string containing a unicode character"
AssetFingerprinter(filesystem_path="tests/app/main/").get_url(
"test_asset_fingerprinter.py"
)