import re import pytest from treeherder.middleware import CustomWhiteNoise URLS_IMMUTABLE = [ # Assets generated by Yarn. "/assets/2.379789df.css", "/assets/dancing_cat.fa5552a5.gif", "/assets/fontawesome-webfont.af7ae505.woff2", "/assets/fontawesome-webfont.fee66e71.woff", "/assets/index.1d85033a.js", "/assets/index.1d85033a.js.map", "/assets/perf.d7fea1e4.css", "/assets/perf.d7fea1e4.css.map", "/assets/treeherder-logo.3df97cff.png", ] URLS_NOT_IMMUTABLE = [ "/", "/contribute.json", "/perf.html", "/revision.txt", "/tree_open.png", "/docs/schema.js", # The unhashed Yarn/webpack output if using `yarn build --mode development`. "/assets/runtime.js", "/assets/vendors~index.js", # The unhashed Django static asset originals (used in development). "/static/debug_toolbar/assets/toolbar.css", "/static/rest_framework/docs/js/jquery.json-view.min.js", ] @pytest.mark.parametrize("url", URLS_IMMUTABLE) def test_immutable_file_test_matches(url): assert CustomWhiteNoise().immutable_file_test("", url) @pytest.mark.parametrize("url", URLS_NOT_IMMUTABLE) def test_immutable_file_test_does_not_match(url): assert not CustomWhiteNoise().immutable_file_test("", url) def test_content_security_policy_header(client): # Ideally we'd test requesting our frontend HTML, eg `/` and `/login.html`, # however they won't exist unless `yarn build` has been run first. # So instead we request an arbitrary static asset from django-rest-framework, # which will be served with the same headers as our frontend HTML. response = client.get("/static/rest_framework/css/default.css") assert response.has_header("Content-Security-Policy") policy_regex = r"default-src 'none'; script-src 'self' 'unsafe-eval' 'report-sample'; .*; report-uri /api/csp-report/" assert re.match(policy_regex, response["Content-Security-Policy"])