-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Starter for a new version of the pledge API, which will be tested and
more RESTful.
- Loading branch information
Showing
3 changed files
with
141 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |