Skip to content

Commit

Permalink
feat: Added tests for PayPal views file
Browse files Browse the repository at this point in the history
  • Loading branch information
shafqatfarhan committed Dec 13, 2024
1 parent 42d4730 commit 711df68
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 1 deletion.
114 changes: 114 additions & 0 deletions commerce_coordinator/apps/paypal/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import base64
import zlib
from unittest.mock import patch, MagicMock

from django.conf import settings
from django.urls import reverse
from rest_framework.test import APITestCase

from commerce_coordinator.apps.paypal.views import PayPalWebhookView
from commerce_coordinator.apps.paypal.models import KeyValueCache


class PayPalWebhookViewTests(APITestCase):
""" Tests for PayPalWebhookView """

def setUp(self):
super().setUp()
self.url = reverse('paypal:paypal_webhook')
self.headers = {
'paypal-transmission-id': 'test-transmission-id',
'paypal-transmission-time': '2023-01-01T00:00:00Z',
'paypal-transmission-sig': base64.b64encode(b'test-signature').decode('utf-8'),
'paypal-cert-url': 'https://www.paypal.com/cert.pem',
}
self.body = b'test-body'
self.crc = zlib.crc32(self.body)
self.message = f"{self.headers['paypal-transmission-id']}|{self.headers['paypal-transmission-time']}|{settings.PAYPAL_WEBHOOK_ID}|{self.crc}"

@patch('requests.get')
@patch('commerce_coordinator.apps.paypal.views.x509.load_pem_x509_certificate')
@patch('commerce_coordinator.apps.paypal.views.CommercetoolsAPIClient')
def test_post_refund_event(self, mock_commercetools_client, mock_load_cert, mock_requests_get):
mock_requests_get.return_value.text = 'test-cert'
mock_load_cert.return_value.public_key.return_value.verify = MagicMock()

mock_commercetools_client.return_value.get_payment_by_transaction_interaction_id.return_value = MagicMock(key='test-paypal-order-id')

data = {
"event_type": "PAYMENT.CAPTURE.REFUNDED",
"resource": {
"id": "test-refund-id",
"create_time": "2023-01-01T00:00:00Z",
"status": "COMPLETED",
"amount": {
"value": "100.00",
"currency_code": "USD"
},
"invoice_id": "test-order-number",
"links": [
{"rel": "up", "href": "https://api.paypal.com/v2/payments/captures/test-capture-id"}
]
}
}

response = self.client.post(self.url, data, format='json', **self.headers)
self.assertEqual(response.status_code, 200)

@patch('requests.get')
@patch('commerce_coordinator.apps.paypal.views.x509.load_pem_x509_certificate')
def test_post_invalid_signature(self, mock_load_cert, mock_requests_get):
mock_requests_get.return_value.text = 'test-cert'
mock_load_cert.return_value.public_key.return_value.verify.side_effect = Exception("Invalid signature")

data = {
"event_type": "PAYMENT.CAPTURE.REFUNDED",
"resource": {}
}

response = self.client.post(self.url, data, format='json', **self.headers)
self.assertEqual(response.status_code, 400)

@patch('requests.get')
def test_get_certificate_from_cache(self, mock_requests_get):
KeyValueCache.objects.create(cache_key=self.headers['paypal-cert-url'], cache_value='cached-cert')
view = PayPalWebhookView()
cert = view._get_certificate(self.headers['paypal-cert-url'])
self.assertEqual(cert, 'cached-cert')
mock_requests_get.assert_not_called()

@patch('requests.get')
def test_get_certificate_from_url(self, mock_requests_get):
mock_requests_get.return_value.text = 'test-cert'
view = PayPalWebhookView()
cert = view._get_certificate(self.headers['paypal-cert-url'])
self.assertEqual(cert, 'test-cert')
mock_requests_get.assert_called_once_with(self.headers['paypal-cert-url'])

def test_is_valid_url(self):
view = PayPalWebhookView()
self.assertTrue(view._is_valid_url('https://www.paypal.com/cert.pem'))
self.assertFalse(view._is_valid_url('ftp://www.paypal.com/cert.pem'))
self.assertFalse(view._is_valid_url('https://www.untrusted.com/cert.pem'))

def test_missing_headers(self):
data = {
"event_type": "PAYMENT.CAPTURE.REFUNDED",
"resource": {}
}
response = self.client.post(self.url, data, format='json')
self.assertEqual(response.status_code, 400)

@patch('requests.get')
@patch('commerce_coordinator.apps.paypal.views.x509.load_pem_x509_certificate')
def test_invalid_event_type(self, mock_load_cert, mock_requests_get):
mock_requests_get.return_value.text = 'test-cert'
mock_load_cert.return_value.public_key.return_value.verify = MagicMock()

data = {
"event_type": "INVALID.EVENT.TYPE",
"resource": {}
}

response = self.client.post(self.url, data, format='json', **self.headers)
self.assertEqual(response.status_code, 200)
2 changes: 1 addition & 1 deletion commerce_coordinator/apps/paypal/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def _get_certificate(self, url):
raise ValueError("Invalid or untrusted URL provided")
try:
cache = KeyValueCache.objects.get(cache_key=url)
return cache.value
return cache.cache_value
except KeyValueCache.DoesNotExist:
r = requests.get(url) # pylint: disable=missing-timeout
KeyValueCache.objects.create(cache_key=url, cache_value=r.text)
Expand Down

0 comments on commit 711df68

Please sign in to comment.