🚨(backend) fix linting issues after upgrading

The last upgrades introduced some linting issues.
This commit fixes them.
This commit is contained in:
Anthony LC
2024-08-20 16:42:27 +02:00
committed by Anthony LC
parent 7babc46261
commit a970a83229
43 changed files with 93 additions and 41 deletions

View File

@@ -1,4 +1,5 @@
"""Admin classes and registrations for core app.""" """Admin classes and registrations for core app."""
from django.contrib import admin from django.contrib import admin
from django.contrib.auth import admin as auth_admin from django.contrib.auth import admin as auth_admin
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _

View File

@@ -1,4 +1,5 @@
"""Impress core API endpoints""" """Impress core API endpoints"""
from django.conf import settings from django.conf import settings
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@@ -16,9 +17,9 @@ def exception_handler(exc, context):
https://gist.github.com/twidi/9d55486c36b6a51bdcb05ce3a763e79f https://gist.github.com/twidi/9d55486c36b6a51bdcb05ce3a763e79f
""" """
if isinstance(exc, ValidationError): if isinstance(exc, ValidationError):
if hasattr(exc, "message_dict"): detail = exc.message_dict
detail = exc.message_dict
elif hasattr(exc, "message"): if hasattr(exc, "message"):
detail = exc.message detail = exc.message
elif hasattr(exc, "messages"): elif hasattr(exc, "messages"):
detail = exc.messages detail = exc.messages

View File

@@ -1,4 +1,5 @@
"""A JSONField for DRF to handle serialization/deserialization.""" """A JSONField for DRF to handle serialization/deserialization."""
import json import json
from rest_framework import serializers from rest_framework import serializers

View File

@@ -1,4 +1,5 @@
"""Permission handlers for the impress core app.""" """Permission handlers for the impress core app."""
from django.core import exceptions from django.core import exceptions
from rest_framework import permissions from rest_framework import permissions

View File

@@ -1,4 +1,5 @@
"""Client serializers for the impress core app.""" """Client serializers for the impress core app."""
from django.db.models import Q from django.db.models import Q
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _

View File

@@ -1,4 +1,5 @@
"""API endpoints""" """API endpoints"""
from django.contrib.postgres.aggregates import ArrayAgg from django.contrib.postgres.aggregates import ArrayAgg
from django.db.models import ( from django.db.models import (
OuterRef, OuterRef,

View File

@@ -1,6 +1,7 @@
""" """
Core application enums declaration Core application enums declaration
""" """
from django.conf import global_settings, settings from django.conf import global_settings, settings
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _

View File

@@ -2,6 +2,7 @@
""" """
Core application factories Core application factories
""" """
from django.conf import settings from django.conf import settings
from django.contrib.auth.hashers import make_password from django.contrib.auth.hashers import make_password

View File

@@ -1,6 +1,7 @@
""" """
Declare and configure the models for the impress core application Declare and configure the models for the impress core application
""" """
import hashlib import hashlib
import os import os
import tempfile import tempfile
@@ -316,6 +317,29 @@ class Document(BaseModel):
def __str__(self): def __str__(self):
return self.title return self.title
def save(self, *args, **kwargs):
"""Write content to object storage only if _content has changed."""
super().save(*args, **kwargs)
if self._content:
file_key = self.file_key
bytes_content = self._content.encode("utf-8")
if default_storage.exists(file_key):
response = default_storage.connection.meta.client.head_object(
Bucket=default_storage.bucket_name, Key=file_key
)
has_changed = (
response["ETag"].strip('"')
!= hashlib.md5(bytes_content).hexdigest() # noqa
)
else:
has_changed = True
if has_changed:
content_file = ContentFile(bytes_content)
default_storage.save(file_key, content_file)
@property @property
def key_base(self): def key_base(self):
"""Key base of the location where the document is stored in object storage.""" """Key base of the location where the document is stored in object storage."""
@@ -356,28 +380,6 @@ class Document(BaseModel):
Bucket=default_storage.bucket_name, Key=self.file_key, VersionId=version_id Bucket=default_storage.bucket_name, Key=self.file_key, VersionId=version_id
) )
def save(self, *args, **kwargs):
"""Write content to object storage only if _content has changed."""
super().save(*args, **kwargs)
if self._content:
file_key = self.file_key
bytes_content = self._content.encode("utf-8")
if default_storage.exists(file_key):
response = default_storage.connection.meta.client.head_object(
Bucket=default_storage.bucket_name, Key=file_key
)
has_changed = (
response["ETag"].strip('"')
!= hashlib.md5(bytes_content).hexdigest() # noqa
)
else:
has_changed = True
if has_changed:
content_file = ContentFile(bytes_content)
default_storage.save(file_key, content_file)
def get_versions_slice( def get_versions_slice(
self, from_version_id="", from_datetime=None, page_size=None self, from_version_id="", from_datetime=None, page_size=None
): ):

View File

@@ -92,9 +92,12 @@ def test_models_oidc_user_getter_invalid_token(django_assert_num_queries, monkey
monkeypatch.setattr(OIDCAuthenticationBackend, "get_userinfo", get_userinfo_mocked) monkeypatch.setattr(OIDCAuthenticationBackend, "get_userinfo", get_userinfo_mocked)
with django_assert_num_queries(0), pytest.raises( with (
SuspiciousOperation, django_assert_num_queries(0),
match="User info contained no recognizable user identification", pytest.raises(
SuspiciousOperation,
match="User info contained no recognizable user identification",
),
): ):
klass.get_or_create_user(access_token="test-token", id_token=None, payload=None) klass.get_or_create_user(access_token="test-token", id_token=None, payload=None)

View File

@@ -1,4 +1,5 @@
"""Fixtures for tests in the impress core application""" """Fixtures for tests in the impress core application"""
from unittest import mock from unittest import mock
import pytest import pytest

View File

@@ -1,6 +1,7 @@
""" """
Test document accesses API endpoints for users in impress's core app. Test document accesses API endpoints for users in impress's core app.
""" """
import random import random
from uuid import uuid4 from uuid import uuid4
@@ -67,6 +68,7 @@ def test_api_document_accesses_list_authenticated_related(via, mock_user_get_tea
client.force_login(user) client.force_login(user)
document = factories.DocumentFactory() document = factories.DocumentFactory()
user_access = None
if via == USER: if via == USER:
user_access = models.DocumentAccess.objects.create( user_access = models.DocumentAccess.objects.create(
document=document, document=document,
@@ -543,6 +545,7 @@ def test_api_document_accesses_update_owner_self(via, mock_user_get_teams):
client.force_login(user) client.force_login(user)
document = factories.DocumentFactory() document = factories.DocumentFactory()
access = None
if via == USER: if via == USER:
access = factories.UserDocumentAccessFactory( access = factories.UserDocumentAccessFactory(
document=document, user=user, role="owner" document=document, user=user, role="owner"
@@ -773,6 +776,7 @@ def test_api_document_accesses_delete_owners_last_owner(via, mock_user_get_teams
client.force_login(user) client.force_login(user)
document = factories.DocumentFactory() document = factories.DocumentFactory()
access = None
if via == USER: if via == USER:
access = factories.UserDocumentAccessFactory( access = factories.UserDocumentAccessFactory(
document=document, user=user, role="owner" document=document, user=user, role="owner"

View File

@@ -1,6 +1,7 @@
""" """
Test document accesses API endpoints for users in impress's core app. Test document accesses API endpoints for users in impress's core app.
""" """
import random import random
from django.core import mail from django.core import mail

View File

@@ -1,6 +1,7 @@
""" """
Unit tests for the Invitation model Unit tests for the Invitation model
""" """
import random import random
import time import time
@@ -250,7 +251,7 @@ def test_api_document_invitations__create__cannot_duplicate_invitation():
) )
assert response.status_code == status.HTTP_400_BAD_REQUEST assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.json()["__all__"] == [ assert response.json() == [
"Document invitation with this Email address and Document already exists." "Document invitation with this Email address and Document already exists."
] ]
@@ -278,9 +279,7 @@ def test_api_document_invitations__create__cannot_invite_existing_users():
) )
assert response.status_code == status.HTTP_400_BAD_REQUEST assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.json()["email"] == [ assert response.json() == ["This email is already associated to a registered user."]
"This email is already associated to a registered user."
]
def test_api_document_invitations__list__anonymous_user(): def test_api_document_invitations__list__anonymous_user():
@@ -567,8 +566,9 @@ def test_api_document_invitations__update__forbidden__not_authenticated(
client = APIClient() client = APIClient()
client.force_login(user) client.force_login(user)
url = f"/api/v1.0/documents/{invitation.document.id}/invitations/{invitation.id}/" url = f"/api/v1.0/documents/{invitation.document.id}/invitations/{invitation.id}/"
if method == "put":
response = client.put(url) response = client.put(url)
if method == "patch": if method == "patch":
response = client.patch(url) response = client.patch(url)

View File

@@ -1,6 +1,7 @@
""" """
Test document versions API endpoints for users in impress's core app. Test document versions API endpoints for users in impress's core app.
""" """
import random import random
import time import time

View File

@@ -1,6 +1,7 @@
""" """
Tests for Documents API endpoint in impress's core app: create Tests for Documents API endpoint in impress's core app: create
""" """
import uuid import uuid
import pytest import pytest

View File

@@ -1,6 +1,7 @@
""" """
Tests for Documents API endpoint in impress's core app: delete Tests for Documents API endpoint in impress's core app: delete
""" """
import random import random
import pytest import pytest

View File

@@ -1,6 +1,7 @@
""" """
Tests for Documents API endpoint in impress's core app: list Tests for Documents API endpoint in impress's core app: list
""" """
from unittest import mock from unittest import mock
import pytest import pytest

View File

@@ -1,6 +1,7 @@
""" """
Tests for Documents API endpoint in impress's core app: retrieve Tests for Documents API endpoint in impress's core app: retrieve
""" """
import pytest import pytest
from rest_framework.test import APIClient from rest_framework.test import APIClient
@@ -228,6 +229,8 @@ def test_api_documents_retrieve_authenticated_related_team_members(
factories.TeamDocumentAccessFactory() factories.TeamDocumentAccessFactory()
response = client.get(f"/api/v1.0/documents/{document.id!s}/") response = client.get(f"/api/v1.0/documents/{document.id!s}/")
# pylint: disable=R0801
assert response.status_code == 200 assert response.status_code == 200
content = response.json() content = response.json()
expected_abilities = { expected_abilities = {

View File

@@ -1,6 +1,7 @@
""" """
Tests for Documents API endpoint in impress's core app: update Tests for Documents API endpoint in impress's core app: update
""" """
import random import random
import pytest import pytest

View File

@@ -1,6 +1,7 @@
""" """
Test suite for generated openapi schema. Test suite for generated openapi schema.
""" """
import json import json
from io import StringIO from io import StringIO

View File

@@ -1,6 +1,7 @@
""" """
Tests for Templates API endpoint in impress's core app: create Tests for Templates API endpoint in impress's core app: create
""" """
import pytest import pytest
from rest_framework.test import APIClient from rest_framework.test import APIClient

View File

@@ -1,6 +1,7 @@
""" """
Tests for Templates API endpoint in impress's core app: delete Tests for Templates API endpoint in impress's core app: delete
""" """
import random import random
import pytest import pytest

View File

@@ -1,6 +1,7 @@
""" """
Test users API endpoints in the impress core app. Test users API endpoints in the impress core app.
""" """
import pytest import pytest
from rest_framework.test import APIClient from rest_framework.test import APIClient
@@ -97,7 +98,7 @@ def test_api_templates_generate_document_related(via, mock_user_get_teams):
client = APIClient() client = APIClient()
client.force_login(user) client.force_login(user)
access = None
if via == USER: if via == USER:
access = factories.UserTemplateAccessFactory(user=user) access = factories.UserTemplateAccessFactory(user=user)
elif via == TEAM: elif via == TEAM:

View File

@@ -1,6 +1,7 @@
""" """
Tests for Templates API endpoint in impress's core app: list Tests for Templates API endpoint in impress's core app: list
""" """
from unittest import mock from unittest import mock
import pytest import pytest

View File

@@ -1,6 +1,7 @@
""" """
Tests for Templates API endpoint in impress's core app: retrieve Tests for Templates API endpoint in impress's core app: retrieve
""" """
import pytest import pytest
from rest_framework.test import APIClient from rest_framework.test import APIClient

View File

@@ -1,6 +1,7 @@
""" """
Tests for Templates API endpoint in impress's core app: update Tests for Templates API endpoint in impress's core app: update
""" """
import random import random
import pytest import pytest

View File

@@ -1,6 +1,7 @@
""" """
Test template accesses API endpoints for users in impress's core app. Test template accesses API endpoints for users in impress's core app.
""" """
import random import random
from uuid import uuid4 from uuid import uuid4
@@ -67,6 +68,7 @@ def test_api_template_accesses_list_authenticated_related(via, mock_user_get_tea
client.force_login(user) client.force_login(user)
template = factories.TemplateFactory() template = factories.TemplateFactory()
user_access = None
if via == USER: if via == USER:
user_access = models.TemplateAccess.objects.create( user_access = models.TemplateAccess.objects.create(
template=template, template=template,
@@ -733,6 +735,7 @@ def test_api_template_accesses_update_owner_self(via, mock_user_get_teams):
client.force_login(user) client.force_login(user)
template = factories.TemplateFactory() template = factories.TemplateFactory()
access = None
if via == USER: if via == USER:
access = factories.UserTemplateAccessFactory( access = factories.UserTemplateAccessFactory(
template=template, user=user, role="owner" template=template, user=user, role="owner"
@@ -957,6 +960,7 @@ def test_api_template_accesses_delete_owners_last_owner(via, mock_user_get_teams
client.force_login(user) client.force_login(user)
template = factories.TemplateFactory() template = factories.TemplateFactory()
access = None
if via == USER: if via == USER:
access = factories.UserTemplateAccessFactory( access = factories.UserTemplateAccessFactory(
template=template, user=user, role="owner" template=template, user=user, role="owner"

View File

@@ -1,6 +1,7 @@
""" """
Test users API endpoints in the impress core app. Test users API endpoints in the impress core app.
""" """
import pytest import pytest
from rest_framework.test import APIClient from rest_framework.test import APIClient

View File

@@ -1,6 +1,7 @@
""" """
Unit tests for the DocumentAccess model Unit tests for the DocumentAccess model
""" """
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@@ -318,7 +319,7 @@ def test_models_document_access_get_abilities_for_editor_of_administrator():
def test_models_document_access_get_abilities_for_editor_of_editor_user( def test_models_document_access_get_abilities_for_editor_of_editor_user(
django_assert_num_queries django_assert_num_queries,
): ):
"""Check abilities of editor access for the editor of a document.""" """Check abilities of editor access for the editor of a document."""
access = factories.UserDocumentAccessFactory(role="editor") access = factories.UserDocumentAccessFactory(role="editor")
@@ -377,7 +378,7 @@ def test_models_document_access_get_abilities_for_reader_of_administrator():
def test_models_document_access_get_abilities_for_reader_of_reader_user( def test_models_document_access_get_abilities_for_reader_of_reader_user(
django_assert_num_queries django_assert_num_queries,
): ):
"""Check abilities of reader access for the reader of a document.""" """Check abilities of reader access for the reader of a document."""
access = factories.UserDocumentAccessFactory(role="reader") access = factories.UserDocumentAccessFactory(role="reader")

View File

@@ -1,6 +1,7 @@
""" """
Unit tests for the Document model Unit tests for the Document model
""" """
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.core.files.storage import default_storage from django.core.files.storage import default_storage

View File

@@ -1,6 +1,7 @@
""" """
Unit tests for the Invitation model Unit tests for the Invitation model
""" """
import time import time
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser

View File

@@ -1,6 +1,7 @@
""" """
Unit tests for the TemplateAccess model Unit tests for the TemplateAccess model
""" """
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@@ -318,7 +319,7 @@ def test_models_template_access_get_abilities_for_editor_of_administrator():
def test_models_template_access_get_abilities_for_editor_of_editor_user( def test_models_template_access_get_abilities_for_editor_of_editor_user(
django_assert_num_queries django_assert_num_queries,
): ):
"""Check abilities of editor access for the editor of a template.""" """Check abilities of editor access for the editor of a template."""
access = factories.UserTemplateAccessFactory(role="editor") access = factories.UserTemplateAccessFactory(role="editor")
@@ -377,7 +378,7 @@ def test_models_template_access_get_abilities_for_reader_of_administrator():
def test_models_template_access_get_abilities_for_reader_of_reader_user( def test_models_template_access_get_abilities_for_reader_of_reader_user(
django_assert_num_queries django_assert_num_queries,
): ):
"""Check abilities of reader access for the reader of a template.""" """Check abilities of reader access for the reader of a template."""
access = factories.UserTemplateAccessFactory(role="reader") access = factories.UserTemplateAccessFactory(role="reader")

View File

@@ -1,6 +1,7 @@
""" """
Unit tests for the Template model Unit tests for the Template model
""" """
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError

View File

@@ -1,6 +1,7 @@
""" """
Unit tests for the User model Unit tests for the User model
""" """
from unittest import mock from unittest import mock
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError

View File

@@ -1,6 +1,7 @@
""" """
Unit tests for the Invitation model Unit tests for the Invitation model
""" """
import smtplib import smtplib
from logging import Logger from logging import Logger
from unittest import mock from unittest import mock

View File

@@ -1,4 +1,5 @@
"""URL configuration for the core app.""" """URL configuration for the core app."""
from django.conf import settings from django.conf import settings
from django.urls import include, path, re_path from django.urls import include, path, re_path

View File

@@ -1,6 +1,7 @@
""" """
Utilities for the core app. Utilities for the core app.
""" """
import smtplib import smtplib
from logging import getLogger from logging import getLogger

View File

@@ -1,4 +1,5 @@
"""Management user to create a superuser.""" """Management user to create a superuser."""
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand

View File

@@ -1,4 +1,5 @@
"""Impress celery configuration file.""" """Impress celery configuration file."""
import os import os
from celery import Celery from celery import Celery

View File

@@ -9,6 +9,7 @@ https://docs.djangoproject.com/en/3.1/topics/settings/
For the full list of settings and their values, see For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.1/ref/settings/ https://docs.djangoproject.com/en/3.1/ref/settings/
""" """
import json import json
import os import os

View File

@@ -2,6 +2,7 @@
""" """
impress's sandbox management script. impress's sandbox management script.
""" """
import os import os
import sys import sys

View File

@@ -100,11 +100,11 @@ exclude = [
"__pycache__", "__pycache__",
"*/migrations/*", "*/migrations/*",
] ]
ignore= ["DJ001", "PLR2004"]
line-length = 88 line-length = 88
[tool.ruff.lint] [tool.ruff.lint]
ignore = ["DJ001", "PLR2004"]
select = [ select = [
"B", # flake8-bugbear "B", # flake8-bugbear
"BLE", # flake8-blind-except "BLE", # flake8-blind-except
@@ -126,7 +126,7 @@ select = [
section-order = ["future","standard-library","django","third-party","impress","first-party","local-folder"] section-order = ["future","standard-library","django","third-party","impress","first-party","local-folder"]
sections = { impress=["core"], django=["django"] } sections = { impress=["core"], django=["django"] }
[tool.ruff.per-file-ignores] [tool.ruff.lint.per-file-ignores]
"**/tests/*" = ["S", "SLF"] "**/tests/*" = ["S", "SLF"]
[tool.pytest.ini_options] [tool.pytest.ini_options]