diff --git a/.ambient-package-update/metadata.py b/.ambient-package-update/metadata.py
index 6e1c906..76e3dd6 100644
--- a/.ambient-package-update/metadata.py
+++ b/.ambient-package-update/metadata.py
@@ -10,19 +10,19 @@
from ambient_package_update.metadata.ruff_ignored_inspection import RuffIgnoredInspection
METADATA = PackageMetadata(
- package_name='ambient_toolbox',
- company='Ambient Innovation: GmbH',
+ package_name="ambient_toolbox",
+ company="Ambient Innovation: GmbH",
authors=[
PackageAuthor(
- name='Ambient Digital',
- email='hello@ambient.digital',
+ name="Ambient Digital",
+ email="hello@ambient.digital",
),
],
- development_status='5 - Production/Stable',
+ development_status="5 - Production/Stable",
license=LICENSE_MIT,
license_year=2012,
readme_content=ReadmeContent(
- tagline='Python toolbox of Ambient Digital containing an abundance of useful tools and gadgets.',
+ tagline="Python toolbox of Ambient Digital containing an abundance of useful tools and gadgets.",
content="""## Features
* Useful classes and mixins for Django admin
@@ -51,38 +51,38 @@
""",
),
dependencies=[
- 'Django>=3.2.20',
- 'bleach>=1.4,<6',
- 'python-dateutil>=2.5.3',
+ "Django>=3.2.20",
+ "bleach>=1.4,<6",
+ "python-dateutil>=2.5.3",
],
supported_django_versions=SUPPORTED_DJANGO_VERSIONS,
supported_python_versions=SUPPORTED_PYTHON_VERSIONS,
has_migrations=True,
optional_dependencies={
- 'dev': [
+ "dev": [
*DEV_DEPENDENCIES,
- 'gevent~=22.10',
+ "gevent~=22.10",
],
- 'drf': [
- 'djangorestframework>=3.8.2',
+ "drf": [
+ "djangorestframework>=3.8.2",
],
- 'graphql': [
- 'graphene-django>=2.2.0',
- 'django-graphql-jwt>=0.2.1',
+ "graphql": [
+ "graphene-django>=2.2.0",
+ "django-graphql-jwt>=0.2.1",
],
- 'sentry': [
- 'sentry-sdk>=1.19.1',
+ "sentry": [
+ "sentry-sdk>=1.19.1",
],
- 'view-layer': [
- 'django-crispy-forms>=1.4.0',
+ "view-layer": [
+ "django-crispy-forms>=1.4.0",
],
},
ruff_ignore_list=[
- RuffIgnoredInspection(key='N999', comment="Project name contains underscore, not fixable"),
- RuffIgnoredInspection(key='A003', comment="Django attributes shadow python builtins"),
- RuffIgnoredInspection(key='DJ001', comment="Django model text-based fields shouldn't be nullable"),
- RuffIgnoredInspection(key='B905', comment="Can be enabled when Python <=3.9 support is dropped"),
- RuffIgnoredInspection(key='DTZ001', comment="TODO will affect \"tz_today()\" method"),
- RuffIgnoredInspection(key='DTZ005', comment="TODO will affect \"tz_today()\" method"),
+ RuffIgnoredInspection(key="N999", comment="Project name contains underscore, not fixable"),
+ RuffIgnoredInspection(key="A003", comment="Django attributes shadow python builtins"),
+ RuffIgnoredInspection(key="DJ001", comment="Django model text-based fields shouldn't be nullable"),
+ RuffIgnoredInspection(key="B905", comment="Can be enabled when Python <=3.9 support is dropped"),
+ RuffIgnoredInspection(key="DTZ001", comment='TODO will affect "tz_today()" method'),
+ RuffIgnoredInspection(key="DTZ005", comment='TODO will affect "tz_today()" method'),
],
)
diff --git a/.coveragerc b/.coveragerc
index f50d2ce..6c92442 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,9 +1,9 @@
[run]
omit =
setup.py,
+ *_test.py,
tests.py,
- tests/*,
- testapp/*,
+ *tests*,
conftest.py
[report]
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 1c3cffc..3ec18a7 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -2,18 +2,14 @@
# https://pre-commit.com/
repos:
- - repo: https://github.com/psf/black-pre-commit-mirror
- rev: 23.10.0
- hooks:
- - id: black
- args: [ --check, --diff, --config, ./pyproject.toml ]
- stages: [ push ]
-
- - repo: https://github.com/charliermarsh/ruff-pre-commit
- rev: 'v0.1.1'
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.1.3
hooks:
+ # Run the Ruff linter.
- id: ruff
- args: [ --fix, --unsafe-fixes, --exit-non-zero-on-fix ]
+ args: [--fix, --exit-non-zero-on-fix]
+ # Run the Ruff formatter.
+ - id: ruff-format
- repo: https://github.com/asottile/pyupgrade
rev: v3.15.0
diff --git a/CHANGES.md b/CHANGES.md
index 9d8c4b7..565ad6f 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -3,6 +3,7 @@
**9.1.6** (2023-10-31)
* Added migration docs to Readme
* Added migration check to GitHub actions
+ * Switched formatter from `black` to `ruff`
* Updates from ambient updater
* Fixes typos
diff --git a/README.md b/README.md
index 4580e95..637ba18 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
[![Downloads](https://static.pepy.tech/badge/ambient-toolbox)](https://pepy.tech/project/ambient-toolbox)
[![Coverage](https://img.shields.io/badge/Coverage-100%25-success)](https://github.com/ambient-innovation/ambient-toolbox/actions?workflow=CI)
[![Linting](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
-[![Coding Style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/python/black)
+[![Coding Style](https://img.shields.io/badge/code%20style-Ruff-000000.svg)](https://github.com/astral-sh/ruff)
[![Documentation Status](https://readthedocs.org/projects/ambient-toolbox/badge/?version=latest)](https://ambient-toolbox.readthedocs.io/en/latest/?badge=latest)
Python toolbox of Ambient Digital containing an abundance of useful tools and gadgets.
diff --git a/ambient_toolbox/__init__.py b/ambient_toolbox/__init__.py
index d65a5ff..efada71 100644
--- a/ambient_toolbox/__init__.py
+++ b/ambient_toolbox/__init__.py
@@ -1,3 +1,3 @@
"""Python toolbox of Ambient Digital containing an abundance of useful tools and gadgets."""
-__version__ = '9.1.6'
+__version__ = "9.1.6"
diff --git a/ambient_toolbox/admin/model_admins/classes.py b/ambient_toolbox/admin/model_admins/classes.py
index 2516272..eebd983 100644
--- a/ambient_toolbox/admin/model_admins/classes.py
+++ b/ambient_toolbox/admin/model_admins/classes.py
@@ -14,10 +14,10 @@ def get_readonly_fields(self, request, obj=None):
]
return self.readonly_fields
- def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
+ def changeform_view(self, request, object_id=None, form_url="", extra_context=None):
extra_context = extra_context or {}
- extra_context['show_save_and_continue'] = False
- extra_context['show_save'] = False
+ extra_context["show_save_and_continue"] = False
+ extra_context["show_save"] = False
return super().changeform_view(request, object_id, extra_context=extra_context)
def has_add_permission(self, request):
@@ -39,8 +39,8 @@ class EditableOnlyAdmin(admin.ModelAdmin):
def get_actions(self, request):
# Disable delete
actions = super().get_actions(request)
- if 'delete_selected' in actions:
- del actions['delete_selected']
+ if "delete_selected" in actions:
+ del actions["delete_selected"]
return actions
def has_add_permission(self, request):
diff --git a/ambient_toolbox/admin/model_admins/inlines.py b/ambient_toolbox/admin/model_admins/inlines.py
index c50a276..e1b7d4e 100644
--- a/ambient_toolbox/admin/model_admins/inlines.py
+++ b/ambient_toolbox/admin/model_admins/inlines.py
@@ -25,5 +25,5 @@ def get_readonly_fields(self, request, obj=None):
+ [field.name for field in self.opts.local_many_to_many]
)
)
- result.remove('id')
+ result.remove("id")
return result
diff --git a/ambient_toolbox/admin/model_admins/mixins.py b/ambient_toolbox/admin/model_admins/mixins.py
index 537f5e4..37af0d3 100644
--- a/ambient_toolbox/admin/model_admins/mixins.py
+++ b/ambient_toolbox/admin/model_admins/mixins.py
@@ -16,7 +16,7 @@ class AdminCreateFormMixin:
def get_form(self, request, obj=None, **kwargs):
defaults = {}
if obj is None:
- defaults['form'] = self.add_form
+ defaults["form"] = self.add_form
defaults.update(kwargs)
return super().get_form(request, obj, **defaults)
@@ -58,7 +58,7 @@ def _resolve_url(request):
def get_parent_object_from_request(self, request):
resolved = self._resolve_url(request)
if resolved.kwargs:
- return self.parent_model.objects.get(pk=resolved.kwargs.get('object_id', None))
+ return self.parent_model.objects.get(pk=resolved.kwargs.get("object_id", None))
return None
def get_formset(self, request, obj=None, **kwargs):
@@ -75,7 +75,7 @@ class FetchObjectMixin:
def get_object_from_request(self, request):
resolved = resolve(request.path_info)
if resolved.kwargs:
- return self.model.objects.get(pk=resolved.kwargs.get('object_id', None))
+ return self.model.objects.get(pk=resolved.kwargs.get("object_id", None))
return None
@@ -90,10 +90,10 @@ def get_readonly_fields(self, request, obj=None):
Set the fields CommonInfo handles to readonly to avoid users fiddling around with them.
"""
return super().get_readonly_fields(request, obj) + (
- 'created_by',
- 'lastmodified_by',
- 'created_at',
- 'lastmodified_at',
+ "created_by",
+ "lastmodified_by",
+ "created_at",
+ "lastmodified_at",
)
def get_user_obj(self, request) -> Optional[AbstractUser]:
@@ -145,7 +145,7 @@ def change_view(self, request, *args, **kwargs):
else:
opts = self.model._meta
url = reverse(
- 'admin:{app}_{model}_changelist'.format(
+ "admin:{app}_{model}_changelist".format(
app=opts.app_label,
model=opts.model_name,
)
diff --git a/ambient_toolbox/admin/views/forms.py b/ambient_toolbox/admin/views/forms.py
index 764e99f..d4e01a0 100644
--- a/ambient_toolbox/admin/views/forms.py
+++ b/ambient_toolbox/admin/views/forms.py
@@ -9,24 +9,24 @@ class AdminCrispyForm(forms.Form):
Base crispy form to be used in custom views within the django admin.
"""
- section_title = _('No title defined')
- button_label = _('Save')
+ section_title = _("No title defined")
+ button_label = _("Save")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Build fieldset
- fieldset_list = ['']
+ fieldset_list = [""]
for field in self.fields:
- fieldset_list.append(Div(field, css_class='form-row field-name')) # noqa: PERF401
+ fieldset_list.append(Div(field, css_class="form-row field-name")) # noqa: PERF401
# Crispy
self.helper = FormHelper()
- self.helper.form_method = 'post'
- self.helper.add_input(Submit('submit', self.button_label, css_class="button btn-primary"))
+ self.helper.form_method = "post"
+ self.helper.add_input(Submit("submit", self.button_label, css_class="button btn-primary"))
self.helper.layout = Layout(
Div(
- Div(HTML(f'
{self.section_title}
'), Fieldset(*fieldset_list), css_class='module aligned'),
- css_class='custom-form',
+ Div(HTML(f"{self.section_title}
"), Fieldset(*fieldset_list), css_class="module aligned"),
+ css_class="custom-form",
),
)
diff --git a/ambient_toolbox/admin/views/mixins.py b/ambient_toolbox/admin/views/mixins.py
index 6581455..59fbd1f 100644
--- a/ambient_toolbox/admin/views/mixins.py
+++ b/ambient_toolbox/admin/views/mixins.py
@@ -8,7 +8,7 @@ class AdminViewMixin:
"""
model = None
- admin_page_title = ''
+ admin_page_title = ""
def has_view_permission(self, user, **kwargs) -> bool:
"""
@@ -39,23 +39,23 @@ def get_context_data(self, **kwargs):
admin_site = self.get_admin_site()
context.update(
{
- 'site_header': admin_site.site_header,
- 'site_title': admin_site.site_title,
- 'title': self.admin_page_title,
- 'name': self.admin_page_title,
- 'original': self.admin_page_title,
- 'is_nav_sidebar_enabled': True,
- 'available_apps': admin.site.get_app_list(self.request),
- 'opts': {
- 'app_label': self.model._meta.app_label,
- 'verbose_name': self.model._meta.verbose_name,
- 'verbose_name_plural': self.model._meta.verbose_name_plural,
- 'model_name': self.model._meta.model_name,
- 'app_config': {
- 'verbose_name': self.model._meta.app_config.verbose_name,
+ "site_header": admin_site.site_header,
+ "site_title": admin_site.site_title,
+ "title": self.admin_page_title,
+ "name": self.admin_page_title,
+ "original": self.admin_page_title,
+ "is_nav_sidebar_enabled": True,
+ "available_apps": admin.site.get_app_list(self.request),
+ "opts": {
+ "app_label": self.model._meta.app_label,
+ "verbose_name": self.model._meta.verbose_name,
+ "verbose_name_plural": self.model._meta.verbose_name_plural,
+ "model_name": self.model._meta.model_name,
+ "app_config": {
+ "verbose_name": self.model._meta.app_config.verbose_name,
},
},
- 'has_permission': admin_site.has_permission(request=self.request),
+ "has_permission": admin_site.has_permission(request=self.request),
}
)
return context
diff --git a/ambient_toolbox/apps.py b/ambient_toolbox/apps.py
index e84b645..b36e674 100644
--- a/ambient_toolbox/apps.py
+++ b/ambient_toolbox/apps.py
@@ -3,5 +3,5 @@
class AmbientToolboxConfig(AppConfig):
- name = 'ambient_toolbox'
- verbose_name = _('Ambient Toolbox')
+ name = "ambient_toolbox"
+ verbose_name = _("Ambient Toolbox")
diff --git a/ambient_toolbox/context_processors.py b/ambient_toolbox/context_processors.py
index 4b1652e..75770b9 100644
--- a/ambient_toolbox/context_processors.py
+++ b/ambient_toolbox/context_processors.py
@@ -2,4 +2,4 @@
def server_settings(request):
- return {'DEBUG_MODE': settings.DEBUG, 'SERVER_URL': settings.SERVER_URL}
+ return {"DEBUG_MODE": settings.DEBUG, "SERVER_URL": settings.SERVER_URL}
diff --git a/ambient_toolbox/drf/fields.py b/ambient_toolbox/drf/fields.py
index 1fcab78..f9004f2 100644
--- a/ambient_toolbox/drf/fields.py
+++ b/ambient_toolbox/drf/fields.py
@@ -17,7 +17,7 @@ def to_representation(self, value):
# parent serializer.
# Explanation: With `many=True` DRF creates an intermediate `ListSerializer`. It has `many=True`, so we'll end
# up in the first if-case. If we do not use `many=True`, the "many" attribute is not set.
- if getattr(self.parent, 'many', False):
+ if getattr(self.parent, "many", False):
parent = self.parent.parent
else:
parent = self.parent
diff --git a/ambient_toolbox/drf/serializers.py b/ambient_toolbox/drf/serializers.py
index 778cba1..c3aa9b8 100644
--- a/ambient_toolbox/drf/serializers.py
+++ b/ambient_toolbox/drf/serializers.py
@@ -23,12 +23,12 @@ class CommonInfoSerializer(BaseModelSerializer):
def validate(self, data):
data = super().validate(data)
- request = self.context.get('request', None)
+ request = self.context.get("request", None)
if request.user:
- data['lastmodified_by'] = request.user
+ data["lastmodified_by"] = request.user
if not self.instance:
# If this is a new instance, set created_by
- data['created_by'] = request.user
+ data["created_by"] = request.user
return data
diff --git a/ambient_toolbox/drf/tests.py b/ambient_toolbox/drf/tests.py
index 834b4fe..6b3a3c9 100644
--- a/ambient_toolbox/drf/tests.py
+++ b/ambient_toolbox/drf/tests.py
@@ -45,12 +45,12 @@ def execute_request( # noqa: PLR0913
*,
url,
view_kwargs=None,
- method='get',
+ method="get",
data=None,
view_class=None,
user=None,
viewset_kwargs=None,
- data_format='json',
+ data_format="json",
) -> Response:
"""
Helper method which wraps all relevant setup to execute a request to the backends api
diff --git a/ambient_toolbox/gitlab/coverage.py b/ambient_toolbox/gitlab/coverage.py
index 97ef130..83a928e 100644
--- a/ambient_toolbox/gitlab/coverage.py
+++ b/ambient_toolbox/gitlab/coverage.py
@@ -18,41 +18,41 @@ def __init__(self) -> None:
super().__init__()
# Get ENV variables
- self.current_pipeline_id: int = int(os.environ.get('CI_PIPELINE_ID'))
- self.base_api_url: str = os.environ.get('CI_API_V4_URL')
- self.current_branch: str = os.environ.get('CI_COMMIT_REF_NAME')
- self.token: str = os.environ.get('GITLAB_CI_COVERAGE_PIPELINE_TOKEN')
- self.project_id: int = int(os.environ.get('CI_PROJECT_ID'))
- self.job_name: str = os.environ.get('CI_COVERAGE_JOB_NAME', '')
- self.target_branch: str = os.environ.get('GITLAB_CI_COVERAGE_TARGET_BRANCH', 'develop')
+ self.current_pipeline_id: int = int(os.environ.get("CI_PIPELINE_ID"))
+ self.base_api_url: str = os.environ.get("CI_API_V4_URL")
+ self.current_branch: str = os.environ.get("CI_COMMIT_REF_NAME")
+ self.token: str = os.environ.get("GITLAB_CI_COVERAGE_PIPELINE_TOKEN")
+ self.project_id: int = int(os.environ.get("CI_PROJECT_ID"))
+ self.job_name: str = os.environ.get("CI_COVERAGE_JOB_NAME", "")
+ self.target_branch: str = os.environ.get("GITLAB_CI_COVERAGE_TARGET_BRANCH", "develop")
self.pipelines_url = (
- f'{self.base_api_url}/projects/{self.project_id}/pipelines?ref={self.target_branch}&status=success'
+ f"{self.base_api_url}/projects/{self.project_id}/pipelines?ref={self.target_branch}&status=success"
)
- self.pipelines_url_with_token = f'{self.pipelines_url}&private_token={self.token}'
+ self.pipelines_url_with_token = f"{self.pipelines_url}&private_token={self.token}"
- self.disable_coverage: bool = os.environ.get('GITLAB_CI_DISABLE_COVERAGE', False)
+ self.disable_coverage: bool = os.environ.get("GITLAB_CI_DISABLE_COVERAGE", False)
def get_latest_target_branch_commit_sha(self) -> str:
"""
Get the latest commit which is in the current branch and the target compare branch.
"""
result = subprocess.run(
- ['git', 'merge-base', '--fork-point', f'origin/{self.target_branch}'], stdout=subprocess.PIPE, check=True
+ ["git", "merge-base", "--fork-point", f"origin/{self.target_branch}"], stdout=subprocess.PIPE, check=True
)
return result.stdout.decode("utf-8").strip()
def get_pipeline_id_by_commit_sha(self, sha: str) -> int | None:
- pipeline_url = f'{self.pipelines_url_with_token}&sha={sha}'
+ pipeline_url = f"{self.pipelines_url_with_token}&sha={sha}"
response = httpx.get(pipeline_url)
status_code = response.status_code
if status_code == HTTPStatus.OK:
pipelines = json.loads(response.content)
if pipelines and len(pipelines) > 0:
- return pipelines[0].get('id', None)
+ return pipelines[0].get("id", None)
else:
- print('\n### ERROR: No pipelines found for SHA1 ###\n')
- print(f'Pipeline URL: {self.pipelines_url}&sha={sha}')
+ print("\n### ERROR: No pipelines found for SHA1 ###\n")
+ print(f"Pipeline URL: {self.pipelines_url}&sha={sha}")
print(response.content)
return None
@@ -60,39 +60,39 @@ def get_coverage_from_pipeline(self, pipeline_id: int, job_name: str) -> (float,
"""
Get coverage from given pipeline (by id)
"""
- jobs_url = f'{self.base_api_url}/projects/{self.project_id}/pipelines/{pipeline_id}/jobs'
- jobs_with_token_url = f'{jobs_url}?private_token={self.token}'
+ jobs_url = f"{self.base_api_url}/projects/{self.project_id}/pipelines/{pipeline_id}/jobs"
+ jobs_with_token_url = f"{jobs_url}?private_token={self.token}"
- print(f'Jobs-API-URL: {jobs_url}')
+ print(f"Jobs-API-URL: {jobs_url}")
jobs_response = httpx.get(jobs_with_token_url)
jobs_status_code = jobs_response.status_code
if jobs_status_code != HTTPStatus.OK:
- raise ConnectionError(f'Call to jobs api endpoint failed with status code {jobs_status_code}')
+ raise ConnectionError(f"Call to jobs api endpoint failed with status code {jobs_status_code}")
jobs = json.loads(jobs_response.content)
coverages = {
- job['name']: {'id': job['id'], 'coverage': float(job['coverage']), 'web_url': job['web_url']}
+ job["name"]: {"id": job["id"], "coverage": float(job["coverage"]), "web_url": job["web_url"]}
for job in jobs
- if job.get('coverage')
+ if job.get("coverage")
}
- pipeline_url = f'{self.base_api_url}/projects/{self.project_id}/pipelines/{pipeline_id}'
- pipeline_with_token_url = f'{pipeline_url}?private_token={self.token}'
+ pipeline_url = f"{self.base_api_url}/projects/{self.project_id}/pipelines/{pipeline_id}"
+ pipeline_with_token_url = f"{pipeline_url}?private_token={self.token}"
pipeline_response = httpx.get(pipeline_with_token_url)
pipeline_status_code = pipeline_response.status_code
if pipeline_status_code != HTTPStatus.OK:
- raise ConnectionError(f'Call to pipeline api endpoint failed with status code {pipeline_status_code}')
+ raise ConnectionError(f"Call to pipeline api endpoint failed with status code {pipeline_status_code}")
pipeline = json.loads(pipeline_response.content)
- coverages_total = float(pipeline['coverage'] if pipeline['coverage'] else 0.0)
- print(f'Pipeline-API-URL: {pipeline_url}')
+ coverages_total = float(pipeline["coverage"] if pipeline["coverage"] else 0.0)
+ print(f"Pipeline-API-URL: {pipeline_url}")
print(f'Pipeline-URL: {pipeline["web_url"]}')
- if job_name == '':
+ if job_name == "":
print(
- '\033[91mATTN: No CI_COVERAGE_JOB_NAME provided, using Total Coverage and skipping Coverage Diff\033[0m'
+ "\033[91mATTN: No CI_COVERAGE_JOB_NAME provided, using Total Coverage and skipping Coverage Diff\033[0m"
)
return coverages_total, coverages_total, None
@@ -101,23 +101,23 @@ def get_coverage_from_pipeline(self, pipeline_id: int, job_name: str) -> (float,
print(f'Job-URL: {coverage_job["web_url"]}')
job_url = f'{self.base_api_url}/projects/{self.project_id}/jobs/{coverage_job["id"]}/trace'
- job_with_token_url = f'{job_url}?private_token={self.token}'
+ job_with_token_url = f"{job_url}?private_token={self.token}"
job_response = httpx.get(job_with_token_url)
job_status_code = job_response.status_code
if job_status_code != HTTPStatus.OK:
- raise ConnectionError(f'Call to job api endpoint failed with status code {job_status_code}')
+ raise ConnectionError(f"Call to job api endpoint failed with status code {job_status_code}")
- print(f'Job-Log-URL: {job_url}')
+ print(f"Job-Log-URL: {job_url}")
job_log = re.search(
- r'Name\s+Stmts\s+Miss\s+Branch\s+BrPart\s+Cover\s+Missing.*files skipped due to complete coverage\.',
- job_response.content.decode('utf-8'),
+ r"Name\s+Stmts\s+Miss\s+Branch\s+BrPart\s+Cover\s+Missing.*files skipped due to complete coverage\.",
+ job_response.content.decode("utf-8"),
re.DOTALL | re.MULTILINE,
)
# print(job_log.group())
- return coverage_job['coverage'] if coverage_job else 0.0, coverages_total, job_log.group()
+ return coverage_job["coverage"] if coverage_job else 0.0, coverages_total, job_log.group()
@staticmethod
def color_text(sign: int, prefix: str, target: float, current: float, diff: float):
@@ -135,9 +135,9 @@ def color_text(sign: int, prefix: str, target: float, current: float, diff: floa
:return: fully assembled and colored summary text
"""
change = {
- -1: {'text': 'dropped', 'color': '\033[91m'},
- 0: {'text': 'unchanged', 'color': ''},
- 1: {'text': 'climbed', 'color': '\033[92m'},
+ -1: {"text": "dropped", "color": "\033[91m"},
+ 0: {"text": "unchanged", "color": ""},
+ 1: {"text": "climbed", "color": "\033[92m"},
}
return (
f'{change[sign]["color"]} {prefix} {change[sign]["text"]} '
@@ -150,31 +150,31 @@ def print_diff(target_job_log, current_job_log):
Print a diff between the coverage reports of Current and Target branch
"""
diff = ndiff(target_job_log.splitlines(keepends=True), current_job_log.splitlines(keepends=True))
- print('\n############################## Coverage Diff ##############################')
- print('# \033[91m- Target Branch\033[0m #')
- print('# \033[92m+ Current Branch\033[0m #')
- print('###########################################################################')
+ print("\n############################## Coverage Diff ##############################")
+ print("# \033[91m- Target Branch\033[0m #")
+ print("# \033[92m+ Current Branch\033[0m #")
+ print("###########################################################################")
for _idx, line in enumerate(diff):
match = re.match(
- r'^\s*-+\s*$|'
- r'^\s*Name\s+Stmts\s+Miss\s+Branch\s+BrPart\s+Cover\s+Missing|' # first line of the report
- r'^.*files skipped due to complete coverage.$|' # Final line of the report
- r'^[+\-?]', # Line starts with +,-,$ to indicate changes
+ r"^\s*-+\s*$|"
+ r"^\s*Name\s+Stmts\s+Miss\s+Branch\s+BrPart\s+Cover\s+Missing|" # first line of the report
+ r"^.*files skipped due to complete coverage.$|" # Final line of the report
+ r"^[+\-?]", # Line starts with +,-,$ to indicate changes
line,
)
if match:
- if line[0] == '-':
- print('\033[91m', end="")
- if line[0] == '+':
- print('\033[92m', end="")
+ if line[0] == "-":
+ print("\033[91m", end="")
+ if line[0] == "+":
+ print("\033[92m", end="")
print(line, end="")
- if line[0] in ['+', '-']:
- print('\033[0m', end="")
+ if line[0] in ["+", "-"]:
+ print("\033[0m", end="")
- print('\n###########################################################################')
- print('# \033[91m- Target Branch\033[0m #')
- print('# \033[92m+ Current Branch\033[0m #')
- print('############################## Coverage Diff ##############################\n')
+ print("\n###########################################################################")
+ print("# \033[91m- Target Branch\033[0m #")
+ print("# \033[92m+ Current Branch\033[0m #")
+ print("############################## Coverage Diff ##############################\n")
def process(self):
"""
@@ -184,58 +184,58 @@ def process(self):
# Check, if coverage is supposed to run. If not, inform the user and return early.
if self.disable_coverage:
- print('Coverage was skipped!')
+ print("Coverage was skipped!")
sys.exit(0)
- print('\n###########################################################################\n')
- print('DEBUG INFO:')
+ print("\n###########################################################################\n")
+ print("DEBUG INFO:")
# Get the latest commit SHA which is also in develop
commit_sha = self.get_latest_target_branch_commit_sha()
# Try to find the latest successful pipeline for "TARGET_BRANCH" where our SHA was in
- print('Trying base branch for comparison.')
+ print("Trying base branch for comparison.")
target_pipeline_id = None
if commit_sha:
print(f'Found latest target branch commit SHA "{commit_sha}".')
target_pipeline_id = self.get_pipeline_id_by_commit_sha(commit_sha)
- print(f'Target branch pipeline ID identified: {target_pipeline_id}.')
+ print(f"Target branch pipeline ID identified: {target_pipeline_id}.")
# Get target pipeline id (from develop branch) if we were not successful the first time
if not target_pipeline_id:
print("Didn't work. Using default branch for comparison.")
response = httpx.get(self.pipelines_url_with_token)
status_code = response.status_code
- print(f'Pipelines-API-URL: {self.pipelines_url}')
+ print(f"Pipelines-API-URL: {self.pipelines_url}")
# Ensure call did not go sideways
if status_code != HTTPStatus.OK:
- raise ConnectionError(f'Call to global pipeline api endpoint failed with status code {status_code}')
+ raise ConnectionError(f"Call to global pipeline api endpoint failed with status code {status_code}")
# Read target pipeline ID from content
try:
- target_pipeline_id = json.loads(response.content)[0]['id']
+ target_pipeline_id = json.loads(response.content)[0]["id"]
except IndexError:
# This happens when there are zero `target_branch` pipelines
target_pipeline_id = 0
- print(f'Default branch pipeline ID identified: {target_pipeline_id}.')
+ print(f"Default branch pipeline ID identified: {target_pipeline_id}.")
# Get coverage from target pipeline
- print(f'Target Pipeline ID: {target_pipeline_id}')
+ print(f"Target Pipeline ID: {target_pipeline_id}")
target_job_coverage, target_total_coverage, target_job_log = self.get_coverage_from_pipeline(
target_pipeline_id, self.job_name
)
# Get coverage from this pipeline
- print(f'Current pipeline ID: {self.current_pipeline_id}')
+ print(f"Current pipeline ID: {self.current_pipeline_id}")
current_job_coverage, current_total_coverage, current_job_log = self.get_coverage_from_pipeline(
self.current_pipeline_id, self.job_name
)
if target_job_log is None or current_job_log is None:
- print('\n\n\033[91m***************************************************************************\033[0m')
- print(' \033[91m**/!\\** Coverage log not found. Skipping diff. **/!\\**\033[0m ')
- print('\033[91m***************************************************************************\033[0m\n\n')
+ print("\n\n\033[91m***************************************************************************\033[0m")
+ print(" \033[91m**/!\\** Coverage log not found. Skipping diff. **/!\\**\033[0m ")
+ print("\033[91m***************************************************************************\033[0m\n\n")
else:
self.print_diff(target_job_log, current_job_log)
@@ -250,41 +250,41 @@ def process(self):
diff_total_coverage = current_total_coverage - target_total_coverage
coverage = {
- 'total': {
- 'target': target_total_coverage,
- 'current': current_total_coverage,
- 'sign': sign_total_coverage,
- 'diff': diff_total_coverage,
- 'prefix': 'Total coverage',
+ "total": {
+ "target": target_total_coverage,
+ "current": current_total_coverage,
+ "sign": sign_total_coverage,
+ "diff": diff_total_coverage,
+ "prefix": "Total coverage",
},
- 'job': {
- 'target': target_job_coverage,
- 'current': current_job_coverage,
- 'sign': sign_job_coverage,
- 'diff': diff_job_coverage,
- 'prefix': 'Job coverage',
+ "job": {
+ "target": target_job_coverage,
+ "current": current_job_coverage,
+ "sign": sign_job_coverage,
+ "diff": diff_job_coverage,
+ "prefix": "Job coverage",
},
}
# Print results
print(
self.color_text(
- coverage['total']['sign'],
- coverage['total']['prefix'],
- coverage['total']['target'],
- coverage['total']['current'],
- coverage['total']['diff'],
+ coverage["total"]["sign"],
+ coverage["total"]["prefix"],
+ coverage["total"]["target"],
+ coverage["total"]["current"],
+ coverage["total"]["diff"],
)
)
print(
self.color_text(
- coverage['job']['sign'],
- coverage['job']['prefix'],
- coverage['job']['target'],
- coverage['job']['current'],
- coverage['job']['diff'],
+ coverage["job"]["sign"],
+ coverage["job"]["prefix"],
+ coverage["job"]["target"],
+ coverage["job"]["current"],
+ coverage["job"]["diff"],
)
)
- if coverage['job']['sign'] == -1:
+ if coverage["job"]["sign"] == -1:
sys.exit(1)
diff --git a/ambient_toolbox/graphql/forms/mutations.py b/ambient_toolbox/graphql/forms/mutations.py
index 42211e3..c667672 100644
--- a/ambient_toolbox/graphql/forms/mutations.py
+++ b/ambient_toolbox/graphql/forms/mutations.py
@@ -30,7 +30,7 @@ def on_resolve(payload):
result = cls.mutate_and_get_payload(root, info, **input)
if result.errors:
- err_msg = ''
+ err_msg = ""
for err in result.errors:
err_msg += f"Field '{err.field}': {err.messages[0]} "
@@ -42,7 +42,7 @@ def on_resolve(payload):
return on_resolve(result)
-@method_decorator(login_required, name='perform_mutate')
+@method_decorator(login_required, name="perform_mutate")
class LoginRequiredDjangoModelFormMutation(DjangoValidatedModelFormMutation):
"""
Ensures that you need to be logged in with GraphQL JWT (json web token) authentication
diff --git a/ambient_toolbox/graphql/schemes/mutations.py b/ambient_toolbox/graphql/schemes/mutations.py
index 983cef8..350de85 100644
--- a/ambient_toolbox/graphql/schemes/mutations.py
+++ b/ambient_toolbox/graphql/schemes/mutations.py
@@ -21,7 +21,7 @@ class Input:
@classmethod
def __init_subclass_with_meta__(cls, resolver=None, output=None, arguments=None, _meta=None, model=None, **options):
if not model:
- raise AttributeError('DeleteMutation needs a valid model to be set.')
+ raise AttributeError("DeleteMutation needs a valid model to be set.")
super().__init_subclass_with_meta__(resolver, output, arguments, _meta, **options)
cls.model = model
@@ -45,10 +45,10 @@ def mutate_and_get_payload(cls, root, info, **input_data):
Ensure custom validation, fetch object and delete it afterwards.
"""
if not cls.validate(info.context):
- raise GraphQLError('Delete method not allowed.')
+ raise GraphQLError("Delete method not allowed.")
# Get object id
- object_id = int(input_data.get('id', None))
+ object_id = int(input_data.get("id", None))
# Find and delete object
obj = cls.get_queryset(info.context).get(pk=object_id)
@@ -58,7 +58,7 @@ def mutate_and_get_payload(cls, root, info, **input_data):
return DeleteMutation()
-@method_decorator(login_required, name='mutate_and_get_payload')
+@method_decorator(login_required, name="mutate_and_get_payload")
class LoginRequiredDeleteMutation(DeleteMutation):
"""
Deletes an object from the database.
diff --git a/ambient_toolbox/graphql/sentry/utils.py b/ambient_toolbox/graphql/sentry/utils.py
index 3a0290d..73b20ef 100644
--- a/ambient_toolbox/graphql/sentry/utils.py
+++ b/ambient_toolbox/graphql/sentry/utils.py
@@ -9,4 +9,4 @@ def ignore_graphene_logger():
Test for:
* sentry_sdk >= 0.13.0
"""
- ignore_logger('graphql.execution.utils')
+ ignore_logger("graphql.execution.utils")
diff --git a/ambient_toolbox/graphql/tests/base_test.py b/ambient_toolbox/graphql/tests/base_test.py
index 9c7a293..5a7ce03 100644
--- a/ambient_toolbox/graphql/tests/base_test.py
+++ b/ambient_toolbox/graphql/tests/base_test.py
@@ -9,7 +9,7 @@ class GraphQLTestCase(TestCase):
"""
# URL to graphql endpoint
- GRAPHQL_URL = '/graphql/'
+ GRAPHQL_URL = "/graphql/"
# Here you need to set your graphql schema for the tests
GRAPHQL_SCHEMA = None
@@ -18,7 +18,7 @@ def setUpClass(cls):
super().setUpClass()
if not cls.GRAPHQL_SCHEMA:
- raise AttributeError('Variable GRAPHQL_SCHEMA not defined in GraphQLTestCase.')
+ raise AttributeError("Variable GRAPHQL_SCHEMA not defined in GraphQLTestCase.")
cls._client = Client(cls.GRAPHQL_SCHEMA)
@@ -31,13 +31,13 @@ def query(self, query: str, op_name: str = None, input_data: dict = None):
:return: Response object from client
"""
- body = {'query': query}
+ body = {"query": query}
if op_name:
- body['operation_name'] = op_name
+ body["operation_name"] = op_name
if input_data:
- body['variables'] = {'input': input_data}
+ body["variables"] = {"input": input_data}
- resp = self._client.post(self.GRAPHQL_URL, json.dumps(body), content_type='application/json')
+ resp = self._client.post(self.GRAPHQL_URL, json.dumps(body), content_type="application/json")
return resp
def assertResponseNoErrors(self, resp): # noqa: N802
@@ -48,7 +48,7 @@ def assertResponseNoErrors(self, resp): # noqa: N802
"""
content = json.loads(resp.content)
self.assertEqual(resp.status_code, 200)
- self.assertNotIn('errors', list(content.keys()))
+ self.assertNotIn("errors", list(content.keys()))
def assertResponseHasErrors(self, resp): # noqa: N802
"""
@@ -56,4 +56,4 @@ def assertResponseHasErrors(self, resp): # noqa: N802
:resp HttpResponse: Response
"""
content = json.loads(resp.content)
- self.assertIn('errors', list(content.keys()))
+ self.assertIn("errors", list(content.keys()))
diff --git a/ambient_toolbox/mail/backends/whitelist_smtp.py b/ambient_toolbox/mail/backends/whitelist_smtp.py
index 3127420..e55860c 100644
--- a/ambient_toolbox/mail/backends/whitelist_smtp.py
+++ b/ambient_toolbox/mail/backends/whitelist_smtp.py
@@ -23,7 +23,7 @@ def get_domain_whitelist() -> list:
Getter for configuration variable from the settings.
Will return a list of domains: ['ambient.digital', 'ambient.digital']
"""
- return getattr(settings, 'EMAIL_BACKEND_DOMAIN_WHITELIST', [])
+ return getattr(settings, "EMAIL_BACKEND_DOMAIN_WHITELIST", [])
@staticmethod
def get_email_regex():
@@ -31,8 +31,8 @@ def get_email_regex():
Getter for configuration variable from the settings.
Will return a RegEX to match email whitelisted domains.
"""
- return r'^[\w\-\.]+@(%s)$' % '|'.join(x for x in WhitelistEmailBackend.get_domain_whitelist()).replace(
- '.', r'\.'
+ return r"^[\w\-\.]+@(%s)$" % "|".join(x for x in WhitelistEmailBackend.get_domain_whitelist()).replace(
+ ".", r"\."
)
@staticmethod
@@ -56,7 +56,7 @@ def whitify_mail_addresses(mail_address_list: list) -> list:
allowed_recipients.append(to)
elif WhitelistEmailBackend.get_backend_redirect_address():
# Send not allowed emails to the configured redirect address (with CATCHALL)
- allowed_recipients.append(WhitelistEmailBackend.get_backend_redirect_address() % to.replace('@', '_'))
+ allowed_recipients.append(WhitelistEmailBackend.get_backend_redirect_address() % to.replace("@", "_"))
return allowed_recipients
def _process_recipients(self, email_messages):
diff --git a/ambient_toolbox/management/commands/install_permission_fixtures.py b/ambient_toolbox/management/commands/install_permission_fixtures.py
index 8c3b2c7..7038619 100644
--- a/ambient_toolbox/management/commands/install_permission_fixtures.py
+++ b/ambient_toolbox/management/commands/install_permission_fixtures.py
@@ -18,14 +18,14 @@ def add_arguments(self, parser):
)
def handle(self, *args, **options):
- dry_run = options.get('dry_run')
+ dry_run = options.get("dry_run")
if dry_run:
print('Starting in "dry-run" mode...')
try:
fixture_declaration_list = settings.GROUP_PERMISSION_FIXTURES
except AttributeError:
- print('No fixtures found in Django settings.')
+ print("No fixtures found in Django settings.")
fixture_declaration_list = []
for declaration_path in fixture_declaration_list:
@@ -34,11 +34,11 @@ def handle(self, *args, **options):
assert isinstance(
declaration_class, type(GroupPermissionDeclaration)
- ), f"Could\'t load group declaration \"{declaration_path}\"."
+ ), f'Could\'t load group declaration "{declaration_path}".'
print(f'> Installing permissions of group "{declaration_class.name}"...')
service = PermissionSetupService(group_declaration=declaration_class, dry_run=dry_run)
new_permissions, removed_permissions = service.process()
- print(f'> Newly installed permissions: {new_permissions}')
- print(f'> Removed permissions: {removed_permissions}\n')
+ print(f"> Newly installed permissions: {new_permissions}")
+ print(f"> Removed permissions: {removed_permissions}\n")
diff --git a/ambient_toolbox/managers.py b/ambient_toolbox/managers.py
index 47be914..31431e3 100644
--- a/ambient_toolbox/managers.py
+++ b/ambient_toolbox/managers.py
@@ -10,13 +10,13 @@ class AbstractPermissionMixin:
"""
def visible_for(self, user):
- raise NotImplementedError('Please implement this method')
+ raise NotImplementedError("Please implement this method")
def editable_for(self, user):
- raise NotImplementedError('Please implement this method')
+ raise NotImplementedError("Please implement this method")
def deletable_for(self, user):
- raise NotImplementedError('Please implement this method')
+ raise NotImplementedError("Please implement this method")
class AbstractUserSpecificQuerySet(QuerySet, AbstractPermissionMixin):
@@ -28,13 +28,13 @@ def default(self, user):
return self
def visible_for(self, user):
- raise NotImplementedError('Please implement this method')
+ raise NotImplementedError("Please implement this method")
def editable_for(self, user):
- raise NotImplementedError('Please implement this method')
+ raise NotImplementedError("Please implement this method")
def deletable_for(self, user):
- raise NotImplementedError('Please implement this method')
+ raise NotImplementedError("Please implement this method")
class AbstractUserSpecificManager(Manager, AbstractPermissionMixin):
diff --git a/ambient_toolbox/middleware/current_request.py b/ambient_toolbox/middleware/current_request.py
index ce18c21..8bfe969 100644
--- a/ambient_toolbox/middleware/current_request.py
+++ b/ambient_toolbox/middleware/current_request.py
@@ -4,7 +4,7 @@
if TYPE_CHECKING:
from django.http import HttpRequest, HttpResponse
-_request_cv: ContextVar[Optional['HttpRequest']] = ContextVar('request', default=None)
+_request_cv: ContextVar[Optional["HttpRequest"]] = ContextVar("request", default=None)
class CurrentRequestMiddleware:
@@ -12,10 +12,10 @@ class CurrentRequestMiddleware:
Middleware which stores the current request in a thread-safe manner.
"""
- def __init__(self, get_response: Callable[['HttpRequest'], 'HttpResponse']):
+ def __init__(self, get_response: Callable[["HttpRequest"], "HttpResponse"]):
self.get_response = get_response
- def __call__(self, request: 'HttpRequest') -> 'HttpResponse':
+ def __call__(self, request: "HttpRequest") -> "HttpResponse":
token = _request_cv.set(request)
response = self.get_response(request)
_request_cv.reset(token)
diff --git a/ambient_toolbox/middleware/current_user.py b/ambient_toolbox/middleware/current_user.py
index afbe8fd..277d309 100644
--- a/ambient_toolbox/middleware/current_user.py
+++ b/ambient_toolbox/middleware/current_user.py
@@ -19,7 +19,7 @@ class CurrentUserMiddleware(CurrentRequestMiddleware):
# of one of the next major releases, then fully dropping support for
# CurrentUserMiddleware.
- def __init__(self, get_response: Callable[['HttpRequest'], 'HttpResponse']):
+ def __init__(self, get_response: Callable[["HttpRequest"], "HttpResponse"]):
warnings.warn(
"CurrentUserMiddleware is deprecated. Use CurrentRequestMiddleware instead.",
category=DeprecationWarning,
diff --git a/ambient_toolbox/mixins/bleacher.py b/ambient_toolbox/mixins/bleacher.py
index bd8dcd7..021e814 100644
--- a/ambient_toolbox/mixins/bleacher.py
+++ b/ambient_toolbox/mixins/bleacher.py
@@ -32,35 +32,35 @@ class BleacherMixin:
BLEACH_FIELD_LIST = []
DEFAULT_ALLOWED_ATTRIBUTES = {
- '*': ['class', 'style', 'id'],
- 'a': ['href', 'rel'],
- 'img': ['alt', 'src'],
+ "*": ["class", "style", "id"],
+ "a": ["href", "rel"],
+ "img": ["alt", "src"],
}
DEFAULT_ALLOWED_TAGS = bleach.ALLOWED_TAGS + [
- 'span',
- 'p',
- 'h1',
- 'h2',
- 'h3',
- 'h4',
- 'h5',
- 'h6',
- 'img',
- 'div',
- 'u',
- 'br',
- 'blockquote',
+ "span",
+ "p",
+ "h1",
+ "h2",
+ "h3",
+ "h4",
+ "h5",
+ "h6",
+ "img",
+ "div",
+ "u",
+ "br",
+ "blockquote",
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
- self.fields_to_bleach = getattr(self, 'BLEACH_FIELD_LIST', [])
- self.allowed_tags = getattr(self, 'ALLOWED_TAGS', self.DEFAULT_ALLOWED_TAGS)
- self.allowed_attributes = getattr(self, 'ALLOWED_ATTRIBUTES', self.DEFAULT_ALLOWED_ATTRIBUTES)
+ self.fields_to_bleach = getattr(self, "BLEACH_FIELD_LIST", [])
+ self.allowed_tags = getattr(self, "ALLOWED_TAGS", self.DEFAULT_ALLOWED_TAGS)
+ self.allowed_attributes = getattr(self, "ALLOWED_ATTRIBUTES", self.DEFAULT_ALLOWED_ATTRIBUTES)
def _bleach_field(self, field_name):
- str_to_bleach = getattr(self, field_name, '')
+ str_to_bleach = getattr(self, field_name, "")
if str_to_bleach:
cleaned_value = bleach.clean(str_to_bleach, tags=self.allowed_tags, attributes=self.allowed_attributes)
setattr(self, field_name, cleaned_value)
diff --git a/ambient_toolbox/models.py b/ambient_toolbox/models.py
index 0106686..3c311e5 100644
--- a/ambient_toolbox/models.py
+++ b/ambient_toolbox/models.py
@@ -57,7 +57,7 @@ def save(self, force_insert=False, force_update=False, using=None, update_fields
# Handle case that somebody only wants to update some fields
if update_fields is not None and self.ALWAYS_UPDATE_FIELDS:
- update_fields = {'lastmodified_at', 'lastmodified_by', 'created_at', 'created_by'}.union(update_fields)
+ update_fields = {"lastmodified_at", "lastmodified_by", "created_at", "created_by"}.union(update_fields)
super().save(
force_insert=force_insert,
diff --git a/ambient_toolbox/permissions/fixtures/helpers.py b/ambient_toolbox/permissions/fixtures/helpers.py
index fe69f28..f2e29c4 100644
--- a/ambient_toolbox/permissions/fixtures/helpers.py
+++ b/ambient_toolbox/permissions/fixtures/helpers.py
@@ -3,8 +3,8 @@
def generate_default_permissions(model_name: str) -> List[str]:
return [
- f'add_{model_name}',
- f'change_{model_name}',
- f'delete_{model_name}',
- f'view_{model_name}',
+ f"add_{model_name}",
+ f"change_{model_name}",
+ f"delete_{model_name}",
+ f"view_{model_name}",
]
diff --git a/ambient_toolbox/permissions/fixtures/services.py b/ambient_toolbox/permissions/fixtures/services.py
index 99c0eff..60dc84a 100644
--- a/ambient_toolbox/permissions/fixtures/services.py
+++ b/ambient_toolbox/permissions/fixtures/services.py
@@ -48,7 +48,7 @@ def process(self) -> (List[Permission], List[Permission]):
# Add permission object to list
if new_permission in defined_permission_list:
- raise ValueError(f'Permission {new_permission} declared twice.')
+ raise ValueError(f"Permission {new_permission} declared twice.")
defined_permission_list.append(new_permission)
# Check if permission is already set in the group
diff --git a/ambient_toolbox/sentry/helpers.py b/ambient_toolbox/sentry/helpers.py
index 45f0db7..c4c33c1 100644
--- a/ambient_toolbox/sentry/helpers.py
+++ b/ambient_toolbox/sentry/helpers.py
@@ -22,11 +22,11 @@ def __init__(self, denylist: Optional[List[str]] = None, standard_denylist: Opti
self.denylist = [] if denylist is None else denylist
self.standard_denylist = (
[
- 'username',
- 'email',
- 'ip_address',
- 'serializer',
- 'admin',
+ "username",
+ "email",
+ "ip_address",
+ "serializer",
+ "admin",
]
if standard_denylist
else []
@@ -49,15 +49,15 @@ def strip_sensitive_data_from_sentry_event(event, hint):
Requires "sentry-sdk>=1.5.0" to work.
"""
try:
- del event['user']['username']
+ del event["user"]["username"]
except KeyError:
pass
try:
- del event['user']['email']
+ del event["user"]["email"]
except KeyError:
pass
try:
- del event['user']['ip_address']
+ del event["user"]["ip_address"]
except KeyError:
pass
return event
diff --git a/ambient_toolbox/services/custom_scrubber.py b/ambient_toolbox/services/custom_scrubber.py
index 50b3dfd..6432290 100644
--- a/ambient_toolbox/services/custom_scrubber.py
+++ b/ambient_toolbox/services/custom_scrubber.py
@@ -13,7 +13,7 @@ class ScrubbingError(RuntimeError):
class AbstractScrubbingService:
- DEFAULT_USER_PASSWORD = 'Admin0404!'
+ DEFAULT_USER_PASSWORD = "Admin0404!"
# Overwritable values
keep_session_data = False
@@ -23,32 +23,32 @@ class AbstractScrubbingService:
post_scrub_functions = []
def __init__(self):
- self._logger = logging.getLogger('django_scrubber')
+ self._logger = logging.getLogger("django_scrubber")
def _get_hashed_default_password(self):
return make_password(self.DEFAULT_USER_PASSWORD)
def _validation(self):
if not settings.DEBUG:
- self._logger.warning('Attention! Has to run in DEBUG mode!')
+ self._logger.warning("Attention! Has to run in DEBUG mode!")
return False
- if 'django_scrubber' not in settings.INSTALLED_APPS:
- self._logger.warning('Attention! django-scrubber needs to be installed!')
+ if "django_scrubber" not in settings.INSTALLED_APPS:
+ self._logger.warning("Attention! django-scrubber needs to be installed!")
return False
- if 'django_scrubber' not in list(settings.LOGGING['loggers'].keys()):
- self._logger.warning('Attention! Logging for django-scrubber is not activated!')
+ if "django_scrubber" not in list(settings.LOGGING["loggers"].keys()):
+ self._logger.warning("Attention! Logging for django-scrubber is not activated!")
return True
def process(self):
- self._logger.info('Start scrubbing process...')
+ self._logger.info("Start scrubbing process...")
- self._logger.info('Validating setup...')
+ self._logger.info("Validating setup...")
if not self._validation():
- self._logger.warning('Aborting process!')
- raise ScrubbingError('Scrubber settings validation failed')
+ self._logger.warning("Aborting process!")
+ raise ScrubbingError("Scrubber settings validation failed")
# Custom pre-scrubbing
for name in self.pre_scrub_functions:
@@ -57,7 +57,7 @@ def process(self):
method()
self._logger.info('Scrubbing data with "scrub_data"...')
- call_command('scrub_data')
+ call_command("scrub_data")
# Custom post-scrubbing
for name in self.post_scrub_functions:
@@ -81,9 +81,9 @@ def process(self):
self._logger.info('Clearing data from "django_scrubber_fakedata" ...')
# We truncate and don't scrub because the table is huge and clearing on object-level might take a while.
# Furthermore can we avoid having a direct dependency to django-scrubber this way.
- cursor = connections['default'].cursor()
- cursor.execute('TRUNCATE TABLE django_scrubber_fakedata;')
+ cursor = connections["default"].cursor()
+ cursor.execute("TRUNCATE TABLE django_scrubber_fakedata;")
- self._logger.info('Scrubbing finished!')
+ self._logger.info("Scrubbing finished!")
return True
diff --git a/ambient_toolbox/templatetags/ai_email_tags.py b/ambient_toolbox/templatetags/ai_email_tags.py
index 303b6b2..13b6018 100644
--- a/ambient_toolbox/templatetags/ai_email_tags.py
+++ b/ambient_toolbox/templatetags/ai_email_tags.py
@@ -6,7 +6,7 @@
def obfuscate_string(value):
- return ''.join([f'{str(ord(char)):s};' for char in value])
+ return "".join([f"{str(ord(char)):s};" for char in value])
@register.filter
@@ -25,4 +25,4 @@ def obfuscate_mailto(value, text=False):
else:
link_text = mail
- return mark_safe('{:s}'.format(obfuscate_string('mailto:'), mail, link_text))
+ return mark_safe('{:s}'.format(obfuscate_string("mailto:"), mail, link_text))
diff --git a/ambient_toolbox/templatetags/ai_file_tags.py b/ambient_toolbox/templatetags/ai_file_tags.py
index 45c6f04..5a208eb 100644
--- a/ambient_toolbox/templatetags/ai_file_tags.py
+++ b/ambient_toolbox/templatetags/ai_file_tags.py
@@ -17,7 +17,7 @@ def filename(value, max_length=25):
"""
name = os.path.basename(value.url)
if len(name) > max_length:
- ext = name.split('.')[-1]
+ ext = name.split(".")[-1]
name = f"{name[:max_length]}[..].{ext}"
return name
diff --git a/ambient_toolbox/templatetags/ai_number_tags.py b/ambient_toolbox/templatetags/ai_number_tags.py
index 8ae142b..bfc4fe1 100644
--- a/ambient_toolbox/templatetags/ai_number_tags.py
+++ b/ambient_toolbox/templatetags/ai_number_tags.py
@@ -3,7 +3,7 @@
register = template.Library()
-@register.filter(name='multiply')
+@register.filter(name="multiply")
def multiply(value, arg):
"""
Multiplies the arg and the value
@@ -16,7 +16,7 @@ def multiply(value, arg):
return None
-@register.filter(name='subtract')
+@register.filter(name="subtract")
def subtract(value, arg):
"""
Subtracts the arg from the value
@@ -26,7 +26,7 @@ def subtract(value, arg):
return int(value) - int(arg)
-@register.filter(name='divide')
+@register.filter(name="divide")
def divide(value, arg):
"""
Divides the value by the arg
@@ -37,7 +37,7 @@ def divide(value, arg):
return None
-@register.filter(name='to_int')
+@register.filter(name="to_int")
def to_int(value):
"""
Parses a string to int value
diff --git a/ambient_toolbox/templatetags/ai_object_tags.py b/ambient_toolbox/templatetags/ai_object_tags.py
index 3f95a27..75b5aea 100644
--- a/ambient_toolbox/templatetags/ai_object_tags.py
+++ b/ambient_toolbox/templatetags/ai_object_tags.py
@@ -12,9 +12,9 @@ def dict_key_lookup(the_dict, key):
:param key:
:return: str
"""
- return the_dict.get(key, '')
+ return the_dict.get(key, "")
-@register.filter(name='label')
+@register.filter(name="label")
def label(value):
return value.field.__class__.__name__
diff --git a/ambient_toolbox/templatetags/ai_string_tags.py b/ambient_toolbox/templatetags/ai_string_tags.py
index 25f9f99..3227bcf 100644
--- a/ambient_toolbox/templatetags/ai_string_tags.py
+++ b/ambient_toolbox/templatetags/ai_string_tags.py
@@ -4,7 +4,7 @@
register = template.Library()
-@register.filter(name='get_first_char')
+@register.filter(name="get_first_char")
def get_first_char(value):
"""
Returns the first char of the given string
@@ -14,7 +14,7 @@ def get_first_char(value):
return value[:1]
-@register.filter(name='concat')
+@register.filter(name="concat")
def concat(obj, value: str) -> str:
"""
Concatenates the two given strings
diff --git a/ambient_toolbox/tests/mixins.py b/ambient_toolbox/tests/mixins.py
index 250db7c..de7a1ae 100644
--- a/ambient_toolbox/tests/mixins.py
+++ b/ambient_toolbox/tests/mixins.py
@@ -35,8 +35,8 @@ def _get_response(self, method, user, data, url_params=None, *args, **kwargs):
factory = self.factory_class()
req_kwargs = {}
if data:
- req_kwargs.update({'data': data})
- request = getattr(factory, method)('/', **req_kwargs)
+ req_kwargs.update({"data": data})
+ request = getattr(factory, method)("/", **req_kwargs)
# Annotate a request object with a session
middleware = SessionMiddleware(get_response=HttpResponse(status=200))
@@ -55,15 +55,15 @@ def _get_response(self, method, user, data, url_params=None, *args, **kwargs):
def get(self, user=None, data=None, url_params=None, *args, **kwargs):
"""Returns response for a GET request."""
- return self._get_response('get', user, data, url_params, *args, **kwargs)
+ return self._get_response("get", user, data, url_params, *args, **kwargs)
def post(self, user=None, data=None, url_params=None, *args, **kwargs):
"""Returns response for a POST request."""
- return self._get_response('post', user, data, url_params, *args, **kwargs)
+ return self._get_response("post", user, data, url_params, *args, **kwargs)
def delete(self, user=None, data=None, url_params=None, *args, **kwargs):
"""Returns response for a DELETE request."""
- return self._get_response('delete', user, data, url_params, *args, **kwargs)
+ return self._get_response("delete", user, data, url_params, *args, **kwargs)
class RequestProviderMixin:
@@ -75,13 +75,13 @@ class RequestProviderMixin:
@staticmethod
def get_request(
- user: Union[AbstractBaseUser, AnonymousUser, None] = None, method: str = 'GET', url: Optional[str] = None
+ user: Union[AbstractBaseUser, AnonymousUser, None] = None, method: str = "GET", url: Optional[str] = None
):
"""
Creates and returns a django request.
"""
# Determine URL
- url = url if url else '/'
+ url = url if url else "/"
# Create test request
factory = RequestFactory()
@@ -92,7 +92,7 @@ def get_request(
if user is None or isinstance(user, AbstractBaseUser) or isinstance(user, AnonymousUser): # noqa: PLR1701
request.user = user
else:
- raise ValueError(_('Please pass a user object to RequestProviderMixin.'))
+ raise ValueError(_("Please pass a user object to RequestProviderMixin."))
# Annotate a request object with a session
session_middleware = SessionMiddleware(get_response=HttpResponse(status=200))
diff --git a/ambient_toolbox/tests/structure_validator/settings.py b/ambient_toolbox/tests/structure_validator/settings.py
index 315164a..7460e17 100644
--- a/ambient_toolbox/tests/structure_validator/settings.py
+++ b/ambient_toolbox/tests/structure_validator/settings.py
@@ -5,7 +5,7 @@
try:
TEST_STRUCTURE_VALIDATOR_BASE_DIR = settings.BASE_DIR
except AttributeError:
- TEST_STRUCTURE_VALIDATOR_BASE_DIR = ''
-TEST_STRUCTURE_VALIDATOR_BASE_APP_NAME = 'apps'
+ TEST_STRUCTURE_VALIDATOR_BASE_DIR = ""
+TEST_STRUCTURE_VALIDATOR_BASE_APP_NAME = "apps"
TEST_STRUCTURE_VALIDATOR_APP_LIST = settings.INSTALLED_APPS
TEST_STRUCTURE_VALIDATOR_IGNORED_DIRECTORY_LIST = []
diff --git a/ambient_toolbox/tests/structure_validator/test_structure_validator.py b/ambient_toolbox/tests/structure_validator/test_structure_validator.py
index 8b895e6..680f478 100644
--- a/ambient_toolbox/tests/structure_validator/test_structure_validator.py
+++ b/ambient_toolbox/tests/structure_validator/test_structure_validator.py
@@ -18,7 +18,7 @@ def __init__(self):
@staticmethod
def _get_file_whitelist() -> list:
- default_whitelist = ['__init__']
+ default_whitelist = ["__init__"]
try:
return default_whitelist + settings.TEST_STRUCTURE_VALIDATOR_FILE_WHITELIST
except AttributeError:
@@ -40,7 +40,7 @@ def _get_base_app_name() -> str:
@staticmethod
def _get_ignored_directory_list() -> list:
- default_dir_list = ['__pycache__']
+ default_dir_list = ["__pycache__"]
try:
return default_dir_list + settings.TEST_STRUCTURE_VALIDATOR_IGNORED_DIRECTORY_LIST
except AttributeError:
@@ -54,21 +54,21 @@ def _get_app_list() -> Union[list, tuple]:
return toolbox_settings.TEST_STRUCTURE_VALIDATOR_APP_LIST
def _check_missing_test_prefix(self, *, root: str, file: str, filename: str, extension: str) -> bool:
- if extension == '.py' and not filename[0:5] == "test_" and filename not in self.file_whitelist:
- file_path = f"{root}\\{file}".replace('\\', '/')
+ if extension == ".py" and not filename[0:5] == "test_" and filename not in self.file_whitelist:
+ file_path = f"{root}\\{file}".replace("\\", "/")
self.issue_list.append(f'Python file without "test_" prefix found: {file_path!r}.')
return False
return True
def _check_missing_init(self, *, root: str, init_found: bool, number_of_py_files: int) -> bool:
if not init_found and number_of_py_files > 0:
- path = root.replace('\\', '/')
+ path = root.replace("\\", "/")
self.issue_list.append(f"__init__.py missing in {path!r}.")
return False
return True
def _build_path_to_test_package(self, app: str) -> Path:
- return self._get_base_dir() / Path(app.replace('.', '/')) / 'tests'
+ return self._get_base_dir() / Path(app.replace(".", "/")) / "tests"
def process(self) -> None: # noqa: PLR0912
backend_package = self._get_base_app_name()
@@ -79,7 +79,7 @@ def process(self) -> None: # noqa: PLR0912
continue
app_path = self._build_path_to_test_package(app=app)
for root, dirs, files in os.walk(app_path):
- cleaned_root = root.replace('\\', '/')
+ cleaned_root = root.replace("\\", "/")
print(f"Inspecting {cleaned_root!r}...")
init_found = False
number_of_py_files = 0
@@ -118,7 +118,7 @@ def process(self) -> None: # noqa: PLR0912
print("=======================")
if number_of_issues:
- print(f'Checking test structure failed with {number_of_issues} issue(s).')
+ print(f"Checking test structure failed with {number_of_issues} issue(s).")
sys.exit(1)
else:
print("0 issues detected. Yeah!")
diff --git a/ambient_toolbox/utils/date.py b/ambient_toolbox/utils/date.py
index fa8b193..62523c3 100644
--- a/ambient_toolbox/utils/date.py
+++ b/ambient_toolbox/utils/date.py
@@ -66,12 +66,12 @@ def first_day_of_month(source_date: datetime.date) -> datetime.date:
def get_formatted_date_str(source_date: Union[datetime.date, datetime.datetime]) -> str:
- return source_date.strftime('%d.%m.%Y')
+ return source_date.strftime("%d.%m.%Y")
def get_time_from_seconds(seconds: int) -> str:
if seconds < 0:
- raise ValueError(_('Seconds must be positive.'))
+ raise ValueError(_("Seconds must be positive."))
hours = seconds // 3600
minutes = (seconds - (hours * 3600)) // 60
seconds = seconds - ((hours * 3600) + (minutes * 60))
@@ -93,7 +93,7 @@ def get_start_and_end_date_from_calendar_week(year: int, calendar_week: int) ->
"""
Returns the first and last day of a given calendar week
"""
- monday = datetime.datetime.strptime(f'{year}-{calendar_week}-1', "%Y-%W-%w").astimezone().date()
+ monday = datetime.datetime.strptime(f"{year}-{calendar_week}-1", "%Y-%W-%w").astimezone().date()
return monday, monday + datetime.timedelta(days=6.9)
@@ -124,7 +124,7 @@ def date_month_delta(start_date: datetime.date, end_date: datetime.date) -> floa
"""
# If `start_date` is greater, this logic doesn't make any sense
if start_date > end_date:
- raise NotImplementedError('Start date > end date')
+ raise NotImplementedError("Start date > end date")
# Calculate date difference between dates
date_diff = (end_date - start_date).days
diff --git a/ambient_toolbox/utils/file.py b/ambient_toolbox/utils/file.py
index e9a260f..19b59f2 100644
--- a/ambient_toolbox/utils/file.py
+++ b/ambient_toolbox/utils/file.py
@@ -8,12 +8,12 @@ def get_filename_without_ending(file_path: str) -> str:
"""
# if filename has file_path parts
- if '/' in file_path:
- filename = file_path.rsplit('/')[-1]
+ if "/" in file_path:
+ filename = file_path.rsplit("/")[-1]
else:
filename = file_path
- return filename.rsplit('.', 1)[0]
+ return filename.rsplit(".", 1)[0]
def crc(file_path: str) -> str:
@@ -40,7 +40,7 @@ def md5_checksum(file_path: str) -> str:
:param file_path: the file for which the MD5 hashsum should be calculated.
:return: returns the MD5 of the file in hexadecimal format.
"""
- with open(file_path, 'rb') as fh:
+ with open(file_path, "rb") as fh:
m = hashlib.md5()
while True:
data = fh.read(8192)
diff --git a/ambient_toolbox/utils/log_whodid.py b/ambient_toolbox/utils/log_whodid.py
index 0b0259e..7fd145f 100644
--- a/ambient_toolbox/utils/log_whodid.py
+++ b/ambient_toolbox/utils/log_whodid.py
@@ -5,8 +5,8 @@ def log_whodid(obj: models.Model, user) -> None:
"""
Stores the given user as creator or editor of the given object
"""
- if hasattr(obj, 'created_by') and obj.created_by is None:
+ if hasattr(obj, "created_by") and obj.created_by is None:
obj.created_by = user
- if hasattr(obj, 'lastmodified_by'):
+ if hasattr(obj, "lastmodified_by"):
obj.lastmodified_by = user
diff --git a/ambient_toolbox/utils/model.py b/ambient_toolbox/utils/model.py
index 3917156..d1c57e3 100644
--- a/ambient_toolbox/utils/model.py
+++ b/ambient_toolbox/utils/model.py
@@ -12,7 +12,7 @@ def object_to_dict(obj, blacklisted_fields: list = None, include_id: bool = Fals
# Add default django primary key to blacklist
if not include_id:
- blacklisted_fields.append('id')
+ blacklisted_fields.append("id")
data = vars(obj)
valid_data = {}
@@ -22,7 +22,7 @@ def object_to_dict(obj, blacklisted_fields: list = None, include_id: bool = Fals
if type(f) != ForeignKey:
valid_fields.append(f.name)
else:
- valid_fields.append(f'{f.name}_id')
+ valid_fields.append(f"{f.name}_id")
for key, value in list(data.items()):
if key in valid_fields and key not in blacklisted_fields:
diff --git a/ambient_toolbox/utils/named_tuple.py b/ambient_toolbox/utils/named_tuple.py
index 4eaac65..4d6ca31 100644
--- a/ambient_toolbox/utils/named_tuple.py
+++ b/ambient_toolbox/utils/named_tuple.py
@@ -105,7 +105,7 @@ def get_value_from_tuple_by_key(choices: tuple, key) -> Any:
try:
return dict(choices)[key]
except KeyError:
- return '-'
+ return "-"
def get_key_from_tuple_by_value(choices: tuple, value) -> Any:
@@ -117,4 +117,4 @@ def get_key_from_tuple_by_value(choices: tuple, value) -> Any:
try:
return [x[0] for x in choices if x[1] == value][0]
except IndexError:
- return '-'
+ return "-"
diff --git a/ambient_toolbox/utils/string.py b/ambient_toolbox/utils/string.py
index 7fd0e5e..f81c667 100644
--- a/ambient_toolbox/utils/string.py
+++ b/ambient_toolbox/utils/string.py
@@ -21,13 +21,13 @@ def slugify_file_name(file_name: str, length: int = 40) -> str:
Slugify the given file name
"""
name, ext = os.path.splitext(file_name)
- name = smart_str(slugify(name).replace('-', '_'))
+ name = smart_str(slugify(name).replace("-", "_"))
ext = smart_str(slugify(ext))
- result = '{}{}{}'.format(name[:length], "." if ext else "", ext)
+ result = "{}{}{}".format(name[:length], "." if ext else "", ext)
return result
-def smart_truncate(text: Optional[str], max_length: int = 100, suffix: str = '...') -> str:
+def smart_truncate(text: Optional[str], max_length: int = 100, suffix: str = "...") -> str:
"""
Returns a string of at most `max_length` characters, cutting
only at word-boundaries. If the string was truncated, `suffix`
@@ -36,7 +36,7 @@ def smart_truncate(text: Optional[str], max_length: int = 100, suffix: str = '..
can choose a custom suffix.
"""
if text is None:
- return ''
+ return ""
# Return the string itself if length is smaller or equal to the limit
if len(text) <= max_length:
@@ -46,10 +46,10 @@ def smart_truncate(text: Optional[str], max_length: int = 100, suffix: str = '..
value = text[:max_length]
# Break into words and remove the last
- words = value.split(' ')[:-1]
+ words = value.split(" ")[:-1]
# Join the words and return
- return ' '.join(words) + suffix
+ return " ".join(words) + suffix
def float_to_string(value: Optional[float], replacement: str = "0,00") -> str:
@@ -59,7 +59,7 @@ def float_to_string(value: Optional[float], replacement: str = "0,00") -> str:
# todo thousand separator would be nice
If the passed object is None, it will return `replacement`.
"""
- return ("%.2f" % value).replace('.', ',') if value is not None else replacement
+ return ("%.2f" % value).replace(".", ",") if value is not None else replacement
def date_to_string(value: Optional[datetime.date], replacement: str = "-", str_format: str = "%d.%m.%Y") -> str:
@@ -102,8 +102,8 @@ def encode_to_xml(text: str) -> str:
Encodes ampersand, greater and lower characters in a given string to HTML-entities.
"""
text_str = str(text)
- text_str = text_str.replace('&', '&')
- text_str = text_str.replace('<', '<')
- text_str = text_str.replace('>', '>')
+ text_str = text_str.replace("&", "&")
+ text_str = text_str.replace("<", "<")
+ text_str = text_str.replace(">", ">")
return text_str
diff --git a/ambient_toolbox/view_layer/form_mixins.py b/ambient_toolbox/view_layer/form_mixins.py
index 5730e6c..e678564 100644
--- a/ambient_toolbox/view_layer/form_mixins.py
+++ b/ambient_toolbox/view_layer/form_mixins.py
@@ -11,12 +11,12 @@ class CrispyLayoutFormMixin:
def __init__(self, *args, **kwargs):
# Crispy
self.helper = FormHelper()
- self.helper.form_class = 'form-horizontal form-bordered form-row-stripped'
- self.helper.form_method = 'post'
- self.helper.add_input(Submit('submit_button', _('Save')))
+ self.helper.form_class = "form-horizontal form-bordered form-row-stripped"
+ self.helper.form_method = "post"
+ self.helper.add_input(Submit("submit_button", _("Save")))
self.helper.form_tag = True
- self.helper.label_class = 'col-md-3'
- self.helper.field_class = 'col-md-9'
- self.helper.label_size = ' col-md-offset-3'
+ self.helper.label_class = "col-md-3"
+ self.helper.field_class = "col-md-9"
+ self.helper.label_size = " col-md-offset-3"
super().__init__(*args, **kwargs)
diff --git a/ambient_toolbox/view_layer/formset_mixins.py b/ambient_toolbox/view_layer/formset_mixins.py
index 89651f2..d5a7d82 100644
--- a/ambient_toolbox/view_layer/formset_mixins.py
+++ b/ambient_toolbox/view_layer/formset_mixins.py
@@ -7,6 +7,6 @@ def get_number_of_children(self):
# Count all choices which are not being deleted right now
no_choices = 0
for form in self.forms:
- if getattr(form, 'cleaned_data', None) and not form.cleaned_data.get('DELETE'):
+ if getattr(form, "cleaned_data", None) and not form.cleaned_data.get("DELETE"):
no_choices += 1
return no_choices
diff --git a/ambient_toolbox/view_layer/formset_view_mixin.py b/ambient_toolbox/view_layer/formset_view_mixin.py
index 704fbee..3eea19b 100644
--- a/ambient_toolbox/view_layer/formset_view_mixin.py
+++ b/ambient_toolbox/view_layer/formset_view_mixin.py
@@ -13,11 +13,11 @@ class _FormsetMixin:
def get_formset_kwargs(self):
# may be overridden or extended
- return {'instance': self.object}
+ return {"instance": self.object}
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
- context['formset'] = self.formset_class(**self.get_formset_kwargs())
+ context["formset"] = self.formset_class(**self.get_formset_kwargs())
return context
def form_valid(self, form, formset):
@@ -28,7 +28,7 @@ def form_valid(self, form, formset):
formset.instance = self.object
formset.save()
- if hasattr(self, 'additional_is_valid'):
+ if hasattr(self, "additional_is_valid"):
self.additional_is_valid(form, formset)
# Return response (a redirect)
@@ -47,8 +47,8 @@ def post(self, request, *args, **kwargs):
context = self.get_context_data()
# Update form and formset variables
- context['form'] = form
- context['formset'] = formset
+ context["form"] = form
+ context["formset"] = formset
# Pass all data to template
return render(request, self.get_template_names(), context)
diff --git a/ambient_toolbox/view_layer/htmx_mixins.py b/ambient_toolbox/view_layer/htmx_mixins.py
index eb54081..2c791fd 100644
--- a/ambient_toolbox/view_layer/htmx_mixins.py
+++ b/ambient_toolbox/view_layer/htmx_mixins.py
@@ -22,13 +22,13 @@ def dispatch(self, request, *args, **kwargs):
# Set redirect header if set
if hx_redirect_url:
- response['HX-Redirect'] = hx_redirect_url
+ response["HX-Redirect"] = hx_redirect_url
# Set trigger header if set
if isinstance(hx_trigger, dict):
- response['HX-Trigger'] = json.dumps(hx_trigger)
+ response["HX-Trigger"] = json.dumps(hx_trigger)
elif isinstance(hx_trigger, str):
- response['HX-Trigger'] = hx_trigger
+ response["HX-Trigger"] = hx_trigger
# Return augmented response
return response
diff --git a/ambient_toolbox/view_layer/mixins.py b/ambient_toolbox/view_layer/mixins.py
index 586bf0c..bd8e693 100644
--- a/ambient_toolbox/view_layer/mixins.py
+++ b/ambient_toolbox/view_layer/mixins.py
@@ -11,14 +11,14 @@ class DjangoPermissionRequiredMixin:
permission_list = None
login_required = True
- login_view_name = 'login-view'
+ login_view_name = "login-view"
def __init__(self):
super().__init__()
if self.permission_list is None:
raise RuntimeError(
- _('Class-based view using DjangoPermissionRequiredMixin without defining a permission list.')
+ _("Class-based view using DjangoPermissionRequiredMixin without defining a permission list.")
)
def get_login_url(self) -> str:
@@ -54,7 +54,7 @@ def dispatch(self, request, *args, **kwargs):
# Validate that user has all required permissions
if not self.has_permissions(request.user):
- return render(request, '403.html', status=403)
+ return render(request, "403.html", status=403)
# If everything goes well, we'll continue to the view
return super().dispatch(request, *args, **kwargs)
diff --git a/ambient_toolbox/view_layer/tests/mixins.py b/ambient_toolbox/view_layer/tests/mixins.py
index 49299e3..ab729ae 100644
--- a/ambient_toolbox/view_layer/tests/mixins.py
+++ b/ambient_toolbox/view_layer/tests/mixins.py
@@ -24,7 +24,7 @@ def setUpTestData(cls):
@classmethod
def get_test_user(cls):
- return get_user_model().objects.create(username='test_user', email='test.user@ambient-toolbox.com')
+ return get_user_model().objects.create(username="test_user", email="test.user@ambient-toolbox.com")
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
@@ -33,7 +33,7 @@ def __init__(self, *args, **kwargs) -> None:
raise TestSetupConfigurationError(_('BaseViewPermissionTestMixin used without setting a "view_class".'))
def get_view_instance(
- self, *, user: Union[AbstractBaseUser, AnonymousUser], kwargs: dict = None, method: str = 'GET'
+ self, *, user: Union[AbstractBaseUser, AnonymousUser], kwargs: dict = None, method: str = "GET"
):
"""
Creates an instance of the given view class and injects a valid request.
@@ -49,8 +49,8 @@ def test_view_class_inherits_mixin(self):
def test_permissions_are_equal(self):
# Sanity checks
- self.assertIsNotNone(self.permission_list, msg='Missing permission list declaration in test.')
- self.assertIsNotNone(self.view_class.permission_list, msg='Missing permission list declaration in view.')
+ self.assertIsNotNone(self.permission_list, msg="Missing permission list declaration in test.")
+ self.assertIsNotNone(self.view_class.permission_list, msg="Missing permission list declaration in view.")
# Assert same amount of permissions
self.assertEqual(len(self.permission_list), len(self.view_class.permission_list))
@@ -65,11 +65,11 @@ def test_permissions_are_equal(self):
def test_permissions_exist_in_database(self):
for permission in self.permission_list:
- if '.' not in permission:
+ if "." not in permission:
raise TestSetupConfigurationError(
f'View "{self.view_class}" contains ill-formatted permission ' f'"{permission}".'
)
- app_label, codename = permission.split('.')
+ app_label, codename = permission.split(".")
permission_qs = Permission.objects.filter(content_type__app_label=app_label, codename=codename)
if not permission_qs.exists():
@@ -78,7 +78,7 @@ def test_permissions_exist_in_database(self):
)
def test_passes_login_barrier_is_called(self):
- with mock.patch.object(self.view_class, 'passes_login_barrier', return_value=False) as mock_method:
+ with mock.patch.object(self.view_class, "passes_login_barrier", return_value=False) as mock_method:
view = self.get_view_instance(user=AnonymousUser())
response = view.dispatch(request=view.request, **view.kwargs)
# If a user is not logged in, he'll be forwarded to the login view
@@ -87,7 +87,7 @@ def test_passes_login_barrier_is_called(self):
mock_method.assert_called_once()
def test_has_permissions_is_called(self):
- with mock.patch.object(self.view_class, 'has_permissions', return_value=False) as mock_method:
+ with mock.patch.object(self.view_class, "has_permissions", return_value=False) as mock_method:
view = self.get_view_instance(user=self.user)
response = view.dispatch(request=view.request, **view.kwargs)
self.assertEqual(response.status_code, 403)
diff --git a/ambient_toolbox/view_layer/views.py b/ambient_toolbox/view_layer/views.py
index 844ffce..5805c58 100644
--- a/ambient_toolbox/view_layer/views.py
+++ b/ambient_toolbox/view_layer/views.py
@@ -29,7 +29,7 @@ class RequestInFormKwargsMixin:
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
- kwargs.update({'request': self.request})
+ kwargs.update({"request": self.request})
return kwargs
@@ -41,7 +41,7 @@ class UserInFormKwargsMixin:
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
- kwargs.update({'user': self.request.user})
+ kwargs.update({"user": self.request.user})
return kwargs
@@ -53,7 +53,7 @@ class ToggleView(SingleObjectMixin, generic.View):
"""
object = None
- http_method_names = ('post',)
+ http_method_names = ("post",)
def post(self, request, *args, **kwargs):
raise NotImplementedError
diff --git a/docs/conf.py b/docs/conf.py
index b4b43b5..a38601e 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -16,18 +16,18 @@
import django
from django.conf import settings
-sys.path.insert(0, os.path.abspath('..')) # so that we can access the "ambient_toolbox" package
+sys.path.insert(0, os.path.abspath("..")) # so that we can access the "ambient_toolbox" package
settings.configure(
INSTALLED_APPS=[
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
- 'ambient_toolbox',
+ "django.contrib.admin",
+ "django.contrib.auth",
+ "django.contrib.contenttypes",
+ "django.contrib.sessions",
+ "django.contrib.messages",
+ "django.contrib.staticfiles",
+ "ambient_toolbox",
],
- SECRET_KEY='ASDFjklö123456890',
+ SECRET_KEY="ASDFjklö123456890",
)
django.setup()
@@ -35,32 +35,32 @@
# -- Project information -----------------------------------------------------
-project = 'ambient-toolbox'
-copyright = '2023, Ambient Innovation: GmbH' # noqa: A001
-author = 'Ambient Innovation: GmbH '
+project = "ambient-toolbox"
+copyright = "2023, Ambient Innovation: GmbH" # noqa: A001
+author = "Ambient Innovation: GmbH "
version = __version__
release = __version__
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# extensions coming with Sphinx (named "sphinx.ext.*") or your custom
# ones.
extensions = [
- 'sphinx_rtd_theme',
- 'sphinx.ext.autodoc',
- 'm2r2',
+ "sphinx_rtd_theme",
+ "sphinx.ext.autodoc",
+ "m2r2",
]
-source_suffix = ['.rst', '.md']
+source_suffix = [".rst", ".md"]
# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
-exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# -- Options for HTML output -------------------------------------------------
@@ -68,17 +68,17 @@
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
-# html_theme = 'alabaster'
-html_theme = 'sphinx_rtd_theme'
+# html_theme = "alabaster"
+html_theme = "sphinx_rtd_theme"
html_theme_options = {
- 'display_version': False,
- 'style_external_links': False,
+ "display_version": False,
+ "style_external_links": False,
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = ["_static"]
# Set master doc file
-master_doc = 'index'
+master_doc = "index"
diff --git a/manage.py b/manage.py
index 1b243ab..9e94ce3 100644
--- a/manage.py
+++ b/manage.py
@@ -6,7 +6,7 @@
def main():
"""Run administrative tasks."""
- os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
@@ -18,5 +18,5 @@ def main():
execute_from_command_line(sys.argv)
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/pyproject.toml b/pyproject.toml
index 0aadc19..2a3e819 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -44,12 +44,12 @@ dev = [
'pytest-mock~=3.10',
'coverage~=7.3',
'pre-commit~=3.5',
- 'black~=23.10',
+ 'ruff~=0.1',
'sphinx==4.2.0',
'sphinx-rtd-theme==1.0.0',
'm2r2==0.3.1',
'mistune<2.0.0',
- 'ambient-package-update~=23.10.5',
+ 'ambient-package-update~=23.10.6',
'gevent~=22.10',
]
drf = [
@@ -76,15 +76,6 @@ name = "ambient_toolbox"
'Bugtracker' = 'https://github.com/ambient-innovation/ambient-toolbox/issues'
'Changelog' = 'https://ambient-toolbox.readthedocs.io/en/latest/features/changelog.html'
-
-[tool.black]
-# use force-exclude, so that black also applies exclude when run using pre-commit: https://github.com/psf/black/issues/395
-force-exclude = '''.*/migrations/.*'''
-line-length = 120
-multi_line_output = 3
-skip-string-normalization = true
-include_trailing_comma = true
-
[tool.ruff]
select = [
"E", # pycodestyle errors
@@ -173,6 +164,19 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
# Assume Python 3.12
target-version = "py312"
+[tool.ruff.format]
+# Like Black, use double quotes for strings.
+quote-style = "double"
+
+# Like Black, indent with spaces, rather than tabs.
+indent-style = "space"
+
+# Like Black, respect magic trailing commas.
+skip-magic-trailing-comma = false
+
+# Like Black, automatically detect the appropriate line ending.
+line-ending = "auto"
+
[tool.tox]
legacy_tox_ini = """
[tox]
diff --git a/settings.py b/settings.py
index 116bd94..7774b84 100644
--- a/settings.py
+++ b/settings.py
@@ -3,64 +3,64 @@
BASE_PATH = Path(__file__).resolve(strict=True).parent
INSTALLED_APPS = (
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
- 'testapp',
+ "django.contrib.admin",
+ "django.contrib.auth",
+ "django.contrib.contenttypes",
+ "django.contrib.sessions",
+ "django.contrib.messages",
+ "django.contrib.staticfiles",
+ "testapp",
)
DEBUG = False
-ALLOWED_HOSTS = ['localhost:8000']
+ALLOWED_HOSTS = ["localhost:8000"]
-SECRET_KEY = 'ASDFjklö123456890'
+SECRET_KEY = "ASDFjklö123456890"
# Routing
-ROOT_URLCONF = 'testapp.urls'
+ROOT_URLCONF = "testapp.urls"
-DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
+DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': 'db.sqlite',
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3",
+ "NAME": "db.sqlite",
}
}
TEMPLATES = [
{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': ['templates'],
- 'APP_DIRS': True,
- 'OPTIONS': {
- 'context_processors': [
- 'django.template.context_processors.debug',
- 'django.template.context_processors.request',
- 'django.contrib.auth.context_processors.auth',
- 'django.contrib.messages.context_processors.messages',
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": ["templates"],
+ "APP_DIRS": True,
+ "OPTIONS": {
+ "context_processors": [
+ "django.template.context_processors.debug",
+ "django.template.context_processors.request",
+ "django.contrib.auth.context_processors.auth",
+ "django.contrib.messages.context_processors.messages",
],
- 'debug': True,
+ "debug": True,
},
},
]
MIDDLEWARE = (
- 'django.middleware.security.SecurityMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.common.CommonMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',
- 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ "django.middleware.security.SecurityMiddleware",
+ "django.contrib.sessions.middleware.SessionMiddleware",
+ "django.middleware.common.CommonMiddleware",
+ "django.middleware.csrf.CsrfViewMiddleware",
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
+ "django.contrib.messages.middleware.MessageMiddleware",
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
)
# Mail backend
-EMAIL_BACKEND_DOMAIN_WHITELIST = ''
-EMAIL_BACKEND_REDIRECT_ADDRESS = ''
+EMAIL_BACKEND_DOMAIN_WHITELIST = ""
+EMAIL_BACKEND_REDIRECT_ADDRESS = ""
-TIME_ZONE = 'UTC'
+TIME_ZONE = "UTC"
-LOCALE_PATHS = [str(BASE_PATH) + '/ambient_toolbox/locale']
+LOCALE_PATHS = [str(BASE_PATH) + "/ambient_toolbox/locale"]
diff --git a/testapp/api/serializers.py b/testapp/api/serializers.py
index 9e01499..7a18592 100644
--- a/testapp/api/serializers.py
+++ b/testapp/api/serializers.py
@@ -7,6 +7,6 @@ class MySingleSignalModelSerializer(serializers.ModelSerializer):
class Meta:
model = MySingleSignalModel
fields = [
- 'id',
- 'value',
+ "id",
+ "value",
]
diff --git a/testapp/api/urls.py b/testapp/api/urls.py
index 5d2a516..24c0724 100644
--- a/testapp/api/urls.py
+++ b/testapp/api/urls.py
@@ -3,4 +3,4 @@
from testapp.api.views import MySingleSignalModelViewSet
model_router = DefaultRouter()
-model_router.register(r'my-single-signal-model', MySingleSignalModelViewSet, basename='my-single-signal-model')
+model_router.register(r"my-single-signal-model", MySingleSignalModelViewSet, basename="my-single-signal-model")
diff --git a/testapp/forms.py b/testapp/forms.py
index 1d5eead..96ddefc 100644
--- a/testapp/forms.py
+++ b/testapp/forms.py
@@ -6,4 +6,4 @@
class CommonInfoBasedModelTestForm(forms.ModelForm):
class Meta:
model = CommonInfoBasedModel
- fields = ('value',)
+ fields = ("value",)
diff --git a/testapp/models.py b/testapp/models.py
index 36bc0ad..324a97a 100644
--- a/testapp/models.py
+++ b/testapp/models.py
@@ -22,7 +22,7 @@ def __str__(self):
class ForeignKeyRelatedModel(models.Model):
single_signal = models.ForeignKey(
- MySingleSignalModel, on_delete=models.CASCADE, related_name='foreign_key_related_models'
+ MySingleSignalModel, on_delete=models.CASCADE, related_name="foreign_key_related_models"
)
objects = GloballyVisibleQuerySet.as_manager()
@@ -43,7 +43,7 @@ def __str__(self):
return str(self.value)
-@receiver(pre_save, sender=MyMultipleSignalModel, dispatch_uid='test.mysinglesignalmodel.increase_value_with_uuid')
+@receiver(pre_save, sender=MyMultipleSignalModel, dispatch_uid="test.mysinglesignalmodel.increase_value_with_uuid")
def increase_value_with_dispatch_uid(sender, instance, **kwargs):
instance.value += 1
@@ -51,7 +51,7 @@ def increase_value_with_dispatch_uid(sender, instance, **kwargs):
@receiver(post_save, sender=MyMultipleSignalModel)
def send_email(sender, instance, **kwargs):
msg = EmailMultiAlternatives(
- 'Test Mail', 'I am content', from_email='test@example.com', to=['random.dude@example.com']
+ "Test Mail", "I am content", from_email="test@example.com", to=["random.dude@example.com"]
)
msg.send()
@@ -75,14 +75,14 @@ def __str__(self):
class ModelWithFkToSelf(models.Model):
- parent = models.ForeignKey('self', blank=True, null=True, related_name='children', on_delete=models.CASCADE)
+ parent = models.ForeignKey("self", blank=True, null=True, related_name="children", on_delete=models.CASCADE)
def __str__(self):
return str(self.id)
class ModelWithOneToOneToSelf(models.Model):
- peer = models.OneToOneField('self', blank=True, null=True, related_name='related_peer', on_delete=models.CASCADE)
+ peer = models.OneToOneField("self", blank=True, null=True, related_name="related_peer", on_delete=models.CASCADE)
def __str__(self):
return str(self.id)
diff --git a/testapp/permissions.py b/testapp/permissions.py
index e83147c..a465a20 100644
--- a/testapp/permissions.py
+++ b/testapp/permissions.py
@@ -2,11 +2,11 @@
class TestGroupDeclaration(GroupPermissionDeclaration):
- name = ('group_1',)
+ name = ("group_1",)
permission_list = [
PermissionModelDeclaration(
- app_label='testapp',
- codename_list=['view_mysinglesignalmodel'],
- model='mysinglesignalmodel',
+ app_label="testapp",
+ codename_list=["view_mysinglesignalmodel"],
+ model="mysinglesignalmodel",
),
]
diff --git a/testapp/urls.py b/testapp/urls.py
index b24d26b..ca9e2c7 100644
--- a/testapp/urls.py
+++ b/testapp/urls.py
@@ -10,9 +10,9 @@
urlpatterns = [
# django Admin
- path('admin/', admin.site.urls),
+ path("admin/", admin.site.urls),
# REST Viewsets
- path('api/v1/', include(router.urls)),
+ path("api/v1/", include(router.urls)),
# Custom login view
- path("other/login/", TemplateView.as_view(template_name="testapp/test_template.html"), name='other-login-view'),
+ path("other/login/", TemplateView.as_view(template_name="testapp/test_template.html"), name="other-login-view"),
]
diff --git a/tests/admin/model_admin_mixins/test_admin_common_info_mixin.py b/tests/admin/model_admin_mixins/test_admin_common_info_mixin.py
index c27585d..bc5dff9 100644
--- a/tests/admin/model_admin_mixins/test_admin_common_info_mixin.py
+++ b/tests/admin/model_admin_mixins/test_admin_common_info_mixin.py
@@ -13,7 +13,7 @@
class CommonInfoBasedModelForm(forms.ModelForm):
class Meta:
model = CommonInfoBasedModel
- fields = ('value',)
+ fields = ("value",)
class TestCommonInfoAdminMixinAdmin(CommonInfoAdminMixin, admin.ModelAdmin):
@@ -25,7 +25,7 @@ class CommonInfoAdminMixinTest(RequestProviderMixin, TestCase):
def setUpTestData(cls):
super().setUpTestData()
- cls.user = User.objects.create(username='my_user')
+ cls.user = User.objects.create(username="my_user")
cls.request = cls.get_request(cls.user)
admin.site.register(CommonInfoBasedModel, TestCommonInfoAdminMixinAdmin)
@@ -39,11 +39,11 @@ def tearDownClass(cls):
def test_readonly_fields_are_set(self):
model_admin = TestCommonInfoAdminMixinAdmin(model=CommonInfoBasedModel, admin_site=admin.site)
- self.assertIn('created_by', model_admin.get_readonly_fields(self.request))
- self.assertIn('created_at', model_admin.get_readonly_fields(self.request))
+ self.assertIn("created_by", model_admin.get_readonly_fields(self.request))
+ self.assertIn("created_at", model_admin.get_readonly_fields(self.request))
- self.assertIn('lastmodified_by', model_admin.get_readonly_fields(self.request))
- self.assertIn('lastmodified_at', model_admin.get_readonly_fields(self.request))
+ self.assertIn("lastmodified_by", model_admin.get_readonly_fields(self.request))
+ self.assertIn("lastmodified_at", model_admin.get_readonly_fields(self.request))
def test_get_user_obj_regular(self):
model_admin = TestCommonInfoAdminMixinAdmin(model=CommonInfoBasedModel, admin_site=admin.site)
@@ -61,8 +61,8 @@ def test_created_by_is_set_on_creation(self):
def test_created_by_is_not_altered_on_update(self):
model_admin = TestCommonInfoAdminMixinAdmin(model=CommonInfoBasedModel, admin_site=admin.site)
- other_user = User.objects.create(username='other_user')
- with mock.patch.object(CommonInfoBasedModel, 'get_current_user', return_value=other_user):
+ other_user = User.objects.create(username="other_user")
+ with mock.patch.object(CommonInfoBasedModel, "get_current_user", return_value=other_user):
obj = CommonInfoBasedModel.objects.create(value=1, created_by=other_user, lastmodified_by=other_user)
form = CommonInfoBasedModelForm(instance=obj)
diff --git a/tests/admin/model_admin_mixins/test_admin_create_form_mixin.py b/tests/admin/model_admin_mixins/test_admin_create_form_mixin.py
index 368262c..0c7a44b 100644
--- a/tests/admin/model_admin_mixins/test_admin_create_form_mixin.py
+++ b/tests/admin/model_admin_mixins/test_admin_create_form_mixin.py
@@ -22,7 +22,7 @@ class AdminCreateFormMixinTest(RequestProviderMixin, TestCase):
def setUpTestData(cls):
super().setUpTestData()
- cls.super_user = User.objects.create(username='super_user', is_superuser=True)
+ cls.super_user = User.objects.create(username="super_user", is_superuser=True)
admin.site.register(ForeignKeyRelatedModel, TestAdminCreateFormMixinAdmin)
diff --git a/tests/admin/model_admin_mixins/test_admin_no_inlines_for_create_mixin.py b/tests/admin/model_admin_mixins/test_admin_no_inlines_for_create_mixin.py
index a249ffa..0505441 100644
--- a/tests/admin/model_admin_mixins/test_admin_no_inlines_for_create_mixin.py
+++ b/tests/admin/model_admin_mixins/test_admin_no_inlines_for_create_mixin.py
@@ -20,7 +20,7 @@ class AdminNoInlinesForCreateMixinTest(RequestProviderMixin, TestCase):
def setUpTestData(cls):
super().setUpTestData()
- cls.super_user = User.objects.create(username='super_user', is_superuser=True)
+ cls.super_user = User.objects.create(username="super_user", is_superuser=True)
admin.site.register(MySingleSignalModel, TestAdminNoInlinesForCreateMixinAdmin)
diff --git a/tests/admin/model_admin_mixins/test_admin_request_in_form_mixin.py b/tests/admin/model_admin_mixins/test_admin_request_in_form_mixin.py
index 4a18390..15d76f1 100644
--- a/tests/admin/model_admin_mixins/test_admin_request_in_form_mixin.py
+++ b/tests/admin/model_admin_mixins/test_admin_request_in_form_mixin.py
@@ -17,7 +17,7 @@ class AdminRequestInFormMixinTest(RequestProviderMixin, TestCase):
def setUpTestData(cls):
super().setUpTestData()
- cls.super_user = User.objects.create(username='super_user', is_superuser=True)
+ cls.super_user = User.objects.create(username="super_user", is_superuser=True)
admin.site.register(MySingleSignalModel, TestAdminRequestInFormMixinAdmin)
diff --git a/tests/admin/model_admin_mixins/test_deactivatable_change_view_admin_mixin.py b/tests/admin/model_admin_mixins/test_deactivatable_change_view_admin_mixin.py
index 1cdc7bb..0095d1d 100644
--- a/tests/admin/model_admin_mixins/test_deactivatable_change_view_admin_mixin.py
+++ b/tests/admin/model_admin_mixins/test_deactivatable_change_view_admin_mixin.py
@@ -33,14 +33,14 @@ def test_can_see_change_view_negative_flag(self):
def test_get_list_display_links_can_see_method_called(self):
admin_cls = TestAdmin(admin_site=None, model=User)
- with mock.patch.object(admin_cls, 'can_see_change_view', return_value=True) as mock_method:
- admin_cls.get_list_display_links(request=self.get_request(user=self.user), list_display=('first_name',))
+ with mock.patch.object(admin_cls, "can_see_change_view", return_value=True) as mock_method:
+ admin_cls.get_list_display_links(request=self.get_request(user=self.user), list_display=("first_name",))
mock_method.assert_called_once()
def test_get_list_display_links_can_see_method_positive_flag(self):
admin_cls = TestAdmin(admin_site=None, model=User)
- field_tuple = ('first_name',)
+ field_tuple = ("first_name",)
self.assertEqual(
list(field_tuple),
admin_cls.get_list_display_links(request=self.get_request(user=self.user), list_display=field_tuple),
@@ -50,13 +50,13 @@ def test_get_list_display_links_can_see_method_negative_flag(self):
admin_cls = TestAdmin(admin_site=None, model=User)
admin_cls.enable_change_view = False
self.assertIsNone(
- admin_cls.get_list_display_links(request=self.get_request(user=self.user), list_display=('first_name',))
+ admin_cls.get_list_display_links(request=self.get_request(user=self.user), list_display=("first_name",))
)
def test_change_view_can_see_method_called_because_of_positive_flag(self):
admin_cls = TestAdmin(admin_site=None, model=User)
- with mock.patch.object(admin_cls, 'can_see_change_view', return_value=True) as mocked_can_see_method:
- with mock.patch('django.contrib.admin.ModelAdmin.change_view') as mocked_base_change_view:
+ with mock.patch.object(admin_cls, "can_see_change_view", return_value=True) as mocked_can_see_method:
+ with mock.patch("django.contrib.admin.ModelAdmin.change_view") as mocked_base_change_view:
admin_cls.change_view(request=self.get_request(user=self.super_user), object_id=str(self.user.id))
mocked_can_see_method.assert_called_once()
@@ -64,8 +64,8 @@ def test_change_view_can_see_method_called_because_of_positive_flag(self):
def test_change_view_can_see_method_not_called_because_of_negative_flag(self):
admin_cls = TestAdmin(admin_site=None, model=User)
- with mock.patch.object(admin_cls, 'can_see_change_view', return_value=False) as mocked_can_see_method:
- with mock.patch('django.contrib.admin.ModelAdmin.change_view') as mocked_base_change_view:
+ with mock.patch.object(admin_cls, "can_see_change_view", return_value=False) as mocked_can_see_method:
+ with mock.patch("django.contrib.admin.ModelAdmin.change_view") as mocked_base_change_view:
admin_cls.change_view(request=self.get_request(user=self.super_user), object_id=str(self.user.id))
mocked_can_see_method.assert_called_once()
diff --git a/tests/admin/model_admin_mixins/test_fetch_object_mixin.py b/tests/admin/model_admin_mixins/test_fetch_object_mixin.py
index 8d19756..2b919cc 100644
--- a/tests/admin/model_admin_mixins/test_fetch_object_mixin.py
+++ b/tests/admin/model_admin_mixins/test_fetch_object_mixin.py
@@ -22,7 +22,7 @@ class FetchObjectMixinTest(RequestProviderMixin, TestCase):
def setUpTestData(cls):
super().setUpTestData()
- cls.super_user = User.objects.create(username='super_user', is_superuser=True)
+ cls.super_user = User.objects.create(username="super_user", is_superuser=True)
admin.site.register(MySingleSignalModel, TestFetchObjectMixinAdmin)
@@ -39,8 +39,8 @@ def test_model_is_set(self):
request = self.get_request(self.super_user)
return_obj = MockResolverResponse()
- return_obj.kwargs = {'object_id': obj.id}
- with mock.patch('ambient_toolbox.admin.model_admins.mixins.resolve', return_value=return_obj):
+ return_obj.kwargs = {"object_id": obj.id}
+ with mock.patch("ambient_toolbox.admin.model_admins.mixins.resolve", return_value=return_obj):
obj_from_request = model_admin.get_object_from_request(request)
self.assertEqual(obj_from_request, obj)
diff --git a/tests/admin/model_admin_mixins/test_fetch_parent_object_inline_mixin.py b/tests/admin/model_admin_mixins/test_fetch_parent_object_inline_mixin.py
index d13cef6..610881a 100644
--- a/tests/admin/model_admin_mixins/test_fetch_parent_object_inline_mixin.py
+++ b/tests/admin/model_admin_mixins/test_fetch_parent_object_inline_mixin.py
@@ -26,7 +26,7 @@ class FetchParentObjectInlineMixinTest(RequestProviderMixin, TestCase):
def setUpTestData(cls):
super().setUpTestData()
- cls.super_user = User.objects.create(username='super_user', is_superuser=True)
+ cls.super_user = User.objects.create(username="super_user", is_superuser=True)
admin.site.register(MySingleSignalModel, TestFetchParentObjectInlineMixinAdmin)
@@ -48,8 +48,8 @@ def test_parent_model_is_set(self):
inline = inline_list[0](parent_model=MySingleSignalModel, admin_site=admin.site)
return_obj = MockResolverResponse()
- return_obj.kwargs = {'object_id': obj.id}
- with mock.patch.object(model_admin.inlines[0], '_resolve_url', return_value=return_obj):
+ return_obj.kwargs = {"object_id": obj.id}
+ with mock.patch.object(model_admin.inlines[0], "_resolve_url", return_value=return_obj):
inline.get_formset(request=request, obj=obj)
self.assertEqual(inline.parent_object, obj)
diff --git a/tests/ambient_toolbox/test_test_structure_validator.py b/tests/ambient_toolbox/test_test_structure_validator.py
index 9444093..1cfcf79 100644
--- a/tests/ambient_toolbox/test_test_structure_validator.py
+++ b/tests/ambient_toolbox/test_test_structure_validator.py
@@ -11,21 +11,21 @@ class TestStructureValidatorTest(TestCase):
def test_init_regular(self):
service = TestStructureValidator()
- self.assertEqual(service.file_whitelist, ['__init__'])
+ self.assertEqual(service.file_whitelist, ["__init__"])
self.assertEqual(service.issue_list, [])
- @override_settings(TEST_STRUCTURE_VALIDATOR_FILE_WHITELIST=['my_file'])
+ @override_settings(TEST_STRUCTURE_VALIDATOR_FILE_WHITELIST=["my_file"])
def test_get_file_whitelist_from_settings(self):
service = TestStructureValidator()
file_whitelist = service._get_file_whitelist()
- self.assertEqual(file_whitelist, ['__init__', 'my_file'])
+ self.assertEqual(file_whitelist, ["__init__", "my_file"])
def test_get_file_whitelist_fallback(self):
service = TestStructureValidator()
file_whitelist = service._get_file_whitelist()
- self.assertEqual(file_whitelist, ['__init__'])
+ self.assertEqual(file_whitelist, ["__init__"])
@override_settings(TEST_STRUCTURE_VALIDATOR_BASE_DIR=settings.BASE_PATH)
def test_get_base_dir_from_settings(self):
@@ -38,27 +38,27 @@ def test_get_base_dir_fallback(self):
service = TestStructureValidator()
base_dir = service._get_base_dir()
- self.assertEqual(base_dir, '')
+ self.assertEqual(base_dir, "")
- @override_settings(TEST_STRUCTURE_VALIDATOR_BASE_APP_NAME='my_project')
+ @override_settings(TEST_STRUCTURE_VALIDATOR_BASE_APP_NAME="my_project")
def test_get_base_app_name_from_settings(self):
service = TestStructureValidator()
base_app_name = service._get_base_app_name()
- self.assertEqual(base_app_name, 'my_project')
+ self.assertEqual(base_app_name, "my_project")
def test_get_base_app_name_fallback(self):
service = TestStructureValidator()
base_app_name = service._get_base_app_name()
- self.assertEqual(base_app_name, 'apps')
+ self.assertEqual(base_app_name, "apps")
- @override_settings(TEST_STRUCTURE_VALIDATOR_APP_LIST=['apps.my_app', 'apps.other_app'])
+ @override_settings(TEST_STRUCTURE_VALIDATOR_APP_LIST=["apps.my_app", "apps.other_app"])
def test_get_app_list_from_settings(self):
service = TestStructureValidator()
base_app_name = service._get_app_list()
- self.assertEqual(base_app_name, ['apps.my_app', 'apps.other_app'])
+ self.assertEqual(base_app_name, ["apps.my_app", "apps.other_app"])
def test_get_app_list_fallback(self):
service = TestStructureValidator()
@@ -66,39 +66,39 @@ def test_get_app_list_fallback(self):
self.assertEqual(base_app_name, settings.INSTALLED_APPS)
- @override_settings(TEST_STRUCTURE_VALIDATOR_IGNORED_DIRECTORY_LIST=['my_dir', 'other_dir'])
+ @override_settings(TEST_STRUCTURE_VALIDATOR_IGNORED_DIRECTORY_LIST=["my_dir", "other_dir"])
def test_get_ignored_directory_list_from_settings(self):
service = TestStructureValidator()
dir_list = service._get_ignored_directory_list()
- self.assertEqual(dir_list, ['__pycache__', 'my_dir', 'other_dir'])
+ self.assertEqual(dir_list, ["__pycache__", "my_dir", "other_dir"])
def test_get_ignored_directory_list_fallback(self):
service = TestStructureValidator()
dir_list = service._get_ignored_directory_list()
- self.assertEqual(dir_list, ['__pycache__'])
+ self.assertEqual(dir_list, ["__pycache__"])
def test_check_missing_test_prefix_correct_prefix(self):
service = TestStructureValidator()
result = service._check_missing_test_prefix(
- root='root/path',
- file='missing_prefix',
- filename='test_my_file',
- extension='.py',
+ root="root/path",
+ file="missing_prefix",
+ filename="test_my_file",
+ extension=".py",
)
self.assertTrue(result)
self.assertEqual(len(service.issue_list), 0)
- @override_settings(TEST_STRUCTURE_VALIDATOR_FILE_WHITELIST=['my_file'])
+ @override_settings(TEST_STRUCTURE_VALIDATOR_FILE_WHITELIST=["my_file"])
def test_check_missing_test_prefix_wrong_prefix_but_whitelisted(self):
service = TestStructureValidator()
result = service._check_missing_test_prefix(
- root='root/path',
- file='missing_prefix',
- filename='my_file',
- extension='.py',
+ root="root/path",
+ file="missing_prefix",
+ filename="my_file",
+ extension=".py",
)
self.assertTrue(result)
@@ -107,10 +107,10 @@ def test_check_missing_test_prefix_wrong_prefix_but_whitelisted(self):
def test_check_missing_test_prefix_wrong_prefix_but_not_py_file(self):
service = TestStructureValidator()
result = service._check_missing_test_prefix(
- root='root/path',
- file='missing_prefix',
- filename='missing_prefix',
- extension='.txt',
+ root="root/path",
+ file="missing_prefix",
+ filename="missing_prefix",
+ extension=".txt",
)
self.assertTrue(result)
@@ -119,10 +119,10 @@ def test_check_missing_test_prefix_wrong_prefix_but_not_py_file(self):
def test_check_missing_test_prefix_wrong_prefix(self):
service = TestStructureValidator()
result = service._check_missing_test_prefix(
- root='root/path',
- file='missing_prefix',
- filename='missing_prefix',
- extension='.py',
+ root="root/path",
+ file="missing_prefix",
+ filename="missing_prefix",
+ extension=".py",
)
self.assertFalse(result)
@@ -130,54 +130,54 @@ def test_check_missing_test_prefix_wrong_prefix(self):
def test_check_missing_init_init_found_files_in_dir(self):
service = TestStructureValidator()
- result = service._check_missing_init(root='root/path', init_found=True, number_of_py_files=1)
+ result = service._check_missing_init(root="root/path", init_found=True, number_of_py_files=1)
self.assertTrue(result)
self.assertEqual(len(service.issue_list), 0)
def test_check_missing_init_no_init_no_files(self):
service = TestStructureValidator()
- result = service._check_missing_init(root='root/path', init_found=False, number_of_py_files=0)
+ result = service._check_missing_init(root="root/path", init_found=False, number_of_py_files=0)
self.assertTrue(result)
self.assertEqual(len(service.issue_list), 0)
def test_check_missing_init_no_init_but_files(self):
service = TestStructureValidator()
- result = service._check_missing_init(root='root/path', init_found=False, number_of_py_files=1)
+ result = service._check_missing_init(root="root/path", init_found=False, number_of_py_files=1)
self.assertFalse(result)
self.assertEqual(len(service.issue_list), 1)
@override_settings(
- TEST_STRUCTURE_VALIDATOR_BASE_DIR=Path('/src/ambient_toolbox/'),
- TEST_STRUCTURE_VALIDATOR_BASE_APP_NAME='my_project',
+ TEST_STRUCTURE_VALIDATOR_BASE_DIR=Path("/src/ambient_toolbox/"),
+ TEST_STRUCTURE_VALIDATOR_BASE_APP_NAME="my_project",
)
def test_build_path_to_test_package_with_settings_path(self):
service = TestStructureValidator()
- path = service._build_path_to_test_package(app='my_project.my_app')
+ path = service._build_path_to_test_package(app="my_project.my_app")
- self.assertEqual(path, Path('/src/ambient_toolbox/my_project/my_app/tests'))
+ self.assertEqual(path, Path("/src/ambient_toolbox/my_project/my_app/tests"))
@override_settings(
- TEST_STRUCTURE_VALIDATOR_BASE_DIR='/src/ambient_toolbox/', TEST_STRUCTURE_VALIDATOR_BASE_APP_NAME='my_project'
+ TEST_STRUCTURE_VALIDATOR_BASE_DIR="/src/ambient_toolbox/", TEST_STRUCTURE_VALIDATOR_BASE_APP_NAME="my_project"
)
def test_build_path_to_test_package_with_settings_str(self):
service = TestStructureValidator()
- path = service._build_path_to_test_package(app='my_project.my_app')
+ path = service._build_path_to_test_package(app="my_project.my_app")
- self.assertEqual(path, Path('/src/ambient_toolbox/my_project/my_app/tests'))
+ self.assertEqual(path, Path("/src/ambient_toolbox/my_project/my_app/tests"))
def test_build_path_to_test_package_with_defaults(self):
service = TestStructureValidator()
- path = service._build_path_to_test_package(app='my_project.my_app')
+ path = service._build_path_to_test_package(app="my_project.my_app")
- self.assertEqual(path, Path('my_project/my_app/tests'))
+ self.assertEqual(path, Path("my_project/my_app/tests"))
@override_settings(
TEST_STRUCTURE_VALIDATOR_BASE_DIR=settings.BASE_PATH,
- TEST_STRUCTURE_VALIDATOR_APP_LIST=['testapp'],
- TEST_STRUCTURE_VALIDATOR_BASE_APP_NAME='',
+ TEST_STRUCTURE_VALIDATOR_APP_LIST=["testapp"],
+ TEST_STRUCTURE_VALIDATOR_BASE_APP_NAME="",
)
def test_process_functional(self):
service = TestStructureValidator()
@@ -189,12 +189,12 @@ def test_process_functional(self):
complaint_list = sorted(service.issue_list)
self.assertIn('Python file without "test_" prefix found:', complaint_list[0])
- self.assertIn('testapp/tests/subdirectory/missing_test_prefix.py', complaint_list[0])
+ self.assertIn("testapp/tests/subdirectory/missing_test_prefix.py", complaint_list[0])
- self.assertIn('__init__.py missing in', complaint_list[1])
- self.assertIn('testapp/tests/missing_init', complaint_list[1])
+ self.assertIn("__init__.py missing in", complaint_list[1])
+ self.assertIn("testapp/tests/missing_init", complaint_list[1])
- @mock.patch.object(TestStructureValidator, "_get_app_list", return_value=['invalidly_located_app'])
+ @mock.patch.object(TestStructureValidator, "_get_app_list", return_value=["invalidly_located_app"])
def test_process_invalidly_located_app(self, mocked_get_app_list):
service = TestStructureValidator()
diff --git a/tests/drf/test_fields.py b/tests/drf/test_fields.py
index 7a9f54e..83e4742 100644
--- a/tests/drf/test_fields.py
+++ b/tests/drf/test_fields.py
@@ -15,8 +15,8 @@ class TestManyTrueSerializer(serializers.ModelSerializer):
class Meta:
model = ModelWithFkToSelf
fields = [
- 'id',
- 'children',
+ "id",
+ "children",
]
@@ -27,8 +27,8 @@ class TestManyFalseSerializer(serializers.ModelSerializer):
class Meta:
model = ModelWithOneToOneToSelf
fields = [
- 'id',
- 'peer',
+ "id",
+ "peer",
]
@@ -50,9 +50,9 @@ def test_create_super_called(self, mocked_create):
def test_many_true_regular(self):
serializer = TestManyTrueSerializer()
- self.assertIn('children', serializer.fields)
- self.assertIsInstance(serializer.fields['children'], ListSerializer)
- self.assertIsInstance(serializer.fields['children'].child, RecursiveField)
+ self.assertIn("children", serializer.fields)
+ self.assertIsInstance(serializer.fields["children"], ListSerializer)
+ self.assertIsInstance(serializer.fields["children"].child, RecursiveField)
def test_many_true_representation(self):
mwfts_1 = ModelWithFkToSelf.objects.create(parent=None)
@@ -62,16 +62,16 @@ def test_many_true_representation(self):
representation = serializer.to_representation(instance=mwfts_1)
self.assertIsInstance(representation, dict)
- self.assertIn('children', representation)
- self.assertEqual(len(representation['children']), 1)
- self.assertEqual(representation['children'][0]['id'], mwfts_2.id)
- self.assertEqual(representation['children'][0]['children'], [])
+ self.assertIn("children", representation)
+ self.assertEqual(len(representation["children"]), 1)
+ self.assertEqual(representation["children"][0]["id"], mwfts_2.id)
+ self.assertEqual(representation["children"][0]["children"], [])
def test_many_false_regular(self):
serializer = TestManyFalseSerializer()
- self.assertIn('peer', serializer.fields)
- self.assertIsInstance(serializer.fields['peer'], RecursiveField)
+ self.assertIn("peer", serializer.fields)
+ self.assertIsInstance(serializer.fields["peer"], RecursiveField)
def test_many_false_representation(self):
mwotos_no_peer = ModelWithOneToOneToSelf.objects.create(peer=None)
@@ -81,7 +81,7 @@ def test_many_false_representation(self):
representation = serializer.to_representation(instance=mwotos_has_peer)
self.assertIsInstance(representation, dict)
- self.assertIn('peer', representation)
- self.assertEqual(len(representation['peer']), 2)
- self.assertEqual(representation['peer']['id'], mwotos_no_peer.id)
- self.assertEqual(representation['peer']['peer'], None)
+ self.assertIn("peer", representation)
+ self.assertEqual(len(representation["peer"]), 2)
+ self.assertEqual(representation["peer"]["id"], mwotos_no_peer.id)
+ self.assertEqual(representation["peer"]["peer"], None)
diff --git a/tests/mixins/test_validation.py b/tests/mixins/test_validation.py
index c873940..212296c 100644
--- a/tests/mixins/test_validation.py
+++ b/tests/mixins/test_validation.py
@@ -12,7 +12,7 @@ def test_clean_regular(self):
def test_clean_is_called(self):
obj = ModelWithCleanMixin()
- with mock.patch.object(obj, 'clean') as mocked_method:
+ with mock.patch.object(obj, "clean") as mocked_method:
obj.save()
mocked_method.assert_called_once()
diff --git a/tests/permissions/fixtures/test_declarations.py b/tests/permissions/fixtures/test_declarations.py
index 840d937..f76eda8 100644
--- a/tests/permissions/fixtures/test_declarations.py
+++ b/tests/permissions/fixtures/test_declarations.py
@@ -6,25 +6,25 @@
class PermissionFixtureDeclarationTest(TestCase):
def test_permission_model_declaration_regular(self):
permission = PermissionModelDeclaration(
- app_label='my_app',
- codename_list=['view_mymodel'],
- model='mymodel',
+ app_label="my_app",
+ codename_list=["view_mymodel"],
+ model="mymodel",
)
- self.assertEqual(permission.app_label, 'my_app')
- self.assertEqual(permission.codename_list, ['view_mymodel'])
- self.assertEqual(permission.model, 'mymodel')
+ self.assertEqual(permission.app_label, "my_app")
+ self.assertEqual(permission.codename_list, ["view_mymodel"])
+ self.assertEqual(permission.model, "mymodel")
def test_group_permission_declaration_regular(self):
permission = PermissionModelDeclaration(
- app_label='my_app',
- codename_list=['view_mymodel'],
- model='mymodel',
+ app_label="my_app",
+ codename_list=["view_mymodel"],
+ model="mymodel",
)
group = GroupPermissionDeclaration(
- name='my_group',
+ name="my_group",
permission_list=[permission],
)
- self.assertEqual(group.name, 'my_group')
+ self.assertEqual(group.name, "my_group")
self.assertEqual(group.permission_list, [permission])
diff --git a/tests/permissions/fixtures/test_helpers.py b/tests/permissions/fixtures/test_helpers.py
index 1f3f441..e738ca8 100644
--- a/tests/permissions/fixtures/test_helpers.py
+++ b/tests/permissions/fixtures/test_helpers.py
@@ -5,10 +5,10 @@
class PermissionFixtureHelperTest(TestCase):
def test_generate_default_permissions_regular(self):
- permission_list = generate_default_permissions('mymodel')
+ permission_list = generate_default_permissions("mymodel")
self.assertEqual(len(permission_list), 4)
- self.assertIn('add_mymodel', permission_list)
- self.assertIn('change_mymodel', permission_list)
- self.assertIn('delete_mymodel', permission_list)
- self.assertIn('view_mymodel', permission_list)
+ self.assertIn("add_mymodel", permission_list)
+ self.assertIn("change_mymodel", permission_list)
+ self.assertIn("delete_mymodel", permission_list)
+ self.assertIn("view_mymodel", permission_list)
diff --git a/tests/permissions/fixtures/test_services_setup_service.py b/tests/permissions/fixtures/test_services_setup_service.py
index a78d80d..47cc81a 100644
--- a/tests/permissions/fixtures/test_services_setup_service.py
+++ b/tests/permissions/fixtures/test_services_setup_service.py
@@ -10,17 +10,17 @@ class PermissionSetupServiceTest(TestCase):
def setUpTestData(cls):
super().setUpTestData()
- cls.group, created = Group.objects.get_or_create(name='my_group')
+ cls.group, created = Group.objects.get_or_create(name="my_group")
cls.permission_view = Permission.objects.get_by_natural_key(
- app_label='testapp', codename='view_mysinglesignalmodel', model='mysinglesignalmodel'
+ app_label="testapp", codename="view_mysinglesignalmodel", model="mysinglesignalmodel"
)
cls.permission_change = Permission.objects.get_by_natural_key(
- app_label='testapp', codename='change_mysinglesignalmodel', model='mysinglesignalmodel'
+ app_label="testapp", codename="change_mysinglesignalmodel", model="mysinglesignalmodel"
)
def test_init_regular(self):
- group_declaration = GroupPermissionDeclaration(name='my_group', permission_list=[])
+ group_declaration = GroupPermissionDeclaration(name="my_group", permission_list=[])
service = PermissionSetupService(group_declaration=group_declaration)
self.assertEqual(service.group_declaration, group_declaration)
@@ -28,10 +28,10 @@ def test_init_regular(self):
def test_process_add_permission(self):
group_declaration = GroupPermissionDeclaration(
- name='my_group',
+ name="my_group",
permission_list=[
PermissionModelDeclaration(
- app_label='testapp', codename_list=['change_mysinglesignalmodel'], model='mysinglesignalmodel'
+ app_label="testapp", codename_list=["change_mysinglesignalmodel"], model="mysinglesignalmodel"
)
],
)
@@ -49,7 +49,7 @@ def test_process_add_permission(self):
def test_process_remove_permission(self):
self.group.permissions.add(self.permission_view)
- group_declaration = GroupPermissionDeclaration(name='my_group', permission_list=[])
+ group_declaration = GroupPermissionDeclaration(name="my_group", permission_list=[])
service = PermissionSetupService(group_declaration=group_declaration)
new_permissions, removed_permissions = service.process()
@@ -64,10 +64,10 @@ def test_process_no_changes_permission(self):
self.group.permissions.add(self.permission_view)
group_declaration = GroupPermissionDeclaration(
- name='my_group',
+ name="my_group",
permission_list=[
PermissionModelDeclaration(
- app_label='testapp', codename_list=['view_mysinglesignalmodel'], model='mysinglesignalmodel'
+ app_label="testapp", codename_list=["view_mysinglesignalmodel"], model="mysinglesignalmodel"
)
],
)
@@ -86,10 +86,10 @@ def test_process_invalid_permission(self):
self.group.permissions.add(self.permission_view)
group_declaration = GroupPermissionDeclaration(
- name='my_group',
+ name="my_group",
permission_list=[
PermissionModelDeclaration(
- app_label='testapp', codename_list=['invalid_permission'], model='mysinglesignalmodel'
+ app_label="testapp", codename_list=["invalid_permission"], model="mysinglesignalmodel"
)
],
)
@@ -104,10 +104,10 @@ def test_process_invalid_app(self):
self.group.permissions.add(self.permission_view)
group_declaration = GroupPermissionDeclaration(
- name='my_group',
+ name="my_group",
permission_list=[
PermissionModelDeclaration(
- app_label='invalid_app', codename_list=['view_mysinglesignalmodel'], model='mysinglesignalmodel'
+ app_label="invalid_app", codename_list=["view_mysinglesignalmodel"], model="mysinglesignalmodel"
)
],
)
@@ -120,10 +120,10 @@ def test_process_invalid_model(self):
self.group.permissions.add(self.permission_view)
group_declaration = GroupPermissionDeclaration(
- name='my_group',
+ name="my_group",
permission_list=[
PermissionModelDeclaration(
- app_label='testapp', codename_list=['view_mysinglesignalmodel'], model='invalid_model'
+ app_label="testapp", codename_list=["view_mysinglesignalmodel"], model="invalid_model"
)
],
)
@@ -136,29 +136,29 @@ def test_process_duplicated_permission_declaration(self):
self.group.permissions.add(self.permission_view)
group_declaration = GroupPermissionDeclaration(
- name='my_group',
+ name="my_group",
permission_list=[
PermissionModelDeclaration(
- app_label='testapp', codename_list=['view_mysinglesignalmodel'], model='mysinglesignalmodel'
+ app_label="testapp", codename_list=["view_mysinglesignalmodel"], model="mysinglesignalmodel"
),
PermissionModelDeclaration(
- app_label='testapp', codename_list=['view_mysinglesignalmodel'], model='mysinglesignalmodel'
+ app_label="testapp", codename_list=["view_mysinglesignalmodel"], model="mysinglesignalmodel"
),
],
)
service = PermissionSetupService(group_declaration=group_declaration)
- with self.assertRaisesMessage(ValueError, f'Permission {self.permission_view} declared twice.'):
+ with self.assertRaisesMessage(ValueError, f"Permission {self.permission_view} declared twice."):
service.process()
def test_process_dry_run_not_persisting(self):
self.group.permissions.add(self.permission_view)
group_declaration = GroupPermissionDeclaration(
- name='my_group',
+ name="my_group",
permission_list=[
PermissionModelDeclaration(
- app_label='testapp', codename_list=['change_mysinglesignalmodel'], model='mysinglesignalmodel'
+ app_label="testapp", codename_list=["change_mysinglesignalmodel"], model="mysinglesignalmodel"
)
],
)
diff --git a/tests/permissions/test_install_permission_fixtures_command.py b/tests/permissions/test_install_permission_fixtures_command.py
index 9cb2074..36d8832 100644
--- a/tests/permissions/test_install_permission_fixtures_command.py
+++ b/tests/permissions/test_install_permission_fixtures_command.py
@@ -22,22 +22,22 @@ def test_add_arguments_regular(self):
self.assertTrue("--dry-run" in [action.option_strings[0] for action in parser._actions])
- @override_settings(GROUP_PERMISSION_FIXTURES=['testapp.permissions.TestGroupDeclaration'])
- @mock.patch.object(PermissionSetupService, 'process', return_value=([], []))
+ @override_settings(GROUP_PERMISSION_FIXTURES=["testapp.permissions.TestGroupDeclaration"])
+ @mock.patch.object(PermissionSetupService, "process", return_value=([], []))
def test_run_command_regular(self, mocked_process):
command = Command()
command.handle()
mocked_process.assert_called_once()
- @mock.patch.object(PermissionSetupService, 'process')
+ @mock.patch.object(PermissionSetupService, "process")
def test_run_command_no_settings_variable(self, mocked_process):
command = Command()
command.handle()
mocked_process.assert_not_called()
- @mock.patch.object(PermissionSetupService, 'process')
+ @mock.patch.object(PermissionSetupService, "process")
def test_run_command_dry_run(self, mocked_process):
command = Command()
command.handle(dry_run=True)
diff --git a/tests/sentry/mock_data.py b/tests/sentry/mock_data.py
index 2e1a845..05121b9 100644
--- a/tests/sentry/mock_data.py
+++ b/tests/sentry/mock_data.py
@@ -1,136 +1,136 @@
SENTRY_EVENT = {
- 'level': 'error',
- 'exception': {
- 'values': [
+ "level": "error",
+ "exception": {
+ "values": [
{
- 'module': None,
- 'type': 'ZeroDivisionError',
- 'value': 'division by zero',
- 'mechanism': {'type': 'django', 'handled': False},
- 'stacktrace': {
- 'frames': [
+ "module": None,
+ "type": "ZeroDivisionError",
+ "value": "division by zero",
+ "mechanism": {"type": "django", "handled": False},
+ "stacktrace": {
+ "frames": [
{
- 'filename': 'test/account/api/views.py',
- 'abs_path': '/opt/project/backend/test/account/api/views.py',
- 'function': 'perform_update',
- 'module': 'test.account.api.views',
- 'lineno': 123,
- 'pre_context': ['test = 1/0'],
- 'vars': {
- 'self': '',
- 'serializer': 'TestDetailSerializer()',
- '__class__': "",
- 'admin': '',
- 'test_data': '123',
+ "filename": "test/account/api/views.py",
+ "abs_path": "/opt/project/backend/test/account/api/views.py",
+ "function": "perform_update",
+ "module": "test.account.api.views",
+ "lineno": 123,
+ "pre_context": ["test = 1/0"],
+ "vars": {
+ "self": "",
+ "serializer": "TestDetailSerializer()",
+ "__class__": "",
+ "admin": "",
+ "test_data": "123",
},
- 'in_app': True,
+ "in_app": True,
}
]
},
}
]
},
- 'request': {
- 'url': 'http://localhost:8000/api/v2/test/17/',
- 'query_string': '',
- 'method': 'PUT',
- 'env': {'SERVER_NAME': 'cdc3cb5b00af', 'SERVER_PORT': '8000', 'REMOTE_ADDR': '172.22.0.1'},
- 'headers': {
- 'Content-Length': '1202',
- 'Content-Type': 'application/json',
- 'Host': 'localhost:8000',
- 'User-Agent': 'Mozilla/5.0 (Macintosh;) Gecko/20100101 Firefox/112.0',
- 'Accept': 'application/json, text/plain, */*',
- 'Accept-Language': 'en',
- 'Accept-Encoding': 'gzip, deflate, br',
- 'Authorization': 'Token 123123123123123123123123123123123123abcd',
- 'Origin': 'http://127.0.0.1:3000',
- 'Dnt': '1',
- 'Connection': 'keep-alive',
- 'Referer': 'http://127.0.0.1:3000/',
- 'Sec-Fetch-Dest': 'empty',
- 'Sec-Fetch-Mode': 'cors',
- 'Sec-Fetch-Site': 'cross-site',
+ "request": {
+ "url": "http://localhost:8000/api/v2/test/17/",
+ "query_string": "",
+ "method": "PUT",
+ "env": {"SERVER_NAME": "cdc3cb5b00af", "SERVER_PORT": "8000", "REMOTE_ADDR": "172.22.0.1"},
+ "headers": {
+ "Content-Length": "1202",
+ "Content-Type": "application/json",
+ "Host": "localhost:8000",
+ "User-Agent": "Mozilla/5.0 (Macintosh;) Gecko/20100101 Firefox/112.0",
+ "Accept": "application/json, text/plain, */*",
+ "Accept-Language": "en",
+ "Accept-Encoding": "gzip, deflate, br",
+ "Authorization": "Token 123123123123123123123123123123123123abcd",
+ "Origin": "http://127.0.0.1:3000",
+ "Dnt": "1",
+ "Connection": "keep-alive",
+ "Referer": "http://127.0.0.1:3000/",
+ "Sec-Fetch-Dest": "empty",
+ "Sec-Fetch-Mode": "cors",
+ "Sec-Fetch-Site": "cross-site",
},
- 'cookies': {},
- 'data': '',
+ "cookies": {},
+ "data": "",
},
- 'user': {'email': 'test@test.local', 'id': '1337', 'ip_address': '172.22.0.1', 'username': 'test@test.local'},
+ "user": {"email": "test@test.local", "id": "1337", "ip_address": "172.22.0.1", "username": "test@test.local"},
}
SCRUBBED_SENTRY_EVENT = {
- 'level': 'error',
- 'exception': {
- 'values': [
+ "level": "error",
+ "exception": {
+ "values": [
{
- 'module': None,
- 'type': 'ZeroDivisionError',
- 'value': 'division by zero',
- 'mechanism': {'type': 'django', 'handled': False},
- 'stacktrace': {
- 'frames': [
+ "module": None,
+ "type": "ZeroDivisionError",
+ "value": "division by zero",
+ "mechanism": {"type": "django", "handled": False},
+ "stacktrace": {
+ "frames": [
{
- 'filename': 'test/account/api/views.py',
- 'abs_path': '/opt/project/backend/test/account/api/views.py',
- 'function': 'perform_update',
- 'module': 'test.account.api.views',
- 'lineno': 123,
- 'pre_context': ['test = 1/0'],
- 'vars': {
- 'self': "''",
- 'serializer': '[Filtered]', # filtered due to standard filter
- '__class__': '""',
- 'admin': '[Filtered]', # filtered due to standard filter
- 'test_data': "'123'",
+ "filename": "test/account/api/views.py",
+ "abs_path": "/opt/project/backend/test/account/api/views.py",
+ "function": "perform_update",
+ "module": "test.account.api.views",
+ "lineno": 123,
+ "pre_context": ["test = 1/0"],
+ "vars": {
+ "self": "''",
+ "serializer": "[Filtered]", # filtered due to standard filter
+ "__class__": "\"\"",
+ "admin": "[Filtered]", # filtered due to standard filter
+ "test_data": "'123'",
},
- 'in_app': True,
+ "in_app": True,
}
]
},
}
]
},
- 'request': {
- 'url': 'http://localhost:8000/api/v2/test/17/',
- 'query_string': '',
- 'method': 'PUT',
- 'env': {'SERVER_NAME': 'cdc3cb5b00af', 'SERVER_PORT': '8000', 'REMOTE_ADDR': '172.22.0.1'},
- 'headers': {
- 'Content-Length': '1202',
- 'Content-Type': 'application/json',
- 'Host': 'localhost:8000',
- 'User-Agent': 'Mozilla/5.0 (Macintosh;) Gecko/20100101 Firefox/112.0',
- 'Accept': 'application/json, text/plain, */*',
- 'Accept-Language': 'en',
- 'Accept-Encoding': 'gzip, deflate, br',
- 'Authorization': '[Filtered]', # filtered due to default sentry filter
- 'Origin': 'http://127.0.0.1:3000',
- 'Dnt': '1',
- 'Connection': 'keep-alive',
- 'Referer': 'http://127.0.0.1:3000/',
- 'Sec-Fetch-Dest': 'empty',
- 'Sec-Fetch-Mode': 'cors',
- 'Sec-Fetch-Site': 'cross-site',
+ "request": {
+ "url": "http://localhost:8000/api/v2/test/17/",
+ "query_string": "",
+ "method": "PUT",
+ "env": {"SERVER_NAME": "cdc3cb5b00af", "SERVER_PORT": "8000", "REMOTE_ADDR": "172.22.0.1"},
+ "headers": {
+ "Content-Length": "1202",
+ "Content-Type": "application/json",
+ "Host": "localhost:8000",
+ "User-Agent": "Mozilla/5.0 (Macintosh;) Gecko/20100101 Firefox/112.0",
+ "Accept": "application/json, text/plain, */*",
+ "Accept-Language": "en",
+ "Accept-Encoding": "gzip, deflate, br",
+ "Authorization": "[Filtered]", # filtered due to default sentry filter
+ "Origin": "http://127.0.0.1:3000",
+ "Dnt": "1",
+ "Connection": "keep-alive",
+ "Referer": "http://127.0.0.1:3000/",
+ "Sec-Fetch-Dest": "empty",
+ "Sec-Fetch-Mode": "cors",
+ "Sec-Fetch-Site": "cross-site",
},
- 'cookies': {},
- 'data': '',
+ "cookies": {},
+ "data": "",
},
- 'user': {
- 'email': '[Filtered]', # filtered due to default sentry filter
- 'id': '1337',
- 'ip_address': '[Filtered]', # filtered due to default sentry filter
- 'username': '[Filtered]', # filtered due to default sentry filter
+ "user": {
+ "email": "[Filtered]", # filtered due to default sentry filter
+ "id": "1337",
+ "ip_address": "[Filtered]", # filtered due to default sentry filter
+ "username": "[Filtered]", # filtered due to default sentry filter
},
- '_meta': {
- 'exception': {
- 'values': {
- '0': {
- 'stacktrace': {
- 'frames': {
- '0': {
- 'vars': {
- 'serializer': {'': {'rem': [['!config', 's']]}},
- 'admin': {'': {'rem': [['!config', 's']]}},
+ "_meta": {
+ "exception": {
+ "values": {
+ "0": {
+ "stacktrace": {
+ "frames": {
+ "0": {
+ "vars": {
+ "serializer": {"": {"rem": [["!config", "s"]]}},
+ "admin": {"": {"rem": [["!config", "s"]]}},
}
}
}
@@ -138,11 +138,11 @@
}
}
},
- 'request': {'headers': {'Authorization': {'': {'rem': [['!config', 's']]}}}},
- 'user': {
- 'email': {'': {'rem': [['!config', 's']]}},
- 'ip_address': {'': {'rem': [['!config', 's']]}},
- 'username': {'': {'rem': [['!config', 's']]}},
+ "request": {"headers": {"Authorization": {"": {"rem": [["!config", "s"]]}}}},
+ "user": {
+ "email": {"": {"rem": [["!config", "s"]]}},
+ "ip_address": {"": {"rem": [["!config", "s"]]}},
+ "username": {"": {"rem": [["!config", "s"]]}},
},
},
}
diff --git a/tests/sentry/test_sentry_helper.py b/tests/sentry/test_sentry_helper.py
index e0a165f..344df32 100644
--- a/tests/sentry/test_sentry_helper.py
+++ b/tests/sentry/test_sentry_helper.py
@@ -8,22 +8,22 @@
class SentryHelperTest(TestCase):
def test_strip_sensitive_data_from_sentry_event_regular(self):
- event = {'user': {'email': 'mymail@example.com', 'ip_address': '127.0.0.1', 'username': 'my-user'}}
+ event = {"user": {"email": "mymail@example.com", "ip_address": "127.0.0.1", "username": "my-user"}}
self.assertIsInstance(strip_sensitive_data_from_sentry_event(event, None), dict)
def test_strip_sensitive_data_from_sentry_event_missing_key_email(self):
- event = {'user': {'ip_address': '127.0.0.1', 'username': 'my-user'}}
+ event = {"user": {"ip_address": "127.0.0.1", "username": "my-user"}}
self.assertIsInstance(strip_sensitive_data_from_sentry_event(event, None), dict)
def test_strip_sensitive_data_from_sentry_event_missing_key_ip_address(self):
- event = {'user': {'email': 'mymail@example.com', 'username': 'my-user'}}
+ event = {"user": {"email": "mymail@example.com", "username": "my-user"}}
self.assertIsInstance(strip_sensitive_data_from_sentry_event(event, None), dict)
def test_strip_sensitive_data_from_sentry_event_missing_key_username(self):
- event = {'user': {'email': 'mymail@example.com', 'ip_address': '127.0.0.1'}}
+ event = {"user": {"email": "mymail@example.com", "ip_address": "127.0.0.1"}}
self.assertIsInstance(strip_sensitive_data_from_sentry_event(event, None), dict)
diff --git a/tests/test_admin_forms.py b/tests/test_admin_forms.py
index 2190395..f198cb9 100644
--- a/tests/test_admin_forms.py
+++ b/tests/test_admin_forms.py
@@ -12,4 +12,4 @@ def test_admin_crispy_form_regular(self):
self.assertIsInstance(form.helper, FormHelper)
self.assertIsInstance(form.helper.layout, Layout)
- self.assertEqual(form.helper.form_method, 'post')
+ self.assertEqual(form.helper.form_method, "post")
diff --git a/tests/test_admin_inlines.py b/tests/test_admin_inlines.py
index f9cc5ab..db16d86 100644
--- a/tests/test_admin_inlines.py
+++ b/tests/test_admin_inlines.py
@@ -16,7 +16,7 @@ class AdminInlineTest(RequestProviderMixin, TestCase):
def setUpTestData(cls):
super().setUpTestData()
- cls.super_user = User.objects.create(username='super_user', is_superuser=True)
+ cls.super_user = User.objects.create(username="super_user", is_superuser=True)
def test_read_only_tabular_inline_admin_all_fields_readonly(self):
obj = MySingleSignalModel(value=1)
@@ -26,7 +26,7 @@ def test_read_only_tabular_inline_admin_all_fields_readonly(self):
readonly_fields = admin_class.get_readonly_fields(request=self.get_request(), obj=fk_related_obj)
self.assertEqual(len(readonly_fields), 1)
- self.assertIn('single_signal', readonly_fields)
+ self.assertIn("single_signal", readonly_fields)
def test_read_only_admin_tabular_inline_no_change_permissions(self):
admin_class = TestReadOnlyTabularInline(parent_model=MySingleSignalModel, admin_site=admin.site)
diff --git a/tests/test_admin_model_admins_classes.py b/tests/test_admin_model_admins_classes.py
index 9f75d3c..cc643e2 100644
--- a/tests/test_admin_model_admins_classes.py
+++ b/tests/test_admin_model_admins_classes.py
@@ -20,7 +20,7 @@ class AdminClassesTest(RequestProviderMixin, TestCase):
def setUpTestData(cls):
super().setUpTestData()
- cls.super_user = User.objects.create(username='super_user', is_superuser=True)
+ cls.super_user = User.objects.create(username="super_user", is_superuser=True)
admin.site.register(MySingleSignalModel, TestReadOnlyAdmin)
admin.site.register(MyMultipleSignalModel, TestEditableOnlyAdmin)
@@ -39,8 +39,8 @@ def test_read_only_admin_all_fields_readonly(self):
readonly_fields = admin_class.get_readonly_fields(request=self.get_request(), obj=obj)
self.assertEqual(len(readonly_fields), 2)
- self.assertIn('id', readonly_fields)
- self.assertIn('value', readonly_fields)
+ self.assertIn("id", readonly_fields)
+ self.assertIn("value", readonly_fields)
def test_read_only_admin_no_change_permissions(self):
admin_class = TestReadOnlyAdmin(model=MySingleSignalModel, admin_site=admin.site)
@@ -58,7 +58,7 @@ def test_editable_only_admin_delete_action_removed(self):
request = self.get_request(self.super_user)
actions = admin_class.get_actions(request=request)
- self.assertNotIn('delete_selected', actions)
+ self.assertNotIn("delete_selected", actions)
def test_editable_only_admin_no_change_permissions(self):
admin_class = TestEditableOnlyAdmin(model=MyMultipleSignalModel, admin_site=admin.site)
diff --git a/tests/test_admin_view_mixins.py b/tests/test_admin_view_mixins.py
index 9c15593..947674b 100644
--- a/tests/test_admin_view_mixins.py
+++ b/tests/test_admin_view_mixins.py
@@ -11,8 +11,8 @@
class TestView(AdminViewMixin, generic.TemplateView):
model = MySingleSignalModel
- admin_page_title = 'My fancy title'
- template_name = 'testapp/test_template.html'
+ admin_page_title = "My fancy title"
+ template_name = "testapp/test_template.html"
class AdminViewMixinTest(RequestProviderMixin, TestCase):
@@ -22,8 +22,8 @@ def setUpTestData(cls):
cls.view = TestView()
- cls.super_user = User.objects.create(username='super_user', is_superuser=True)
- cls.regular_user = User.objects.create(username='test_user', is_superuser=False)
+ cls.super_user = User.objects.create(username="super_user", is_superuser=True)
+ cls.regular_user = User.objects.create(username="test_user", is_superuser=False)
# View needs a request since django 3.2
request = cls.get_request(cls.super_user)
@@ -54,17 +54,17 @@ def test_admin_view_mixin_get_context_data_regular(self):
context_data = self.view.get_context_data()
# Simply assert custom fields are available
- self.assertIn('site_header', context_data)
- self.assertIn('site_title', context_data)
- self.assertIn('name', context_data)
- self.assertIn('original', context_data)
- self.assertIn('is_nav_sidebar_enabled', context_data)
- self.assertIn('available_apps', context_data)
- self.assertIn('opts', context_data)
- self.assertIn('app_label', context_data['opts'])
- self.assertIn('verbose_name', context_data['opts'])
- self.assertIn('verbose_name_plural', context_data['opts'])
- self.assertIn('model_name', context_data['opts'])
- self.assertIn('app_config', context_data['opts'])
- self.assertIn('verbose_name', context_data['opts']['app_config'])
- self.assertIn('has_permission', context_data)
+ self.assertIn("site_header", context_data)
+ self.assertIn("site_title", context_data)
+ self.assertIn("name", context_data)
+ self.assertIn("original", context_data)
+ self.assertIn("is_nav_sidebar_enabled", context_data)
+ self.assertIn("available_apps", context_data)
+ self.assertIn("opts", context_data)
+ self.assertIn("app_label", context_data["opts"])
+ self.assertIn("verbose_name", context_data["opts"])
+ self.assertIn("verbose_name_plural", context_data["opts"])
+ self.assertIn("model_name", context_data["opts"])
+ self.assertIn("app_config", context_data["opts"])
+ self.assertIn("verbose_name", context_data["opts"]["app_config"])
+ self.assertIn("has_permission", context_data)
diff --git a/tests/test_context_manager.py b/tests/test_context_manager.py
index ce3bcf3..ade087f 100644
--- a/tests/test_context_manager.py
+++ b/tests/test_context_manager.py
@@ -19,9 +19,9 @@ def test_single_signal_executed_regular(self):
def test_single_signal_not_executed(self):
kwargs = {
- 'signal': signals.pre_save,
- 'receiver': increase_value_no_dispatch_uid,
- 'sender': MySingleSignalModel,
+ "signal": signals.pre_save,
+ "receiver": increase_value_no_dispatch_uid,
+ "sender": MySingleSignalModel,
}
with TempDisconnectSignal(**kwargs):
@@ -31,15 +31,15 @@ def test_single_signal_not_executed(self):
def test_multiple_signals_not_executed(self):
kwargs_pre = {
- 'signal': signals.pre_save,
- 'receiver': increase_value_with_dispatch_uid,
- 'sender': MyMultipleSignalModel,
- 'dispatch_uid': 'test.mysinglesignalmodel.increase_value_with_uuid',
+ "signal": signals.pre_save,
+ "receiver": increase_value_with_dispatch_uid,
+ "sender": MyMultipleSignalModel,
+ "dispatch_uid": "test.mysinglesignalmodel.increase_value_with_uuid",
}
kwargs_post = {
- 'signal': signals.post_save,
- 'receiver': send_email,
- 'sender': MyMultipleSignalModel,
+ "signal": signals.post_save,
+ "receiver": send_email,
+ "sender": MyMultipleSignalModel,
}
with TempDisconnectSignal(**kwargs_pre):
@@ -53,10 +53,10 @@ def test_multiple_signals_not_executed(self):
def test_multiple_signals_one_still_active(self):
kwargs_pre = {
- 'signal': signals.pre_save,
- 'receiver': increase_value_with_dispatch_uid,
- 'sender': MyMultipleSignalModel,
- 'dispatch_uid': 'test.mysinglesignalmodel.increase_value_with_uuid',
+ "signal": signals.pre_save,
+ "receiver": increase_value_with_dispatch_uid,
+ "sender": MyMultipleSignalModel,
+ "dispatch_uid": "test.mysinglesignalmodel.increase_value_with_uuid",
}
with TempDisconnectSignal(**kwargs_pre):
diff --git a/tests/test_managers.py b/tests/test_managers.py
index c703712..6a553a6 100644
--- a/tests/test_managers.py
+++ b/tests/test_managers.py
@@ -10,7 +10,7 @@ def setUpTestData(cls):
super().setUpTestData()
# Create test user
- cls.user = User.objects.create(username='my-username')
+ cls.user = User.objects.create(username="my-username")
# Create list of objects
cls.object_list = [
diff --git a/tests/test_middleware.py b/tests/test_middleware.py
index 3e0a3f9..d5a06ff 100644
--- a/tests/test_middleware.py
+++ b/tests/test_middleware.py
@@ -18,13 +18,13 @@ def test_current_user_is_none_if_request_user_is_none(self):
self.assertEqual(response.status_code, HTTPStatus.NO_CONTENT)
def test_current_user_is_same_as_request_user(self):
- new_user = Mock(user_name='test_user')
+ new_user = Mock(user_name="test_user")
response = set_current_user(user=new_user)
self.assertEqual(response.status_code, HTTPStatus.OK)
def test_current_user_is_thread_safe(self):
- user1 = Mock(user_name='user1')
- user2 = Mock(user_name='user2')
+ user1 = Mock(user_name="user1")
+ user2 = Mock(user_name="user2")
current_users = []
ready_event = threading.Event()
proceed_event = threading.Event()
@@ -43,12 +43,12 @@ def test_current_user_is_thread_safe(self):
proceed_event.set()
first_thread.join()
self.assertEqual(current_users[0], user2)
- self.assertEqual(current_users[0].user_name, 'user2')
+ self.assertEqual(current_users[0].user_name, "user2")
self.assertEqual(current_users[1], user1)
- self.assertEqual(current_users[1].user_name, 'user1')
+ self.assertEqual(current_users[1].user_name, "user1")
def test_user_is_cleared_after_request(self):
- user = Mock(user_name='test_user')
+ user = Mock(user_name="test_user")
request = Mock(user=user)
middleware = CurrentUserMiddleware(get_response=lambda request: HttpResponse(status=HTTPStatus.OK))
response = middleware(request)
@@ -63,7 +63,7 @@ def test_replaced_user_is_reflected_in_middleware(self):
# This should ideally be taken into account in our middleware since it
# is also used to provide the user for `CommonInfo.lastmodified_by`.
def get_response(request):
- replaced_user = Mock(user_name='replaced_user')
+ replaced_user = Mock(user_name="replaced_user")
request.user = replaced_user
user_from_mw = CurrentUserMiddleware.get_current_user()
if user_from_mw is not replaced_user:
diff --git a/tests/test_models.py b/tests/test_models.py
index 1c775b6..b87110d 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -9,7 +9,7 @@
class CommonInfoTest(TestCase):
- @freeze_time('2022-06-26 10:00')
+ @freeze_time("2022-06-26 10:00")
def test_save_created_at_set(self):
obj = CommonInfoBasedModel.objects.create(value=1, value_b=1)
obj.created_at = None
@@ -17,9 +17,9 @@ def test_save_created_at_set(self):
self.assertEqual(obj.created_at, timezone.now())
- @freeze_time('2022-06-26 10:00')
+ @freeze_time("2022-06-26 10:00")
def test_save_update_fields_common_fields_set(self):
- with freeze_time('2020-09-19'):
+ with freeze_time("2020-09-19"):
obj = CommonInfoBasedModel.objects.create(value=1, value_b=1)
obj.value = 2
obj.value_b = 999
@@ -29,7 +29,7 @@ def test_save_update_fields_common_fields_set(self):
False, # default for force_insert
False, # default for force_update
None, # default for using
- (x for x in ['value']), # update_fields is supposed to accept any Iterable[str]
+ (x for x in ["value"]), # update_fields is supposed to accept any Iterable[str]
)
obj.save(*args)
@@ -38,22 +38,22 @@ def test_save_update_fields_common_fields_set(self):
self.assertEqual(obj.value_b, 1, "value_b should not have changed")
self.assertEqual(obj.lastmodified_at, datetime.datetime(2022, 6, 26, 10))
- @patch('testapp.models.CommonInfoBasedModel.ALWAYS_UPDATE_FIELDS', new_callable=PropertyMock)
- @freeze_time('2022-06-26 10:00')
+ @patch("testapp.models.CommonInfoBasedModel.ALWAYS_UPDATE_FIELDS", new_callable=PropertyMock)
+ @freeze_time("2022-06-26 10:00")
def test_save_update_fields_common_fields_set_without_always_update(self, always_update_mock):
always_update_mock.return_value = False
- with freeze_time('2020-09-19'):
+ with freeze_time("2020-09-19"):
obj = CommonInfoBasedModel.objects.create(value=1)
obj.value = 2
- obj.save(update_fields=('value',))
+ obj.save(update_fields=("value",))
obj.refresh_from_db()
self.assertEqual(obj.value, 2)
self.assertEqual(obj.lastmodified_at, datetime.datetime(2020, 9, 19))
- @freeze_time('2022-06-26 10:00')
+ @freeze_time("2022-06-26 10:00")
def test_save_common_fields_set_without_update_fields(self):
- with freeze_time('2020-09-19'):
+ with freeze_time("2020-09-19"):
obj = CommonInfoBasedModel.objects.create(value=1)
obj.value = 2
obj.save()
diff --git a/tests/test_rest_api_mixins.py b/tests/test_rest_api_mixins.py
index 16d8793..2cd042d 100644
--- a/tests/test_rest_api_mixins.py
+++ b/tests/test_rest_api_mixins.py
@@ -10,7 +10,7 @@
class BaseApiTest(BaseViewSetTestMixin, TestCase):
def get_default_api_user(self) -> AbstractUser:
- return User.objects.create(username='my-username', is_active=True)
+ return User.objects.create(username="my-username", is_active=True)
class MySingleSignalModelApiViewTest(BaseApiTest):
@@ -29,20 +29,20 @@ def setUpTestData(cls):
def test_action_not_activated(self):
with self.assertRaises(AttributeError):
self.execute_request(
- method='post',
- url=reverse('my-single-signal-model-list'),
- viewset_kwargs={'post': 'create'},
+ method="post",
+ url=reverse("my-single-signal-model-list"),
+ viewset_kwargs={"post": "create"},
user=self.default_api_user,
)
def test_list_authentication_required(self):
- self.validate_authentication_required(url=reverse('my-single-signal-model-list'), method='get', view='list')
+ self.validate_authentication_required(url=reverse("my-single-signal-model-list"), method="get", view="list")
def test_list_regular(self):
response = self.execute_request(
- method='get',
- url=reverse('my-single-signal-model-list'),
- viewset_kwargs={'get': 'list'},
+ method="get",
+ url=reverse("my-single-signal-model-list"),
+ viewset_kwargs={"get": "list"},
user=self.default_api_user,
)
diff --git a/tests/test_utils_date.py b/tests/test_utils_date.py
index 0465a2e..2ce6439 100644
--- a/tests/test_utils_date.py
+++ b/tests/test_utils_date.py
@@ -118,7 +118,7 @@ def test_tz_today_as_object_tz_not_active(self):
def test_tz_today_as_str(self):
frozen_date = datetime.datetime(year=2019, month=9, day=19, hour=10)
with freeze_time(frozen_date):
- self.assertEqual(tz_today('%d.%m.%Y'), '19.09.2019')
+ self.assertEqual(tz_today("%d.%m.%Y"), "19.09.2019")
def test_add_months_one_month(self):
source_date = datetime.date(year=2020, month=6, day=26)
@@ -162,7 +162,7 @@ def test_add_minutes_negative_minutes(self):
add_minutes(source_datetime, -2), datetime.datetime(year=2020, month=6, day=26, hour=7, minute=58)
)
- @freeze_time('2020-06-26')
+ @freeze_time("2020-06-26")
def test_get_next_month_regular(self):
self.assertEqual(get_next_month(), datetime.date(year=2020, month=7, day=26))
@@ -172,40 +172,40 @@ def test_first_day_of_month_regular(self):
def test_get_formatted_date_str_regular(self):
source_date = datetime.date(year=2020, month=6, day=26)
- self.assertEqual(get_formatted_date_str(source_date), '26.06.2020')
+ self.assertEqual(get_formatted_date_str(source_date), "26.06.2020")
def test_get_time_from_seconds_one_hour(self):
- self.assertEqual(get_time_from_seconds(3600), '01:00:00')
+ self.assertEqual(get_time_from_seconds(3600), "01:00:00")
def test_get_time_from_seconds_one_minute(self):
- self.assertEqual(get_time_from_seconds(60), '00:01:00')
+ self.assertEqual(get_time_from_seconds(60), "00:01:00")
def test_get_time_from_seconds_big_hours(self):
- self.assertEqual(get_time_from_seconds(3600 * 99), '99:00:00')
+ self.assertEqual(get_time_from_seconds(3600 * 99), "99:00:00")
def test_get_time_from_seconds_huge_hours(self):
- self.assertEqual(get_time_from_seconds(3600 * 1000), '1000:00:00')
+ self.assertEqual(get_time_from_seconds(3600 * 1000), "1000:00:00")
def test_get_time_from_seconds_negative_seconds(self):
with self.assertRaises(ValueError):
get_time_from_seconds(-1)
- @override_settings(TIME_ZONE='UTC')
+ @override_settings(TIME_ZONE="UTC")
def test_datetime_format_regular(self):
source_date = datetime.datetime(year=2020, month=6, day=26, hour=8, tzinfo=pytz.UTC)
- self.assertEqual(datetime_format(source_date, '%d.%m.%Y %H:%M'), '26.06.2020 08:00')
+ self.assertEqual(datetime_format(source_date, "%d.%m.%Y %H:%M"), "26.06.2020 08:00")
- @override_settings(TIME_ZONE='Europe/Cologne')
+ @override_settings(TIME_ZONE="Europe/Cologne")
def test_datetime_format_wrong_timezone(self):
source_date = datetime.datetime(year=2020, month=6, day=26, hour=8, tzinfo=datetime.timezone.utc)
- self.assertEqual(datetime_format(source_date, '%d.%m.%Y %H:%M'), '26.06.2020 08:00')
+ self.assertEqual(datetime_format(source_date, "%d.%m.%Y %H:%M"), "26.06.2020 08:00")
- @override_settings(TIME_ZONE='Europe/Berlin')
+ @override_settings(TIME_ZONE="Europe/Berlin")
def test_datetime_format_different_timezone(self):
source_date = datetime.datetime(year=2020, month=6, day=26, hour=8, tzinfo=pytz.UTC)
- self.assertEqual(datetime_format(source_date, '%d.%m.%Y %H:%M'), '26.06.2020 10:00')
+ self.assertEqual(datetime_format(source_date, "%d.%m.%Y %H:%M"), "26.06.2020 10:00")
- @freeze_time('2022-12-14')
+ @freeze_time("2022-12-14")
def test_get_first_and_last_of_month_in_december(self):
first_of_month, last_of_month = get_first_and_last_of_month()
expected_first_of_month = datetime.date(day=1, month=12, year=2022)
@@ -214,7 +214,7 @@ def test_get_first_and_last_of_month_in_december(self):
self.assertEqual(expected_first_of_month, first_of_month)
self.assertEqual(expected_last_of_month, last_of_month)
- @freeze_time('2020-02-14')
+ @freeze_time("2020-02-14")
def test_get_first_and_last_of_month_in_february_leap_year(self):
first_of_month, last_of_month = get_first_and_last_of_month()
expected_first_of_month = datetime.date(day=1, month=2, year=2020)
@@ -223,7 +223,7 @@ def test_get_first_and_last_of_month_in_february_leap_year(self):
self.assertEqual(expected_first_of_month, first_of_month)
self.assertEqual(expected_last_of_month, last_of_month)
- @freeze_time('2022-02-14')
+ @freeze_time("2022-02-14")
def test_get_first_and_last_of_month_in_february_non_leap_year(self):
first_of_month, last_of_month = get_first_and_last_of_month()
expected_first_of_month = datetime.date(day=1, month=2, year=2022)
@@ -232,7 +232,7 @@ def test_get_first_and_last_of_month_in_february_non_leap_year(self):
self.assertEqual(expected_first_of_month, first_of_month)
self.assertEqual(expected_last_of_month, last_of_month)
- @freeze_time('2022-04-04')
+ @freeze_time("2022-04-04")
def test_get_first_and_last_of_month_in_april(self):
first_of_month, last_of_month = get_first_and_last_of_month()
expected_first_of_month = datetime.date(day=1, month=4, year=2022)
@@ -244,25 +244,25 @@ def test_get_first_and_last_of_month_in_april(self):
def test_get_first_and_last_of_month_with_date_objects_passed(self):
date_mapping = {
datetime.date(day=14, month=12, year=2022): {
- 'first': datetime.date(day=1, month=12, year=2022),
- 'last': datetime.date(day=31, month=12, year=2022),
+ "first": datetime.date(day=1, month=12, year=2022),
+ "last": datetime.date(day=31, month=12, year=2022),
},
datetime.date(day=14, month=2, year=2020): {
- 'first': datetime.date(day=1, month=2, year=2020),
- 'last': datetime.date(day=29, month=2, year=2020),
+ "first": datetime.date(day=1, month=2, year=2020),
+ "last": datetime.date(day=29, month=2, year=2020),
},
datetime.date(day=14, month=2, year=2022): {
- 'first': datetime.date(day=1, month=2, year=2022),
- 'last': datetime.date(day=28, month=2, year=2022),
+ "first": datetime.date(day=1, month=2, year=2022),
+ "last": datetime.date(day=28, month=2, year=2022),
},
datetime.date(day=4, month=4, year=2022): {
- 'first': datetime.date(day=1, month=4, year=2022),
- 'last': datetime.date(day=30, month=4, year=2022),
+ "first": datetime.date(day=1, month=4, year=2022),
+ "last": datetime.date(day=30, month=4, year=2022),
},
}
for date_object in date_mapping:
first_of_month, last_of_month = get_first_and_last_of_month(date_object=date_object)
- self.assertEqual(date_mapping[date_object]['first'], first_of_month)
- self.assertEqual(date_mapping[date_object]['last'], last_of_month)
+ self.assertEqual(date_mapping[date_object]["first"], first_of_month)
+ self.assertEqual(date_mapping[date_object]["last"], last_of_month)
diff --git a/tests/test_utils_file.py b/tests/test_utils_file.py
index 376af73..f3ff725 100644
--- a/tests/test_utils_file.py
+++ b/tests/test_utils_file.py
@@ -4,30 +4,30 @@
def test_get_filename_without_ending_full_path():
- assert get_filename_without_ending('path/to/my/text-file.txt') == "text-file"
+ assert get_filename_without_ending("path/to/my/text-file.txt") == "text-file"
def test_get_filename_without_ending_only_filename():
- assert get_filename_without_ending('text-file.txt') == "text-file"
+ assert get_filename_without_ending("text-file.txt") == "text-file"
@pytest.fixture
def gen_test_file(tmp_path):
def inner(content):
- test_file = tmp_path / 'test_file.txt'
+ test_file = tmp_path / "test_file.txt"
test_file.write_text(content)
return test_file
return inner
-@pytest.mark.parametrize('test_func', [crc, md5_checksum])
+@pytest.mark.parametrize("test_func", [crc, md5_checksum])
def test_closes_file(mocker, test_func):
"""
Tests if the CRC and MD5 checksum functions use a context manager to open the file, to guarantee that the opened
file descriptor is closed.
"""
- open_mock = mocker.patch('ambient_toolbox.utils.file.open')
+ open_mock = mocker.patch("ambient_toolbox.utils.file.open")
open_mock.return_value.__enter__.return_value.read.return_value = None # to make f.read() return None.
file_mock = mocker.Mock()
test_func(file_mock)
@@ -36,11 +36,11 @@ def test_closes_file(mocker, test_func):
@pytest.mark.parametrize(
- 'content, crc_result, md5_result',
+ "content, crc_result, md5_result",
[
- ('The answer to life, the universe, and everything.', '31F49620', 'f81ab2f7fb6cacf50f973b0dc8faff44'),
- ('The quick brown fox jumps over the lazy dog', '414FA339', '9e107d9d372bb6826bd81d3542a419d6'),
- ('', '00000000', 'd41d8cd98f00b204e9800998ecf8427e'),
+ ("The answer to life, the universe, and everything.", "31F49620", "f81ab2f7fb6cacf50f973b0dc8faff44"),
+ ("The quick brown fox jumps over the lazy dog", "414FA339", "9e107d9d372bb6826bd81d3542a419d6"),
+ ("", "00000000", "d41d8cd98f00b204e9800998ecf8427e"),
],
)
def test_crc_and_md5(gen_test_file, content, crc_result, md5_result):
diff --git a/tests/test_utils_model.py b/tests/test_utils_model.py
index d058116..16e3638 100644
--- a/tests/test_utils_model.py
+++ b/tests/test_utils_model.py
@@ -7,19 +7,19 @@
class UtilModelTest(TestCase):
def test_object_to_dict_regular(self):
obj = MySingleSignalModel.objects.create(value=17)
- self.assertEqual(object_to_dict(obj), {'value': obj.value})
+ self.assertEqual(object_to_dict(obj), {"value": obj.value})
def test_object_to_dict_blacklist(self):
obj = MySingleSignalModel.objects.create(value=17)
- self.assertEqual(object_to_dict(obj, ['value']), {})
+ self.assertEqual(object_to_dict(obj, ["value"]), {})
def test_object_to_dict_with_id_with_blacklist(self):
obj = MySingleSignalModel.objects.create(value=17)
- self.assertEqual(object_to_dict(obj, ['value'], True), {'id': obj.id})
+ self.assertEqual(object_to_dict(obj, ["value"], True), {"id": obj.id})
def test_with_id_no_blacklist(self):
obj = MySingleSignalModel.objects.create(value=17)
- self.assertEqual(object_to_dict(obj, include_id=True), {'id': obj.id, 'value': obj.value})
+ self.assertEqual(object_to_dict(obj, include_id=True), {"id": obj.id, "value": obj.value})
def test_object_to_dict_valid_fields_append(self):
obj = MySingleSignalModel.objects.create(value=17)
@@ -27,5 +27,5 @@ def test_object_to_dict_valid_fields_append(self):
valid_data = object_to_dict(dummy_instance)
- self.assertIn('single_signal_id', valid_data)
- self.assertEqual(valid_data['single_signal_id'], obj.id)
+ self.assertIn("single_signal_id", valid_data)
+ self.assertEqual(valid_data["single_signal_id"], obj.id)
diff --git a/tests/test_utils_named_tuple.py b/tests/test_utils_named_tuple.py
index f4c1c62..30977bf 100644
--- a/tests/test_utils_named_tuple.py
+++ b/tests/test_utils_named_tuple.py
@@ -21,10 +21,10 @@ def setUpClass(cls):
)
cls.colors_choices = get_namedtuple_choices(
- 'COLORS',
+ "COLORS",
(
- (1, 'black', 'Black'),
- (2, 'white', 'White'),
+ (1, "black", "Black"),
+ (2, "white", "White"),
),
)
@@ -33,39 +33,39 @@ def test_get_namedtuple_choices_regular(self):
self.assertEqual(self.colors_choices.white, 2)
def test_get_namedtuple_choices_get_choices_regular(self):
- self.assertEqual(self.colors_choices.get_choices(), [(1, 'Black'), (2, 'White')])
+ self.assertEqual(self.colors_choices.get_choices(), [(1, "Black"), (2, "White")])
def test_get_namedtuple_choices_get_choices_dict_regular(self):
- self.assertEqual(self.colors_choices.get_choices_dict(), OrderedDict([(1, 'Black'), (2, 'White')]))
+ self.assertEqual(self.colors_choices.get_choices_dict(), OrderedDict([(1, "Black"), (2, "White")]))
def test_get_namedtuple_choices_get_all_regular(self):
for index, color in enumerate(self.colors_choices.get_all()):
expected_tuple = "invalid_data"
if index == 0:
- expected_tuple = (1, 'black', 'Black')
+ expected_tuple = (1, "black", "Black")
elif index == 1:
- expected_tuple = (2, 'white', 'White')
+ expected_tuple = (2, "white", "White")
self.assertEqual(color, expected_tuple)
def test_get_namedtuple_choices_get_choices_tuple_regular(self):
- self.assertEqual(self.colors_choices.get_choices_tuple(), ((1, 'black', 'Black'), (2, 'white', 'White')))
+ self.assertEqual(self.colors_choices.get_choices_tuple(), ((1, "black", "Black"), (2, "white", "White")))
def test_get_namedtuple_choices_get_values_regular(self):
self.assertEqual(self.colors_choices.get_values(), [1, 2])
def test_get_namedtuple_choices_get_value_by_name_regular(self):
- self.assertEqual(self.colors_choices.get_value_by_name('black'), 1)
- self.assertEqual(self.colors_choices.get_value_by_name('white'), 2)
- self.assertFalse(self.colors_choices.get_value_by_name('no-existing'))
+ self.assertEqual(self.colors_choices.get_value_by_name("black"), 1)
+ self.assertEqual(self.colors_choices.get_value_by_name("white"), 2)
+ self.assertFalse(self.colors_choices.get_value_by_name("no-existing"))
def test_get_namedtuple_choices_get_desc_by_value_regular(self):
- self.assertEqual(self.colors_choices.get_desc_by_value(1), 'Black')
- self.assertEqual(self.colors_choices.get_desc_by_value(2), 'White')
+ self.assertEqual(self.colors_choices.get_desc_by_value(1), "Black")
+ self.assertEqual(self.colors_choices.get_desc_by_value(2), "White")
self.assertFalse(self.colors_choices.get_desc_by_value(-1))
def test_get_namedtuple_choices_get_name_by_value_regular(self):
- self.assertEqual(self.colors_choices.get_name_by_value(1), 'black')
- self.assertEqual(self.colors_choices.get_name_by_value(2), 'white')
+ self.assertEqual(self.colors_choices.get_name_by_value(1), "black")
+ self.assertEqual(self.colors_choices.get_name_by_value(2), "white")
self.assertFalse(self.colors_choices.get_name_by_value(-1))
def test_get_namedtuple_choices_is_valid_regular(self):
@@ -74,24 +74,24 @@ def test_get_namedtuple_choices_is_valid_regular(self):
self.assertFalse(self.colors_choices.is_valid(-1))
def test_get_value_from_tuple_by_key_found(self):
- self.assertEqual(get_value_from_tuple_by_key(self.MY_CHOICE_LIST, self.MY_CHOICE_TWO), 'Choice 2')
+ self.assertEqual(get_value_from_tuple_by_key(self.MY_CHOICE_LIST, self.MY_CHOICE_TWO), "Choice 2")
def test_get_value_from_tuple_by_key_not_found(self):
- self.assertEqual(get_value_from_tuple_by_key(self.MY_CHOICE_LIST, 99), '-')
+ self.assertEqual(get_value_from_tuple_by_key(self.MY_CHOICE_LIST, 99), "-")
def test_get_key_from_tuple_by_value_found(self):
- self.assertEqual(get_key_from_tuple_by_value(self.MY_CHOICE_LIST, 'Choice 2'), self.MY_CHOICE_TWO)
+ self.assertEqual(get_key_from_tuple_by_value(self.MY_CHOICE_LIST, "Choice 2"), self.MY_CHOICE_TWO)
def test_get_key_from_tuple_by_value_not_found(self):
- self.assertEqual(get_key_from_tuple_by_value(self.MY_CHOICE_LIST, 'Something odd'), '-')
+ self.assertEqual(get_key_from_tuple_by_value(self.MY_CHOICE_LIST, "Something odd"), "-")
def test_get_values_case_is_instance(self):
choices = get_namedtuple_choices(
- 'TestChoices',
+ "TestChoices",
(
- (0, 'zero', 'Zero'),
- (1, 'one', 'One'),
- ([2, 3], 'two_three', 'Two Three'),
+ (0, "zero", "Zero"),
+ (1, "one", "One"),
+ ([2, 3], "two_three", "Two Three"),
),
)
diff --git a/tests/test_utils_string.py b/tests/test_utils_string.py
index d6c1be8..122bc6e 100644
--- a/tests/test_utils_string.py
+++ b/tests/test_utils_string.py
@@ -18,119 +18,119 @@
class UtilsStringTest(TestCase):
def test_distinct_regular(self):
- not_distinct_list = ['Beer', 'Wine', 'Whiskey', 'Beer']
+ not_distinct_list = ["Beer", "Wine", "Whiskey", "Beer"]
distinct_list = distinct(not_distinct_list)
self.assertEqual(len(distinct_list), 3)
- self.assertIn('Beer', distinct_list)
- self.assertIn('Whiskey', distinct_list)
- self.assertIn('Wine', distinct_list)
+ self.assertIn("Beer", distinct_list)
+ self.assertIn("Whiskey", distinct_list)
+ self.assertIn("Wine", distinct_list)
def test_slugify_file_name_regular(self):
- filename = 'hola and hello.txt'
+ filename = "hola and hello.txt"
slug = slugify_file_name(filename)
- self.assertEqual(slug, 'hola_and_hello.txt')
+ self.assertEqual(slug, "hola_and_hello.txt")
def test_slugify_file_name_nothing_to_slugify(self):
- filename = 'hola.txt'
+ filename = "hola.txt"
slug = slugify_file_name(filename)
self.assertEqual(slug, filename)
def test_slugify_file_name_max_length(self):
- filename = 'a very long filename.txt'
+ filename = "a very long filename.txt"
slug = slugify_file_name(filename, 6)
- self.assertEqual(slug, 'a_very.txt')
+ self.assertEqual(slug, "a_very.txt")
def test_smart_truncate_in_word(self):
- my_sentence = 'I am a very interesting sentence.'
+ my_sentence = "I am a very interesting sentence."
truncated_str = smart_truncate(my_sentence, 10)
- self.assertEqual(truncated_str, 'I am a...')
+ self.assertEqual(truncated_str, "I am a...")
def test_smart_truncate_after_word(self):
- my_sentence = 'I am a very interesting sentence.'
+ my_sentence = "I am a very interesting sentence."
truncated_str = smart_truncate(my_sentence, 14)
- self.assertEqual(truncated_str, 'I am a very...')
+ self.assertEqual(truncated_str, "I am a very...")
def test_smart_truncate_changed_postfix(self):
- my_sentence = 'I am a very interesting sentence.'
- truncated_str = smart_truncate(my_sentence, 10, '[...]')
- self.assertEqual(truncated_str, 'I am a[...]')
+ my_sentence = "I am a very interesting sentence."
+ truncated_str = smart_truncate(my_sentence, 10, "[...]")
+ self.assertEqual(truncated_str, "I am a[...]")
def test_smart_truncate_not_cutting_on_too_short_strings(self):
- my_sentence = 'I am a very interesting sentence.'
- truncated_str = smart_truncate(my_sentence, 100, '---')
+ my_sentence = "I am a very interesting sentence."
+ truncated_str = smart_truncate(my_sentence, 100, "---")
self.assertEqual(truncated_str, my_sentence)
def test_smart_truncate_no_text(self):
- truncated_str = smart_truncate(None, 100, '---')
+ truncated_str = smart_truncate(None, 100, "---")
self.assertEqual(truncated_str, "")
def test_float_to_string_regular(self):
- self.assertEqual(float_to_string(5.61), '5,61')
+ self.assertEqual(float_to_string(5.61), "5,61")
def test_float_to_string_value_replacement_not_used(self):
- self.assertEqual(float_to_string(4.41, '-'), '4,41')
+ self.assertEqual(float_to_string(4.41, "-"), "4,41")
def test_float_to_string_no_value_replacement_used(self):
- self.assertEqual(float_to_string(None, 'Heureka'), 'Heureka')
+ self.assertEqual(float_to_string(None, "Heureka"), "Heureka")
def test_float_to_string_value_greater_thousand(self):
- self.assertEqual(float_to_string(1234.56), '1234,56')
+ self.assertEqual(float_to_string(1234.56), "1234,56")
def test_date_to_string_regular(self):
- self.assertEqual(date_to_string(datetime.date(2020, 9, 19)), '19.09.2020')
+ self.assertEqual(date_to_string(datetime.date(2020, 9, 19)), "19.09.2020")
def test_date_to_string_other_format(self):
- self.assertEqual(date_to_string(datetime.date(2020, 9, 19), str_format='%Y-%m-%d'), '2020-09-19')
+ self.assertEqual(date_to_string(datetime.date(2020, 9, 19), str_format="%Y-%m-%d"), "2020-09-19")
def test_date_to_string_replacement_undefined(self):
- self.assertEqual(date_to_string(None), '-')
+ self.assertEqual(date_to_string(None), "-")
def test_date_to_string_replacement_defined(self):
- self.assertEqual(date_to_string(None, 'no date'), 'no date')
+ self.assertEqual(date_to_string(None, "no date"), "no date")
def test_datetime_to_string_regular(self):
- self.assertEqual(datetime_to_string(datetime.datetime(2020, 9, 19, 8, tzinfo=pytz.UTC)), '19.09.2020 08:00')
+ self.assertEqual(datetime_to_string(datetime.datetime(2020, 9, 19, 8, tzinfo=pytz.UTC)), "19.09.2020 08:00")
def test_datetime_to_string_other_format(self):
self.assertEqual(
- datetime_to_string(datetime.datetime(2020, 9, 19, 8, tzinfo=pytz.UTC), str_format='%Y-%m-%d'), '2020-09-19'
+ datetime_to_string(datetime.datetime(2020, 9, 19, 8, tzinfo=pytz.UTC), str_format="%Y-%m-%d"), "2020-09-19"
)
def test_datetime_to_string_replacement_undefined(self):
- self.assertEqual(datetime_to_string(None), '-')
+ self.assertEqual(datetime_to_string(None), "-")
def test_datetime_to_string_replacement_defined(self):
- self.assertEqual(datetime_to_string(None, 'no date'), 'no date')
+ self.assertEqual(datetime_to_string(None, "no date"), "no date")
def test_number_to_string_regular(self):
- self.assertEqual(number_to_string(5.61, decimal_digits=2), '5.61')
+ self.assertEqual(number_to_string(5.61, decimal_digits=2), "5.61")
def test_number_to_string_value_replacement_not_used(self):
- self.assertEqual(number_to_string(4.41, decimal_digits=2, replacement='-'), '4.41')
+ self.assertEqual(number_to_string(4.41, decimal_digits=2, replacement="-"), "4.41")
def test_number_to_string_no_value_replacement_used(self):
- self.assertEqual(number_to_string(None, replacement='Heureka'), 'Heureka')
+ self.assertEqual(number_to_string(None, replacement="Heureka"), "Heureka")
def test_number_to_string_value_greater_thousand(self):
- self.assertEqual(number_to_string(1234.56, decimal_digits=2), '1,234.56')
+ self.assertEqual(number_to_string(1234.56, decimal_digits=2), "1,234.56")
def test_number_to_string_int_value_no_digits(self):
- self.assertEqual(number_to_string(117), '117')
+ self.assertEqual(number_to_string(117), "117")
def test_number_to_string_int_value_with_digits(self):
- self.assertEqual(number_to_string(117, decimal_digits=2), '117.00')
+ self.assertEqual(number_to_string(117, decimal_digits=2), "117.00")
def test_string_or_none_to_string_regular(self):
- my_str = 'I am a string.'
+ my_str = "I am a string."
self.assertEqual(string_or_none_to_string(my_str), my_str)
def test_string_or_none_to_string_replacement_undefined(self):
- self.assertEqual(string_or_none_to_string(None), '-')
+ self.assertEqual(string_or_none_to_string(None), "-")
def test_string_or_none_to_string_replacement_defined(self):
- self.assertEqual(string_or_none_to_string(None, 'no value'), 'no value')
+ self.assertEqual(string_or_none_to_string(None, "no value"), "no value")
def test_encode_to_xml_regular(self):
- xml_str = 'Something with an ampersand (&)'
- self.assertEqual(encode_to_xml(xml_str), '<tag>Something with an ampersand (&)</tag>')
+ xml_str = "Something with an ampersand (&)"
+ self.assertEqual(encode_to_xml(xml_str), "<tag>Something with an ampersand (&)</tag>")
diff --git a/tests/tests/mixins/test_django_message_framework.py b/tests/tests/mixins/test_django_message_framework.py
index ec15338..410ce29 100644
--- a/tests/tests/mixins/test_django_message_framework.py
+++ b/tests/tests/mixins/test_django_message_framework.py
@@ -12,9 +12,9 @@ def setUpTestData(cls):
cls.request = cls.get_request()
def test_full_message_found(self):
- messages.add_message(self.request, messages.INFO, 'My message')
- self.assert_full_message_in_request(request=self.request, message='My message')
+ messages.add_message(self.request, messages.INFO, "My message")
+ self.assert_full_message_in_request(request=self.request, message="My message")
def test_partial_message_found(self):
- messages.add_message(self.request, messages.INFO, 'My message')
- self.assert_partial_message_in_request(request=self.request, message='My')
+ messages.add_message(self.request, messages.INFO, "My message")
+ self.assert_partial_message_in_request(request=self.request, message="My")
diff --git a/tests/tests/mixins/test_request_provider_mixin.py b/tests/tests/mixins/test_request_provider_mixin.py
index 6daa6cc..0d6a772 100644
--- a/tests/tests/mixins/test_request_provider_mixin.py
+++ b/tests/tests/mixins/test_request_provider_mixin.py
@@ -14,7 +14,7 @@ def test_request_is_request(self):
self.assertIsInstance(request, HttpRequest)
def test_request_user_set(self):
- user = User.objects.create(username='albertus_magnus')
+ user = User.objects.create(username="albertus_magnus")
request = self.get_request(user)
self.assertEqual(request.user, user)
@@ -26,23 +26,23 @@ def test_django_messages_set_up_correctly(self):
request = self.get_request(None)
# This would fail if the django messages were not set up correctly
- messages.add_message(request, messages.SUCCESS, 'I am a great message!')
+ messages.add_message(request, messages.SUCCESS, "I am a great message!")
self.assertIsInstance(request.session, SessionBase)
def test_django_session_set_up_correctly(self):
request = self.get_request(None)
- request.session['my_val'] = 27
+ request.session["my_val"] = 27
request.session.modified = True
- self.assertEqual(request.session['my_val'], 27)
+ self.assertEqual(request.session["my_val"], 27)
def test_passed_user_is_none(self):
request = self.get_request(None)
self.assertIsNone(request.user)
def test_passed_user_is_regular_user(self):
- user = User.objects.create(username='albertus_magnus')
+ user = User.objects.create(username="albertus_magnus")
request = self.get_request(user)
self.assertEqual(request.user, user)
@@ -58,8 +58,8 @@ def test_passed_user_is_other_type(self):
def test_default_url_used(self):
request = self.get_request()
- self.assertEqual(request.build_absolute_uri(), 'http://testserver/')
+ self.assertEqual(request.build_absolute_uri(), "http://testserver/")
def test_passed_url_used(self):
- request = self.get_request(url='my-url')
- self.assertEqual(request.build_absolute_uri(), 'http://testserver/my-url')
+ request = self.get_request(url="my-url")
+ self.assertEqual(request.build_absolute_uri(), "http://testserver/my-url")
diff --git a/tests/tests/test_mail_backends.py b/tests/tests/test_mail_backends.py
index 96b27cb..10f60b3 100644
--- a/tests/tests/test_mail_backends.py
+++ b/tests/tests/test_mail_backends.py
@@ -8,43 +8,43 @@
@override_settings(
- EMAIL_BACKEND='ambient_toolbox.mail.backends.whitelist_smtp.WhitelistEmailBackend',
- EMAIL_BACKEND_DOMAIN_WHITELIST=['valid.domain'],
- EMAIL_BACKEND_REDIRECT_ADDRESS='%s@testuser.valid.domain',
+ EMAIL_BACKEND="ambient_toolbox.mail.backends.whitelist_smtp.WhitelistEmailBackend",
+ EMAIL_BACKEND_DOMAIN_WHITELIST=["valid.domain"],
+ EMAIL_BACKEND_REDIRECT_ADDRESS="%s@testuser.valid.domain",
)
class MailBackendWhitelistBackendTest(TestCase):
def test_whitify_mail_addresses_replace(self):
- email_1 = 'albertus.magnus@example.com'
- email_2 = 'thomas_von_aquin@example.com'
+ email_1 = "albertus.magnus@example.com"
+ email_2 = "thomas_von_aquin@example.com"
processed_list = WhitelistEmailBackend.whitify_mail_addresses(mail_address_list=[email_1, email_2])
self.assertEqual(len(processed_list), 2)
- self.assertEqual(processed_list[0], 'albertus.magnus_example.com@testuser.valid.domain')
- self.assertEqual(processed_list[1], 'thomas_von_aquin_example.com@testuser.valid.domain')
+ self.assertEqual(processed_list[0], "albertus.magnus_example.com@testuser.valid.domain")
+ self.assertEqual(processed_list[1], "thomas_von_aquin_example.com@testuser.valid.domain")
def test_whitify_mail_addresses_whitelisted_domain(self):
- email = 'platon@valid.domain'
+ email = "platon@valid.domain"
processed_list = WhitelistEmailBackend.whitify_mail_addresses(mail_address_list=[email])
self.assertEqual(len(processed_list), 1)
self.assertEqual(processed_list[0], email)
- @override_settings(EMAIL_BACKEND_REDIRECT_ADDRESS='')
+ @override_settings(EMAIL_BACKEND_REDIRECT_ADDRESS="")
def test_whitify_mail_addresses_no_redirect_configured(self):
- email = 'sokrates@example.com'
+ email = "sokrates@example.com"
processed_list = WhitelistEmailBackend.whitify_mail_addresses(mail_address_list=[email])
self.assertEqual(len(processed_list), 0)
def test_process_recipients_regular(self):
mail = EmailMultiAlternatives(
- 'Test subject', 'Here is the message.', 'from@example.com', ['to@example.com'], connection=None
+ "Test subject", "Here is the message.", "from@example.com", ["to@example.com"], connection=None
)
backend = WhitelistEmailBackend()
message_list = backend._process_recipients([mail])
self.assertEqual(len(message_list), 1)
- self.assertEqual(message_list[0].to, ['to_example.com@testuser.valid.domain'])
+ self.assertEqual(message_list[0].to, ["to_example.com@testuser.valid.domain"])
@mock.patch.object(EmailBackend, "send_messages")
@mock.patch.object(WhitelistEmailBackend, "_process_recipients")
diff --git a/tests/view_layer/test_formset_mixins.py b/tests/view_layer/test_formset_mixins.py
index f6d41ff..9e2792b 100644
--- a/tests/view_layer/test_formset_mixins.py
+++ b/tests/view_layer/test_formset_mixins.py
@@ -9,7 +9,7 @@
class ForeignKeyRelatedModelForm(forms.ModelForm):
class Meta:
model = ForeignKeyRelatedModel
- fields = ('single_signal',)
+ fields = ("single_signal",)
class MySingleSignalModelFormset(CountChildrenFormsetMixin, BaseInlineFormSet):
@@ -47,10 +47,10 @@ def test_regular_with_data(self):
)
formset = formset_class(
- {'fkrm-INITIAL_FORMS': '2', 'fkrm-MIN_NUM_FORMS': '2', 'fkrm-MAX_NUM_FORMS': '3', 'fkrm-TOTAL_FORMS': '2'},
+ {"fkrm-INITIAL_FORMS": "2", "fkrm-MIN_NUM_FORMS": "2", "fkrm-MAX_NUM_FORMS": "3", "fkrm-TOTAL_FORMS": "2"},
None,
instance=mssm,
- prefix='fkrm',
+ prefix="fkrm",
)
formset.is_valid()
diff --git a/tests/view_layer/test_htmx_response_mixin.py b/tests/view_layer/test_htmx_response_mixin.py
index b4389bf..49c26c4 100644
--- a/tests/view_layer/test_htmx_response_mixin.py
+++ b/tests/view_layer/test_htmx_response_mixin.py
@@ -8,37 +8,37 @@
class HtmxResponseMixinTest(RequestProviderMixin, TestCase):
class TestView(HtmxResponseMixin, generic.View):
- hx_redirect_url = 'https://my-url.com'
- hx_trigger = 'myEvent'
+ hx_redirect_url = "https://my-url.com"
+ hx_trigger = "myEvent"
class TestViewWithTriggerDict(HtmxResponseMixin, generic.View):
- hx_trigger = {'myEvent': None}
+ hx_trigger = {"myEvent": None}
def test_dispatch_functional(self):
view = self.TestView()
response = view.dispatch(request=self.get_request(user=AnonymousUser()))
- self.assertIn('HX-Redirect', response)
- self.assertEqual(response['HX-Redirect'], 'https://my-url.com')
+ self.assertIn("HX-Redirect", response)
+ self.assertEqual(response["HX-Redirect"], "https://my-url.com")
- self.assertIn('HX-Trigger', response)
- self.assertEqual(response['HX-Trigger'], 'myEvent')
+ self.assertIn("HX-Trigger", response)
+ self.assertEqual(response["HX-Trigger"], "myEvent")
def test_dispatch_trigger_with_dict(self):
view = self.TestViewWithTriggerDict()
response = view.dispatch(request=self.get_request(user=AnonymousUser()))
- self.assertIn('HX-Trigger', response)
- self.assertEqual(response['HX-Trigger'], "{\"myEvent\": null}")
+ self.assertIn("HX-Trigger", response)
+ self.assertEqual(response["HX-Trigger"], '{"myEvent": null}')
def test_get_hx_redirect_url_regular(self):
view = self.TestView()
- self.assertEqual(view.get_hx_redirect_url(), 'https://my-url.com')
+ self.assertEqual(view.get_hx_redirect_url(), "https://my-url.com")
def test_get_hx_trigger_regular(self):
view = self.TestView()
- self.assertEqual(view.get_hx_trigger(), 'myEvent')
+ self.assertEqual(view.get_hx_trigger(), "myEvent")
diff --git a/tests/view_layer/test_meta_mixins.py b/tests/view_layer/test_meta_mixins.py
index 08f44b3..50656c2 100644
--- a/tests/view_layer/test_meta_mixins.py
+++ b/tests/view_layer/test_meta_mixins.py
@@ -14,37 +14,37 @@ class TestViewNoPerms(DjangoPermissionRequiredMixin, generic.View):
pass
class TestViewSinglePerm(DjangoPermissionRequiredMixin, generic.View):
- permission_list = ['auth.change_user']
+ permission_list = ["auth.change_user"]
login_view_name = "other-login-view"
def get(self, *args, **kwargs):
return HttpResponse(status=200)
class TestViewMultiplePerms(DjangoPermissionRequiredMixin, generic.View):
- permission_list = ['auth.change_user', 'auth.add_user']
+ permission_list = ["auth.change_user", "auth.add_user"]
def get_login_url(self):
- return 'login/'
+ return "login/"
class TestDifferentLoginNameView(DjangoPermissionRequiredMixin, generic.View):
- permission_list = ['auth.change_user']
- login_view_name = 'other-login-view'
+ permission_list = ["auth.change_user"]
+ login_view_name = "other-login-view"
@classmethod
def setUpTestData(cls):
super().setUpTestData()
- cls.permission = Permission.objects.get_by_natural_key(app_label='auth', codename='change_user', model='user')
+ cls.permission = Permission.objects.get_by_natural_key(app_label="auth", codename="change_user", model="user")
def setUp(self) -> None:
super().setUp()
- self.user = User.objects.create(username='test_user', email='test.user@ambient-toolbox.com')
+ self.user = User.objects.create(username="test_user", email="test.user@ambient-toolbox.com")
def test_get_login_url(self):
- self.assertEqual(self.TestViewMultiplePerms().get_login_url(), 'login/')
+ self.assertEqual(self.TestViewMultiplePerms().get_login_url(), "login/")
def test_get_custom_login_url(self):
- self.assertEqual(self.TestDifferentLoginNameView().get_login_url(), '/other/login/')
+ self.assertEqual(self.TestDifferentLoginNameView().get_login_url(), "/other/login/")
def test_permissions_are_set_validation(self):
with self.assertRaises(RuntimeError):
diff --git a/tests/view_layer/test_views.py b/tests/view_layer/test_views.py
index 0f44b8e..faa4dba 100644
--- a/tests/view_layer/test_views.py
+++ b/tests/view_layer/test_views.py
@@ -10,19 +10,19 @@
class UserInFormKwargsMixinTest(RequestProviderMixin, TestCase):
def test_get_form_kwargs_regular(self):
- user = User(username='my-user')
+ user = User(username="my-user")
view = UserInFormKwargsMixinView()
view.request = self.get_request(user=user)
form_kwargs = view.get_form_kwargs()
- self.assertIn('user', form_kwargs)
- self.assertEqual(form_kwargs['user'], user)
+ self.assertIn("user", form_kwargs)
+ self.assertEqual(form_kwargs["user"], user)
class ToggleViewTest(RequestProviderMixin, TestCase):
def test_http_method_set_correctly(self):
- self.assertEqual(ToggleView.http_method_names, ('post',))
+ self.assertEqual(ToggleView.http_method_names, ("post",))
def test_post_raises_not_implemented_error(self):
with self.assertRaises(NotImplementedError):