From 2098b7a9559fb5bd5fa05f1ed16cb9263e56b764 Mon Sep 17 00:00:00 2001 From: Abdessamad Derraz <3028866+Abdess@users.noreply.github.com> Date: Fri, 23 Oct 2026 02:30:20 +0200 Subject: [PATCH] fix: judge a redirect page by its target --- scripts/validate_site.py | 9 ++++++++- tests/test_site_validation.py | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/scripts/validate_site.py b/scripts/validate_site.py index 6f76ca6f..2328d0d3 100644 --- a/scripts/validate_site.py +++ b/scripts/validate_site.py @@ -41,6 +41,8 @@ class Page: empty_headers: int = 0 runtime_diagrams: int = 0 size: int = 0 + # A moved page's old address: a meta refresh to the new one, no content. + redirect: str = "" # Budgets the site was brought under on 2026-10-22, with room to grow. A @@ -90,6 +92,8 @@ class _PageParser(HTMLParser): self.page.lang = data.get("lang", "") elif tag == "title": self._title_depth += 1 + elif tag == "meta" and data.get("http-equiv", "").lower() == "refresh": + self.page.redirect = data.get("content", "").partition("url=")[2] elif tag == "meta" and data.get("name", "").lower() == "description": self.page.descriptions.append(data.get("content", "").strip()) elif tag == "h1": @@ -347,7 +351,10 @@ def validate_site(site: Path, base_path: str = "/retrobios/") -> list[str]: titles: dict[str, list[Path]] = defaultdict(list) descriptions: dict[str, list[Path]] = defaultdict(list) - issues.extend(_check_pages(pages, site, titles, descriptions)) + # A redirect has no page to judge, only a target. The link check below + # still follows its link, so a redirect to nowhere is reported. + content = {path: page for path, page in pages.items() if not page.redirect} + issues.extend(_check_pages(content, site, titles, descriptions)) for label, values in (("title", titles), ("description", descriptions)): for value, paths in values.items(): diff --git a/tests/test_site_validation.py b/tests/test_site_validation.py index 8894a12b..644b5b35 100644 --- a/tests/test_site_validation.py +++ b/tests/test_site_validation.py @@ -149,6 +149,25 @@ class RenderedSiteValidation(unittest.TestCase): self.assertTrue(any("images missing alt" in issue for issue in issues)) self.assertTrue(any("broken local link" in issue for issue in issues)) + def test_a_redirect_is_judged_by_its_target(self): + """A moved page's old address holds only a meta refresh. It has no + title or landmark to check, but a target that is gone is reported.""" + (self.site / "index.html").write_text( + _page("Home", "Unique home description."), encoding="utf-8" + ) + for name, target in (("old", "/retrobios/"), ("lost", "/retrobios/gone/")): + folder = self.site / name + folder.mkdir() + (folder / "index.html").write_text( + f'Redirecting to: {target}' + f'' + f'Redirecting', + encoding="utf-8", + ) + issues = validate_site(self.site, self.config) + self.assertFalse([i for i in issues if "old/" in i], issues) + self.assertTrue(any("lost/" in i and "broken local link" in i for i in issues), issues) + def test_duplicate_search_metadata_fails(self): (self.site / "index.html").write_text( _page("Repeated", "Repeated description."), encoding="utf-8"