#!/usr/bin/env python3 import shutil import subprocess import sys import tempfile import unittest from pathlib import Path PROJECT_ROOT = Path(__file__).resolve().parents[1] SDK_SRC = PROJECT_ROOT / "packages" / "jwebot-sdk" / "src" KERNEL_SRC = PROJECT_ROOT / "packages" / "jwebot-kernel" / "src" sys.path[:0] = [str(SDK_SRC), str(KERNEL_SRC)] from jwebot_kernel import ( # noqa: E402 ExpectedExtension, HostedExtensionError, HostedExtensionRuntime, SignedExtensionInventory, build_release, install_release, sign_release_record, ) from jwebot_sdk import ExtensionResult, ReplyPlan # noqa: E402 PUBLISHER = "test-publisher" def publisher_key(root: Path): private_key = root / "publisher" result = subprocess.run( [ "/usr/bin/ssh-keygen", "-q", "-t", "ed25519", "-N", "", "-f", str(private_key), ], capture_output=True, check=False, ) if result.returncode != 0: raise RuntimeError("cannot generate test publisher key") allowed_signers = root / "allowed_signers" allowed_signers.write_text( f"{PUBLISHER} " + private_key.with_suffix(".pub").read_text(encoding="utf-8"), encoding="utf-8", ) return private_key, allowed_signers def install_example(base: Path, private_key: Path, allowed_signers: Path): source = base / "source" shutil.copytree(PROJECT_ROOT / "examples" / "hello-command", source) artifact, record_path, _ = build_release(source, base / "dist") signature_path, _ = sign_release_record( record_path, private_key, PUBLISHER, ) state_root = base / "state" release_dir = install_release( artifact, record_path, state_root / "hello-command", signature=signature_path, allowed_signers=allowed_signers, expected_publisher=PUBLISHER, health_check=lambda release: None, ) return state_root, release_dir def expected(author: str = "example"): return ExpectedExtension( plugin_id="hello-command", author=author, commands=("/hello",), service_profiles=(), ) @unittest.skipUnless( Path("/usr/bin/ssh-keygen").is_file(), "/usr/bin/ssh-keygen is unavailable", ) class SignedInventoryTests(unittest.TestCase): def test_signed_inventory_loads_and_freezes_current_release(self): with tempfile.TemporaryDirectory() as directory: base = Path(directory) private_key, allowed_signers = publisher_key(base) state_root, release_dir = install_example( base, private_key, allowed_signers, ) inventory = SignedExtensionInventory.load( state_root, allowed_signers, [expected()], expected_publisher=PUBLISHER, require_all=True, ) self.assertTrue(inventory.catalog.frozen) self.assertEqual( inventory.releases["hello-command"].release_dir, release_dir, ) match = inventory.catalog.resolve_command("/hello world") self.assertEqual(match.plugin_id, "hello-command") self.assertEqual(match.arguments, "world") def test_signed_inventory_rejects_expected_author_mismatch(self): with tempfile.TemporaryDirectory() as directory: base = Path(directory) private_key, allowed_signers = publisher_key(base) state_root, _ = install_example( base, private_key, allowed_signers, ) with self.assertRaisesRegex( HostedExtensionError, "inventory mismatch", ): SignedExtensionInventory.load( state_root, allowed_signers, [expected(author="wrong")], expected_publisher=PUBLISHER, ) def test_signed_inventory_can_require_every_release(self): with tempfile.TemporaryDirectory() as directory: base = Path(directory) _, allowed_signers = publisher_key(base) with self.assertRaisesRegex( HostedExtensionError, "are missing", ): SignedExtensionInventory.load( base / "state", allowed_signers, [expected()], require_all=True, ) def test_hosted_runtime_health_gates_and_invokes_result(self): with tempfile.TemporaryDirectory() as directory: base = Path(directory) private_key, allowed_signers = publisher_key(base) state_root, _ = install_example( base, private_key, allowed_signers, ) inventory = SignedExtensionInventory.load( state_root, allowed_signers, [expected()], expected_publisher=PUBLISHER, require_all=True, ) calls = [] def invoke(request, service_handler): calls.append((dict(request), service_handler)) if request["op"] == "health": return { "status": "ok", "api_version": "1", "plugin_id": "hello-command", "author": "example", "description": "Return a local greeting", "help": ["/hello [name]"], "commands": ["/hello"], "service_profiles": [], } return { "status": "ok", "api_version": "1", "plugin_id": "hello-command", "result": ExtensionResult( reply=ReplyPlan.text("hosted") ).to_mapping(), } runtime = HostedExtensionRuntime( inventory, {"hello-command": invoke}, lambda profile, operation, payload: {}, require_all_healthy=True, ) result = runtime.invoke( "hello-command", "/hello", "world", { "event_id": "event-1", "observed_at": "2026-10-14T10:00:00+08:00", "sender": "Alice", "text": "@JWeBot /hello world", "group_fingerprint": "group-a", "mention_bot": True, }, ) self.assertEqual(result.reply.message, "hosted") self.assertEqual(calls[1][0]["arguments"], "world") def test_unhealthy_host_is_not_active_in_preferred_mode(self): with tempfile.TemporaryDirectory() as directory: base = Path(directory) private_key, allowed_signers = publisher_key(base) state_root, _ = install_example( base, private_key, allowed_signers, ) inventory = SignedExtensionInventory.load( state_root, allowed_signers, [expected()], expected_publisher=PUBLISHER, ) runtime = HostedExtensionRuntime( inventory, {"hello-command": lambda request, service: {"status": "error"}}, lambda profile, operation, payload: {}, ) self.assertFalse(runtime.available("hello-command")) self.assertIn("hello-command", runtime.failures) if __name__ == "__main__": unittest.main()