From 8c8323308bd276e0860159e925e80e1ed1d648b5 Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Tue, 8 Feb 2022 14:38:13 +0100 Subject: [PATCH 01/11] Bump pytest to 7.0.0 and drop deprecated pytest-runner --- pytest.ini | 3 +++ requirements.txt | 3 +-- setup.py | 13 +------------ 3 files changed, 5 insertions(+), 14 deletions(-) create mode 100644 pytest.ini diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 00000000..3be22c69 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +markers = + mvp: mark tests as required by MVP diff --git a/requirements.txt b/requirements.txt index 5996c1c1..89155f83 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,8 +16,7 @@ marshmallow==3.0.0b11 marshmallow-enum==1.4.1 passlib==1.7.1 phonenumbers==8.9.11 -pytest==3.7.2 -pytest-runner==4.2 +pytest==7.0.0 python-dateutil==2.7.3 python-stdnum==1.9 PyYAML==5.4 diff --git a/setup.py b/setup.py index 6a0db9b9..287cf651 100644 --- a/setup.py +++ b/setup.py @@ -3,11 +3,6 @@ from setuptools import find_packages, setup from ereuse_devicehub import __version__ -test_requires = [ - 'pytest', - 'requests_mock' -] - setup( name='ereuse-devicehub', version=__version__, @@ -52,17 +47,12 @@ setup( 'docs-auto': [ 'sphinx-autobuild' ], - 'test': test_requires }, - tests_require=test_requires, entry_points={ 'console_scripts': [ 'dh = ereuse_devicehub.cli:cli' ] }, - setup_requires=[ - 'pytest-runner' - ], classifiers=[ 'Development Status :: 2 - Pre-Alpha', 'Environment :: Web Environment', @@ -71,8 +61,7 @@ setup( 'License :: OSI Approved :: GNU Affero General Public License v3', 'Operating System :: OS Independent', 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', 'Topic :: Software Development :: Libraries :: Python Modules', From 311369691fd2d1ca87b9f4288603375beb8ebecc Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Tue, 8 Feb 2022 14:48:54 +0100 Subject: [PATCH 02/11] Fix "message" parameter of pytest.raises Removed in version 5.0 of pytest https://docs.pytest.org/en/7.0.x/deprecations.html#message-parameter-of-pytest-raises --- tests/test_action.py | 64 ++++++++++++++++++++++---------------------- tests/test_auth.py | 7 +++-- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/tests/test_action.py b/tests/test_action.py index 8de74e81..8ca9c44b 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -75,14 +75,14 @@ def test_erase_basic(): def test_validate_device_data_storage(): """Checks the validation for data-storage-only actions works.""" # We can't set a GraphicCard - with pytest.raises(TypeError, - message='EraseBasic.device must be a DataStorage ' - 'but you passed '): + with pytest.raises(TypeError): models.EraseBasic( device=GraphicCard(serial_number='foo', manufacturer='bar', model='foo-bar'), clean_with_zeros=True, **conftest.T ) + pytest.fail('EraseBasic.device must be a DataStorage ' + 'but you passed ') @pytest.mark.mvp @@ -335,10 +335,10 @@ def test_outgoinlot_status_actions(action_model: models.Action, user: UserClient @pytest.mark.parametrize('action_model', (pytest.param(ams, id=ams.__class__.__name__) for ams in [ - models.Recycling, - models.Use, - models.Refurbish, - models.Management + models.Recycling, + models.Use, + models.Refurbish, + models.Management ])) def test_incominglot_status_actions(action_model: models.Action, user: UserClient, user2: UserClient): """Test of status actions in outgoinlot.""" @@ -494,10 +494,10 @@ def test_recycling_container(user: UserClient): @pytest.mark.parametrize('action_model', (pytest.param(ams, id=ams.__class__.__name__) for ams in [ - models.Recycling, - models.Use, - models.Refurbish, - models.Management + models.Recycling, + models.Use, + models.Refurbish, + models.Management ])) def test_status_without_lot(action_model: models.Action, user: UserClient): """Test of status actions for devices without lot.""" @@ -512,10 +512,10 @@ def test_status_without_lot(action_model: models.Action, user: UserClient): @pytest.mark.parametrize('action_model', (pytest.param(ams, id=ams.__class__.__name__) for ams in [ - models.Recycling, - models.Use, - models.Refurbish, - models.Management + models.Recycling, + models.Use, + models.Refurbish, + models.Management ])) def test_status_in_temporary_lot(action_model: models.Action, user: UserClient): """Test of status actions for devices in a temporary lot.""" @@ -913,7 +913,7 @@ def test_allocate(user: UserClient): snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot) device_id = snapshot['device']['id'] devicehub_id = snapshot['device']['devicehubID'] - post_request = {"transaction": "ccc", + post_request = {"transaction": "ccc", "finalUserCode": "aabbcc", "name": "John", "severity": "Info", @@ -1638,7 +1638,7 @@ def test_confirmRevoke(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -1659,8 +1659,8 @@ def test_confirmRevoke(user: UserClient, user2: UserClient): 'type': 'Confirm', 'action': trade.id, 'devices': [ - snap1['device']['id'], - snap2['device']['id'], + snap1['device']['id'], + snap2['device']['id'], snap3['device']['id'], snap4['device']['id'], snap5['device']['id'], @@ -1677,7 +1677,7 @@ def test_confirmRevoke(user: UserClient, user2: UserClient): assert trade.devices[-1].actions[-1].t == 'Confirm' assert trade.devices[-1].actions[-1].user == trade.user_from - # The manager remove one device of the lot and automaticaly + # The manager remove one device of the lot and automaticaly # is create one revoke action device_10 = trade.devices[-1] lot, _ = user.delete({}, @@ -1804,7 +1804,7 @@ def test_trade_case2(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices[:-1]) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -1926,7 +1926,7 @@ def test_trade_case4(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices[:-1]) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -1991,7 +1991,7 @@ def test_trade_case5(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -2057,7 +2057,7 @@ def test_trade_case6(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices[:-1]) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -2125,7 +2125,7 @@ def test_trade_case7(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -2192,7 +2192,7 @@ def test_trade_case8(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -2266,7 +2266,7 @@ def test_trade_case9(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices[:-1]) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -2348,7 +2348,7 @@ def test_trade_case10(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices[:-1]) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -2435,7 +2435,7 @@ def test_trade_case11(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -2507,7 +2507,7 @@ def test_trade_case12(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -2584,7 +2584,7 @@ def test_trade_case13(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices[:-1]) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', @@ -2664,7 +2664,7 @@ def test_trade_case14(user: UserClient, user2: UserClient): item='{}/devices'.format(lot['id']), query=devices[:-1]) - # the manager shares the temporary lot with the SCRAP as an incoming lot + # the manager shares the temporary lot with the SCRAP as an incoming lot # for the CRAP to confirm it request_post = { 'type': 'Trade', diff --git a/tests/test_auth.py b/tests/test_auth.py index 81cefb0e..f59964fc 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -24,11 +24,14 @@ def test_authenticate_error(app: Devicehub): MESSAGE = 'Provide a suitable token.' create_user() # Token doesn't exist - with pytest.raises(Unauthorized, message=MESSAGE): + with pytest.raises(Unauthorized): app.auth.authenticate(token=str(uuid4())) + pytest.fail(MESSAGE) + # Wrong token format - with pytest.raises(Unauthorized, message=MESSAGE): + with pytest.raises(Unauthorized): app.auth.authenticate(token='this is a wrong uuid') + pytest.fail(MESSAGE) @pytest.mark.mvp From 4256a8ba81d94d9d88bdacab76d88afc58486e5c Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Tue, 8 Feb 2022 14:53:44 +0100 Subject: [PATCH 03/11] Add missing dependency `more-itertools` --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 89155f83..f2a2ee7c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,6 +14,7 @@ hashids==1.2.0 inflection==0.3.1 marshmallow==3.0.0b11 marshmallow-enum==1.4.1 +more-itertools==8.12.0 passlib==1.7.1 phonenumbers==8.9.11 pytest==7.0.0 From 01b85661b9386944010be0cbd26136ebf266615f Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Wed, 9 Feb 2022 09:29:15 +0100 Subject: [PATCH 04/11] Fix "message" parameter of pytest.raises (part 2) --- tests/test_inventory.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_inventory.py b/tests/test_inventory.py index 70e4dfb7..056253dc 100644 --- a/tests/test_inventory.py +++ b/tests/test_inventory.py @@ -144,5 +144,7 @@ def test_create_existing_inventory(cli, tdb1): cli.invoke('inv', 'add', '--common') with tdb1.app_context(): assert db.has_schema('tdb1') - with pytest.raises(AssertionError, message='Schema tdb1 already exists.'): + + with pytest.raises(AssertionError): cli.invoke('inv', 'add', '--common') + pytest.fail('Schema tdb1 already exists.') From 3a395bed8033180afa04d515e0b6f584ce3367a7 Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Wed, 9 Feb 2022 09:42:44 +0100 Subject: [PATCH 05/11] Add pytest-xdist to run test in parallel Disable coverage because it's not compatible with parallel execution --- .github/workflows/flask.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index d94c15d8..cacc314c 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -50,7 +50,7 @@ jobs: pip install virtualenv virtualenv env source env/bin/activate - pip install flake8 pytest coverage + pip install flake8 pytest pytest-xdist pip install -r requirements.txt - name: Prepare database @@ -68,11 +68,4 @@ jobs: - name: Run Tests run: | source env/bin/activate - coverage run --source='ereuse_devicehub' env/bin/pytest -m mvp --maxfail=5 tests/ - coverage report --include='ereuse_devicehub/*' - coverage xml - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} + pytest -m mvp --maxfail=5 tests/ -n auto From 74432031e4bc1de41c42587060c4ba8733158ae7 Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Wed, 9 Feb 2022 09:54:57 +0100 Subject: [PATCH 06/11] Revert "Add pytest-xdist to run test in parallel" This reverts commit 3a395bed8033180afa04d515e0b6f584ce3367a7. --- .github/workflows/flask.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index cacc314c..d94c15d8 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -50,7 +50,7 @@ jobs: pip install virtualenv virtualenv env source env/bin/activate - pip install flake8 pytest pytest-xdist + pip install flake8 pytest coverage pip install -r requirements.txt - name: Prepare database @@ -68,4 +68,11 @@ jobs: - name: Run Tests run: | source env/bin/activate - pytest -m mvp --maxfail=5 tests/ -n auto + coverage run --source='ereuse_devicehub' env/bin/pytest -m mvp --maxfail=5 tests/ + coverage report --include='ereuse_devicehub/*' + coverage xml + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.CODECOV_TOKEN }} From 09649fee291ecd1911e1096dde5e44bcc0f16b84 Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Thu, 10 Feb 2022 09:51:42 +0100 Subject: [PATCH 07/11] Sort requirements alphabetically --- requirements.txt | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/requirements.txt b/requirements.txt index f2a2ee7c..4c70af21 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,7 @@ ereuse-utils[naming,test,session,cli]==0.4.0b49 Flask==1.0.2 Flask-Cors==3.0.10 Flask-SQLAlchemy==2.3.2 +flask-WeasyPrint==0.5 hashids==1.2.0 inflection==0.3.1 marshmallow==3.0.0b11 @@ -17,23 +18,22 @@ marshmallow-enum==1.4.1 more-itertools==8.12.0 passlib==1.7.1 phonenumbers==8.9.11 +psycopg2-binary==2.8.3 +PyJWT==2.0.0a1 pytest==7.0.0 python-dateutil==2.7.3 -python-stdnum==1.9 -PyYAML==5.4 -requests[security]==2.27.1 -requests-mock==1.5.2 -SQLAlchemy==1.2.17 -SQLAlchemy-Utils==0.33.11 -teal==0.2.0a38 -webargs==5.5.3 -Werkzeug==0.15.3 -sqlalchemy-citext==1.3.post0 -flask-weasyprint==0.5 -weasyprint==44 -psycopg2-binary==2.8.3 -sortedcontainers==2.1.0 -tqdm==4.32.2 python-decouple==3.3 python-dotenv==0.14.0 -pyjwt==2.0.0a1 +python-stdnum==1.9 +PyYAML==5.4 +requests-mock==1.5.2 +requests[security]==2.27.1 +sortedcontainers==2.1.0 +SQLAlchemy==1.2.17 +sqlalchemy-citext==1.3.post0 +SQLAlchemy-Utils==0.33.11 +teal==0.2.0a38 +tqdm==4.32.2 +WeasyPrint==44 +webargs==5.5.3 +Werkzeug==0.15.3 From 0b41b526fd923f827d057ada701d7dd4d49034c4 Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Fri, 11 Feb 2022 12:25:48 +0100 Subject: [PATCH 08/11] Drop tqdm as requirement (added but never used) --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 4c70af21..6801fe8b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,6 @@ SQLAlchemy==1.2.17 sqlalchemy-citext==1.3.post0 SQLAlchemy-Utils==0.33.11 teal==0.2.0a38 -tqdm==4.32.2 WeasyPrint==44 webargs==5.5.3 Werkzeug==0.15.3 From d66c335118db8af7abe91b053eddfb4a29852122 Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Fri, 11 Feb 2022 12:28:18 +0100 Subject: [PATCH 09/11] Drop python-dotenv from requirements.txt (unused) --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 6801fe8b..dd57ce18 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,7 +23,6 @@ PyJWT==2.0.0a1 pytest==7.0.0 python-dateutil==2.7.3 python-decouple==3.3 -python-dotenv==0.14.0 python-stdnum==1.9 PyYAML==5.4 requests-mock==1.5.2 From 5cf6adb1c3ad7af9824794b61cde4a90c1a1bb8b Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Fri, 11 Feb 2022 12:49:10 +0100 Subject: [PATCH 10/11] Drop Werkzeug because it's a Flask dependency --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index dd57ce18..6d6a9473 100644 --- a/requirements.txt +++ b/requirements.txt @@ -34,4 +34,3 @@ SQLAlchemy-Utils==0.33.11 teal==0.2.0a38 WeasyPrint==44 webargs==5.5.3 -Werkzeug==0.15.3 From e185ba297ba47b80228056b73064010c9ca6fe89 Mon Sep 17 00:00:00 2001 From: Santiago Lamora Date: Fri, 11 Feb 2022 12:53:19 +0100 Subject: [PATCH 11/11] Move testing requirements to separate file Created requirements-testing.txt --- .github/workflows/flask.yml | 2 +- requirements-testing.txt | 4 ++++ requirements.txt | 2 -- 3 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 requirements-testing.txt diff --git a/.github/workflows/flask.yml b/.github/workflows/flask.yml index d94c15d8..d96660df 100644 --- a/.github/workflows/flask.yml +++ b/.github/workflows/flask.yml @@ -50,7 +50,7 @@ jobs: pip install virtualenv virtualenv env source env/bin/activate - pip install flake8 pytest coverage + pip install -r requirements-testing.txt pip install -r requirements.txt - name: Prepare database diff --git a/requirements-testing.txt b/requirements-testing.txt new file mode 100644 index 00000000..a802865d --- /dev/null +++ b/requirements-testing.txt @@ -0,0 +1,4 @@ +coverage +flake8 +pytest==7.0.0 +requests-mock==1.5.2 diff --git a/requirements.txt b/requirements.txt index 6d6a9473..56070142 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,12 +20,10 @@ passlib==1.7.1 phonenumbers==8.9.11 psycopg2-binary==2.8.3 PyJWT==2.0.0a1 -pytest==7.0.0 python-dateutil==2.7.3 python-decouple==3.3 python-stdnum==1.9 PyYAML==5.4 -requests-mock==1.5.2 requests[security]==2.27.1 sortedcontainers==2.1.0 SQLAlchemy==1.2.17