feat: publish unlisted GTIN tool
This commit is contained in:
@@ -26,7 +26,8 @@ import pages # noqa: E402
|
||||
from content import CONTACT, LEGAL, SITE as META # noqa: E402
|
||||
|
||||
ROUTE_PATHS = [route[0] for route in pages.ROUTES]
|
||||
HTML_FILES = sorted(SITE.rglob("*.html"))
|
||||
HTML_FILES = [SITE / route[1] for route in pages.ROUTES] + [SITE / "404.html"]
|
||||
GTIN_HTML = SITE / "gtin" / "index.html"
|
||||
|
||||
|
||||
def read(path: Path) -> str:
|
||||
@@ -48,8 +49,8 @@ class BuildLayout(unittest.TestCase):
|
||||
self.assertTrue((SITE / rel).is_file(), f"missing {rel}")
|
||||
|
||||
def test_no_stray_html_files(self):
|
||||
expected = {route[1] for route in pages.ROUTES} | {"404.html"}
|
||||
actual = {str(f.relative_to(SITE)) for f in HTML_FILES}
|
||||
expected = {route[1] for route in pages.ROUTES} | {"404.html", "gtin/index.html"}
|
||||
actual = {str(f.relative_to(SITE)) for f in SITE.rglob("*.html")}
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_site_files_are_world_readable(self):
|
||||
@@ -214,6 +215,9 @@ class PrivacyAndLegal(unittest.TestCase):
|
||||
for needle in (
|
||||
"keine Zugriffsprotokolle",
|
||||
"keine Cookies",
|
||||
"GTIN-Tool",
|
||||
"bis zu 20",
|
||||
"nicht an einen Server übertragen",
|
||||
"youtube-nocookie.com",
|
||||
"Art. 6 Abs. 1 lit. f DSGVO",
|
||||
LEGAL["authority"],
|
||||
@@ -314,6 +318,43 @@ class Content(unittest.TestCase):
|
||||
self.assertIn("User-agent: *", read(SITE / "robots.txt"))
|
||||
self.assertIn(f"Sitemap: {META['url']}/sitemap.xml", read(SITE / "robots.txt"))
|
||||
|
||||
def test_gtin_tool_is_public_but_unlisted(self):
|
||||
text = read(GTIN_HTML)
|
||||
self.assertIn("GTIN Generator", text)
|
||||
self.assertIn('<link rel="canonical" href="https://desfoto.de/gtin/" />', text)
|
||||
self.assertIn('<meta name="robots" content="noindex, nofollow" />', text)
|
||||
self.assertIn('href="/impressum/"', text)
|
||||
self.assertIn('href="/datenschutz/"', text)
|
||||
self.assertNotIn('href="/"', text)
|
||||
self.assertNotIn("/gtin/", read(SITE / "sitemap.xml"))
|
||||
for file in HTML_FILES:
|
||||
with self.subTest(file=str(file.relative_to(SITE))):
|
||||
self.assertNotIn("/gtin", read(file))
|
||||
|
||||
def test_gtin_assets_and_local_data_storage_are_scoped(self):
|
||||
html_text = read(GTIN_HTML)
|
||||
for asset in ("./css/app.css", "./js/app.js", "./manifest.webmanifest"):
|
||||
with self.subTest(asset=asset):
|
||||
self.assertTrue((SITE / "gtin" / asset.removeprefix("./")).is_file())
|
||||
self.assertIn(asset, html_text)
|
||||
self.assertTrue((SITE / "gtin" / "sw.js").is_file())
|
||||
self.assertFalse((SITE / "gtin" / "health").exists())
|
||||
app_js = read(SITE / "gtin" / "js" / "app.js")
|
||||
self.assertIn("desfoto.gtin.verlauf.v1", app_js)
|
||||
self.assertIn("localStorage", app_js)
|
||||
self.assertIn(".register('./sw.js', { scope: './' })", app_js)
|
||||
self.assertNotIn("fetch(", app_js)
|
||||
self.assertNotIn("XMLHttpRequest", app_js)
|
||||
service_worker = read(SITE / "gtin" / "sw.js")
|
||||
self.assertIn("name.startsWith(CACHE_PREFIX)", service_worker)
|
||||
self.assertIn("if (!ziel.pathname.startsWith(SCOPE_PFAD)) return;", service_worker)
|
||||
self.assertNotIn("/impressum/", service_worker)
|
||||
|
||||
def test_gtin_manifest_uses_the_web_app_manifest_mime_type(self):
|
||||
conf = read(ROOT / "nginx.conf")
|
||||
self.assertIn("location = /gtin/manifest.webmanifest", conf)
|
||||
self.assertIn("default_type application/manifest+json;", conf)
|
||||
|
||||
|
||||
class Redesign(unittest.TestCase):
|
||||
"""The 2026 redesign: Arbeitsbereiche, real portfolio, logo, motion layer."""
|
||||
|
||||
Reference in New Issue
Block a user