Skip to content

Commit 94d13ee

Browse files
Abel Milashclaude
andcommitted
Fix remaining async issues found in fresh review
- async_fetchxml_query.py: fix leftover await r.json() -> r.json() - _async_odata.py: add TYPE_CHECKING guard for aiohttp annotation - test helpers: replace AsyncMock with MagicMock for .json/.text on _AsyncResponse-compatible mocks (body already materialized, no await) All 2155 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 138d78f commit 94d13ee

6 files changed

Lines changed: 21 additions & 20 deletions

File tree

src/PowerPlatform/Dataverse/aio/data/_async_odata.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
import time
1313
import warnings
1414
from datetime import datetime, timezone
15-
from typing import Any, AsyncIterator, Dict, List, Optional, Union
15+
from typing import TYPE_CHECKING, Any, AsyncIterator, Dict, List, Optional, Union
16+
17+
if TYPE_CHECKING:
18+
import aiohttp
1619

1720
from urllib.parse import quote as _url_quote
1821

src/PowerPlatform/Dataverse/aio/models/async_fetchxml_query.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ async def execute_pages(self) -> AsyncIterator[QueryResult]:
100100
params={"fetchXml": current_xml},
101101
)
102102
try:
103-
data = await r.json(content_type=None)
103+
data = r.json()
104104
except Exception:
105105
data = {}
106106

tests/unit/aio/core/test_async_http.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ def _make_resp(status: int = 200) -> MagicMock:
1515
resp.status = status
1616
resp.headers = {}
1717
resp.read = AsyncMock(return_value=b"")
18-
resp.text = AsyncMock(return_value="")
1918
return resp
2019

2120

tests/unit/aio/data/test_async_batch_internal.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,13 @@ def _make_batch_client():
133133

134134

135135
def _batch_resp(status=200, text="", json_payload=None):
136-
"""Create a mock response suitable for the batch execute() path."""
136+
"""Create a mock _AsyncResponse-compatible response for the batch execute() path."""
137137
r = MagicMock()
138138
r.status = status
139+
r.status_code = status
139140
r.headers = {"Content-Type": "application/json"}
140-
r.text = AsyncMock(return_value=text)
141-
r.json = AsyncMock(return_value=json_payload or {})
141+
r.text = text
142+
r.json = MagicMock(return_value=json_payload or {})
142143
return r
143144

144145

tests/unit/aio/data/test_async_upload.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,11 @@ def _make_client() -> _AsyncODataClient:
2626

2727

2828
def _resp(status=200, headers=None, json_data=None):
29-
"""Create a mock aiohttp-compatible response."""
29+
"""Create a mock _AsyncResponse-compatible response."""
3030
r = MagicMock()
3131
r.status = status
3232
r.headers = headers or {}
33-
r.text = AsyncMock(return_value="")
34-
r.json = AsyncMock(return_value=json_data or {})
35-
r.read = AsyncMock(return_value=b"")
33+
r.json = MagicMock(return_value=json_data or {})
3634
return r
3735

3836

tests/unit/aio/test_async_query.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ async def test_execute_returns_query_result(self, async_client, mock_od):
148148
mock_od._entity_set_from_schema_name = AsyncMock(return_value="accounts")
149149

150150
resp = MagicMock()
151-
resp.json = AsyncMock(return_value={
151+
resp.json = MagicMock(return_value={
152152
"value": [{"name": "Contoso", "accountid": "g1"}],
153153
"@Microsoft.Dynamics.CRM.morerecords": False,
154154
})
@@ -165,7 +165,7 @@ async def test_execute_pages_yields_pages(self, async_client, mock_od):
165165
mock_od._entity_set_from_schema_name = AsyncMock(return_value="accounts")
166166

167167
resp = MagicMock()
168-
resp.json = AsyncMock(return_value={
168+
resp.json = MagicMock(return_value={
169169
"value": [{"name": "Contoso", "accountid": "g1"}],
170170
"@Microsoft.Dynamics.CRM.morerecords": False,
171171
})
@@ -410,13 +410,13 @@ async def test_execute_multi_page_with_cookie(self, async_client, mock_od):
410410
paging_cookie = f'<cookie pagenumber="2" pagingcookie="{encoded}" istracking="false" />'
411411

412412
page1 = MagicMock()
413-
page1.json = AsyncMock(return_value={
413+
page1.json = MagicMock(return_value={
414414
"value": [{"name": "Contoso", "accountid": "g1"}],
415415
"@Microsoft.Dynamics.CRM.morerecords": True,
416416
"@Microsoft.Dynamics.CRM.fetchxmlpagingcookie": paging_cookie,
417417
})
418418
page2 = MagicMock()
419-
page2.json = AsyncMock(return_value={
419+
page2.json = MagicMock(return_value={
420420
"value": [{"name": "Fabrikam", "accountid": "g2"}],
421421
"@Microsoft.Dynamics.CRM.morerecords": False,
422422
})
@@ -435,13 +435,13 @@ async def test_execute_multi_page_cookie_parse_error_fallback(self, async_client
435435
mock_od._entity_set_from_schema_name = AsyncMock(return_value="accounts")
436436

437437
page1 = MagicMock()
438-
page1.json = AsyncMock(return_value={
438+
page1.json = MagicMock(return_value={
439439
"value": [{"name": "Contoso", "accountid": "g1"}],
440440
"@Microsoft.Dynamics.CRM.morerecords": True,
441441
"@Microsoft.Dynamics.CRM.fetchxmlpagingcookie": "<<<not valid xml>>>",
442442
})
443443
page2 = MagicMock()
444-
page2.json = AsyncMock(return_value={
444+
page2.json = MagicMock(return_value={
445445
"value": [{"name": "Fabrikam", "accountid": "g2"}],
446446
"@Microsoft.Dynamics.CRM.morerecords": False,
447447
})
@@ -461,13 +461,13 @@ async def test_execute_multi_page_no_cookie_simple_paging(self, async_client, mo
461461
mock_od._entity_set_from_schema_name = AsyncMock(return_value="accounts")
462462

463463
page1 = MagicMock()
464-
page1.json = AsyncMock(return_value={
464+
page1.json = MagicMock(return_value={
465465
"value": [{"name": "Contoso", "accountid": "g1"}],
466466
"@Microsoft.Dynamics.CRM.morerecords": True,
467467
# No fetchxmlpagingcookie key
468468
})
469469
page2 = MagicMock()
470-
page2.json = AsyncMock(return_value={
470+
page2.json = MagicMock(return_value={
471471
"value": [{"name": "Fabrikam", "accountid": "g2"}],
472472
"@Microsoft.Dynamics.CRM.morerecords": False,
473473
})
@@ -485,7 +485,7 @@ async def test_execute_json_parse_error_yields_empty_page(self, async_client, mo
485485
mock_od._entity_set_from_schema_name = AsyncMock(return_value="accounts")
486486

487487
resp = MagicMock()
488-
resp.json = AsyncMock(side_effect=Exception("invalid json"))
488+
resp.json = MagicMock(side_effect=Exception("invalid json"))
489489
mock_od._request = AsyncMock(return_value=resp)
490490

491491
result = await async_client.query.fetchxml(_SIMPLE_FETCHXML).execute()
@@ -504,7 +504,7 @@ def _make_page_resp(page_num: int):
504504
encoded = urllib.parse.quote(urllib.parse.quote(inner))
505505
cookie = f'<cookie pagenumber="{page_num + 1}" pagingcookie="{encoded}" istracking="false" />'
506506
resp = MagicMock()
507-
resp.json = AsyncMock(return_value={
507+
resp.json = MagicMock(return_value={
508508
"value": [{"name": f"Record{page_num}", "accountid": f"g{page_num}"}],
509509
"@Microsoft.Dynamics.CRM.morerecords": True,
510510
"@Microsoft.Dynamics.CRM.fetchxmlpagingcookie": cookie,

0 commit comments

Comments
 (0)