Skip to content

Commit 06b07d0

Browse files
authored
from_http bug None and non dict data bug fixes (cloudevents#119)
* resolving from_http bugs Signed-off-by: Curtis Mason <cumason@google.com> * resolved from_http bugs Signed-off-by: Curtis Mason <cumason@google.com> * nit fix Signed-off-by: Curtis Mason <cumason@google.com>
1 parent 14c7618 commit 06b07d0

File tree

4 files changed

+46
-24
lines changed

4 files changed

+46
-24
lines changed

cloudevents/http/event.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ def __init__(
5959

6060
if self._attributes["specversion"] not in _required_by_version:
6161
raise cloud_exceptions.MissingRequiredFields(
62-
f"Invalid specversion: {self._attributes['specversion']}. "
62+
f"Invalid specversion: {self._attributes['specversion']}"
6363
)
6464
# There is no good way to default 'source' and 'type', so this
6565
# checks for those (or any new required attributes).
6666
required_set = _required_by_version[self._attributes["specversion"]]
6767
if not required_set <= self._attributes.keys():
6868
raise cloud_exceptions.MissingRequiredFields(
69-
f"Missing required keys: {required_set - self._attributes.keys()}. "
69+
f"Missing required keys: {required_set - self._attributes.keys()}"
7070
)
7171

7272
def __eq__(self, other):

cloudevents/http/http_methods.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def from_http(
3232
if not isinstance(data, (str, bytes, bytearray)):
3333
raise cloud_exceptions.InvalidStructuredJSON(
3434
"Expected json of type (str, bytes, bytearray), "
35-
f"but instead found {type(data)}. "
35+
f"but instead found type {type(data)}"
3636
)
3737

3838
headers = {key.lower(): value for key, value in headers.items()}
@@ -47,22 +47,28 @@ def from_http(
4747
try:
4848
raw_ce = json.loads(data)
4949
except json.decoder.JSONDecodeError:
50-
raise cloud_exceptions.InvalidStructuredJSON(
51-
"Failed to read fields from structured event. "
52-
f"The following can not be parsed as json: {data}. "
50+
raise cloud_exceptions.MissingRequiredFields(
51+
"Failed to read specversion from both headers and data. "
52+
f"The following can not be parsed as json: {data}"
53+
)
54+
if hasattr(raw_ce, "get"):
55+
specversion = raw_ce.get("specversion", None)
56+
else:
57+
raise cloud_exceptions.MissingRequiredFields(
58+
"Failed to read specversion from both headers and data. "
59+
f"The following deserialized data has no 'get' method: {raw_ce}"
5360
)
54-
specversion = raw_ce.get("specversion", None)
5561

5662
if specversion is None:
5763
raise cloud_exceptions.MissingRequiredFields(
58-
"Failed to find specversion in HTTP request. "
64+
"Failed to find specversion in HTTP request"
5965
)
6066

6167
event_handler = _obj_by_version.get(specversion, None)
6268

6369
if event_handler is None:
6470
raise cloud_exceptions.InvalidRequiredFields(
65-
f"Found invalid specversion {specversion}. "
71+
f"Found invalid specversion {specversion}"
6672
)
6773

6874
event = marshall.FromRequest(
@@ -96,7 +102,7 @@ def _to_http(
96102

97103
if event._attributes["specversion"] not in _obj_by_version:
98104
raise cloud_exceptions.InvalidRequiredFields(
99-
f"Unsupported specversion: {event._attributes['specversion']}. "
105+
f"Unsupported specversion: {event._attributes['specversion']}"
100106
)
101107

102108
event_handler = _obj_by_version[event._attributes["specversion"]]()

cloudevents/tests/test_http_cloudevent.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,19 @@ def test_http_cloudevent_mutates_equality(specversion):
7575
def test_cloudevent_missing_specversion():
7676
attributes = {"specversion": "0.2", "source": "s", "type": "t"}
7777
with pytest.raises(cloud_exceptions.MissingRequiredFields) as e:
78-
event = CloudEvent(attributes, None)
78+
_ = CloudEvent(attributes, None)
7979
assert "Invalid specversion: 0.2" in str(e.value)
8080

8181

8282
def test_cloudevent_missing_minimal_required_fields():
8383
attributes = {"type": "t"}
8484
with pytest.raises(cloud_exceptions.MissingRequiredFields) as e:
85-
event = CloudEvent(attributes, None)
85+
_ = CloudEvent(attributes, None)
8686
assert f"Missing required keys: {set(['source'])}" in str(e.value)
8787

8888
attributes = {"source": "s"}
8989
with pytest.raises(cloud_exceptions.MissingRequiredFields) as e:
90-
event = CloudEvent(attributes, None)
90+
_ = CloudEvent(attributes, None)
9191
assert f"Missing required keys: {set(['type'])}" in str(e.value)
9292

9393

cloudevents/tests/test_http_events.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,8 @@ async def echo(request):
9090

9191
@pytest.mark.parametrize("body", invalid_cloudevent_request_body)
9292
def test_missing_required_fields_structured(body):
93-
with pytest.raises(cloud_exceptions.MissingRequiredFields):
94-
# CloudEvent constructor throws TypeError if missing required field
95-
# and NotImplementedError because structured calls aren't
96-
# implemented. In this instance one of the required keys should have
97-
# prefix e-id instead of ce-id therefore it should throw
93+
with pytest.raises(cloud_exceptions.MissingRequiredFields) as e:
94+
9895
_ = from_http(
9996
{"Content-Type": "application/cloudevents+json"}, json.dumps(body),
10097
)
@@ -103,13 +100,16 @@ def test_missing_required_fields_structured(body):
103100
@pytest.mark.parametrize("headers", invalid_test_headers)
104101
def test_missing_required_fields_binary(headers):
105102
with pytest.raises(cloud_exceptions.MissingRequiredFields):
106-
# CloudEvent constructor throws TypeError if missing required field
107-
# and NotImplementedError because structured calls aren't
108-
# implemented. In this instance one of the required keys should have
109-
# prefix e-id instead of ce-id therefore it should throw
110103
_ = from_http(headers, json.dumps(test_data))
111104

112105

106+
@pytest.mark.parametrize("headers", invalid_test_headers)
107+
def test_missing_required_fields_empty_data_binary(headers):
108+
# Test for issue #115
109+
with pytest.raises(cloud_exceptions.MissingRequiredFields):
110+
_ = from_http(headers, None)
111+
112+
113113
@pytest.mark.parametrize("specversion", ["1.0", "0.3"])
114114
def test_emit_binary_event(specversion):
115115
headers = {
@@ -450,11 +450,13 @@ def test_is_structured():
450450
def test_empty_json_structured():
451451
headers = {"Content-Type": "application/cloudevents+json"}
452452
data = ""
453-
with pytest.raises(cloud_exceptions.InvalidStructuredJSON) as e:
453+
with pytest.raises(cloud_exceptions.MissingRequiredFields) as e:
454454
from_http(
455455
headers, data,
456456
)
457-
assert "Failed to read fields from structured event. " in str(e.value)
457+
assert "Failed to read specversion from both headers and data" in str(
458+
e.value
459+
)
458460

459461

460462
def test_uppercase_headers_with_none_data_binary():
@@ -472,3 +474,17 @@ def test_uppercase_headers_with_none_data_binary():
472474

473475
_, new_data = to_binary(event)
474476
assert new_data == None
477+
478+
479+
def test_non_dict_data_no_headers_bug():
480+
# Test for issue #116
481+
headers = {"Content-Type": "application/cloudevents+json"}
482+
data = "123"
483+
with pytest.raises(cloud_exceptions.MissingRequiredFields) as e:
484+
from_http(
485+
headers, data,
486+
)
487+
assert "Failed to read specversion from both headers and data" in str(
488+
e.value
489+
)
490+
assert "The following deserialized data has no 'get' method" in str(e.value)

0 commit comments

Comments
 (0)