Merge branch 'upgrade-dependencies' into teal3

This commit is contained in:
Santiago L 2022-04-05 14:03:02 +02:00
commit 47a167b947
8 changed files with 58 additions and 60 deletions

View File

@ -47,7 +47,7 @@ jobs:
sudo apt-get update -qy sudo apt-get update -qy
sudo apt-get -y install postgresql-client --no-install-recommends sudo apt-get -y install postgresql-client --no-install-recommends
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install flake8 pytest coverage pip install -r requirements-testing.txt
pip install -r requirements.txt pip install -r requirements.txt
- name: Prepare database - name: Prepare database

3
pytest.ini Normal file
View File

@ -0,0 +1,3 @@
[pytest]
markers =
mvp: mark tests as required by MVP

4
requirements-testing.txt Normal file
View File

@ -0,0 +1,4 @@
coverage
flake8
pytest==7.0.0
requests-mock==1.5.2

View File

@ -12,35 +12,32 @@ Flask-Cors==3.0.10
Flask-Login==0.5.0 Flask-Login==0.5.0
Flask-SQLAlchemy==2.3.2 Flask-SQLAlchemy==2.3.2
Flask-WTF==1.0.0 Flask-WTF==1.0.0
flask-WeasyPrint==0.5
hashids==1.2.0 hashids==1.2.0
inflection==0.3.1 inflection==0.3.1
# lock itsdangerous version until upgrade to Flask 2.x
itsdangerous==2.0.1 itsdangerous==2.0.1
# lock Jinja2 version because it's the latest compatible with Flask 1.0.X # lock Jinja2 version because it's the latest compatible with Flask 1.0.X
# see related info on https://github.com/pallets/jinja/issues/1628 # see related info on https://github.com/pallets/jinja/issues/1628
Jinja2==3.0.3 Jinja2==3.0.3
marshmallow==3.0.0b11 marshmallow==3.0.0b11
marshmallow-enum==1.4.1 marshmallow-enum==1.4.1
more-itertools==8.12.0
passlib==1.7.1 passlib==1.7.1
phonenumbers==8.9.11 phonenumbers==8.9.11
pytest==3.7.2 psycopg2-binary==2.8.3
pytest-runner==4.2 PyJWT==2.0.0a1
python-dateutil==2.7.3 python-dateutil==2.7.3
python-decouple==3.3
python-stdnum==1.9 python-stdnum==1.9
PyYAML==5.4 PyYAML==5.4
requests[security]==2.27.1 requests[security]==2.27.1
requests-mock==1.5.2 sortedcontainers==2.1.0
SQLAlchemy==1.3.24 SQLAlchemy==1.3.24
sqlalchemy-citext==1.3.post0
SQLAlchemy-Utils==0.33.11 SQLAlchemy-Utils==0.33.11
# teal under development version # teal under development version
-e git+https://github.com/eReuse/teal/@upgrade-dependencies#egg=teal -e git+https://github.com/eReuse/teal/@upgrade-dependencies#egg=teal
WeasyPrint==44
webargs==5.5.3 webargs==5.5.3
Werkzeug>=2.0 Werkzeug>=2.0
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

View File

@ -3,11 +3,6 @@ from setuptools import find_packages, setup
from ereuse_devicehub import __version__ from ereuse_devicehub import __version__
test_requires = [
'pytest',
'requests_mock'
]
setup( setup(
name='ereuse-devicehub', name='ereuse-devicehub',
version=__version__, version=__version__,
@ -52,17 +47,12 @@ setup(
'docs-auto': [ 'docs-auto': [
'sphinx-autobuild' 'sphinx-autobuild'
], ],
'test': test_requires
}, },
tests_require=test_requires,
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [
'dh = ereuse_devicehub.cli:cli' 'dh = ereuse_devicehub.cli:cli'
] ]
}, },
setup_requires=[
'pytest-runner'
],
classifiers=[ classifiers=[
'Development Status :: 2 - Pre-Alpha', 'Development Status :: 2 - Pre-Alpha',
'Environment :: Web Environment', 'Environment :: Web Environment',
@ -71,8 +61,7 @@ setup(
'License :: OSI Approved :: GNU Affero General Public License v3', 'License :: OSI Approved :: GNU Affero General Public License v3',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Programming Language :: Python :: 3 :: Only', 'Programming Language :: Python :: 3 :: Only',
'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.6',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Software Development :: Libraries :: Python Modules',

View File

@ -75,14 +75,14 @@ def test_erase_basic():
def test_validate_device_data_storage(): def test_validate_device_data_storage():
"""Checks the validation for data-storage-only actions works.""" """Checks the validation for data-storage-only actions works."""
# We can't set a GraphicCard # We can't set a GraphicCard
with pytest.raises(TypeError, with pytest.raises(TypeError):
message='EraseBasic.device must be a DataStorage '
'but you passed <GraphicCard None model=\'foo-bar\' S/N=\'foo\'>'):
models.EraseBasic( models.EraseBasic(
device=GraphicCard(serial_number='foo', manufacturer='bar', model='foo-bar'), device=GraphicCard(serial_number='foo', manufacturer='bar', model='foo-bar'),
clean_with_zeros=True, clean_with_zeros=True,
**conftest.T **conftest.T
) )
pytest.fail('EraseBasic.device must be a DataStorage '
'but you passed <GraphicCard None model=\'foo-bar\' S/N=\'foo\'>')
@pytest.mark.mvp @pytest.mark.mvp
@ -335,10 +335,10 @@ def test_outgoinlot_status_actions(action_model: models.Action, user: UserClient
@pytest.mark.parametrize('action_model', @pytest.mark.parametrize('action_model',
(pytest.param(ams, id=ams.__class__.__name__) (pytest.param(ams, id=ams.__class__.__name__)
for ams in [ for ams in [
models.Recycling, models.Recycling,
models.Use, models.Use,
models.Refurbish, models.Refurbish,
models.Management models.Management
])) ]))
def test_incominglot_status_actions(action_model: models.Action, user: UserClient, user2: UserClient): def test_incominglot_status_actions(action_model: models.Action, user: UserClient, user2: UserClient):
"""Test of status actions in outgoinlot.""" """Test of status actions in outgoinlot."""
@ -494,10 +494,10 @@ def test_recycling_container(user: UserClient):
@pytest.mark.parametrize('action_model', @pytest.mark.parametrize('action_model',
(pytest.param(ams, id=ams.__class__.__name__) (pytest.param(ams, id=ams.__class__.__name__)
for ams in [ for ams in [
models.Recycling, models.Recycling,
models.Use, models.Use,
models.Refurbish, models.Refurbish,
models.Management models.Management
])) ]))
def test_status_without_lot(action_model: models.Action, user: UserClient): def test_status_without_lot(action_model: models.Action, user: UserClient):
"""Test of status actions for devices without lot.""" """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.mark.parametrize('action_model',
(pytest.param(ams, id=ams.__class__.__name__) (pytest.param(ams, id=ams.__class__.__name__)
for ams in [ for ams in [
models.Recycling, models.Recycling,
models.Use, models.Use,
models.Refurbish, models.Refurbish,
models.Management models.Management
])) ]))
def test_status_in_temporary_lot(action_model: models.Action, user: UserClient): def test_status_in_temporary_lot(action_model: models.Action, user: UserClient):
"""Test of status actions for devices in a temporary lot.""" """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) snapshot, _ = user.post(file('basic.snapshot'), res=models.Snapshot)
device_id = snapshot['device']['id'] device_id = snapshot['device']['id']
devicehub_id = snapshot['device']['devicehubID'] devicehub_id = snapshot['device']['devicehubID']
post_request = {"transaction": "ccc", post_request = {"transaction": "ccc",
"finalUserCode": "aabbcc", "finalUserCode": "aabbcc",
"name": "John", "name": "John",
"severity": "Info", "severity": "Info",
@ -1638,7 +1638,7 @@ def test_confirmRevoke(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -1659,8 +1659,8 @@ def test_confirmRevoke(user: UserClient, user2: UserClient):
'type': 'Confirm', 'type': 'Confirm',
'action': trade.id, 'action': trade.id,
'devices': [ 'devices': [
snap1['device']['id'], snap1['device']['id'],
snap2['device']['id'], snap2['device']['id'],
snap3['device']['id'], snap3['device']['id'],
snap4['device']['id'], snap4['device']['id'],
snap5['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].t == 'Confirm'
assert trade.devices[-1].actions[-1].user == trade.user_from 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 # is create one revoke action
device_10 = trade.devices[-1] device_10 = trade.devices[-1]
lot, _ = user.delete({}, lot, _ = user.delete({},
@ -1804,7 +1804,7 @@ def test_trade_case2(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices[:-1]) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -1926,7 +1926,7 @@ def test_trade_case4(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices[:-1]) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -1991,7 +1991,7 @@ def test_trade_case5(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -2057,7 +2057,7 @@ def test_trade_case6(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices[:-1]) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -2125,7 +2125,7 @@ def test_trade_case7(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -2192,7 +2192,7 @@ def test_trade_case8(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -2266,7 +2266,7 @@ def test_trade_case9(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices[:-1]) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -2348,7 +2348,7 @@ def test_trade_case10(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices[:-1]) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -2435,7 +2435,7 @@ def test_trade_case11(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -2507,7 +2507,7 @@ def test_trade_case12(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -2584,7 +2584,7 @@ def test_trade_case13(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices[:-1]) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',
@ -2664,7 +2664,7 @@ def test_trade_case14(user: UserClient, user2: UserClient):
item='{}/devices'.format(lot['id']), item='{}/devices'.format(lot['id']),
query=devices[:-1]) 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 # for the CRAP to confirm it
request_post = { request_post = {
'type': 'Trade', 'type': 'Trade',

View File

@ -24,11 +24,14 @@ def test_authenticate_error(app: Devicehub):
MESSAGE = 'Provide a suitable token.' MESSAGE = 'Provide a suitable token.'
create_user() create_user()
# Token doesn't exist # Token doesn't exist
with pytest.raises(Unauthorized, message=MESSAGE): with pytest.raises(Unauthorized):
app.auth.authenticate(token=str(uuid4())) app.auth.authenticate(token=str(uuid4()))
pytest.fail(MESSAGE)
# Wrong token format # Wrong token format
with pytest.raises(Unauthorized, message=MESSAGE): with pytest.raises(Unauthorized):
app.auth.authenticate(token='this is a wrong uuid') app.auth.authenticate(token='this is a wrong uuid')
pytest.fail(MESSAGE)
@pytest.mark.mvp @pytest.mark.mvp

View File

@ -144,5 +144,7 @@ def test_create_existing_inventory(cli, tdb1):
cli.invoke('inv', 'add', '--common') cli.invoke('inv', 'add', '--common')
with tdb1.app_context(): with tdb1.app_context():
assert db.has_schema('tdb1') assert db.has_schema('tdb1')
with pytest.raises(AssertionError, message='Schema tdb1 already exists.'):
with pytest.raises(AssertionError):
cli.invoke('inv', 'add', '--common') cli.invoke('inv', 'add', '--common')
pytest.fail('Schema tdb1 already exists.')