diff --git a/README.md b/README.md index f8ee7d5..d265e2e 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ async def main(): # Get all transactions response = await client.transactions.get_transactions() - print("Transactions:", response["transactions"]) + print("Transactions:", response["report"]["transactions"]) # Run the async function diff --git a/extend/resources/resource.py b/extend/resources/resource.py index a9e3615..7efd8a8 100644 --- a/extend/resources/resource.py +++ b/extend/resources/resource.py @@ -23,26 +23,28 @@ async def _request( params: Optional[Dict] = None, data: Optional[Dict[str, Any]] = None, files: Optional[Dict[str, Any]] = None, + base_url_override: Optional[str] = None, ) -> Any: if params is not None: params = {k: v for k, v in params.items() if v is not None} match method: case "get": - return await self._api_client.get(self.build_full_path(path), params) + return await self._api_client.get(self.build_full_path(path, base_url_override), params) case "post": - return await self._api_client.post(self.build_full_path(path), params) + return await self._api_client.post(self.build_full_path(path, base_url_override), params) case "put": - return await self._api_client.put(self.build_full_path(path), params) + return await self._api_client.put(self.build_full_path(path, base_url_override), params) case "patch": - return await self._api_client.patch(self.build_full_path(path), params) + return await self._api_client.patch(self.build_full_path(path, base_url_override), params) case "post_multipart": return await self._api_client.post_multipart( - self.build_full_path(path), + self.build_full_path(path, base_url_override), data=data, files=files ) case _: raise ValueError(f"Unsupported HTTP method: {method}") - def build_full_path(self, path): - return f"{self._base_url}{path or ''}" + def build_full_path(self, path, base_url_override): + base = base_url_override if base_url_override is not None else self._base_url + return f"{base}{path or ''}" diff --git a/extend/resources/transactions.py b/extend/resources/transactions.py index 5a9a8fd..ef7c702 100644 --- a/extend/resources/transactions.py +++ b/extend/resources/transactions.py @@ -71,7 +71,7 @@ async def get_transactions( "sort": sort_field, } - return await self._request(method="get", params=params) + return await self._request(method="get", params=params, base_url_override='/reports/transactions/v2') async def get_transaction(self, transaction_id: str) -> Dict: """Get detailed information about a specific transaction. diff --git a/tests/test_client.py b/tests/test_client.py index 3cfcd14..4fdc89f 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -250,13 +250,13 @@ async def test_cancel_and_close_virtual_card(extend, mocker, mock_virtual_card): @pytest.mark.asyncio async def test_get_transactions(extend, mocker, mock_transaction): mock_response: Any = { - "transactions": [mock_transaction, mock_transaction] + "report": {"transactions": [mock_transaction, mock_transaction]} } mocker.patch.object(extend._api_client, 'get', return_value=mock_response) response = await extend.transactions.get_transactions() - assert len(response["transactions"]) == 2 + assert len(response["report"]["transactions"]) == 2 # Additional recurrence validation tests diff --git a/tests/test_integration.py b/tests/test_integration.py index fe486f3..d7cd357 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -184,12 +184,13 @@ async def test_list_transactions(self, extend): # Verify response structure assert isinstance(response, dict), "Response should be a dictionary" - assert "transactions" in response, "Response should contain 'transactions' key" - assert isinstance(response["transactions"], list), "Transactions should be a list" + assert "transactions" in response["report"], "Response should contain 'report' key" + assert isinstance(response["report"]["transactions"], list), "Transactions should be a list" # If there are transactions, verify their structure - if response["transactions"]: - transaction = response["transactions"][0] + if response["report"] and response["report"]['transactions']: + transactions = response["report"]['transactions'] + transaction = transactions[0] required_fields = ["id", "status", "virtualCardId", "merchantName", "type", "authBillingAmountCents"] for field in required_fields: assert field in transaction, f"Transaction should contain '{field}' field" @@ -216,10 +217,11 @@ async def test_list_transactions_with_sorting(self, extend): # Verify response contains transactions and basic structure assert isinstance(response, dict), f"Response for sort {sort_field} should be a dictionary" - assert "transactions" in response, f"Response for sort {sort_field} should contain 'transactions' key" + assert "report" in response, f"Response for sort {sort_field} should contain 'report' key" + assert "transactions" in response["report"], f"Report should contain 'transactions' key" # If we have enough data, test opposite sort direction for comparison - if len(response["transactions"]) > 1: + if len(response["report"]["transactions"]) > 1: # Determine the field name and opposite sort field is_desc = sort_field.startswith("-") field_name = sort_field[1:] if is_desc else sort_field @@ -232,8 +234,8 @@ async def test_list_transactions_with_sorting(self, extend): ) # Get IDs in both sort orders for comparison - sorted_ids = [tx["id"] for tx in response["transactions"]] - opposite_sorted_ids = [tx["id"] for tx in opposite_response["transactions"]] + sorted_ids = [tx["id"] for tx in response["report"]["transactions"]] + opposite_sorted_ids = [tx["id"] for tx in opposite_response["report"]["transactions"]] # If we have the same set of transactions in both responses, # verify that different sort directions produce different orders @@ -469,8 +471,9 @@ async def test_create_receipt_attachment(self, extend): # Retrieve a valid transaction id from existing transactions transactions_response = await extend.transactions.get_transactions(page=0, per_page=1) - assert transactions_response.get("transactions"), "No transactions available for testing receipt attachment" - transaction_id = transactions_response["transactions"][0]["id"] + assert transactions_response["report"][ + "transactions"], "No transactions available for testing receipt attachment" + transaction_id = transactions_response["report"]["transactions"][0]["id"] # Call the receipt attachment upload method response = await extend.receipt_attachments.create_receipt_attachment(