The object getters in matching need to accept none for workflows

This commit is contained in:
shamoon
2026-08-18 19:46:38 -07:00
parent 52dd76c62b
commit f2b5bac1d0
2 changed files with 23 additions and 26 deletions
+17 -7
View File
@@ -11,7 +11,7 @@ from documents.models import Correspondent
from documents.models import DocumentType
from documents.models import StoragePath
from documents.models import Tag
from documents.permissions import get_objects_for_user_owner_aware
from documents.permissions import permitted_object_ids
from documents.permissions import restrict_queryset_to_visible
MATCH_THRESHOLD = 0.8
@@ -63,30 +63,40 @@ def resolve_storage_path_ids(ids: list[int], user: User | None) -> list[StorageP
def _match_by_name(
names: list[str],
user: User,
user: User | None,
model: type[ModelT],
perm: str,
) -> list[ModelT]:
queryset = get_objects_for_user_owner_aware(user, [perm], model)
# A workflow may have no user. In that case permitted_object_ids limits
# matching to unowned objects, avoiding another user's private taxonomy.
queryset = model.objects.filter(
pk__in=permitted_object_ids(user, model, perm),
)
return _match_names_to_queryset(names, queryset)
def match_tags_by_name(names: list[str], user: User) -> list[Tag]:
def match_tags_by_name(names: list[str], user: User | None) -> list[Tag]:
return _match_by_name(names, user, Tag, "view_tag")
def match_correspondents_by_name(
names: list[str],
user: User,
user: User | None,
) -> list[Correspondent]:
return _match_by_name(names, user, Correspondent, "view_correspondent")
def match_document_types_by_name(names: list[str], user: User) -> list[DocumentType]:
def match_document_types_by_name(
names: list[str],
user: User | None,
) -> list[DocumentType]:
return _match_by_name(names, user, DocumentType, "view_documenttype")
def match_storage_paths_by_name(names: list[str], user: User) -> list[StoragePath]:
def match_storage_paths_by_name(
names: list[str],
user: User | None,
) -> list[StoragePath]:
return _match_by_name(names, user, StoragePath, "view_storagepath")
+6 -19
View File
@@ -1,5 +1,4 @@
from collections.abc import Callable
from unittest.mock import patch
import pytest
import pytest_mock
@@ -45,33 +44,25 @@ class TestAIMatching(TestCase):
self.storage_path1 = StoragePath.objects.create(name="Test Storage Path 1")
self.storage_path2 = StoragePath.objects.create(name="Test Storage Path 2")
@patch("paperless_ai.matching.get_objects_for_user_owner_aware")
def test_match_tags_by_name(self, mock_get_objects) -> None:
mock_get_objects.return_value = Tag.objects.all()
def test_match_tags_by_name(self) -> None:
names = ["Test Tag 1", "Nonexistent Tag"]
result = match_tags_by_name(names, user=None)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].name, "Test Tag 1")
@patch("paperless_ai.matching.get_objects_for_user_owner_aware")
def test_match_correspondents_by_name(self, mock_get_objects) -> None:
mock_get_objects.return_value = Correspondent.objects.all()
def test_match_correspondents_by_name(self) -> None:
names = ["Test Correspondent 1", "Nonexistent Correspondent"]
result = match_correspondents_by_name(names, user=None)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].name, "Test Correspondent 1")
@patch("paperless_ai.matching.get_objects_for_user_owner_aware")
def test_match_document_types_by_name(self, mock_get_objects) -> None:
mock_get_objects.return_value = DocumentType.objects.all()
def test_match_document_types_by_name(self) -> None:
names = ["Test Document Type 1", "Nonexistent Document Type"]
result = match_document_types_by_name(names, user=None)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].name, "Test Document Type 1")
@patch("paperless_ai.matching.get_objects_for_user_owner_aware")
def test_match_storage_paths_by_name(self, mock_get_objects) -> None:
mock_get_objects.return_value = StoragePath.objects.all()
def test_match_storage_paths_by_name(self) -> None:
names = ["Test Storage Path 1", "Nonexistent Storage Path"]
result = match_storage_paths_by_name(names, user=None)
self.assertEqual(len(result), 1)
@@ -83,16 +74,12 @@ class TestAIMatching(TestCase):
unmatched_names = extract_unmatched_names(llm_names, matched_objects)
self.assertEqual(unmatched_names, ["Nonexistent Tag"])
@patch("paperless_ai.matching.get_objects_for_user_owner_aware")
def test_match_tags_by_name_with_empty_names(self, mock_get_objects) -> None:
mock_get_objects.return_value = Tag.objects.all()
def test_match_tags_by_name_with_empty_names(self) -> None:
names = [None, "", " "]
result = match_tags_by_name(names, user=None)
self.assertEqual(result, [])
@patch("paperless_ai.matching.get_objects_for_user_owner_aware")
def test_match_tags_with_fuzzy_matching(self, mock_get_objects) -> None:
mock_get_objects.return_value = Tag.objects.all()
def test_match_tags_with_fuzzy_matching(self) -> None:
names = ["Test Taag 1", "Teest Tag 2"]
result = match_tags_by_name(names, user=None)
self.assertEqual(len(result), 2)