From 54c4c808cc73bd4c97269d762231bd2eb5744d77 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Sat, 11 Jul 2026 10:10:49 -0400 Subject: [PATCH] Bootstrap the plugin registry for fresh checkouts in tests The test suite silently depended on the gitignored dev instance/plugins.json to know which plugins to load - green on the dev box, red on any fresh clone (CI caught it). conftest now seeds a registry enabling all bundled plugins when none exists; an existing dev registry is left untouched. Co-Authored-By: Claude Fable 5 --- tests/conftest.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/conftest.py b/tests/conftest.py index 7608ca5..d655520 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,7 +7,11 @@ schema. Switch to savepoint-per-test if test count grows past a few hundred. """ +import json import os +from datetime import datetime, timezone +from pathlib import Path + import pytest from werkzeug.security import generate_password_hash @@ -18,6 +22,34 @@ from shopdb import create_app from shopdb.extensions import db as _db +def _bootstrap_plugin_registry(): + # Fresh clones (CI) have no instance/plugins.json - the registry is + # gitignored dev state - so no plugins would load and every plugin-backed + # test fails. Seed a registry enabling all bundled plugins. An existing + # dev registry is left untouched. + repo = Path(__file__).resolve().parent.parent + state_file = repo / 'instance' / 'plugins.json' + if state_file.exists(): + return + stamp = datetime.now(timezone.utc).replace(tzinfo=None).isoformat() + plugins = {} + for manifest_path in sorted((repo / 'plugins').glob('*/manifest.json')): + manifest = json.loads(manifest_path.read_text()) + plugins[manifest['name']] = { + 'name': manifest['name'], + 'version': manifest.get('version', '1.0.0'), + 'installed_at': stamp, + 'enabled': True, + 'migrations_applied': [], + 'config': {}, + } + state_file.parent.mkdir(parents=True, exist_ok=True) + state_file.write_text(json.dumps({'plugins': plugins}, indent=2)) + + +_bootstrap_plugin_registry() + + @pytest.fixture(scope='session') def app(): """Create the Flask application for the test session."""