Skip to content
This repository has been archived by the owner on Jan 12, 2022. It is now read-only.

Commit

Permalink
further work
Browse files Browse the repository at this point in the history
  • Loading branch information
zupo committed Dec 20, 2012
1 parent 4a649e0 commit 7c87834
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ lib
parts
var
src/niteoweb.ipn.core/
src/plone.api/
4 changes: 3 additions & 1 deletion buildout.d/travis.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ parts -=
omelette
instance

auto-checkout = niteoweb.ipn.core
auto-checkout =
niteoweb.ipn.core
plone.api
19 changes: 10 additions & 9 deletions src/niteoweb/ipn/jvzoo/browser/jvzoo.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
logger = logging.getLogger("niteoweb.ipn.jvzoo")


class JVZoo(grok.view):
class JVZoo(grok.View):
"""A view for handling IPN POST requests from JVZOO."""

grok.context(ISiteRoot)
Expand All @@ -29,16 +29,16 @@ def render(self):

# prepare values
params = dict(self.request.form)
settings = api.portal.get_registry_record(
'niteoweb.ipn.jvzoo.interfaces.IJVZooSettings')
params['secretkey'] = settings.secretkey
params['secretkey'] = api.portal.get_registry_record(
'niteoweb.ipn.jvzoo.interfaces.IJVZooSettings.secretkey')

try:
# verify and parse post
self._verify_POST(params)
data = self._parse_POST(params)
logger.info("POST successfully parsed for '%s'" % data['email'])

# call action in niteoweb.ipn based on transaction type
# call action in niteoweb.ipn.core based on transaction type
ipn = getAdapter(self.context, IIPN)
if data['transaction_type'] in ['SALE', 'BILL', 'UNCANCEL-REBILL']:
ipn.enable_member()
Expand All @@ -51,20 +51,20 @@ def render(self):

except KeyError as ex:
msg = "POST parameter missing: %s" % ex
logger.error(msg)
logger.warning(msg)
return msg

except AssertionError:
msg = "Checksum verification failed."
logger.error(msg)
logger.warning(msg)
return msg

except Exception as ex:
msg = "POST handling failed: %s" % ex
logger.error(msg)
logger.warning(msg)
return msg

return 'POST successfully parsed.'
return 'Done.'

def _verify_POST(self, params):
"""Verifies if received POST is a valid JVZoo POST request.
Expand Down Expand Up @@ -96,6 +96,7 @@ def _parse_POST(self, params):
'fullname': u"%s" % params['ccustname'].decode("utf-8"),
'product_id': params['cproditem'],
'product_name': params['cprodtitle'],
'payment_id': params['ctransreceipt'],
'affiliate': params['ctransaffiliate'],
'transaction_type': params['ctransaction'],
}
1 change: 1 addition & 0 deletions src/niteoweb/ipn/jvzoo/profiles/default/browserlayer.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<?xml version="1.0"?>
<layers>
<layer
name="niteoweb.ipn.jvzoo"
Expand Down
4 changes: 2 additions & 2 deletions src/niteoweb/ipn/jvzoo/profiles/default/metadata.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<metadata>
<version>0100</version>
<dependencies>
<!-- <dependency>profile-niteoweb.ipn.core:default</dependency> -->
<dependency>profile-plone.app.registry:default</dependency>
<dependency>profile-niteoweb.ipn.core:default</dependency>
</dependencies>
</metadata>
1 change: 0 additions & 1 deletion src/niteoweb/ipn/jvzoo/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,5 +70,4 @@ class JvzooControlPanelTestCase(FunctionalTestCase, ControlPanelTestCase):
"""Test case used for control panel tests
Comes with convenience methods from plone.app.controlpanel.
"""
183 changes: 183 additions & 0 deletions src/niteoweb/ipn/jvzoo/tests/test_jvzoo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# -*- coding: utf-8 -*-
"""Test all aspects of the @@jvzoo view."""

from niteoweb.ipn.jvzoo.testing import IntegrationTestCase
from plone import api
from zope.testing.loggingsupport import InstalledHandler

import mock

log = InstalledHandler('niteoweb.ipn.jvzoo')

KEY_RECORD = 'niteoweb.ipn.jvzoo.interfaces.IJVZooSettings.secretkey'


class TestJVZoo(IntegrationTestCase):
"""Test all aspects of @@jvzoo."""

def setUp(self):
"""Prepare testing environment."""
self.portal = self.layer['portal']
self.view = self.portal.restrictedTraverse('jvzoo')

def tearDown(self):
"""Clean up after yourself."""
log.clear()

def test_call_with_no_POST(self):
"""Test @@jvzoo's response when POST is empty."""
html = self.view()
self.failUnless('No POST request.' in html)

def test_call_with_missing_parameter(self):
"""Test @@jvzoo's response when POST is missing a parameter."""

# put something into self.request.form so it's not empty
self.portal.REQUEST.form = dict(foo='bar')

# set secretkey
api.portal.set_registry_record(KEY_RECORD, u'secret')

# test html
html = self.view()
self.assertEqual(html, "POST parameter missing: 'cverify'")

# test log output
self.assertEqual(len(log.records), 1)
self.assertEqual(log.records[0].name, 'niteoweb.ipn.jvzoo')
self.assertEqual(log.records[0].levelname, 'WARNING')
self.assertEqual(
log.records[0].getMessage(),
"POST parameter missing: 'cverify'",
)

def test_call_with_missing_secret_key(self):
"""Test @@jvzoo's response when JVZoo secret-key is not set."""

# put something into self.request.form so it's not empty
self.portal.REQUEST.form = dict(foo='bar')

# test html
html = self.view()
self.assertEqual(
html, "POST handling failed: JVZoo secret-key is not set.")

# test log output
self.assertEqual(len(log.records), 1)
self.assertEqual(log.records[0].name, 'niteoweb.ipn.jvzoo')
self.assertEqual(log.records[0].levelname, 'WARNING')
self.assertEqual(
log.records[0].getMessage(),
"POST handling failed: JVZoo secret-key is not set.",
)

@mock.patch('niteoweb.ipn.jvzoo.browser.jvzoo.JVZoo._verify_POST')
def test_call_with_invalid_checksum(self, verify_post):
"""Test @@jvzoo's response when checksum cannot be verified."""

# put something into self.request.form so it's not empty
self.portal.REQUEST.form = dict(foo='bar')

# mock return from _verify_POST
verify_post.side_effect = AssertionError

# test html
html = self.view()
self.assertEqual(html, 'Checksum verification failed.')

# test log output
self.assertEqual(len(log.records), 1)
self.assertEqual(log.records[0].name, 'niteoweb.ipn.jvzoo')
self.assertEqual(log.records[0].levelname, 'WARNING')
self.assertEqual(
log.records[0].getMessage(),
"Checksum verification failed.",
)

@mock.patch('niteoweb.ipn.jvzoo.browser.jvzoo.JVZoo._verify_POST')
def test_call_with_internal_exception(self, verify_post):
"""Test @@jvzoo's response when there is an internal problem."""

# put something into self.request.form so it's not empty
self.portal.REQUEST.form = dict(foo='bar')

# mock return from _verify_POST
verify_post.side_effect = Exception('Internal foo.')

# test html
html = self.view()
self.assertEqual(html, 'POST handling failed: Internal foo.')

# test log output
self.assertEqual(len(log.records), 1)
self.assertEqual(log.records[0].name, 'niteoweb.ipn.jvzoo')
self.assertEqual(log.records[0].levelname, 'WARNING')
self.assertEqual(
log.records[0].getMessage(),
"POST handling failed: Internal foo.",
)

@mock.patch('niteoweb.ipn.jvzoo.browser.jvzoo.JVZoo._verify_POST')
@mock.patch('niteoweb.ipn.jvzoo.browser.jvzoo.JVZoo._parse_POST')
def test_call_with_valid_POST(self, parse_post, verify_post):
"""Test @@jvzoo's response when POST is valid."""

# put something into self.request.form so it's not empty
self.portal.REQUEST.form = dict(value='non empty value')

# mock post handling
verify_post.return_value = True
parse_post.return_value = dict(
email='jsmith@email.com',
transaction_type='SALE'
)

# test html
html = self.view()
self.assertIn('Done.', html)

# test log output
self.assertEqual(len(log.records), 1)
self.assertEqual(log.records[0].name, 'niteoweb.ipn.jvzoo')
self.assertEqual(log.records[0].levelname, 'INFO')
self.assertEqual(
log.records[0].getMessage(),
"POST successfully parsed for 'jsmith@email.com'",
)

def test_verify_POST(self):
"""Test POST verification process."""
params = dict(
secretkey='secret',
ccustname='fullname',
cverify='38CFCDED',
)
self.view._verify_POST(params)
self.assertTrue(True)

def test_parse_POST(self):
"""Test that POST parameters are correctly mirrored into member
fields.
"""
post_params = dict(
ccustname='fullname',
ccustemail='email',
ctransreceipt='payment_id',
cproditem='product_id',
cprodtitle='product_name',
ctransaffiliate='affiliate',
ctransaction='SALE',
)

expected = dict(
fullname=u'fullname',
email='email',
product_id='product_id',
product_name='product_name',
affiliate='affiliate',
payment_id='payment_id',
transaction_type='SALE',
)

result = self.view._parse_POST(post_params)
self.assertEqual(result, expected)

0 comments on commit 7c87834

Please sign in to comment.