Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion aws_lambda_powertools/utilities/data_classes/alb_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,17 @@ def request_context(self) -> ALBEventRequestContext:

@property
def resolved_query_string_parameters(self) -> dict[str, list[str]]:
params = self.multi_value_query_string_parameters or super().resolved_query_string_parameters
multi_value = self.multi_value_query_string_parameters
single_value = super().resolved_query_string_parameters

if not multi_value:
params = single_value
elif not single_value:
params = multi_value
else:
# Merge both: multi_value takes precedence, single_value fills missing keys
params = {**single_value, **multi_value}

if not self.decode_query_parameters:
return params

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,17 @@ def multi_value_headers(self) -> dict[str, list[str]]:

@property
def resolved_query_string_parameters(self) -> dict[str, list[str]]:
return self.multi_value_query_string_parameters or super().resolved_query_string_parameters
multi_value = self.multi_value_query_string_parameters
single_value = super().resolved_query_string_parameters

if not multi_value:
return single_value

if not single_value:
return multi_value

# Merge both: multi_value takes precedence, single_value fills missing keys
return {**single_value, **multi_value}

@property
def resolved_headers_field(self) -> dict[str, Any]:
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/data_classes/required_dependencies/test_alb_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,17 @@ def test_alb_event_decode_multi_value_query_parameters():
# With decode_query_parameters, the key and value are not decoded
parsed_event.decode_query_parameters = True
assert parsed_event.resolved_query_string_parameters == {expected_key: expected_values}


def test_alb_event_merged_query_string_parameters():
"""When both multiValueQueryStringParameters and queryStringParameters are present,
resolved_query_string_parameters should merge them (GH #7993)."""
raw_event = load_event("albMultiValueQueryStringEvent.json")
raw_event["multiValueQueryStringParameters"] = {"ids": ["1", "2", "3"]}
raw_event["queryStringParameters"] = {"status": "fizzbuzz"}

parsed_event = ALBEvent(raw_event)
resolved = parsed_event.resolved_query_string_parameters

assert resolved["ids"] == ["1", "2", "3"]
assert resolved["status"] == ["fizzbuzz"]
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,53 @@ def test_api_gateway_proxy_v2_iam_event():
assert iam.principal_org_id == iam_raw["principalOrgId"]
assert iam.user_arn == iam_raw["userArn"]
assert iam.user_id == iam_raw["userId"]


def test_api_gateway_proxy_event_merged_query_string_parameters():
"""When both multiValueQueryStringParameters and queryStringParameters are present,
resolved_query_string_parameters should merge them (GH #7993)."""
raw_event = load_event("apiGatewayProxyEvent.json")
raw_event["multiValueQueryStringParameters"] = {"ids": ["1", "2", "3"]}
raw_event["queryStringParameters"] = {"status": "fizzbuzz"}

parsed_event = APIGatewayProxyEvent(raw_event)
resolved = parsed_event.resolved_query_string_parameters

assert resolved["ids"] == ["1", "2", "3"]
assert resolved["status"] == ["fizzbuzz"]


def test_api_gateway_proxy_event_multi_value_takes_precedence():
"""When the same key exists in both, multiValueQueryStringParameters wins."""
raw_event = load_event("apiGatewayProxyEvent.json")
raw_event["multiValueQueryStringParameters"] = {"key": ["a", "b"]}
raw_event["queryStringParameters"] = {"key": "c"}

parsed_event = APIGatewayProxyEvent(raw_event)
resolved = parsed_event.resolved_query_string_parameters

assert resolved["key"] == ["a", "b"]


def test_api_gateway_proxy_event_only_single_value_query_params():
"""When only queryStringParameters is present, it should still work."""
raw_event = load_event("apiGatewayProxyEvent.json")
raw_event["multiValueQueryStringParameters"] = None
raw_event["queryStringParameters"] = {"status": "active"}

parsed_event = APIGatewayProxyEvent(raw_event)
resolved = parsed_event.resolved_query_string_parameters

assert resolved["status"] == ["active"]


def test_api_gateway_proxy_event_only_multi_value_query_params():
"""When only multiValueQueryStringParameters is present, it should still work."""
raw_event = load_event("apiGatewayProxyEvent.json")
raw_event["multiValueQueryStringParameters"] = {"ids": ["1", "2"]}
raw_event["queryStringParameters"] = None

parsed_event = APIGatewayProxyEvent(raw_event)
resolved = parsed_event.resolved_query_string_parameters

assert resolved["ids"] == ["1", "2"]
Loading