def setUp(self): self.save_received_data = False # if True, leave a hard copy of the html sources received from the PSP self.create_fake_order() self.viveum_backend = backends_pool.get_payment_backends_list()[0] self.factory = RequestFactory() self.request = Mock() setattr(self.request, 'session', {}) setattr(self.request, 'is_secure', lambda: False) user = User.objects.create(username="******", email="*****@*****.**", first_name="Test", last_name="Tester", password="******") setattr(self.request, 'user', user) self.country_usa = Country(name='USA') self.country_usa.save() self.client = Client() self.client.login(username='******', password='******') self.add_product_to_cart() self.checkout()
def setUp(self): current_site = Site.objects.get(id=settings.SITE_ID) current_site.domain = settings.HOST_NAME current_site.save() self._create_fake_order() self.ipayment_backend = backends_pool.get_payment_backends_list()[0] self.factory = RequestFactory() self.request = Mock() setattr(self.request, 'session', {}) setattr(self.request, 'is_secure', lambda: False) user = User.objects.create(username="******", email="*****@*****.**", first_name="Test", last_name="Tester", password="******") setattr(self.request, 'user', user) self.country_usa = Country(name='USA') self.country_usa.save() self.client = Client() self.client.login(username='******', password='******') self._create_cart() self._go_shopping()
class ViveumTest(LiveServerTestCase): def setUp(self): self.save_received_data = False # if True, leave a hard copy of the html sources received from the PSP self.create_fake_order() self.viveum_backend = backends_pool.get_payment_backends_list()[0] self.factory = RequestFactory() self.request = Mock() setattr(self.request, 'session', {}) setattr(self.request, 'is_secure', lambda: False) user = User.objects.create(username="******", email="*****@*****.**", first_name="Test", last_name="Tester", password="******") setattr(self.request, 'user', user) self.country_usa = Country(name='USA') self.country_usa.save() self.client = Client() self.client.login(username='******', password='******') self.add_product_to_cart() self.checkout() def tearDown(self): time.sleep(10) # this keeps the live test server running for a while def add_product_to_cart(self): product = DiaryProduct(isbn='1234567890', number_of_pages=100, name='test', slug='test', active=True, unit_price=Decimal('1.23')) product.save() self.cart = get_or_create_cart(self.request, True) self.cart.add_product(product, 1) self.cart.save() def checkout(self): # add address information post_data = { 'ship-name': 'John Doe', 'ship-address': 'Rosestreet', 'ship-address2': '', 'ship-zip_code': '01234', 'ship-city': 'Toledeo', 'ship-state': 'Ohio', 'ship-country': self.country_usa.pk, 'bill-name': 'John Doe', 'bill-address': 'Rosestreet', 'bill-address2': '', 'bill-zip_code': '01234', 'bill-city': 'Toledeo', 'bill-state': 'Ohio', 'bill-country': self.country_usa.pk, 'shipping_method': 'flat', 'payment_method': 'viveum', } response = self.client.post(reverse('checkout_selection'), post_data, follow=True) urlobj = urlparse.urlparse(response.redirect_chain[0][0]) self.assertEqual(resolve(urlobj.path).url_name, 'checkout_shipping') urlobj = urlparse.urlparse(response.redirect_chain[1][0]) self.assertEqual(resolve(urlobj.path).url_name, 'flat') self.order = self.viveum_backend.shop.get_order(self.request) def create_fake_order(self): """ Create a fake order with a random order id, so that the following real order does not start with 1. Otherwise this could cause errors if this test is invoked multiple times. """ order_id = random.randint(100001, 999999) Order.objects.create(id=order_id, status=Order.CANCELLED) def send_transaction_data(self): """ Send data fields for the current transaction to the PSP using method POST. """ form_dict = self.viveum_backend.get_form_dict(self.request) self.viveum_backend.sign_form_dict(form_dict) url = settings.VIVEUM_PAYMENT.get('ORDER_STANDARD_URL') response = requests.post(url, data=form_dict, verify=True) self.assertEqual(response.status_code, 200, 'PSP failed to answer with HTTP code 200') return response.content def credit_card_payment(self, htmlsource, cc_number): """ Our PSP returned an HTML page containing a form with hidden input fields and with text fields to enter the credit card number. Use these fields to simulate a POST request which actually performes the payment. """ dom = PyQuery(htmlsource) elements = dom('input[type=hidden]') self.assertTrue(elements, 'No hidden input fields found in form') elements.extend(dom('input[name=Ecom_Payment_Card_Name]')) values = dict((elem.name, elem.value) for elem in elements) values.update({ 'Ecom_Payment_Card_Number': cc_number, 'Ecom_Payment_Card_ExpDate_Month': '12', 'Ecom_Payment_Card_ExpDate_Year': '2029', 'Ecom_Payment_Card_Verification': '123', }) form = dom('form[name=OGONE_CC_FORM]') url = form.attr('action') response = requests.post(url, data=values, verify=True) self.assertEqual(response.status_code, 200, 'PSP failed to answer with HTTP code 200') return response.content def extract_redirection_path(self, htmlsource): dom = PyQuery(htmlsource) form = dom('table table form') self.assertTrue(form, 'Redirect form not found in DOM') return urlparse.urlparse(form.attr('action')) def process_success_view(self, htmlsource): urlobj = self.extract_redirection_path(htmlsource) self.assertEqual(urlobj.path, reverse('viveum_accept')) data = dict(urlparse.parse_qsl(urlobj.query)) httpresp = self.client.get(urlobj.path, data, follow=True) self.assertEqual(len(httpresp.redirect_chain), 1, 'No redirection after receiving payment status') urlobj = urlparse.urlparse(httpresp.redirect_chain[0][0]) self.assertEqual(httpresp.status_code, 200, 'Merchant failed to finish payment receivement') self.assertEqual(resolve(urlobj.path).url_name, 'thank_you_for_your_order') def process_decline_view(self, htmlsource): dom = PyQuery(htmlsource) form = dom('#form3') self.assertTrue(form, 'No <form id="#form1"> found in html output') elements = form.find('input') values = dict((elem.name, elem.value) for elem in elements) values.update({'cancel': 'Cancel'}) url = form.attr('action') response = requests.post(url, data=values, verify=True) self.assertEqual(response.status_code, 200, 'PSP did not accept payment cancellation') self.save_htmlsource('decline_form', response.content) # in response check for string 'Cancelled' dom = PyQuery(response.content) tables = dom('table.ncoltable1') self.assertEqual(len(tables), 3) self.assertEqual(tables.eq(1).find('h3').text(), 'Cancelled') form = tables.eq(2).find('form') urlobj = urlparse.urlparse(form.attr('action')) data = dict(urlparse.parse_qsl(urlobj.query)) httpresp = self.client.get(urlobj.path, data, follow=True) self.assertEqual(len(httpresp.redirect_chain), 2, 'No redirection after declining payment') urlobj = urlparse.urlparse(httpresp.redirect_chain[1][0]) self.assertEqual(httpresp.status_code, 200) self.assertEqual(resolve(urlobj.path).url_name, 'viveum') def save_htmlsource(self, name, htmlsource): if self.save_received_data: f = open('psp-%s.tmp.html' % name, 'w') f.write(htmlsource) f.close() def test_visa_payment(self): """ With a valid credit card number, the payment is accepted. The payment module creates a confirmation object, which declares this payment as successful. The corresponding order object is set to status COMPLETED. """ payment_form = self.send_transaction_data() self.save_htmlsource('payment_form', payment_form) authorized_form = self.credit_card_payment(payment_form, '4111111111111111') self.save_htmlsource('authorized_form', authorized_form) self.process_success_view(authorized_form) order = Order.objects.get(pk=self.order.id) # Our order self.assertEqual(order.status, Order.COMPLETED) confirmation = Confirmation.objects.get(order__pk=self.order.id) # The PSP's confirmation self.assertEqual(confirmation.brand, 'VISA') self.assertEqual(confirmation.amount, order.order_total) def test_declined_payment(self): """ With an invalid credit card number, the payment is declined. The payment module creates a confirmation object, which cancels this payment. """ payment_form = self.send_transaction_data() self.save_htmlsource('payment_form', payment_form) authorized_form = self.credit_card_payment(payment_form, '4111113333333333') self.save_htmlsource('authorized_form', authorized_form) self.process_decline_view(authorized_form) confirmation = Confirmation.objects.get(order__pk=self.order.id) # The PSP's confirmation self.assertEqual(confirmation.brand, 'VISA') self.assertTrue(str(confirmation.status).startswith('1')) def test_template(self): httpresp = self.client.get(reverse('viveum_template')) self.assertContains(httpresp, '$$$PAYMENT ZONE$$$')
class IPaymentTest(LiveServerTestCase): def setUp(self): current_site = Site.objects.get(id=settings.SITE_ID) current_site.domain = settings.HOST_NAME current_site.save() self._create_fake_order() self.ipayment_backend = backends_pool.get_payment_backends_list()[0] self.factory = RequestFactory() self.request = Mock() setattr(self.request, 'session', {}) setattr(self.request, 'is_secure', lambda: False) user = User.objects.create(username="******", email="*****@*****.**", first_name="Test", last_name="Tester", password="******") setattr(self.request, 'user', user) self.country_usa = Country(name='USA') self.country_usa.save() self.client = Client() self.client.login(username='******', password='******') self._create_cart() self._go_shopping() def tearDown(self): time.sleep(10) # this keeps the server running for a while def _create_cart(self): self.product = DiaryProduct(isbn='1234567890', number_of_pages=100) self.product.name = 'test' self.product.slug = 'test' self.product.short_description = 'test' self.product.long_description = 'test' self.product.unit_price = Decimal('1.0') self.product.save() self.cart = get_or_create_cart(self.request) self.cart.add_product(self.product, 1) self.cart.save() def _go_shopping(self): # add address information post = { 'ship-name': 'John Doe', 'ship-address': 'Rosestreet', 'ship-address2': '', 'ship-zip_code': '01234', 'ship-city': 'Toledeo', 'ship-state': 'Ohio', 'ship-country': self.country_usa.pk, 'bill-name': 'John Doe', 'bill-address': 'Rosestreet', 'bill-address2': '', 'bill-zip_code': '01234', 'bill-city': 'Toledeo', 'bill-state': 'Ohio', 'bill-country': self.country_usa.pk, 'shipping_method': 'flat', 'payment_method': 'ipayment', } response = self.client.post(reverse('checkout_selection'), post, follow=True) urlobj = urlparse.urlparse(response.redirect_chain[0][0]) self.assertEqual(resolve(urlobj.path).url_name, 'checkout_shipping') urlobj = urlparse.urlparse(response.redirect_chain[1][0]) self.assertEqual(resolve(urlobj.path).url_name, 'flat') self.order = self.ipayment_backend.shop.get_order(self.request) def _simulate_payment(self): """ Simulate a payment to the IPayment processor. The full payment information is sent with method POST. Make sure your test environment is reachable from the Internet. This test will a) invoke a POST request from IPayment to this server b) redirect the client to a given URL on this server Both actions shall result in the confirmation of the payment. """ post = self.ipayment_backend.get_hidden_context(self.order) post['advanced_strict_id_check'] = 0 # disabled for testing only # (see ipayment_Technik-Handbuch.pdf page 32) if settings.IPAYMENT['useSessionId']: post['ipayment_session_id'] = self.ipayment_backend.get_session_id(self.request, self.order) else: post.update(self.ipayment_backend.get_sessionless_context(self.request, self.order)) post['trx_securityhash'] = self.ipayment_backend._calc_trx_security_hash(post) post.update({ 'addr_name': 'John Doe', 'cc_number': '4012888888881881', # Visa test credit card number 'cc_checkcode': '123', 'cc_expdate_month': '12', 'cc_expdate_year': '2029', }) ipayment_uri = '/merchant/%s/processor/2.0/' % settings.IPAYMENT['accountId'] headers = { "Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain" } conn = httplib.HTTPSConnection('ipayment.de') conn.request("POST", ipayment_uri, urllib.urlencode(post), headers) httpresp = conn.getresponse() self.assertEqual(httpresp.status, 302, 'Expected to be redirected back from IPayment') redir_url = urlparse.urlparse(httpresp.getheader('location')) query_params = urlparse.parse_qs(redir_url.query) redir_uri = redir_url.path + '?' + redir_url.query conn.close() self.assertEqual(query_params['ret_status'][0], 'SUCCESS', 'IPayment reported: ' + redir_uri) # IPayent redirected the customer onto 'redir_uri'. Continue to complete the order. response = self.client.get(redir_uri, follow=True) self.assertEqual(len(response.redirect_chain), 1, '') urlobj = urlparse.urlparse(response.redirect_chain[0][0]) self.assertEqual(resolve(urlobj.path).url_name, 'thank_you_for_your_order') self.assertEqual(response.status_code, 200) order = Order.objects.get(pk=self.order.id) self.assertEqual(order.status, Order.COMPLETED) confirmation = Confirmation.objects.get(shopper_id=self.order.id) self.assertEqual(confirmation.ret_status, 'SUCCESS') def _create_fake_order(self): """ Create a fake order with a random order id, so that the following real order does not start with 1. Otherwise this could cause errors if this test is invoked multiple times. """ order_id = random.randint(100001, 999999) Order.objects.create(id=order_id, status=Order.CANCELLED) def test_without_session(self): """ Simulate a payment to the IPayment processor without using a session. """ setattr(settings, 'IPAYMENT', settings.IPAYMENT_WITHOUT_SESSION) self._simulate_payment() def test_with_session(self): """ Simulate a payment to the IPayment processor using a session id generated through a SOAP invocation. """ setattr(settings, 'IPAYMENT', settings.IPAYMENT_WITH_SESSION) self._simulate_payment()