Skip to content

Commit fe42bc8

Browse files
Share extension list response parsing across managers
Co-authored-by: Shri Sukhani <shrisukhani@users.noreply.github.com>
1 parent 8494946 commit fe42bc8

File tree

4 files changed

+61
-30
lines changed

4 files changed

+61
-30
lines changed

hyperbrowser/client/managers/async_manager/extension.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from hyperbrowser.exceptions import HyperbrowserError
44
from ...file_utils import ensure_existing_file_path
5+
from ..extension_utils import parse_extension_list_response_data
56
from hyperbrowser.models.extension import CreateExtensionParams, ExtensionResponse
67

78

@@ -38,18 +39,4 @@ async def list(self) -> List[ExtensionResponse]:
3839
response = await self._client.transport.get(
3940
self._client._build_url("/extensions/list"),
4041
)
41-
if not isinstance(response.data, dict):
42-
raise HyperbrowserError(
43-
f"Expected dict response but got {type(response.data)}"
44-
)
45-
if "extensions" not in response.data:
46-
raise HyperbrowserError(
47-
f"Expected 'extensions' key in response but got {response.data.keys()}"
48-
)
49-
if not isinstance(response.data["extensions"], list):
50-
raise HyperbrowserError(
51-
f"Expected list in 'extensions' key but got {type(response.data['extensions'])}"
52-
)
53-
return [
54-
ExtensionResponse(**extension) for extension in response.data["extensions"]
55-
]
42+
return parse_extension_list_response_data(response.data)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from typing import Any, List
2+
3+
from hyperbrowser.exceptions import HyperbrowserError
4+
from hyperbrowser.models.extension import ExtensionResponse
5+
6+
7+
def parse_extension_list_response_data(response_data: Any) -> List[ExtensionResponse]:
8+
if not isinstance(response_data, dict):
9+
raise HyperbrowserError(f"Expected dict response but got {type(response_data)}")
10+
if "extensions" not in response_data:
11+
raise HyperbrowserError(
12+
f"Expected 'extensions' key in response but got {response_data.keys()}"
13+
)
14+
if not isinstance(response_data["extensions"], list):
15+
raise HyperbrowserError(
16+
f"Expected list in 'extensions' key but got {type(response_data['extensions'])}"
17+
)
18+
return [ExtensionResponse(**extension) for extension in response_data["extensions"]]

hyperbrowser/client/managers/sync_manager/extension.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from hyperbrowser.exceptions import HyperbrowserError
44
from ...file_utils import ensure_existing_file_path
5+
from ..extension_utils import parse_extension_list_response_data
56
from hyperbrowser.models.extension import CreateExtensionParams, ExtensionResponse
67

78

@@ -38,18 +39,4 @@ def list(self) -> List[ExtensionResponse]:
3839
response = self._client.transport.get(
3940
self._client._build_url("/extensions/list"),
4041
)
41-
if not isinstance(response.data, dict):
42-
raise HyperbrowserError(
43-
f"Expected dict response but got {type(response.data)}"
44-
)
45-
if "extensions" not in response.data:
46-
raise HyperbrowserError(
47-
f"Expected 'extensions' key in response but got {response.data.keys()}"
48-
)
49-
if not isinstance(response.data["extensions"], list):
50-
raise HyperbrowserError(
51-
f"Expected list in 'extensions' key but got {type(response.data['extensions'])}"
52-
)
53-
return [
54-
ExtensionResponse(**extension) for extension in response.data["extensions"]
55-
]
42+
return parse_extension_list_response_data(response.data)

tests/test_extension_utils.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import pytest
2+
3+
from hyperbrowser.client.managers.extension_utils import (
4+
parse_extension_list_response_data,
5+
)
6+
from hyperbrowser.exceptions import HyperbrowserError
7+
8+
9+
def test_parse_extension_list_response_data_parses_extensions():
10+
parsed = parse_extension_list_response_data(
11+
{
12+
"extensions": [
13+
{
14+
"id": "ext_123",
15+
"name": "my-extension",
16+
"createdAt": "2026-01-01T00:00:00Z",
17+
"updatedAt": "2026-01-01T00:00:00Z",
18+
}
19+
]
20+
}
21+
)
22+
23+
assert len(parsed) == 1
24+
assert parsed[0].id == "ext_123"
25+
26+
27+
def test_parse_extension_list_response_data_rejects_non_dict_payload():
28+
with pytest.raises(HyperbrowserError, match="Expected dict response"):
29+
parse_extension_list_response_data(["not-a-dict"]) # type: ignore[arg-type]
30+
31+
32+
def test_parse_extension_list_response_data_rejects_missing_extensions_key():
33+
with pytest.raises(HyperbrowserError, match="Expected 'extensions' key"):
34+
parse_extension_list_response_data({})
35+
36+
37+
def test_parse_extension_list_response_data_rejects_non_list_extensions():
38+
with pytest.raises(HyperbrowserError, match="Expected list in 'extensions' key"):
39+
parse_extension_list_response_data({"extensions": "not-a-list"})

0 commit comments

Comments
 (0)