import json from akos.compiler import codegen_python, codegen_ts, codegen_mcp, openapi, probe, scan from tests.conftest import SPEC def _contract(): return openapi.parse(json.dumps(SPEC).replace("{port}", "9"), source_url="http://127.0.0.1:9/openapi.json") def test_openapi_parse_resolves_refs_and_pagination(): c = _contract() ops = {e["operation_id"]: e for e in c["endpoints"]} assert set(ops) == {"listItems", "ratesByYear", "secure"} assert ops["listItems"]["pagination"]["style"] == "page" assert ops["listItems"]["response_schema"]["properties"]["items"]["items"]["properties"]["name"]["type"] == "string" assert c["license"]["name"] == "CC0-1.0" and c["base_url"] == "http://127.0.0.1:9" assert any(v["unit"] == "USD" for v in c["variables"]) def test_generated_python_client_is_valid_and_scans_clean(): c = _contract() src = codegen_python.generate(c, akp_id="mock.data", version=1, contract_hash="a" * 64, credential_env=None) compile(src, "client.py", "exec") res = scan.scan_python(src) assert res["ok"], res["findings"] assert "CREDENTIAL_ENV = None" in src and "BASE_URL = 'http://127.0.0.1:9'" in src assert "rm -rf" in src # injection text is carried as data (escaped string), never executed tests = codegen_python.generate_tests(c, akp_id="mock.data", fixtures={"listItems": {"query": {"page": 1}, "body": "{}"}}) for name, s in tests.items(): compile(s, name, "exec"); assert scan.scan_python(s, name)["ok"] def test_scan_rejects_dangerous_code(): bad = "import subprocess\nsubprocess.run(['ls'])\neval('1')\nimport os\nos.system('x')\nopen('f','w')\n" r = scan.scan_python(bad) assert not r["ok"] and len(r["findings"]) >= 4 def test_ts_and_mcp_generation(): c = _contract() ts = codegen_ts.generate(c, akp_id="mock.data", version=1, contract_hash="b" * 64, credential_env="AKOS_CRED_X") assert "export class Client" in ts and "listItems(" in ts m = codegen_mcp.generate(c, akp_id="mock.data", version=1, opaque=False) assert len(m["tools"]) == 3 and m["tools"][1]["inputSchema"]["required"] == ["year"] def test_probe_inference_marks_inferred(): body = json.dumps([{"meta": 1}, [{"a": 1, "b": "x"}, {"a": 2, "b": None}]]).encode() c = probe.contract_from_probe("https://example.org/v2/data?x=1", "GET", 200, body, "application/json") e = c["endpoints"][0] assert e["inferred"] and e["parameters"][0]["name"] == "x" assert e["response_schema"]["type"] == "array" assert probe.merge({"type": "integer"}, {"type": "number"}) == {"type": "number"}