mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-09-21 08:58:31 +00:00
Chore: Share the API client fixtures and build test users cheaply
This commit is contained in:
@@ -15,7 +15,9 @@ if TYPE_CHECKING:
|
||||
from collections.abc import Generator
|
||||
from pathlib import Path
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from pytest_django.fixtures import Settings
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from paperless_testing.dirs import PaperlessDirs
|
||||
|
||||
@@ -82,3 +84,43 @@ def paperless_dirs(
|
||||
reset_backend()
|
||||
yield dirs
|
||||
reset_backend()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def rest_api_client() -> APIClient:
|
||||
"""The basic DRF APIClient, unauthenticated."""
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
return APIClient()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def regular_user(db: None) -> User:
|
||||
"""Unprivileged user for permission boundary tests."""
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
return UserFactory(username="regular")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def admin_client(rest_api_client: APIClient, admin_user: User) -> APIClient:
|
||||
"""Admin client pre-authenticated and sending the v10 Accept header."""
|
||||
rest_api_client.force_authenticate(user=admin_user)
|
||||
rest_api_client.credentials(HTTP_ACCEPT="application/json; version=10")
|
||||
return rest_api_client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def v9_client(rest_api_client: APIClient, admin_user: User) -> APIClient:
|
||||
"""Admin client pre-authenticated and sending the v9 Accept header."""
|
||||
rest_api_client.force_authenticate(user=admin_user)
|
||||
rest_api_client.credentials(HTTP_ACCEPT="application/json; version=9")
|
||||
return rest_api_client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def user_client(rest_api_client: APIClient, regular_user: User) -> APIClient:
|
||||
"""Regular-user client pre-authenticated and sending the v10 Accept header."""
|
||||
rest_api_client.force_authenticate(user=regular_user)
|
||||
rest_api_client.credentials(HTTP_ACCEPT="application/json; version=10")
|
||||
return rest_api_client
|
||||
|
||||
@@ -5,14 +5,10 @@ from typing import TYPE_CHECKING
|
||||
|
||||
import filelock
|
||||
import pytest
|
||||
from django.contrib.auth import get_user_model
|
||||
from pytest_django.fixtures import Settings
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from paperless_testing.factories import DocumentFactory
|
||||
|
||||
UserModelT = get_user_model()
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from documents.models import Document
|
||||
from paperless_testing.dirs import PaperlessDirs
|
||||
@@ -76,44 +72,6 @@ def _search_index(
|
||||
reset_backend()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def rest_api_client():
|
||||
"""
|
||||
The basic DRF ApiClient
|
||||
"""
|
||||
yield APIClient()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def regular_user(django_user_model: type[UserModelT]) -> UserModelT:
|
||||
"""Unprivileged authenticated user for permission boundary tests."""
|
||||
return django_user_model.objects.create_user(username="regular", password="regular")
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def admin_client(rest_api_client: APIClient, admin_user: UserModelT) -> APIClient:
|
||||
"""Admin client pre-authenticated and sending the v10 Accept header."""
|
||||
rest_api_client.force_authenticate(user=admin_user)
|
||||
rest_api_client.credentials(HTTP_ACCEPT="application/json; version=10")
|
||||
return rest_api_client
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def v9_client(rest_api_client: APIClient, admin_user: UserModelT) -> APIClient:
|
||||
"""Admin client pre-authenticated and sending the v9 Accept header."""
|
||||
rest_api_client.force_authenticate(user=admin_user)
|
||||
rest_api_client.credentials(HTTP_ACCEPT="application/json; version=9")
|
||||
return rest_api_client
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def user_client(rest_api_client: APIClient, regular_user: UserModelT) -> APIClient:
|
||||
"""Regular-user client pre-authenticated and sending the v10 Accept header."""
|
||||
rest_api_client.force_authenticate(user=regular_user)
|
||||
rest_api_client.credentials(HTTP_ACCEPT="application/json; version=10")
|
||||
return rest_api_client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def indexed_document(_search_index: None) -> "Document":
|
||||
"""One searchable document, for tests about what the search endpoint
|
||||
|
||||
@@ -14,7 +14,6 @@ from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
import time_machine
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from documents.models import CustomField
|
||||
from documents.models import CustomFieldInstance
|
||||
@@ -23,6 +22,7 @@ from documents.models import Note
|
||||
from documents.models import StoragePath
|
||||
from documents.search._query import parse_user_query
|
||||
from paperless_testing.factories import DocumentFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
@@ -148,7 +148,7 @@ class TestJsonSubpaths:
|
||||
THEN:
|
||||
- Only the document with alice's note matches
|
||||
"""
|
||||
alice = User.objects.create_user(username="alice")
|
||||
alice = UserFactory(username="alice")
|
||||
doc_with_note = DocumentFactory(
|
||||
title="Has note",
|
||||
content="x",
|
||||
|
||||
@@ -3,7 +3,6 @@ from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import connection
|
||||
from django.test.utils import CaptureQueriesContext
|
||||
from guardian.shortcuts import assign_perm
|
||||
@@ -763,8 +762,8 @@ class TestSearchIds:
|
||||
|
||||
def test_respects_permission_filter(self, backend: TantivyBackend) -> None:
|
||||
"""search_ids must respect user permission filtering."""
|
||||
owner = User.objects.create_user("ids_owner")
|
||||
other = User.objects.create_user("ids_other")
|
||||
owner = UserFactory(username="ids_owner")
|
||||
other = UserFactory(username="ids_other")
|
||||
doc = Document.objects.create(
|
||||
title="private doc",
|
||||
content="secret keyword",
|
||||
@@ -1071,7 +1070,7 @@ class TestFieldHandling:
|
||||
|
||||
def test_notes_include_user_information(self, backend: TantivyBackend) -> None:
|
||||
"""Notes must be indexed with user information when available for structured queries."""
|
||||
user = User.objects.create_user("notewriter")
|
||||
user = UserFactory(username="notewriter")
|
||||
doc = Document.objects.create(
|
||||
title="Doc with notes",
|
||||
content="test",
|
||||
@@ -1173,7 +1172,7 @@ class TestHighlightHits:
|
||||
notes.note: prefix so the query targets notes content directly, but
|
||||
the snippet is generated from notes_text which stores the same text.
|
||||
"""
|
||||
user = User.objects.create_user("hl_noteuser")
|
||||
user = UserFactory(username="hl_noteuser")
|
||||
doc = Document.objects.create(
|
||||
title="Doc with matching note",
|
||||
content="unrelated content",
|
||||
|
||||
@@ -17,12 +17,12 @@ from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from documents.models import CustomField
|
||||
from documents.models import CustomFieldInstance
|
||||
from documents.models import Note
|
||||
from paperless_testing.factories import DocumentFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Callable
|
||||
@@ -53,7 +53,7 @@ class TestBareJsonFieldPrefixes:
|
||||
decoy's content match does not resurface through a demoted
|
||||
text search
|
||||
"""
|
||||
alice = User.objects.create_user(username="alice")
|
||||
alice = UserFactory(username="alice")
|
||||
with_note = DocumentFactory(title="Has note", content="x")
|
||||
Note.objects.create(document=with_note, user=alice, note="crocodile")
|
||||
backend.add_or_update(with_note)
|
||||
@@ -116,7 +116,7 @@ class TestBareJsonFieldPrefixes:
|
||||
document; the default-subpath resolution for the bare
|
||||
prefix does not interfere with explicit subpath addressing
|
||||
"""
|
||||
bob = User.objects.create_user(username="bob")
|
||||
bob = UserFactory(username="bob")
|
||||
doc = DocumentFactory(title="Bob note", content="x")
|
||||
Note.objects.create(document=doc, user=bob, note="remark")
|
||||
backend.add_or_update(doc)
|
||||
|
||||
@@ -20,7 +20,6 @@ from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
import tantivy
|
||||
from django.contrib.auth.models import User
|
||||
from whoosh_compat import FieldKind
|
||||
|
||||
from documents.models import CustomField
|
||||
@@ -28,6 +27,7 @@ from documents.models import CustomFieldInstance
|
||||
from documents.models import Document
|
||||
from documents.models import Note
|
||||
from documents.search._fields import PUBLIC_FIELDS
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from documents.search._backend import TantivyBackend
|
||||
@@ -49,7 +49,7 @@ class TestJsonSubpathsAreWrittenAtIndexTime:
|
||||
- Every subpath PUBLIC_FIELDS declares for notes/custom_fields
|
||||
is present as a key in the document's stored JSON payload
|
||||
"""
|
||||
user = User.objects.create_user(username="completeness-user")
|
||||
user = UserFactory(username="completeness-user")
|
||||
field = CustomField.objects.create(
|
||||
name="Completeness Field",
|
||||
data_type=CustomField.FieldDataType.STRING,
|
||||
|
||||
@@ -25,6 +25,7 @@ from documents.models import Document
|
||||
from documents.models import DocumentType
|
||||
from documents.models import StoragePath
|
||||
from documents.models import Tag
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from documents.search._backend import TantivyBackend
|
||||
@@ -34,22 +35,22 @@ pytestmark = [pytest.mark.search, pytest.mark.django_db]
|
||||
|
||||
@pytest.fixture
|
||||
def owner() -> User:
|
||||
return User.objects.create_user(username="owner")
|
||||
return UserFactory(username="owner")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def stranger() -> User:
|
||||
return User.objects.create_user(username="stranger")
|
||||
return UserFactory(username="stranger")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def viewer() -> User:
|
||||
return User.objects.create_user(username="viewer")
|
||||
return UserFactory(username="viewer")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def group_member() -> User:
|
||||
user = User.objects.create_user(username="group_member")
|
||||
user = UserFactory(username="group_member")
|
||||
user.groups.add(Group.objects.create(name="accounting"))
|
||||
return user
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ from io import BytesIO
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.test import override_settings
|
||||
from PIL import Image
|
||||
@@ -15,6 +14,7 @@ from documents.tests.utils import read_streaming_response
|
||||
from paperless.models import ApplicationConfiguration
|
||||
from paperless.models import ColorConvertChoices
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestApiAppConfig(DirectoriesMixin, APITestCase):
|
||||
@@ -23,7 +23,7 @@ class TestApiAppConfig(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
user = User.objects.create_superuser(username="temp_admin")
|
||||
user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
def test_api_get_config(self) -> None:
|
||||
@@ -267,7 +267,7 @@ class TestApiAppConfig(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- old app_logo file is deleted
|
||||
"""
|
||||
admin = User.objects.create_superuser(username="admin")
|
||||
admin = UserFactory(username="admin", superuser=True)
|
||||
self.client.force_login(user=admin)
|
||||
response = self.client.get("/logo/")
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@@ -5,7 +5,6 @@ import shutil
|
||||
import zipfile
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import override_settings
|
||||
from django.utils import timezone
|
||||
from rest_framework import status
|
||||
@@ -17,6 +16,7 @@ from documents.models import DocumentType
|
||||
from documents.tests.utils import SampleDirMixin
|
||||
from documents.tests.utils import read_streaming_response
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestBulkDownload(DirectoriesMixin, SampleDirMixin, APITestCase):
|
||||
@@ -25,7 +25,7 @@ class TestBulkDownload(DirectoriesMixin, SampleDirMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
self.doc1 = Document.objects.create(title="unrelated", checksum="A")
|
||||
@@ -326,7 +326,7 @@ class TestBulkDownload(DirectoriesMixin, SampleDirMixin, APITestCase):
|
||||
)
|
||||
|
||||
def test_download_insufficient_permissions(self) -> None:
|
||||
user = User.objects.create_user(username="temp_user")
|
||||
user = UserFactory(username="temp_user")
|
||||
user.user_permissions.add(
|
||||
Permission.objects.get(codename="view_document"),
|
||||
)
|
||||
|
||||
@@ -16,13 +16,14 @@ from documents.models import DocumentType
|
||||
from documents.models import StoragePath
|
||||
from documents.models import Tag
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestBulkEditAPI(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
user = User.objects.create_superuser(username="temp_admin")
|
||||
user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.user = user
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
@@ -284,9 +285,9 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase):
|
||||
m,
|
||||
) -> None:
|
||||
self.setup_mock(m, "modify_custom_fields")
|
||||
user = User.objects.create_user(username="doc-owner")
|
||||
user = UserFactory(username="doc-owner")
|
||||
user.user_permissions.add(Permission.objects.get(codename="change_document"))
|
||||
other_user = User.objects.create_user(username="other-user")
|
||||
other_user = UserFactory(username="other-user")
|
||||
source_doc = Document.objects.create(
|
||||
checksum="source",
|
||||
title="Source",
|
||||
@@ -787,7 +788,7 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase):
|
||||
@mock.patch("documents.serialisers.bulk_edit.set_storage_path")
|
||||
def test_api_bulk_edit_with_all_true_resolves_owned_duplicates(self, m) -> None:
|
||||
self.setup_mock(m, "set_storage_path")
|
||||
user = User.objects.create_user(username="duplicate-owner")
|
||||
user = UserFactory(username="duplicate-owner")
|
||||
user.user_permissions.add(
|
||||
Permission.objects.get(codename="change_document"),
|
||||
)
|
||||
@@ -1919,7 +1920,7 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase):
|
||||
@mock.patch("documents.views.bulk_edit.merge")
|
||||
def test_merge_and_delete_requires_change_permission(self, m) -> None:
|
||||
self.setup_mock(m, "merge")
|
||||
user = User.objects.create_user(username="no-change")
|
||||
user = UserFactory(username="no-change")
|
||||
user.user_permissions.add(
|
||||
Permission.objects.get(codename="add_document"),
|
||||
Permission.objects.get(codename="delete_document"),
|
||||
@@ -2345,7 +2346,7 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase):
|
||||
@mock.patch("documents.views.bulk_edit.edit_pdf")
|
||||
def test_edit_pdf_update_requires_change_permission(self, m) -> None:
|
||||
self.setup_mock(m, "edit_pdf")
|
||||
user = User.objects.create_user(username="no-change")
|
||||
user = UserFactory(username="no-change")
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
response = self.client.post(
|
||||
@@ -2372,7 +2373,7 @@ class TestBulkEditAPI(DirectoriesMixin, APITestCase):
|
||||
) -> None:
|
||||
self.setup_mock(edit_pdf_mock, "edit_pdf")
|
||||
self.setup_mock(remove_password_mock, "remove_password")
|
||||
user = User.objects.create_user(username="no-delete")
|
||||
user = UserFactory(username="no-delete")
|
||||
user.user_permissions.add(
|
||||
Permission.objects.get(codename="add_document"),
|
||||
Permission.objects.get(codename="change_document"),
|
||||
|
||||
@@ -10,6 +10,8 @@ from rest_framework import status
|
||||
from rest_framework.test import APIClient
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
@@ -17,7 +19,7 @@ if TYPE_CHECKING:
|
||||
class TestChatStreamingViewInputValidation(APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
def _mock_ai_enabled(self) -> mock.MagicMock:
|
||||
|
||||
@@ -4,7 +4,6 @@ from unittest import mock
|
||||
from unittest.mock import ANY
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import override_settings
|
||||
from guardian.shortcuts import assign_perm
|
||||
from rest_framework import status
|
||||
@@ -14,13 +13,14 @@ from documents.models import CustomField
|
||||
from documents.models import CustomFieldInstance
|
||||
from documents.models import Document
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestCustomFieldsAPI(DirectoriesMixin, APITestCase):
|
||||
ENDPOINT = "/api/custom_fields/"
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
return super().setUp()
|
||||
|
||||
@@ -1174,11 +1174,11 @@ class TestCustomFieldsAPI(DirectoriesMixin, APITestCase):
|
||||
def test_documentlink_patch_requires_change_permission_on_target_documents(
|
||||
self,
|
||||
) -> None:
|
||||
source_owner = User.objects.create_user(username="source-owner")
|
||||
source_owner = UserFactory(username="source-owner")
|
||||
source_owner.user_permissions.add(
|
||||
Permission.objects.get(codename="change_document"),
|
||||
)
|
||||
other_user = User.objects.create_user(username="other-user")
|
||||
other_user = UserFactory(username="other-user")
|
||||
|
||||
source_doc = Document.objects.create(
|
||||
title="Source",
|
||||
@@ -1221,11 +1221,11 @@ class TestCustomFieldsAPI(DirectoriesMixin, APITestCase):
|
||||
def test_documentlink_patch_allowed_with_change_permission_on_target_documents(
|
||||
self,
|
||||
) -> None:
|
||||
source_owner = User.objects.create_user(username="source-owner")
|
||||
source_owner = UserFactory(username="source-owner")
|
||||
source_owner.user_permissions.add(
|
||||
Permission.objects.get(codename="change_document"),
|
||||
)
|
||||
other_user = User.objects.create_user(username="other-user")
|
||||
other_user = UserFactory(username="other-user")
|
||||
|
||||
source_doc = Document.objects.create(
|
||||
title="Source",
|
||||
@@ -1337,7 +1337,7 @@ class TestCustomFieldsAPI(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(results[0]["document_count"], 1)
|
||||
|
||||
# Test as user without access to the document
|
||||
non_superuser = User.objects.create_user(username="non_superuser")
|
||||
non_superuser = UserFactory(username="non_superuser")
|
||||
non_superuser.user_permissions.add(
|
||||
*Permission.objects.exclude(codename="view_global_statistics"),
|
||||
)
|
||||
|
||||
@@ -6,7 +6,6 @@ from unittest import mock
|
||||
|
||||
from auditlog.models import LogEntry # type: ignore[import-untyped]
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.test import TestCase as DjangoTestCase
|
||||
@@ -22,6 +21,7 @@ from documents.tests.utils import read_streaming_response
|
||||
from documents.versioning import annotate_effective_content
|
||||
from documents.views import DocumentSelectionMixin
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pathlib import Path
|
||||
@@ -31,7 +31,7 @@ class TestDocumentVersioningApi(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
def _make_pdf_upload(self, name: str = "version.pdf") -> SimpleUploadedFile:
|
||||
@@ -89,8 +89,8 @@ class TestDocumentVersioningApi(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_root_endpoint_returns_403_when_user_lacks_permission(self) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
viewer = User.objects.create_user(username="viewer")
|
||||
owner = UserFactory(username="owner")
|
||||
viewer = UserFactory(username="viewer")
|
||||
viewer.user_permissions.add(
|
||||
Permission.objects.get(codename="view_document"),
|
||||
)
|
||||
@@ -283,8 +283,8 @@ class TestDocumentVersioningApi(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(mock_backend.add_or_update.call_args[0][0].id, root.id)
|
||||
|
||||
def test_delete_version_returns_403_without_permission(self) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
other = User.objects.create_user(username="other")
|
||||
owner = UserFactory(username="owner")
|
||||
other = UserFactory(username="other")
|
||||
other.user_permissions.add(
|
||||
Permission.objects.get(codename="delete_document"),
|
||||
)
|
||||
@@ -371,8 +371,8 @@ class TestDocumentVersioningApi(DirectoriesMixin, APITestCase):
|
||||
self.assertTrue(resp.data["is_root"])
|
||||
|
||||
def test_update_version_label_returns_403_without_permission(self) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
other = User.objects.create_user(username="other")
|
||||
owner = UserFactory(username="owner")
|
||||
other = UserFactory(username="other")
|
||||
other.user_permissions.add(
|
||||
Permission.objects.get(codename="change_document"),
|
||||
)
|
||||
@@ -553,8 +553,8 @@ class TestDocumentVersioningApi(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
def test_metadata_returns_403_when_user_lacks_permission(self) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
other = User.objects.create_user(username="other")
|
||||
owner = UserFactory(username="owner")
|
||||
other = UserFactory(username="other")
|
||||
other.user_permissions.add(
|
||||
Permission.objects.get(codename="view_document"),
|
||||
)
|
||||
@@ -653,8 +653,8 @@ class TestDocumentVersioningApi(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(resp.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
def test_update_version_returns_403_without_permission(self) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
other = User.objects.create_user(username="other")
|
||||
owner = UserFactory(username="owner")
|
||||
other = UserFactory(username="other")
|
||||
root = Document.objects.create(
|
||||
title="root",
|
||||
checksum="root",
|
||||
@@ -672,7 +672,7 @@ class TestDocumentVersioningApi(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(resp.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
def test_update_version_requires_global_change_permission(self) -> None:
|
||||
user = User.objects.create_user(username="add-only")
|
||||
user = UserFactory(username="add-only")
|
||||
user.user_permissions.add(Permission.objects.get(codename="add_document"))
|
||||
root = Document.objects.create(
|
||||
title="root",
|
||||
@@ -978,7 +978,7 @@ class TestVersionAwareFilters(DjangoTestCase):
|
||||
superseded content -- selecting documents the list view, filtered by
|
||||
the same term, does not show.
|
||||
"""
|
||||
user = User.objects.create_superuser(username="bulk_selection")
|
||||
user = UserFactory(username="bulk_selection", superuser=True)
|
||||
|
||||
selected = DocumentSelectionMixin()._resolve_document_ids(
|
||||
user=user,
|
||||
@@ -1005,7 +1005,7 @@ class TestBulkSelectionExcludesVersions(DjangoTestCase):
|
||||
"Select all matching" reconstructs the document list, which never
|
||||
contains version documents as rows of their own.
|
||||
"""
|
||||
user = User.objects.create_superuser(username="bulk_versions")
|
||||
user = UserFactory(username="bulk_versions", superuser=True)
|
||||
root = Document.objects.create(
|
||||
title="shared-title root",
|
||||
checksum="bulk-root",
|
||||
|
||||
@@ -53,13 +53,14 @@ from documents.tests.utils import read_streaming_response
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import DocumentFactory
|
||||
from paperless_testing.factories import TagFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
cache.clear()
|
||||
|
||||
@@ -357,8 +358,8 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
with Path(filename).open("wb") as f:
|
||||
f.write(content)
|
||||
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user2 = User.objects.create_user(username="test2")
|
||||
user1 = UserFactory(username="test1")
|
||||
user2 = UserFactory(username="test2")
|
||||
user1.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
user2.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
|
||||
@@ -760,7 +761,7 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
- History is returned
|
||||
"""
|
||||
# No auditlog permissions
|
||||
user = User.objects.create_user(username="test")
|
||||
user = UserFactory(username="test")
|
||||
user.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
self.client.force_authenticate(user=user)
|
||||
doc = Document.objects.create(
|
||||
@@ -776,7 +777,7 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
# superuser
|
||||
user.is_superuser = True
|
||||
user.save()
|
||||
user2 = User.objects.create_user(username="test2")
|
||||
user2 = UserFactory(username="test2")
|
||||
doc2 = Document.objects.create(
|
||||
title="Second title",
|
||||
checksum="456",
|
||||
@@ -1073,8 +1074,8 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
self.assertEqual(response.data["duplicate_documents"], [])
|
||||
|
||||
def test_has_duplicates_filter_respects_document_permissions(self) -> None:
|
||||
owner = User.objects.create_user(username="duplicate-owner")
|
||||
requester = User.objects.create_user(username="duplicate-requester")
|
||||
owner = UserFactory(username="duplicate-owner")
|
||||
requester = UserFactory(username="duplicate-requester")
|
||||
requester.user_permissions.add(
|
||||
Permission.objects.get(codename="view_document"),
|
||||
)
|
||||
@@ -1317,8 +1318,8 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
THEN:
|
||||
- Owner filters work correctly but still respect permissions
|
||||
"""
|
||||
u1 = User.objects.create_user("user1")
|
||||
u2 = User.objects.create_user("user2")
|
||||
u1 = UserFactory(username="user1")
|
||||
u2 = UserFactory(username="user2")
|
||||
u1.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
u2.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
|
||||
@@ -1424,7 +1425,7 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
- The document is returned exactly once, not once per permission path
|
||||
(regression test for https://github.com/paperless-ngx/paperless-ngx/issues/13331)
|
||||
"""
|
||||
user = User.objects.create_user("user1")
|
||||
user = UserFactory(username="user1")
|
||||
user.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
group = Group.objects.create(name="group1")
|
||||
user.groups.add(group)
|
||||
@@ -1452,8 +1453,8 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
THEN:
|
||||
- The document does not appear in their results
|
||||
"""
|
||||
owner = User.objects.create_user("owner1")
|
||||
stranger = User.objects.create_user("stranger1")
|
||||
owner = UserFactory(username="owner1")
|
||||
stranger = UserFactory(username="stranger1")
|
||||
stranger.user_permissions.add(
|
||||
*Permission.objects.filter(codename="view_document"),
|
||||
)
|
||||
@@ -1474,9 +1475,9 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
THEN:
|
||||
- Only the group member sees the document
|
||||
"""
|
||||
owner = User.objects.create_user("owner2")
|
||||
member = User.objects.create_user("member1")
|
||||
non_member = User.objects.create_user("nonmember1")
|
||||
owner = UserFactory(username="owner2")
|
||||
member = UserFactory(username="member1")
|
||||
non_member = UserFactory(username="nonmember1")
|
||||
for u in (member, non_member):
|
||||
u.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
|
||||
@@ -1785,8 +1786,8 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
THEN:
|
||||
- Statistics only include inbox counts for tags accessible by the user
|
||||
"""
|
||||
u1 = User.objects.create_user("user1")
|
||||
u2 = User.objects.create_user("user2")
|
||||
u1 = UserFactory(username="user1")
|
||||
u2 = UserFactory(username="user2")
|
||||
inbox_tag_u1 = Tag.objects.create(name="inbox_u1", is_inbox_tag=True, owner=u1)
|
||||
Tag.objects.create(name="inbox_u2", is_inbox_tag=True, owner=u2)
|
||||
doc_u1 = Document.objects.create(
|
||||
@@ -1816,8 +1817,8 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
self.assertEqual(response.data["documents_inbox"], 0)
|
||||
|
||||
def test_statistics_with_statistics_permission(self) -> None:
|
||||
owner = User.objects.create_user("owner")
|
||||
stats_user = User.objects.create_user("stats-user")
|
||||
owner = UserFactory(username="owner")
|
||||
stats_user = UserFactory(username="stats-user")
|
||||
stats_user.user_permissions.add(
|
||||
Permission.objects.get(codename="view_global_statistics"),
|
||||
)
|
||||
@@ -1986,7 +1987,7 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)
|
||||
|
||||
def test_upload_insufficient_permissions(self) -> None:
|
||||
self.client.force_authenticate(user=User.objects.create_user("testuser2"))
|
||||
self.client.force_authenticate(user=UserFactory(username="testuser2"))
|
||||
|
||||
with (Path(__file__).parent / "samples" / "simple.pdf").open("rb") as f:
|
||||
response = self.client.post(
|
||||
@@ -2782,9 +2783,9 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
mock_get_date_parser.assert_not_called()
|
||||
|
||||
def test_saved_views(self) -> None:
|
||||
u1 = User.objects.create_user("user1")
|
||||
u2 = User.objects.create_user("user2")
|
||||
u3 = User.objects.create_user("user3")
|
||||
u1 = UserFactory(username="user1")
|
||||
u2 = UserFactory(username="user2")
|
||||
u3 = UserFactory(username="user3")
|
||||
|
||||
view_perm = Permission.objects.get(codename="view_savedview")
|
||||
change_perm = Permission.objects.get(codename="change_savedview")
|
||||
@@ -3064,7 +3065,7 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
self.assertListEqual(saved_view_settings["sidebar_views_visible_ids"], [v2.id])
|
||||
|
||||
def test_saved_view_create_update_patch(self) -> None:
|
||||
User.objects.create_user("user1")
|
||||
UserFactory(username="user1")
|
||||
|
||||
view = {
|
||||
"name": "test",
|
||||
@@ -3127,7 +3128,7 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
- Display options are updated
|
||||
- Display fields are validated
|
||||
"""
|
||||
User.objects.create_user("user1")
|
||||
UserFactory(username="user1")
|
||||
|
||||
view = {
|
||||
"name": "test",
|
||||
@@ -3568,11 +3569,11 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
THEN:
|
||||
- Notes are neither created nor deleted
|
||||
"""
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user1 = UserFactory(username="test1")
|
||||
user1.user_permissions.add(*Permission.objects.all())
|
||||
user1.save()
|
||||
|
||||
user2 = User.objects.create_user(username="test2")
|
||||
user2 = UserFactory(username="test2")
|
||||
user2.save()
|
||||
|
||||
doc = Document.objects.create(
|
||||
@@ -3616,7 +3617,7 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
def test_notes_require_global_document_permissions(self) -> None:
|
||||
user = User.objects.create_user(username="note_editor")
|
||||
user = UserFactory(username="note_editor")
|
||||
user.user_permissions.add(
|
||||
*Permission.objects.filter(
|
||||
codename__in=["view_note", "add_note", "delete_note"],
|
||||
@@ -3797,11 +3798,11 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
- Unique items are created
|
||||
- Non-unique items are not allowed
|
||||
"""
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user1 = UserFactory(username="test1")
|
||||
user1.user_permissions.add(*Permission.objects.filter(codename="add_tag"))
|
||||
user1.save()
|
||||
|
||||
user2 = User.objects.create_user(username="test2")
|
||||
user2 = UserFactory(username="test2")
|
||||
user2.user_permissions.add(*Permission.objects.filter(codename="add_tag"))
|
||||
user2.save()
|
||||
|
||||
@@ -3857,11 +3858,11 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
- Unique items are created
|
||||
- Non-unique items are not allowed on update
|
||||
"""
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user1 = UserFactory(username="test1")
|
||||
user1.user_permissions.add(*Permission.objects.filter(codename="change_tag"))
|
||||
user1.save()
|
||||
|
||||
user2 = User.objects.create_user(username="test2")
|
||||
user2 = UserFactory(username="test2")
|
||||
user2.user_permissions.add(*Permission.objects.filter(codename="change_tag"))
|
||||
user2.save()
|
||||
|
||||
@@ -3993,11 +3994,11 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
THEN:
|
||||
- Links only shown if user has permissions
|
||||
"""
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user1 = UserFactory(username="test1")
|
||||
user1.user_permissions.add(*Permission.objects.all())
|
||||
user1.save()
|
||||
|
||||
user2 = User.objects.create_user(username="test2")
|
||||
user2 = UserFactory(username="test2")
|
||||
user2.save()
|
||||
|
||||
doc = Document.objects.create(
|
||||
@@ -4034,11 +4035,11 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
THEN:
|
||||
- Share link creation is denied until view permission is granted
|
||||
"""
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user1 = UserFactory(username="test1")
|
||||
user1.user_permissions.add(*Permission.objects.filter(codename="add_sharelink"))
|
||||
user1.save()
|
||||
|
||||
user2 = User.objects.create_user(username="test2")
|
||||
user2 = UserFactory(username="test2")
|
||||
user2.save()
|
||||
|
||||
doc = Document.objects.create(
|
||||
@@ -4097,11 +4098,11 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
THEN:
|
||||
- ASN +1 from user2's doc is returned for user1
|
||||
"""
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user1 = UserFactory(username="test1")
|
||||
user1.user_permissions.add(*Permission.objects.all())
|
||||
user1.save()
|
||||
|
||||
user2 = User.objects.create_user(username="test2")
|
||||
user2 = UserFactory(username="test2")
|
||||
user2.save()
|
||||
|
||||
doc1 = Document.objects.create(
|
||||
@@ -4141,7 +4142,7 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
THEN:
|
||||
- ASN 1 is returned
|
||||
"""
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user1 = UserFactory(username="test1")
|
||||
user1.user_permissions.add(*Permission.objects.all())
|
||||
user1.save()
|
||||
|
||||
@@ -4170,7 +4171,7 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
THEN:
|
||||
- Explicit error is returned
|
||||
"""
|
||||
user1 = User.objects.create_superuser(username="test1")
|
||||
user1 = UserFactory(username="test1", superuser=True)
|
||||
|
||||
self.client.force_authenticate(user1)
|
||||
|
||||
@@ -4348,7 +4349,7 @@ class TestDocumentApi(DirectoriesMixin, ConsumeTaskMixin, APITestCase):
|
||||
THEN:
|
||||
- Error response is returned
|
||||
"""
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user1 = UserFactory(username="test1")
|
||||
user1.user_permissions.add(*Permission.objects.all())
|
||||
user1.save()
|
||||
|
||||
@@ -4454,7 +4455,7 @@ class TestDocumentApiTagColors(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
@@ -4534,7 +4535,7 @@ class TestDocumentApiCustomFieldsSorting(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
self.doc1 = Document.objects.create(
|
||||
|
||||
@@ -3,7 +3,6 @@ import shutil
|
||||
from unittest import mock
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.core import mail
|
||||
from django.test import override_settings
|
||||
from rest_framework import status
|
||||
@@ -12,6 +11,7 @@ from rest_framework.test import APITestCase
|
||||
from documents.models import Document
|
||||
from documents.tests.utils import SampleDirMixin
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestEmail(DirectoriesMixin, SampleDirMixin, APITestCase):
|
||||
@@ -20,7 +20,7 @@ class TestEmail(DirectoriesMixin, SampleDirMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
self.doc1 = Document.objects.create(
|
||||
@@ -303,7 +303,7 @@ class TestEmail(DirectoriesMixin, SampleDirMixin, APITestCase):
|
||||
THEN:
|
||||
- Forbidden response is returned
|
||||
"""
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user1 = UserFactory(username="test1")
|
||||
user1.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
|
||||
doc_owned = Document.objects.create(
|
||||
@@ -338,7 +338,7 @@ class TestEmail(DirectoriesMixin, SampleDirMixin, APITestCase):
|
||||
THEN:
|
||||
- Request succeeds
|
||||
"""
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user1 = UserFactory(username="test1")
|
||||
user1.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
|
||||
self.client.force_authenticate(user1)
|
||||
|
||||
@@ -4,7 +4,6 @@ from collections.abc import Callable
|
||||
from datetime import date
|
||||
from urllib.parse import quote
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from documents.models import CustomField
|
||||
@@ -14,6 +13,7 @@ from documents.models import SavedView
|
||||
from documents.models import SavedViewFilterRule
|
||||
from documents.serialisers import DocumentSerializer
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class DocumentWrapper:
|
||||
@@ -35,7 +35,7 @@ class TestCustomFieldsSearch(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
# Create one custom field per type. The fields are called f"{type}_field".
|
||||
|
||||
@@ -22,13 +22,14 @@ from documents.models import DocumentType
|
||||
from documents.models import StoragePath
|
||||
from documents.models import Tag
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestApiObjects(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
user = User.objects.create_superuser(username="temp_admin")
|
||||
user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
self.tag1 = Tag.objects.create(name="t1", is_inbox_tag=True)
|
||||
@@ -153,7 +154,7 @@ class TestApiObjects(DirectoriesMixin, APITestCase):
|
||||
|
||||
# A newer document owned by another user must not leak through the
|
||||
# aggregate for a non-superuser who cannot view it
|
||||
other = User.objects.create_user(username="other")
|
||||
other = UserFactory(username="other")
|
||||
Document.objects.create(
|
||||
mime_type="application/pdf",
|
||||
correspondent=self.c1,
|
||||
@@ -162,7 +163,7 @@ class TestApiObjects(DirectoriesMixin, APITestCase):
|
||||
owner=other,
|
||||
)
|
||||
|
||||
user = User.objects.create_user(username="regular")
|
||||
user = UserFactory(username="regular")
|
||||
user.user_permissions.add(
|
||||
Permission.objects.get(codename="view_correspondent"),
|
||||
)
|
||||
@@ -200,7 +201,7 @@ class TestApiStoragePaths(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
user = User.objects.create_superuser(username="temp_admin")
|
||||
user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
self.sp1 = StoragePath.objects.create(name="sp1", path="Something/{checksum}")
|
||||
@@ -455,8 +456,8 @@ class TestApiStoragePaths(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(response.data, "folder/Something.pdf")
|
||||
|
||||
def test_test_storage_path_requires_document_view_permission(self) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
unprivileged = User.objects.create_user(username="unprivileged")
|
||||
owner = UserFactory(username="owner")
|
||||
unprivileged = UserFactory(username="unprivileged")
|
||||
unprivileged.user_permissions.add(
|
||||
Permission.objects.get(codename="view_document"),
|
||||
)
|
||||
@@ -481,8 +482,8 @@ class TestApiStoragePaths(DirectoriesMixin, APITestCase):
|
||||
self.assertIn("document", response.data)
|
||||
|
||||
def test_test_storage_path_allows_shared_document_view_permission(self) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
viewer = User.objects.create_user(username="viewer")
|
||||
owner = UserFactory(username="owner")
|
||||
viewer = UserFactory(username="viewer")
|
||||
document = Document.objects.create(
|
||||
mime_type="application/pdf",
|
||||
owner=owner,
|
||||
@@ -545,7 +546,7 @@ class TestApiStoragePaths(DirectoriesMixin, APITestCase):
|
||||
def test_test_storage_path_exposes_basic_document_context_but_not_sensitive_owner_data(
|
||||
self,
|
||||
) -> None:
|
||||
owner = User.objects.create_user(
|
||||
owner = UserFactory(
|
||||
username="owner",
|
||||
password="password",
|
||||
email="owner@example.com",
|
||||
@@ -614,8 +615,8 @@ class TestApiStoragePaths(DirectoriesMixin, APITestCase):
|
||||
def test_test_storage_path_includes_related_objects_for_visible_document(
|
||||
self,
|
||||
) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
viewer = User.objects.create_user(username="viewer")
|
||||
owner = UserFactory(username="owner")
|
||||
viewer = UserFactory(username="viewer")
|
||||
private_correspondent = Correspondent.objects.create(
|
||||
name="Private Correspondent",
|
||||
owner=owner,
|
||||
@@ -662,7 +663,7 @@ class TestApiStoragePaths(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(response.data, "Private Correspondent.pdf")
|
||||
|
||||
def test_test_storage_path_superuser_can_view_private_related_objects(self) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
owner = UserFactory(username="owner")
|
||||
private_correspondent = Correspondent.objects.create(
|
||||
name="Private Correspondent",
|
||||
owner=owner,
|
||||
@@ -693,8 +694,8 @@ class TestApiStoragePaths(DirectoriesMixin, APITestCase):
|
||||
def test_test_storage_path_includes_doc_type_storage_path_and_tags(
|
||||
self,
|
||||
) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
viewer = User.objects.create_user(username="viewer")
|
||||
owner = UserFactory(username="owner")
|
||||
viewer = UserFactory(username="viewer")
|
||||
private_document_type = DocumentType.objects.create(
|
||||
name="Private Type",
|
||||
owner=owner,
|
||||
@@ -756,8 +757,8 @@ class TestApiStoragePaths(DirectoriesMixin, APITestCase):
|
||||
def test_test_storage_path_includes_custom_fields_for_visible_document(
|
||||
self,
|
||||
) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
viewer = User.objects.create_user(username="viewer")
|
||||
owner = UserFactory(username="owner")
|
||||
viewer = UserFactory(username="viewer")
|
||||
document = Document.objects.create(
|
||||
mime_type="application/pdf",
|
||||
owner=owner,
|
||||
@@ -798,7 +799,7 @@ class TestBulkEditObjects(APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.temp_admin = User.objects.create_superuser(username="temp_admin")
|
||||
self.temp_admin = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.temp_admin)
|
||||
|
||||
self.t1 = Tag.objects.create(name="t1")
|
||||
|
||||
@@ -20,6 +20,7 @@ from documents.models import MatchingModel
|
||||
from documents.models import StoragePath
|
||||
from documents.models import Tag
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
@@ -93,14 +94,14 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
self.assertNotIn("X-Version", response)
|
||||
|
||||
def test_api_version_with_auth(self) -> None:
|
||||
user = User.objects.create_superuser(username="test")
|
||||
user = UserFactory(username="test", superuser=True)
|
||||
self.client.force_authenticate(user)
|
||||
response = self.client.get("/api/documents/")
|
||||
self.assertIn("X-Api-Version", response)
|
||||
self.assertIn("X-Version", response)
|
||||
|
||||
def test_api_insufficient_permissions(self) -> None:
|
||||
user = User.objects.create_user(username="test")
|
||||
user = UserFactory(username="test")
|
||||
self.client.force_authenticate(user)
|
||||
|
||||
Document.objects.create(title="Test")
|
||||
@@ -137,7 +138,7 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
)
|
||||
|
||||
def test_api_sufficient_permissions(self) -> None:
|
||||
user = User.objects.create_user(username="test")
|
||||
user = UserFactory(username="test")
|
||||
user.user_permissions.add(*Permission.objects.all())
|
||||
user.is_staff = True
|
||||
self.client.force_authenticate(user)
|
||||
@@ -166,8 +167,8 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
)
|
||||
|
||||
def test_api_get_object_permissions(self) -> None:
|
||||
user1 = User.objects.create_user(username="test1")
|
||||
user2 = User.objects.create_user(username="test2")
|
||||
user1 = UserFactory(username="test1")
|
||||
user2 = UserFactory(username="test2")
|
||||
user1.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
self.client.force_authenticate(user1)
|
||||
|
||||
@@ -205,7 +206,7 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Object created with current user as owner
|
||||
"""
|
||||
user1 = User.objects.create_superuser(username="user1")
|
||||
user1 = UserFactory(username="user1", superuser=True)
|
||||
|
||||
self.client.force_authenticate(user1)
|
||||
|
||||
@@ -234,7 +235,7 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Object created with no owner
|
||||
"""
|
||||
user1 = User.objects.create_superuser(username="user1")
|
||||
user1 = UserFactory(username="user1", superuser=True)
|
||||
|
||||
self.client.force_authenticate(user1)
|
||||
|
||||
@@ -265,7 +266,7 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Object permissions are set appropriately
|
||||
"""
|
||||
user1 = User.objects.create_superuser(username="user1")
|
||||
user1 = UserFactory(username="user1", superuser=True)
|
||||
user2 = User.objects.create(username="user2")
|
||||
group1 = Group.objects.create(name="group1")
|
||||
|
||||
@@ -313,7 +314,7 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Object permissions are set appropriately
|
||||
"""
|
||||
user1 = User.objects.create_superuser(username="user1")
|
||||
user1 = UserFactory(username="user1", superuser=True)
|
||||
user2 = User.objects.create(username="user2")
|
||||
group1 = Group.objects.create(name="group1")
|
||||
|
||||
@@ -363,7 +364,7 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
mime_type="application/pdf",
|
||||
content="this is a document",
|
||||
)
|
||||
user1 = User.objects.create_superuser(username="user1")
|
||||
user1 = UserFactory(username="user1", superuser=True)
|
||||
user2 = User.objects.create(username="user2")
|
||||
group1 = Group.objects.create(name="group1")
|
||||
|
||||
@@ -413,7 +414,7 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
mime_type="application/pdf",
|
||||
content="this is a document",
|
||||
)
|
||||
user1 = User.objects.create_superuser(username="user1")
|
||||
user1 = UserFactory(username="user1", superuser=True)
|
||||
user2 = User.objects.create(username="user2")
|
||||
group1 = Group.objects.create(name="group1")
|
||||
doc.owner = user1
|
||||
@@ -446,8 +447,8 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
self.assertIn("change_document", get_perms(group1, doc))
|
||||
|
||||
def test_document_permissions_change_requires_owner(self) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
editor = User.objects.create_user(username="editor")
|
||||
owner = UserFactory(username="owner")
|
||||
editor = UserFactory(username="editor")
|
||||
editor.user_permissions.add(
|
||||
*Permission.objects.all(),
|
||||
)
|
||||
@@ -499,9 +500,9 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
def test_dynamic_permissions_fields(self) -> None:
|
||||
user1 = User.objects.create_user(username="user1")
|
||||
user1 = UserFactory(username="user1")
|
||||
user1.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
user2 = User.objects.create_user(username="user2")
|
||||
user2 = UserFactory(username="user2")
|
||||
|
||||
Document.objects.create(title="Test", content="content 1", checksum="1")
|
||||
doc2 = Document.objects.create(
|
||||
@@ -574,8 +575,8 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
owned by someone else with no explicit guardian grant -- mirrors
|
||||
guardian's own ObjectPermissionChecker.has_perm() superuser shortcut.
|
||||
"""
|
||||
superuser = User.objects.create_superuser(username="admin")
|
||||
other_user = User.objects.create_user(username="user2")
|
||||
superuser = UserFactory(username="admin", superuser=True)
|
||||
other_user = UserFactory(username="user2")
|
||||
Document.objects.create(
|
||||
title="Test",
|
||||
content="content",
|
||||
@@ -602,7 +603,7 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- MFA required error is returned
|
||||
"""
|
||||
user1 = User.objects.create_user(username="user1")
|
||||
user1 = UserFactory(username="user1")
|
||||
user1.set_password("password")
|
||||
user1.save()
|
||||
|
||||
@@ -626,7 +627,7 @@ class TestApiAuth(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- MFA code is required
|
||||
"""
|
||||
user1 = User.objects.create_user(username="user1")
|
||||
user1 = UserFactory(username="user1")
|
||||
user1.set_password("password")
|
||||
user1.save()
|
||||
|
||||
@@ -688,7 +689,7 @@ class TestApiUser(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
def test_get_users(self) -> None:
|
||||
@@ -858,7 +859,7 @@ class TestApiUser(DirectoriesMixin, APITestCase):
|
||||
)
|
||||
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
|
||||
|
||||
regular_user = User.objects.create_user(username="regular_user")
|
||||
regular_user = UserFactory(username="regular_user")
|
||||
regular_user.user_permissions.add(
|
||||
*Permission.objects.all(),
|
||||
)
|
||||
@@ -885,9 +886,9 @@ class TestApiUser(DirectoriesMixin, APITestCase):
|
||||
- Only superusers can change superuser status
|
||||
"""
|
||||
|
||||
user1 = User.objects.create_user(username="user1")
|
||||
user1 = UserFactory(username="user1")
|
||||
user1.user_permissions.add(*Permission.objects.all())
|
||||
user2 = User.objects.create_superuser(username="user2")
|
||||
user2 = UserFactory(username="user2", superuser=True)
|
||||
|
||||
self.client.force_authenticate(user1)
|
||||
|
||||
@@ -972,9 +973,9 @@ class TestApiUser(DirectoriesMixin, APITestCase):
|
||||
- Only superusers can change staff status
|
||||
"""
|
||||
|
||||
user1 = User.objects.create_user(username="user1")
|
||||
user1 = UserFactory(username="user1")
|
||||
user1.user_permissions.add(*Permission.objects.all())
|
||||
user2 = User.objects.create_superuser(username="user2")
|
||||
user2 = UserFactory(username="user2", superuser=True)
|
||||
|
||||
self.client.force_authenticate(user1)
|
||||
|
||||
@@ -1027,7 +1028,7 @@ class TestApiGroup(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
def test_get_groups(self) -> None:
|
||||
@@ -1128,7 +1129,7 @@ class TestBulkEditObjectPermissions(APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.temp_admin = User.objects.create_superuser(username="temp_admin")
|
||||
self.temp_admin = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.temp_admin)
|
||||
|
||||
self.t1 = Tag.objects.create(name="t1")
|
||||
@@ -1680,7 +1681,7 @@ class TestFullPermissionsFlag(APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.admin = User.objects.create_superuser(username="admin")
|
||||
self.admin = UserFactory(username="admin", superuser=True)
|
||||
|
||||
def test_full_perms_flag(self) -> None:
|
||||
"""
|
||||
|
||||
@@ -9,6 +9,7 @@ from rest_framework.authtoken.models import Token
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
# see allauth.socialaccount.providers.openid.provider.OpenIDProvider
|
||||
@@ -55,10 +56,11 @@ class TestApiProfile(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(
|
||||
self.user = UserFactory(
|
||||
username="temp_admin",
|
||||
first_name="firstname",
|
||||
last_name="surname",
|
||||
superuser=True,
|
||||
)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
@@ -401,7 +403,7 @@ class TestApiTOTPViews(APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
def test_get_totp(self) -> None:
|
||||
|
||||
@@ -7,7 +7,6 @@ import time_machine
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import override_settings
|
||||
from django.utils import timezone
|
||||
from guardian.shortcuts import assign_perm
|
||||
@@ -31,6 +30,7 @@ from paperless_mail.models import MailAccount
|
||||
from paperless_mail.models import MailRule
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import DocumentFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
pytestmark = pytest.mark.search
|
||||
|
||||
@@ -40,7 +40,7 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
|
||||
super().setUp()
|
||||
reset_backend()
|
||||
|
||||
self.user = User.objects.create_superuser(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
def tearDown(self) -> None:
|
||||
@@ -949,8 +949,8 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Terms only within docs user has access to are returned
|
||||
"""
|
||||
u1 = User.objects.create_user("user1")
|
||||
u2 = User.objects.create_user("user2")
|
||||
u1 = UserFactory(username="user1")
|
||||
u2 = UserFactory(username="user2")
|
||||
u1.user_permissions.add(Permission.objects.get(codename="view_document"))
|
||||
|
||||
self.client.force_authenticate(user=u1)
|
||||
@@ -999,8 +999,8 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(response.data, ["applebaum", "apples", "appletini"])
|
||||
|
||||
def test_search_autocomplete_group_revocation_is_immediate(self) -> None:
|
||||
user = User.objects.create_user("group-user")
|
||||
owner = User.objects.create_user("document-owner")
|
||||
user = UserFactory(username="group-user")
|
||||
owner = UserFactory(username="document-owner")
|
||||
group = Group.objects.create(name="temporary-viewers")
|
||||
user.user_permissions.add(Permission.objects.get(codename="view_document"))
|
||||
user.groups.add(group)
|
||||
@@ -1091,8 +1091,8 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
|
||||
self.assertIsNone(response.data["corrected_query"])
|
||||
|
||||
def test_search_spelling_suggestion_suppressed_for_private_terms(self) -> None:
|
||||
owner = User.objects.create_user("owner")
|
||||
attacker = User.objects.create_user("attacker")
|
||||
owner = UserFactory(username="owner")
|
||||
attacker = UserFactory(username="attacker")
|
||||
attacker.user_permissions.add(
|
||||
Permission.objects.get(codename="view_document"),
|
||||
)
|
||||
@@ -1222,8 +1222,8 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- The request is rejected
|
||||
"""
|
||||
owner = User.objects.create_user("owner")
|
||||
attacker = User.objects.create_user("attacker")
|
||||
owner = UserFactory(username="owner")
|
||||
attacker = UserFactory(username="attacker")
|
||||
attacker.user_permissions.add(
|
||||
Permission.objects.get(codename="view_document"),
|
||||
)
|
||||
@@ -1534,9 +1534,9 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
|
||||
- Only owned docs are returned for regular users
|
||||
- All docs are returned for superuser
|
||||
"""
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
u1 = User.objects.create_user("user1")
|
||||
u2 = User.objects.create_user("user2")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
u1 = UserFactory(username="user1")
|
||||
u2 = UserFactory(username="user2")
|
||||
u1.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
u2.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
|
||||
@@ -1588,8 +1588,8 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Only docs with granted view permissions are returned
|
||||
"""
|
||||
u1 = User.objects.create_user("user1")
|
||||
u2 = User.objects.create_user("user2")
|
||||
u1 = UserFactory(username="user1")
|
||||
u2 = UserFactory(username="user2")
|
||||
u1.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
u2.user_permissions.add(*Permission.objects.filter(codename="view_document"))
|
||||
|
||||
@@ -1641,8 +1641,8 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(r.data["count"], 1)
|
||||
|
||||
def test_search_sorting(self) -> None:
|
||||
u1 = User.objects.create_user("user1")
|
||||
u2 = User.objects.create_user("user2")
|
||||
u1 = UserFactory(username="user1")
|
||||
u2 = UserFactory(username="user2")
|
||||
c1 = Correspondent.objects.create(name="corres Ax")
|
||||
c2 = Correspondent.objects.create(name="corres Cx")
|
||||
c3 = Correspondent.objects.create(name="corres Bx")
|
||||
@@ -1892,8 +1892,8 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
|
||||
pk=5,
|
||||
)
|
||||
|
||||
user1 = User.objects.create_user("bank user1")
|
||||
user2 = User.objects.create_superuser("user2")
|
||||
user1 = UserFactory(username="bank user1")
|
||||
user2 = UserFactory(username="user2", superuser=True)
|
||||
group1 = Group.objects.create(name="bank group1")
|
||||
Group.objects.create(name="group2")
|
||||
|
||||
@@ -2018,8 +2018,8 @@ class TestDocumentSearchApi(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(returned.get(root.id), "latest content")
|
||||
|
||||
def test_global_search_filters_owned_mail_objects(self) -> None:
|
||||
user1 = User.objects.create_user("mail-search-user")
|
||||
user2 = User.objects.create_user("other-mail-search-user")
|
||||
user1 = UserFactory(username="mail-search-user")
|
||||
user2 = UserFactory(username="other-mail-search-user")
|
||||
user1.user_permissions.add(
|
||||
Permission.objects.get(codename="view_mailaccount"),
|
||||
Permission.objects.get(codename="view_mailrule"),
|
||||
|
||||
@@ -6,7 +6,6 @@ from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import override_settings
|
||||
from django.utils import timezone
|
||||
from rest_framework import status
|
||||
@@ -16,6 +15,7 @@ from documents.models import PaperlessTask
|
||||
from documents.permissions import has_system_status_permission
|
||||
from paperless import version
|
||||
from paperless_testing.factories import PaperlessTaskFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestSystemStatus(APITestCase):
|
||||
@@ -23,9 +23,7 @@ class TestSystemStatus(APITestCase):
|
||||
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
self.user = User.objects.create_superuser(
|
||||
username="temp_admin",
|
||||
)
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.tmp_dir = Path(tempfile.mkdtemp())
|
||||
self.override = override_settings(MEDIA_ROOT=self.tmp_dir)
|
||||
self.override.enable()
|
||||
@@ -96,7 +94,7 @@ class TestSystemStatus(APITestCase):
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
self.assertEqual(response["WWW-Authenticate"], "Token")
|
||||
normal_user = User.objects.create_user(username="normal_user")
|
||||
normal_user = UserFactory(username="normal_user")
|
||||
self.client.force_login(normal_user)
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
@@ -107,7 +105,7 @@ class TestSystemStatus(APITestCase):
|
||||
response = self.client.get(self.ENDPOINT)
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
user = User.objects.create_user(username="status_user")
|
||||
user = UserFactory(username="status_user")
|
||||
user.user_permissions.add(
|
||||
Permission.objects.get(codename="view_system_monitoring"),
|
||||
)
|
||||
|
||||
@@ -26,7 +26,6 @@ from paperless_testing.factories import PaperlessTaskFactory
|
||||
pytestmark = pytest.mark.api
|
||||
|
||||
ENDPOINT = "/api/tasks/"
|
||||
ACCEPT_V10 = "application/json; version=10"
|
||||
ACCEPT_V9 = "application/json; version=9"
|
||||
|
||||
|
||||
@@ -346,21 +345,18 @@ class TestGetTasksV10:
|
||||
self,
|
||||
admin_user: User,
|
||||
regular_user: User,
|
||||
user_client: APIClient,
|
||||
) -> None:
|
||||
"""Regular users see their own tasks and unowned (system) tasks; other users' tasks are hidden."""
|
||||
regular_user.user_permissions.add(
|
||||
Permission.objects.get(codename="view_paperlesstask"),
|
||||
)
|
||||
|
||||
client = APIClient()
|
||||
client.force_authenticate(user=regular_user)
|
||||
client.credentials(HTTP_ACCEPT=ACCEPT_V10)
|
||||
|
||||
PaperlessTaskFactory(owner=admin_user) # other user — not visible
|
||||
unowned_task = PaperlessTaskFactory() # unowned (system task) — visible
|
||||
own_task = PaperlessTaskFactory(owner=regular_user)
|
||||
|
||||
response = client.get(ENDPOINT)
|
||||
response = user_client.get(ENDPOINT)
|
||||
|
||||
assert response.status_code == status.HTTP_200_OK
|
||||
assert response.data["count"] == 2
|
||||
@@ -732,19 +728,19 @@ class TestAcknowledge:
|
||||
|
||||
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||
|
||||
def test_succeeds_with_change_permission(self, regular_user: User) -> None:
|
||||
def test_succeeds_with_change_permission(
|
||||
self,
|
||||
regular_user: User,
|
||||
user_client: APIClient,
|
||||
) -> None:
|
||||
"""Users granted change_paperlesstask permission can acknowledge tasks."""
|
||||
regular_user.user_permissions.add(
|
||||
Permission.objects.get(codename="change_paperlesstask"),
|
||||
)
|
||||
regular_user.save()
|
||||
|
||||
client = APIClient()
|
||||
client.force_authenticate(user=regular_user)
|
||||
client.credentials(HTTP_ACCEPT=ACCEPT_V10)
|
||||
|
||||
task = PaperlessTaskFactory()
|
||||
response = client.post(
|
||||
response = user_client.post(
|
||||
ENDPOINT + "acknowledge/",
|
||||
{"tasks": [task.id]},
|
||||
format="json",
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
from datetime import date
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.cache import cache
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from documents.models import Document
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestTrashAPI(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_user(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin")
|
||||
self.user.user_permissions.add(*Permission.objects.all())
|
||||
self.client.force_authenticate(user=self.user)
|
||||
cache.clear()
|
||||
@@ -70,7 +70,7 @@ class TestTrashAPI(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(Document.global_objects.count(), 0)
|
||||
|
||||
def test_trash_list_requires_global_document_view_permission(self) -> None:
|
||||
user = User.objects.create_user(username="trash_owner")
|
||||
user = UserFactory(username="trash_owner")
|
||||
document = Document.objects.create(title="Owned", owner=user)
|
||||
document.delete()
|
||||
self.client.force_authenticate(user)
|
||||
@@ -140,7 +140,7 @@ class TestTrashAPI(DirectoriesMixin, APITestCase):
|
||||
created=date(2023, 1, 2),
|
||||
)
|
||||
document_not_owned.delete()
|
||||
user2 = User.objects.create_user(username="user2")
|
||||
user2 = UserFactory(username="user2")
|
||||
document_u2 = Document.objects.create(
|
||||
title="Title3",
|
||||
content="content3",
|
||||
@@ -158,7 +158,7 @@ class TestTrashAPI(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(resp.data["results"][1]["id"], document_u1.pk)
|
||||
|
||||
# superuser sees all documents
|
||||
superuser = User.objects.create_superuser(username="superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
self.client.force_authenticate(user=superuser)
|
||||
resp = self.client.get("/api/trash/")
|
||||
self.assertEqual(resp.status_code, status.HTTP_200_OK)
|
||||
@@ -174,7 +174,7 @@ class TestTrashAPI(DirectoriesMixin, APITestCase):
|
||||
- 403 Forbidden
|
||||
"""
|
||||
|
||||
user2 = User.objects.create_user(username="user2")
|
||||
user2 = UserFactory(username="user2")
|
||||
document = Document.objects.create(
|
||||
title="Title",
|
||||
content="content",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import json
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import override_settings
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from paperless.version import __full_version_str__
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestApiUiSettings(DirectoriesMixin, APITestCase):
|
||||
@@ -15,7 +15,7 @@ class TestApiUiSettings(DirectoriesMixin, APITestCase):
|
||||
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
self.test_user = User.objects.create_superuser(username="test")
|
||||
self.test_user = UserFactory(username="test", superuser=True)
|
||||
self.test_user.first_name = "Test"
|
||||
self.test_user.last_name = "User"
|
||||
self.test_user.save()
|
||||
@@ -91,7 +91,7 @@ class TestApiUiSettings(DirectoriesMixin, APITestCase):
|
||||
)
|
||||
|
||||
def test_api_set_ui_settings_insufficient_global_permissions(self) -> None:
|
||||
not_superuser = User.objects.create_user(username="test_not_superuser")
|
||||
not_superuser = UserFactory(username="test_not_superuser")
|
||||
self.client.force_authenticate(user=not_superuser)
|
||||
|
||||
settings = {
|
||||
@@ -111,7 +111,7 @@ class TestApiUiSettings(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
|
||||
def test_api_set_ui_settings_sufficient_global_permissions(self) -> None:
|
||||
not_superuser = User.objects.create_user(username="test_not_superuser")
|
||||
not_superuser = UserFactory(username="test_not_superuser")
|
||||
not_superuser.user_permissions.add(
|
||||
*Permission.objects.filter(codename__contains="uisettings"),
|
||||
)
|
||||
|
||||
@@ -15,6 +15,7 @@ from documents.models import Workflow
|
||||
from documents.models import WorkflowAction
|
||||
from documents.models import WorkflowTrigger
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestApiWorkflows(DirectoriesMixin, APITestCase):
|
||||
@@ -25,7 +26,7 @@ class TestApiWorkflows(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
user = User.objects.create_superuser(username="temp_admin")
|
||||
user = UserFactory(username="temp_admin", superuser=True)
|
||||
self.client.force_authenticate(user=user)
|
||||
self.user2 = User.objects.create(username="user2")
|
||||
self.user3 = User.objects.create(username="user3")
|
||||
|
||||
@@ -35,6 +35,7 @@ from documents.tests.utils import FileSystemAssertsMixin
|
||||
from documents.tests.utils import GetConsumerMixin
|
||||
from paperless_mail.models import MailRule
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class _BaseNewStyleParser:
|
||||
@@ -769,7 +770,7 @@ class TestConsumer(
|
||||
|
||||
original_modified = timezone.now() - datetime.timedelta(days=1)
|
||||
Document.objects.filter(pk=root_doc.pk).update(modified=original_modified)
|
||||
actor = User.objects.create_user(
|
||||
actor = UserFactory(
|
||||
username="actor",
|
||||
email="actor@example.com",
|
||||
password="password",
|
||||
|
||||
@@ -8,7 +8,6 @@ from unittest import mock
|
||||
import pytest
|
||||
from auditlog.context import disable_auditlog
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.db import DatabaseError
|
||||
from django.db import connection
|
||||
from django.test import TestCase
|
||||
@@ -33,6 +32,7 @@ from documents.tasks import empty_trash
|
||||
from documents.tests.utils import FileSystemAssertsMixin
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import DocumentFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestFileHandling(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
@@ -1323,7 +1323,7 @@ class TestFilenameGeneration(DirectoriesMixin, TestCase):
|
||||
- Document without owner returns "none"
|
||||
"""
|
||||
|
||||
u1 = User.objects.create_user("user1")
|
||||
u1 = UserFactory(username="user1")
|
||||
|
||||
owned_doc = Document.objects.create(
|
||||
title="The Title",
|
||||
|
||||
@@ -3,7 +3,6 @@ from unittest import mock
|
||||
|
||||
from auditlog.models import LogEntry
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import TestCase
|
||||
from rest_framework import status
|
||||
@@ -12,6 +11,7 @@ from rest_framework.test import APITestCase
|
||||
from documents.bulk_edit import merge_as_versions
|
||||
from documents.models import Document
|
||||
from documents.serialisers import MergeDocumentsAsVersionsSerializer
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestMergeDocumentsAsVersionsSerializer(TestCase):
|
||||
@@ -294,7 +294,7 @@ class TestMergeDocumentsAsVersions(TestCase):
|
||||
@mock.patch("documents.bulk_edit.bulk_update_documents.apply_async")
|
||||
@mock.patch("documents.search.get_backend")
|
||||
def test_writes_audit_log_entry(self, *_mocks) -> None:
|
||||
user = User.objects.create_user(username="merger")
|
||||
user = UserFactory(username="merger")
|
||||
root = Document.objects.create(checksum="A", title="Root")
|
||||
source = Document.objects.create(checksum="B", title="Source")
|
||||
LogEntry.objects.all().delete()
|
||||
@@ -335,7 +335,7 @@ class TestMergeDocumentsAsVersions(TestCase):
|
||||
|
||||
class TestMergeDocumentsAsVersionsAPI(APITestCase):
|
||||
def setUp(self) -> None:
|
||||
self.user = User.objects.create_user(username="user")
|
||||
self.user = UserFactory(username="user")
|
||||
self.user.user_permissions.add(
|
||||
Permission.objects.get(codename="change_document"),
|
||||
Permission.objects.get(codename="view_document"),
|
||||
@@ -382,7 +382,7 @@ class TestMergeDocumentsAsVersionsAPI(APITestCase):
|
||||
@mock.patch("documents.views.bulk_edit.merge_as_versions")
|
||||
def test_requires_change_permission(self, merge_mock) -> None:
|
||||
merge_mock.__name__ = "merge_as_versions"
|
||||
user = User.objects.create_user(username="no-change")
|
||||
user = UserFactory(username="no-change")
|
||||
self.doc1.owner = user
|
||||
self.doc1.save()
|
||||
self.doc2.owner = user
|
||||
@@ -405,7 +405,7 @@ class TestMergeDocumentsAsVersionsAPI(APITestCase):
|
||||
def test_requires_delete_permission(self, merge_mock) -> None:
|
||||
merge_mock.__name__ = "merge_as_versions"
|
||||
# Owns them and may change them, but may not make them stop being documents
|
||||
user = User.objects.create_user(username="no-delete")
|
||||
user = UserFactory(username="no-delete")
|
||||
user.user_permissions.add(
|
||||
Permission.objects.get(codename="change_document"),
|
||||
Permission.objects.get(codename="view_document"),
|
||||
|
||||
@@ -8,7 +8,6 @@ import pytest
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import override_settings
|
||||
from guardian.shortcuts import assign_perm
|
||||
from rest_framework.test import APIClient
|
||||
@@ -30,6 +29,7 @@ from paperless_testing.factories import DocumentFactory
|
||||
from paperless_testing.factories import DocumentTypeFactory
|
||||
from paperless_testing.factories import StoragePathFactory
|
||||
from paperless_testing.factories import TagFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from paperless_testing.dirs import PaperlessDirs
|
||||
@@ -51,8 +51,8 @@ def assert_visible_document_ids(actual_ids, *, expected_visible, expected_hidden
|
||||
@pytest.mark.django_db
|
||||
class TestPermittedDocumentIdsSecurity:
|
||||
def test_owner_sees_own_document(self):
|
||||
user = User.objects.create_user(username="alice")
|
||||
stranger = User.objects.create_user(username="mallory")
|
||||
user = UserFactory(username="alice")
|
||||
stranger = UserFactory(username="mallory")
|
||||
owned = DocumentFactory(owner=user)
|
||||
strangers_doc = DocumentFactory(owner=stranger)
|
||||
|
||||
@@ -65,7 +65,7 @@ class TestPermittedDocumentIdsSecurity:
|
||||
)
|
||||
|
||||
def test_unowned_document_visible_to_everyone(self):
|
||||
user = User.objects.create_user(username="alice")
|
||||
user = UserFactory(username="alice")
|
||||
unowned = DocumentFactory(owner=None)
|
||||
|
||||
assert_visible_document_ids(
|
||||
@@ -75,9 +75,9 @@ class TestPermittedDocumentIdsSecurity:
|
||||
)
|
||||
|
||||
def test_explicit_user_permission_grants_visibility(self):
|
||||
grantee = User.objects.create_user(username="alice")
|
||||
stranger = User.objects.create_user(username="mallory")
|
||||
owner = User.objects.create_user(username="owner")
|
||||
grantee = UserFactory(username="alice")
|
||||
stranger = UserFactory(username="mallory")
|
||||
owner = UserFactory(username="owner")
|
||||
shared = DocumentFactory(owner=owner)
|
||||
not_shared = DocumentFactory(owner=owner)
|
||||
assign_perm("view_document", grantee, shared)
|
||||
@@ -94,9 +94,9 @@ class TestPermittedDocumentIdsSecurity:
|
||||
)
|
||||
|
||||
def test_explicit_group_permission_grants_visibility_to_members_only(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
member = User.objects.create_user(username="member")
|
||||
non_member = User.objects.create_user(username="non_member")
|
||||
owner = UserFactory(username="owner")
|
||||
member = UserFactory(username="member")
|
||||
non_member = UserFactory(username="non_member")
|
||||
group = Group.objects.create(name="finance")
|
||||
member.groups.add(group)
|
||||
shared = DocumentFactory(owner=owner)
|
||||
@@ -114,7 +114,7 @@ class TestPermittedDocumentIdsSecurity:
|
||||
)
|
||||
|
||||
def test_soft_deleted_document_excluded_by_default(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
owner = UserFactory(username="owner")
|
||||
doc = DocumentFactory(owner=owner)
|
||||
doc.delete() # soft delete
|
||||
doc.refresh_from_db()
|
||||
@@ -130,8 +130,8 @@ class TestPermittedDocumentIdsSecurity:
|
||||
)
|
||||
|
||||
def test_superuser_sees_everything_including_no_perm_documents(self):
|
||||
superuser = User.objects.create_superuser(username="root")
|
||||
owner = User.objects.create_user(username="owner")
|
||||
superuser = UserFactory(username="root", superuser=True)
|
||||
owner = UserFactory(username="owner")
|
||||
doc = DocumentFactory(owner=owner)
|
||||
|
||||
assert_visible_document_ids(
|
||||
@@ -141,7 +141,7 @@ class TestPermittedDocumentIdsSecurity:
|
||||
)
|
||||
|
||||
def test_anonymous_user_sees_only_unowned_documents(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
owner = UserFactory(username="owner")
|
||||
owned = DocumentFactory(owner=owner)
|
||||
unowned = DocumentFactory(owner=None)
|
||||
|
||||
@@ -155,7 +155,7 @@ class TestPermittedDocumentIdsSecurity:
|
||||
@pytest.mark.django_db
|
||||
class TestPermittedDocumentIdsIncludeDeleted:
|
||||
def test_include_deleted_true_reveals_soft_deleted_owned_document(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
owner = UserFactory(username="owner")
|
||||
doc = DocumentFactory(owner=owner)
|
||||
doc.delete()
|
||||
|
||||
@@ -166,8 +166,8 @@ class TestPermittedDocumentIdsIncludeDeleted:
|
||||
)
|
||||
|
||||
def test_include_deleted_true_still_respects_permission_boundary(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
stranger = User.objects.create_user(username="mallory")
|
||||
owner = UserFactory(username="owner")
|
||||
stranger = UserFactory(username="mallory")
|
||||
doc = DocumentFactory(owner=owner)
|
||||
doc.delete()
|
||||
|
||||
@@ -195,8 +195,8 @@ class TestAiChatAllDocumentsPermissionBoundary:
|
||||
def test_chat_all_documents_excludes_unshared_document(self, mock_stream_chat):
|
||||
mock_stream_chat.return_value = iter([b"data"])
|
||||
|
||||
owner = User.objects.create_user(username="owner")
|
||||
asker = User.objects.create_user(username="asker")
|
||||
owner = UserFactory(username="owner")
|
||||
asker = UserFactory(username="asker")
|
||||
asker.user_permissions.add(
|
||||
*Permission.objects.filter(codename="view_document"),
|
||||
)
|
||||
@@ -223,8 +223,8 @@ class TestAiChatAllDocumentsPermissionBoundary:
|
||||
@pytest.mark.django_db
|
||||
class TestDuplicateDocumentsPermissionBoundary:
|
||||
def test_get_viewable_duplicates_includes_soft_deleted_but_respects_perms(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
stranger = User.objects.create_user(username="mallory")
|
||||
owner = UserFactory(username="owner")
|
||||
stranger = UserFactory(username="mallory")
|
||||
original = DocumentFactory(owner=owner, checksum="dupe-checksum")
|
||||
dup_visible = DocumentFactory(owner=owner, checksum="dupe-checksum")
|
||||
dup_hidden = DocumentFactory(owner=owner, checksum="dupe-checksum")
|
||||
@@ -241,9 +241,9 @@ class TestDuplicateDocumentsPermissionBoundary:
|
||||
@pytest.mark.django_db
|
||||
class TestPermittedDocumentIdsArbitraryPermission:
|
||||
def test_change_document_permission_is_distinct_from_view(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
viewer_only = User.objects.create_user(username="viewer")
|
||||
editor = User.objects.create_user(username="editor")
|
||||
owner = UserFactory(username="owner")
|
||||
viewer_only = UserFactory(username="viewer")
|
||||
editor = UserFactory(username="editor")
|
||||
doc = DocumentFactory(owner=owner)
|
||||
assign_perm("view_document", viewer_only, doc)
|
||||
assign_perm("change_document", editor, doc)
|
||||
@@ -261,8 +261,8 @@ class TestPermittedDocumentIdsArbitraryPermission:
|
||||
)
|
||||
|
||||
def test_qualified_permission_string_is_normalized_to_codename(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
editor = User.objects.create_user(username="editor")
|
||||
owner = UserFactory(username="owner")
|
||||
editor = UserFactory(username="editor")
|
||||
doc = DocumentFactory(owner=owner)
|
||||
assign_perm("change_document", editor, doc)
|
||||
|
||||
@@ -273,9 +273,9 @@ class TestPermittedDocumentIdsArbitraryPermission:
|
||||
)
|
||||
|
||||
def test_delete_permission_with_include_deleted_for_trash_restore(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
stranger = User.objects.create_user(username="mallory")
|
||||
view_only = User.objects.create_user(username="viewer")
|
||||
owner = UserFactory(username="owner")
|
||||
stranger = UserFactory(username="mallory")
|
||||
view_only = UserFactory(username="viewer")
|
||||
doc = DocumentFactory(owner=owner)
|
||||
assign_perm("view_document", view_only, doc)
|
||||
doc.delete()
|
||||
@@ -311,8 +311,8 @@ class TestEmailDocumentPermissionBoundary:
|
||||
self,
|
||||
rest_api_client,
|
||||
):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
requester = User.objects.create_user(username="requester")
|
||||
owner = UserFactory(username="owner")
|
||||
requester = UserFactory(username="requester")
|
||||
requester.user_permissions.add(
|
||||
Permission.objects.get(codename="view_document"),
|
||||
)
|
||||
@@ -343,8 +343,8 @@ class TestBulkEditChangePermissionBoundary:
|
||||
# permitted document must not be partially applied just because it
|
||||
# was bundled with a forbidden one, proving the endpoint checks
|
||||
# every document in the batch rather than only the first/last.
|
||||
owner = User.objects.create_user(username="owner")
|
||||
requester = User.objects.create_user(username="requester")
|
||||
owner = UserFactory(username="owner")
|
||||
requester = UserFactory(username="requester")
|
||||
# grant the global change_document permission so the object-level
|
||||
# check (not the global has_perm check) is what's under test
|
||||
requester.user_permissions.add(
|
||||
@@ -376,8 +376,8 @@ class TestBulkDownloadPermissionChecksRootDocument:
|
||||
rest_api_client: APIClient,
|
||||
paperless_dirs: PaperlessDirs,
|
||||
) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
requester = User.objects.create_user(username="requester")
|
||||
owner = UserFactory(username="owner")
|
||||
requester = UserFactory(username="requester")
|
||||
root = DocumentFactory(owner=owner)
|
||||
root.source_path.write_bytes(b"%PDF-1.4 test")
|
||||
assign_perm("view_document", requester, root)
|
||||
@@ -396,8 +396,8 @@ class TestBulkDownloadPermissionChecksRootDocument:
|
||||
rest_api_client: APIClient,
|
||||
paperless_dirs: PaperlessDirs,
|
||||
) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
requester = User.objects.create_user(username="requester")
|
||||
owner = UserFactory(username="owner")
|
||||
requester = UserFactory(username="requester")
|
||||
requester.user_permissions.add(
|
||||
Permission.objects.get(codename="view_document"),
|
||||
)
|
||||
@@ -424,7 +424,7 @@ class TestBulkDownloadPermissionChecksRootDocument:
|
||||
# root-or-version bug; a user with no grant at all (the old
|
||||
# `stranger` case) can't tell the two apart, since they're denied
|
||||
# either way.
|
||||
version_only_grantee = User.objects.create_user(username="version_only_grantee")
|
||||
version_only_grantee = UserFactory(username="version_only_grantee")
|
||||
version_only_grantee.user_permissions.add(
|
||||
Permission.objects.get(codename="view_document"),
|
||||
)
|
||||
@@ -447,8 +447,8 @@ class TestTrashRestorePermissionBoundary:
|
||||
self,
|
||||
rest_api_client,
|
||||
):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
requester = User.objects.create_user(username="requester")
|
||||
owner = UserFactory(username="owner")
|
||||
requester = UserFactory(username="requester")
|
||||
requester.user_permissions.add(
|
||||
Permission.objects.get(codename="delete_document"),
|
||||
)
|
||||
@@ -468,8 +468,8 @@ class TestTrashRestorePermissionBoundary:
|
||||
self,
|
||||
rest_api_client,
|
||||
):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
requester = User.objects.create_user(username="requester")
|
||||
owner = UserFactory(username="owner")
|
||||
requester = UserFactory(username="requester")
|
||||
requester.user_permissions.add(
|
||||
Permission.objects.get(codename="delete_document"),
|
||||
)
|
||||
@@ -486,8 +486,8 @@ class TestTrashRestorePermissionBoundary:
|
||||
assert response.status_code == HTTPStatus.OK
|
||||
|
||||
def test_restore_requires_global_delete_permission(self, rest_api_client):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
requester = User.objects.create_user(username="requester")
|
||||
owner = UserFactory(username="owner")
|
||||
requester = UserFactory(username="requester")
|
||||
rest_api_client.force_authenticate(user=requester)
|
||||
doc = DocumentFactory(owner=owner)
|
||||
assign_perm("delete_document", requester, doc)
|
||||
@@ -515,8 +515,8 @@ class TestTrashViewExcludesExplicitlyGrantedDocuments:
|
||||
"""
|
||||
|
||||
def test_explicit_grant_does_not_leak_trashed_document(self, rest_api_client):
|
||||
owner = User.objects.create_user(username="trash_owner")
|
||||
grantee = User.objects.create_user(username="trash_grantee")
|
||||
owner = UserFactory(username="trash_owner")
|
||||
grantee = UserFactory(username="trash_grantee")
|
||||
grantee.user_permissions.add(
|
||||
Permission.objects.get(codename="view_document"),
|
||||
)
|
||||
@@ -544,8 +544,8 @@ class TestTrashViewExcludesExplicitlyGrantedDocuments:
|
||||
)
|
||||
class TestPermittedObjectIdsGenericModels:
|
||||
def test_owner_sees_own_object(self, model, factory, perm):
|
||||
owner = User.objects.create_user(username=f"owner_{model.__name__}")
|
||||
stranger = User.objects.create_user(username=f"stranger_{model.__name__}")
|
||||
owner = UserFactory(username=f"owner_{model.__name__}")
|
||||
stranger = UserFactory(username=f"stranger_{model.__name__}")
|
||||
owned = factory(owner=owner)
|
||||
strangers = factory(owner=stranger)
|
||||
|
||||
@@ -558,12 +558,12 @@ class TestPermittedObjectIdsGenericModels:
|
||||
@pytest.mark.parametrize("is_superuser", [False, True])
|
||||
def test_inactive_user_sees_nothing(self, model, factory, perm, is_superuser):
|
||||
suffix = f"{model.__name__}_{is_superuser}"
|
||||
user = User.objects.create_user(
|
||||
user = UserFactory(
|
||||
username=f"inactive_{suffix}",
|
||||
is_active=False,
|
||||
is_superuser=is_superuser,
|
||||
)
|
||||
other = User.objects.create_user(username=f"other_{suffix}")
|
||||
other = UserFactory(username=f"other_{suffix}")
|
||||
granted = factory(owner=other)
|
||||
assign_perm(perm, user, granted)
|
||||
|
||||
@@ -578,7 +578,7 @@ class TestPermittedObjectIdsGenericModels:
|
||||
)
|
||||
|
||||
def test_unowned_object_visible_to_everyone(self, model, factory, perm):
|
||||
user = User.objects.create_user(username=f"user_{model.__name__}")
|
||||
user = UserFactory(username=f"user_{model.__name__}")
|
||||
unowned = factory(owner=None)
|
||||
|
||||
assert_visible_document_ids(
|
||||
@@ -588,9 +588,9 @@ class TestPermittedObjectIdsGenericModels:
|
||||
)
|
||||
|
||||
def test_explicit_permission_grants_visibility(self, model, factory, perm):
|
||||
owner = User.objects.create_user(username=f"owner2_{model.__name__}")
|
||||
grantee = User.objects.create_user(username=f"grantee_{model.__name__}")
|
||||
stranger = User.objects.create_user(username=f"stranger2_{model.__name__}")
|
||||
owner = UserFactory(username=f"owner2_{model.__name__}")
|
||||
grantee = UserFactory(username=f"grantee_{model.__name__}")
|
||||
stranger = UserFactory(username=f"stranger2_{model.__name__}")
|
||||
shared = factory(owner=owner)
|
||||
not_shared = factory(owner=owner)
|
||||
assign_perm(perm, grantee, shared)
|
||||
@@ -612,9 +612,9 @@ class TestPermittedObjectIdsGenericModels:
|
||||
factory,
|
||||
perm,
|
||||
):
|
||||
owner = User.objects.create_user(username=f"owner3_{model.__name__}")
|
||||
member = User.objects.create_user(username=f"member_{model.__name__}")
|
||||
non_member = User.objects.create_user(username=f"nonmember_{model.__name__}")
|
||||
owner = UserFactory(username=f"owner3_{model.__name__}")
|
||||
member = UserFactory(username=f"member_{model.__name__}")
|
||||
non_member = UserFactory(username=f"nonmember_{model.__name__}")
|
||||
group = Group.objects.create(name=f"group_{model.__name__}")
|
||||
member.groups.add(group)
|
||||
shared = factory(owner=owner)
|
||||
@@ -632,8 +632,8 @@ class TestPermittedObjectIdsGenericModels:
|
||||
)
|
||||
|
||||
def test_superuser_sees_everything(self, model, factory, perm):
|
||||
superuser = User.objects.create_superuser(username=f"root_{model.__name__}")
|
||||
owner = User.objects.create_user(username=f"owner4_{model.__name__}")
|
||||
superuser = UserFactory(username=f"root_{model.__name__}", superuser=True)
|
||||
owner = UserFactory(username=f"owner4_{model.__name__}")
|
||||
obj = factory(owner=owner)
|
||||
|
||||
assert_visible_document_ids(
|
||||
@@ -646,8 +646,8 @@ class TestPermittedObjectIdsGenericModels:
|
||||
@pytest.mark.django_db
|
||||
class TestMatchingRespectsObjectPermissions:
|
||||
def test_match_tags_only_considers_tags_visible_to_user(self):
|
||||
owner = User.objects.create_user(username="tag_owner")
|
||||
classifying_user = User.objects.create_user(username="classifier_user")
|
||||
owner = UserFactory(username="tag_owner")
|
||||
classifying_user = UserFactory(username="classifier_user")
|
||||
visible_tag = TagFactory(
|
||||
owner=owner,
|
||||
match="invoice",
|
||||
@@ -667,8 +667,8 @@ class TestMatchingRespectsObjectPermissions:
|
||||
assert hidden_tag.pk not in matched_ids
|
||||
|
||||
def test_match_correspondents_only_considers_correspondents_visible_to_user(self):
|
||||
owner = User.objects.create_user(username="correspondent_owner")
|
||||
classifying_user = User.objects.create_user(username="classifier_user2")
|
||||
owner = UserFactory(username="correspondent_owner")
|
||||
classifying_user = UserFactory(username="classifier_user2")
|
||||
visible_correspondent = CorrespondentFactory(
|
||||
owner=owner,
|
||||
match="invoice",
|
||||
@@ -688,8 +688,8 @@ class TestMatchingRespectsObjectPermissions:
|
||||
assert hidden_correspondent.pk not in matched_ids
|
||||
|
||||
def test_match_document_types_only_considers_document_types_visible_to_user(self):
|
||||
owner = User.objects.create_user(username="document_type_owner")
|
||||
classifying_user = User.objects.create_user(username="classifier_user3")
|
||||
owner = UserFactory(username="document_type_owner")
|
||||
classifying_user = UserFactory(username="classifier_user3")
|
||||
visible_document_type = DocumentTypeFactory(
|
||||
owner=owner,
|
||||
match="invoice",
|
||||
@@ -709,8 +709,8 @@ class TestMatchingRespectsObjectPermissions:
|
||||
assert hidden_document_type.pk not in matched_ids
|
||||
|
||||
def test_match_storage_paths_only_considers_storage_paths_visible_to_user(self):
|
||||
owner = User.objects.create_user(username="storage_path_owner")
|
||||
classifying_user = User.objects.create_user(username="classifier_user4")
|
||||
owner = UserFactory(username="storage_path_owner")
|
||||
classifying_user = UserFactory(username="classifier_user4")
|
||||
visible_storage_path = StoragePathFactory(
|
||||
owner=owner,
|
||||
match="invoice",
|
||||
@@ -733,9 +733,9 @@ class TestMatchingRespectsObjectPermissions:
|
||||
@pytest.mark.django_db
|
||||
class TestBulkEditObjectsApplyToAllPermissionBoundary:
|
||||
def test_apply_to_all_tags_excludes_unpermitted_tag(self, rest_api_client):
|
||||
owner = User.objects.create_user(username="tags_owner")
|
||||
requester = User.objects.create_user(username="tags_requester")
|
||||
new_owner = User.objects.create_user(username="tags_new_owner")
|
||||
owner = UserFactory(username="tags_owner")
|
||||
requester = UserFactory(username="tags_requester")
|
||||
new_owner = UserFactory(username="tags_new_owner")
|
||||
# grant the global change_tag permission so the object-level
|
||||
# filtering (not the global has_perm check) is what's under test
|
||||
requester.user_permissions.add(
|
||||
@@ -773,8 +773,8 @@ class TestBulkEditObjectsApplyToAllPermissionBoundary:
|
||||
request rather than being silently skipped. Editing permissions is
|
||||
limited to the owner, same as documents.
|
||||
"""
|
||||
owner = User.objects.create_user(username="shared_tags_owner")
|
||||
requester = User.objects.create_user(username="shared_tags_requester")
|
||||
owner = UserFactory(username="shared_tags_owner")
|
||||
requester = UserFactory(username="shared_tags_requester")
|
||||
requester.user_permissions.add(
|
||||
Permission.objects.get(codename="change_tag"),
|
||||
)
|
||||
@@ -833,9 +833,9 @@ class TestBulkEditObjectsTagDescendantPartialPermission:
|
||||
would pass/fail based on FK cascade behavior, not on whether the
|
||||
descendant-expansion logic itself respected per-object permissions.
|
||||
"""
|
||||
owner = User.objects.create_user(username="tag_hierarchy_owner")
|
||||
requester = User.objects.create_user(username="tag_hierarchy_requester")
|
||||
new_owner = User.objects.create_user(username="tag_hierarchy_new_owner")
|
||||
owner = UserFactory(username="tag_hierarchy_owner")
|
||||
requester = UserFactory(username="tag_hierarchy_requester")
|
||||
new_owner = UserFactory(username="tag_hierarchy_new_owner")
|
||||
# global change_tag permission so the has_perm() gate passes and the
|
||||
# object-level permitted_object_ids filtering is what's under test
|
||||
requester.user_permissions.add(
|
||||
@@ -892,7 +892,7 @@ class TestRestrictQuerysetToVisible:
|
||||
- The queryset is returned unfiltered, rather than
|
||||
permitted_object_ids(None, ...)'s narrower "unowned rows only"
|
||||
"""
|
||||
owner = User.objects.create_user(username="vis_none_owner")
|
||||
owner = UserFactory(username="vis_none_owner")
|
||||
tag = TagFactory(owner=owner)
|
||||
|
||||
visible = restrict_queryset_to_visible(Tag.objects.all(), None, "view_tag")
|
||||
@@ -909,8 +909,8 @@ class TestRestrictQuerysetToVisible:
|
||||
- The queryset is returned unfiltered, skipping the permission
|
||||
lookup entirely
|
||||
"""
|
||||
superuser = User.objects.create_superuser(username="vis_active_super")
|
||||
owner = User.objects.create_user(username="vis_active_super_owner")
|
||||
superuser = UserFactory(username="vis_active_super", superuser=True)
|
||||
owner = UserFactory(username="vis_active_super_owner")
|
||||
tag = TagFactory(owner=owner)
|
||||
|
||||
visible = restrict_queryset_to_visible(
|
||||
@@ -932,7 +932,7 @@ class TestRestrictQuerysetToVisible:
|
||||
deactivation has to win over the superuser shortcut, matching
|
||||
permitted_object_ids's own ordering
|
||||
"""
|
||||
user = User.objects.create_user(
|
||||
user = UserFactory(
|
||||
username="vis_inactive_super",
|
||||
is_active=False,
|
||||
is_superuser=True,
|
||||
@@ -953,8 +953,8 @@ class TestRestrictQuerysetToVisible:
|
||||
THEN:
|
||||
- Only the rows permitted_object_ids() reports are visible
|
||||
"""
|
||||
user = User.objects.create_user(username="vis_regular")
|
||||
other = User.objects.create_user(username="vis_regular_other")
|
||||
user = UserFactory(username="vis_regular")
|
||||
other = UserFactory(username="vis_regular_other")
|
||||
own = TagFactory(owner=user)
|
||||
hidden = TagFactory(owner=other)
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import pytest
|
||||
from django.contrib.auth.models import User
|
||||
from guardian.shortcuts import assign_perm
|
||||
from rest_framework.test import APIRequestFactory
|
||||
|
||||
from documents.filters import PermittedObjectsFilter
|
||||
from documents.models import Tag
|
||||
from paperless_testing.factories import TagFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class _DummyView:
|
||||
@@ -15,8 +15,8 @@ class _DummyView:
|
||||
@pytest.mark.django_db
|
||||
class TestPermittedObjectsFilter:
|
||||
def test_superuser_bypasses_filtering_entirely(self):
|
||||
superuser = User.objects.create_superuser(username="root")
|
||||
owner = User.objects.create_user(username="owner")
|
||||
superuser = UserFactory(username="root", superuser=True)
|
||||
owner = UserFactory(username="owner")
|
||||
TagFactory(owner=owner)
|
||||
request = APIRequestFactory().get("/")
|
||||
request.user = superuser
|
||||
@@ -29,8 +29,8 @@ class TestPermittedObjectsFilter:
|
||||
assert result.count() == Tag.objects.count()
|
||||
|
||||
def test_non_superuser_sees_only_owned_unowned_and_granted(self):
|
||||
owner = User.objects.create_user(username="owner")
|
||||
grantee = User.objects.create_user(username="grantee")
|
||||
owner = UserFactory(username="owner")
|
||||
grantee = UserFactory(username="grantee")
|
||||
owned = TagFactory(owner=grantee)
|
||||
unowned = TagFactory(owner=None)
|
||||
granted = TagFactory(owner=owner)
|
||||
@@ -49,8 +49,8 @@ class TestPermittedObjectsFilter:
|
||||
assert hidden.pk not in visible_ids
|
||||
|
||||
def test_include_granted_false_excludes_explicitly_shared_objects(self):
|
||||
owner = User.objects.create_user(username="owner2")
|
||||
grantee = User.objects.create_user(username="grantee2")
|
||||
owner = UserFactory(username="owner2")
|
||||
grantee = UserFactory(username="grantee2")
|
||||
owned = TagFactory(owner=grantee)
|
||||
granted = TagFactory(owner=owner)
|
||||
assign_perm("view_tag", grantee, granted)
|
||||
@@ -74,14 +74,14 @@ class TestPermittedObjectsFilter:
|
||||
[("inactive", False), ("inactive_super", True)],
|
||||
)
|
||||
def test_inactive_user_sees_nothing(self, username: str, *, is_superuser: bool):
|
||||
user = User.objects.create_user(
|
||||
user = UserFactory(
|
||||
username=username,
|
||||
is_active=False,
|
||||
is_superuser=is_superuser,
|
||||
)
|
||||
TagFactory(owner=None)
|
||||
TagFactory(owner=user)
|
||||
granted = TagFactory(owner=User.objects.create_user(username=f"o_{username}"))
|
||||
granted = TagFactory(owner=UserFactory(username=f"o_{username}"))
|
||||
assign_perm("view_tag", user, granted)
|
||||
request = APIRequestFactory().get("/")
|
||||
request.user = user
|
||||
@@ -94,7 +94,7 @@ class TestPermittedObjectsFilter:
|
||||
assert result.count() == 0
|
||||
|
||||
def test_inactive_user_sees_nothing_with_include_granted_false(self):
|
||||
user = User.objects.create_user(username="inactive_owner", is_active=False)
|
||||
user = UserFactory(username="inactive_owner", is_active=False)
|
||||
TagFactory(owner=user)
|
||||
TagFactory(owner=None)
|
||||
request = APIRequestFactory().get("/")
|
||||
|
||||
@@ -22,6 +22,7 @@ from documents.tasks import build_share_link_bundle
|
||||
from documents.tasks import cleanup_expired_share_link_bundles
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import DocumentFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class ShareLinkBundleAPITests(DirectoriesMixin, APITestCase):
|
||||
@@ -29,7 +30,7 @@ class ShareLinkBundleAPITests(DirectoriesMixin, APITestCase):
|
||||
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
self.user = User.objects.create_superuser(username="bundle_admin")
|
||||
self.user = UserFactory(username="bundle_admin", superuser=True)
|
||||
self.client.force_authenticate(self.user)
|
||||
self.document = DocumentFactory.create()
|
||||
|
||||
@@ -55,8 +56,8 @@ class ShareLinkBundleAPITests(DirectoriesMixin, APITestCase):
|
||||
self,
|
||||
delay_mock,
|
||||
) -> None:
|
||||
owner = User.objects.create_user(username="document_owner")
|
||||
requester = User.objects.create_user(username="bundle_creator")
|
||||
owner = UserFactory(username="document_owner")
|
||||
requester = UserFactory(username="bundle_creator")
|
||||
requester.user_permissions.add(
|
||||
Permission.objects.get(codename="add_sharelinkbundle"),
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from unittest import mock
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
@@ -14,12 +13,13 @@ from documents.models import WorkflowTrigger
|
||||
from documents.serialisers import TagSerializer
|
||||
from documents.signals.handlers import run_workflows
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestTagHierarchyPermissions(APITestCase):
|
||||
def test_children_only_include_visible_tags(self) -> None:
|
||||
owner = User.objects.create_user(username="owner")
|
||||
requester = User.objects.create_user(username="requester")
|
||||
owner = UserFactory(username="owner")
|
||||
requester = UserFactory(username="requester")
|
||||
requester.user_permissions.add(
|
||||
Permission.objects.get(codename="view_tag"),
|
||||
)
|
||||
@@ -49,7 +49,7 @@ class TestTagHierarchyPermissions(APITestCase):
|
||||
class TestTagHierarchy(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
self.user = User.objects.create_superuser(username="admin")
|
||||
self.user = UserFactory(username="admin", superuser=True)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
self.parent = Tag.objects.create(name="Parent")
|
||||
|
||||
@@ -18,6 +18,7 @@ from documents.signals.handlers import task_postrun_handler
|
||||
from documents.signals.handlers import task_prerun_handler
|
||||
from documents.signals.handlers import task_revoked_handler
|
||||
from paperless_testing.factories import PaperlessTaskFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -34,8 +35,8 @@ def consume_input_doc():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def consume_overrides(django_user_model):
|
||||
user = django_user_model.objects.create_user(username="testuser")
|
||||
def consume_overrides():
|
||||
user = UserFactory(username="testuser")
|
||||
overrides = mock.MagicMock(spec=DocumentMetadataOverrides)
|
||||
overrides.owner_id = user.id
|
||||
return overrides
|
||||
|
||||
@@ -34,6 +34,7 @@ from paperless.models import ApplicationConfiguration
|
||||
from paperless_ai.exceptions import LLMProviderError
|
||||
from paperless_ai.exceptions import LLMTimeoutError
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestViews(DirectoriesMixin, TestCase):
|
||||
@@ -43,7 +44,7 @@ class TestViews(DirectoriesMixin, TestCase):
|
||||
ApplicationConfiguration.objects.get_or_create()
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.user = User.objects.create_user("testuser")
|
||||
self.user = UserFactory(username="testuser")
|
||||
super().setUp()
|
||||
|
||||
def test_login_redirect(self) -> None:
|
||||
@@ -338,7 +339,7 @@ class TestViews(DirectoriesMixin, TestCase):
|
||||
|
||||
class TestAISuggestions(DirectoriesMixin, TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.user = User.objects.create_superuser(username="testuser")
|
||||
self.user = UserFactory(username="testuser", superuser=True)
|
||||
self.document = Document.objects.create(
|
||||
title="Test Document",
|
||||
filename="test.pdf",
|
||||
@@ -425,9 +426,9 @@ class TestAISuggestions(DirectoriesMixin, TestCase):
|
||||
requester; the invisible tag id does not leak into either the
|
||||
matched or suggested tags
|
||||
"""
|
||||
tag_owner = User.objects.create_user(username="cache_tag_owner")
|
||||
tag_owner = UserFactory(username="cache_tag_owner")
|
||||
invisible_tag = Tag.objects.create(name="cache_restricted", owner=tag_owner)
|
||||
requester = User.objects.create_user(username="cache_requester")
|
||||
requester = UserFactory(username="cache_requester")
|
||||
requester.user_permissions.add(
|
||||
*Permission.objects.filter(
|
||||
codename__in=["view_document", "change_document", "view_tag"],
|
||||
@@ -637,7 +638,7 @@ class TestAISuggestions(DirectoriesMixin, TestCase):
|
||||
- The classification runs with the second user's visibility
|
||||
context without evicting the first user's result
|
||||
"""
|
||||
second_user = User.objects.create_superuser(username="second_user")
|
||||
second_user = UserFactory(username="second_user", superuser=True)
|
||||
empty_choices = {
|
||||
"tags": {"existing_ids": [], "new_names": []},
|
||||
"correspondents": {"existing_ids": [], "new_names": []},
|
||||
@@ -875,9 +876,9 @@ class TestAISuggestions(DirectoriesMixin, TestCase):
|
||||
permission filtering survives the full request path
|
||||
- it does not appear in either the matched or suggested tags
|
||||
"""
|
||||
tag_owner = User.objects.create_user(username="tagowner")
|
||||
tag_owner = UserFactory(username="tagowner")
|
||||
invisible_tag = Tag.objects.create(name="restricted", owner=tag_owner)
|
||||
requester = User.objects.create_user(username="requester")
|
||||
requester = UserFactory(username="requester")
|
||||
requester.user_permissions.add(
|
||||
*Permission.objects.filter(
|
||||
codename__in=["view_document", "change_document", "view_tag"],
|
||||
@@ -956,7 +957,7 @@ class TestAIChatStreamingView(DirectoriesMixin, TestCase):
|
||||
ENDPOINT = "/api/documents/chat/"
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.user = User.objects.create_user(username="testuser", password="pass")
|
||||
self.user = UserFactory(username="testuser", password="pass")
|
||||
self.client.force_login(user=self.user)
|
||||
self.document = Document.objects.create(
|
||||
title="Test Document",
|
||||
|
||||
@@ -71,6 +71,7 @@ from documents.workflows.actions import execute_password_removal_action
|
||||
from paperless_mail.models import MailAccount
|
||||
from paperless_mail.models import MailRule
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestWorkflows(
|
||||
@@ -1952,7 +1953,7 @@ class TestWorkflows(
|
||||
original_filename="sample.pdf",
|
||||
)
|
||||
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
self.client.force_authenticate(user=superuser)
|
||||
|
||||
self.client.patch(
|
||||
@@ -1982,7 +1983,7 @@ class TestWorkflows(
|
||||
w.actions.add(action)
|
||||
w.save()
|
||||
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
self.client.force_authenticate(user=superuser)
|
||||
test_file = shutil.copy(
|
||||
self.SAMPLE_DIR / "simple.pdf",
|
||||
@@ -2040,7 +2041,7 @@ class TestWorkflows(
|
||||
value_text="existing value",
|
||||
)
|
||||
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
self.client.force_authenticate(user=superuser)
|
||||
|
||||
self.client.patch(
|
||||
@@ -2084,7 +2085,7 @@ class TestWorkflows(
|
||||
)
|
||||
CustomFieldInstance.objects.create(document=doc, field=self.cf1)
|
||||
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
self.client.force_authenticate(user=superuser)
|
||||
|
||||
self.client.patch(
|
||||
@@ -2134,7 +2135,7 @@ class TestWorkflows(
|
||||
assign_perm("documents.view_document", self.group1, doc)
|
||||
assign_perm("documents.change_document", self.group1, doc)
|
||||
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
self.client.force_authenticate(user=superuser)
|
||||
|
||||
self.client.patch(
|
||||
@@ -2905,7 +2906,7 @@ class TestWorkflows(
|
||||
assign_perm("documents.view_document", self.group1, doc)
|
||||
assign_perm("documents.change_document", self.group1, doc)
|
||||
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
self.client.force_authenticate(user=superuser)
|
||||
|
||||
self.client.patch(
|
||||
@@ -2977,7 +2978,7 @@ class TestWorkflows(
|
||||
doc.refresh_from_db()
|
||||
doc.tags.set([self.t1, self.t2])
|
||||
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
self.client.force_authenticate(user=superuser)
|
||||
self.client.patch(
|
||||
f"/api/documents/{doc.id}/",
|
||||
@@ -3041,7 +3042,7 @@ class TestWorkflows(
|
||||
doc.refresh_from_db()
|
||||
doc.tags.set([self.t1])
|
||||
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
self.client.force_authenticate(user=superuser)
|
||||
self.client.patch(
|
||||
f"/api/documents/{doc.id}/",
|
||||
@@ -3102,7 +3103,7 @@ class TestWorkflows(
|
||||
assign_perm("documents.view_document", self.group1, doc)
|
||||
assign_perm("documents.change_document", self.group1, doc)
|
||||
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
self.client.force_authenticate(user=superuser)
|
||||
|
||||
self.client.patch(
|
||||
@@ -3395,7 +3396,7 @@ class TestWorkflows(
|
||||
original_filename="sample.pdf",
|
||||
)
|
||||
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
self.client.force_authenticate(user=superuser)
|
||||
|
||||
self.client.patch(
|
||||
@@ -5357,7 +5358,7 @@ class TestDateWorkflowLocalization(
|
||||
c = Correspondent.objects.create(name="Correspondent Name")
|
||||
|
||||
client = APIClient()
|
||||
superuser = User.objects.create_superuser("superuser")
|
||||
superuser = UserFactory(username="superuser", superuser=True)
|
||||
client.force_authenticate(user=superuser)
|
||||
|
||||
trigger = WorkflowTrigger.objects.create(
|
||||
|
||||
@@ -2,22 +2,20 @@ import os
|
||||
from unittest import mock
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import override_settings
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from paperless.settings import _parse_remote_user_settings
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestRemoteUser(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_superuser(
|
||||
username="temp_admin",
|
||||
)
|
||||
self.user = UserFactory(username="temp_admin", superuser=True)
|
||||
|
||||
def test_remote_user(self) -> None:
|
||||
"""
|
||||
|
||||
@@ -15,6 +15,7 @@ from pytest_mock import MockerFixture
|
||||
from rest_framework.authtoken.models import Token
|
||||
|
||||
from paperless.adapter import DrfTokenStrategy
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@@ -25,7 +26,7 @@ class TestCustomAccountAdapter:
|
||||
# With no accounts, signups should be allowed
|
||||
assert adapter.is_open_for_signup(None)
|
||||
|
||||
User.objects.create_user("testuser")
|
||||
UserFactory(username="testuser")
|
||||
|
||||
settings.ACCOUNT_ALLOW_SIGNUPS = True
|
||||
assert adapter.is_open_for_signup(None)
|
||||
@@ -92,7 +93,7 @@ class TestCustomAccountAdapter:
|
||||
) -> None:
|
||||
settings.ACCOUNT_DEFAULT_GROUPS = ["group1", "group2"]
|
||||
Group.objects.create(name="group1")
|
||||
user = User.objects.create_user("testuser")
|
||||
user = UserFactory(username="testuser")
|
||||
adapter = get_adapter()
|
||||
form = mocker.MagicMock(
|
||||
cleaned_data={
|
||||
@@ -152,7 +153,7 @@ class TestCustomSocialAccountAdapter:
|
||||
settings.SOCIAL_ACCOUNT_DEFAULT_GROUPS = ["group1", "group2"]
|
||||
Group.objects.create(name="group1")
|
||||
adapter = get_social_adapter()
|
||||
user = User.objects.create_user("testuser")
|
||||
user = UserFactory(username="testuser")
|
||||
sociallogin = mocker.MagicMock(user=user)
|
||||
|
||||
user = adapter.save_user(HttpRequest(), sociallogin, None)
|
||||
@@ -187,7 +188,7 @@ class TestDrfTokenStrategy:
|
||||
THEN:
|
||||
- A new token is created and its key is returned
|
||||
"""
|
||||
user = User.objects.create_user("testuser")
|
||||
user = UserFactory(username="testuser")
|
||||
request = HttpRequest()
|
||||
request.user = user
|
||||
|
||||
@@ -207,7 +208,7 @@ class TestDrfTokenStrategy:
|
||||
THEN:
|
||||
- The same token key is returned (no new token created)
|
||||
"""
|
||||
user = User.objects.create_user("testuser")
|
||||
user = UserFactory(username="testuser")
|
||||
existing_token = Token.objects.create(user=user)
|
||||
|
||||
request = HttpRequest()
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import uuid
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import TestCase
|
||||
from django.test import override_settings
|
||||
from django.urls import resolve
|
||||
from django.urls import reverse
|
||||
from rest_framework import status
|
||||
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestApiAuthViews(TestCase):
|
||||
def test_api_auth_login_uses_allauth_login_view(self):
|
||||
@@ -24,10 +25,7 @@ class TestApiAuthViews(TestCase):
|
||||
@override_settings(DISABLE_REGULAR_LOGIN=True)
|
||||
def test_api_auth_login_respects_disable_regular_login(self):
|
||||
username = f"testuser-{uuid.uuid4().hex}"
|
||||
User.objects.create_user(
|
||||
username=username,
|
||||
password="testpassword",
|
||||
)
|
||||
UserFactory(username=username, password="testpassword")
|
||||
|
||||
response = self.client.post(
|
||||
reverse("rest_framework:login"),
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import RequestFactory
|
||||
from django.test import TestCase
|
||||
from django.test import override_settings
|
||||
|
||||
from paperless.auth import AutoLoginMiddleware
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
@override_settings(AUTO_LOGIN_USERNAME="autologin")
|
||||
@@ -29,7 +29,7 @@ class TestAutoLoginMiddleware(TestCase):
|
||||
THEN:
|
||||
- That user is attached to the request
|
||||
"""
|
||||
user = User.objects.create_user(username="autologin")
|
||||
user = UserFactory(username="autologin")
|
||||
|
||||
request = self._process(self.factory.get("/"))
|
||||
|
||||
@@ -44,7 +44,7 @@ class TestAutoLoginMiddleware(TestCase):
|
||||
THEN:
|
||||
- The request is left anonymous rather than authenticated as them
|
||||
"""
|
||||
User.objects.create_user(username="autologin", is_active=False)
|
||||
UserFactory(username="autologin", is_active=False)
|
||||
|
||||
request = self.factory.get("/")
|
||||
request.user = AnonymousUser()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from unittest.mock import Mock
|
||||
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.auth.models import User
|
||||
from django.http import HttpRequest
|
||||
from django.test import TestCase
|
||||
from django.test import override_settings
|
||||
@@ -9,6 +8,7 @@ from django.test import override_settings
|
||||
from documents.models import UiSettings
|
||||
from paperless.signals import handle_failed_login
|
||||
from paperless.signals import handle_social_account_updated
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestFailedLoginLogging(TestCase):
|
||||
@@ -120,7 +120,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
- The user's groups are updated to match the social login's groups
|
||||
"""
|
||||
group = Group.objects.create(name="group1")
|
||||
user = User.objects.create_user(username="testuser")
|
||||
user = UserFactory(username="testuser")
|
||||
sociallogin = Mock(
|
||||
user=user,
|
||||
account=Mock(
|
||||
@@ -147,7 +147,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
- The user's groups are not updated
|
||||
"""
|
||||
Group.objects.create(name="group1")
|
||||
user = User.objects.create_user(username="testuser")
|
||||
user = UserFactory(username="testuser")
|
||||
sociallogin = Mock(
|
||||
user=user,
|
||||
account=Mock(
|
||||
@@ -180,7 +180,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
would be rejected for a deactivated user anyway
|
||||
"""
|
||||
Group.objects.create(name="admin-group")
|
||||
user = User.objects.create_user(
|
||||
user = UserFactory(
|
||||
username="inactive_user",
|
||||
is_active=False,
|
||||
is_superuser=False,
|
||||
@@ -215,7 +215,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
- The user's groups are cleared to match the social login's groups
|
||||
"""
|
||||
group = Group.objects.create(name="group1")
|
||||
user = User.objects.create_user(username="testuser")
|
||||
user = UserFactory(username="testuser")
|
||||
user.groups.add(group)
|
||||
user.save()
|
||||
sociallogin = Mock(
|
||||
@@ -244,7 +244,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
- The user's groups are updated using `userinfo.groups`
|
||||
"""
|
||||
group = Group.objects.create(name="group1")
|
||||
user = User.objects.create_user(username="testuser")
|
||||
user = UserFactory(username="testuser")
|
||||
sociallogin = Mock(
|
||||
user=user,
|
||||
account=Mock(
|
||||
@@ -275,7 +275,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
- The user's groups are updated using `id_token.groups`
|
||||
"""
|
||||
group = Group.objects.create(name="group1")
|
||||
user = User.objects.create_user(username="testuser")
|
||||
user = UserFactory(username="testuser")
|
||||
sociallogin = Mock(
|
||||
user=user,
|
||||
account=Mock(
|
||||
@@ -310,11 +310,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
THEN:
|
||||
- User is not promoted, since only an exact group match counts
|
||||
"""
|
||||
user = User.objects.create_user(
|
||||
username="testuser",
|
||||
is_superuser=False,
|
||||
is_staff=False,
|
||||
)
|
||||
user = UserFactory(username="testuser", is_superuser=False, is_staff=False)
|
||||
sociallogin = Mock(
|
||||
user=user,
|
||||
account=Mock(
|
||||
@@ -345,11 +341,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
THEN:
|
||||
- User becomes superuser and staff
|
||||
"""
|
||||
user = User.objects.create_user(
|
||||
username="testuser_s_e",
|
||||
is_superuser=False,
|
||||
is_staff=False,
|
||||
)
|
||||
user = UserFactory(username="testuser_s_e", is_superuser=False, is_staff=False)
|
||||
sociallogin = Mock(
|
||||
user=user,
|
||||
account=Mock(
|
||||
@@ -380,11 +372,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
THEN:
|
||||
- User loses superuser status but preserves staff status if they had it
|
||||
"""
|
||||
user = User.objects.create_user(
|
||||
username="testuser_s_d",
|
||||
is_superuser=True,
|
||||
is_staff=True,
|
||||
)
|
||||
user = UserFactory(username="testuser_s_d", is_superuser=True, is_staff=True)
|
||||
sociallogin = Mock(
|
||||
user=user,
|
||||
account=Mock(
|
||||
@@ -415,11 +403,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
THEN:
|
||||
- User becomes staff
|
||||
"""
|
||||
user = User.objects.create_user(
|
||||
username="testuser_st_e",
|
||||
is_superuser=False,
|
||||
is_staff=False,
|
||||
)
|
||||
user = UserFactory(username="testuser_st_e", is_superuser=False, is_staff=False)
|
||||
sociallogin = Mock(
|
||||
user=user,
|
||||
account=Mock(
|
||||
@@ -450,11 +434,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
THEN:
|
||||
- User loses staff status
|
||||
"""
|
||||
user = User.objects.create_user(
|
||||
username="testuser_st_d",
|
||||
is_superuser=False,
|
||||
is_staff=True,
|
||||
)
|
||||
user = UserFactory(username="testuser_st_d", is_superuser=False, is_staff=True)
|
||||
sociallogin = Mock(
|
||||
user=user,
|
||||
account=Mock(
|
||||
@@ -485,11 +465,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
- Roles are correctly assigned/revoked according to groups
|
||||
"""
|
||||
# Case 1: has both
|
||||
user = User.objects.create_user(
|
||||
username="testuser_b_1",
|
||||
is_superuser=False,
|
||||
is_staff=False,
|
||||
)
|
||||
user = UserFactory(username="testuser_b_1", is_superuser=False, is_staff=False)
|
||||
sociallogin = Mock(
|
||||
user=user,
|
||||
account=Mock(extra_data={"groups": ["admin-group", "staff-group"]}),
|
||||
@@ -504,11 +480,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
self.assertTrue(user.is_staff)
|
||||
|
||||
# Case 2: has only staff
|
||||
user2 = User.objects.create_user(
|
||||
username="testuser_b_2",
|
||||
is_superuser=True,
|
||||
is_staff=True,
|
||||
)
|
||||
user2 = UserFactory(username="testuser_b_2", is_superuser=True, is_staff=True)
|
||||
sociallogin2 = Mock(
|
||||
user=user2,
|
||||
account=Mock(extra_data={"groups": ["staff-group"]}),
|
||||
@@ -523,11 +495,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
self.assertTrue(user2.is_staff)
|
||||
|
||||
# Case 3: has neither
|
||||
user3 = User.objects.create_user(
|
||||
username="testuser_b_3",
|
||||
is_superuser=True,
|
||||
is_staff=True,
|
||||
)
|
||||
user3 = UserFactory(username="testuser_b_3", is_superuser=True, is_staff=True)
|
||||
sociallogin3 = Mock(
|
||||
user=user3,
|
||||
account=Mock(extra_data={"groups": ["other-group"]}),
|
||||
@@ -554,11 +522,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
THEN:
|
||||
- Existing roles are not modified
|
||||
"""
|
||||
user = User.objects.create_user(
|
||||
username="testuser_n_s",
|
||||
is_superuser=True,
|
||||
is_staff=True,
|
||||
)
|
||||
user = UserFactory(username="testuser_n_s", is_superuser=True, is_staff=True)
|
||||
sociallogin = Mock(
|
||||
user=user,
|
||||
account=Mock(extra_data={"groups": ["admin-group", "staff-group"]}),
|
||||
@@ -586,7 +550,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
THEN:
|
||||
- User's superuser status is demoted, matching the group claim exactly
|
||||
"""
|
||||
user = User.objects.create_user(
|
||||
user = UserFactory(
|
||||
username="local_admin",
|
||||
password="password123",
|
||||
is_superuser=True,
|
||||
@@ -618,11 +582,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
THEN:
|
||||
- User's superuser status is demoted, even though they are the last admin
|
||||
"""
|
||||
user = User.objects.create_user(
|
||||
username="last_admin",
|
||||
is_superuser=True,
|
||||
is_staff=True,
|
||||
)
|
||||
user = UserFactory(username="last_admin", is_superuser=True, is_staff=True)
|
||||
user.set_unusable_password()
|
||||
user.save()
|
||||
|
||||
@@ -652,7 +612,7 @@ class TestSyncSocialLoginGroups(TestCase):
|
||||
THEN:
|
||||
- User's staff status is demoted, matching the group claim exactly
|
||||
"""
|
||||
user = User.objects.create_user(
|
||||
user = UserFactory(
|
||||
username="local_staff",
|
||||
password="password123",
|
||||
is_superuser=False,
|
||||
@@ -688,8 +648,8 @@ class TestUserGroupDeletionCleanup(TestCase):
|
||||
THEN:
|
||||
- References in ui_settings are cleaned up
|
||||
"""
|
||||
user = User.objects.create_user(username="testuser")
|
||||
user2 = User.objects.create_user(username="testuser2")
|
||||
user = UserFactory(username="testuser")
|
||||
user2 = UserFactory(username="testuser2")
|
||||
group = Group.objects.create(name="testgroup")
|
||||
|
||||
ui_settings = UiSettings.objects.create(
|
||||
@@ -727,8 +687,8 @@ class TestUserGroupDeletionCleanup(TestCase):
|
||||
THEN:
|
||||
- Error is logged and the system remains stable
|
||||
"""
|
||||
user = User.objects.create_user(username="testuser")
|
||||
user2 = User.objects.create_user(username="testuser2")
|
||||
user = UserFactory(username="testuser")
|
||||
user2 = UserFactory(username="testuser2")
|
||||
user2_id = user2.id
|
||||
Group.objects.create(name="testgroup")
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import CorrespondentFactory
|
||||
from paperless_testing.factories import DocumentTypeFactory
|
||||
from paperless_testing.factories import TagFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
@@ -33,7 +34,7 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_user(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin")
|
||||
self.user.user_permissions.add(*Permission.objects.all())
|
||||
self.user.save()
|
||||
self.client.force_authenticate(user=self.user)
|
||||
@@ -291,7 +292,7 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
imap_port=443,
|
||||
owner=None,
|
||||
)
|
||||
user = User.objects.create_user(username="no_perms")
|
||||
user = UserFactory(username="no_perms")
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
response = self.client.post(
|
||||
@@ -321,7 +322,7 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- API returns forbidden
|
||||
"""
|
||||
owner = User.objects.create_user(username="account_owner")
|
||||
owner = UserFactory(username="account_owner")
|
||||
account = MailAccountFactory(
|
||||
username="admin",
|
||||
password="secret",
|
||||
@@ -329,7 +330,7 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
imap_port=443,
|
||||
owner=owner,
|
||||
)
|
||||
user = User.objects.create_user(username="object_perms_only")
|
||||
user = UserFactory(username="object_perms_only")
|
||||
assign_perm("change_mailaccount", user, account)
|
||||
self.client.force_authenticate(user=user)
|
||||
|
||||
@@ -377,7 +378,7 @@ class TestAPIMailAccounts(DirectoriesMixin, APITestCase):
|
||||
- Only unowned, owned by user or granted accounts are provided
|
||||
"""
|
||||
|
||||
user2 = User.objects.create_user(username="temp_admin2")
|
||||
user2 = UserFactory(username="temp_admin2")
|
||||
|
||||
account1 = MailAccountFactory(name="Email1")
|
||||
account2 = MailAccountFactory(name="Email2", owner=self.user)
|
||||
@@ -400,7 +401,7 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_user(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin")
|
||||
self.user.user_permissions.add(*Permission.objects.all())
|
||||
self.user.save()
|
||||
self.client.force_authenticate(user=self.user)
|
||||
@@ -590,7 +591,7 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(returned_rule1.action, MailRule.MailAction.DELETE)
|
||||
|
||||
def test_create_mail_rule_scopes_accounts(self) -> None:
|
||||
other_user = User.objects.create_user(username="mail-owner")
|
||||
other_user = UserFactory(username="mail-owner")
|
||||
foreign_account = MailAccountFactory(name="ForeignEmail", owner=other_user)
|
||||
|
||||
response = self.client.post(
|
||||
@@ -633,7 +634,7 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
def test_create_mail_rule_allowed_for_granted_account_change_permission(
|
||||
self,
|
||||
) -> None:
|
||||
other_user = User.objects.create_user(username="mail-owner")
|
||||
other_user = UserFactory(username="mail-owner")
|
||||
foreign_account = MailAccountFactory(name="ForeignEmail", owner=other_user)
|
||||
assign_perm("change_mailaccount", self.user, foreign_account)
|
||||
|
||||
@@ -658,7 +659,7 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
|
||||
def test_update_mail_rule_forbidden_for_unpermitted_account(self) -> None:
|
||||
own_account = MailAccountFactory()
|
||||
other_user = User.objects.create_user(username="mail-owner")
|
||||
other_user = UserFactory(username="mail-owner")
|
||||
foreign_account = MailAccountFactory(owner=other_user)
|
||||
rule1 = MailRuleFactory(account=own_account)
|
||||
|
||||
@@ -681,7 +682,7 @@ class TestAPIMailRules(DirectoriesMixin, APITestCase):
|
||||
- Only unowned, owned by user or granted mail rules are provided
|
||||
"""
|
||||
|
||||
user2 = User.objects.create_user(username="temp_admin2")
|
||||
user2 = UserFactory(username="temp_admin2")
|
||||
account1 = MailAccountFactory()
|
||||
rule1 = MailRuleFactory(account=account1, order=0)
|
||||
rule2 = MailRuleFactory(account=account1, order=1, owner=self.user)
|
||||
@@ -737,7 +738,7 @@ class TestAPIProcessedMails(DirectoriesMixin, APITestCase):
|
||||
def setUp(self) -> None:
|
||||
super().setUp()
|
||||
|
||||
self.user = User.objects.create_user(username="temp_admin")
|
||||
self.user = UserFactory(username="temp_admin")
|
||||
self.user.user_permissions.add(*Permission.objects.all())
|
||||
self.user.save()
|
||||
self.client.force_authenticate(user=self.user)
|
||||
@@ -751,7 +752,7 @@ class TestAPIProcessedMails(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Only unowned, owned by user or granted processed mails are provided
|
||||
"""
|
||||
user2 = User.objects.create_user(username="temp_admin2")
|
||||
user2 = UserFactory(username="temp_admin2")
|
||||
rule = MailRuleFactory()
|
||||
pm1 = ProcessedMailFactory(rule=rule)
|
||||
pm2 = ProcessedMailFactory(
|
||||
@@ -802,7 +803,7 @@ class TestAPIProcessedMails(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- Only the specified processed mails are deleted, respecting ownership and permissions
|
||||
"""
|
||||
user2 = User.objects.create_user(username="temp_admin2")
|
||||
user2 = UserFactory(username="temp_admin2")
|
||||
rule = MailRuleFactory()
|
||||
# unowned, owned by self, and one with explicit object perm
|
||||
pm_unowned = ProcessedMailFactory(rule=rule)
|
||||
@@ -855,8 +856,8 @@ class TestAPIProcessedMails(DirectoriesMixin, APITestCase):
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def test_bulk_delete_requires_global_delete_permission(self) -> None:
|
||||
owner = User.objects.create_user(username="mail_owner")
|
||||
requester = User.objects.create_user(username="mail_deleter")
|
||||
owner = UserFactory(username="mail_owner")
|
||||
requester = UserFactory(username="mail_deleter")
|
||||
requester.user_permissions.add(
|
||||
Permission.objects.get(codename="add_processedmail"),
|
||||
)
|
||||
@@ -893,7 +894,7 @@ class TestAPIProcessedMails(DirectoriesMixin, APITestCase):
|
||||
THEN:
|
||||
- The request is rejected and neither mail is deleted
|
||||
"""
|
||||
user2 = User.objects.create_user(username="temp_admin2")
|
||||
user2 = UserFactory(username="temp_admin2")
|
||||
rule = MailRuleFactory()
|
||||
# Created first so it sorts ahead of the forbidden mail, i.e. the
|
||||
# permission check has to cover the whole batch before deleting rather
|
||||
|
||||
@@ -9,7 +9,6 @@ from unittest import mock
|
||||
|
||||
import pytest
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.management import call_command
|
||||
from django.db import DatabaseError
|
||||
from django.test import TestCase
|
||||
@@ -43,6 +42,7 @@ from paperless_mail.tests.factories import MailAccountFactory
|
||||
from paperless_mail.tests.factories import MailRuleFactory
|
||||
from paperless_testing.dirs import DirectoriesMixin
|
||||
from paperless_testing.factories import CorrespondentFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
@@ -2263,10 +2263,7 @@ class TestMailAccountTestView(APITestCase):
|
||||
self.mailMocker = MailMocker()
|
||||
self.mailMocker.setUp()
|
||||
self.addCleanup(self.mailMocker.doCleanups)
|
||||
self.user = User.objects.create_user(
|
||||
username="testuser",
|
||||
password="testpassword",
|
||||
)
|
||||
self.user = UserFactory(username="testuser", password="testpassword")
|
||||
self.user.user_permissions.add(
|
||||
*Permission.objects.filter(
|
||||
codename__in=["add_mailaccount", "change_mailaccount"],
|
||||
@@ -2409,10 +2406,7 @@ class TestMailAccountTestView(APITestCase):
|
||||
self.assertIn(expected_str, error_str)
|
||||
|
||||
def test_mail_account_test_view_existing_forbidden_for_other_owner(self) -> None:
|
||||
other_user = User.objects.create_user(
|
||||
username="otheruser",
|
||||
password="testpassword",
|
||||
)
|
||||
other_user = UserFactory(username="otheruser", password="testpassword")
|
||||
existing_account = MailAccount.objects.create(
|
||||
name="Owned account",
|
||||
imap_server="imap.example.com",
|
||||
@@ -2535,9 +2529,10 @@ class TestMailAccountProcess(APITestCase):
|
||||
self.mailMocker = MailMocker()
|
||||
self.mailMocker.setUp()
|
||||
self.addCleanup(self.mailMocker.doCleanups)
|
||||
self.user = User.objects.create_superuser(
|
||||
self.user = UserFactory(
|
||||
username="testuser",
|
||||
password="testpassword",
|
||||
superuser=True,
|
||||
)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
self.account = MailAccount.objects.create(
|
||||
@@ -2560,9 +2555,10 @@ class TestMailAccountProcess(APITestCase):
|
||||
|
||||
class TestMailRuleAPI(APITestCase):
|
||||
def setUp(self) -> None:
|
||||
self.user = User.objects.create_superuser(
|
||||
self.user = UserFactory(
|
||||
username="testuser",
|
||||
password="testpassword",
|
||||
superuser=True,
|
||||
)
|
||||
self.client.force_authenticate(user=self.user)
|
||||
self.account = MailAccountFactory(owner=self.user)
|
||||
|
||||
@@ -2,7 +2,6 @@ from datetime import timedelta
|
||||
from unittest import mock
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from django.test import TestCase
|
||||
from django.test import override_settings
|
||||
from django.utils import timezone
|
||||
@@ -14,6 +13,7 @@ from paperless_mail.mail import MailAccountHandler
|
||||
from paperless_mail.models import MailAccount
|
||||
from paperless_mail.oauth import PaperlessMailOAuth2Manager
|
||||
from paperless_mail.tests.factories import MailAccountFactory
|
||||
from paperless_testing.factories import UserFactory
|
||||
|
||||
|
||||
@override_settings(
|
||||
@@ -27,7 +27,7 @@ class TestMailOAuth(
|
||||
TestCase,
|
||||
):
|
||||
def setUp(self) -> None:
|
||||
self.user = User.objects.create_user("testuser")
|
||||
self.user = UserFactory(username="testuser")
|
||||
self.user.user_permissions.add(
|
||||
*Permission.objects.filter(
|
||||
codename__in=[
|
||||
|
||||
@@ -78,7 +78,10 @@ class UserFactory(DjangoModelFactory[UserModelT]):
|
||||
username = factory.Sequence(lambda n: f"user{n}")
|
||||
is_staff = False
|
||||
is_superuser = False
|
||||
password = factory.django.Password("test")
|
||||
# Hashing a real password costs about half a second per user, and no test
|
||||
# authenticates with its password. None gives the unusable password
|
||||
# create_user() gives.
|
||||
password = factory.django.Password(None)
|
||||
|
||||
class Params:
|
||||
superuser = factory.Trait(is_staff=True, is_superuser=True)
|
||||
|
||||
Reference in New Issue
Block a user