Skip to content

Commit 292c045

Browse files
committed
improv: test parser
1 parent ad00cb0 commit 292c045

File tree

4 files changed

+99
-5
lines changed

4 files changed

+99
-5
lines changed

aws_lambda_powertools/utilities/parser/envelopes/base.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ class BaseEnvelope(ABC):
1414
def _parse_user_dict_schema(user_event: Dict[str, Any], schema: BaseModel) -> Any:
1515
if user_event is None:
1616
return None
17+
1718
try:
1819
logger.debug("parsing user dictionary schema")
1920
return schema(**user_event)
2021
except (ValidationError, TypeError) as e:
21-
logger.exception("Validation exception while extracting user custom schema")
2222
raise SchemaValidationError("Failed to extract custom schema") from e
2323

2424
@staticmethod
@@ -41,8 +41,8 @@ def parse(self, event: Dict[str, Any], schema: BaseModel):
4141

4242

4343
def parse_envelope(event: Dict[str, Any], envelope: BaseEnvelope, schema: BaseModel):
44-
if not callable(envelope) and not isinstance(BaseEnvelope):
44+
try:
45+
logger.debug(f"Parsing and validating event schema, envelope={envelope}")
46+
return envelope().parse(event=event, schema=schema)
47+
except (TypeError, AttributeError):
4548
raise InvalidEnvelopeError(f"envelope must be a callable and instance of BaseEnvelope, envelope={envelope}")
46-
47-
logger.debug(f"Parsing and validating event schema, envelope={envelope}")
48-
return envelope().parse(event=event, schema=schema)

tests/functional/parser/conftest.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from typing import Any, Dict
2+
3+
import pytest
4+
from pydantic import BaseModel, ValidationError
5+
6+
from aws_lambda_powertools.utilities.parser.envelopes.base import BaseEnvelope
7+
from aws_lambda_powertools.utilities.parser.exceptions import SchemaValidationError
8+
9+
10+
@pytest.fixture
11+
def dummy_event():
12+
return {"payload": {"message": "hello world"}}
13+
14+
15+
@pytest.fixture
16+
def dummy_schema():
17+
"""Wanted payload structure"""
18+
19+
class MyDummyModel(BaseModel):
20+
message: str
21+
22+
return MyDummyModel
23+
24+
25+
@pytest.fixture
26+
def dummy_envelope_schema():
27+
"""Event wrapper structure"""
28+
29+
class MyDummyEnvelopeSchema(BaseModel):
30+
payload: Dict
31+
32+
return MyDummyEnvelopeSchema
33+
34+
35+
@pytest.fixture
36+
def dummy_envelope(dummy_envelope_schema):
37+
class MyDummyEnvelope(BaseEnvelope):
38+
"""Unwrap dummy event within payload key"""
39+
40+
def parse(self, event: Dict[str, Any], schema: BaseModel):
41+
try:
42+
parsed_enveloped = dummy_envelope_schema(**event)
43+
except (ValidationError, TypeError) as e:
44+
raise SchemaValidationError("Dummy input doesn't conform with schema") from e
45+
return self._parse_user_dict_schema(user_event=parsed_enveloped.payload, schema=schema)
46+
47+
return MyDummyEnvelope

tests/functional/parser/test_eventbridge.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,8 @@ def test_validate_event_does_not_conform_with_user_dict_schema():
5454
def test_handle_eventbridge_trigger_event_no_envelope():
5555
event_dict = load_event("eventBridgeEvent.json")
5656
handle_eventbridge_no_envelope(event_dict, LambdaContext())
57+
58+
59+
def test_handle_invalid_event_with_eventbridge_envelope():
60+
with pytest.raises(exceptions.SchemaValidationError):
61+
handle_eventbridge(event={}, context=LambdaContext())
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from typing import Dict
2+
3+
import pytest
4+
5+
from aws_lambda_powertools.utilities.parser import exceptions, parser
6+
from aws_lambda_powertools.utilities.typing import LambdaContext
7+
8+
9+
@pytest.mark.parametrize("invalid_value", [None, bool(), [], (), object])
10+
def test_parser_unsupported_event(dummy_schema, invalid_value):
11+
@parser(schema=dummy_schema)
12+
def handle_no_envelope(event: Dict, _: LambdaContext):
13+
return event
14+
15+
with pytest.raises(TypeError):
16+
handle_no_envelope(event=invalid_value, context=LambdaContext())
17+
18+
19+
@pytest.mark.parametrize("invalid_envelope", [bool(), [], (), object])
20+
def test_parser_invalid_envelope_type(dummy_schema, invalid_envelope):
21+
@parser(schema=dummy_schema, envelope=invalid_envelope)
22+
def handle_no_envelope(event: Dict, _: LambdaContext):
23+
return event
24+
25+
with pytest.raises(exceptions.InvalidEnvelopeError):
26+
handle_no_envelope(event={}, context=LambdaContext())
27+
28+
29+
def test_parser_schema_with_envelope(dummy_event, dummy_schema, dummy_envelope):
30+
@parser(schema=dummy_schema, envelope=dummy_envelope)
31+
def handle_no_envelope(event: Dict, _: LambdaContext):
32+
return event
33+
34+
handle_no_envelope(dummy_event, LambdaContext())
35+
36+
37+
def test_parser_schema_no_envelope(dummy_event, dummy_schema):
38+
@parser(schema=dummy_schema)
39+
def handle_no_envelope(event: Dict, _: LambdaContext):
40+
return event
41+
42+
handle_no_envelope(dummy_event["payload"], LambdaContext())

0 commit comments

Comments
 (0)