"""Run test scripts after a response is received.""" import json from app.models import HttpResponse, TestResult class TestContext: """Exposes pm.test(), pm.expect(), pm.response in test scripts.""" def __init__(self, response: HttpResponse): self.results: list[TestResult] = [] self.response = _ResponseProxy(response) self.expect = _expect def test(self, name: str, fn): try: fn() self.results.append(TestResult(name=name, passed=True)) except AssertionError as e: self.results.append(TestResult(name=name, passed=False, message=str(e))) except Exception as e: self.results.append(TestResult(name=name, passed=False, message=f"Error: {e}")) class _ResponseProxy: def __init__(self, resp: HttpResponse): self._resp = resp self.status = resp.status self.responseTime = resp.elapsed_ms self.text = resp.body try: self._json = json.loads(resp.body) except Exception: self._json = None def json(self): return self._json def to_have_status(self, code: int): assert self._resp.status == code, f"Expected status {code}, got {self._resp.status}" class _Assertion: def __init__(self, value): self._value = value def to_equal(self, expected): assert self._value == expected, f"Expected {expected!r}, got {self._value!r}" return self def to_be_truthy(self): assert self._value, f"Expected truthy, got {self._value!r}" return self def to_include(self, substr): assert substr in str(self._value), f"Expected {substr!r} in {self._value!r}" return self def to_be_below(self, n): assert self._value < n, f"Expected {self._value} < {n}" return self def to_have_property(self, key): assert hasattr(self._value, key) or (isinstance(self._value, dict) and key in self._value), \ f"Expected property {key!r}" return self def _expect(value) -> _Assertion: return _Assertion(value) def run_tests(script: str, response: HttpResponse) -> list[TestResult]: if not script or not script.strip(): return [] ctx = TestContext(response) namespace = { "pm": ctx, "response": ctx.response, "expect": _expect, } try: exec(script, namespace) except Exception as e: ctx.results.append(TestResult(name="Script Error", passed=False, message=str(e))) return ctx.results