From e826ecc83671a1d61d0d964030b090b1e4f88dc5 Mon Sep 17 00:00:00 2001 From: Arne Brutschy Date: Tue, 10 Jun 2014 09:41:49 +0200 Subject: [PATCH 1/3] Making overholt work with recent dependencies 1) update of tests - adjust model factories to new Factory-Boy - enable login system for recent Flask-Login (disabled by default for tests) - obtain CSRF token from login form using Flask-Fillin (old method didn't work anymore) 2) update of forms imports for new wtf 3) update all dependencies --- overholt/products/forms.py | 6 +-- overholt/stores/forms.py | 4 +- requirements.txt | 76 ++++++++++++++++++++------------------ tests/__init__.py | 12 ++++-- tests/factories.py | 47 +++++++++++++---------- tests/settings.py | 1 + tests/utils.py | 11 ------ 7 files changed, 83 insertions(+), 74 deletions(-) diff --git a/overholt/products/forms.py b/overholt/products/forms.py index 2e7adbf..cc417f4 100644 --- a/overholt/products/forms.py +++ b/overholt/products/forms.py @@ -5,9 +5,9 @@ Product forms """ - -from flask_wtf import Form, TextField, SelectMultipleField, Required, \ - Optional +from flask.ext.wtf import Form +from wtforms import TextField, SelectMultipleField +from wtforms.validators import Required, Optional from ..services import products diff --git a/overholt/stores/forms.py b/overholt/stores/forms.py index 4edf74c..2bc5ea6 100644 --- a/overholt/stores/forms.py +++ b/overholt/stores/forms.py @@ -6,7 +6,9 @@ Store forms """ -from flask_wtf import Form, TextField, Required, Optional +from flask.ext.wtf import Form +from wtforms import TextField +from wtforms.validators import Required, Optional __all__ = ['NewStoreForm', 'UpdateStoreForm'] diff --git a/requirements.txt b/requirements.txt index 7480fe4..0ecafa2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,41 +1,45 @@ Flask==0.10.1 -Flask-Assets==0.8 -Flask-Login==0.2.3 -Flask-Mail==0.7.3 -Flask-Principal==0.3.3 -Flask-SQLAlchemy==0.16 -Flask-Script==0.5.3 -Flask-Security==1.6.4 -Flask-WTF==0.8 -Jinja2==2.7 -Mako==0.8.1 -MarkupSafe==0.18 -MySQL-python==1.2.4 +Flask-Assets==0.9 +Flask-Login==0.2.11 +Flask-Mail==0.9.0 +Flask-Principal==0.4.0 +Flask-SQLAlchemy==1.0 +Flask-Script==2.0.5 +Flask-Security==1.7.2 +Flask-WTF==0.9.5 +Flask-fillin==0.2 +Jinja2==2.7.3 +Mako==1.0.0 +MarkupSafe==0.23 +MySQL-python==1.2.5 Pygments==1.6 -SQLAlchemy==0.8.1 -Sphinx==1.2b1 -WTForms==1.0.4 -Werkzeug==0.9.1 -alembic==0.5.0 -amqp==1.0.12 +SQLAlchemy==0.9.4 +Sphinx==1.2.2 +WTForms==2.0 +Werkzeug==0.9.6 +alembic==0.6.5 +amqp==1.4.5 anyjson==0.3.3 -billiard==2.7.3.30 -blinker==1.2 -celery==3.0.20 -cssmin==0.1.4 -distribute==0.6.34 -docutils==0.10 -factory-boy==1.3.0 -itsdangerous==0.21 -jsmin==2.0.3 -kombu==2.5.12 +argparse==1.2.1 +billiard==3.3.0.17 +blinker==1.3 +celery==3.1.11 +cssmin==0.2.0 +distribute==0.7.3 +docutils==0.11 +factory-boy==2.3.1 +itsdangerous==0.24 +jsmin==2.0.9 +kombu==3.0.18 +lxml==3.3.5 mock==1.0.1 -nose==1.3.0 -passlib==1.6.1 -python-dateutil==2.1 -redis==2.7.6 -simplejson==3.3.0 -six==1.3.0 -sphinxcontrib-httpdomain==1.1.8 -webassets==0.8 +nose==1.3.3 +passlib==1.6.2 +python-dateutil==2.2 +pytz==2014.4 +redis==2.10.1 +simplejson==3.5.2 +six==1.7.2 +sphinxcontrib-httpdomain==1.2.1 +webassets==0.9 wsgiref==0.1.2 diff --git a/tests/__init__.py b/tests/__init__.py index 8c55265..12c3d60 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -6,11 +6,13 @@ tests package """ +from flask.ext.fillin import FormWrapper +from flask.testing import FlaskClient from unittest import TestCase from overholt.core import db -from .factories import UserFactory +from .factories import UserFactory, RoleFactory from .utils import FlaskTestCaseMixin @@ -24,17 +26,17 @@ def _create_app(self): raise NotImplementedError def _create_fixtures(self): - self.user = UserFactory() + role = RoleFactory() + self.user = UserFactory(roles=[role]) def setUp(self): super(OverholtAppTestCase, self).setUp() self.app = self._create_app() - self.client = self.app.test_client() + self.client = FlaskClient(self.app, response_wrapper=FormWrapper) self.app_context = self.app.app_context() self.app_context.push() db.create_all() self._create_fixtures() - self._create_csrf_token() def tearDown(self): super(OverholtAppTestCase, self).tearDown() @@ -42,6 +44,8 @@ def tearDown(self): self.app_context.pop() def _login(self, email=None, password=None): + r = self.get('/login') + self.csrf_token = r.form.fields['csrf_token'] email = email or self.user.email password = password or 'password' return self.post('/login', data={'email': email, 'password': password}, diff --git a/tests/factories.py b/tests/factories.py index 9ebdcb9..48ecded 100644 --- a/tests/factories.py +++ b/tests/factories.py @@ -9,29 +9,32 @@ from datetime import datetime from factory import Factory, Sequence, LazyAttribute -from flask_security.utils import encrypt_password +from flask.ext.security.utils import encrypt_password from overholt.core import db from overholt.models import * -def create_sqlalchemy_model_function(class_to_create, *args, **kwargs): - entity = class_to_create(**kwargs) - db.session.add(entity) - db.session.commit() - return entity +class TestFactory(Factory): + @classmethod + def _create(cls, target_class, *args, **kwargs): + entity = target_class(**kwargs) + db.session.add(entity) + db.session.commit() + return entity -Factory.set_creation_function(create_sqlalchemy_model_function) +class RoleFactory(TestFactory): + class Meta: + model = Role - -class RoleFactory(Factory): - FACTORY_FOR = Role name = 'admin' description = 'Administrator' -class UserFactory(Factory): - FACTORY_FOR = User +class UserFactory(TestFactory): + class Meta: + model = User + email = Sequence(lambda n: 'user{0}@overholt.com'.format(n)) password = LazyAttribute(lambda a: encrypt_password('password')) last_login_at = datetime.utcnow() @@ -39,12 +42,14 @@ class UserFactory(Factory): last_login_ip = '127.0.0.1' current_login_ip = '127.0.0.1' login_count = 1 - roles = LazyAttribute(lambda _: [RoleFactory()]) + roles = [] active = True -class StoreFactory(Factory): - FACTORY_FOR = Store +class StoreFactory(TestFactory): + class Meta: + model = Store + name = Sequence(lambda n: 'Store Number {0}'.format(n)) address = '123 Overholt Alley' city = 'Overholt' @@ -52,11 +57,15 @@ class StoreFactory(Factory): zip_code = '12345' -class ProductFactory(Factory): - FACTORY_FOR = Product +class ProductFactory(TestFactory): + class Meta: + model = Product + name = Sequence(lambda n: 'Product Number {0}'.format(n)) -class CategoryFactory(Factory): - FACTORY_FOR = Category +class CategoryFactory(TestFactory): + class Meta: + model = Category + name = Sequence(lambda n: 'Category {0}'.format(n)) diff --git a/tests/settings.py b/tests/settings.py index 7f821fb..9553bfc 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -8,6 +8,7 @@ DEBUG = False TESTING = True +LOGIN_DISABLED = False SQLALCHEMY_POOL_SIZE = None SQLALCHEMY_POOL_TIMEOUT = None diff --git a/tests/utils.py b/tests/utils.py index 42612eb..7ab7a63 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -26,17 +26,6 @@ def get_auth_headers(username=None, password=None): class FlaskTestCaseMixin(object): - def _create_csrf_token(self): - csrf_key = 'csrf_token' - with self.client.session_transaction() as session: - session['csrf'] = csrf_key - secret_key = self.app.config['SECRET_KEY'] - expires = (datetime.now() + timedelta(minutes=30)).strftime('%Y%m%d%H%M%S') - csrf_build = '%s%s' % (csrf_key, expires) - csrf_token = csrf_build.encode('utf8') - csrf_hmac = hmac.new(secret_key, csrf_token, digestmod=sha1) - self.csrf_token = '%s##%s' % (expires, csrf_hmac.hexdigest()) - def _html_data(self, kwargs): if 'data' in kwargs: kwargs['data']['csrf_token'] = self.csrf_token From 4053008ca5c5da31660c44521cd444bf308d54e0 Mon Sep 17 00:00:00 2001 From: Arne Brutschy Date: Tue, 10 Jun 2014 20:17:07 +0200 Subject: [PATCH 2/3] flask.ext. -> flask_ --- manage.py | 2 +- overholt/manage/users.py | 2 +- overholt/products/forms.py | 2 +- overholt/settings.py | 6 ++++-- overholt/stores/forms.py | 2 +- tests/__init__.py | 2 +- tests/factories.py | 2 +- wsgi.py | 2 +- 8 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manage.py b/manage.py index d644b57..1000cf2 100644 --- a/manage.py +++ b/manage.py @@ -6,7 +6,7 @@ Manager module """ -from flask.ext.script import Manager +from flask_script import Manager from overholt.api import create_app from overholt.manage import CreateUserCommand, DeleteUserCommand, ListUsersCommand diff --git a/overholt/manage/users.py b/overholt/manage/users.py index c2dc88e..ceb9039 100644 --- a/overholt/manage/users.py +++ b/overholt/manage/users.py @@ -7,7 +7,7 @@ """ from flask import current_app -from flask.ext.script import Command, prompt, prompt_pass +from flask_script import Command, prompt, prompt_pass from flask_security.forms import RegisterForm from flask_security.registerable import register_user from werkzeug.datastructures import MultiDict diff --git a/overholt/products/forms.py b/overholt/products/forms.py index cc417f4..a9e859f 100644 --- a/overholt/products/forms.py +++ b/overholt/products/forms.py @@ -5,7 +5,7 @@ Product forms """ -from flask.ext.wtf import Form +from flask_wtf import Form from wtforms import TextField, SelectMultipleField from wtforms.validators import Required, Optional diff --git a/overholt/settings.py b/overholt/settings.py index f7a2949..d3e4e24 100644 --- a/overholt/settings.py +++ b/overholt/settings.py @@ -9,8 +9,10 @@ DEBUG = True SECRET_KEY = 'super-secret-key' -SQLALCHEMY_DATABASE_URI = 'mysql://root@33.33.33.10:3306/overholt' -CELERY_BROKER_URL = 'redis://33.33.33.10:6379/0' +import os +basedir = os.path.abspath(os.path.dirname(__file__)) +SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db') +CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0' MAIL_DEFAULT_SENDER = 'info@overholt.com' MAIL_SERVER = 'smtp.postmarkapp.com' diff --git a/overholt/stores/forms.py b/overholt/stores/forms.py index 2bc5ea6..25fb65f 100644 --- a/overholt/stores/forms.py +++ b/overholt/stores/forms.py @@ -6,7 +6,7 @@ Store forms """ -from flask.ext.wtf import Form +from flask_wtf import Form from wtforms import TextField from wtforms.validators import Required, Optional diff --git a/tests/__init__.py b/tests/__init__.py index 12c3d60..55a5cb6 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -6,7 +6,7 @@ tests package """ -from flask.ext.fillin import FormWrapper +from flask_fillin import FormWrapper from flask.testing import FlaskClient from unittest import TestCase diff --git a/tests/factories.py b/tests/factories.py index 48ecded..3a23211 100644 --- a/tests/factories.py +++ b/tests/factories.py @@ -9,7 +9,7 @@ from datetime import datetime from factory import Factory, Sequence, LazyAttribute -from flask.ext.security.utils import encrypt_password +from flask_security.utils import encrypt_password from overholt.core import db from overholt.models import * diff --git a/wsgi.py b/wsgi.py index 9df676e..d4b2eed 100644 --- a/wsgi.py +++ b/wsgi.py @@ -16,4 +16,4 @@ }) if __name__ == "__main__": - run_simple('0.0.0.0', 5000, application, use_reloader=True, use_debugger=True) + run_simple('0.0.0.0', 5001, application, use_reloader=True, use_debugger=True) From 1d4041150281cd2c52b89bcb8243a2a4295fabac Mon Sep 17 00:00:00 2001 From: Arne Brutschy Date: Sat, 14 Jun 2014 00:16:59 +0200 Subject: [PATCH 3/3] Making overholt work with recent dependencies 1) update of tests - adjust model factories to new Factory-Boy - enable login system for recent Flask-Login (disabled by default for tests) - obtain CSRF token from login form using Flask-Fillin (old method didn't work anymore) 2) update of forms imports for new wtf 3) update all dependencies 4) flask.ext. -> flask_ --- overholt/settings.py | 6 ++---- wsgi.py | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/overholt/settings.py b/overholt/settings.py index d3e4e24..f7a2949 100644 --- a/overholt/settings.py +++ b/overholt/settings.py @@ -9,10 +9,8 @@ DEBUG = True SECRET_KEY = 'super-secret-key' -import os -basedir = os.path.abspath(os.path.dirname(__file__)) -SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db') -CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0' +SQLALCHEMY_DATABASE_URI = 'mysql://root@33.33.33.10:3306/overholt' +CELERY_BROKER_URL = 'redis://33.33.33.10:6379/0' MAIL_DEFAULT_SENDER = 'info@overholt.com' MAIL_SERVER = 'smtp.postmarkapp.com' diff --git a/wsgi.py b/wsgi.py index d4b2eed..9df676e 100644 --- a/wsgi.py +++ b/wsgi.py @@ -16,4 +16,4 @@ }) if __name__ == "__main__": - run_simple('0.0.0.0', 5001, application, use_reloader=True, use_debugger=True) + run_simple('0.0.0.0', 5000, application, use_reloader=True, use_debugger=True)