unipath
para gerenciar os arquivos"""
A view de pagamento faz uma integração com o Paypal
"""
class TestPaymentView(TestCase):
def test_pay_order(self):
data = {'credit_card': '1234'}
self.client.post('/pagamento/42', data)
order = Order.objects.get(id=42)
self.assertTrue(order.paid)
pip install requests
"""
Uma possível implementação da integração
"""
def payment_view(order_id):
# códigos pra recuperar a ordem, validar form e tudo mais
data = {
'resource_id': order_id,
'credit_card': form.cleaned_data['credit_card']
}
paypal_response = requests.post('http://paypal.com/api', data=data)
if paypal_response.text == 'SUCCESS':
order.paid = True
order.save()
# códigos pra seguir o fluxo http
"""
Utilizando a lib requests-mock: pip install requests-mock
"""
import requests_mock
class TestPaymentView(TestCase):
def test_pay_order(self):
data = {'credit_card': '1234'}
with requests_mock.Mocker() as mock:
mock.post('http://paypal.com/api', text='SUCCESS')
self.client.post('/pagamento/42', data)
order = Order.objects.get(id=42)
self.assertTrue(order.paid)
import requests_mock
class TestPaypalPaymentClient(TestCase):
def setUp(self):
self.paypal_client = PaypalPaymentClient()
self.data = {'credit_card': '1234', 'resource_id': 42}
def test_check_payment_was_successful(self):
with requests_mock.Mocker() as mock:
mock.post('http://paypal.com/api', text='SUCCESS')
paypal_response = self.paypal_client.pay(**self.data)
self.assertTrue(paypal_response.success)
def test_check_payment_wasnt_successful(self):
with requests_mock.Mocker() as mock:
mock.post('http://paypal.com/api', text='ERROR')
paypal_response = self.paypal_client.pay(**self.data)
self.assertFalse(paypal_response.success())
import requests
class PaypalResponse(object):
def __init__(self, paypal_response_text):
self.paypal_response_text = paypal_response_text
def success(self):
return self.paypal_response_text == 'SUCCESS'
class PaypalPaymentClient(object):
def pay(self, credit_card, resource_id):
data = {'credit_card': credit_card, 'resource_id': resource_id}
response = requests.post('http://paypal.com/api/', data=data)
return PaypalResponse(response.text)
class TestPaypalPaymentClient(TestCase):
"""..... testes de responsabilidade"""
def test_ensure_payment_url(self):
self.assertEqual('http://paypal.com', self.paypal_client.host)
self.assertEqual('/api/', self.paypal_client.path)
self.assertEqual('http://paypal.com/api/', self.paypal_client.payment_url)
import requests
class PaypalResponse(object):
def __init__(self, paypal_response_text):
self.paypal_response_text = paypal_response_text
def success(self):
return self.paypal_response_text == 'SUCCESS'
class PaypalPaymentClient(object):
def __init__(self):
self.host = 'http://paypal.com'
self.path = '/api/'
self.payment_url = '{}{}'.format(self.host, self.path)
def pay(self, credit_card, resource_id):
data = {'credit_card': credit_card, 'resource_id': resource_id}
response = requests.post(self.payment_url, data=data)
return PaypalResponse(response.text)
class TestPaypalPaymentClient(TestCase):
"""..... testes de responsabilidade e confiança"""
def test_raises_custom_exception_if_not_200_api_response(self):
with requests_mock.Mocker() as mock:
mock.post('http://paypal.com/api', text='ERROR', status_code=408)
self.assertRaises(
PaypalApiCommunicationException, self.paypal_client.pay, **self.data
)
import requests
class PaypalApiCommunicationException(Exception):
"""
Exception raised when Paypal API answers other than 200 status code
"""
class PaypalResponse(object):
def __init__(self, paypal_response_text):
self.paypal_response_text = paypal_response_text
def success(self):
return self.paypal_response_text == 'SUCCESS'
class PaypalPaymentClient(object):
def __init__(self):
self.host = 'http://paypal.com'
self.path = '/api/'
self.payment_url = '{}{}'.format(self.host, self.path)
def pay(self, credit_card, resource_id):
data = {'credit_card': credit_card, 'resource_id': resource_id}
response = requests.post(self.payment_url, data=data)
if not response.ok:
msg = 'Error {} - Content: {}'.format(response.status_code, response.text)
raise PaypalApiCommunicationException()
return PaypalResponse(response.text)
from mock import patch, Mock
class TestPaymentView(TestCase):
@patch.object(PaypalResponse, 'success', Mock(return_value=True))
def test_pay_order(self):
data = {'credit_card': '1234'}
self.client.post('/pagamento/42', data)
order = Order.objects.get(id=42)
self.assertTrue(order.paid)
@patch.object(PaypalResponse, 'success', Mock(side_effect=PaypalApiCommunicationException))
def test_400_if_paypal_error(self):
data = {'credit_card': '1234'}
response = self.client.post('/pagamento/42', data)
self.assertEqual(400, response.status_code)
"""
Nova possível implementação da integração
"""
def payment_view(order_id):
# códigos pra recuperar a ordem, validar form e tudo mais
data = {
'resource_id': order_id,
'credit_card': form.cleaned_data['credit_card']
}
paypal_client = PaypalPaymentClient()
try:
response = paypal_client.pay(**data)
except PaypalApiCommunicationException:
return HttpResponseBadRequest()
if response.success():
order.paid = True
order.save()
# códigos pra seguir o fluxo http
Bernardo Fontes