|
14 | 14 | TooManyRequestsError, |
15 | 15 | ) |
16 | 16 | from creatorsapi_python_sdk.models.condition import Condition |
| 17 | +from creatorsapi_python_sdk.models.get_browse_nodes_resource import ( |
| 18 | + GetBrowseNodesResource, |
| 19 | +) |
| 20 | +from creatorsapi_python_sdk.models.get_items_resource import GetItemsResource |
| 21 | +from creatorsapi_python_sdk.models.get_variations_resource import GetVariationsResource |
| 22 | +from creatorsapi_python_sdk.models.search_items_resource import SearchItemsResource |
17 | 23 | from creatorsapi_python_sdk.models.sort_by import SortBy |
18 | 24 |
|
19 | 25 |
|
@@ -120,6 +126,22 @@ async def test_context_manager_creates_and_closes_client( |
120 | 126 |
|
121 | 127 | mock_client.__aexit__.assert_called_once() |
122 | 128 |
|
| 129 | + @patch("amazon_creatorsapi.aio.api.AsyncOAuth2TokenManager") |
| 130 | + async def test_context_manager_exit_without_client( |
| 131 | + self, |
| 132 | + mock_token_manager: MagicMock, |
| 133 | + ) -> None: |
| 134 | + """Test __aexit__ works explicitly when no client initialized.""" |
| 135 | + api = AsyncAmazonCreatorsApi( |
| 136 | + credential_id="test_id", |
| 137 | + credential_secret="test_secret", |
| 138 | + version="2.2", |
| 139 | + tag="test-tag", |
| 140 | + country="ES", |
| 141 | + ) |
| 142 | + # Should not raise |
| 143 | + await api.__aexit__(None, None, None) |
| 144 | + |
123 | 145 |
|
124 | 146 | class TestAsyncAmazonCreatorsApiGetItems(unittest.IsolatedAsyncioTestCase): |
125 | 147 | """Tests for get_items() method.""" |
@@ -166,6 +188,45 @@ async def test_get_items_success( |
166 | 188 |
|
167 | 189 | self.assertEqual(len(items), 1) |
168 | 190 |
|
| 191 | + @patch("amazon_creatorsapi.aio.api.AsyncOAuth2TokenManager") |
| 192 | + @patch("amazon_creatorsapi.aio.api.AsyncHttpClient") |
| 193 | + async def test_get_items_with_resources( |
| 194 | + self, |
| 195 | + mock_http_client_class: MagicMock, |
| 196 | + mock_token_manager_class: MagicMock, |
| 197 | + ) -> None: |
| 198 | + """Test get_items with explicit resources.""" |
| 199 | + mock_response = MagicMock() |
| 200 | + mock_response.status_code = 200 |
| 201 | + mock_response.json.return_value = { |
| 202 | + "itemsResult": {"items": [{"ASIN": "B0DLFMFBJW"}]} |
| 203 | + } |
| 204 | + |
| 205 | + mock_client = AsyncMock() |
| 206 | + mock_client.post.return_value = mock_response |
| 207 | + mock_client.__aenter__.return_value = mock_client |
| 208 | + mock_http_client_class.return_value = mock_client |
| 209 | + |
| 210 | + mock_token_manager = AsyncMock() |
| 211 | + mock_token_manager.get_token.return_value = "test_token" |
| 212 | + mock_token_manager_class.return_value = mock_token_manager |
| 213 | + |
| 214 | + async with AsyncAmazonCreatorsApi( |
| 215 | + credential_id="test_id", |
| 216 | + credential_secret="test_secret", |
| 217 | + version="2.2", |
| 218 | + tag="test-tag", |
| 219 | + country="ES", |
| 220 | + ) as api: |
| 221 | + items = await api.get_items( |
| 222 | + ["B0DLFMFBJW"], resources=[GetItemsResource.ITEM_INFO_DOT_TITLE] |
| 223 | + ) |
| 224 | + |
| 225 | + self.assertEqual(len(items), 1) |
| 226 | + # Verify resources were passed |
| 227 | + call_args = mock_client.post.call_args |
| 228 | + self.assertIn("'resources': ['itemInfo.title']", str(call_args)) |
| 229 | + |
169 | 230 | @patch("amazon_creatorsapi.aio.api.AsyncOAuth2TokenManager") |
170 | 231 | @patch("amazon_creatorsapi.aio.api.AsyncHttpClient") |
171 | 232 | async def test_get_items_not_found( |
@@ -280,6 +341,72 @@ async def test_search_items_success( |
280 | 341 |
|
281 | 342 | self.assertIsNotNone(result) |
282 | 343 |
|
| 344 | + @patch("amazon_creatorsapi.aio.api.AsyncOAuth2TokenManager") |
| 345 | + @patch("amazon_creatorsapi.aio.api.AsyncHttpClient") |
| 346 | + async def test_search_items_with_resources( |
| 347 | + self, |
| 348 | + mock_http_client_class: MagicMock, |
| 349 | + mock_token_manager_class: MagicMock, |
| 350 | + ) -> None: |
| 351 | + """Test search_items with explicit resources.""" |
| 352 | + mock_response = MagicMock() |
| 353 | + mock_response.status_code = 200 |
| 354 | + mock_response.json.return_value = { |
| 355 | + "searchResult": {"items": [{"ASIN": "B0DLFMFBJY"}]} |
| 356 | + } |
| 357 | + mock_client = AsyncMock() |
| 358 | + mock_client.post.return_value = mock_response |
| 359 | + mock_client.__aenter__.return_value = mock_client |
| 360 | + mock_http_client_class.return_value = mock_client |
| 361 | + mock_token_manager = AsyncMock() |
| 362 | + mock_token_manager.get_token.return_value = "test_token" |
| 363 | + mock_token_manager_class.return_value = mock_token_manager |
| 364 | + |
| 365 | + async with AsyncAmazonCreatorsApi( |
| 366 | + credential_id="test_id", |
| 367 | + credential_secret="test_secret", |
| 368 | + version="2.2", |
| 369 | + tag="test-tag", |
| 370 | + country="ES", |
| 371 | + ) as api: |
| 372 | + await api.search_items( |
| 373 | + keywords="test", resources=[SearchItemsResource.ITEM_INFO_DOT_TITLE] |
| 374 | + ) |
| 375 | + |
| 376 | + @patch("amazon_creatorsapi.aio.api.AsyncOAuth2TokenManager") |
| 377 | + @patch("amazon_creatorsapi.aio.api.AsyncHttpClient") |
| 378 | + async def test_search_items_without_keywords( |
| 379 | + self, |
| 380 | + mock_http_client_class: MagicMock, |
| 381 | + mock_token_manager_class: MagicMock, |
| 382 | + ) -> None: |
| 383 | + """Test search_items without keywords (using other params).""" |
| 384 | + mock_response = MagicMock() |
| 385 | + mock_response.status_code = 200 |
| 386 | + mock_response.json.return_value = { |
| 387 | + "searchResult": {"items": [{"ASIN": "B0DLFMFBJY"}]} |
| 388 | + } |
| 389 | + mock_client = AsyncMock() |
| 390 | + mock_client.post.return_value = mock_response |
| 391 | + mock_client.__aenter__.return_value = mock_client |
| 392 | + mock_http_client_class.return_value = mock_client |
| 393 | + mock_token_manager = AsyncMock() |
| 394 | + mock_token_manager.get_token.return_value = "test_token" |
| 395 | + mock_token_manager_class.return_value = mock_token_manager |
| 396 | + |
| 397 | + async with AsyncAmazonCreatorsApi( |
| 398 | + credential_id="test_id", |
| 399 | + credential_secret="test_secret", |
| 400 | + version="2.2", |
| 401 | + tag="test-tag", |
| 402 | + country="ES", |
| 403 | + ) as api: |
| 404 | + await api.search_items(browse_node_id="123456") |
| 405 | + |
| 406 | + call_args = mock_client.post.call_args |
| 407 | + self.assertNotIn("keywords", str(call_args)) |
| 408 | + self.assertIn("browseNodeId", str(call_args)) |
| 409 | + |
283 | 410 |
|
284 | 411 | class TestAsyncAmazonCreatorsApiErrorHandling(unittest.IsolatedAsyncioTestCase): |
285 | 412 | """Tests for error handling.""" |
@@ -467,6 +594,38 @@ async def test_get_variations_success( |
467 | 594 |
|
468 | 595 | self.assertIsNotNone(result) |
469 | 596 |
|
| 597 | + @patch("amazon_creatorsapi.aio.api.AsyncOAuth2TokenManager") |
| 598 | + @patch("amazon_creatorsapi.aio.api.AsyncHttpClient") |
| 599 | + async def test_get_variations_with_resources( |
| 600 | + self, |
| 601 | + mock_http_client_class: MagicMock, |
| 602 | + mock_token_manager_class: MagicMock, |
| 603 | + ) -> None: |
| 604 | + """Test get_variations with explicit resources.""" |
| 605 | + mock_response = MagicMock() |
| 606 | + mock_response.status_code = 200 |
| 607 | + mock_response.json.return_value = { |
| 608 | + "variationsResult": {"items": [{"ASIN": "B0DLFMFBJV"}]} |
| 609 | + } |
| 610 | + mock_client = AsyncMock() |
| 611 | + mock_client.post.return_value = mock_response |
| 612 | + mock_client.__aenter__.return_value = mock_client |
| 613 | + mock_http_client_class.return_value = mock_client |
| 614 | + mock_token_manager = AsyncMock() |
| 615 | + mock_token_manager.get_token.return_value = "test_token" |
| 616 | + mock_token_manager_class.return_value = mock_token_manager |
| 617 | + |
| 618 | + async with AsyncAmazonCreatorsApi( |
| 619 | + credential_id="test_id", |
| 620 | + credential_secret="test_secret", |
| 621 | + version="2.2", |
| 622 | + tag="test-tag", |
| 623 | + country="ES", |
| 624 | + ) as api: |
| 625 | + await api.get_variations( |
| 626 | + "B0DLFMFBJV", resources=[GetVariationsResource.ITEM_INFO_DOT_TITLE] |
| 627 | + ) |
| 628 | + |
470 | 629 | @patch("amazon_creatorsapi.aio.api.AsyncOAuth2TokenManager") |
471 | 630 | @patch("amazon_creatorsapi.aio.api.AsyncHttpClient") |
472 | 631 | async def test_get_variations_with_params( |
@@ -585,6 +744,40 @@ async def test_get_browse_nodes_success( |
585 | 744 |
|
586 | 745 | self.assertEqual(len(result), 1) |
587 | 746 |
|
| 747 | + @patch("amazon_creatorsapi.aio.api.AsyncOAuth2TokenManager") |
| 748 | + @patch("amazon_creatorsapi.aio.api.AsyncHttpClient") |
| 749 | + async def test_get_browse_nodes_with_resources( |
| 750 | + self, |
| 751 | + mock_http_client_class: MagicMock, |
| 752 | + mock_token_manager_class: MagicMock, |
| 753 | + ) -> None: |
| 754 | + """Test get_browse_nodes with explicit resources.""" |
| 755 | + mock_response = MagicMock() |
| 756 | + mock_response.status_code = 200 |
| 757 | + mock_response.json.return_value = { |
| 758 | + "browseNodesResult": { |
| 759 | + "browseNodes": [{"Id": "123456", "DisplayName": "Electronics"}] |
| 760 | + } |
| 761 | + } |
| 762 | + mock_client = AsyncMock() |
| 763 | + mock_client.post.return_value = mock_response |
| 764 | + mock_client.__aenter__.return_value = mock_client |
| 765 | + mock_http_client_class.return_value = mock_client |
| 766 | + mock_token_manager = AsyncMock() |
| 767 | + mock_token_manager.get_token.return_value = "test_token" |
| 768 | + mock_token_manager_class.return_value = mock_token_manager |
| 769 | + |
| 770 | + async with AsyncAmazonCreatorsApi( |
| 771 | + credential_id="test_id", |
| 772 | + credential_secret="test_secret", |
| 773 | + version="2.2", |
| 774 | + tag="test-tag", |
| 775 | + country="ES", |
| 776 | + ) as api: |
| 777 | + await api.get_browse_nodes( |
| 778 | + ["123456"], resources=[GetBrowseNodesResource.BROWSE_NODES_DOT_ANCESTOR] |
| 779 | + ) |
| 780 | + |
588 | 781 | @patch("amazon_creatorsapi.aio.api.AsyncOAuth2TokenManager") |
589 | 782 | @patch("amazon_creatorsapi.aio.api.AsyncHttpClient") |
590 | 783 | async def test_get_browse_nodes_with_languages( |
|
0 commit comments