import re import pytest from apps.blog.models import ArticleIndexPage, ArticlePage from apps.blog.tests.factories import AuthorFactory @pytest.mark.django_db def test_security_headers_present(client, home_page): resp = client.get("/") assert resp.status_code == 200 assert "Content-Security-Policy" in resp assert "Permissions-Policy" in resp assert "unsafe-inline" not in resp["Content-Security-Policy"] assert "script-src" in resp["Content-Security-Policy"] assert resp["X-Frame-Options"] == "SAMEORIGIN" assert "strict-origin-when-cross-origin" in resp["Referrer-Policy"] @pytest.mark.django_db def test_csp_nonce_applied_to_inline_script(client, home_page): resp = client.get("/") csp = resp["Content-Security-Policy"] match = re.search(r"nonce-([^' ;]+)", csp) assert match nonce = match.group(1) html = resp.content.decode() assert f'nonce="{nonce}"' in html @pytest.mark.django_db def test_robots_disallows_cms_and_contains_sitemap(client): resp = client.get("/robots.txt") body = resp.content.decode() assert resp.status_code == 200 assert "Disallow: /cms/" in body assert "Sitemap:" in body @pytest.mark.django_db def test_admin_obscured_path_redirects_to_cms(client): resp = client.get("/admin/") assert resp.status_code == 302 assert resp["Location"] == "/cms/" @pytest.mark.django_db def test_article_comment_form_contains_csrf_token(client, home_page): index = ArticleIndexPage(title="Articles", slug="articles") home_page.add_child(instance=index) author = AuthorFactory() article = ArticlePage( title="CSRF Article", slug="csrf-article", author=author, summary="summary", body=[("rich_text", "

Body

")], ) index.add_child(instance=article) article.save_revision().publish() resp = client.get("/articles/csrf-article/") html = resp.content.decode() assert resp.status_code == 200 assert "csrfmiddlewaretoken" in html @pytest.mark.django_db def test_consent_rejects_open_redirect(client, home_page): resp = client.post( "/consent/", {"reject_all": "1"}, HTTP_REFERER="https://evil.example.com/phish", ) assert resp.status_code == 302 assert resp["Location"] == "/" @pytest.mark.django_db def test_article_json_ld_script_has_csp_nonce(client, home_page): index = ArticleIndexPage(title="Articles", slug="articles") home_page.add_child(instance=index) author = AuthorFactory() article = ArticlePage( title="Nonce Article", slug="nonce-article", author=author, summary="summary", body=[("rich_text", "

Body

")], ) index.add_child(instance=article) article.save_revision().publish() resp = client.get("/articles/nonce-article/") csp = resp["Content-Security-Policy"] match = re.search(r"nonce-([^' ;]+)", csp) assert match nonce = match.group(1) html = resp.content.decode() assert f'type="application/ld+json" nonce="{nonce}"' in html