From 54774e663ebb1f68c253df5df0dcd67b2fb16d79 Mon Sep 17 00:00:00 2001 From: Raphael Fakhri <153192858+RaphaelFakhri@users.noreply.github.com> Date: Wed, 4 Nov 2026 07:09:06 +0000 Subject: [PATCH 1/2] fix(json-format): reject data and data_base64 together in JSON schema The JSON format spec states that the data and data_base64 members are mutually exclusive, but cloudevents.json accepted an event that has both. Add a not/required constraint so validators reject such events, and add schema tests to the tools test suite. Signed-off-by: Raphael Fakhri <153192858+RaphaelFakhri@users.noreply.github.com> --- cloudevents/formats/cloudevents.json | 4 +++ tools/requirements.txt | 3 +- tools/test_json_schema.py | 46 ++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tools/test_json_schema.py diff --git a/cloudevents/formats/cloudevents.json b/cloudevents/formats/cloudevents.json index b9d555033..289f03e5b 100644 --- a/cloudevents/formats/cloudevents.json +++ b/cloudevents/formats/cloudevents.json @@ -81,6 +81,10 @@ } }, "required": ["id", "source", "specversion", "type"], + "not": { + "description": "The data and data_base64 members are mutually exclusive.", + "required": ["data", "data_base64"] + }, "definitions": { "iddef": { "type": "string", diff --git a/tools/requirements.txt b/tools/requirements.txt index 1f671151c..8a9fe5486 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -4,4 +4,5 @@ tenacity aiohttp tqdm pymdown-extensions -pytest-asyncio \ No newline at end of file +pytest-asyncio +jsonschema \ No newline at end of file diff --git a/tools/test_json_schema.py b/tools/test_json_schema.py new file mode 100644 index 000000000..38e7f42e4 --- /dev/null +++ b/tools/test_json_schema.py @@ -0,0 +1,46 @@ +import json +from pathlib import Path + +import pytest +from jsonschema import Draft7Validator + +_SCHEMA_PATH = ( + Path(__file__).parent.parent / "cloudevents" / "formats" / "cloudevents.json" +) +_REQUIRED_ATTRIBUTES = { + "specversion": "1.0", + "type": "com.example.someevent", + "source": "/mycontext", + "id": "A234-1234-1234", +} + + +@pytest.fixture(scope="module") +def validator(): + schema = json.loads(_SCHEMA_PATH.read_text()) + Draft7Validator.check_schema(schema) + return Draft7Validator(schema) + + +@pytest.mark.parametrize( + "payload", + [ + {}, + {"data": {"key": "value"}}, + {"data": None}, + {"data_base64": "Zm9vYg=="}, + ], +) +def test_valid_event(validator, payload): + assert validator.is_valid({**_REQUIRED_ATTRIBUTES, **payload}) + + +@pytest.mark.parametrize( + "payload", + [ + {"data": {"key": "value"}, "data_base64": "Zm9vYg=="}, + {"data": None, "data_base64": "Zm9vYg=="}, + ], +) +def test_data_and_data_base64_are_mutually_exclusive(validator, payload): + assert not validator.is_valid({**_REQUIRED_ATTRIBUTES, **payload}) From 4087a01e38748cbb8d2e75b942432898091d3873 Mon Sep 17 00:00:00 2001 From: Raphael Fakhri <153192858+RaphaelFakhri@users.noreply.github.com> Date: Fri, 6 Nov 2026 20:31:36 +0000 Subject: [PATCH 2/2] Remove the JSON schema test and its requirement Signed-off-by: Raphael Fakhri <153192858+RaphaelFakhri@users.noreply.github.com> --- tools/requirements.txt | 3 +-- tools/test_json_schema.py | 46 --------------------------------------- 2 files changed, 1 insertion(+), 48 deletions(-) delete mode 100644 tools/test_json_schema.py diff --git a/tools/requirements.txt b/tools/requirements.txt index 8a9fe5486..1f671151c 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -4,5 +4,4 @@ tenacity aiohttp tqdm pymdown-extensions -pytest-asyncio -jsonschema \ No newline at end of file +pytest-asyncio \ No newline at end of file diff --git a/tools/test_json_schema.py b/tools/test_json_schema.py deleted file mode 100644 index 38e7f42e4..000000000 --- a/tools/test_json_schema.py +++ /dev/null @@ -1,46 +0,0 @@ -import json -from pathlib import Path - -import pytest -from jsonschema import Draft7Validator - -_SCHEMA_PATH = ( - Path(__file__).parent.parent / "cloudevents" / "formats" / "cloudevents.json" -) -_REQUIRED_ATTRIBUTES = { - "specversion": "1.0", - "type": "com.example.someevent", - "source": "/mycontext", - "id": "A234-1234-1234", -} - - -@pytest.fixture(scope="module") -def validator(): - schema = json.loads(_SCHEMA_PATH.read_text()) - Draft7Validator.check_schema(schema) - return Draft7Validator(schema) - - -@pytest.mark.parametrize( - "payload", - [ - {}, - {"data": {"key": "value"}}, - {"data": None}, - {"data_base64": "Zm9vYg=="}, - ], -) -def test_valid_event(validator, payload): - assert validator.is_valid({**_REQUIRED_ATTRIBUTES, **payload}) - - -@pytest.mark.parametrize( - "payload", - [ - {"data": {"key": "value"}, "data_base64": "Zm9vYg=="}, - {"data": None, "data_base64": "Zm9vYg=="}, - ], -) -def test_data_and_data_base64_are_mutually_exclusive(validator, payload): - assert not validator.is_valid({**_REQUIRED_ATTRIBUTES, **payload})