Merge pull request #145 from Nebucatnetzer/mypy

Mypy
This commit is contained in:
Andreas Zweili 2023-07-10 19:42:23 +02:00 committed by GitHub
commit b05c6c81d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 362 additions and 501 deletions

View File

@ -1,8 +0,0 @@
[flake8]
exclude =
*migrations*,
__init__.py,
*cache*,
venv/,
src/manage.py,
src/network_inventory/settings/*

View File

@ -51,7 +51,7 @@
pkgs.python310Packages.pip
(pkgs.writeScriptBin "dev" "${builtins.readFile ./dev.sh}")
];
PYTHON_KEYRING_BACKEND="keyring.backends.fail.Keyring";
PYTHON_KEYRING_BACKEND = "keyring.backends.fail.Keyring";
shellHook = ''
export DJANGO_SETTINGS_MODULE=network_inventory.settings.local
'';
@ -68,8 +68,10 @@
checkInputs = [ pkgs.inventoryDevEnv ];
checkPhase = ''
mkdir -p $out
flake8 . --count --show-source --statistics
pylint --rc-file pyproject.toml -j 0 -E src/
cd src/ && mypy --config-file=../pyproject.toml .
'';
DJANGO_SETTINGS_MODULE = "network_inventory.settings.ram_test";
};
tests = pkgs.stdenv.mkDerivation {
dontPatch = true;

327
poetry.lock generated
View File

@ -20,14 +20,14 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"]
[[package]]
name = "astroid"
version = "2.15.5"
version = "2.15.6"
description = "An abstract syntax tree for Python with inference support."
category = "dev"
optional = false
python-versions = ">=3.7.2"
files = [
{file = "astroid-2.15.5-py3-none-any.whl", hash = "sha256:078e5212f9885fa85fbb0cf0101978a336190aadea6e13305409d099f71b2324"},
{file = "astroid-2.15.5.tar.gz", hash = "sha256:1039262575027b441137ab4a62a793a9b43defb42c32d5670f38686207cd780f"},
{file = "astroid-2.15.6-py3-none-any.whl", hash = "sha256:389656ca57b6108f939cf5d2f9a2a825a3be50ba9d589670f393236e0a03b91c"},
{file = "astroid-2.15.6.tar.gz", hash = "sha256:903f024859b7c7687d7a7f3a3f73b17301f8e42dfd9cc9df9d4418172d3e2dbd"},
]
[package.dependencies]
@ -38,22 +38,6 @@ wrapt = [
{version = ">=1.14,<2", markers = "python_version >= \"3.11\""},
]
[[package]]
name = "autopep8"
version = "2.0.2"
description = "A tool that automatically formats Python code to conform to the PEP 8 style guide"
category = "dev"
optional = false
python-versions = ">=3.6"
files = [
{file = "autopep8-2.0.2-py2.py3-none-any.whl", hash = "sha256:86e9303b5e5c8160872b2f5ef611161b2893e9bfe8ccc7e2f76385947d57a2f1"},
{file = "autopep8-2.0.2.tar.gz", hash = "sha256:f9849cdd62108cb739dbcdbfb7fdcc9a30d1b63c4cc3e1c1f893b5360941b61c"},
]
[package.dependencies]
pycodestyle = ">=2.10.0"
tomli = {version = "*", markers = "python_version < \"3.11\""}
[[package]]
name = "black"
version = "22.12.0"
@ -92,14 +76,14 @@ uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "click"
version = "8.1.3"
version = "8.1.4"
description = "Composable command line interface toolkit"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
{file = "click-8.1.4-py3-none-any.whl", hash = "sha256:2739815aaa5d2c986a88f1e9230c55e17f0caad3d958a5e13ad0797c166db9e3"},
{file = "click-8.1.4.tar.gz", hash = "sha256:b97d0c74955da062a7d4ef92fadb583806a585b2ea81958a81bd72726cbb8e37"},
]
[package.dependencies]
@ -200,14 +184,14 @@ graph = ["objgraph (>=1.7.2)"]
[[package]]
name = "django"
version = "4.2.2"
version = "4.2.3"
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
category = "main"
optional = false
python-versions = ">=3.8"
files = [
{file = "Django-4.2.2-py3-none-any.whl", hash = "sha256:672b3fa81e1f853bb58be1b51754108ab4ffa12a77c06db86aa8df9ed0c46fe5"},
{file = "Django-4.2.2.tar.gz", hash = "sha256:2a6b6fbff5b59dd07bef10bcb019bee2ea97a30b2a656d51346596724324badf"},
{file = "Django-4.2.3-py3-none-any.whl", hash = "sha256:f7c7852a5ac5a3da5a8d5b35cc6168f31b605971441798dac845f17ca8028039"},
{file = "Django-4.2.3.tar.gz", hash = "sha256:45a747e1c5b3d6df1b141b1481e193b033fd1fdbda3ff52677dc81afdaacbaed"},
]
[package.dependencies]
@ -275,14 +259,14 @@ Django = ">=2.2"
[[package]]
name = "django-htmx"
version = "1.15.0"
version = "1.16.0"
description = "Extensions for using Django with htmx."
category = "main"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "django_htmx-1.15.0-py3-none-any.whl", hash = "sha256:b76068485905ad9f911419746f07f877633bb036c0870a0f9fc13dec42c6e425"},
{file = "django_htmx-1.15.0.tar.gz", hash = "sha256:bac7ff59bf507db6d40424f635f83889ce028a54f47663f227083413de22cabf"},
{file = "django_htmx-1.16.0-py3-none-any.whl", hash = "sha256:360d11266666e5d92bda57069f671f2c04642eb1fc071e4c4160cf9f504cbfa6"},
{file = "django_htmx-1.16.0.tar.gz", hash = "sha256:56a65045e079503877ba1354acb481030cf54da1e1f731d33c280e0a14b214cf"},
]
[package.dependencies]
@ -322,16 +306,56 @@ python-monkey-business = ">=1.0.0"
dev = ["Pillow", "black", "dj-database-url", "django-selenosis", "flake8", "pytest", "pytest-cov", "pytest-django", "pytest-xdist", "selenium"]
test = ["Pillow", "dj-database-url", "django-selenosis", "pytest", "pytest-cov", "pytest-django", "pytest-xdist", "selenium"]
[[package]]
name = "django-stubs"
version = "4.2.3"
description = "Mypy stubs for Django"
category = "dev"
optional = false
python-versions = ">=3.8"
files = [
{file = "django-stubs-4.2.3.tar.gz", hash = "sha256:dadab39b46d9ae8f37a8e879c590f39a9e042b565c03fa0c5a8f754b441b1f23"},
{file = "django_stubs-4.2.3-py3-none-any.whl", hash = "sha256:e30e2e4927ba14bec587ed2c686404b6b8e473cabe9baca445e7d2e1e0d7b14f"},
]
[package.dependencies]
django = "*"
django-stubs-ext = ">=4.2.2"
mypy = ">=1.0.0"
tomli = {version = "*", markers = "python_version < \"3.11\""}
types-pytz = "*"
types-PyYAML = "*"
typing-extensions = "*"
[package.extras]
compatible-mypy = ["mypy (>=1.4.0,<1.5.0)"]
[[package]]
name = "django-stubs-ext"
version = "4.2.2"
description = "Monkey-patching and extensions for django-stubs"
category = "dev"
optional = false
python-versions = ">=3.8"
files = [
{file = "django-stubs-ext-4.2.2.tar.gz", hash = "sha256:c69d1cc46f1c4c3b7894b685a5022c29b2a36c7cfb52e23762eaf357ebfc2c98"},
{file = "django_stubs_ext-4.2.2-py3-none-any.whl", hash = "sha256:fdacc65a14d2d4b97334b58ff178a5853ec8c8c76cec406e417916ad67536ce4"},
]
[package.dependencies]
django = "*"
typing-extensions = "*"
[[package]]
name = "django-tables2"
version = "2.5.3"
version = "2.6.0"
description = "Table/data-grid framework for Django"
category = "main"
optional = false
python-versions = "*"
files = [
{file = "django-tables2-2.5.3.tar.gz", hash = "sha256:f6c1623aac188d29aae9cf6b4de3211c96c525e49890654bec3359c181600eb9"},
{file = "django_tables2-2.5.3-py2.py3-none-any.whl", hash = "sha256:e336fdf8899a8fab110550a40cad956064bd4054818e0b972c1893b3e2542168"},
{file = "django-tables2-2.6.0.tar.gz", hash = "sha256:479eed04007cc04bcf764a6fb7a5e3955d94b878ba7f3a4bd4edbd2f7769e08d"},
{file = "django_tables2-2.6.0-py2.py3-none-any.whl", hash = "sha256:04f23c1181d93716c67085a3c324b449180fd0c5162ef4619acb0b2d9a166133"},
]
[package.dependencies]
@ -354,14 +378,14 @@ files = [
[[package]]
name = "exceptiongroup"
version = "1.1.1"
version = "1.1.2"
description = "Backport of PEP 654 (exception groups)"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"},
{file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"},
{file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"},
{file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"},
]
[package.extras]
@ -397,23 +421,6 @@ files = [
[package.dependencies]
python-dateutil = ">=2.4"
[[package]]
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 = [
{file = "flake8-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"},
{file = "flake8-6.0.0.tar.gz", hash = "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"},
]
[package.dependencies]
mccabe = ">=0.7.0,<0.8.0"
pycodestyle = ">=2.10.0,<2.11.0"
pyflakes = ">=3.0.0,<3.1.0"
[[package]]
name = "gunicorn"
version = "20.1.0"
@ -561,6 +568,53 @@ Faker = ">=5.4.0,<12.1"
[package.extras]
tests = ["Django (>=3.0)", "Flask (>=1.0)", "Marshmallow (>=3.9)", "SQLAlchemy (>=1.1.4)", "flask-sqlalchemy (>=2.1)", "mongoengine (>=0.10.1)", "peewee (>=3.7.0)", "pony (>=0.7)", "psycopg2-binary (>=2.8.4)", "pytest"]
[[package]]
name = "mypy"
version = "1.4.1"
description = "Optional static typing for Python"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "mypy-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:566e72b0cd6598503e48ea610e0052d1b8168e60a46e0bfd34b3acf2d57f96a8"},
{file = "mypy-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ca637024ca67ab24a7fd6f65d280572c3794665eaf5edcc7e90a866544076878"},
{file = "mypy-1.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dde1d180cd84f0624c5dcaaa89c89775550a675aff96b5848de78fb11adabcd"},
{file = "mypy-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8c4d8e89aa7de683e2056a581ce63c46a0c41e31bd2b6d34144e2c80f5ea53dc"},
{file = "mypy-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:bfdca17c36ae01a21274a3c387a63aa1aafe72bff976522886869ef131b937f1"},
{file = "mypy-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7549fbf655e5825d787bbc9ecf6028731973f78088fbca3a1f4145c39ef09462"},
{file = "mypy-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98324ec3ecf12296e6422939e54763faedbfcc502ea4a4c38502082711867258"},
{file = "mypy-1.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:141dedfdbfe8a04142881ff30ce6e6653c9685b354876b12e4fe6c78598b45e2"},
{file = "mypy-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8207b7105829eca6f3d774f64a904190bb2231de91b8b186d21ffd98005f14a7"},
{file = "mypy-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:16f0db5b641ba159eff72cff08edc3875f2b62b2fa2bc24f68c1e7a4e8232d01"},
{file = "mypy-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:470c969bb3f9a9efcedbadcd19a74ffb34a25f8e6b0e02dae7c0e71f8372f97b"},
{file = "mypy-1.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5952d2d18b79f7dc25e62e014fe5a23eb1a3d2bc66318df8988a01b1a037c5b"},
{file = "mypy-1.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:190b6bab0302cec4e9e6767d3eb66085aef2a1cc98fe04936d8a42ed2ba77bb7"},
{file = "mypy-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9d40652cc4fe33871ad3338581dca3297ff5f2213d0df345bcfbde5162abf0c9"},
{file = "mypy-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:01fd2e9f85622d981fd9063bfaef1aed6e336eaacca00892cd2d82801ab7c042"},
{file = "mypy-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2460a58faeea905aeb1b9b36f5065f2dc9a9c6e4c992a6499a2360c6c74ceca3"},
{file = "mypy-1.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2746d69a8196698146a3dbe29104f9eb6a2a4d8a27878d92169a6c0b74435b6"},
{file = "mypy-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae704dcfaa180ff7c4cfbad23e74321a2b774f92ca77fd94ce1049175a21c97f"},
{file = "mypy-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:43d24f6437925ce50139a310a64b2ab048cb2d3694c84c71c3f2a1626d8101dc"},
{file = "mypy-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c482e1246726616088532b5e964e39765b6d1520791348e6c9dc3af25b233828"},
{file = "mypy-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43b592511672017f5b1a483527fd2684347fdffc041c9ef53428c8dc530f79a3"},
{file = "mypy-1.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34a9239d5b3502c17f07fd7c0b2ae6b7dd7d7f6af35fbb5072c6208e76295816"},
{file = "mypy-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5703097c4936bbb9e9bce41478c8d08edd2865e177dc4c52be759f81ee4dd26c"},
{file = "mypy-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e02d700ec8d9b1859790c0475df4e4092c7bf3272a4fd2c9f33d87fac4427b8f"},
{file = "mypy-1.4.1-py3-none-any.whl", hash = "sha256:45d32cec14e7b97af848bddd97d85ea4f0db4d5a149ed9676caa4eb2f7402bb4"},
{file = "mypy-1.4.1.tar.gz", hash = "sha256:9bbcd9ab8ea1f2e1c8031c21445b511442cc45c89951e49bbf852cbb70755b1b"},
]
[package.dependencies]
mypy-extensions = ">=1.0.0"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
typing-extensions = ">=4.1.0"
[package.extras]
dmypy = ["psutil (>=4.0)"]
install-types = ["pip"]
python2 = ["typed-ast (>=1.4.0,<2)"]
reports = ["lxml"]
[[package]]
name = "mypy-extensions"
version = "1.0.0"
@ -613,28 +667,16 @@ files = [
{file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"},
]
[[package]]
name = "pep8"
version = "1.7.1"
description = "Python style guide checker"
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "pep8-1.7.1-py2.py3-none-any.whl", hash = "sha256:b22cfae5db09833bb9bd7c8463b53e1a9c9b39f12e304a8d0bba729c501827ee"},
{file = "pep8-1.7.1.tar.gz", hash = "sha256:fe249b52e20498e59e0b5c5256aa52ee99fc295b26ec9eaa85776ffdb9fe6374"},
]
[[package]]
name = "platformdirs"
version = "3.8.0"
version = "3.8.1"
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 = [
{file = "platformdirs-3.8.0-py3-none-any.whl", hash = "sha256:ca9ed98ce73076ba72e092b23d3c93ea6c4e186b3f1c3dad6edd98ff6ffcca2e"},
{file = "platformdirs-3.8.0.tar.gz", hash = "sha256:b0cabcb11063d21a0b261d557acb0a9d2126350e63b70cdf7db6347baea456dc"},
{file = "platformdirs-3.8.1-py3-none-any.whl", hash = "sha256:cec7b889196b9144d088e4c57d9ceef7374f6c39694ad1577a0aab50d27ea28c"},
{file = "platformdirs-3.8.1.tar.gz", hash = "sha256:f87ca4fcff7d2b0f81c6a748a77973d7af0f4d526f98f308477c3c436c74d528"},
]
[package.extras]
@ -729,30 +771,6 @@ files = [
{file = "psycopg2_binary-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:f6a88f384335bb27812293fdb11ac6aee2ca3f51d3c7820fe03de0a304ab6249"},
]
[[package]]
name = "pycodestyle"
version = "2.10.0"
description = "Python style guide checker"
category = "dev"
optional = false
python-versions = ">=3.6"
files = [
{file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"},
{file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"},
]
[[package]]
name = "pyflakes"
version = "3.0.1"
description = "passive checker of Python programs"
category = "dev"
optional = false
python-versions = ">=3.6"
files = [
{file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"},
{file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"},
]
[[package]]
name = "pylint"
version = "2.17.4"
@ -783,6 +801,41 @@ typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""
spelling = ["pyenchant (>=3.2,<4.0)"]
testutils = ["gitpython (>3)"]
[[package]]
name = "pylint-django"
version = "2.5.3"
description = "A Pylint plugin to help Pylint understand the Django web framework"
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "pylint-django-2.5.3.tar.gz", hash = "sha256:0ac090d106c62fe33782a1d01bda1610b761bb1c9bf5035ced9d5f23a13d8591"},
{file = "pylint_django-2.5.3-py3-none-any.whl", hash = "sha256:56b12b6adf56d548412445bd35483034394a1a94901c3f8571980a13882299d5"},
]
[package.dependencies]
pylint = ">=2.0,<3"
pylint-plugin-utils = ">=0.7"
[package.extras]
for-tests = ["coverage", "django-tables2", "django-tastypie", "factory-boy", "pylint (>=2.13)", "pytest", "wheel"]
with-django = ["Django"]
[[package]]
name = "pylint-plugin-utils"
version = "0.8.2"
description = "Utilities and helpers for writing Pylint plugins"
category = "dev"
optional = false
python-versions = ">=3.7,<4.0"
files = [
{file = "pylint_plugin_utils-0.8.2-py3-none-any.whl", hash = "sha256:ae11664737aa2effbf26f973a9e0b6779ab7106ec0adc5fe104b0907ca04e507"},
{file = "pylint_plugin_utils-0.8.2.tar.gz", hash = "sha256:d3cebf68a38ba3fba23a873809155562571386d4c1b03e5b4c4cc26c3eee93e4"},
]
[package.dependencies]
pylint = ">=1.7"
[[package]]
name = "pytest"
version = "7.4.0"
@ -900,14 +953,14 @@ test = ["coverage", "pycodestyle", "pyflakes", "pylint", "pytest", "pytest-cov"]
[[package]]
name = "python-lsp-server"
version = "1.7.3"
version = "1.7.4"
description = "Python Language Server for the Language Server Protocol"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "python-lsp-server-1.7.3.tar.gz", hash = "sha256:a31b0525be6ec831c7d2b476b744e5aa5074633e1d1b77ee97f332cde15983ea"},
{file = "python_lsp_server-1.7.3-py3-none-any.whl", hash = "sha256:f4ae64834da1d4312067a8ee05a76c7652167c3c90d1cef44022366d695c4c0e"},
{file = "python-lsp-server-1.7.4.tar.gz", hash = "sha256:c84254485a4d9431b24ecefd59741d21c00165611bcf6037bd7d54d0ed06a197"},
{file = "python_lsp_server-1.7.4-py3-none-any.whl", hash = "sha256:f8053f7aefcb60af4e91f3fab1a093b15ba0c4688ba67e6ab69e7b73e997b2cb"},
]
[package.dependencies]
@ -947,29 +1000,6 @@ files = [
[package.dependencies]
six = ">=1.7.0"
[[package]]
name = "pytoolconfig"
version = "1.2.5"
description = "Python tool configuration"
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "pytoolconfig-1.2.5-py3-none-any.whl", hash = "sha256:239ba9d3e537b91d0243275a497700ea39a5e259ddb80421c366e3b288bf30fe"},
{file = "pytoolconfig-1.2.5.tar.gz", hash = "sha256:a50f9dfe23b03a9d40414c1fdf902fefbeae12f2ac75a3c8f915944d6ffac279"},
]
[package.dependencies]
packaging = ">=22.0"
platformdirs = {version = ">=1.4.4", optional = true, markers = "extra == \"global\""}
tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
[package.extras]
doc = ["sphinx (>=4.5.0)", "tabulate (>=0.8.9)"]
gendocs = ["pytoolconfig[doc]", "sphinx (>=4.5.0)", "sphinx-autodoc-typehints (>=1.18.1)", "sphinx-rtd-theme (>=1.0.0)"]
global = ["platformdirs (>=1.4.4)"]
validation = ["pydantic (>=1.7.4)"]
[[package]]
name = "pyyaml"
version = "6.0"
@ -1020,25 +1050,6 @@ files = [
{file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
]
[[package]]
name = "rope"
version = "1.8.0"
description = "a python refactoring library..."
category = "dev"
optional = false
python-versions = ">=3.7"
files = [
{file = "rope-1.8.0-py3-none-any.whl", hash = "sha256:0767424ed40ce237dcf1c1f5088054fef960e5b19f4a0850783a259a3600d7bd"},
{file = "rope-1.8.0.tar.gz", hash = "sha256:3de1d1f1cf2412540c6a150067fe25298175e7c2b72455b6ca8395f61678da82"},
]
[package.dependencies]
pytoolconfig = {version = ">=1.2.2", extras = ["global"]}
[package.extras]
dev = ["build (>=0.7.0)", "pip-tools (>=6.12.1)", "pre-commit (>=2.20.0)", "pytest (>=7.0.1)", "pytest-timeout (>=2.1.0)", "toml (>=0.10.2)"]
doc = ["pytoolconfig[doc]", "sphinx (>=4.5.0)", "sphinx-autodoc-typehints (>=1.18.1)", "sphinx-rtd-theme (>=1.0.0)"]
[[package]]
name = "setuptools"
version = "68.0.0"
@ -1109,16 +1120,40 @@ files = [
{file = "tomlkit-0.11.8.tar.gz", hash = "sha256:9330fc7faa1db67b541b28e62018c17d20be733177d290a13b24c62d1614e0c3"},
]
[[package]]
name = "types-pytz"
version = "2023.3.0.0"
description = "Typing stubs for pytz"
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "types-pytz-2023.3.0.0.tar.gz", hash = "sha256:ecdc70d543aaf3616a7e48631543a884f74205f284cefd6649ddf44c6a820aac"},
{file = "types_pytz-2023.3.0.0-py3-none-any.whl", hash = "sha256:4fc2a7fbbc315f0b6630e0b899fd6c743705abe1094d007b0e612d10da15e0f3"},
]
[[package]]
name = "types-pyyaml"
version = "6.0.12.10"
description = "Typing stubs for PyYAML"
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "types-PyYAML-6.0.12.10.tar.gz", hash = "sha256:ebab3d0700b946553724ae6ca636ea932c1b0868701d4af121630e78d695fc97"},
{file = "types_PyYAML-6.0.12.10-py3-none-any.whl", hash = "sha256:662fa444963eff9b68120d70cda1af5a5f2aa57900003c2006d7626450eaae5f"},
]
[[package]]
name = "typing-extensions"
version = "4.6.3"
version = "4.7.1"
description = "Backported and Experimental Type Hints for Python 3.7+"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "typing_extensions-4.6.3-py3-none-any.whl", hash = "sha256:88a4153d8505aabbb4e13aacb7c486c2b4a33ca3b3f807914a9b4c844c471c26"},
{file = "typing_extensions-4.6.3.tar.gz", hash = "sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5"},
{file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"},
{file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"},
]
[[package]]
@ -1289,19 +1324,7 @@ files = [
{file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"},
]
[[package]]
name = "yapf"
version = "0.32.0"
description = "A formatter for Python code."
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "yapf-0.32.0-py2.py3-none-any.whl", hash = "sha256:8fea849025584e486fd06d6ba2bed717f396080fd3cc236ba10cb97c4c51cf32"},
{file = "yapf-0.32.0.tar.gz", hash = "sha256:a3f5085d37ef7e3e004c4ba9f9b3e40c54ff1901cd111f05145ae313a7c67d1b"},
]
[metadata]
lock-version = "2.0"
python-versions = "^3.9"
content-hash = "95419a1919aadc2d6bbd680b89480fa6b53f4dc29d2f7e2ea7ec7f849bfba1ba"
content-hash = "56454bd1da936edf92442e1f87d0cdb1ace8cda9297e33f4eba8a98230cc4610"

View File

@ -1,5 +1,8 @@
[tool.black]
line-length = 79
[tool.pylint]
max-line-length = 88
load-plugins = [
"pylint_django",
]
[tool.poetry]
name = "network_inventory"
@ -11,6 +14,45 @@ packages = [
{ include = "src" },
]
[tool.mypy]
exclude = [
"tests/",
]
plugins = ["mypy_django_plugin.main"]
mypy_path = "./src"
# Start off with these
warn_unused_configs = true
warn_redundant_casts = true
warn_unused_ignores = true
# Getting these passing should be easy
strict_equality = true
strict_concatenate = true
# Strongly recommend enabling this one as soon as you can
#check_untyped_defs = true
# These shouldn't be too much additional work, but may be tricky to
# get passing if you use a lot of untyped libraries
#disallow_subclassing_any = true
#disallow_untyped_decorators = true
#disallow_any_generics = true
[tool.django-stubs]
django_settings_module = "network_inventory.settings.local"
[[tool.mypy.overrides]]
module = [
"nested_admin.*",
"django_tables2.*",
"floppyforms.*",
"django_filters.*",
"crispy_forms.*",
"mixer.*",
"guardian.*",
]
ignore_missing_imports = true
[tool.poetry.group.main.dependencies]
python = "^3.9"
Django = "^4.1.3"
@ -27,21 +69,19 @@ psycopg2-binary = "^2.9.5"
PyYAML = "^6.0"
[tool.poetry.group.dev.dependencies]
autopep8 = "^2.0.0"
black = "^22.10.0"
coverage = "^6.5.0"
flake8 = "^6.0.0"
jedi = "^0.18.2"
mixer = "^7.2.2"
pep8 = "^1.7.1"
pylint = "^2.15.8"
pytest = "^7.2.0"
pytest-cov = "^4.0.0"
pytest-django = "^4.5.2"
pytest-xdist = "^3.1.0"
rope = "^1.5.1"
yapf = "^0.32.0"
python-lsp-server = "^1.7.3"
mypy = "^1.4.1"
django-stubs = "^4.2.3"
pylint-django = "^2.5.3"
execnet = "~1.9.0"
[build-system]
requires = ["poetry-core>=1.0.0"]

View File

@ -11,8 +11,6 @@ def backup_view_permission(old_fuction):
if user.has_perm("customers.view_customer", backup.computer.customer):
return old_fuction(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return HttpResponseForbidden("You're not allowed to access this device.")
return new_function

View File

@ -20,18 +20,12 @@ class Backup(models.Model):
computer = models.ForeignKey(
Computer, related_name="source_computer", on_delete=models.CASCADE
)
method = models.ForeignKey(
BackupMethod, models.SET_NULL, blank=True, null=True
)
software = models.ForeignKey(
Software, models.SET_NULL, blank=True, null=True
)
method = models.ForeignKey(BackupMethod, models.SET_NULL, blank=True, null=True)
software = models.ForeignKey(Software, models.SET_NULL, blank=True, null=True)
source_path = models.CharField(max_length=200, blank=True)
exec_time = models.TimeField(null=True, blank=True)
exec_days = models.ManyToManyField(Weekday, blank=True)
target_device = models.ManyToManyField(
Computer, through="TargetDevice", blank=True
)
target_device = models.ManyToManyField(Computer, through="TargetDevice", blank=True)
class Meta:
ordering = ["name"]
@ -50,9 +44,7 @@ class Backup(models.Model):
class TargetDevice(models.Model):
device = models.ForeignKey(
Computer, models.SET_NULL, blank=True, null=True
)
device = models.ForeignKey(Computer, models.SET_NULL, blank=True, null=True)
backup = models.ForeignKey(Backup, on_delete=models.CASCADE)
target_path = models.CharField(max_length=200, blank=True)

View File

@ -53,9 +53,7 @@ def test_backup_detail_view_with_target_device(create_admin_user):
software=mixer.SELECT,
method=mixer.SELECT,
)
mixer.blend(
"backups.TargetDevice", device=target_computer, backup=mixer.SELECT
)
mixer.blend("backups.TargetDevice", device=target_computer, backup=mixer.SELECT)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/backup/" + str(backup.id) + "/")
@ -79,9 +77,7 @@ def test_backup_detail_view_with_notification(create_admin_user):
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/backup/" + str(backup.id) + "/")
assert response.status_code == 200 and helper.in_content(
response, notification
)
assert response.status_code == 200 and helper.in_content(response, notification)
def test_backup_detail_view_with_day_relation(create_admin_user):

View File

@ -23,9 +23,7 @@ def test_customer_backup_table(create_admin_user):
computer = mixer.blend("computers.Computer", customer=customer)
backup = mixer.blend("backups.Backup", computer=computer)
response = client.get("/customer/" + str(customer.id) + "/backups/")
assert response.status_code == 200 and helper.in_content(
response, backup.name
)
assert response.status_code == 200 and helper.in_content(response, backup.name)
def test_customer_backup_table_no_backup(create_admin_user):

View File

@ -3,9 +3,7 @@ from django.urls import path
from . import views
urlpatterns = [
path(
"customer/<int:pk>/backups/", views.backups_table_view, name="backups"
),
path("customer/<int:pk>/backups/", views.backups_table_view, name="backups"),
path("backup/<int:pk>/", views.backup_detail_view, name="backup"),
path(
"create/backup-for-computer/<int:pk>/",

View File

@ -47,7 +47,7 @@ def backup_detail_view(request, pk):
class BackupCreateView(LoginRequiredMixin, CreateView):
model = Backup
template_name = "backups/backup_create.html"
fields = "__all__"
fields = "__all__" # type: ignore
def get_success_url(self):
return reverse("computer", args=(self.computer.pk,))
@ -63,7 +63,7 @@ class BackupCreateView(LoginRequiredMixin, CreateView):
}
class BackupDeleteView(LoginRequiredMixin, DeleteView):
class BackupDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = Backup
template_name = "backups/backup_confirm_delete.html"
@ -71,7 +71,7 @@ class BackupDeleteView(LoginRequiredMixin, DeleteView):
return reverse("computer", args=(self.object.computer.pk,))
class BackupDeleteFromTableView(LoginRequiredMixin, DeleteView):
class BackupDeleteFromTableView(LoginRequiredMixin, DeleteView): # type: ignore
model = Backup
template_name = "backups/backup_confirm_delete.html"

View File

@ -26,62 +26,64 @@ from .models import (
)
class SoftwareInLine(nested_admin.NestedStackedInline):
class SoftwareInLine(nested_admin.NestedStackedInline): # pylint: disable=no-member
model = ComputerSoftwareRelation
extra = 0
verbose_name_plural = "Software"
class RamInLine(nested_admin.NestedStackedInline):
class RamInLine(nested_admin.NestedStackedInline): # pylint: disable=no-member
model = ComputerRamRelation
extra = 0
verbose_name_plural = "RAM Modules"
class DiskInLine(nested_admin.NestedStackedInline):
class DiskInLine(nested_admin.NestedStackedInline): # pylint: disable=no-member
model = ComputerDiskRelation
extra = 0
verbose_name_plural = "Disks"
class DisksInRaidInLine(nested_admin.NestedStackedInline):
class DisksInRaidInLine(nested_admin.NestedStackedInline): # pylint: disable=no-member
model = DisksInRaid
extra = 0
verbose_name_plural = "Disks in RAID"
class CpusInLine(nested_admin.NestedStackedInline):
class CpusInLine(nested_admin.NestedStackedInline): # pylint: disable=no-member
model = ComputerCpuRelation
extra = 0
verbose_name_plural = "CPUs"
class GpusInLine(nested_admin.NestedStackedInline):
class GpusInLine(nested_admin.NestedStackedInline): # pylint: disable=no-member
model = ComputerGpuRelation
extra = 0
verbose_name_plural = "GPUs"
class RaidInLine(nested_admin.NestedStackedInline):
class RaidInLine(nested_admin.NestedStackedInline): # pylint: disable=no-member
model = Raid
extra = 0
verbose_name_plural = "RAID"
inlines = (DisksInRaidInLine,)
class DeviceInNetInline(nested_admin.NestedStackedInline):
class DeviceInNetInline(nested_admin.NestedStackedInline): # pylint: disable=no-member
model = DeviceInNet
extra = 0
verbose_name_plural = "Nets"
class LicenseWithComputerInLine(nested_admin.NestedStackedInline):
class LicenseWithComputerInLine(
nested_admin.NestedStackedInline
): # pylint: disable=no-member
model = LicenseWithComputer
extra = 0
verbose_name_plural = "Licenses"
class ComputerAdmin(nested_admin.NestedModelAdmin):
class ComputerAdmin(nested_admin.NestedModelAdmin): # pylint: disable=no-member
list_display = ("name", "host")
inlines = (
SoftwareInLine,

View File

@ -41,15 +41,9 @@ class ComputerUpdateForm(forms.ModelForm):
def __init__(self, request, *args, **kwargs):
super(ComputerUpdateForm, self).__init__(*args, **kwargs)
customers = utils.objects_for_allowed_customers(
Customer, user=request.user
)
locations = utils.objects_for_allowed_customers(
Location, user=request.user
)
hosts = utils.objects_for_allowed_customers(
Computer, user=request.user
)
customers = utils.objects_for_allowed_customers(Customer, user=request.user)
locations = utils.objects_for_allowed_customers(Location, user=request.user)
hosts = utils.objects_for_allowed_customers(Computer, user=request.user)
users = utils.objects_for_allowed_customers(User, user=request.user)
self.fields["customer"].queryset = customers
self.fields["location"].queryset = locations

View File

@ -23,12 +23,8 @@ class Computer(Device):
ram = models.ManyToManyField(Ram, through="ComputerRamRelation")
gpu = models.ManyToManyField(Gpu, through="ComputerGpuRelation")
disks = models.ManyToManyField(Disk, through="ComputerDiskRelation")
software = models.ManyToManyField(
Software, through="ComputerSoftwareRelation"
)
host = models.ForeignKey(
"self", null=True, blank=True, on_delete=models.CASCADE
)
software = models.ManyToManyField(Software, through="ComputerSoftwareRelation")
host = models.ForeignKey("self", null=True, blank=True, on_delete=models.CASCADE)
allocated_space = models.IntegerField(null=True, blank=True)
def __str__(self):

View File

@ -12,9 +12,7 @@ class RaidType(Category):
class Raid(models.Model):
usable_space = models.IntegerField(blank=True, null=True)
raid_type = models.ForeignKey(
RaidType, models.SET_NULL, blank=True, null=True
)
raid_type = models.ForeignKey(RaidType, models.SET_NULL, blank=True, null=True)
computer = models.ForeignKey(Computer, on_delete=models.CASCADE)
def __str__(self):

View File

@ -15,15 +15,11 @@ def test_computer_detail_view_not_logged_in():
def test_computer_detail_view(create_admin_user):
create_admin_user()
computer = mixer.blend(
"computers.Computer", customer=mixer.SELECT, os=mixer.SELECT
)
computer = mixer.blend("computers.Computer", customer=mixer.SELECT, os=mixer.SELECT)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/computer/" + str(computer.id) + "/")
assert response.status_code == 200 and helper.in_content(
response, computer
)
assert response.status_code == 200 and helper.in_content(response, computer)
def test_computer_detail_view_not_found(create_admin_user):
@ -43,9 +39,7 @@ def test_computer_detail_view_ram_relation(create_admin_user):
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/computer/" + str(computer.id) + "/")
assert response.status_code == 200 and helper.in_content(
response, "RAM Modules:"
)
assert response.status_code == 200 and helper.in_content(response, "RAM Modules:")
def test_computer_detail_view_raid_relation(create_admin_user):
@ -53,9 +47,7 @@ def test_computer_detail_view_raid_relation(create_admin_user):
computer = mixer.blend("computers.Computer", customer=mixer.SELECT)
raid_type = mixer.blend("computers.RaidType")
disk = mixer.blend("computers.Disk")
raid = mixer.blend(
"computers.Raid", computer=computer, raid_type=raid_type
)
raid = mixer.blend("computers.Raid", computer=computer, raid_type=raid_type)
mixer.blend("computers.DisksInRaid", raid=raid, disk=disk)
client = Client()
client.login(username="pharma-admin", password="password")

View File

@ -12,9 +12,7 @@ def test_computer_create_form(create_admin_user):
fixture = create_admin_user()
user = mixer.blend("core.InventoryUser", customer=fixture["customer"])
form = forms.ComputerCreateForm(user=user, data={})
assert (
form.is_valid() is False
), "Should be false because no data was given"
assert form.is_valid() is False, "Should be false because no data was given"
data = {"name": "pharma-pc1", "customer": 3}
form = forms.ComputerCreateForm(user=user, data=data)
@ -32,9 +30,7 @@ def test_computer_update_form(create_admin_user):
request = HttpRequest()
request.user = fixture["admin"]
form = forms.ComputerUpdateForm(request, data={})
assert (
form.is_valid() is False
), "Should be false because no data was given"
assert form.is_valid() is False, "Should be false because no data was given"
data = {"name": "pharma-pc1", "customer": 20356}
form = forms.ComputerUpdateForm(request, data=data)

View File

@ -27,6 +27,4 @@ def test_computer_list_view(create_admin_user):
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/computers/all/")
assert response.status_code == 200 and helper.in_content(
response, computer
)
assert response.status_code == 200 and helper.in_content(response, computer)

View File

@ -21,9 +21,7 @@ def test_customer_computer_table(create_admin_user):
client.login(username="pharma-admin", password="password")
computer = mixer.blend("computers.Computer", customer=mixer.SELECT)
response = client.get("/customer/" + str(customer.id) + "/computers/")
assert response.status_code == 200 and helper.in_content(
response, computer
)
assert response.status_code == 200 and helper.in_content(response, computer)
def test_customer_computer_table_no_computer(create_admin_user):

View File

@ -41,9 +41,7 @@ from .tables import ComputersTable
@login_required
def computer_detail_view(request, pk):
device = utils.get_object_with_view_permission(
Computer, user=request.user, pk=pk
)
device = utils.get_object_with_view_permission(Computer, user=request.user, pk=pk)
disks_relations = ComputerDiskRelation.objects.filter(computer=pk)
warranty_relations = Warranty.objects.filter(device=pk)
ram_relations = ComputerRamRelation.objects.filter(computer=pk)
@ -76,9 +74,7 @@ def computer_detail_view(request, pk):
@login_required
def computers_table_view(request, pk):
table = ComputersTable(
utils.get_objects_for_customer(
Computer, user=request.user, customer_pk=pk
)
utils.get_objects_for_customer(Computer, user=request.user, customer_pk=pk)
)
RequestConfig(request).configure(table)
return render(
@ -139,9 +135,7 @@ def computer_update_view(request, pk):
A view to create a customer.
"""
template_name = "computers/computer_update.html"
computer = utils.get_object_with_view_permission(
Computer, user=request.user, pk=pk
)
computer = utils.get_object_with_view_permission(Computer, user=request.user, pk=pk)
if request.method == "POST":
form = ComputerUpdateForm(request, request.POST, instance=computer)
if form.is_valid():
@ -152,7 +146,7 @@ def computer_update_view(request, pk):
return TemplateResponse(request, template_name, {"form": form})
class ComputerDeleteView(LoginRequiredMixin, DeleteView):
class ComputerDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = Computer
def get_success_url(self):
@ -178,7 +172,7 @@ class ComputerRamRelationCreateView(LoginRequiredMixin, CreateView):
}
class ComputerRamRelationDeleteView(LoginRequiredMixin, DeleteView):
class ComputerRamRelationDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = ComputerRamRelation
template_name = "computers/relation_confirm_delete.html"
@ -205,7 +199,7 @@ class ComputerCpuRelationCreateView(LoginRequiredMixin, CreateView):
}
class ComputerCpuRelationDeleteView(LoginRequiredMixin, DeleteView):
class ComputerCpuRelationDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = ComputerCpuRelation
template_name = "computers/relation_confirm_delete.html"
@ -232,7 +226,7 @@ class ComputerGpuRelationCreateView(LoginRequiredMixin, CreateView):
}
class ComputerGpuRelationDeleteView(LoginRequiredMixin, DeleteView):
class ComputerGpuRelationDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = ComputerGpuRelation
template_name = "computers/relation_confirm_delete.html"
@ -259,7 +253,7 @@ class ComputerDiskRelationCreateView(LoginRequiredMixin, CreateView):
}
class ComputerDiskRelationDeleteView(LoginRequiredMixin, DeleteView):
class ComputerDiskRelationDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = ComputerDiskRelation
template_name = "computers/relation_confirm_delete.html"
@ -286,7 +280,7 @@ class ComputerSoftwareRelationCreateView(LoginRequiredMixin, CreateView):
}
class ComputerSoftwareRelationDeleteView(LoginRequiredMixin, DeleteView):
class ComputerSoftwareRelationDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = ComputerSoftwareRelation
template_name = "computers/relation_confirm_delete.html"
@ -313,7 +307,7 @@ class RaidCreateView(LoginRequiredMixin, CreateView):
}
class RaidDeleteView(LoginRequiredMixin, DeleteView):
class RaidDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = Raid
template_name = "computers/relation_confirm_delete.html"

View File

@ -22,9 +22,7 @@ def django_db_setup(django_db_setup, django_db_blocker):
def create_admin_user():
def _create_admin_user():
User = get_user_model()
admin = User.objects.create_user(
"pharma-admin", "admin@pharma.com", "password"
)
admin = User.objects.create_user("pharma-admin", "admin@pharma.com", "password")
customer = mixer.blend("customers.Customer")
group = Group.objects.create(name="Pharma Corp. Admin")
admin.groups.add(group)

View File

@ -15,9 +15,7 @@ def test_get_object_with_view_permission(create_admin_user):
fixture = create_admin_user()
customer = fixture["customer"]
admin = fixture["admin"]
object = utils.get_object_with_view_permission(
Customer, user=admin, pk=customer.id
)
object = utils.get_object_with_view_permission(Customer, user=admin, pk=customer.id)
assert object == customer
@ -26,9 +24,7 @@ def test_get_object_with_view_permission_device(create_admin_user):
customer = fixture["customer"]
admin = fixture["admin"]
device = mixer.blend(Device, customer=customer)
object = utils.get_object_with_view_permission(
Device, user=admin, pk=device.id
)
object = utils.get_object_with_view_permission(Device, user=admin, pk=device.id)
assert object == device
@ -37,9 +33,7 @@ def test_get_object_without_view_permission(create_admin_user):
customer = mixer.blend(Customer)
admin = fixture["admin"]
with pytest.raises(Http404):
utils.get_object_with_view_permission(
Customer, user=admin, pk=customer.id
)
utils.get_object_with_view_permission(Customer, user=admin, pk=customer.id)
def test_get_object_without_view_permission_device(create_admin_user):

View File

@ -16,9 +16,7 @@ def test_get_objects_for_customer_with_customer(create_admin_user):
customer = fixture["customer"]
admin = fixture["admin"]
with pytest.raises(Exception):
utils.get_objects_for_customer(
Customer, user=admin, customer_pk=customer.id
)
utils.get_objects_for_customer(Customer, user=admin, customer_pk=customer.id)
def test_get_objects_for_customer_device(create_admin_user):
@ -37,9 +35,7 @@ def test_get_all_objects_for_unallowed_customers(create_admin_user):
customer = mixer.blend(Customer)
admin = fixture["admin"]
with pytest.raises(Http404):
utils.get_objects_for_customer(
Customer, user=admin, customer_pk=customer.id
)
utils.get_objects_for_customer(Customer, user=admin, customer_pk=customer.id)
def test_get_all_objects_for_unallowed_customers_device(create_admin_user):
@ -48,6 +44,4 @@ def test_get_all_objects_for_unallowed_customers_device(create_admin_user):
admin = fixture["admin"]
mixer.blend(Device, customer=customer)
with pytest.raises(Http404):
utils.get_objects_for_customer(
Device, user=admin, customer_pk=customer.id
)
utils.get_objects_for_customer(Device, user=admin, customer_pk=customer.id)

View File

@ -34,9 +34,7 @@ def _get_customers(user):
user : django.contrib.auth.models.User
"""
return get_objects_for_user(
user, "customers.view_customer", klass=Customer
)
return get_objects_for_user(user, "customers.view_customer", klass=Customer)
def get_object_with_view_permission(model, user=None, pk=None):

View File

@ -10,8 +10,6 @@ def customer_view_permission(old_function):
if user.has_perm("customers.view_customer", customer):
return old_function(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this page."
)
return HttpResponseForbidden("You're not allowed to access this page.")
return new_function

View File

@ -43,4 +43,4 @@ class DummyLocation(models.Model):
location = models.ForeignKey(Location, on_delete=models.CASCADE)
def __str__(self):
return self.location
return self.location.name

View File

@ -6,9 +6,7 @@ from core.tables import CoreTable
class CustomersTable(CoreTable):
name = tables.LinkColumn("customer", args=[A("pk")])
nets = tables.LinkColumn(
"nets", text="Nets", args=[A("pk")], orderable=False
)
nets = tables.LinkColumn("nets", text="Nets", args=[A("pk")], orderable=False)
computers = tables.LinkColumn(
"computers", text="Computers", args=[A("pk")], orderable=False
)
@ -21,12 +19,8 @@ class CustomersTable(CoreTable):
licenses = tables.LinkColumn(
"licenses", text="Licenses", args=[A("pk")], orderable=False
)
users = tables.LinkColumn(
"users", text="Users", args=[A("pk")], orderable=False
)
groups = tables.LinkColumn(
"groups", text="Groups", args=[A("pk")], orderable=False
)
users = tables.LinkColumn("users", text="Users", args=[A("pk")], orderable=False)
groups = tables.LinkColumn("groups", text="Groups", args=[A("pk")], orderable=False)
project_manager = tables.Column(verbose_name="Project Manager")
delete = tables.LinkColumn(
"customer_delete",

View File

@ -42,24 +42,12 @@ def test_customer_list_view(create_admin_user):
assert (
response.status_code == 200
and helper.in_content(response, customer)
and helper.in_content(
response, "/customer/" + str(customer.id) + "/nets/"
)
and helper.in_content(
response, "/customer/" + str(customer.id) + "/computers/"
)
and helper.in_content(
response, "/customer/" + str(customer.id) + "/devices/"
)
and helper.in_content(
response, "/customer/" + str(customer.id) + "/backups/"
)
and helper.in_content(
response, "/customer/" + str(customer.id) + "/licenses/"
)
and helper.in_content(
response, "/customer/" + str(customer.id) + "/users/"
)
and helper.in_content(response, "/customer/" + str(customer.id) + "/nets/")
and helper.in_content(response, "/customer/" + str(customer.id) + "/computers/")
and helper.in_content(response, "/customer/" + str(customer.id) + "/devices/")
and helper.in_content(response, "/customer/" + str(customer.id) + "/backups/")
and helper.in_content(response, "/customer/" + str(customer.id) + "/licenses/")
and helper.in_content(response, "/customer/" + str(customer.id) + "/users/")
and helper.in_content(response, project_manager)
)
@ -75,41 +63,21 @@ def test_customer_list_view_multiple_customers(create_admin_user):
assert (
response.status_code == 200
and helper.in_content(response, customer1)
and helper.in_content(
response, "/customer/" + str(customer1.id) + "/nets/"
)
and helper.in_content(response, "/customer/" + str(customer1.id) + "/nets/")
and helper.in_content(
response, "/customer/" + str(customer1.id) + "/computers/"
)
and helper.in_content(
response, "/customer/" + str(customer1.id) + "/devices/"
)
and helper.in_content(
response, "/customer/" + str(customer1.id) + "/backups/"
)
and helper.in_content(
response, "/customer/" + str(customer1.id) + "/licenses/"
)
and helper.in_content(
response, "/customer/" + str(customer1.id) + "/users/"
)
and helper.in_content(response, "/customer/" + str(customer1.id) + "/devices/")
and helper.in_content(response, "/customer/" + str(customer1.id) + "/backups/")
and helper.in_content(response, "/customer/" + str(customer1.id) + "/licenses/")
and helper.in_content(response, "/customer/" + str(customer1.id) + "/users/")
and helper.in_content(response, customer2)
and helper.in_content(
response, "/customer/" + str(customer2.id) + "/nets/"
)
and helper.in_content(response, "/customer/" + str(customer2.id) + "/nets/")
and helper.in_content(
response, "/customer/" + str(customer2.id) + "/computers/"
)
and helper.in_content(
response, "/customer/" + str(customer2.id) + "/devices/"
)
and helper.in_content(
response, "/customer/" + str(customer2.id) + "/backups/"
)
and helper.in_content(
response, "/customer/" + str(customer2.id) + "/licenses/"
)
and helper.in_content(
response, "/customer/" + str(customer1.id) + "/users/"
)
and helper.in_content(response, "/customer/" + str(customer2.id) + "/devices/")
and helper.in_content(response, "/customer/" + str(customer2.id) + "/backups/")
and helper.in_content(response, "/customer/" + str(customer2.id) + "/licenses/")
and helper.in_content(response, "/customer/" + str(customer1.id) + "/users/")
)

View File

@ -10,9 +10,7 @@ def test_location_form(create_admin_user):
fixture = create_admin_user()
user = fixture["admin"]
form = forms.LocationForm(user=user, data={})
assert (
form.is_valid() is False
), "Should be false because no data was given"
assert form.is_valid() is False, "Should be false because no data was given"
data = {"name": "Main Office", "customer": 3}
form = forms.LocationForm(user=user, data=data)

View File

@ -14,9 +14,7 @@ def test_load_htmx_create_location_view(create_admin_user):
client.login(username="pharma-admin", password="password")
url = "/create/location/"
response = client.get(url)
assert response.status_code == 200 and helper.in_content(
response, "Add Location"
)
assert response.status_code == 200 and helper.in_content(response, "Add Location")
def test_htmx_create_location_view(create_admin_user):
@ -25,9 +23,7 @@ def test_htmx_create_location_view(create_admin_user):
client.login(username="pharma-admin", password="password")
data = {"name": mixer.faker.name(), "save_location": 1}
response = client.post("/create/location/", data)
assert response.status_code == 200 and helper.in_content(
response, data["name"]
)
assert response.status_code == 200 and helper.in_content(response, data["name"])
def test_htmx_create_location_view_invalid_form(create_admin_user):

View File

@ -24,9 +24,7 @@ def customers_table_view(request):
customers = utils.objects_for_allowed_customers(Customer, request.user)
table = CustomersTable(customers)
RequestConfig(request).configure(table)
return render(
request, "customers/customer_list.html", {"customers": table}
)
return render(request, "customers/customer_list.html", {"customers": table})
@login_required
@ -44,23 +42,17 @@ def create_customer(request):
)
form = CustomerForm()
context = {"form": form}
return TemplateResponse(
request, "customers/partials/customer_create.html", context
)
return TemplateResponse(request, "customers/partials/customer_create.html", context)
@login_required
def customer_detail_view(request, pk):
customer = utils.get_object_with_view_permission(
Customer, user=request.user, pk=pk
)
customer = utils.get_object_with_view_permission(Customer, user=request.user, pk=pk)
context = {"customer": customer}
return TemplateResponse(
request, "customers/customer_details.html", context
)
return TemplateResponse(request, "customers/customer_details.html", context)
class CustomerDeleteView(LoginRequiredMixin, DeleteView):
class CustomerDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = Customer
def get_success_url(self):

View File

@ -12,13 +12,13 @@ from .models import (
)
class DeviceInNetInline(nested_admin.NestedStackedInline):
class DeviceInNetInline(nested_admin.NestedStackedInline): # pylint: disable=no-member
model = DeviceInNet
extra = 0
verbose_name_plural = "Nets"
class DeviceAdmin(nested_admin.NestedModelAdmin):
class DeviceAdmin(nested_admin.NestedModelAdmin): # pylint: disable=no-member
inlines = (DeviceInNetInline,)

View File

@ -11,8 +11,6 @@ def device_view_permission(old_function):
if user.has_perm("customers.view_customer", device.customer):
return old_function(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return HttpResponseForbidden("You're not allowed to access this device.")
return new_function

View File

@ -69,12 +69,8 @@ class DeviceUpdateForm(forms.ModelForm):
def __init__(self, request, *args, **kwargs):
super(DeviceUpdateForm, self).__init__(*args, **kwargs)
customers = utils.objects_for_allowed_customers(
Customer, user=request.user
)
locations = utils.objects_for_allowed_customers(
Location, user=request.user
)
customers = utils.objects_for_allowed_customers(Customer, user=request.user)
locations = utils.objects_for_allowed_customers(Location, user=request.user)
users = utils.objects_for_allowed_customers(User, user=request.user)
self.fields["customer"].queryset = customers
self.fields["location"].queryset = locations

View File

@ -38,9 +38,7 @@ class DeviceCategory(Category):
class HardwareModel(models.Model):
name = models.CharField(max_length=50)
manufacturer = models.ForeignKey(
DeviceManufacturer, on_delete=models.CASCADE
)
manufacturer = models.ForeignKey(DeviceManufacturer, on_delete=models.CASCADE)
class Meta:
ordering = ["name"]
@ -56,19 +54,13 @@ class Device(models.Model):
category = models.ForeignKey(
DeviceCategory, on_delete=models.SET_NULL, null=True, blank=True
)
owner = models.ForeignKey(
Owner, on_delete=models.SET_NULL, null=True, blank=True
)
owner = models.ForeignKey(Owner, on_delete=models.SET_NULL, null=True, blank=True)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
manufacturer = models.ForeignKey(
DeviceManufacturer, models.SET_NULL, null=True, blank=True
)
model = models.ForeignKey(
HardwareModel, models.SET_NULL, null=True, blank=True
)
location = models.ForeignKey(
Location, models.SET_NULL, null=True, blank=True
)
model = models.ForeignKey(HardwareModel, models.SET_NULL, null=True, blank=True)
location = models.ForeignKey(Location, models.SET_NULL, null=True, blank=True)
user = models.ForeignKey(User, models.SET_NULL, null=True, blank=True)
installation_date = models.DateField(null=True, blank=True)
net = models.ManyToManyField(Net, through="DeviceInNet")

View File

@ -16,9 +16,7 @@ class WarrantyType(Category):
class Warranty(models.Model):
customer = models.ForeignKey(
Customer, on_delete=models.CASCADE, blank=True
)
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, blank=True)
device = models.ForeignKey(Device, on_delete=models.CASCADE)
valid_from = models.DateField()
valid_until = models.DateField()

View File

@ -12,9 +12,7 @@ def test_device_create_form(create_admin_user):
fixture = create_admin_user()
user = mixer.blend("core.InventoryUser", customer=fixture["customer"])
form = forms.DeviceCreateForm(user=user, data={})
assert (
form.is_valid() is False
), "Should be false because no data was given"
assert form.is_valid() is False, "Should be false because no data was given"
data = {"name": "pharma-device1", "customer": 3}
form = forms.DeviceCreateForm(user=user, data=data)
@ -32,9 +30,7 @@ def test_device_update_form(create_admin_user):
request = HttpRequest()
request.user = fixture["admin"]
form = forms.DeviceUpdateForm(request, data={})
assert (
form.is_valid() is False
), "Should be false because no data was given"
assert form.is_valid() is False, "Should be false because no data was given"
data = {"name": "pharma-device1", "customer": 3}
form = forms.DeviceUpdateForm(request, data=data)
@ -50,9 +46,7 @@ def test_device_update_form(create_admin_user):
def test_device_create_form_duplicate_device(create_admin_user):
fixture = create_admin_user()
user = mixer.blend("core.InventoryUser", customer=fixture["customer"])
mixer.blend(
"devices.Device", name="pharma-device1", customer=fixture["customer"]
)
mixer.blend("devices.Device", name="pharma-device1", customer=fixture["customer"])
data = {"name": "pharma-device1", "customer": fixture["customer"].id}
form = forms.DeviceCreateForm(user=user, data=data)
assert (

View File

@ -35,9 +35,7 @@ def test_load_device_update_view(create_admin_user):
client.login(username="pharma-admin", password="password")
device = mixer.blend("devices.Device", customer=mixer.SELECT)
response = client.get("/update/device/{}/".format(device.pk))
assert response.status_code == 200 and helper.in_content(
response, device.name
)
assert response.status_code == 200 and helper.in_content(response, device.name)
def test_device_update_view(create_admin_user):
@ -187,9 +185,7 @@ def test_device_in_net_update_view(create_admin_user):
"mac_address": "",
"ip_status": "1",
}
response = client.post(
"/update/device-in-net/{}/".format(device_in_net.pk), data
)
response = client.post("/update/device-in-net/{}/".format(device_in_net.pk), data)
assert response.status_code == 302
device_in_net.refresh_from_db()
assert device_in_net.ip == data["ip"]

View File

@ -9,9 +9,7 @@ pytestmark = pytest.mark.django_db
def test_warranty_create_form(create_admin_user):
create_admin_user()
form = forms.WarrantyCreateForm(data={})
assert (
form.is_valid() is False
), "Should be false because no data was given"
assert form.is_valid() is False, "Should be false because no data was given"
device = mixer.blend("devices.Device")
@ -33,8 +31,7 @@ def test_warranty_create_form(create_admin_user):
form.is_valid() is False
), "Should be false because valid from is before valid until"
assert (
"Valid from date must be before valid until date"
== form.errors["__all__"][0]
"Valid from date must be before valid until date" == form.errors["__all__"][0]
)
@ -51,6 +48,5 @@ def test_warranty_update_form(create_admin_user):
form = forms.WarrantyUpdateForm(data=data)
assert form.is_valid() is False
assert (
"Valid from date must be before valid until date"
== form.errors["__all__"][0]
"Valid from date must be before valid until date" == form.errors["__all__"][0]
)

View File

@ -39,9 +39,7 @@ def test_warranties_view_plenty_of_time(create_admin_user):
user.save()
device = mixer.blend("devices.Device", customer=fixture["customer"])
more_than_one_year = datetime.date(datetime.today() + timedelta(400))
mixer.blend(
"devices.Warranty", device=device, valid_until=more_than_one_year
)
mixer.blend("devices.Warranty", device=device, valid_until=more_than_one_year)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/warranties/")
@ -77,9 +75,7 @@ def test_warranties_view_warranty_one_year_till_expiration(create_admin_user):
user.save()
device = mixer.blend("devices.Device", customer=fixture["customer"])
not_one_year_more = datetime.date(datetime.today() + timedelta(200))
mixer.blend(
"devices.Warranty", device=device, valid_until=not_one_year_more
)
mixer.blend("devices.Warranty", device=device, valid_until=not_one_year_more)
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/warranties/")

View File

@ -4,9 +4,7 @@ from . import views
urlpatterns = [
path(
"customer/<int:pk>/devices/", views.devices_table_view, name="devices"
),
path("customer/<int:pk>/devices/", views.devices_table_view, name="devices"),
path("device/<int:pk>/", views.device_detail_view, name="device"),
path(
"manufacturer/<int:pk>/",

View File

@ -60,16 +60,12 @@ def device_detail_view(request, pk):
def devices_table_view(request, pk):
table = DevicesTable(Device.objects.filter(customer=pk))
RequestConfig(request).configure(table)
return render(
request, "devices/device_list.html", {"devices": table, "pk": pk}
)
return render(request, "devices/device_list.html", {"devices": table, "pk": pk})
@login_required
def warranties_view(request):
table = WarrantiesTable(
utils.objects_for_allowed_customers(Warranty, request.user)
)
table = WarrantiesTable(utils.objects_for_allowed_customers(Warranty, request.user))
RequestConfig(request).configure(table)
return render(request, "devices/warranties_list.html", {"devices": table})
@ -111,9 +107,7 @@ def device_update_view(request, pk):
"""
template_name = "devices/device_update.html"
request.session["device_to_update"] = pk
device = utils.get_object_with_view_permission(
Device, user=request.user, pk=pk
)
device = utils.get_object_with_view_permission(Device, user=request.user, pk=pk)
if request.method == "POST" and "save_device" in request.POST:
form = DeviceUpdateForm(request, request.POST, instance=device)
if form.is_valid():
@ -124,7 +118,7 @@ def device_update_view(request, pk):
return TemplateResponse(request, template_name, {"form": form})
class DeviceDeleteView(LoginRequiredMixin, DeleteView):
class DeviceDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = Device
def get_success_url(self):
@ -160,7 +154,7 @@ class WarrantyUpdateView(LoginRequiredMixin, UpdateView):
return self.request.POST.get("previous_page")
class WarrantyDeleteView(LoginRequiredMixin, DeleteView):
class WarrantyDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = Warranty
def get_success_url(self):
@ -195,7 +189,7 @@ class DeviceInNetUpdateView(LoginRequiredMixin, UpdateView):
return self.request.POST.get("previous_page")
class DeviceInNetDeleteView(LoginRequiredMixin, DeleteView):
class DeviceInNetDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = DeviceInNet
template_name = "devices/device_in_net_confirm_delete.html"

View File

@ -48,9 +48,7 @@ class LicenseWithUser(models.Model):
class Meta:
constraints = [
models.UniqueConstraint(
fields=["user", "license"], name="user per license"
)
models.UniqueConstraint(fields=["user", "license"], name="user per license")
]

View File

@ -61,9 +61,7 @@ def test_customer_license_table_no_license(create_admin_user):
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/customer/" + str(customer.id) + "/licenses/")
assert response.status_code == 200 and helper.not_in_content(
response, customer
)
assert response.status_code == 200 and helper.not_in_content(response, customer)
def test_customer_license_table_no_permission(create_admin_user):

View File

@ -41,7 +41,7 @@ def licenses_table_view(request, pk):
class LicenseWithComputerCreateView(LoginRequiredMixin, CreateView):
model = LicenseWithComputer
template_name = "licenses/license_with_computer_create.html"
fields = "__all__"
fields = "__all__" # type: ignore
def get_success_url(self):
return reverse("computer", args=(self.computer.pk,))
@ -57,7 +57,7 @@ class LicenseWithComputerCreateView(LoginRequiredMixin, CreateView):
}
class LicenseWithComputerDeleteView(LoginRequiredMixin, DeleteView):
class LicenseWithComputerDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = LicenseWithComputer
template_name = "licenses/license_with_computer_confirm_delete.html"
@ -65,7 +65,7 @@ class LicenseWithComputerDeleteView(LoginRequiredMixin, DeleteView):
return reverse("computer", args=(self.object.computer.pk,))
class UserLicenseDeleteView(LoginRequiredMixin, DeleteView):
class UserLicenseDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = UserLicense
template_name = "licenses/license_confirm_delete.html"
@ -73,7 +73,7 @@ class UserLicenseDeleteView(LoginRequiredMixin, DeleteView):
return reverse("licenses", args=(self.object.customer.pk,))
class ComputerLicenseDeleteView(LoginRequiredMixin, DeleteView):
class ComputerLicenseDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = ComputerLicense
template_name = "licenses/license_confirm_delete.html"

View File

@ -3,9 +3,7 @@ import os
import sys
if __name__ == "__main__":
os.environ.setdefault(
"DJANGO_SETTINGS_MODULE", "network_inventory.settings"
)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "network_inventory.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:

View File

@ -11,8 +11,6 @@ def net_view_permission(old_fuction):
if user.has_perm("customers.view_customer", net.customer):
return old_fuction(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return HttpResponseForbidden("You're not allowed to access this device.")
return new_function

View File

@ -15,9 +15,7 @@ def test_net_detail_view_no_permission(create_admin_user):
net = mixer.blend("nets.Net")
customer = mixer.blend("customers.Customer")
device = mixer.blend("computers.Computer", customer=customer)
mixer.blend(
"devices.DeviceInNet", device=device, net=net, ip="10.7.89.101"
)
mixer.blend("devices.DeviceInNet", device=device, net=net, ip="10.7.89.101")
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/net/" + str(net.id) + "/")
@ -28,9 +26,7 @@ def test_net_detail_view(create_admin_user):
fixture = create_admin_user()
net = mixer.blend("nets.Net", customer=mixer.SELECT)
device = mixer.blend("computers.Computer", customer=fixture["customer"])
device_in_net = DeviceInNet.objects.create(
device=device, net=net, ip="10.7.89.101"
)
device_in_net = DeviceInNet.objects.create(device=device, net=net, ip="10.7.89.101")
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/net/" + str(net.id) + "/")

View File

@ -29,12 +29,10 @@ def net_detail_view(request, pk):
net = get_object_or_404(Net, pk=pk)
table = NetDetailTable(DeviceInNet.objects.filter(net=net))
RequestConfig(request).configure(table)
return render(
request, "nets/net_details.html", {"table": table, "net": net}
)
return render(request, "nets/net_details.html", {"table": table, "net": net})
class NetDeleteView(LoginRequiredMixin, DeleteView):
class NetDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = Net
def get_success_url(self):

View File

@ -11,8 +11,6 @@ def user_view_permission(old_fuction):
if user.has_perm("customers.view_customer", inventory_user.customer):
return old_fuction(request, pk)
else:
return HttpResponseForbidden(
"You're not allowed to access this device."
)
return HttpResponseForbidden("You're not allowed to access this device.")
return new_function

View File

@ -37,9 +37,7 @@ def test_customer_user_table_no_user(create_admin_user):
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/customer/" + str(customer.id) + "/users/")
assert response.status_code == 200 and helper.not_in_content(
response, customer
)
assert response.status_code == 200 and helper.not_in_content(response, customer)
def test_customer_user_table_no_permission(create_admin_user):

View File

@ -61,6 +61,4 @@ def test_group_detail_view_with_child_group(create_admin_user):
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/group/" + str(group.id) + "/")
assert response.status_code == 200 and helper.in_content(
response, child_group
)
assert response.status_code == 200 and helper.in_content(response, child_group)

View File

@ -38,9 +38,7 @@ def test_user_detail_view_group(create_admin_user):
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/user/" + str(user.id) + "/")
assert response.status_code == 200 and helper.in_content(
response, "Groups"
)
assert response.status_code == 200 and helper.in_content(response, "Groups")
def test_user_detail_view_mail_alias(create_admin_user):
@ -50,9 +48,7 @@ def test_user_detail_view_mail_alias(create_admin_user):
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/user/" + str(user.id) + "/")
assert response.status_code == 200 and helper.in_content(
response, "Mail Alias"
)
assert response.status_code == 200 and helper.in_content(response, "Mail Alias")
def test_user_detail_view_license(create_admin_user):
@ -63,9 +59,7 @@ def test_user_detail_view_license(create_admin_user):
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/user/" + str(user.id) + "/")
assert response.status_code == 200 and helper.in_content(
response, "License"
)
assert response.status_code == 200 and helper.in_content(response, "License")
def test_user_detail_view_computer(create_admin_user):
@ -75,9 +69,7 @@ def test_user_detail_view_computer(create_admin_user):
client = Client()
client.login(username="pharma-admin", password="password")
response = client.get("/user/" + str(user.id) + "/")
assert response.status_code == 200 and helper.in_content(
response, computer
)
assert response.status_code == 200 and helper.in_content(response, computer)
def test_user_detail_view_no_permission(create_admin_user):

View File

@ -52,7 +52,7 @@ def user_detail_view(request, pk):
)
class UserDeleteView(LoginRequiredMixin, DeleteView):
class UserDeleteView(LoginRequiredMixin, DeleteView): # type: ignore
model = User
def get_success_url(self):
@ -64,9 +64,7 @@ class UserDeleteView(LoginRequiredMixin, DeleteView):
def groups_table_view(request, pk):
customer = get_object_or_404(Customer, pk=pk)
groups_table = GroupsTable(
utils.get_objects_for_customer(
Group, user=request.user, customer_pk=pk
)
utils.get_objects_for_customer(Group, user=request.user, customer_pk=pk)
)
RequestConfig(request).configure(groups_table)
return TemplateResponse(
@ -81,9 +79,7 @@ def groups_table_view(request, pk):
@login_required
def group_detail_view(request, pk):
group = utils.get_object_with_view_permission(
Group, user=request.user, pk=pk
)
group = utils.get_object_with_view_permission(Group, user=request.user, pk=pk)
users = group.user_set.all()
groups = Group.objects.filter(parent_group=group)
print(groups)
@ -96,9 +92,7 @@ def group_detail_view(request, pk):
@login_required
def delete_group(request, pk):
group = utils.get_object_with_view_permission(
Group, user=request.user, pk=pk
)
group = utils.get_object_with_view_permission(Group, user=request.user, pk=pk)
if request.method == "POST":
group.delete()
return redirect("groups", pk=group.customer.pk)