Skip to content

Commit

Permalink
Starter for a new version of the pledge API, which will be tested and
Browse files Browse the repository at this point in the history
more RESTful.
  • Loading branch information
hjfreyer committed May 23, 2014
1 parent 12cb17c commit 829ae2f
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 1 deletion.
91 changes: 91 additions & 0 deletions backend/handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
"""Handlers for MayOne.US."""

from collections import namedtuple
import json
import logging
import webapp2

import validictory

# Immutable environment with both configuration variables, and backends to be
# mocked out in tests.
Environment = namedtuple(
'Environment',
[
# AppEngine app name.
'app_name',

# Stripe creds to export.
'stripe_public_key',

# PaymentProcessor
'payment_processor',

# MailingListSubscriber
'mailing_list_subscriber',
])


class PaymentProcessor(object):
"""Interface which processes payments."""
def CreateCustomer(self, payment_params, pledge_model):
"""Does whatever the payment processor needs to do in order to be able to
charge the customer later.
Args:
payment_params: dict with keys like 'paypal' or 'stripe', with values
which are dicts with parameters specific to that payment platform.
pledge_model: A not-yet-committed pledge model for us to modify to include
a record of the customer.
"""
raise NotImplementedError()


class MailingListSubscriber(object):
"""Interface which signs folks up for emails."""
def Subscribe(self, first_name, last_name, amount_cents, ip_addr, time,
source):
raise NotImplementedError()


_STR = dict(type='string')
class PledgeHandler(webapp2.RequestHandler):
CREATE_SCHEMA = dict(
type='object',
properties=dict(
email=_STR,
phone=dict(type='string', blank=True),
firstName=_STR,
lastName=_STR,
occupation=_STR,
employer=_STR,
target=_STR,
subscribe=dict(type='boolean'),
amountCents=dict(type='integer', minimum=100)
)
)

def post(self):
try:
data = json.loads(self.request.body)
except ValueError, e:
logging.warning('Bad JSON request: %s', e)
self.error(400)
self.response.write('Invalid request')
return

try:
validictory.validate(data, PledgeHandler.CREATE_SCHEMA)
except ValueError, e:
logging.warning('Schema check failed: %s', e)
self.error(400)
self.response.write('Invalid request')
return

self.response.headers['Content-Type'] = 'application/json'
json.dump(dict(id='2'), self.response)


HANDLERS = [
('/r/pledge', PledgeHandler),
]
3 changes: 2 additions & 1 deletion backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from google.appengine.ext import db
from google.appengine.ext import deferred

import handlers
import model
import stripe
import wp_import
Expand Down Expand Up @@ -226,4 +227,4 @@ def post(self, url_nonce):
('/contact.do', ContactHandler),
# See wp_import
# ('/import.do', wp_import.ImportHandler),
], debug=False)
] + handlers.HANDLERS, debug=False)
48 changes: 48 additions & 0 deletions unittests/test_e2e.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import unittest
import logging
#from datetime import datetime, timedelta

#from google.appengine.api import memcache
from google.appengine.ext import ndb
from google.appengine.ext import testbed

import webtest
import webapp2
from backend import handlers
from backend import model

class BaseTest(unittest.TestCase):
def setUp(self):
self.testbed = testbed.Testbed()
self.testbed.activate()

self.testbed.init_datastore_v3_stub()

self.app = webtest.TestApp(webapp2.WSGIApplication(handlers.HANDLERS))

def tearDown(self):
self.testbed.deactivate()

class PledgeTest(BaseTest):
SAMPLE_USER = dict(
email='pika@pokedex.biz',
phone='212-234-5432',
firstName='Pika',
lastName='Chu',
occupation=u'Pok\u00E9mon',
employer='Nintendo',
target='Republicans Only',
subscribe=False,
amountCents=4200)

def testBadJson(self):
self.app.post('/r/pledge', '{foo', status=400)

def testNotEnoughJson(self):
self.app.post_json('/r/pledge', dict(email='foo@bar.com'), status=400)

def testCreateAddsPledge(self):
resp = self.app.post_json('/r/pledge', PledgeTest.SAMPLE_USER)

pledge = model.Pledge.get_by_key_name(resp.json['id'])
self.assertIsNotNone(pledge)

0 comments on commit 829ae2f

Please sign in to comment.