Skip to content

Commit 30e6790

Browse files
Accept mapping extension list response payloads
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 06730da commit 30e6790

2 files changed

Lines changed: 52 additions & 7 deletions

File tree

hyperbrowser/client/managers/extension_utils.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections.abc import Mapping
12
from typing import Any, List
23

34
from hyperbrowser.exceptions import HyperbrowserError
@@ -9,13 +10,19 @@ def _get_type_name(value: Any) -> str:
910

1011

1112
def parse_extension_list_response_data(response_data: Any) -> List[ExtensionResponse]:
12-
if not isinstance(response_data, dict):
13+
if not isinstance(response_data, Mapping):
1314
raise HyperbrowserError(
14-
f"Expected dict response but got {_get_type_name(response_data)}"
15+
f"Expected mapping response but got {_get_type_name(response_data)}"
1516
)
1617
if "extensions" not in response_data:
18+
available_keys = ", ".join(sorted(str(key) for key in response_data.keys()))
19+
if available_keys:
20+
available_keys = f"[{available_keys}]"
21+
else:
22+
available_keys = "[]"
1723
raise HyperbrowserError(
18-
f"Expected 'extensions' key in response but got {response_data.keys()}"
24+
"Expected 'extensions' key in response but got "
25+
f"{available_keys} keys"
1926
)
2027
if not isinstance(response_data["extensions"], list):
2128
raise HyperbrowserError(
@@ -24,13 +31,13 @@ def parse_extension_list_response_data(response_data: Any) -> List[ExtensionResp
2431
)
2532
parsed_extensions: List[ExtensionResponse] = []
2633
for index, extension in enumerate(response_data["extensions"]):
27-
if not isinstance(extension, dict):
34+
if not isinstance(extension, Mapping):
2835
raise HyperbrowserError(
2936
"Expected extension object at index "
3037
f"{index} but got {_get_type_name(extension)}"
3138
)
3239
try:
33-
parsed_extensions.append(ExtensionResponse(**extension))
40+
parsed_extensions.append(ExtensionResponse(**dict(extension)))
3441
except HyperbrowserError:
3542
raise
3643
except Exception as exc:

tests/test_extension_utils.py

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import pytest
2+
from types import MappingProxyType
23

34
from hyperbrowser.client.managers import extension_utils
45
from hyperbrowser.client.managers.extension_utils import (
@@ -26,12 +27,14 @@ def test_parse_extension_list_response_data_parses_extensions():
2627

2728

2829
def test_parse_extension_list_response_data_rejects_non_dict_payload():
29-
with pytest.raises(HyperbrowserError, match="Expected dict response"):
30+
with pytest.raises(HyperbrowserError, match="Expected mapping response"):
3031
parse_extension_list_response_data(["not-a-dict"]) # type: ignore[arg-type]
3132

3233

3334
def test_parse_extension_list_response_data_rejects_missing_extensions_key():
34-
with pytest.raises(HyperbrowserError, match="Expected 'extensions' key"):
35+
with pytest.raises(
36+
HyperbrowserError, match="Expected 'extensions' key in response but got \\[\\] keys"
37+
):
3538
parse_extension_list_response_data({})
3639

3740

@@ -77,3 +80,38 @@ def __init__(self, **kwargs):
7780
parse_extension_list_response_data({"extensions": [{"id": "ext_1"}]})
7881

7982
assert exc_info.value.original_error is None
83+
84+
85+
def test_parse_extension_list_response_data_accepts_mapping_proxy_payload():
86+
extension_mapping = MappingProxyType(
87+
{
88+
"id": "ext_123",
89+
"name": "my-extension",
90+
"createdAt": "2026-01-01T00:00:00Z",
91+
"updatedAt": "2026-01-01T00:00:00Z",
92+
}
93+
)
94+
payload = MappingProxyType({"extensions": [extension_mapping]})
95+
96+
parsed = parse_extension_list_response_data(payload)
97+
98+
assert len(parsed) == 1
99+
assert parsed[0].id == "ext_123"
100+
101+
102+
def test_parse_extension_list_response_data_missing_key_lists_available_keys():
103+
with pytest.raises(
104+
HyperbrowserError,
105+
match=(
106+
"Expected 'extensions' key in response but got "
107+
"\\[createdAt, id, name, updatedAt\\] keys"
108+
),
109+
):
110+
parse_extension_list_response_data(
111+
{
112+
"id": "ext_123",
113+
"name": "my-extension",
114+
"createdAt": "2026-01-01T00:00:00Z",
115+
"updatedAt": "2026-01-01T00:00:00Z",
116+
}
117+
)

0 commit comments

Comments
 (0)