mirror of
https://github.com/Such-Software/adaptive-multi-protocol-gateway.git
synced 2026-10-17 15:41:41 +02:00
176 lines
6.3 KiB
Python
176 lines
6.3 KiB
Python
import contextlib
|
|
import io
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from ampg.capabilities import IDENTITY_ADAPTERS, INTERACTION_TIERS, PAYMENT_ADAPTERS
|
|
from ampg.cli import main
|
|
from ampg.metadata import (
|
|
IDENTITY_ADAPTERS as METADATA_IDENTITY_ADAPTERS,
|
|
INTERACTION_TIERS as METADATA_INTERACTION_TIERS,
|
|
PAYMENT_ADAPTERS as METADATA_PAYMENT_ADAPTERS,
|
|
)
|
|
from ampg.route_manifest import (
|
|
route_manifest_schema_json,
|
|
validate_route_manifest,
|
|
)
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
class RouteManifestTest(unittest.TestCase):
|
|
def test_example_route_manifest_is_valid(self):
|
|
data = json.loads((ROOT / "examples/route-manifest.json").read_text(encoding="utf-8"))
|
|
|
|
self.assertEqual([], validate_route_manifest(data))
|
|
|
|
def test_route_catalog_generator_matches_example_manifest(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
output = Path(tmp) / "route-manifest.json"
|
|
result = subprocess.run(
|
|
[
|
|
sys.executable,
|
|
"tools/generate_route_manifest.py",
|
|
"examples/route-catalog.json",
|
|
str(output),
|
|
],
|
|
cwd=ROOT,
|
|
check=False,
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
|
|
self.assertEqual("", result.stderr)
|
|
self.assertEqual(0, result.returncode)
|
|
self.assertEqual(
|
|
(ROOT / "examples/route-manifest.json").read_text(encoding="utf-8"),
|
|
output.read_text(encoding="utf-8"),
|
|
)
|
|
|
|
check_result = subprocess.run(
|
|
[
|
|
sys.executable,
|
|
"tools/generate_route_manifest.py",
|
|
"examples/route-catalog.json",
|
|
str(output),
|
|
"--check",
|
|
],
|
|
cwd=ROOT,
|
|
check=False,
|
|
capture_output=True,
|
|
text=True,
|
|
)
|
|
self.assertEqual("", check_result.stderr)
|
|
self.assertEqual(0, check_result.returncode)
|
|
|
|
def test_invalid_route_manifest_reports_all_contract_issues(self):
|
|
issues = validate_route_manifest(
|
|
{
|
|
"schema": "wrong",
|
|
"default_tier": "magic",
|
|
"deny_routes": ["admin/*"],
|
|
"extra": True,
|
|
"routes": [
|
|
{
|
|
"match": "play/*",
|
|
"tier": "paid",
|
|
"identity": "cookie-ish",
|
|
"payments": "coin",
|
|
"realtime": "yes",
|
|
"public_allowed": "no",
|
|
"extra": True,
|
|
},
|
|
[],
|
|
],
|
|
}
|
|
)
|
|
|
|
by_path = {issue.path: issue for issue in issues}
|
|
self.assertEqual("unknown-field", by_path["$.extra"].code)
|
|
self.assertEqual("schema", by_path["$.schema"].code)
|
|
self.assertEqual("enum", by_path["$.default_tier"].code)
|
|
self.assertEqual("pattern", by_path["$.deny_routes[0]"].code)
|
|
self.assertEqual("unknown-field", by_path["$.routes[0].extra"].code)
|
|
self.assertEqual("pattern", by_path["$.routes[0].match"].code)
|
|
self.assertEqual("enum", by_path["$.routes[0].tier"].code)
|
|
self.assertEqual("enum", by_path["$.routes[0].identity"].code)
|
|
self.assertEqual("enum", by_path["$.routes[0].payments"].code)
|
|
self.assertEqual("type", by_path["$.routes[0].realtime"].code)
|
|
self.assertEqual("type", by_path["$.routes[0].public_allowed"].code)
|
|
self.assertEqual("type", by_path["$.routes[1]"].code)
|
|
|
|
def test_route_manifest_validate_cli(self):
|
|
stdout = io.StringIO()
|
|
|
|
with contextlib.redirect_stdout(stdout):
|
|
status = main(["route-manifest", "validate", "examples/route-manifest.json"])
|
|
|
|
self.assertEqual(0, status)
|
|
self.assertIn("schema=ampg.route-manifest.v1 routes=4 status=ok", stdout.getvalue())
|
|
|
|
def test_route_manifest_validate_cli_reports_issues(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
path = Path(tmp) / "routes.json"
|
|
path.write_text(
|
|
json.dumps(
|
|
{
|
|
"schema": "ampg.route-manifest.v1",
|
|
"routes": [{"match": "play/*", "tier": "paid"}],
|
|
}
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
stdout = io.StringIO()
|
|
|
|
with contextlib.redirect_stdout(stdout):
|
|
status = main(["route-manifest", "validate", str(path)])
|
|
|
|
output = stdout.getvalue()
|
|
self.assertEqual(1, status)
|
|
self.assertIn("json_path=$.routes[0].match code=pattern", output)
|
|
self.assertIn("json_path=$.routes[0].tier code=enum", output)
|
|
self.assertIn("status=fail issues=2", output)
|
|
|
|
def test_route_manifest_schema_file_matches_generated_schema(self):
|
|
schema_path = ROOT / "schemas/ampg.route-manifest.v1.schema.json"
|
|
|
|
self.assertEqual(
|
|
route_manifest_schema_json(),
|
|
schema_path.read_text(encoding="utf-8"),
|
|
)
|
|
|
|
def test_route_manifest_schema_cli_can_write_schema(self):
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
path = Path(tmp) / "schema.json"
|
|
stdout = io.StringIO()
|
|
|
|
with contextlib.redirect_stdout(stdout):
|
|
status = main(["route-manifest", "schema", "--output", str(path)])
|
|
|
|
self.assertEqual(0, status)
|
|
self.assertEqual(route_manifest_schema_json(), path.read_text(encoding="utf-8"))
|
|
self.assertIn(f"AMPG_ROUTE_MANIFEST_SCHEMA path={path}", stdout.getvalue())
|
|
|
|
def test_capability_constants_match_generated_metadata(self):
|
|
self.assertEqual(
|
|
tuple(tier.name for tier in METADATA_INTERACTION_TIERS),
|
|
INTERACTION_TIERS,
|
|
)
|
|
self.assertEqual(
|
|
tuple(adapter.name for adapter in METADATA_IDENTITY_ADAPTERS),
|
|
IDENTITY_ADAPTERS,
|
|
)
|
|
self.assertEqual(
|
|
tuple(adapter.name for adapter in METADATA_PAYMENT_ADAPTERS),
|
|
PAYMENT_ADAPTERS,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|