From 1d1002cd2a38d6b56b657384a0c5a7f870f9dced Mon Sep 17 00:00:00 2001 From: Aaron Harper Date: Tue, 24 Sep 2024 13:29:43 -0400 Subject: [PATCH] Assert bodies in sync tests (#162) --- tests/test_registration/cases/__init__.py | 8 +-- .../cases/cloud_branch_env.py | 61 ++++++++++++++++++- ..._invalid_sig.py => in_band_invalid_sig.py} | 6 ++ ..._missing_sig.py => in_band_missing_sig.py} | 6 ++ tests/test_registration/cases/out_of_band.py | 46 +++++++++++++- .../cases/server_kind_mismatch.py | 10 +-- 6 files changed, 126 insertions(+), 11 deletions(-) rename tests/test_registration/cases/{in_sync_invalid_sig.py => in_band_invalid_sig.py} (90%) rename tests/test_registration/cases/{in_sync_missing_sig.py => in_band_missing_sig.py} (85%) diff --git a/tests/test_registration/cases/__init__.py b/tests/test_registration/cases/__init__.py index 27e71bd..fe2221b 100644 --- a/tests/test_registration/cases/__init__.py +++ b/tests/test_registration/cases/__init__.py @@ -3,16 +3,16 @@ from . import ( base, cloud_branch_env, - in_sync_invalid_sig, - in_sync_missing_sig, + in_band_invalid_sig, + in_band_missing_sig, out_of_band, server_kind_mismatch, ) _modules = ( cloud_branch_env, - in_sync_invalid_sig, - in_sync_missing_sig, + in_band_invalid_sig, + in_band_missing_sig, out_of_band, server_kind_mismatch, ) diff --git a/tests/test_registration/cases/cloud_branch_env.py b/tests/test_registration/cases/cloud_branch_env.py index 941fe7d..b359ace 100644 --- a/tests/test_registration/cases/cloud_branch_env.py +++ b/tests/test_registration/cases/cloud_branch_env.py @@ -2,7 +2,7 @@ import inngest import inngest.fast_api -from inngest._internal import net, server_lib +from inngest._internal import const, net, server_lib from . import base @@ -70,6 +70,65 @@ def fn( str, ) + assert json.loads(res.body.decode("utf-8")) == { + "app_id": client.app_id, + "env": "my-env", + "framework": framework.value, + "functions": [ + { + "batchEvents": None, + "cancel": None, + "concurrency": None, + "debounce": None, + "id": fn.id, + "idempotency": None, + "name": "foo", + "priority": None, + "rateLimit": None, + "steps": { + "step": { + "id": "step", + "name": "step", + "retries": {"attempts": 0}, + "runtime": { + "type": "http", + "url": f"http://test.local?fnId={fn.id}&stepId=step", + }, + } + }, + "throttle": None, + "triggers": [{"event": "app/foo", "expression": None}], + } + ], + "inspection": { + "schema_version": "2024-05-24", + "api_origin": "https://api.inngest.com/", + "app_id": client.app_id, + "authentication_succeeded": True, + "capabilities": {"in_band_sync": "v1", "trust_probe": "v1"}, + "env": "my-env", + "event_api_origin": "https://inn.gs/", + "event_key_hash": None, + "framework": framework.value, + "function_count": 1, + "has_event_key": False, + "has_signing_key": True, + "has_signing_key_fallback": False, + "mode": "cloud", + "sdk_language": "py", + "sdk_version": const.VERSION, + "serve_origin": None, + "serve_path": None, + "signing_key_fallback_hash": None, + "signing_key_hash": "709e80c88487a2411e1ee4dfb9f22a861492d20c4765150c0c794abd70f8147c", + }, + "platform": None, + "sdk_author": "inngest", + "sdk_language": "py", + "sdk_version": const.VERSION, + "url": "http://test.local", + } + return base.Case( name=_TEST_NAME, run_test=run_test, diff --git a/tests/test_registration/cases/in_sync_invalid_sig.py b/tests/test_registration/cases/in_band_invalid_sig.py similarity index 90% rename from tests/test_registration/cases/in_sync_invalid_sig.py rename to tests/test_registration/cases/in_band_invalid_sig.py index 61fdad9..c41cfad 100644 --- a/tests/test_registration/cases/in_sync_invalid_sig.py +++ b/tests/test_registration/cases/in_band_invalid_sig.py @@ -60,6 +60,12 @@ def fn( assert res.headers["x-inngest-expected-server-kind"] == "cloud" assert "x-inngest-sync-kind" not in res.headers + assert json.loads(res.body.decode("utf-8")) == { + "code": "sig_verification_failed", + "message": "", + "name": "SigVerificationFailedError", + } + return base.Case( name=_TEST_NAME, run_test=run_test, diff --git a/tests/test_registration/cases/in_sync_missing_sig.py b/tests/test_registration/cases/in_band_missing_sig.py similarity index 85% rename from tests/test_registration/cases/in_sync_missing_sig.py rename to tests/test_registration/cases/in_band_missing_sig.py index 078b065..c610a46 100644 --- a/tests/test_registration/cases/in_sync_missing_sig.py +++ b/tests/test_registration/cases/in_band_missing_sig.py @@ -53,6 +53,12 @@ def fn( assert res.headers["x-inngest-expected-server-kind"] == "cloud" assert "x-inngest-sync-kind" not in res.headers + assert json.loads(res.body.decode("utf-8")) == { + "code": "header_missing", + "message": "cannot validate signature in production mode without a x-inngest-signature header", + "name": "HeaderMissingError", + } + return base.Case( name=_TEST_NAME, run_test=run_test, diff --git a/tests/test_registration/cases/out_of_band.py b/tests/test_registration/cases/out_of_band.py index 3d0876b..5de3dbf 100644 --- a/tests/test_registration/cases/out_of_band.py +++ b/tests/test_registration/cases/out_of_band.py @@ -24,9 +24,13 @@ def run_test(self: base.TestCase) -> None: @dataclasses.dataclass class State: + body: typing.Optional[bytes] headers: dict[str, list[str]] - state = State(headers={}) + state = State( + body=None, + headers={}, + ) def on_request( *, @@ -38,6 +42,9 @@ def on_request( for k, v in headers.items(): state.headers[k] = v + if body is not None: + state.body = body + return http_proxy.Response( body=json.dumps({}).encode("utf-8"), headers={}, @@ -68,6 +75,8 @@ def fn( self.serve(client, [fn]) res = self.put(body={}) assert res.status_code == 200 + assert json.loads(res.body.decode("utf-8")) == {} + assert state.headers.get("authorization") is not None assert state.headers.get("x-inngest-env") == ["my-env"] assert state.headers.get("x-inngest-framework") == [framework.value] @@ -75,6 +84,41 @@ def fn( f"inngest-py:v{const.VERSION}" ] + host: str + if framework == server_lib.Framework.FAST_API: + host = "http://testserver" + elif framework == server_lib.Framework.FLASK: + host = "http://localhost" + + assert state.body is not None + assert json.loads(state.body.decode("utf-8")) == { + "appname": client.app_id, + "capabilities": {"in_band_sync": "v1", "trust_probe": "v1"}, + "deploy_type": "ping", + "framework": framework.value, + "functions": [ + { + "id": fn.id, + "name": "foo", + "steps": { + "step": { + "id": "step", + "name": "step", + "retries": {"attempts": 0}, + "runtime": { + "type": "http", + "url": f"{host}/api/inngest?fnId={fn.id}&stepId=step", + }, + } + }, + "triggers": [{"event": "app/foo"}], + } + ], + "sdk": f"py:v{const.VERSION}", + "url": f"{host}/api/inngest", + "v": "0.1", + } + return base.Case( name=_TEST_NAME, run_test=run_test, diff --git a/tests/test_registration/cases/server_kind_mismatch.py b/tests/test_registration/cases/server_kind_mismatch.py index 9b9b817..e4d7d07 100644 --- a/tests/test_registration/cases/server_kind_mismatch.py +++ b/tests/test_registration/cases/server_kind_mismatch.py @@ -40,11 +40,11 @@ async def fn( } res = self.put(body={}, headers=headers) assert res.status_code == 400 - res_body = json.loads(res.body) - assert isinstance(res_body, dict) - assert ( - res_body["code"] == server_lib.ErrorCode.SERVER_KIND_MISMATCH.value - ) + + assert json.loads(res.body.decode("utf-8")) == { + "code": "server_kind_mismatch", + "message": "Sync rejected since it's from a Dev Server but expected Cloud", + } return base.Case( name=_TEST_NAME,