diff --git a/apps/wallet/serializers.py b/apps/wallet/serializers.py index ecdff32..b019269 100755 --- a/apps/wallet/serializers.py +++ b/apps/wallet/serializers.py @@ -1,4 +1,5 @@ from django.db import IntegrityError +from django.core.validators import MinValueValidator from django.db.transaction import atomic from rest_framework import serializers from rest_framework.exceptions import APIException @@ -175,7 +176,7 @@ class ApplicationTransactionSerializer(BaseTransactionSerializer): class ApplicationDepositSerializer(serializers.ModelSerializer): payee_id = serializers.UUIDField(required=True) payee_type = serializers.IntegerField(required=True) - amount = serializers.IntegerField(required=True) + amount = serializers.IntegerField(required=True, validators=[MinValueValidator(1)]) # TODO: details as fields class Meta: @@ -200,7 +201,7 @@ class ApplicationDepositSerializer(serializers.ModelSerializer): class ApplicationWithdrawSerializer(serializers.ModelSerializer): payer_id = serializers.UUIDField(required=True) payer_type = serializers.IntegerField(required=True) - amount = serializers.IntegerField(required=True) + amount = serializers.IntegerField(required=True, validators=[MinValueValidator(1)]) class Meta: model = Transaction diff --git a/apps/wallet/tests/application.py b/apps/wallet/tests/application.py index f0c5edc..7b8b425 100755 --- a/apps/wallet/tests/application.py +++ b/apps/wallet/tests/application.py @@ -22,6 +22,18 @@ class ApplicationApiFlowsTests(APITestCase): application_uuid = uuid.UUID('b14e8b86-8f4a-44d9-b29d-badceb470053') client_id = '4INGOCMoulE0fNY1SQlTbPtsWqqxGj2DdqjADq6u' + scopes = [ + 'wallet.application.deposit:verify', + 'wallet.application:get_balance', + 'wallet.application.deposit:submit', + 'wallet.deposit:submit', + 'wallet.wallet:get_balance', + 'wallet.application:get_user_balance', + + 'wallet.application.withdraw:submit', + 'wallet.application.withdraw:verify', + ] + def setUp(self): self.application_user, _ = User.objects.get_or_create(pk=self.application_uuid) self.payer_user, _ = User.objects.get_or_create(pk=self.payer_uuid) @@ -31,18 +43,6 @@ class ApplicationApiFlowsTests(APITestCase): expire_datetime = timezone.now() + timedelta(seconds=3600) expire_datetime.isoformat() - scopes = [ - 'wallet.application.deposit:verify', - 'wallet.application:get_balance', - 'wallet.application.deposit:submit', - 'wallet.deposit:submit', - 'wallet.wallet:get_balance', - 'wallet.application:get_user_balance', - - 'wallet.application.withdraw:submit', - 'wallet.application.withdraw:verify', - ] - self.application_access_token, _created = AccessToken.objects.update_or_create( token=self.application_access_token, defaults={ @@ -50,7 +50,7 @@ class ApplicationApiFlowsTests(APITestCase): "client_id": self.client_id, # "client_owner": owner, "application_id": self.application_uuid, - "scope": ' '.join(scopes), + "scope": ' '.join(self.scopes), "expires": expire_datetime.isoformat(), }, ) @@ -62,7 +62,7 @@ class ApplicationApiFlowsTests(APITestCase): "client_id": self.client_id, # "client_owner": owner, "application_id": self.application_uuid, - "scope": ' '.join(scopes), + "scope": ' '.join(self.scopes), "expires": expire_datetime.isoformat(), }, ) @@ -83,6 +83,24 @@ class ApplicationApiFlowsTests(APITestCase): response = self.client.get(reverse('wallet:user_wallet_balance_api'), HTTP_AUTHORIZATION=auth) self.assertContains(response, 'balance') + + def test_authentication_expired_token(self): + access_token = 'u4naVsdKCbKNOhnElPyXcrwSnqqFbm23' + expired_access_token, _created = AccessToken.objects.update_or_create( + token=access_token, + defaults={ + "user": self.application_user, + "client_id": self.client_id, + # "client_owner": owner, + "application_id": self.application_uuid, + "scope": ' '.join(self.scopes), + "expires": (timezone.now() - timedelta(seconds=3600)).isoformat(), + }, + ) + auth = self._create_authorization_header(expired_access_token.token) + response = self.client.get(reverse('wallet:user_wallet_balance_api'), HTTP_AUTHORIZATION=auth) + self.assertEqual(response.status_code, 401) + # def test_authentication_disallow(self): # auth = self._create_authorization_header('fake_token') # response = self.client.get(reverse('wallet:user_wallet_balance_api'), HTTP_AUTHORIZATION=auth) @@ -154,6 +172,30 @@ class ApplicationApiFlowsTests(APITestCase): response = self.client.post(reverse('wallet:application_deposit_submit_api'), data=data, HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 500) + def test_deposit_flow_zero_amount(self): + auth = self._create_authorization_header(self.application_access_token.token) + + # Deposit process + data = { + 'amount': 0, + 'payee_id': self.payee_uuid, + 'payee_type': TypeChoices.USER + } + response = self.client.post(reverse('wallet:application_deposit_submit_api'), data=data, HTTP_AUTHORIZATION=auth) + self.assertEqual(response.status_code, 400) + + def test_deposit_flow_negative_amount(self): + auth = self._create_authorization_header(self.application_access_token.token) + + # Deposit process + data = { + 'amount': -100, + 'payee_id': self.payee_uuid, + 'payee_type': TypeChoices.USER + } + response = self.client.post(reverse('wallet:application_deposit_submit_api'), data=data, HTTP_AUTHORIZATION=auth) + self.assertEqual(response.status_code, 400) + def test_deposit_flow_prevent_double_spending(self): auth = self._create_authorization_header(self.application_access_token.token) @@ -246,6 +288,32 @@ class ApplicationApiFlowsTests(APITestCase): response = self.client.post(reverse('wallet:application_withdraw_submit_api'), data=data, HTTP_AUTHORIZATION=auth) self.assertEqual(response.status_code, 500) + def test_withdraw_flow_zero_amount(self): + auth = self._create_authorization_header(self.payer_access_token.token) + + # Deposit process + data = { + 'amount': 0, + 'payer_id': self.payer_uuid, + 'payer_type': TypeChoices.USER + } + response = self.client.post(reverse('wallet:application_withdraw_submit_api'), data=data, + HTTP_AUTHORIZATION=auth) + self.assertEqual(response.status_code, 400) + + def test_withdraw_flow_negative_amount(self): + auth = self._create_authorization_header(self.payer_access_token.token) + + # Deposit process + data = { + 'amount': -500, + 'payer_id': self.payer_uuid, + 'payer_type': TypeChoices.USER + } + response = self.client.post(reverse('wallet:application_withdraw_submit_api'), data=data, + HTTP_AUTHORIZATION=auth) + self.assertEqual(response.status_code, 400) + def test_withdraw_flow_prevent_double_spending(self): auth = self._create_authorization_header(self.payer_access_token.token)