PyInventory/src/inventory_project/tests/test_project_setup.py

164 wiersze
5.0 KiB
Python

import os
import shutil
import subprocess
import sys
from pathlib import Path
from django.conf import settings
from django.core import checks
from django.core.cache import cache
from django.test import TestCase
from django_tools.unittest_utils.project_setup import check_editor_config
from packaging.version import Version
import inventory
PACKAGE_ROOT = Path(inventory.__file__).parent.parent.parent
def assert_file_contains_string(file_path, string):
with file_path.open('r') as f:
for line in f:
if string in line:
return
raise AssertionError(f'File {file_path} does not contain {string!r} !')
def test_version(package_root=None, version=None):
if package_root is None:
package_root = PACKAGE_ROOT
if version is None:
version = inventory.__version__
ver_obj = Version(inventory.__version__)
if not ver_obj.is_prerelease:
version_string = f'v{version}'
assert_file_contains_string(
file_path=Path(package_root, 'README.md'), string=version_string
)
assert_file_contains_string(
file_path=Path(package_root, 'pyproject.toml'),
string=f'version = "{version}"'
)
def test_poetry_check(package_root=None):
if package_root is None:
package_root = PACKAGE_ROOT
poerty_bin = shutil.which('poetry')
output = subprocess.check_output(
[poerty_bin, 'check'],
text=True,
env=os.environ,
stderr=subprocess.STDOUT,
cwd=str(package_root),
)
print(output)
assert output == 'All set!\n'
class ProjectSettingsTestCase(TestCase):
def test_project_path(self):
project_path = settings.PROJECT_PATH
assert project_path.is_dir()
assert Path(project_path, 'inventory').is_dir()
assert Path(project_path, 'inventory_project').is_dir()
def test_template_dirs(self):
assert len(settings.TEMPLATES) == 1
dirs = settings.TEMPLATES[0].get('DIRS')
assert len(dirs) == 1
template_path = Path(dirs[0]).resolve()
assert template_path.is_dir()
def test_manage_check(self):
all_issues = checks.run_checks(
app_configs=None,
tags=None,
include_deployment_checks=True,
databases=None,
)
all_issue_ids = {issue.id for issue in all_issues}
excpeted_issues = {
'security.W008', # settings.SECURE_SSL_REDIRECT=False
'async.E001', # os.environ['DJANGO_ALLOW_ASYNC_UNSAFE'] exists
}
if all_issue_ids != excpeted_issues:
print('=' * 100)
for issue in all_issues:
print(issue)
print('=' * 100)
raise AssertionError('There are check issues!')
def test_cache(self):
# django cache should work in tests, because some tests "depends" on it
cache_key = 'a-cache-key'
assert cache.get(cache_key) is None
cache.set(cache_key, 'the cache content', timeout=1)
assert cache.get(cache_key) == 'the cache content'
cache.delete(cache_key)
assert cache.get(cache_key) is None
def test_settings(self):
assert settings.SETTINGS_MODULE == 'inventory_project.settings.tests'
middlewares = [entry.rsplit('.', 1)[-1] for entry in settings.MIDDLEWARE]
assert 'AlwaysLoggedInAsSuperUserMiddleware' not in middlewares
assert 'DebugToolbarMiddleware' not in middlewares
def test_check_editor_config():
check_editor_config(package_root=PACKAGE_ROOT)
class CodeStyleTestCase(TestCase):
def call(self, prog, *args):
venv_bin_path = Path(sys.executable).parent
prog = shutil.which(prog, path=venv_bin_path)
assert prog
# Darker will call other programs like "flake8", "git"
# Use first our venv bin path:
env_path = f'{venv_bin_path}{os.pathsep}{os.environ["PATH"]}'
return subprocess.check_output(
(prog,) + args,
text=True,
env=dict(PATH=env_path),
stderr=subprocess.STDOUT,
cwd=str(PACKAGE_ROOT),
)
def check_code_style(self):
self.call('darker', '--check')
self.call('isort', '--check-only', '.')
self.call('flake8', '.')
def test_code_style(self):
# lint: ## Run code formatters and linter
# poetry run darker --check
# poetry run isort --check-only .
# poetry run flake8 .
#
# fix-code-style: ## Fix code formatting
# poetry run darker
# poetry run isort .
# First try:
try:
self.check_code_style()
except subprocess.CalledProcessError:
# Fix and test again:
try:
self.call('darker')
self.call('isort', '.')
self.check_code_style() # Check again
except subprocess.CalledProcessError as err:
raise AssertionError(f'Linting error:\n{"-"*100}\n{err.stdout}\n{"-"*100}')