tests application transactions with currency
This commit is contained in:
parent
b3fc8cc17f
commit
4736d0c015
5 changed files with 39 additions and 16 deletions
18
apps/wallet/migrations/0011_category_currency.py
Normal file
18
apps/wallet/migrations/0011_category_currency.py
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 5.1.7 on 2025-10-11 13:22
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wallet', '0010_rename_payee_id_transaction__payee_id_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='category',
|
||||||
|
name='currency',
|
||||||
|
field=models.UUIDField(choices=[('166ab7ce33b34799950d45035a9997d6', 'IRANIAN RIAL')], db_index=True, default='166ab7ce33b34799950d45035a9997d6'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -177,7 +177,7 @@ class ApplicationDepositSerializer(serializers.ModelSerializer):
|
||||||
uuid = serializers.UUIDField(required=False, allow_null=None)
|
uuid = serializers.UUIDField(required=False, allow_null=None)
|
||||||
payee_id = serializers.UUIDField(required=True)
|
payee_id = serializers.UUIDField(required=True)
|
||||||
payee_type = serializers.IntegerField(required=True)
|
payee_type = serializers.IntegerField(required=True)
|
||||||
payee_wallet_category = serializers.UUIDField(required=True)
|
payee_wallet_category = serializers.UUIDField(required=False) # TODO: required True
|
||||||
amount = serializers.IntegerField(required=True, validators=[MinValueValidator(1)])
|
amount = serializers.IntegerField(required=True, validators=[MinValueValidator(1)])
|
||||||
# TODO: details as fields
|
# TODO: details as fields
|
||||||
|
|
||||||
|
|
@ -206,7 +206,7 @@ class ApplicationWithdrawSerializer(serializers.ModelSerializer):
|
||||||
uuid = serializers.UUIDField(required=False, allow_null=None)
|
uuid = serializers.UUIDField(required=False, allow_null=None)
|
||||||
payer_id = serializers.UUIDField(required=True)
|
payer_id = serializers.UUIDField(required=True)
|
||||||
payer_type = serializers.IntegerField(required=True)
|
payer_type = serializers.IntegerField(required=True)
|
||||||
payer_wallet_category = serializers.UUIDField(required=True)
|
payer_wallet_category = serializers.UUIDField(required=False) # TODO: required True
|
||||||
amount = serializers.IntegerField(required=True, validators=[MinValueValidator(1)])
|
amount = serializers.IntegerField(required=True, validators=[MinValueValidator(1)])
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ class ApplicationApiFlowsTests(APITestCase):
|
||||||
payer_access_token = '24naVsdKCbKNOhnElPyXcrwSnqqFbm'
|
payer_access_token = '24naVsdKCbKNOhnElPyXcrwSnqqFbm'
|
||||||
payer_uuid = uuid.UUID('b14e8b86-8f4a-44d9-b29d-badceb470051')
|
payer_uuid = uuid.UUID('b14e8b86-8f4a-44d9-b29d-badceb470051')
|
||||||
payee_uuid = uuid.UUID('b14e8b86-8f4a-44d9-b29d-badceb470052')
|
payee_uuid = uuid.UUID('b14e8b86-8f4a-44d9-b29d-badceb470052')
|
||||||
wallet_category1_uuid = uuid.UUID('114e8b86-8f4a-44d9-b29d-badceb470051')
|
wallet_category1_uuid = uuid.UUID('af7d967f-30c0-409b-9066-2549f2da5e5e')
|
||||||
wallet_category2_uuid = uuid.UUID('214e8b86-8f4a-44d9-b29d-badceb470051')
|
wallet_category2_uuid = uuid.UUID('214e8b86-8f4a-44d9-b29d-badceb470051')
|
||||||
# application, _ = Application.objects.get_or_create(client_id=client_id, uuid=application_uuid)
|
# application, _ = Application.objects.get_or_create(client_id=client_id, uuid=application_uuid)
|
||||||
|
|
||||||
|
|
@ -186,6 +186,7 @@ class ApplicationApiFlowsTests(APITestCase):
|
||||||
'payee_type': TypeChoices.USER
|
'payee_type': TypeChoices.USER
|
||||||
}
|
}
|
||||||
response = self.client.post(reverse('wallet:application_deposit_submit_api', kwargs=kwargs_category_uuid), data=data, HTTP_AUTHORIZATION=auth)
|
response = self.client.post(reverse('wallet:application_deposit_submit_api', kwargs=kwargs_category_uuid), data=data, HTTP_AUTHORIZATION=auth)
|
||||||
|
print(response.json())
|
||||||
self.assertEqual(response.status_code, 201)
|
self.assertEqual(response.status_code, 201)
|
||||||
json_response = response.json()
|
json_response = response.json()
|
||||||
|
|
||||||
|
|
@ -232,7 +233,7 @@ class ApplicationApiFlowsTests(APITestCase):
|
||||||
'payee_type': TypeChoices.USER
|
'payee_type': TypeChoices.USER
|
||||||
}
|
}
|
||||||
response = self.client.post(reverse('wallet:application_deposit_submit_api'), data=data, HTTP_AUTHORIZATION=auth)
|
response = self.client.post(reverse('wallet:application_deposit_submit_api'), data=data, HTTP_AUTHORIZATION=auth)
|
||||||
self.assertEqual(response.status_code, 500)
|
self.assertEqual(response.status_code, 422)
|
||||||
|
|
||||||
@override_settings(ALLOWED_NEGATIVE_BALANCE_APPLICATIONS=['b14e8b86-8f4a-44d9-b29d-badceb470053'])
|
@override_settings(ALLOWED_NEGATIVE_BALANCE_APPLICATIONS=['b14e8b86-8f4a-44d9-b29d-badceb470053'])
|
||||||
def test_deposit_flow_skip_insufficient_balance_for_allowed_negative_balance_applications(self):
|
def test_deposit_flow_skip_insufficient_balance_for_allowed_negative_balance_applications(self):
|
||||||
|
|
@ -303,10 +304,11 @@ class ApplicationApiFlowsTests(APITestCase):
|
||||||
'payee_type': TypeChoices.USER
|
'payee_type': TypeChoices.USER
|
||||||
}
|
}
|
||||||
response = self.client.post(reverse('wallet:application_deposit_submit_api'), data=data, HTTP_AUTHORIZATION=auth)
|
response = self.client.post(reverse('wallet:application_deposit_submit_api'), data=data, HTTP_AUTHORIZATION=auth)
|
||||||
|
print(response.json())
|
||||||
self.assertEqual(response.status_code, 201)
|
self.assertEqual(response.status_code, 201)
|
||||||
|
|
||||||
response = self.client.post(reverse('wallet:application_deposit_submit_api'), data=data, HTTP_AUTHORIZATION=auth)
|
response = self.client.post(reverse('wallet:application_deposit_submit_api'), data=data, HTTP_AUTHORIZATION=auth)
|
||||||
self.assertEqual(response.status_code, 500)
|
self.assertEqual(response.status_code, 422)
|
||||||
|
|
||||||
def test_withdraw_flow_success(self):
|
def test_withdraw_flow_success(self):
|
||||||
auth = self._create_authorization_header(self.payer_access_token.token)
|
auth = self._create_authorization_header(self.payer_access_token.token)
|
||||||
|
|
@ -384,6 +386,7 @@ class ApplicationApiFlowsTests(APITestCase):
|
||||||
'uuid': json_response['uuid'],
|
'uuid': json_response['uuid'],
|
||||||
}
|
}
|
||||||
response = self.client.get(reverse('wallet:application_withdraw_verify_api', kwargs=kwargs_category_uuid_transaction_uuid), HTTP_AUTHORIZATION=auth)
|
response = self.client.get(reverse('wallet:application_withdraw_verify_api', kwargs=kwargs_category_uuid_transaction_uuid), HTTP_AUTHORIZATION=auth)
|
||||||
|
print(response.json())
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(response.json()['state'], 5)
|
self.assertEqual(response.json()['state'], 5)
|
||||||
|
|
||||||
|
|
@ -455,6 +458,6 @@ class ApplicationApiFlowsTests(APITestCase):
|
||||||
self.assertEqual(response.status_code, 201)
|
self.assertEqual(response.status_code, 201)
|
||||||
|
|
||||||
response = self.client.post(reverse('wallet:application_withdraw_submit_api'), data=data, HTTP_AUTHORIZATION=auth)
|
response = self.client.post(reverse('wallet:application_withdraw_submit_api'), data=data, HTTP_AUTHORIZATION=auth)
|
||||||
self.assertEqual(response.status_code, 500)
|
self.assertEqual(response.status_code, 422)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ from apps.wallet.models import Transaction, Category, Wallet
|
||||||
from apps.wallet.serializers import ApplicationDepositSerializer, ApplicationWithdrawSerializer, \
|
from apps.wallet.serializers import ApplicationDepositSerializer, ApplicationWithdrawSerializer, \
|
||||||
ApplicationTransactionSerializer, ApplicationBalanceSerializer, MyWalletSerializer
|
ApplicationTransactionSerializer, ApplicationBalanceSerializer, MyWalletSerializer
|
||||||
from utils.exceptions import UnprocessableEntity
|
from utils.exceptions import UnprocessableEntity
|
||||||
|
from wallet.settings import DEFAULT_WALLET_CATEGORY_UUID
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -187,7 +188,7 @@ class CategoryBalanceAPIView(generics.RetrieveAPIView):
|
||||||
required_scopes = ['wallet.application:get_balance']
|
required_scopes = ['wallet.application:get_balance']
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
category_uuid = self.kwargs.get('category_uuid')
|
category_uuid = self.kwargs.get('category_uuid', DEFAULT_WALLET_CATEGORY_UUID)
|
||||||
if category_uuid:
|
if category_uuid:
|
||||||
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
||||||
else:
|
else:
|
||||||
|
|
@ -208,7 +209,7 @@ class CategoryUserBalanceAPIView(generics.RetrieveAPIView):
|
||||||
required_scopes = ['wallet.application:get_user_balance']
|
required_scopes = ['wallet.application:get_user_balance']
|
||||||
|
|
||||||
def get_object(self):
|
def get_object(self):
|
||||||
category_uuid = self.kwargs.get('category_uuid')
|
category_uuid = self.kwargs.get('category_uuid', DEFAULT_WALLET_CATEGORY_UUID)
|
||||||
if category_uuid:
|
if category_uuid:
|
||||||
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
||||||
else:
|
else:
|
||||||
|
|
@ -278,10 +279,10 @@ class CategoryDepositSubmitAPIView(generics.CreateAPIView):
|
||||||
# TODO: get_or_create instead of create if uuid given
|
# TODO: get_or_create instead of create if uuid given
|
||||||
# TODO: it is possible to merage create and submit in one step for improve performance
|
# TODO: it is possible to merage create and submit in one step for improve performance
|
||||||
application = get_application(self.request)
|
application = get_application(self.request)
|
||||||
payee_wallet_category_uuid = serializer.validated_data.pop('payee_wallet_category')
|
payee_wallet_category_uuid = serializer.validated_data.pop('payee_wallet_category', DEFAULT_WALLET_CATEGORY_UUID)
|
||||||
payee_wallet_category_uuid = payee_wallet_category_uuid and str(payee_wallet_category_uuid)
|
payee_wallet_category_uuid = payee_wallet_category_uuid and str(payee_wallet_category_uuid)
|
||||||
|
|
||||||
payer_wallet_category_uuid = self.kwargs.get('category_uuid')
|
payer_wallet_category_uuid = self.kwargs.get('category_uuid', DEFAULT_WALLET_CATEGORY_UUID)
|
||||||
|
|
||||||
if payer_wallet_category_uuid:
|
if payer_wallet_category_uuid:
|
||||||
payer_wallet_category = get_object_or_404(Category.objects.all(), uuid=payer_wallet_category_uuid)
|
payer_wallet_category = get_object_or_404(Category.objects.all(), uuid=payer_wallet_category_uuid)
|
||||||
|
|
@ -311,7 +312,7 @@ class CategoryDepositVerifyAPIView(generics.RetrieveAPIView):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
application = get_application(self.request)
|
application = get_application(self.request)
|
||||||
category_uuid = self.kwargs.get('category_uuid')
|
category_uuid = self.kwargs.get('category_uuid', DEFAULT_WALLET_CATEGORY_UUID)
|
||||||
if category_uuid:
|
if category_uuid:
|
||||||
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
||||||
else:
|
else:
|
||||||
|
|
@ -349,10 +350,10 @@ class CategoryWithdrawSubmitAPIView(generics.CreateAPIView):
|
||||||
# TODO: get_or_create instead of create if uuid given
|
# TODO: get_or_create instead of create if uuid given
|
||||||
# TODO: it is possible to merage create and submit in one step for improve performance
|
# TODO: it is possible to merage create and submit in one step for improve performance
|
||||||
application = get_application(self.request)
|
application = get_application(self.request)
|
||||||
payer_wallet_category_uuid = serializer.validated_data.pop('payer_wallet_category')
|
payer_wallet_category_uuid = serializer.validated_data.pop('payer_wallet_category', DEFAULT_WALLET_CATEGORY_UUID)
|
||||||
payer_wallet_category_uuid = payer_wallet_category_uuid and str(payer_wallet_category_uuid)
|
payer_wallet_category_uuid = payer_wallet_category_uuid and str(payer_wallet_category_uuid)
|
||||||
|
|
||||||
payee_wallet_category_uuid = self.kwargs.get('category_uuid')
|
payee_wallet_category_uuid = self.kwargs.get('category_uuid', DEFAULT_WALLET_CATEGORY_UUID)
|
||||||
if payee_wallet_category_uuid:
|
if payee_wallet_category_uuid:
|
||||||
payee_wallet_category = get_object_or_404(Category.objects.all(), uuid=payee_wallet_category_uuid)
|
payee_wallet_category = get_object_or_404(Category.objects.all(), uuid=payee_wallet_category_uuid)
|
||||||
else:
|
else:
|
||||||
|
|
@ -380,7 +381,7 @@ class CategoryWithdrawVerifyAPIView(generics.RetrieveAPIView):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
application = get_application(self.request)
|
application = get_application(self.request)
|
||||||
category_uuid = self.kwargs.get('category_uuid')
|
category_uuid = self.kwargs.get('category_uuid', DEFAULT_WALLET_CATEGORY_UUID)
|
||||||
if category_uuid:
|
if category_uuid:
|
||||||
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
category = get_object_or_404(Category.objects.all(), uuid=category_uuid)
|
||||||
else:
|
else:
|
||||||
|
|
@ -391,7 +392,7 @@ class CategoryWithdrawVerifyAPIView(generics.RetrieveAPIView):
|
||||||
def retrieve(self, request, *args, **kwargs):
|
def retrieve(self, request, *args, **kwargs):
|
||||||
instance = self.get_object()
|
instance = self.get_object()
|
||||||
if instance.state == StateChoices.PENDING:
|
if instance.state == StateChoices.PENDING:
|
||||||
instance.verify()
|
instance.category_verify()
|
||||||
|
|
||||||
serializer = self.get_serializer(instance)
|
serializer = self.get_serializer(instance)
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
|
||||||
|
|
@ -263,4 +263,5 @@ CACHES = {
|
||||||
}
|
}
|
||||||
|
|
||||||
ALLOWED_NEGATIVE_BALANCE_APPLICATIONS = config('ALLOWED_NEGATIVE_BALANCE_APPLICATIONS', cast=lambda v: [s.strip() for s in v.split(',')])
|
ALLOWED_NEGATIVE_BALANCE_APPLICATIONS = config('ALLOWED_NEGATIVE_BALANCE_APPLICATIONS', cast=lambda v: [s.strip() for s in v.split(',')])
|
||||||
DEFAULT_WALLET_CATEGORY_UUID = 'af7d967f-30c0-409b-9066-2549f2da5e5e'
|
from uuid import UUID
|
||||||
|
DEFAULT_WALLET_CATEGORY_UUID = 'af7d967f-30c0-409b-9066-2549f2da5e5e'
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue