mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-23 10:39:25 -05:00
Test views, caching
This commit is contained in:
parent
ddd2428d9c
commit
778f6c8162
@ -1,6 +1,8 @@
|
|||||||
import tempfile
|
import tempfile
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
@ -10,8 +12,15 @@ from django.test import override_settings
|
|||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
|
|
||||||
|
from documents.caching import get_llm_suggestion_cache
|
||||||
|
from documents.caching import set_llm_suggestions_cache
|
||||||
|
from documents.models import Correspondent
|
||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
|
from documents.models import DocumentType
|
||||||
from documents.models import ShareLink
|
from documents.models import ShareLink
|
||||||
|
from documents.models import StoragePath
|
||||||
|
from documents.models import Tag
|
||||||
|
from documents.signals.handlers import update_llm_suggestions_cache
|
||||||
from documents.tests.utils import DirectoriesMixin
|
from documents.tests.utils import DirectoriesMixin
|
||||||
from paperless.models import ApplicationConfiguration
|
from paperless.models import ApplicationConfiguration
|
||||||
|
|
||||||
@ -154,3 +163,104 @@ class TestViews(DirectoriesMixin, TestCase):
|
|||||||
response.render()
|
response.render()
|
||||||
self.assertEqual(response.request["PATH_INFO"], "/accounts/login/")
|
self.assertEqual(response.request["PATH_INFO"], "/accounts/login/")
|
||||||
self.assertContains(response, b"Share link has expired")
|
self.assertContains(response, b"Share link has expired")
|
||||||
|
|
||||||
|
|
||||||
|
class TestAISuggestions(DirectoriesMixin, TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.user = User.objects.create_superuser(username="testuser")
|
||||||
|
self.document = Document.objects.create(
|
||||||
|
title="Test Document",
|
||||||
|
filename="test.pdf",
|
||||||
|
mime_type="application/pdf",
|
||||||
|
)
|
||||||
|
self.tag1 = Tag.objects.create(name="tag1")
|
||||||
|
self.correspondent1 = Correspondent.objects.create(name="correspondent1")
|
||||||
|
self.document_type1 = DocumentType.objects.create(name="type1")
|
||||||
|
self.path1 = StoragePath.objects.create(name="path1")
|
||||||
|
super().setUp()
|
||||||
|
|
||||||
|
@patch("documents.views.get_llm_suggestion_cache")
|
||||||
|
@patch("documents.views.refresh_suggestions_cache")
|
||||||
|
@override_settings(
|
||||||
|
AI_ENABLED=True,
|
||||||
|
LLM_BACKEND="mock_backend",
|
||||||
|
)
|
||||||
|
def test_suggestions_with_cached_llm(self, mock_refresh_cache, mock_get_cache):
|
||||||
|
mock_get_cache.return_value = MagicMock(suggestions={"tags": ["tag1", "tag2"]})
|
||||||
|
|
||||||
|
self.client.force_login(user=self.user)
|
||||||
|
response = self.client.get(f"/api/documents/{self.document.pk}/suggestions/")
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(response.json(), {"tags": ["tag1", "tag2"]})
|
||||||
|
mock_refresh_cache.assert_called_once_with(self.document.pk)
|
||||||
|
|
||||||
|
@patch("documents.views.get_ai_document_classification")
|
||||||
|
@override_settings(
|
||||||
|
AI_ENABLED=True,
|
||||||
|
LLM_BACKEND="mock_backend",
|
||||||
|
)
|
||||||
|
def test_suggestions_with_ai_enabled(
|
||||||
|
self,
|
||||||
|
mock_get_ai_classification,
|
||||||
|
):
|
||||||
|
mock_get_ai_classification.return_value = {
|
||||||
|
"title": "AI Title",
|
||||||
|
"tags": ["tag1", "tag2"],
|
||||||
|
"correspondents": ["correspondent1"],
|
||||||
|
"document_types": ["type1"],
|
||||||
|
"storage_paths": ["path1"],
|
||||||
|
"dates": ["2023-01-01"],
|
||||||
|
}
|
||||||
|
|
||||||
|
self.client.force_login(user=self.user)
|
||||||
|
response = self.client.get(f"/api/documents/{self.document.pk}/suggestions/")
|
||||||
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
self.assertEqual(
|
||||||
|
response.json(),
|
||||||
|
{
|
||||||
|
"title": "AI Title",
|
||||||
|
"tags": [self.tag1.pk],
|
||||||
|
"suggested_tags": ["tag2"],
|
||||||
|
"correspondents": [self.correspondent1.pk],
|
||||||
|
"suggested_correspondents": [],
|
||||||
|
"document_types": [self.document_type1.pk],
|
||||||
|
"suggested_document_types": [],
|
||||||
|
"storage_paths": [self.path1.pk],
|
||||||
|
"suggested_storage_paths": [],
|
||||||
|
"dates": ["2023-01-01"],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_invalidate_suggestions_cache(self):
|
||||||
|
self.client.force_login(user=self.user)
|
||||||
|
suggestions = {
|
||||||
|
"title": "AI Title",
|
||||||
|
"tags": ["tag1", "tag2"],
|
||||||
|
"correspondents": ["correspondent1"],
|
||||||
|
"document_types": ["type1"],
|
||||||
|
"storage_paths": ["path1"],
|
||||||
|
"dates": ["2023-01-01"],
|
||||||
|
}
|
||||||
|
set_llm_suggestions_cache(
|
||||||
|
self.document.pk,
|
||||||
|
suggestions,
|
||||||
|
backend="mock_backend",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
get_llm_suggestion_cache(
|
||||||
|
self.document.pk,
|
||||||
|
backend="mock_backend",
|
||||||
|
).suggestions,
|
||||||
|
suggestions,
|
||||||
|
)
|
||||||
|
# post_save signal triggered
|
||||||
|
update_llm_suggestions_cache(
|
||||||
|
sender=None,
|
||||||
|
instance=self.document,
|
||||||
|
)
|
||||||
|
self.assertIsNone(
|
||||||
|
get_llm_suggestion_cache(
|
||||||
|
self.document.pk,
|
||||||
|
backend="mock_backend",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
@ -739,51 +739,57 @@ class DocumentViewSet(
|
|||||||
return HttpResponseForbidden("Insufficient permissions")
|
return HttpResponseForbidden("Insufficient permissions")
|
||||||
|
|
||||||
if settings.AI_ENABLED:
|
if settings.AI_ENABLED:
|
||||||
cached = get_llm_suggestion_cache(doc.pk, backend=settings.LLM_BACKEND)
|
cached_llm_suggestions = get_llm_suggestion_cache(
|
||||||
|
doc.pk,
|
||||||
|
backend=settings.LLM_BACKEND,
|
||||||
|
)
|
||||||
|
|
||||||
if cached:
|
if cached_llm_suggestions:
|
||||||
refresh_suggestions_cache(doc.pk)
|
refresh_suggestions_cache(doc.pk)
|
||||||
return Response(cached.suggestions)
|
return Response(cached_llm_suggestions.suggestions)
|
||||||
|
|
||||||
llm_resp = get_ai_document_classification(doc)
|
llm_suggestions = get_ai_document_classification(doc)
|
||||||
|
|
||||||
matched_tags = match_tags_by_name(llm_resp.get("tags", []), request.user)
|
matched_tags = match_tags_by_name(
|
||||||
|
llm_suggestions.get("tags", []),
|
||||||
|
request.user,
|
||||||
|
)
|
||||||
matched_correspondents = match_correspondents_by_name(
|
matched_correspondents = match_correspondents_by_name(
|
||||||
llm_resp.get("correspondents", []),
|
llm_suggestions.get("correspondents", []),
|
||||||
request.user,
|
request.user,
|
||||||
)
|
)
|
||||||
matched_types = match_document_types_by_name(
|
matched_types = match_document_types_by_name(
|
||||||
llm_resp.get("document_types", []),
|
llm_suggestions.get("document_types", []),
|
||||||
request.user,
|
request.user,
|
||||||
)
|
)
|
||||||
matched_paths = match_storage_paths_by_name(
|
matched_paths = match_storage_paths_by_name(
|
||||||
llm_resp.get("storage_paths", []),
|
llm_suggestions.get("storage_paths", []),
|
||||||
request.user,
|
request.user,
|
||||||
)
|
)
|
||||||
|
|
||||||
resp_data = {
|
resp_data = {
|
||||||
"title": llm_resp.get("title"),
|
"title": llm_suggestions.get("title"),
|
||||||
"tags": [t.id for t in matched_tags],
|
"tags": [t.id for t in matched_tags],
|
||||||
"suggested_tags": extract_unmatched_names(
|
"suggested_tags": extract_unmatched_names(
|
||||||
llm_resp.get("tags", []),
|
llm_suggestions.get("tags", []),
|
||||||
matched_tags,
|
matched_tags,
|
||||||
),
|
),
|
||||||
"correspondents": [c.id for c in matched_correspondents],
|
"correspondents": [c.id for c in matched_correspondents],
|
||||||
"suggested_correspondents": extract_unmatched_names(
|
"suggested_correspondents": extract_unmatched_names(
|
||||||
llm_resp.get("correspondents", []),
|
llm_suggestions.get("correspondents", []),
|
||||||
matched_correspondents,
|
matched_correspondents,
|
||||||
),
|
),
|
||||||
"document_types": [d.id for d in matched_types],
|
"document_types": [d.id for d in matched_types],
|
||||||
"suggested_document_types": extract_unmatched_names(
|
"suggested_document_types": extract_unmatched_names(
|
||||||
llm_resp.get("document_types", []),
|
llm_suggestions.get("document_types", []),
|
||||||
matched_types,
|
matched_types,
|
||||||
),
|
),
|
||||||
"storage_paths": [s.id for s in matched_paths],
|
"storage_paths": [s.id for s in matched_paths],
|
||||||
"suggested_storage_paths": extract_unmatched_names(
|
"suggested_storage_paths": extract_unmatched_names(
|
||||||
llm_resp.get("storage_paths", []),
|
llm_suggestions.get("storage_paths", []),
|
||||||
matched_paths,
|
matched_paths,
|
||||||
),
|
),
|
||||||
"dates": llm_resp.get("dates", []),
|
"dates": llm_suggestions.get("dates", []),
|
||||||
}
|
}
|
||||||
|
|
||||||
set_llm_suggestions_cache(doc.pk, resp_data, backend=settings.LLM_BACKEND)
|
set_llm_suggestions_cache(doc.pk, resp_data, backend=settings.LLM_BACKEND)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user