Files
leggen/tests/unit/test_api_accounts.py
2025-09-09 19:39:11 +01:00

248 lines
9.2 KiB
Python

"""Tests for accounts API endpoints."""
import pytest
import respx
import httpx
from unittest.mock import patch
@pytest.mark.api
class TestAccountsAPI:
"""Test account-related API endpoints."""
@respx.mock
def test_get_all_accounts_success(
self, api_client, mock_config, mock_auth_token, sample_account_data
):
"""Test successful retrieval of all accounts."""
requisitions_data = {
"results": [{"id": "req-123", "accounts": ["test-account-123"]}]
}
balances_data = {
"balances": [
{
"balanceAmount": {"amount": "100.50", "currency": "EUR"},
"balanceType": "interimAvailable",
"lastChangeDateTime": "2025-09-01T09:30:00Z",
}
]
}
# Mock GoCardless token creation
respx.post("https://bankaccountdata.gocardless.com/api/v2/token/new/").mock(
return_value=httpx.Response(
200, json={"access": "test-token", "refresh": "test-refresh"}
)
)
# Mock GoCardless API calls
respx.get("https://bankaccountdata.gocardless.com/api/v2/requisitions/").mock(
return_value=httpx.Response(200, json=requisitions_data)
)
respx.get(
"https://bankaccountdata.gocardless.com/api/v2/accounts/test-account-123/"
).mock(return_value=httpx.Response(200, json=sample_account_data))
respx.get(
"https://bankaccountdata.gocardless.com/api/v2/accounts/test-account-123/balances/"
).mock(return_value=httpx.Response(200, json=balances_data))
with patch("leggend.config.config", mock_config):
response = api_client.get("/api/v1/accounts")
assert response.status_code == 200
data = response.json()
assert data["success"] is True
assert len(data["data"]) == 1
account = data["data"][0]
assert account["id"] == "test-account-123"
assert account["institution_id"] == "REVOLUT_REVOLT21"
assert len(account["balances"]) == 1
assert account["balances"][0]["amount"] == 100.50
@respx.mock
def test_get_account_details_success(
self, api_client, mock_config, mock_auth_token, sample_account_data
):
"""Test successful retrieval of specific account details."""
balances_data = {
"balances": [
{
"balanceAmount": {"amount": "250.75", "currency": "EUR"},
"balanceType": "interimAvailable",
}
]
}
# Mock GoCardless token creation
respx.post("https://bankaccountdata.gocardless.com/api/v2/token/new/").mock(
return_value=httpx.Response(
200, json={"access": "test-token", "refresh": "test-refresh"}
)
)
# Mock GoCardless API calls
respx.get(
"https://bankaccountdata.gocardless.com/api/v2/accounts/test-account-123/"
).mock(return_value=httpx.Response(200, json=sample_account_data))
respx.get(
"https://bankaccountdata.gocardless.com/api/v2/accounts/test-account-123/balances/"
).mock(return_value=httpx.Response(200, json=balances_data))
with patch("leggend.config.config", mock_config):
response = api_client.get("/api/v1/accounts/test-account-123")
assert response.status_code == 200
data = response.json()
assert data["success"] is True
account = data["data"]
assert account["id"] == "test-account-123"
assert account["iban"] == "LT313250081177977789"
assert len(account["balances"]) == 1
@respx.mock
def test_get_account_balances_success(
self, api_client, mock_config, mock_auth_token
):
"""Test successful retrieval of account balances."""
balances_data = {
"balances": [
{
"balanceAmount": {"amount": "1000.00", "currency": "EUR"},
"balanceType": "interimAvailable",
"lastChangeDateTime": "2025-09-01T10:00:00Z",
},
{
"balanceAmount": {"amount": "950.00", "currency": "EUR"},
"balanceType": "expected",
},
]
}
# Mock GoCardless token creation
respx.post("https://bankaccountdata.gocardless.com/api/v2/token/new/").mock(
return_value=httpx.Response(
200, json={"access": "test-token", "refresh": "test-refresh"}
)
)
# Mock GoCardless API
respx.get(
"https://bankaccountdata.gocardless.com/api/v2/accounts/test-account-123/balances/"
).mock(return_value=httpx.Response(200, json=balances_data))
with patch("leggend.config.config", mock_config):
response = api_client.get("/api/v1/accounts/test-account-123/balances")
assert response.status_code == 200
data = response.json()
assert data["success"] is True
assert len(data["data"]) == 2
assert data["data"][0]["amount"] == 1000.00
assert data["data"][0]["currency"] == "EUR"
assert data["data"][0]["balance_type"] == "interimAvailable"
@respx.mock
def test_get_account_transactions_success(
self,
api_client,
mock_config,
mock_auth_token,
sample_account_data,
sample_transaction_data,
):
"""Test successful retrieval of account transactions."""
# Mock GoCardless token creation
respx.post("https://bankaccountdata.gocardless.com/api/v2/token/new/").mock(
return_value=httpx.Response(
200, json={"access": "test-token", "refresh": "test-refresh"}
)
)
# Mock GoCardless API calls
respx.get(
"https://bankaccountdata.gocardless.com/api/v2/accounts/test-account-123/"
).mock(return_value=httpx.Response(200, json=sample_account_data))
respx.get(
"https://bankaccountdata.gocardless.com/api/v2/accounts/test-account-123/transactions/"
).mock(return_value=httpx.Response(200, json=sample_transaction_data))
with patch("leggend.config.config", mock_config):
response = api_client.get(
"/api/v1/accounts/test-account-123/transactions?summary_only=true"
)
assert response.status_code == 200
data = response.json()
assert data["success"] is True
assert len(data["data"]) == 1
transaction = data["data"][0]
assert transaction["internal_transaction_id"] == "txn-123"
assert transaction["amount"] == -10.50
assert transaction["currency"] == "EUR"
assert transaction["description"] == "Coffee Shop Payment"
@respx.mock
def test_get_account_transactions_full_details(
self,
api_client,
mock_config,
mock_auth_token,
sample_account_data,
sample_transaction_data,
):
"""Test retrieval of full transaction details."""
# Mock GoCardless token creation
respx.post("https://bankaccountdata.gocardless.com/api/v2/token/new/").mock(
return_value=httpx.Response(
200, json={"access": "test-token", "refresh": "test-refresh"}
)
)
# Mock GoCardless API calls
respx.get(
"https://bankaccountdata.gocardless.com/api/v2/accounts/test-account-123/"
).mock(return_value=httpx.Response(200, json=sample_account_data))
respx.get(
"https://bankaccountdata.gocardless.com/api/v2/accounts/test-account-123/transactions/"
).mock(return_value=httpx.Response(200, json=sample_transaction_data))
with patch("leggend.config.config", mock_config):
response = api_client.get(
"/api/v1/accounts/test-account-123/transactions?summary_only=false"
)
assert response.status_code == 200
data = response.json()
assert data["success"] is True
assert len(data["data"]) == 1
transaction = data["data"][0]
assert transaction["internal_transaction_id"] == "txn-123"
assert transaction["institution_id"] == "REVOLUT_REVOLT21"
assert transaction["iban"] == "LT313250081177977789"
assert "raw_transaction" in transaction
def test_get_account_not_found(self, api_client, mock_config, mock_auth_token):
"""Test handling of non-existent account."""
# Mock 404 response from GoCardless
with respx.mock:
# Mock GoCardless token creation
respx.post("https://bankaccountdata.gocardless.com/api/v2/token/new/").mock(
return_value=httpx.Response(
200, json={"access": "test-token", "refresh": "test-refresh"}
)
)
respx.get(
"https://bankaccountdata.gocardless.com/api/v2/accounts/nonexistent/"
).mock(
return_value=httpx.Response(404, json={"detail": "Account not found"})
)
with patch("leggend.config.config", mock_config):
response = api_client.get("/api/v1/accounts/nonexistent")
assert response.status_code == 404