From ad24dcac58eea06f874055665aeed02801fde004 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Tue, 8 Sep 2026 10:08:23 +0200 Subject: feat: serve the latest Slackware -current ChangeLog entry to Homepage Homepage's customapi widget speaks JSON and cannot parse text, so the ChangeLog needs something in front of it. This proxy fetches the file, keeps only the entry above the first separator, and serves the counts, the CVE ids, a truncated package list and the entry as a page. Package lines are matched by starting at column 0 rather than by their trailing period, since the indented notes below them frequently end in one too. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0184D3xBAHPcZE9jZ45R5J26 --- test_changelog.py | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 test_changelog.py (limited to 'test_changelog.py') diff --git a/test_changelog.py b/test_changelog.py new file mode 100644 index 0000000..b1454b8 --- /dev/null +++ b/test_changelog.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 +# Copyright (C) 2026 Danilo M. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +"""Self-check: run `python3 test_changelog.py`. Fakes the mirror, exercises +parsing, caching and the stale fallback.""" + +import io +import urllib.request + +import slackware_changelog as c + +SAMPLE = """Mon Sep 7 22:56:39 UTC 2026 +a/util-linux-2.42.3-x86_64-1.txz: Upgraded. + This update fixes bugs and security issues. + For more information, see: + https://www.cve.org/CVERecord?id=CVE-2026-76642 + https://www.cve.org/CVERecord?id=CVE-2026-78410 + (* Security fix *) +l/cryptopp-8.9.0-x86_64-3.txz: Rebuilt. + Fixed library location. Thanks to Petri Kaukasoina. +n/foo-1.0-x86_64-1.txz: Added. +n/bar-1.0-x86_64-1.txz: Removed. ++--------------------------+ +Sun Sep 6 00:00:00 UTC 2026 +a/should-not-appear-1.0-x86_64-1.txz: Upgraded. +""" + +fail = [False] + + +def fake_urlopen(url, timeout=0): + if fail[0]: + raise OSError("mirror down") + return io.BytesIO(SAMPLE.encode()) + + +urllib.request.urlopen = fake_urlopen + +d = c.parse(SAMPLE) +assert d["date"] == "Mon Sep 7 22:56:39 UTC 2026", d["date"] +assert (d["packages"], d["upgraded"], d["rebuilt"], d["added"], d["removed"]) == (4, 1, 1, 1, 1), d +assert d["security"] == 1, d +assert d["cves"] == ["CVE-2026-76642", "CVE-2026-78410"], d["cves"] +assert "should-not-appear" not in d["entry"], "the next entry leaked in" +assert d["package_list"][0] == {"name": "a/util-linux-2.42.3-x86_64-1.txz", + "action": "upgraded"}, d["package_list"][0] +assert "1 upgraded" in d["summary"], d["summary"] + +# An indented note that ends in a word plus a period is not a package line. +assert all("Thanks to" not in p["name"] for p in d["package_list"]), d["package_list"] + +# Cache holds, and a failing refresh keeps serving the last good entry. +first = c.fetch() +assert first["date"] == d["date"] +fail[0] = True +stale = c.fetch(force=True) +assert stale["date"] == d["date"], "lost the cached entry on a failed refresh" +assert "mirror down" in stale["stale"], stale.get("stale") + +# /top: flat keys, prefix and .txz stripped, overflow line when truncated. +t = c.top(d, n=2) +assert t["pkg1"] == "util-linux-2.42.3-x86_64-1 - upgraded", t["pkg1"] +assert t["pkg3"] == "... and 2 more", t +assert t["packages"] == 4 and t["date"] == d["date"], t +assert "pkg4" not in t, t +assert "pkg5" not in c.top(d, n=10), "overflow line on a complete list" +assert c.top(d, n=10)["pkg4"] == "bar-1.0-x86_64-1 - removed", c.top(d, n=10) + +page = c.render(c._cache["data"]) +assert "Sep 7" in page and "util-linux" in page +assert "