From f88b1039e5fcbc1292b8d314f591e30306076bbc Mon Sep 17 00:00:00 2001 From: "Thiago J. Barbalho" Date: Sun, 23 Aug 2020 20:07:14 -0300 Subject: [PATCH 1/5] Pin dependency versions --- .gitignore | 1 + requirements.dev.txt | 38 +++++++++++++++--------------- requirements.txt | 55 ++++++++++++++++++++++---------------------- 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index 57258e7..fdba009 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ __pycache__ .idea .coverage* anenv +venv/ coverage.xml docs/_build/ junit.xml diff --git a/requirements.dev.txt b/requirements.dev.txt index 1c8d7b1..34397a3 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -1,20 +1,20 @@ -Flask-SQLAlchemy -mypy -mock -ipdb -pep8 -pytest -pytest-cache -pytest-cov -pytest-flask -pytest-mock -pytest-mccabe -pytest-pep8 -pytest-pylint -pytest-timeout -pytest-watch -pytest-xdist -sqlalchemy_pytest_fixtures -twine -wheel +Flask-SQLAlchemy==2.4.0 +mypy==0.711 +mock==4.0.2 +ipdb==0.12 +pep8==1.7.1 +pytest==6.0.1 +pytest-cache==1.0 +pytest-cov==2.7.1 +pytest-flask==0.15.0 +pytest-mock==1.10.4 +pytest-mccabe==0.1 +pytest-pep8==1.0.6 +pytest-pylint==0.14.0 +pytest-timeout==1.3.3 +pytest-watch==4.2.0 +pytest-xdist==1.29.0 +sqlalchemy_pytest_fixtures==0.3.0 +twine==1.13.0 +wheel==0.35.1 -r requirements.txt diff --git a/requirements.txt b/requirements.txt index e49bad0..d5d4623 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,28 +1,29 @@ -alembic -bcrypt -click -dnspython -feedparser -Flask -flask_admin -flask-bootstrap -Flask-Caching -flask-debugtoolbar -Flask-Gravatar -flask_limiter -flask-nav +alembic==1.0.11 +bcrypt==3.1.7 +click==7.0 +dnspython==1.16.0 +feedparser==5.2.1 +Flask==1.1.1 +flask_admin==1.5.3 +flask-bootstrap==3.3.7.1 +Flask-Caching==1.7.2 +flask-debugtoolbar==0.10.1 +Flask-Gravatar==0.5.0 +flask_limiter==1.0.1 +Flask-Login==0.4.1 +flask-nav==0.6 Flask-Security-Fork==2.0.1 -flask_sqlalchemy_session -Flask-WTF -ghdiff -numpy -pandas -psycopg2 -python-dotenv -python-slugify -pyquery -pygments -pq -scikit-learn -scipy -sphinx +Flask-SQLAlchemy-Session==1.1 +Flask-WTF==0.14.2 +ghdiff==0.4 +numpy==1.19.1 +pandas==1.1.1 +psycopg2==2.8.3 +python-dotenv==0.10.3 +python-slugify==3.0.2 +pyquery==1.4.0 +Pygments==2.4.2 +pq==1.8.0 +Sphinx==2.1.2 +Werkzeug==0.16 +wtforms==2.2.1 From 0bb77379314bc4009d4e91a0ab41c3c601b1dd6d Mon Sep 17 00:00:00 2001 From: "Thiago J. Barbalho" Date: Tue, 25 Aug 2020 11:38:14 -0300 Subject: [PATCH 2/5] Add missing dependency --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index d5d4623..6134c91 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,6 +24,7 @@ python-slugify==3.0.2 pyquery==1.4.0 Pygments==2.4.2 pq==1.8.0 +scikit-learn==0.21.3 Sphinx==2.1.2 Werkzeug==0.16 wtforms==2.2.1 From 40639a5650143169473bbf7198a2b7cf5de46c1d Mon Sep 17 00:00:00 2001 From: "Thiago J. Barbalho" Date: Mon, 31 Aug 2020 19:48:20 -0300 Subject: [PATCH 3/5] Update versions --- requirements.dev.txt | 27 +++++++++++++++------------ requirements.txt | 41 +++++++++++++++++++++-------------------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/requirements.dev.txt b/requirements.dev.txt index 34397a3..47138d7 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -1,19 +1,22 @@ -Flask-SQLAlchemy==2.4.0 -mypy==0.711 -mock==4.0.2 -ipdb==0.12 +attrs==17.4.0 +Flask-SQLAlchemy==2.3.2 +mypy==0.560 +mock==2.0.0 +ipdb==0.11 pep8==1.7.1 -pytest==6.0.1 +pylint==1.8.2 +pytest==3.4.0 pytest-cache==1.0 -pytest-cov==2.7.1 -pytest-flask==0.15.0 -pytest-mock==1.10.4 +pytest-cov==2.5.1 +pytest-flask==0.10.0 +pytest-forked==0.2 pytest-mccabe==0.1 +pytest-mock==1.7.0 pytest-pep8==1.0.6 -pytest-pylint==0.14.0 -pytest-timeout==1.3.3 -pytest-watch==4.2.0 -pytest-xdist==1.29.0 +pytest-pylint==0.8.0 +pytest-timeout==1.2.1 +pytest-watch==4.1.0 +pytest-xdist==1.22.1 sqlalchemy_pytest_fixtures==0.3.0 twine==1.13.0 wheel==0.35.1 diff --git a/requirements.txt b/requirements.txt index 6134c91..49d0bc8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,30 +1,31 @@ -alembic==1.0.11 -bcrypt==3.1.7 -click==7.0 -dnspython==1.16.0 +alembic==0.9.8 +bcrypt==3.1.4 +click==6.7 +dnspython==1.15.0 feedparser==5.2.1 -Flask==1.1.1 -flask_admin==1.5.3 -flask-bootstrap==3.3.7.1 -Flask-Caching==1.7.2 -flask-debugtoolbar==0.10.1 +Flask==0.12.2 +Flask-Admin==1.5.0 +Flask-Bootstrap==3.3.7.1 +Flask-Caching==1.3.3 +Flask-DebugToolbar==0.10.1 Flask-Gravatar==0.5.0 -flask_limiter==1.0.1 +Flask_Limiter==1.0.1 Flask-Login==0.4.1 flask-nav==0.6 Flask-Security-Fork==2.0.1 Flask-SQLAlchemy-Session==1.1 Flask-WTF==0.14.2 ghdiff==0.4 -numpy==1.19.1 -pandas==1.1.1 -psycopg2==2.8.3 -python-dotenv==0.10.3 -python-slugify==3.0.2 +numpy==1.14.0 +pandas==0.22.0 +psycopg2==2.7.4 +python-dotenv==0.9.1 +python-slugify==1.2.5 pyquery==1.4.0 Pygments==2.4.2 -pq==1.8.0 -scikit-learn==0.21.3 -Sphinx==2.1.2 -Werkzeug==0.16 -wtforms==2.2.1 +pq==1.5 +psutil==5.4.3 +scikit-learn==0.19.1 +Sphinx==1.8.4 +Werkzeug==0.14.1 +WTForms==2.1 From f6a9085f86cdefe8747b27c4cb83897995447b40 Mon Sep 17 00:00:00 2001 From: "Thiago J. Barbalho" Date: Mon, 31 Aug 2020 20:58:38 -0300 Subject: [PATCH 4/5] Bump pytest-flask==0.15 --- requirements.dev.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.dev.txt b/requirements.dev.txt index 47138d7..04e9306 100644 --- a/requirements.dev.txt +++ b/requirements.dev.txt @@ -8,7 +8,7 @@ pylint==1.8.2 pytest==3.4.0 pytest-cache==1.0 pytest-cov==2.5.1 -pytest-flask==0.10.0 +pytest-flask==0.15.0 pytest-forked==0.2 pytest-mccabe==0.1 pytest-mock==1.7.0 From 83833b52b3274eadc6d106631962bb42c9c8047e Mon Sep 17 00:00:00 2001 From: "Thiago J. Barbalho" Date: Mon, 31 Aug 2020 21:17:56 -0300 Subject: [PATCH 5/5] Add user fixtures --- pygameweb/fixtures.py | 41 +++++ pygameweb/user/fixtures/fixtures.yml | 152 ++++++++++++++++++ requirements.txt | 1 + setup.py | 2 + .../pygameweb/fixtures/test_user_fixtures.py | 31 ++++ 5 files changed, 227 insertions(+) create mode 100644 pygameweb/fixtures.py create mode 100644 pygameweb/user/fixtures/fixtures.yml create mode 100644 tests/functional/pygameweb/fixtures/test_user_fixtures.py diff --git a/pygameweb/fixtures.py b/pygameweb/fixtures.py new file mode 100644 index 0000000..2a1062f --- /dev/null +++ b/pygameweb/fixtures.py @@ -0,0 +1,41 @@ +""" Populates the database with sample data +""" +import yaml +from flask_sqlalchemy_session import current_session + +from pygameweb.user.models import User, Group +from pygameweb.app import create_app + + +def _user_fixtures(fixture='pygameweb/user/fixtures/fixtures.yml'): + """ Adds user fixtures. + """ + with open(fixture, 'r') as f: + data = yaml.load(f, Loader=yaml.SafeLoader) + current_session.bulk_insert_mappings(Group, data['groups']) + current_session.bulk_insert_mappings(User, data['users']) + current_session.commit() + + # Apply roles to users + for user_data in data['users']: + user = current_session.query(User).get(user_data['id']) + for role in user_data['roles']: + group = current_session.query(Group) \ + .filter_by(name=role).first() + user.roles.append(group) + current_session.add(user) + current_session.commit() + + +# Note: `make_app` is used in tests.fixtures for testing +def populate_db(make_app=create_app): + """ Adds fixtures to database. Useful for testing locally. + """ + app = make_app('pygameweb.config.Config') + # Avoid accidentally running this in production + if app.config['ENV'] == 'production': + raise RuntimeError('Please enable development mode. ' + 'Are you running in production?') + with app.app_context(): + _user_fixtures() + app.logger.info('Fixtures added to database.') diff --git a/pygameweb/user/fixtures/fixtures.yml b/pygameweb/user/fixtures/fixtures.yml new file mode 100644 index 0000000..8d8ec67 --- /dev/null +++ b/pygameweb/user/fixtures/fixtures.yml @@ -0,0 +1,152 @@ +# Define roles +groups: + - id: 1 + name: newbie + title: Newbie + orders: 1 + description: null + + - id: 2 + name: commenter + title: Commenter + orders: 11 + description: null + + - id: 3 + name: moderator + title: Moderator + orders: 3 + description: null + + - id: 4 + name: members + title: Members + orders: 4 + description: null + + - id: 5 + name: admin + title: Admin + orders: 5 + description: null + + +# Define an admin, newbie, member, moderator and a blcoked user +# password is 'password' for all users +users: + - id: 1 + name: admin + email: admin@example.com + password: $2b$12$0hsnVl3JrOLMKZ1UgTWMqe7fKoj5ybZytIdNdN7FRk9SeRNclqbzK + title: Superuser + disabled: 0 + super: 1 + roles: + - admin + - members + - moderator + active: 1 + confirmed_at: !!timestamp 2020-01-01 + last_login_at: !!timestamp 2020-01-01 + current_login_at: null + last_login_ip: null + current_login_ip: null + login_count: null + registered_at: !!timestamp 2020-01-01 00:00:00 + registered_ip: 127.0.0.1 + twitter_user: null + github_user: null + bitbucket_user: null + blog_url: null + + - id: 2 + name: newbie + email: newbie@example.com + password: $2b$12$0hsnVl3JrOLMKZ1UgTWMqe7fKoj5ybZytIdNdN7FRk9SeRNclqbzK + title: Newbie User + disabled: 0 + super: 0 + active: 1 + roles: + - newbie + confirmed_at: !!timestamp 2020-01-01 + last_login_at: !!timestamp 2020-01-01 + current_login_at: null + last_login_ip: null + current_login_ip: null + login_count: null + registered_at: !!timestamp 2020-01-01 00:00:00 + registered_ip: 127.0.0.1 + twitter_user: null + github_user: null + bitbucket_user: null + blog_url: null + + - id: 3 + name: user + email: user@example.com + password: $2b$12$0hsnVl3JrOLMKZ1UgTWMqe7fKoj5ybZytIdNdN7FRk9SeRNclqbzK + title: Regular User + disabled: 0 + super: 0 + active: 1 + roles: + - members + confirmed_at: !!timestamp 2020-01-01 + last_login_at: !!timestamp 2020-01-01 + current_login_at: null + last_login_ip: null + current_login_ip: null + login_count: null + registered_at: !!timestamp 2020-01-01 00:00:00 + registered_ip: 127.0.0.1 + twitter_user: null + github_user: null + bitbucket_user: null + blog_url: null + + - id: 4 + name: moderator + email: moderator@example.com + password: $2b$12$0hsnVl3JrOLMKZ1UgTWMqe7fKoj5ybZytIdNdN7FRk9SeRNclqbzK + title: Moderator User + disabled: 0 + super: 0 + active: 1 + roles: + - moderator + confirmed_at: !!timestamp 2020-01-01 + last_login_at: !!timestamp 2020-01-01 + current_login_at: null + last_login_ip: null + current_login_ip: null + login_count: null + registered_at: !!timestamp 2020-01-01 00:00:00 + registered_ip: 127.0.0.1 + twitter_user: null + github_user: null + bitbucket_user: null + blog_url: null + + - id: 5 + name: blocked_user + email: blocked_user@example.com + password: $2b$12$0hsnVl3JrOLMKZ1UgTWMqe7fKoj5ybZytIdNdN7FRk9SeRNclqbzK + title: Blocked User + disabled: 1 + super: 0 + active: 1 + roles: + - members + confirmed_at: !!timestamp 2020-01-01 + last_login_at: !!timestamp 2020-01-01 + current_login_at: null + last_login_ip: null + current_login_ip: null + login_count: null + registered_at: !!timestamp 2020-01-01 00:00:00 + registered_ip: 127.0.0.1 + twitter_user: null + github_user: null + bitbucket_user: null + blog_url: null diff --git a/requirements.txt b/requirements.txt index 49d0bc8..3c7cf4d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -25,6 +25,7 @@ pyquery==1.4.0 Pygments==2.4.2 pq==1.5 psutil==5.4.3 +pyyaml==5.3.1 scikit-learn==0.19.1 Sphinx==1.8.4 Werkzeug==0.14.1 diff --git a/setup.py b/setup.py index ee96f4f..f7aca7a 100644 --- a/setup.py +++ b/setup.py @@ -82,6 +82,8 @@ def get_requirements(): 'pygameweb.builds.update_version_from_git:release_version_correct', 'pygameweb_github_releases=' 'pygameweb.project.gh_releases:sync_github_releases', + 'pygameweb_fixtures=' + + 'pygameweb.fixtures:populate_db', ], }, ) diff --git a/tests/functional/pygameweb/fixtures/test_user_fixtures.py b/tests/functional/pygameweb/fixtures/test_user_fixtures.py new file mode 100644 index 0000000..9f320db --- /dev/null +++ b/tests/functional/pygameweb/fixtures/test_user_fixtures.py @@ -0,0 +1,31 @@ +import pytest + +from pygameweb.fixtures import populate_db +from pygameweb.user.models import User, Group, users_groups + + +def test_populate_db(app, session): + """ Ensures the populate_db adds sample data. + """ + assert session.query(Group).count() == 0 + assert session.query(User).count() == 0 + + app.config['ENV'] = 'development' + populate_db(make_app=lambda x: app) + assert session.query(Group).count() == 5 + assert session.query(User).count() == 5 + + # Makes sure the admin is really admin + assert 1 == session.query(users_groups) \ + .filter_by(users_id=1, groups_id=5).count() + + +def test_populate_db_production(app, session): + """ Ensures the populate_db won't work in production. + """ + app.config['ENV'] = 'production' + with pytest.raises(RuntimeError): + populate_db(make_app=lambda x: app) + + assert session.query(Group).count() == 0 + assert session.query(User).count() == 0