Skip to content

Commit

Permalink
Merge branch 'release/0.1.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
dessibelle committed Feb 10, 2015
2 parents c6770cb + 4cb38b2 commit f694efe
Show file tree
Hide file tree
Showing 12 changed files with 422 additions and 36 deletions.
1 change: 1 addition & 0 deletions .coveragerc
@@ -1,5 +1,6 @@
[run]
source = payer_api
omit = payer_api/tests/*
branch = 1

[report]
Expand Down
6 changes: 2 additions & 4 deletions .travis.yml
Expand Up @@ -10,11 +10,9 @@ env:
# - PIP_DOWNLOAD_CACHE=pip_cache TOXENV=py32
# - PIP_DOWNLOAD_CACHE=pip_cache TOXENV=py33
# - PIP_DOWNLOAD_CACHE=pip_cache TOXENV=py34
- PIP_DOWNLOAD_CACHE=pip_cache TOXENV=coverage
- PIP_DOWNLOAD_CACHE=pip_cache TOXENV=flake8
after_success: coveralls
cache:
directories:
- pip_cache
branches:
only:
- develop
- master
13 changes: 13 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,13 @@
# Changelog

## 0.1.2
* Bugfix for URL parsing when query string has blank values
* Minor improvements and stability
* Completed test suite

## 0.1.1
* Minor refactoring and improvements
* Added tests

## 0.1.0
* Initial release
2 changes: 1 addition & 1 deletion README.md
@@ -1,7 +1,7 @@
Python Payer API
================

[![Build Status](https://travis-ci.org/dessibelle/python-payer-api.svg?branch=master)](https://travis-ci.org/dessibelle/python-payer-api) [![Coverage Status](https://coveralls.io/repos/dessibelle/python-payer-api/badge.svg)](https://coveralls.io/r/dessibelle/python-payer-api) [![Latest Version](https://pypip.in/version/python-payer-api/badge.svg?style=flat)](https://pypi.python.org/pypi/python-payer-api/)
[![Build Status](https://travis-ci.org/dessibelle/python-payer-api.svg?branch=master)](https://travis-ci.org/dessibelle/python-payer-api) [![Coverage Status](https://coveralls.io/repos/dessibelle/python-payer-api/badge.svg?branch=master)](https://coveralls.io/r/dessibelle/python-payer-api?branch=master) [![Latest Version](https://pypip.in/version/python-payer-api/badge.svg?style=flat)](https://pypi.python.org/pypi/python-payer-api/)

Python package for interacting with the [Payer](http://payer.se) payments API.

Expand Down
2 changes: 1 addition & 1 deletion payer_api/__init__.py
@@ -1,4 +1,4 @@
VERSION = '0.1.1'
VERSION = '0.1.2'

DEBUG_MODE_BRIEF = "brief"
DEBUG_MODE_SILENT = "silent"
Expand Down
7 changes: 5 additions & 2 deletions payer_api/postapi.py
Expand Up @@ -107,10 +107,13 @@ def get_xml_data(self, *args, **kwargs):
raise PayerPostAPIError(
PayerPostAPIError.ERROR_MISSING_PROCESSING_CONTROL)

if not self.xml_document:
xml_data = None
try:
xml_data = self.xml_document.tostring(*args, **kwargs)
except:
raise PayerPostAPIError(PayerPostAPIError.ERROR_XML_ERROR)

return self.xml_document.tostring(*args, **kwargs)
return xml_data

def get_base64_data(self, xml_data=None, *args, **kwargs):
if not xml_data:
Expand Down
8 changes: 8 additions & 0 deletions payer_api/tests/__init__.py
@@ -0,0 +1,8 @@
import unittest


class TestCase(unittest.TestCase):
# Implement assertIsNotNone for Python runtimes < 2.7 or < 3.1
if not hasattr(unittest.TestCase, 'assertIsNotNone'):
def assertIsNotNone(self, value, *args):
self.assertNotEqual(value, None, *args)
2 changes: 2 additions & 0 deletions payer_api/tests/runtests.py
Expand Up @@ -2,6 +2,8 @@

testmodules = [
'payer_api.tests.test_api',
'payer_api.tests.test_xml',
'payer_api.tests.test_order',
]

suite = unittest.TestSuite()
Expand Down
80 changes: 64 additions & 16 deletions payer_api/tests/test_api.py
@@ -1,4 +1,5 @@
import unittest
from payer_api.tests import TestCase
import hashlib
import base64
from payer_api import (
Expand All @@ -16,13 +17,6 @@
)


class TestCase(unittest.TestCase):
# Implement assertIsNotNone for Python runtimes < 2.7 or < 3.1
if not hasattr(unittest.TestCase, 'assertIsNotNone'):
def assertIsNotNone(self, value, *args):
self.assertNotEqual(value, None, *args)


class TestPayerPostAPI(TestCase):

def setUp(self):
Expand Down Expand Up @@ -75,16 +69,28 @@ def getProcessingControl(self):
redirect_back_to_shop_url="http://localhost/webshop/",
)

def test_settings(self):
self.assertEqual(self.api.get_post_url(), self.api.PAYER_POST_URL)
self.assertEqual(
self.api.get_post_url(),
"https://secure.payer.se/PostAPI_V1/InitPayFlow")

def test_checksums(self):
xml_data = self.api.get_xml_data()

checksum = self.api.get_checksum(self.api.get_base64_data())
expected_checksum = hashlib.md5(
"6866ef97a972ba3a2c6ff8bb2812981054770162" +
base64.b64encode(xml_data) +
"1388ac756f07b0dda2961436ba8596c7b7995e94").hexdigest()
def check_checksums(xml_data, b64_data):
checksum = self.api.get_checksum(b64_data)
expected_checksum = hashlib.md5(
"6866ef97a972ba3a2c6ff8bb2812981054770162" +
base64.b64encode(xml_data) +
"1388ac756f07b0dda2961436ba8596c7b7995e94").hexdigest()

self.assertEqual(checksum, expected_checksum)

self.assertEqual(checksum, expected_checksum)
xml_data = self.api.get_xml_data()
b64_data = self.api.get_base64_data()

check_checksums(xml_data, b64_data)
check_checksums("foo bar", self.api.get_base64_data("foo bar"))

def test_callback_validation(self):
xml = self.api.xml_document
Expand Down Expand Up @@ -140,6 +146,10 @@ def get_md5_sum(url):
self.assertTrue(self.api.validate_callback_url(settle_url_test))
self.assertTrue(self.api.validate_callback_url(settle_url_api))

self.api.suppress_validation_checks = True
self.assertTrue(self.api.validate_callback_url("fake url"))
self.api.suppress_validation_checks = False

self.assertEqual(auth_url_test, auth_url_api)
self.assertEqual(settle_url_test, settle_url_api)

Expand All @@ -158,6 +168,12 @@ def get_md5_sum(url):
(self.api, settle_url +
"&md5sum=79acb36d5a10837c377e6f3f1cf9fc9c"))

try:
self.api.validate_callback_url(
settle_url + "&md5sum=79acb36d5a10837c377e6f3f1cf9fc9c")
except PayerURLValidationError as e:
self.assertTrue(str(e).startswith("MD5 checksums did not match."))

# IP white/blacklists
for ip in self.api.ip_whitelist:
self.assertTrue(self.api.validate_callback_ip(ip))
Expand All @@ -168,6 +184,10 @@ def get_md5_sum(url):
self.api.validate_callback_ip,
new_ip)

self.api.suppress_validation_checks = True
self.assertTrue(self.api.validate_callback_ip("fake ip"))
self.api.suppress_validation_checks = False

self.api.add_whitelist_ip(new_ip)
self.assertTrue(self.api.validate_callback_ip(new_ip))

Expand Down Expand Up @@ -198,16 +218,36 @@ def test_config_errors(self):
except:
raised = True

try:
api.get_post_data()
except PayerPostAPIError as e:
self.assertEqual(
e.code,
PayerPostAPIError.ERROR_MISSING_ORDER)

api.set_order(self.getOrder())

self.assertFalse(raised, 'Exception raised')
self.assertIsNotNone(api.get_checksum("data"))

# Order, Processing control, agent ID
self.assertRaises(PayerPostAPIError,
api.get_post_data)

api.agent_id = "AGENT_ID"
try:
api.get_post_data()
except PayerPostAPIError as e:
self.assertEqual(
e.code,
PayerPostAPIError.ERROR_MISSING_PROCESSING_CONTROL)

api.set_order(self.getOrder())
self.assertEqual(
str(e),
repr("Error %s: %s" % (
e.code,
e.ERROR_MESSAGES.get(e.code, "Unknown Error"))))

api.agent_id = "AGENT_ID"
api.set_processing_control(self.getProcessingControl())

raised = False
Expand All @@ -221,6 +261,14 @@ def test_config_errors(self):
self.assertRaises(PayerPostAPIError,
api._generate_xml)

def test_xml_error(self):
data = self.api.get_xml_data()
assert data

self.api.xml_document = "Fake XML document"

self.assertRaises(PayerPostAPIError,
self.api.get_xml_data)

if __name__ == '__main__':
unittest.main()
64 changes: 64 additions & 0 deletions payer_api/tests/test_order.py
@@ -0,0 +1,64 @@
import unittest
from payer_api.tests import TestCase
from payer_api.order import (
PayerOrder,
PayerBuyerDetails,
PayerOrderItem,
)


class TestOrder(TestCase):

def setUp(self):
self.order = PayerOrder(order_id="123456")

self.buyer_details = PayerBuyerDetails(
first_name="John",
last_name="Doe",
address_line_1="1234 Main Street",
postal_code="12345",
city="Anywhere",
phone_mobile="012345678",
email="john.doe@host.com",
)

self.order_items = [
PayerOrderItem(
description='A product',
price_including_vat=123.50,
vat_percentage=25,
quantity=4,
),
PayerOrderItem(
description='Another product',
price_including_vat=123.0,
vat_percentage=12.5,
quantity=2,
),
]

self.info_lines = [
"Shipping with 5 work days",
"Additional line of order info",
]

def test_add_order_item(self):
for order_item in self.order_items:
self.order.add_order_item(order_item)
self.assertTrue(order_item in self.order.order_items)

self.assertEqual(self.order.order_items, self.order_items)

def test_add_info_line(self):
for info_line in self.info_lines:
self.order.add_info_line(info_line)
self.assertTrue(info_line in self.order.info_lines)

self.assertEqual(self.order.info_lines, self.info_lines)

def test_set_buyer_details(self):
self.order.set_buyer_details(self.buyer_details)
self.assertEqual(self.order.buyer_details, self.buyer_details)

if __name__ == '__main__':
unittest.main()

0 comments on commit f694efe

Please sign in to comment.