From 39a53b64394820f195bc2765a890594d5d2bcdef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Tue, 11 Jul 2023 17:10:38 +0200 Subject: [PATCH 01/24] removes cffi and chardet from pyproject.toml Those libraries are not directly used in the code, and the fixed version 1.14.0 of cffi causes python environment installation issues with some Linux distributions (e.g. Archlinux as of july 23). --- poetry.lock | 116 ++----------------------------------------------- pyproject.toml | 2 - 2 files changed, 3 insertions(+), 115 deletions(-) diff --git a/poetry.lock b/poetry.lock index fb3954b1..62133081 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "alembic" version = "1.10.4" description = "A database migration tool for SQLAlchemy." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -26,7 +25,6 @@ tz = ["python-dateutil"] name = "amqp" version = "5.1.1" description = "Low-level AMQP client for Python (fork of amqplib)." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -41,7 +39,6 @@ vine = ">=5.0.0" name = "async-timeout" version = "4.0.2" description = "Timeout context manager for asyncio programs" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -53,7 +50,6 @@ files = [ name = "babel" version = "2.12.1" description = "Internationalization utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -68,7 +64,6 @@ pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} name = "beaker" version = "1.12.1" description = "A Session and Caching library with WSGI Middleware" -category = "main" optional = false python-versions = "*" files = [ @@ -86,7 +81,6 @@ testsuite = ["Mock", "coverage", "cryptography", "pycryptodome", "pylibmc", "pym name = "beautifulsoup4" version = "4.12.2" description = "Screen-scraping library" -category = "dev" optional = false python-versions = ">=3.6.0" files = [ @@ -105,7 +99,6 @@ lxml = ["lxml"] name = "billiard" version = "3.6.4.0" description = "Python multiprocessing fork with improvements and bugfixes" -category = "main" optional = false python-versions = "*" files = [ @@ -117,7 +110,6 @@ files = [ name = "black" version = "23.3.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -167,7 +159,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "blinker" version = "1.6.2" description = "Fast, simple object-to-object and broadcast signaling" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -179,7 +170,6 @@ files = [ name = "cachelib" version = "0.9.0" description = "A collection of cache libraries in the same API interface." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -191,7 +181,6 @@ files = [ name = "celery" version = "5.2.7" description = "Distributed Task Queue." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -246,7 +235,6 @@ zstd = ["zstandard"] name = "certifi" version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -258,7 +246,6 @@ files = [ name = "cffi" version = "1.14.0" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -299,7 +286,6 @@ pycparser = "*" name = "cfgv" version = "3.3.1" description = "Validate configuration and produce human readable error messages." -category = "dev" optional = false python-versions = ">=3.6.1" files = [ @@ -307,23 +293,10 @@ files = [ {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, ] -[[package]] -name = "chardet" -version = "3.0.4" -description = "Universal encoding detector for Python 2 and 3" -category = "main" -optional = false -python-versions = "*" -files = [ - {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, - {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, -] - [[package]] name = "charset-normalizer" version = "2.0.12" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.5.0" files = [ @@ -338,7 +311,6 @@ unicode-backport = ["unicodedata2"] name = "click" version = "8.1.3" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -353,7 +325,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "click-didyoumean" version = "0.3.0" description = "Enables git-like *did-you-mean* feature in click" -category = "main" optional = false python-versions = ">=3.6.2,<4.0.0" files = [ @@ -368,7 +339,6 @@ click = ">=7" name = "click-plugins" version = "1.1.1" description = "An extension module for click to enable registering CLI commands via setuptools entry-points." -category = "main" optional = false python-versions = "*" files = [ @@ -386,7 +356,6 @@ dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] name = "click-repl" version = "0.2.0" description = "REPL plugin for Click" -category = "main" optional = false python-versions = "*" files = [ @@ -403,7 +372,6 @@ six = "*" name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -415,7 +383,6 @@ files = [ name = "coverage" version = "7.2.4" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -482,7 +449,6 @@ toml = ["tomli"] name = "cryptography" version = "41.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -524,7 +490,6 @@ test-randomorder = ["pytest-randomly"] name = "defusedxml" version = "0.7.1" description = "XML bomb protection for Python stdlib modules" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -536,7 +501,6 @@ files = [ name = "distlib" version = "0.3.6" description = "Distribution utilities" -category = "dev" optional = false python-versions = "*" files = [ @@ -548,7 +512,6 @@ files = [ name = "exceptiongroup" version = "1.1.1" description = "Backport of PEP 654 (exception groups)" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -563,7 +526,6 @@ test = ["pytest (>=6)"] name = "filelock" version = "3.12.0" description = "A platform independent file lock." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -579,7 +541,6 @@ testing = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "diff-cover (>=7.5)", "p name = "filetype" version = "1.2.0" description = "Infer file type and MIME type of any file/buffer. No external dependencies." -category = "main" optional = false python-versions = "*" files = [ @@ -591,7 +552,6 @@ files = [ name = "flake8" version = "6.0.0" description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" optional = false python-versions = ">=3.8.1" files = [ @@ -608,7 +568,6 @@ pyflakes = ">=3.0.0,<3.1.0" name = "flask" version = "2.2.5" description = "A simple framework for building complex web applications." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -631,7 +590,6 @@ dotenv = ["python-dotenv"] name = "flask-babel" version = "2.0.0" description = "Adds i18n/l10n support to Flask applications" -category = "main" optional = false python-versions = "*" files = [ @@ -652,7 +610,6 @@ dev = ["Pallets-Sphinx-Themes", "bumpversion", "ghp-import", "pytest", "pytest-m name = "flask-caching" version = "2.0.2" description = "Adds caching support to Flask applications." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -668,7 +625,6 @@ Flask = "<3" name = "flask-migrate" version = "3.1.0" description = "SQLAlchemy database migrations for Flask applications using Alembic." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -685,7 +641,6 @@ Flask-SQLAlchemy = ">=1.0" name = "flask-pyoidc" version = "3.10.0" description = "Flask extension for OpenID Connect authentication." -category = "main" optional = false python-versions = "*" files = [ @@ -702,7 +657,6 @@ requests = "*" name = "flask-sqlalchemy" version = "3.0.3" description = "Add SQLAlchemy support to your Flask application." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -718,7 +672,6 @@ SQLAlchemy = ">=1.4.18" name = "flask-uploads" version = "0.2.1" description = "Flexible and efficient upload handling for Flask" -category = "main" optional = false python-versions = "*" files = [ @@ -732,7 +685,6 @@ Flask = ">=0.8.0" name = "flask-webtest" version = "0.1.1" description = "Utilities for testing Flask applications with WebTest." -category = "dev" optional = false python-versions = "*" files = [ @@ -752,7 +704,6 @@ tests = ["flask-sqlalchemy"] name = "flask-wtf" version = "1.0.1" description = "Form rendering, validation, and CSRF protection for Flask with WTForms." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -772,7 +723,6 @@ email = ["email-validator"] name = "freezegun" version = "1.2.2" description = "Let your Python tests travel through time" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -787,7 +737,6 @@ python-dateutil = ">=2.7" name = "future" version = "0.18.3" description = "Clean single-source support for Python 3 and 2" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -798,7 +747,6 @@ files = [ name = "greenlet" version = "2.0.2" description = "Lightweight in-process concurrent programming" -category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" files = [ @@ -872,7 +820,6 @@ test = ["objgraph", "psutil"] name = "gunicorn" version = "20.1.0" description = "WSGI HTTP Server for UNIX" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -893,7 +840,6 @@ tornado = ["tornado (>=0.2)"] name = "identify" version = "2.5.23" description = "File identification library for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -908,7 +854,6 @@ license = ["ukkonen"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -920,7 +865,6 @@ files = [ name = "importlib-metadata" version = "6.6.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -940,7 +884,6 @@ testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packag name = "importlib-resources" version = "5.12.0" description = "Read resources from Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -959,7 +902,6 @@ testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-chec name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -971,7 +913,6 @@ files = [ name = "itsdangerous" version = "2.1.2" description = "Safely pass data to untrusted environments and back." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -983,7 +924,6 @@ files = [ name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1001,7 +941,6 @@ i18n = ["Babel (>=2.7)"] name = "kombu" version = "5.2.4" description = "Messaging library for Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1033,7 +972,6 @@ zookeeper = ["kazoo (>=1.3.1)"] name = "lxml" version = "4.9.2" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" files = [ @@ -1126,7 +1064,6 @@ source = ["Cython (>=0.29.7)"] name = "mako" version = "1.2.4" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1146,7 +1083,6 @@ testing = ["pytest"] name = "markupsafe" version = "2.1.2" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1206,7 +1142,6 @@ files = [ name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1218,7 +1153,6 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1230,7 +1164,6 @@ files = [ name = "netaddr" version = "0.8.0" description = "A network address manipulation library for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -1242,7 +1175,6 @@ files = [ name = "nodeenv" version = "1.7.0" description = "Node.js virtual environment builder" -category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -1257,7 +1189,6 @@ setuptools = "*" name = "oic" version = "1.4.0" description = "Python implementation of OAuth2 and OpenID Connect" -category = "main" optional = false python-versions = "~=3.5" files = [ @@ -1287,7 +1218,6 @@ types = ["types-requests"] name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1299,7 +1229,6 @@ files = [ name = "pathspec" version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1311,7 +1240,6 @@ files = [ name = "platformdirs" version = "3.5.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1327,7 +1255,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest- name = "pluggy" version = "1.0.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1343,7 +1270,6 @@ testing = ["pytest", "pytest-benchmark"] name = "pre-commit" version = "3.2.2" description = "A framework for managing and maintaining multi-language pre-commit hooks." -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1362,7 +1288,6 @@ virtualenv = ">=20.10.0" name = "prompt-toolkit" version = "3.0.38" description = "Library for building powerful interactive command lines in Python" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -1377,7 +1302,6 @@ wcwidth = "*" name = "psycopg2" version = "2.9.3" description = "psycopg2 - Python-PostgreSQL Database Adapter" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1398,7 +1322,6 @@ files = [ name = "pycodestyle" version = "2.10.0" description = "Python style guide checker" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1410,7 +1333,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1422,7 +1344,6 @@ files = [ name = "pycryptodomex" version = "3.17" description = "Cryptographic library for Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1465,7 +1386,6 @@ files = [ name = "pyflakes" version = "3.0.1" description = "passive checker of Python programs" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1477,7 +1397,6 @@ files = [ name = "pyjwkest" version = "1.4.2" description = "Python implementation of JWT, JWE, JWS and JWK" -category = "main" optional = false python-versions = "*" files = [ @@ -1494,7 +1413,6 @@ six = "*" name = "pytest" version = "7.3.1" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1517,7 +1435,6 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-cov" version = "4.0.0" description = "Pytest plugin for measuring coverage." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1536,7 +1453,6 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-dotenv" version = "0.5.2" description = "A py.test plugin that parses environment files before running tests" -category = "dev" optional = false python-versions = "*" files = [ @@ -1552,7 +1468,6 @@ python-dotenv = ">=0.9.1" name = "pytest-mock" version = "3.10.0" description = "Thin-wrapper around the mock package for easier use with pytest" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1570,7 +1485,6 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -1585,7 +1499,6 @@ six = ">=1.5" name = "python-dotenv" version = "1.0.0" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1600,7 +1513,6 @@ cli = ["click (>=5.0)"] name = "pytz" version = "2023.3" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" files = [ @@ -1612,7 +1524,6 @@ files = [ name = "pyyaml" version = "6.0" description = "YAML parser and emitter for Python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1662,7 +1573,6 @@ files = [ name = "redis" version = "4.4.4" description = "Python client for Redis database and key-value store" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1681,7 +1591,6 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1703,7 +1612,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "setuptools" version = "67.7.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1720,7 +1628,6 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1732,7 +1639,6 @@ files = [ name = "soupsieve" version = "2.4.1" description = "A modern CSS selector implementation for Beautiful Soup." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1744,7 +1650,6 @@ files = [ name = "sqlalchemy" version = "1.4.31" description = "Database Abstraction Library" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -1787,7 +1692,7 @@ files = [ ] [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and platform_machine == \"aarch64\" or python_version >= \"3\" and platform_machine == \"ppc64le\" or python_version >= \"3\" and platform_machine == \"x86_64\" or python_version >= \"3\" and platform_machine == \"amd64\" or python_version >= \"3\" and platform_machine == \"AMD64\" or python_version >= \"3\" and platform_machine == \"win32\" or python_version >= \"3\" and platform_machine == \"WIN32\""} +greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\")"} [package.extras] aiomysql = ["aiomysql", "greenlet (!=0.4.17)"] @@ -1814,7 +1719,6 @@ sqlcipher = ["sqlcipher3-binary"] name = "sqlalchemy-json" version = "0.4.0" description = "JSON type with nested change tracking for SQLAlchemy" -category = "main" optional = false python-versions = "*" files = [ @@ -1830,7 +1734,6 @@ sqlalchemy = ">=0.7" name = "sqlalchemy-utils" version = "0.38.1" description = "Various utility functions for SQLAlchemy." -category = "main" optional = false python-versions = "~=3.4" files = [ @@ -1860,7 +1763,6 @@ url = ["furl (>=0.4.1)"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1872,7 +1774,6 @@ files = [ name = "typing-extensions" version = "4.5.0" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1884,7 +1785,6 @@ files = [ name = "urllib3" version = "1.26.15" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -1901,7 +1801,6 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "vine" version = "5.0.0" description = "Promises, promises, promises." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1913,7 +1812,6 @@ files = [ name = "virtualenv" version = "20.23.0" description = "Virtual Python Environment builder" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1934,7 +1832,6 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.3)", "coverage-enable-subprocess name = "waitress" version = "2.1.2" description = "Waitress WSGI server" -category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -1950,7 +1847,6 @@ testing = ["coverage (>=5.0)", "pytest", "pytest-cover"] name = "wcwidth" version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -1962,7 +1858,6 @@ files = [ name = "webdavclient3" version = "3.14.6" description = "WebDAV client, based on original package https://github.com/designerror/webdav-client-python but uses requests instead of PyCURL" -category = "main" optional = false python-versions = "*" files = [ @@ -1978,7 +1873,6 @@ requests = "*" name = "webob" version = "1.8.7" description = "WSGI request and response object" -category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*" files = [ @@ -1994,7 +1888,6 @@ testing = ["coverage", "pytest (>=3.1.0)", "pytest-cov", "pytest-xdist"] name = "webtest" version = "3.0.0" description = "Helper to test WSGI applications" -category = "dev" optional = false python-versions = ">=3.6, <4" files = [ @@ -2015,7 +1908,6 @@ tests = ["PasteDeploy", "WSGIProxy2", "coverage", "pyquery", "pytest", "pytest-c name = "werkzeug" version = "2.3.4" description = "The comprehensive WSGI web application library." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2033,7 +1925,6 @@ watchdog = ["watchdog (>=2.3)"] name = "wtforms" version = "3.0.1" description = "Form validation and rendering for Python web development." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2051,7 +1942,6 @@ email = ["email-validator"] name = "zipp" version = "3.15.0" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2066,4 +1956,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = ">=3.8.1,<4.0" -content-hash = "51b112794ce233cba0782dda62ab79326e2d597ea6d8401869529bb2627c2fae" +content-hash = "22226362338c2814f71266264082a27169c2afab935ad4f0bebd871b48db6357" diff --git a/pyproject.toml b/pyproject.toml index 52a142b1..faba8598 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,8 +7,6 @@ readme = "README.md" [tool.poetry.dependencies] python = ">=3.8.1,<4.0" -cffi = "1.14.0" -chardet = "3.0.4" flask-pyoidc = "3.10.0" flask-sqlalchemy = "^3.0.3" flask-uploads = "0.2.1" From f5a80f8ea225c65173143bd6d31f6aa836802f8e Mon Sep 17 00:00:00 2001 From: loanR Date: Mon, 17 Jul 2023 18:03:20 +0200 Subject: [PATCH 02/24] Update dependencies for docker containers Remove explicit chardet package from requirements --- web/requirements.app.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/requirements.app.txt b/web/requirements.app.txt index 67b458ce..af6262fa 100644 --- a/web/requirements.app.txt +++ b/web/requirements.app.txt @@ -8,7 +8,6 @@ cachelib==0.9.0 ; python_full_version >= "3.8.1" and python_version < "4.0" celery==5.2.7 ; python_full_version >= "3.8.1" and python_version < "4.0" certifi==2022.12.7 ; python_full_version >= "3.8.1" and python_version < "4.0" cffi==1.14.0 ; python_full_version >= "3.8.1" and python_version < "4.0" -chardet==3.0.4 ; python_full_version >= "3.8.1" and python_version < "4.0" charset-normalizer==2.0.12 ; python_full_version >= "3.8.1" and python_version < "4.0" click-didyoumean==0.3.0 ; python_full_version >= "3.8.1" and python_version < "4.0" click-plugins==1.1.1 ; python_full_version >= "3.8.1" and python_version < "4.0" @@ -27,7 +26,7 @@ flask-uploads==0.2.1 ; python_full_version >= "3.8.1" and python_version < "4.0" flask-wtf==1.0.1 ; python_full_version >= "3.8.1" and python_version < "4.0" flask==2.2.5 ; python_full_version >= "3.8.1" and python_version < "4.0" future==0.18.3 ; python_full_version >= "3.8.1" and python_version < "4.0" -greenlet==2.0.2 ; python_full_version >= "3.8.1" and platform_machine == "aarch64" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "ppc64le" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "x86_64" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "amd64" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "AMD64" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "win32" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "WIN32" and python_version < "4.0" +greenlet==2.0.2 ; python_full_version >= "3.8.1" and platform_machine == "win32" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "WIN32" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "AMD64" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "amd64" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "x86_64" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "ppc64le" and python_version < "4.0" or python_full_version >= "3.8.1" and platform_machine == "aarch64" and python_version < "4.0" gunicorn==20.1.0 ; python_full_version >= "3.8.1" and python_version < "4.0" idna==3.4 ; python_full_version >= "3.8.1" and python_version < "4.0" importlib-metadata==6.6.0 ; python_full_version >= "3.8.1" and python_version < "3.10" From af7439965944bb903ba672888f2e924651d01b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Wed, 19 Jul 2023 10:26:05 +0200 Subject: [PATCH 03/24] chore: bump to flask-webtest 0.1.3 --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- web/requirements.dev.txt | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/poetry.lock b/poetry.lock index 62133081..abf6cd7c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -683,13 +683,13 @@ Flask = ">=0.8.0" [[package]] name = "flask-webtest" -version = "0.1.1" +version = "0.1.3" description = "Utilities for testing Flask applications with WebTest." optional = false python-versions = "*" files = [ - {file = "Flask-WebTest-0.1.1.tar.gz", hash = "sha256:ae1eda72cc5a350aba1398b349c1c74d0795dda13054b347b33eaacb0737a2f4"}, - {file = "Flask_WebTest-0.1.1-py2.py3-none-any.whl", hash = "sha256:0414ca2cf8a63b37285a8708db874cef786dd3e0f3d203cf87a1b43170f33e50"}, + {file = "Flask-WebTest-0.1.3.tar.gz", hash = "sha256:8da31ae2ffef403496dd4752a0937ac39d4619849f2f54c5c7a3792747949559"}, + {file = "Flask_WebTest-0.1.3-py2.py3-none-any.whl", hash = "sha256:71efd3212b2c39ef20914b180ba7bfa6d0b8c0dc17e274ba508cc7a9cdd4ead9"}, ] [package.dependencies] @@ -1956,4 +1956,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = ">=3.8.1,<4.0" -content-hash = "22226362338c2814f71266264082a27169c2afab935ad4f0bebd871b48db6357" +content-hash = "db46a32b1cf3eaf8b9efde0890780178a015d9ecc56f785c1939702277787a8e" diff --git a/pyproject.toml b/pyproject.toml index faba8598..788d6218 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ optional = true [tool.poetry.group.dev.dependencies] pytest = "^7.2.2" pytest-mock = "^3.10.0" -Flask-WebTest = "^0.1.1" +Flask-WebTest = "^0.1.3" freezegun = "^1.2.2" black = "^23.1.0" flake8 = "^6.0.0" diff --git a/web/requirements.dev.txt b/web/requirements.dev.txt index 5a82edf3..9fd4eddc 100644 --- a/web/requirements.dev.txt +++ b/web/requirements.dev.txt @@ -3,14 +3,14 @@ black==23.3.0 ; python_full_version >= "3.8.1" and python_version < "4.0" blinker==1.6.2 ; python_full_version >= "3.8.1" and python_version < "4.0" cfgv==3.3.1 ; python_full_version >= "3.8.1" and python_version < "4.0" click==8.1.3 ; python_full_version >= "3.8.1" and python_version < "4.0" -colorama==0.4.6 ; python_full_version >= "3.8.1" and python_version < "4.0" and sys_platform == "win32" or python_full_version >= "3.8.1" and python_version < "4.0" and platform_system == "Windows" +colorama==0.4.6 ; python_full_version >= "3.8.1" and python_version < "4.0" and (sys_platform == "win32" or platform_system == "Windows") coverage==7.2.4 ; python_full_version >= "3.8.1" and python_version < "4.0" coverage[toml]==7.2.4 ; python_full_version >= "3.8.1" and python_version < "4.0" distlib==0.3.6 ; python_full_version >= "3.8.1" and python_version < "4.0" exceptiongroup==1.1.1 ; python_full_version >= "3.8.1" and python_version < "3.11" filelock==3.12.0 ; python_full_version >= "3.8.1" and python_version < "4.0" flake8==6.0.0 ; python_full_version >= "3.8.1" and python_version < "4.0" -flask-webtest==0.1.1 ; python_full_version >= "3.8.1" and python_version < "4.0" +flask-webtest==0.1.3 ; python_full_version >= "3.8.1" and python_version < "4.0" flask==2.2.5 ; python_full_version >= "3.8.1" and python_version < "4.0" freezegun==1.2.2 ; python_full_version >= "3.8.1" and python_version < "4.0" identify==2.5.23 ; python_full_version >= "3.8.1" and python_version < "4.0" @@ -39,7 +39,7 @@ pyyaml==6.0 ; python_full_version >= "3.8.1" and python_version < "4.0" setuptools==67.7.2 ; python_full_version >= "3.8.1" and python_version < "4.0" six==1.16.0 ; python_full_version >= "3.8.1" and python_version < "4.0" soupsieve==2.4.1 ; python_full_version >= "3.8.1" and python_version < "4" -tomli==2.0.1 ; python_full_version >= "3.8.1" and python_full_version <= "3.11.0a6" +tomli==2.0.1 ; python_full_version >= "3.8.1" and python_version < "3.11" typing-extensions==4.5.0 ; python_full_version >= "3.8.1" and python_version < "3.10" virtualenv==20.23.0 ; python_full_version >= "3.8.1" and python_version < "4.0" waitress==2.1.2 ; python_full_version >= "3.8.1" and python_version < "4" From f8a426830de242d8e1d7d2eba8c37a4a70149840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Wed, 19 Jul 2023 10:28:17 +0200 Subject: [PATCH 04/24] test: added pytest-flask dev dependency This allows reducing the boilerplate when writing unit tests, among other things by making app contexts optional --- poetry.lock | 21 ++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index abf6cd7c..fbd2ccf7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1464,6 +1464,25 @@ files = [ pytest = ">=5.0.0" python-dotenv = ">=0.9.1" +[[package]] +name = "pytest-flask" +version = "1.2.0" +description = "A set of py.test fixtures to test Flask applications." +optional = false +python-versions = ">=3.5" +files = [ + {file = "pytest-flask-1.2.0.tar.gz", hash = "sha256:46fde652f77777bf02dc91205aec4ce20cdf2acbbbd66a918ab91f5c14693d3d"}, + {file = "pytest_flask-1.2.0-py3-none-any.whl", hash = "sha256:fe25b39ad0db09c3d1fe728edecf97ced85e774c775db259a6d25f0270a4e7c9"}, +] + +[package.dependencies] +Flask = "*" +pytest = ">=5.2" +Werkzeug = ">=0.7" + +[package.extras] +docs = ["Sphinx", "sphinx-rtd-theme"] + [[package]] name = "pytest-mock" version = "3.10.0" @@ -1956,4 +1975,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = ">=3.8.1,<4.0" -content-hash = "db46a32b1cf3eaf8b9efde0890780178a015d9ecc56f785c1939702277787a8e" +content-hash = "7f2302ad2dfe4097e49ce0bf19467ddc2648b8631751fafee661125db40b827d" diff --git a/pyproject.toml b/pyproject.toml index 788d6218..870c6684 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,6 +41,7 @@ flake8 = "^6.0.0" pre-commit = "^3.1.1" pytest-cov = "^4.0.0" pytest-dotenv = "^0.5.2" +pytest-flask = "^1.2.0" coverage = "^7.2.2" [build-system] From 2cf98e1520142204d0626e9d90e3a8ab87ada786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Wed, 19 Jul 2023 10:55:21 +0200 Subject: [PATCH 05/24] test: avoid using app_context in unit tests This is made optional by flask-pytest. --- web/tests/conftest.py | 10 +- web/tests/meeting/test_end.py | 5 +- web/tests/meeting/test_join.py | 99 ++++++++--------- web/tests/meeting/test_meeting.py | 156 +++++++++++++-------------- web/tests/meeting/test_recordings.py | 10 +- web/tests/test_default.py | 22 ++-- web/tests/test_user.py | 32 +++--- 7 files changed, 150 insertions(+), 184 deletions(-) diff --git a/web/tests/conftest.py b/web/tests/conftest.py index 53949da1..2099ea3c 100644 --- a/web/tests/conftest.py +++ b/web/tests/conftest.py @@ -69,18 +69,16 @@ def client_app(app): @pytest.fixture() def meeting(app, user): - with app.app_context(): - meeting = Meeting(user=user) - meeting.save() + meeting = Meeting(user=user) + meeting.save() yield meeting @pytest.fixture() def user(app): - with app.app_context(): - user = User(email="alice@domain.tld", given_name="Alice", family_name="Cooper") - user.save() + user = User(email="alice@domain.tld", given_name="Alice", family_name="Cooper") + user.save() yield user diff --git a/web/tests/meeting/test_end.py b/web/tests/meeting/test_end.py index d58ef5ce..2ac264b6 100644 --- a/web/tests/meeting/test_end.py +++ b/web/tests/meeting/test_end.py @@ -2,9 +2,8 @@ def test_end_bbb_meeting(app, client_app, authenticated_user, meeting, mocker): - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_id = meeting.id + meeting = Meeting.query.get(1) + meeting_id = meeting.id mocked_end = mocker.patch("flaskr.models.BBB.end") response = client_app.post( diff --git a/web/tests/meeting/test_join.py b/web/tests/meeting/test_join.py index fd0f7f63..e7a54b4c 100644 --- a/web/tests/meeting/test_join.py +++ b/web/tests/meeting/test_join.py @@ -26,11 +26,10 @@ def authenticated_attendee(client_app, user, mocker): def test_signin_meeting(client_app, app, meeting): - with app.app_context(): - user_id = 1 - meeting = Meeting.query.get(1) - meeting_id = meeting.id - meeting_hash = meeting.get_hash("attendee") + user_id = 1 + meeting = Meeting.query.get(1) + meeting_id = meeting.id + meeting_hash = meeting.get_hash("attendee") url = f"/meeting/signin/{meeting_id}/creator/{user_id}/hash/{meeting_hash}" response = client_app.get(url) @@ -41,11 +40,10 @@ def test_signin_meeting(client_app, app, meeting): def test_signin_meeting_with_authenticated_attendee(client_app, app, meeting): - with app.app_context(): - user_id = 1 - meeting = Meeting.query.get(1) - meeting_id = meeting.id - meeting_hash = meeting.get_hash("authenticated") + user_id = 1 + meeting = Meeting.query.get(1) + meeting_id = meeting.id + meeting_hash = meeting.get_hash("authenticated") url = f"/meeting/signin/{meeting_id}/creator/{user_id}/hash/{meeting_hash}" response = client_app.get(url) @@ -57,9 +55,8 @@ def test_signin_meeting_with_authenticated_attendee(client_app, app, meeting): def test_join_meeting_as_authenticated_attendee( client_app, app, meeting, authenticated_attendee ): - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_id = meeting.id + meeting = Meeting.query.get(1) + meeting_id = meeting.id url = f"/meeting/join/{meeting_id}/authenticated" response = client_app.get(url) @@ -72,11 +69,10 @@ def test_join_meeting_as_authenticated_attendee( def test_join_meeting_as_authenticated_attendee_with_fullname_suffix( client_app, app, meeting, authenticated_attendee, bbb_response ): - with app.app_context(): - user_id = 1 - meeting = Meeting.query.get(1) - meeting_id = meeting.id - meeting_hash = meeting.get_hash("authenticated") + user_id = 1 + meeting = Meeting.query.get(1) + meeting_id = meeting.id + meeting_hash = meeting.get_hash("authenticated") response = client_app.post( "/meeting/join", @@ -100,11 +96,10 @@ def test_join_meeting_as_authenticated_attendee_with_fullname_suffix( def test_join_meeting_as_authenticated_attendee_with_modified_fullname( client_app, app, meeting, authenticated_attendee, bbb_response ): - with app.app_context(): - user_id = 1 - meeting = Meeting.query.get(1) - meeting_id = meeting.id - meeting_hash = meeting.get_hash("authenticated") + user_id = 1 + meeting = Meeting.query.get(1) + meeting_id = meeting.id + meeting_hash = meeting.get_hash("authenticated") response = client_app.post( "/meeting/join", @@ -125,12 +120,11 @@ def test_join_meeting_as_authenticated_attendee_with_modified_fullname( def test_join_meeting(client_app, app, meeting, bbb_response): - with app.app_context(): - user_id = 1 - meeting = Meeting.query.get(1) - meeting_id = meeting.id - meeting_hash = meeting.get_hash("attendee") - fullname = "Bob" + user_id = 1 + meeting = Meeting.query.get(1) + meeting_id = meeting.id + meeting_hash = meeting.get_hash("attendee") + fullname = "Bob" response = client_app.post( "/meeting/join", @@ -151,13 +145,12 @@ def test_join_meeting(client_app, app, meeting, bbb_response): def test_join_mail_meeting(client_app, app, meeting, bbb_response): - with app.app_context(): - user_id = 1 - expiration = int(time.time()) + 1000 - meeting = Meeting.query.get(1) - meeting_id = meeting.id - meeting_hash = meeting.get_mail_signin_hash(meeting_id, expiration) - fullname = "Bob" + user_id = 1 + expiration = int(time.time()) + 1000 + meeting = Meeting.query.get(1) + meeting_id = meeting.id + meeting_hash = meeting.get_mail_signin_hash(meeting_id, expiration) + fullname = "Bob" response = client_app.post( "/meeting/joinmail", @@ -180,10 +173,9 @@ def test_join_mail_meeting(client_app, app, meeting, bbb_response): def test_join_meeting_as_role( client_app, app, authenticated_user, meeting, bbb_response ): - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_id = meeting.id - fullname = "Alice+Cooper" + meeting = Meeting.query.get(1) + meeting_id = meeting.id + fullname = "Alice+Cooper" response = client_app.get(f"/meeting/join/{meeting_id}/attendee") @@ -205,9 +197,8 @@ def test_join_meeting_as_role__meeting_not_found( def test_join_meeting_as_role__not_attendee_or_moderator( client_app, app, authenticated_user, meeting, bbb_response ): - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_id = meeting.id + meeting = Meeting.query.get(1) + meeting_id = meeting.id response = client_app.get(f"/meeting/join/{meeting_id}/journalist") @@ -216,12 +207,11 @@ def test_join_meeting_as_role__not_attendee_or_moderator( def test_waiting_meeting_with_a_fullname_containing_a_slash(client_app, app, meeting): fullname_suffix = "Service EN" - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_fake_id = meeting.fake_id - user_id = meeting.user.id - h = meeting.get_hash("attendee") - fullname = "Alice/Cooper" + meeting = Meeting.query.get(1) + meeting_fake_id = meeting.fake_id + user_id = meeting.user.id + h = meeting.get_hash("attendee") + fullname = "Alice/Cooper" with app.test_request_context(): waiting_meeting_url = url_for( @@ -239,12 +229,11 @@ def test_waiting_meeting_with_a_fullname_containing_a_slash(client_app, app, mee def test_waiting_meeting_with_empty_fullname_suffix(client_app, app, meeting): - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_fake_id = meeting.fake_id - user_id = meeting.user.id - h = meeting.get_hash("attendee") - fullname = "Alice/Cooper" + meeting = Meeting.query.get(1) + meeting_fake_id = meeting.fake_id + user_id = meeting.user.id + h = meeting.get_hash("attendee") + fullname = "Alice/Cooper" with app.test_request_context(): waiting_meeting_url = url_for( diff --git a/web/tests/meeting/test_meeting.py b/web/tests/meeting/test_meeting.py index d10c3fcd..809d5a43 100644 --- a/web/tests/meeting/test_meeting.py +++ b/web/tests/meeting/test_meeting.py @@ -11,9 +11,8 @@ def mocked_is_meeting_running(mocker): def test_show_meeting(client_app, app, authenticated_user, meeting, bbb_response): - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_id = meeting.id + meeting = Meeting.query.get(1) + meeting_id = meeting.id response = client_app.get(f"/meeting/show/{meeting_id}") @@ -24,9 +23,8 @@ def test_show_meeting(client_app, app, authenticated_user, meeting, bbb_response def test_show_meeting_recording( client_app, app, authenticated_user, meeting, bbb_response ): - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_id = meeting.id + meeting = Meeting.query.get(1) + meeting_id = meeting.id response = client_app.get(f"/meeting/recordings/{meeting_id}") @@ -50,9 +48,8 @@ def test_new_meeting_when_recording_not_configured(client_app, app, authenticate def test_edit_meeting(client_app, app, authenticated_user, meeting, bbb_response): - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_id = meeting.id + meeting = Meeting.query.get(1) + meeting_id = meeting.id response = client_app.get(f"/meeting/edit/{meeting_id}") @@ -93,38 +90,36 @@ def test_save_new_meeting( assert response.status_code == 302 assert "welcome" in response.location - with app.app_context(): - meeting = Meeting.query.get(1) - - assert meeting.user_id == 1 - assert meeting.name == "Mon meeting de test" - assert meeting.welcome == "Bienvenue dans mon meeting de test" - assert meeting.maxParticipants == 5 - assert meeting.duration == 60 - assert meeting.guestPolicy is True - assert meeting.webcamsOnlyForModerator is True - assert meeting.muteOnStart is True - assert meeting.lockSettingsDisableCam is True - assert meeting.lockSettingsDisableMic is True - assert meeting.lockSettingsDisablePrivateChat is True - assert meeting.lockSettingsDisablePublicChat is True - assert meeting.lockSettingsDisableNote is True - assert meeting.moderatorOnlyMessage == "Bienvenue aux modérateurs" - assert meeting.logoutUrl == "https://log.out" - assert meeting.moderatorPW == "Motdepasse1" - assert meeting.attendeePW == "Motdepasse2" - assert meeting.record is True - assert meeting.autoStartRecording is True - assert meeting.allowStartStopRecording is True + meeting = Meeting.query.get(1) + + assert meeting.user_id == 1 + assert meeting.name == "Mon meeting de test" + assert meeting.welcome == "Bienvenue dans mon meeting de test" + assert meeting.maxParticipants == 5 + assert meeting.duration == 60 + assert meeting.guestPolicy is True + assert meeting.webcamsOnlyForModerator is True + assert meeting.muteOnStart is True + assert meeting.lockSettingsDisableCam is True + assert meeting.lockSettingsDisableMic is True + assert meeting.lockSettingsDisablePrivateChat is True + assert meeting.lockSettingsDisablePublicChat is True + assert meeting.lockSettingsDisableNote is True + assert meeting.moderatorOnlyMessage == "Bienvenue aux modérateurs" + assert meeting.logoutUrl == "https://log.out" + assert meeting.moderatorPW == "Motdepasse1" + assert meeting.attendeePW == "Motdepasse2" + assert meeting.record is True + assert meeting.autoStartRecording is True + assert meeting.allowStartStopRecording is True def test_save_existing_meeting( app, client_app, authenticated_user, meeting, mocked_is_meeting_running ): - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_id = meeting.id - assert len(Meeting.query.all()) == 1 + meeting = Meeting.query.get(1) + meeting_id = meeting.id + assert len(Meeting.query.all()) == 1 data = MEETING_DATA.copy() data["id"] = meeting_id @@ -137,31 +132,30 @@ def test_save_existing_meeting( assert response.status_code == 302 assert "welcome" in response.location - with app.app_context(): - assert len(Meeting.query.all()) == 1 - - meeting = Meeting.query.get(1) - - assert meeting.user_id == 1 - assert not meeting.name # Name can not be edited - assert meeting.welcome == "Bienvenue dans mon meeting de test" - assert meeting.maxParticipants == 5 - assert meeting.duration == 60 - assert meeting.guestPolicy is True - assert meeting.webcamsOnlyForModerator is True - assert meeting.muteOnStart is True - assert meeting.lockSettingsDisableCam is True - assert meeting.lockSettingsDisableMic is True - assert meeting.lockSettingsDisablePrivateChat is True - assert meeting.lockSettingsDisablePublicChat is True - assert meeting.lockSettingsDisableNote is True - assert meeting.moderatorOnlyMessage == "Bienvenue aux modérateurs" - assert meeting.logoutUrl == "https://log.out" - assert meeting.moderatorPW == "Motdepasse1" - assert meeting.attendeePW == "Motdepasse2" - assert meeting.record is True - assert meeting.autoStartRecording is True - assert meeting.allowStartStopRecording is True + assert len(Meeting.query.all()) == 1 + + meeting = Meeting.query.get(1) + + assert meeting.user_id == 1 + assert not meeting.name # Name can not be edited + assert meeting.welcome == "Bienvenue dans mon meeting de test" + assert meeting.maxParticipants == 5 + assert meeting.duration == 60 + assert meeting.guestPolicy is True + assert meeting.webcamsOnlyForModerator is True + assert meeting.muteOnStart is True + assert meeting.lockSettingsDisableCam is True + assert meeting.lockSettingsDisableMic is True + assert meeting.lockSettingsDisablePrivateChat is True + assert meeting.lockSettingsDisablePublicChat is True + assert meeting.lockSettingsDisableNote is True + assert meeting.moderatorOnlyMessage == "Bienvenue aux modérateurs" + assert meeting.logoutUrl == "https://log.out" + assert meeting.moderatorPW == "Motdepasse1" + assert meeting.attendeePW == "Motdepasse2" + assert meeting.record is True + assert meeting.autoStartRecording is True + assert meeting.allowStartStopRecording is True def test_save_moderatorOnlyMessage_too_long( @@ -183,8 +177,7 @@ def test_save_moderatorOnlyMessage_too_long( assert "Le formulaire contient des erreurs" in response_html assert moderator_only_message in response_html assert "Le message est trop long" in response_html - with app.app_context(): - assert not Meeting.query.all() + assert not Meeting.query.all() def test_save_no_recording_by_default( @@ -197,11 +190,10 @@ def test_save_no_recording_by_default( response = client_app.post("/meeting/save", data=data) assert response.status_code == 302 - with app.app_context(): - meeting = Meeting.query.get(1) - assert meeting.record is False - assert meeting.autoStartRecording is False - assert meeting.allowStartStopRecording is False + meeting = Meeting.query.get(1) + assert meeting.record is False + assert meeting.autoStartRecording is False + assert meeting.allowStartStopRecording is False def test_save_meeting_in_no_recording_environment( @@ -217,10 +209,9 @@ def test_save_meeting_in_no_recording_environment( assert response.status_code == 302 assert "welcome" in response.location - with app.app_context(): - assert len(Meeting.query.all()) == 1 - meeting = Meeting.query.get(1) - assert meeting.record is False + assert len(Meeting.query.all()) == 1 + meeting = Meeting.query.get(1) + assert meeting.record is False def test_create(app, meeting, mocker): @@ -234,7 +225,7 @@ class Resp: "flaskr.tasks.background_upload.delay", return_value=True ) - with app.app_context(), app.test_request_context(): + with app.test_request_context(): meeting = Meeting.query.get(1) meeting.name = "My Meeting" @@ -320,10 +311,9 @@ def test_create_without_logout_url_gets_default( ) assert response.status_code == 302 - with app.app_context(): - meeting = Meeting.query.get(1) - assert meeting - assert meeting.logoutUrl == app.config["MEETING_LOGOUT_URL"] + meeting = Meeting.query.get(1) + assert meeting + assert meeting.logoutUrl == app.config["MEETING_LOGOUT_URL"] def test_create_quick_meeting(app, monkeypatch, user, mocker): @@ -334,7 +324,7 @@ class Resp: mocked_bbb_create_request = mocker.patch("requests.post", return_value=Resp) mocker.patch("flaskr.tasks.background_upload.delay", return_value=True) - with app.app_context(), app.test_request_context(): + with app.test_request_context(): monkeypatch.setattr("flaskr.models.User.id", 1) monkeypatch.setattr("flaskr.models.User.hash", "hash") meeting = get_quick_meeting_from_user_and_random_string(user) @@ -363,9 +353,8 @@ class Resp: def test_edit_files_meeting(client_app, app, authenticated_user, meeting, bbb_response): app.config["FILE_SHARING"] = True - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_id = meeting.id + meeting = Meeting.query.get(1) + meeting_id = meeting.id response = client_app.get(f"/meeting/files/{meeting_id}") @@ -388,9 +377,8 @@ def test_deactivated_meeting_files_cannot_edit( client_app, app, authenticated_user, meeting, bbb_response ): app.config["FILE_SHARING"] = False - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_id = meeting.id + meeting = Meeting.query.get(1) + meeting_id = meeting.id response = client_app.get(f"/meeting/files/{meeting_id}") diff --git a/web/tests/meeting/test_recordings.py b/web/tests/meeting/test_recordings.py index 13fcb76b..3a52e209 100644 --- a/web/tests/meeting/test_recordings.py +++ b/web/tests/meeting/test_recordings.py @@ -116,9 +116,8 @@ class Resp: def test_get_recordings(app, meeting, bbb_getRecordings_response): - with app.app_context(): - meeting = Meeting.query.get(1) - recordings = meeting.bbb.get_recordings() + meeting = Meeting.query.get(1) + recordings = meeting.bbb.get_recordings() assert len(recordings) == 2 first_recording = recordings[0] @@ -158,9 +157,8 @@ class Resp: mocked_bbb_request = mocker.patch("requests.get", return_value=Resp) - with app.app_context(): - meeting = Meeting.query.get(1) - meeting_id = meeting.id + meeting = Meeting.query.get(1) + meeting_id = meeting.id response = client_app.post( f"meeting/{meeting_id}/recordings/recording_id", diff --git a/web/tests/test_default.py b/web/tests/test_default.py index a1c02df1..3e19adf0 100644 --- a/web/tests/test_default.py +++ b/web/tests/test_default.py @@ -1,6 +1,3 @@ -from flask import session - - def test_root__anonymous_user(client_app): response = client_app.get("/") @@ -42,20 +39,19 @@ def test_home__authenticated_user(client_app, mocker, authenticated_user): def test_change_language(client_app): - with client_app: - response = client_app.get("/faq?lang=fr") - - assert response.status_code == 200 + response = client_app.get("/faq?lang=fr") + assert response.status_code == 200 + with client_app.session_transaction() as session: assert session["lang"] == "fr" - response = client_app.get("/faq?lang=uk") - - assert response.status_code == 200 + response = client_app.get("/faq?lang=uk") + assert response.status_code == 200 + with client_app.session_transaction() as session: assert session["lang"] == "uk" - response = client_app.get("/faq") - - assert response.status_code == 200 + response = client_app.get("/faq") + assert response.status_code == 200 + with client_app.session_transaction() as session: assert session["lang"] == "uk" diff --git a/web/tests/test_user.py b/web/tests/test_user.py index fa938e01..03091759 100644 --- a/web/tests/test_user.py +++ b/web/tests/test_user.py @@ -4,38 +4,36 @@ from flaskr.models import User, get_or_create_user -def test_get_or_create_user(app): +def test_get_or_create_user(client_app): user_info = { "given_name": "Alice", "family_name": "Cooper", "preferred_username": "alice", "email": "alice@mydomain.test", } - with app.app_context(): - get_or_create_user(user_info) + get_or_create_user(user_info) - user = User.query.get(1) - assert user.given_name == "Alice" - assert user.family_name == "Cooper" - assert user.email == "alice@mydomain.test" - assert user.last_connection_utc_datetime.date() == date.today() + user = User.query.get(1) + assert user.given_name == "Alice" + assert user.family_name == "Cooper" + assert user.email == "alice@mydomain.test" + assert user.last_connection_utc_datetime.date() == date.today() -def test_update_last_connection_if_more_than_24h(app): +def test_update_last_connection_if_more_than_24h(client_app): user_info = { "given_name": "Alice", "family_name": "Cooper", "preferred_username": "alice", "email": "alice@mydomain.test", } - with app.app_context(): - with freeze_time("2021-08-10"): - get_or_create_user(user_info) + with freeze_time("2021-08-10"): + get_or_create_user(user_info) - with freeze_time("2021-08-11"): - user = User.query.get(1) - assert user.last_connection_utc_datetime.date() == date(2021, 8, 10) + with freeze_time("2021-08-11"): + user = User.query.get(1) + assert user.last_connection_utc_datetime.date() == date(2021, 8, 10) - get_or_create_user(user_info) + get_or_create_user(user_info) - assert user.last_connection_utc_datetime.date() == date(2021, 8, 11) + assert user.last_connection_utc_datetime.date() == date(2021, 8, 11) From cd9a914d5b3782335270828ade7b62df6035bff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Wed, 19 Jul 2023 11:55:15 +0200 Subject: [PATCH 06/24] chore: bump to flask-wtf 1.1.1 --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index fbd2ccf7..5d35524c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -702,13 +702,13 @@ tests = ["flask-sqlalchemy"] [[package]] name = "flask-wtf" -version = "1.0.1" +version = "1.1.1" description = "Form rendering, validation, and CSRF protection for Flask with WTForms." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "Flask-WTF-1.0.1.tar.gz", hash = "sha256:34fe5c6fee0f69b50e30f81a3b7ea16aa1492a771fe9ad0974d164610c09a6c9"}, - {file = "Flask_WTF-1.0.1-py3-none-any.whl", hash = "sha256:9d733658c80be551ce7d5bc13c7a7ac0d80df509be1e23827c847d9520f4359a"}, + {file = "Flask-WTF-1.1.1.tar.gz", hash = "sha256:41c4244e9ae626d63bed42ae4785b90667b885b1535d5a4095e1f63060d12aa9"}, + {file = "Flask_WTF-1.1.1-py3-none-any.whl", hash = "sha256:7887d6f1ebb3e17bf648647422f0944c9a469d0fcf63e3b66fb9a83037e38b2c"}, ] [package.dependencies] @@ -1975,4 +1975,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = ">=3.8.1,<4.0" -content-hash = "7f2302ad2dfe4097e49ce0bf19467ddc2648b8631751fafee661125db40b827d" +content-hash = "206ad45bcc4e2a5a47585e5eeea78e41e58878ef830af8125b0ba65b4296113b" diff --git a/pyproject.toml b/pyproject.toml index 870c6684..e7058220 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ flask-babel = "2.0.0" celery = "5.2.7" flask = "2.2.5" flask-caching = "^2.0.2" -flask-wtf = "1.0.1" +flask-wtf = "^1.1.1" redis = "4.4.4" requests = "^2.27.1" werkzeug = "^2.3.4" From 53a90fa0a5f119d8e6d095d336a254ebf173c25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89loi=20Rivard?= Date: Wed, 19 Jul 2023 11:57:49 +0200 Subject: [PATCH 07/24] refactor: add a name to the flask blueprint This will be mandatory with flask 2.3 --- web/flaskr/models.py | 6 +++--- web/flaskr/routes.py | 10 ++++++---- web/flaskr/templates/meeting/end.html | 4 ++-- web/flaskr/templates/meeting/recordings.html | 2 +- web/tests/meeting/test_join.py | 4 ++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/web/flaskr/models.py b/web/flaskr/models.py index 6f78fc73..4e175a68 100755 --- a/web/flaskr/models.py +++ b/web/flaskr/models.py @@ -712,7 +712,7 @@ def get_join_url(self, meeting_role, fullname, fullname_suffix="", create=False) ) return self.bbb.prepare_request_to_join_bbb(meeting_role, nickname).url return url_for( - "waiting_meeting", + "routes.waiting_meeting", meeting_fake_id=self.fake_id, user_id=self.user.id, h=self.get_hash(meeting_role), @@ -722,7 +722,7 @@ def get_join_url(self, meeting_role, fullname, fullname_suffix="", create=False) def get_signin_url(self, meeting_role): return current_app.config["SERVER_FQDN"] + url_for( - "signin_meeting", + "routes.signin_meeting", meeting_fake_id=self.fake_id, user_id=self.user.id, h=self.get_hash(meeting_role), @@ -740,7 +740,7 @@ def get_mail_signin_url(self): ] # remove milliseconds hash_param = self.get_mail_signin_hash(self.fake_id, expiration) return current_app.config["SERVER_FQDN"] + url_for( - "signin_mail_meeting", + "routes.signin_mail_meeting", meeting_fake_id=self.fake_id, expiration=expiration, h=hash_param, diff --git a/web/flaskr/routes.py b/web/flaskr/routes.py index 2112ec87..3fdc27ba 100755 --- a/web/flaskr/routes.py +++ b/web/flaskr/routes.py @@ -85,7 +85,7 @@ from .templates.content import FAQ_CONTENT -bp = Blueprint("", __name__) +bp = Blueprint("routes", __name__) user_provider_configuration = ProviderConfiguration( @@ -95,6 +95,7 @@ client_id=current_app.config["OIDC_CLIENT_ID"], client_secret=current_app.config["OIDC_CLIENT_SECRET"], token_endpoint_auth_method=current_app.config["OIDC_CLIENT_AUTH_METHOD"], + post_logout_redirect_uris=[f'{current_app.config.get("SERVER_FQDN")}/logout'], ), auth_request_params={"scope": current_app.config["OIDC_SCOPES"]}, ) @@ -107,6 +108,7 @@ token_endpoint_auth_method=current_app.config.get( "OIDC_ATTENDEE_CLIENT_AUTH_METHOD" ), + post_logout_redirect_uris=[f'{current_app.config.get("SERVER_FQDN")}/logout'], ), auth_request_params={ "scope": current_app.config.get("OIDC_ATTENDEE_SCOPES") @@ -675,7 +677,7 @@ def update_recording_name(meeting_id, recording_id): ) else: flash("Vous ne pouvez pas modifier cet enregistrement", "error") - return redirect(url_for("show_meeting_recording", meeting_id=meeting_id)) + return redirect(url_for("routes.show_meeting_recording", meeting_id=meeting_id)) @bp.route("/meeting/new", methods=["GET"]) @@ -1460,7 +1462,7 @@ def signin_meeting(meeting_fake_id, user_id, h): if role == "authenticated": return redirect( - url_for("join_meeting_as_authenticated", meeting_id=meeting_fake_id) + url_for("routes.join_meeting_as_authenticated", meeting_id=meeting_fake_id) ) elif not role: return redirect("/") @@ -1586,7 +1588,7 @@ def join_meeting_as_authenticated(meeting_id): fullname = get_authenticated_attendee_fullname() return redirect( url_for( - "waiting_meeting", + "routes.waiting_meeting", meeting_fake_id=meeting_id, user_id=meeting.user.id, h=meeting.get_hash(role), diff --git a/web/flaskr/templates/meeting/end.html b/web/flaskr/templates/meeting/end.html index ebbdb272..a3a2169b 100644 --- a/web/flaskr/templates/meeting/end.html +++ b/web/flaskr/templates/meeting/end.html @@ -13,10 +13,10 @@
{{ form.hidden_tag() }} - Patienter jusqu'à la fin {{ of_the_meeting }} + Patienter jusqu'à la fin {{ of_the_meeting }}
{% endblock %} {% block footer %} {% include 'footer.html' %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/web/flaskr/templates/meeting/recordings.html b/web/flaskr/templates/meeting/recordings.html index 05f20bf3..2b36bfd4 100644 --- a/web/flaskr/templates/meeting/recordings.html +++ b/web/flaskr/templates/meeting/recordings.html @@ -99,7 +99,7 @@