Skip to content

Commit 1363139

Browse files
committed
CUST-5289 Scope grants query alias normalization to grants resource
Move camelCase-to-snake_case key normalization out of the shared HTTP query builder and into the grants resource so only grants list parameters are transformed. Add grants-specific tests to verify camelCase compatibility and snake_case precedence. Made-with: Cursor
1 parent 9ff6150 commit 1363139

3 files changed

Lines changed: 81 additions & 11 deletions

File tree

nylas/handler/http_client.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,15 @@ def _validate_response(response: Response) -> Tuple[Dict, CaseInsensitiveDict]:
4949

5050
def _build_query_params(base_url: str, query_params: dict = None) -> str:
5151
query_param_parts = []
52-
query_param_key_aliases = {
53-
"sortBy": "sort_by",
54-
"orderBy": "order_by",
55-
"grantStatus": "grant_status",
56-
}
57-
5852
for key, value in query_params.items():
59-
normalized_key = query_param_key_aliases.get(key, key)
6053
if isinstance(value, list):
6154
for item in value:
62-
query_param_parts.append(f"{normalized_key}={quote(str(item))}")
55+
query_param_parts.append(f"{key}={quote(str(item))}")
6356
elif isinstance(value, dict):
6457
for k, v in value.items():
65-
query_param_parts.append(f"{normalized_key}={k}:{quote(str(v))}")
58+
query_param_parts.append(f"{key}={k}:{quote(str(v))}")
6659
else:
67-
query_param_parts.append(f"{normalized_key}={quote(str(value))}")
60+
query_param_parts.append(f"{key}={quote(str(value))}")
6861

6962
query_string = "&".join(query_param_parts)
7063
return f"{base_url}?{query_string}"

nylas/resources/grants.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,28 @@
1313
from nylas.models.response import Response, ListResponse, DeleteResponse
1414

1515

16+
def _normalize_grants_query_params(query_params: ListGrantsQueryParams = None) -> dict:
17+
if not query_params:
18+
return query_params
19+
20+
normalized_query_params = dict(query_params)
21+
key_aliases = {
22+
"sortBy": "sort_by",
23+
"orderBy": "order_by",
24+
"grantStatus": "grant_status",
25+
}
26+
27+
for camel_case_key, snake_case_key in key_aliases.items():
28+
if camel_case_key in normalized_query_params:
29+
if snake_case_key not in normalized_query_params:
30+
normalized_query_params[snake_case_key] = normalized_query_params[
31+
camel_case_key
32+
]
33+
del normalized_query_params[camel_case_key]
34+
35+
return normalized_query_params
36+
37+
1638
class Grants(
1739
ListableApiResource,
1840
FindableApiResource,
@@ -47,7 +69,7 @@ def list(
4769
return super().list(
4870
path="/v3/grants",
4971
response_type=Grant,
50-
query_params=query_params,
72+
query_params=_normalize_grants_query_params(query_params),
5173
overrides=overrides,
5274
)
5375

tests/resources/test_grants.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,61 @@ def test_list_grants(self, http_client_list_response):
6868
"GET", "/v3/grants", None, None, None, overrides=None
6969
)
7070

71+
def test_list_grants_normalizes_camel_case_query_params(
72+
self, http_client_list_response
73+
):
74+
grants = Grants(http_client_list_response)
75+
76+
grants.list(
77+
query_params={
78+
"sortBy": "created_at",
79+
"orderBy": "asc",
80+
"grantStatus": "valid",
81+
"limit": 10,
82+
}
83+
)
84+
85+
http_client_list_response._execute.assert_called_once_with(
86+
"GET",
87+
"/v3/grants",
88+
None,
89+
{
90+
"sort_by": "created_at",
91+
"order_by": "asc",
92+
"grant_status": "valid",
93+
"limit": 10,
94+
},
95+
None,
96+
overrides=None,
97+
)
98+
99+
def test_list_grants_prefers_snake_case_query_params(self, http_client_list_response):
100+
grants = Grants(http_client_list_response)
101+
102+
grants.list(
103+
query_params={
104+
"sortBy": "updated_at",
105+
"sort_by": "created_at",
106+
"orderBy": "desc",
107+
"order_by": "asc",
108+
"grantStatus": "invalid",
109+
"grant_status": "valid",
110+
}
111+
)
112+
113+
http_client_list_response._execute.assert_called_once_with(
114+
"GET",
115+
"/v3/grants",
116+
None,
117+
{
118+
"sort_by": "created_at",
119+
"order_by": "asc",
120+
"grant_status": "valid",
121+
},
122+
None,
123+
overrides=None,
124+
)
125+
71126
def test_find_grant(self, http_client_response):
72127
grants = Grants(http_client_response)
73128

0 commit comments

Comments
 (0)