Initial commit from monorepo
This commit is contained in:
179
billing_app/tests.py
Normal file
179
billing_app/tests.py
Normal file
@@ -0,0 +1,179 @@
|
||||
import json
|
||||
from unittest.mock import patch, MagicMock
|
||||
from graphene_django.utils.testing import GraphQLTestCase
|
||||
from .models import Account
|
||||
import uuid
|
||||
|
||||
class BillingGraphQLTests(GraphQLTestCase):
|
||||
GRAPHQL_URL = '/graphql/public/'
|
||||
|
||||
@patch('billing_app.schemas.tigerbeetle_client')
|
||||
def test_create_transfer_new_accounts(self, mock_tb_client):
|
||||
"""
|
||||
Tests that a transfer is created successfully and that new accounts
|
||||
are created lazily in both the local DB and in TigerBeetle.
|
||||
"""
|
||||
# Configure the mock to return no errors
|
||||
mock_tb_client.create_accounts.return_value = []
|
||||
mock_tb_client.create_transfers.return_value = []
|
||||
|
||||
debit_account_id = str(uuid.uuid4())
|
||||
credit_account_id = str(uuid.uuid4())
|
||||
amount = 100
|
||||
ledger = 1
|
||||
code = 200
|
||||
|
||||
# Ensure accounts do not exist locally
|
||||
self.assertEqual(Account.objects.count(), 0)
|
||||
|
||||
response = self.query(
|
||||
'''
|
||||
mutation createTransfer(
|
||||
$debitAccountId: String!,
|
||||
$creditAccountId: String!,
|
||||
$amount: Int!,
|
||||
$ledger: Int!,
|
||||
$code: Int!
|
||||
) {
|
||||
createTransfer(
|
||||
debitAccountId: $debitAccountId,
|
||||
creditAccountId: $creditAccountId,
|
||||
amount: $amount,
|
||||
ledger: $ledger,
|
||||
code: $code
|
||||
) {
|
||||
success
|
||||
message
|
||||
transferId
|
||||
}
|
||||
}
|
||||
''',
|
||||
variables={
|
||||
'debitAccountId': debit_account_id,
|
||||
'creditAccountId': credit_account_id,
|
||||
'amount': amount,
|
||||
'ledger': ledger,
|
||||
'code': code
|
||||
}
|
||||
)
|
||||
|
||||
self.assertResponseNoErrors(response)
|
||||
content = json.loads(response.content)
|
||||
result = content['data']['createTransfer']
|
||||
|
||||
self.assertTrue(result['success'])
|
||||
self.assertIsNotNone(result['transferId'])
|
||||
self.assertEqual(result['message'], 'Transfer completed successfully.')
|
||||
|
||||
# Verify local accounts were created
|
||||
self.assertEqual(Account.objects.count(), 2)
|
||||
self.assertTrue(Account.objects.filter(uuid=debit_account_id).exists())
|
||||
self.assertTrue(Account.objects.filter(uuid=credit_account_id).exists())
|
||||
|
||||
# Verify TigerBeetle client was called correctly
|
||||
mock_tb_client.create_accounts.assert_called_once()
|
||||
self.assertEqual(len(mock_tb_client.create_accounts.call_args[0][0]), 2) # Called with 2 accounts
|
||||
|
||||
mock_tb_client.create_transfers.assert_called_once()
|
||||
self.assertEqual(len(mock_tb_client.create_transfers.call_args[0][0]), 1) # Called with 1 transfer
|
||||
transfer_arg = mock_tb_client.create_transfers.call_args[0][0][0]
|
||||
self.assertEqual(transfer_arg.amount, amount)
|
||||
|
||||
@patch('billing_app.schemas.tigerbeetle_client')
|
||||
def test_create_transfer_existing_accounts(self, mock_tb_client):
|
||||
"""
|
||||
Tests that a transfer is created successfully with existing accounts
|
||||
and that `create_accounts` is not called.
|
||||
"""
|
||||
mock_tb_client.create_transfers.return_value = []
|
||||
|
||||
debit_account_id = uuid.uuid4()
|
||||
credit_account_id = uuid.uuid4()
|
||||
|
||||
# Pre-populate the local database
|
||||
Account.objects.create(uuid=debit_account_id)
|
||||
Account.objects.create(uuid=credit_account_id)
|
||||
|
||||
self.assertEqual(Account.objects.count(), 2)
|
||||
|
||||
response = self.query(
|
||||
'''
|
||||
mutation createTransfer(
|
||||
$debitAccountId: String!,
|
||||
$creditAccountId: String!,
|
||||
$amount: Int!,
|
||||
$ledger: Int!,
|
||||
$code: Int!
|
||||
) {
|
||||
createTransfer(
|
||||
debitAccountId: $debitAccountId,
|
||||
creditAccountId: $creditAccountId,
|
||||
amount: $amount,
|
||||
ledger: $ledger,
|
||||
code: $code
|
||||
) {
|
||||
success
|
||||
message
|
||||
transferId
|
||||
}
|
||||
}
|
||||
''',
|
||||
variables={
|
||||
'debitAccountId': str(debit_account_id),
|
||||
'creditAccountId': str(credit_account_id),
|
||||
'amount': 50,
|
||||
'ledger': 1,
|
||||
'code': 201
|
||||
}
|
||||
)
|
||||
|
||||
self.assertResponseNoErrors(response)
|
||||
|
||||
# Verify that create_accounts was NOT called
|
||||
mock_tb_client.create_accounts.assert_not_called()
|
||||
|
||||
# Verify that create_transfers WAS called
|
||||
mock_tb_client.create_transfers.assert_called_once()
|
||||
|
||||
def test_create_transfer_invalid_uuid(self):
|
||||
"""
|
||||
Tests that the mutation fails gracefully with an invalid UUID.
|
||||
"""
|
||||
response = self.query(
|
||||
'''
|
||||
mutation createTransfer(
|
||||
$debitAccountId: String!,
|
||||
$creditAccountId: String!,
|
||||
$amount: Int!,
|
||||
$ledger: Int!,
|
||||
$code: Int!
|
||||
) {
|
||||
createTransfer(
|
||||
debitAccountId: $debitAccountId,
|
||||
creditAccountId: $creditAccountId,
|
||||
amount: $amount,
|
||||
ledger: $ledger,
|
||||
code: $code
|
||||
) {
|
||||
success
|
||||
message
|
||||
transferId
|
||||
}
|
||||
}
|
||||
''',
|
||||
variables={
|
||||
'debitAccountId': 'not-a-uuid',
|
||||
'creditAccountId': str(uuid.uuid4()),
|
||||
'amount': 50,
|
||||
'ledger': 1,
|
||||
'code': 202
|
||||
}
|
||||
)
|
||||
|
||||
self.assertResponseNoErrors(response)
|
||||
content = json.loads(response.content)
|
||||
result = content['data']['createTransfer']
|
||||
|
||||
self.assertFalse(result['success'])
|
||||
self.assertEqual(result['message'], 'Invalid account ID format. Must be a valid UUID.')
|
||||
|
||||
Reference in New Issue
Block a user