refactor tests into toplevel folder. Tests can now be run with 'python -m unittest discover' from the root. Removed conditional test code in favor of patching. Created base FormspreeTestCase class that can be subclassed to create new test classes

This commit is contained in:
Cole Krumbholz 2015-01-22 01:54:46 -05:00
parent 4d7794962b
commit aee25e1572
8 changed files with 76 additions and 60 deletions

View File

@ -2,18 +2,25 @@ import flask
from flask import g
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.login import LoginManager, current_user
import fakeredis, redis
import redis
import settings
DB = SQLAlchemy()
if settings.TESTING:
REDIS = fakeredis.FakeStrictRedis()
else:
REDIS = redis.StrictRedis.from_url(settings.REDIS_URL)
import routes
from users.models import User
DB = SQLAlchemy()
_redis = None
def REDIS():
''' function to acquire the global redis connection '''
global _redis
if not _redis:
_redis = get_redis()
return _redis
def get_redis():
''' this may be overridden, for example to setup testing '''
return redis.StrictRedis.from_url(settings.REDIS_URL)
def configure_login(app):
login_manager = LoginManager()
login_manager.init_app(app)

View File

@ -104,15 +104,15 @@ class Form(DB.Model):
basedate = basedate or datetime.datetime.now()
month = basedate.month
key = MONTHLY_COUNTER_KEY(form_id=self.id, month=month)
counter = REDIS.get(key) or 0
counter = REDIS().get(key) or 0
return int(counter)
def increase_monthly_counter(self, basedate=None):
basedate = basedate or datetime.datetime.now()
month = basedate.month
key = MONTHLY_COUNTER_KEY(form_id=self.id, month=month)
REDIS.incr(key)
REDIS.expireat(key, unix_time_for_12_months_from_now(basedate))
REDIS().incr(key)
REDIS().expireat(key, unix_time_for_12_months_from_now(basedate))
@staticmethod
def send_confirmation(email, host):

View File

@ -8,14 +8,12 @@ DEBUG = os.getenv('DEBUG') in ['True', 'true', '1', 'yes']
if DEBUG:
SQLALCHEMY_ECHO = True
TESTING = True if 'test' in sys.argv else False
TEST_DATABASE = os.getenv('TEST_DATABASE_URL')
SQLALCHEMY_DATABASE_URI = TEST_DATABASE if TESTING else os.getenv('DATABASE_URL')
SQLALCHEMY_DATABASE_URI = os.getenv('DATABASE_URL')
LOG_LEVEL = os.getenv('LOG_LEVEL') or 'debug'
NONCE_SECRET = os.getenv('NONCE_SECRET')
MONTHLY_SUBMISSIONS_LIMIT = 2 if TESTING else int(os.getenv('MONTHLY_SUBMISSIONS_LIMIT') or 1000)
MONTHLY_SUBMISSIONS_LIMIT = int(os.getenv('MONTHLY_SUBMISSIONS_LIMIT') or 1000)
REDIS_URL = os.getenv('REDISTOGO_URL')
SERVICE_NAME = os.getenv('SERVICE_NAME') or 'Forms'

View File

@ -1,39 +1,27 @@
import datetime
from flask.ext.script import Manager, prompt_bool
from flask.ext.migrate import Migrate, MigrateCommand, upgrade
from flask.ext.migrate import Migrate, MigrateCommand
from formspree import create_app, app
from formspree.app import REDIS
from formspree.forms.helpers import MONTHLY_COUNTER_KEY
from formspree.forms.models import Form
forms_app = create_app()
manager = Manager(forms_app)
# add flask-migrate commands
Migrate(forms_app, app.DB)
manager.add_command('db', MigrateCommand)
@manager.command
def run_debug(port=5000):
'''runs the app with debug flag set to true'''
forms_app.run(host='0.0.0.0', debug=True, port=int(port))
@manager.command
def test():
import unittest
from formspree.tests import form_posts
from formspree.settings import TEST_DATABASE
assert TEST_DATABASE, "Please configure environment variable: TEST_DATABASE_URL with test database."
print "Launching tests:"
upgrade()
suite = unittest.TestLoader().loadTestsFromTestCase(form_posts.FormPostsTestCase)
unittest.TextTestRunner(verbosity=2).run(suite)
@manager.option('-H', '--host', dest='host', default=None, help='referer hostname')
@manager.option('-e', '--email', dest='email', default=None, help='form email')
@ -41,7 +29,6 @@ def unsubscribe(email, host):
''' Unsubscribes an email by resetting the form to unconfirmed. User may get
one more confirmation email, but if she doesn't confirm that will be it.'''
from formspree.forms.models import Form
form = None
if email and host:
@ -72,6 +59,7 @@ def unsubscribe(email, host):
app.DB.session.commit()
print 'success.'
@manager.option('-i', '--id', dest='id', default=None, help='form id')
@manager.option('-H', '--host', dest='host', default=None, help='referer hostname')
@manager.option('-e', '--email', dest='email', default=None, help='form email')
@ -89,7 +77,7 @@ def monthly_counters(email=None, host=None, id=None, month=datetime.date.today()
return 1
for form in query:
nsubmissions = REDIS.get(MONTHLY_COUNTER_KEY(form_id=form.id, month=month)) or 0
nsubmissions = REDIS().get(MONTHLY_COUNTER_KEY(form_id=form.id, month=month)) or 0
print '%s submissions for %s' % (nsubmissions, form)
if __name__ == "__main__":

View File

@ -2,6 +2,7 @@ flask
flask-script
flask-sqlalchemy
flask-migrate
flask-testing
requests==2.0.0
paste
gunicorn

View File

@ -0,0 +1,34 @@
import os
import fakeredis
from flask.ext.testing import TestCase
import formspree
from formspree import create_app
from formspree import settings
from formspree.app import DB, REDIS
class FormspreeTestCase(TestCase):
@classmethod
def setUpClass(cls):
''' configures app for testing '''
formspree.app.get_redis = lambda : fakeredis.FakeStrictRedis()
settings.MONTHLY_SUBMISSIONS_LIMIT = 2
settings.SQLALCHEMY_DATABASE_URI = os.getenv('TEST_DATABASE_URL')
def create_app(self):
app = create_app()
return app
def setUp(self):
self.assertNotEqual(settings.SQLALCHEMY_DATABASE_URI, os.getenv('DATABASE_URL'))
self.assertEqual(type(REDIS()), fakeredis.FakeStrictRedis)
self.tearDown()
DB.create_all()
def tearDown(self):
DB.session.remove()
DB.drop_all()
REDIS().flushdb()

View File

@ -1,39 +1,27 @@
import os
import unittest
import httpretty
from formspree import create_app, app
from formspree import settings
from formspree.app import DB, REDIS
from formspree.app import DB
from formspree.forms.models import Form
from formspree_test_case import FormspreeTestCase
ajax_headers = {
'Referer': 'example.com',
'X_REQUESTED_WITH': 'xmlhttprequest'
}
test_app = create_app()
client = test_app.test_client()
class FormPostsTestCase(unittest.TestCase):
def setUp(self):
self.tearDown()
DB.create_all()
def tearDown(self):
DB.session.remove()
DB.drop_all()
REDIS.flushdb()
class FormPostsTestCase(FormspreeTestCase):
def test_index_page(self):
r = client.get('/')
r = self.client.get('/')
self.assertEqual(200, r.status_code)
@httpretty.activate
def test_submit_form(self):
httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json')
r = client.post('/alice@example.com',
self.client.post('/alice@example.com',
headers = ajax_headers,
data={'name': 'alice'}
)
@ -42,7 +30,7 @@ class FormPostsTestCase(unittest.TestCase):
@httpretty.activate
def test_second_form(self):
httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json')
r = client.post('/bob@example.com',
self.client.post('/bob@example.com',
headers = ajax_headers,
data={'name': 'bob'}
)
@ -51,7 +39,7 @@ class FormPostsTestCase(unittest.TestCase):
def test_fail_form_submission(self):
no_referer = ajax_headers.copy()
del no_referer['Referer']
r = client.post('/bob@example.com',
r = self.client.post('/bob@example.com',
headers = no_referer,
data={'name': 'bob'}
)
@ -60,7 +48,7 @@ class FormPostsTestCase(unittest.TestCase):
@httpretty.activate
def test_activation_workflow(self):
httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json')
r = client.post('/bob@example.com',
r = self.client.post('/bob@example.com',
headers = ajax_headers,
data={'name': 'bob'}
)
@ -73,7 +61,7 @@ class FormPostsTestCase(unittest.TestCase):
self.assertEqual(f.get_monthly_counter(), 0) # monthly submissions also 0
# form has another submission, number of forms in the table should increase?
r = client.post('/bob@example.com',
r = self.client.post('/bob@example.com',
headers = ajax_headers,
data={'name': 'bob'}
)
@ -89,13 +77,13 @@ class FormPostsTestCase(unittest.TestCase):
self.assertEqual(f.owner_id, None)
# test clicking of activation link
client.get('/confirm/%s' % (f.hash,))
self.client.get('/confirm/%s' % (f.hash,))
f = Form.query.first()
self.assertEqual(f.confirmed, True)
# a third submission should now increase the counter
r = client.post('/bob@example.com',
r = self.client.post('/bob@example.com',
headers = ajax_headers,
data={'name': 'bob'}
)
@ -118,7 +106,7 @@ class FormPostsTestCase(unittest.TestCase):
self.assertEqual(settings.MONTHLY_SUBMISSIONS_LIMIT, 2)
# manually verify luke@example.com
r = client.post('/luke@example.com',
r = self.client.post('/luke@example.com',
headers = ajax_headers,
data={'name': 'luke'}
)
@ -130,7 +118,7 @@ class FormPostsTestCase(unittest.TestCase):
# first submission
httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json')
r = client.post('/luke@example.com',
r = self.client.post('/luke@example.com',
headers = ajax_headers,
data={'name': 'peter'}
)
@ -139,7 +127,7 @@ class FormPostsTestCase(unittest.TestCase):
# second submission
httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json')
r = client.post('/luke@example.com',
r = self.client.post('/luke@example.com',
headers = ajax_headers,
data={'name': 'ana'}
)
@ -148,7 +136,7 @@ class FormPostsTestCase(unittest.TestCase):
# third submission, now we're over the limit
httpretty.register_uri(httpretty.POST, 'https://api.sendgrid.com/api/mail.send.json')
r = client.post('/luke@example.com',
r = self.client.post('/luke@example.com',
headers = ajax_headers,
data={'name': 'maria'}
)