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:
parent
4d7794962b
commit
aee25e1572
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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'
|
||||
|
|
22
manage.py
22
manage.py
|
@ -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__":
|
||||
|
|
|
@ -2,6 +2,7 @@ flask
|
|||
flask-script
|
||||
flask-sqlalchemy
|
||||
flask-migrate
|
||||
flask-testing
|
||||
requests==2.0.0
|
||||
paste
|
||||
gunicorn
|
||||
|
|
|
@ -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()
|
|
@ -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'}
|
||||
)
|
Loading…
Reference in New Issue