mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-09 20:26:33 +00:00
Per-file meta/addons/<id>.yml loader, schema + bridge-parity lints, shared update SPOT, unit/external tests, and layout.md/plugins README docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
206 lines
6.8 KiB
Python
206 lines
6.8 KiB
Python
"""Unit tests for the pure addon drift-discovery core.
|
|
|
|
The live external test (`tests/external/update/addons/`) is warn-only and
|
|
opt-in; the reconciliation logic it relies on is exercised here with fixture
|
|
catalogs covering the three behaviours the requirement calls out: a version
|
|
bump, a newly discovered addon, and a marketplace entry intentionally ignored
|
|
by the curated relevance rules.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import tempfile
|
|
import textwrap
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from utils.roles.mapping import ROLE_DIR_META_ADDONS
|
|
from utils.update.addons import (
|
|
AddonEntry,
|
|
CatalogCandidate,
|
|
collect_addon_entries,
|
|
discover_addon_updates,
|
|
version_is_newer,
|
|
)
|
|
|
|
|
|
def _entry(
|
|
addon_id, version="", monitored=True, upstream_id=None, catalog="wordpress-org"
|
|
):
|
|
spec = {
|
|
"mechanism": "plugin",
|
|
"source": "upstream",
|
|
"version": version,
|
|
"update": {"monitored": monitored, "catalog": catalog},
|
|
}
|
|
if upstream_id:
|
|
spec["update"]["upstream_id"] = upstream_id
|
|
return AddonEntry(
|
|
role="web-app-demo",
|
|
addon_id=addon_id,
|
|
config_path=Path("roles/web-app-demo")
|
|
/ ROLE_DIR_META_ADDONS
|
|
/ f"{addon_id}.yml",
|
|
spec=spec,
|
|
)
|
|
|
|
|
|
class TestVersionIsNewer(unittest.TestCase):
|
|
def test_strictly_newer(self):
|
|
self.assertTrue(version_is_newer("2.3.1", "2.4.0"))
|
|
|
|
def test_equal_is_not_newer(self):
|
|
self.assertFalse(version_is_newer("2.3.1", "2.3.1"))
|
|
|
|
def test_blank_current_never_suggests(self):
|
|
self.assertFalse(version_is_newer("", "2.4.0"))
|
|
|
|
def test_non_semver_latest_ignored(self):
|
|
self.assertFalse(version_is_newer("2.3.1", "master"))
|
|
|
|
|
|
class TestDiscoverAddonUpdates(unittest.TestCase):
|
|
def test_version_bump_suggested_for_monitored_pin(self):
|
|
declared = [_entry("oidc", version="2.3.1")]
|
|
candidates = [
|
|
CatalogCandidate(
|
|
upstream_id="oidc",
|
|
latest="2.4.0",
|
|
mechanism="plugin",
|
|
source="built",
|
|
catalog_url="https://example.test/oidc",
|
|
)
|
|
]
|
|
result = discover_addon_updates(
|
|
role="web-app-demo",
|
|
catalog="wordpress-org",
|
|
declared=declared,
|
|
candidates=candidates,
|
|
)
|
|
self.assertEqual(len(result.version_updates), 1)
|
|
self.assertEqual(result.version_updates[0].current, "2.3.1")
|
|
self.assertEqual(result.version_updates[0].latest, "2.4.0")
|
|
self.assertEqual(result.new_addons, [])
|
|
|
|
def test_unmonitored_pin_is_not_bumped(self):
|
|
declared = [_entry("oidc", version="2.3.1", monitored=False)]
|
|
candidates = [
|
|
CatalogCandidate(
|
|
upstream_id="oidc",
|
|
latest="2.4.0",
|
|
mechanism="plugin",
|
|
source="upstream",
|
|
catalog_url="https://example.test/oidc",
|
|
)
|
|
]
|
|
result = discover_addon_updates(
|
|
role="web-app-demo",
|
|
catalog="wordpress-org",
|
|
declared=declared,
|
|
candidates=candidates,
|
|
)
|
|
self.assertEqual(result.version_updates, [])
|
|
|
|
def test_new_addon_discovered(self):
|
|
declared = [_entry("oidc", version="2.3.1")]
|
|
candidates = [
|
|
CatalogCandidate(
|
|
upstream_id="oidc",
|
|
latest="2.3.1",
|
|
mechanism="plugin",
|
|
source="upstream",
|
|
catalog_url="https://example.test/oidc",
|
|
),
|
|
CatalogCandidate(
|
|
upstream_id="wp-discourse",
|
|
latest="2.5.0",
|
|
mechanism="plugin",
|
|
source="upstream",
|
|
catalog_url="https://example.test/wp-discourse",
|
|
reason="curated: bridges web-app-discourse",
|
|
),
|
|
]
|
|
result = discover_addon_updates(
|
|
role="web-app-demo",
|
|
catalog="wordpress-org",
|
|
declared=declared,
|
|
candidates=candidates,
|
|
)
|
|
self.assertEqual(len(result.new_addons), 1)
|
|
self.assertEqual(result.new_addons[0].addon_id, "wp-discourse")
|
|
self.assertEqual(result.version_updates, [])
|
|
|
|
def test_irrelevant_marketplace_entry_ignored(self):
|
|
declared = [_entry("oidc", version="2.3.1")]
|
|
candidates = [
|
|
CatalogCandidate(
|
|
upstream_id="some-random-marketplace-plugin",
|
|
latest="9.9.9",
|
|
mechanism="plugin",
|
|
source="upstream",
|
|
catalog_url="https://example.test/random",
|
|
relevant=False,
|
|
reason="not in curated relevance set",
|
|
)
|
|
]
|
|
result = discover_addon_updates(
|
|
role="web-app-demo",
|
|
catalog="wordpress-org",
|
|
declared=declared,
|
|
candidates=candidates,
|
|
)
|
|
self.assertEqual(result.new_addons, [])
|
|
self.assertEqual(result.version_updates, [])
|
|
|
|
def test_upstream_id_override_matches_declared(self):
|
|
declared = [_entry("oidc", version="2.3.1", upstream_id="pretix-oidc")]
|
|
candidates = [
|
|
CatalogCandidate(
|
|
upstream_id="pretix-oidc",
|
|
latest="2.4.0",
|
|
mechanism="plugin",
|
|
source="built",
|
|
catalog_url="https://example.test/pretix-oidc",
|
|
)
|
|
]
|
|
result = discover_addon_updates(
|
|
role="web-app-demo",
|
|
catalog="odoo-apps",
|
|
declared=declared,
|
|
candidates=candidates,
|
|
)
|
|
self.assertEqual(len(result.version_updates), 1)
|
|
self.assertEqual(result.version_updates[0].addon_id, "oidc")
|
|
|
|
|
|
class TestCollectAddonEntries(unittest.TestCase):
|
|
def test_collects_and_skips_malformed(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
addons = Path(tmp) / "roles" / "web-app-demo" / ROLE_DIR_META_ADDONS
|
|
addons.mkdir(parents=True)
|
|
(addons / "good.yml").write_text(
|
|
textwrap.dedent(
|
|
"""
|
|
---
|
|
mechanism: plugin
|
|
source: upstream
|
|
version: "1.0"
|
|
update:
|
|
monitored: true
|
|
catalog: wordpress-org
|
|
"""
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
(addons / "bad.yml").write_text("not a mapping\n", encoding="utf-8")
|
|
entries = collect_addon_entries(Path(tmp) / "roles")
|
|
ids = sorted(e.addon_id for e in entries)
|
|
self.assertEqual(ids, ["good"])
|
|
self.assertTrue(entries[0].monitored)
|
|
self.assertEqual(entries[0].catalog, "wordpress-org")
|
|
self.assertEqual(entries[0].upstream_id, "good")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|