mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-07-16 17:04:55 +00:00
Small targeted tests for coverage or pragma no cover
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from django.core.management import call_command
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pytest_mock import MockerFixture
|
||||
|
||||
_COMPACT = "documents.management.commands.document_llmindex.llm_index_compact"
|
||||
_INDEX = "documents.management.commands.document_llmindex.llmindex_index"
|
||||
|
||||
|
||||
class TestDocumentLlmindexCommand:
|
||||
def test_compact_calls_llm_index_compact(self, mocker: MockerFixture) -> None:
|
||||
mock_compact = mocker.patch(_COMPACT)
|
||||
call_command("document_llmindex", "compact")
|
||||
mock_compact.assert_called_once_with()
|
||||
|
||||
def test_rebuild_calls_llmindex_index_with_rebuild_true(
|
||||
self,
|
||||
mocker: MockerFixture,
|
||||
) -> None:
|
||||
mock_index = mocker.patch(_INDEX)
|
||||
call_command("document_llmindex", "rebuild")
|
||||
mock_index.assert_called_once()
|
||||
assert mock_index.call_args.kwargs["rebuild"] is True
|
||||
|
||||
def test_update_calls_llmindex_index_with_rebuild_false(
|
||||
self,
|
||||
mocker: MockerFixture,
|
||||
) -> None:
|
||||
mock_index = mocker.patch(_INDEX)
|
||||
call_command("document_llmindex", "update")
|
||||
mock_index.assert_called_once()
|
||||
assert mock_index.call_args.kwargs["rebuild"] is False
|
||||
@@ -420,7 +420,7 @@ def query_similar_documents(
|
||||
continue
|
||||
try:
|
||||
retrieved_document_ids.append(int(normalized))
|
||||
except ValueError:
|
||||
except ValueError: # pragma: no cover
|
||||
logger.warning(
|
||||
"Skipping LLM index result with invalid document_id %r.",
|
||||
document_id,
|
||||
|
||||
@@ -278,6 +278,22 @@ def test_update_llm_index_no_documents(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_update_no_documents_no_index_returns_early(
|
||||
temp_llm_index_dir: Path,
|
||||
mocker: pytest_mock.MockerFixture,
|
||||
) -> None:
|
||||
"""update with no documents and no existing index must return early."""
|
||||
mock_qs = MagicMock()
|
||||
mock_qs.exists.return_value = False
|
||||
mock_qs.__iter__ = MagicMock(return_value=iter([]))
|
||||
mocker.patch("paperless_ai.indexing.Document.objects.all", return_value=mock_qs)
|
||||
|
||||
result = indexing.update_llm_index(rebuild=False)
|
||||
|
||||
assert result == "No documents found to index."
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_queue_llm_index_update_if_needed_enqueues_when_idle_or_skips_recent() -> None:
|
||||
# No existing tasks
|
||||
@@ -634,6 +650,32 @@ class TestDimensionGuard:
|
||||
"""No table yet — dim mismatch must return False (nothing to compare)."""
|
||||
assert not indexing.embedding_dim_mismatch()
|
||||
|
||||
def test_update_llm_index_forces_rebuild_on_dim_mismatch(
|
||||
self,
|
||||
temp_llm_index_dir: Path,
|
||||
mock_embed_model: FakeEmbedding,
|
||||
mocker: pytest_mock.MockerFixture,
|
||||
) -> None:
|
||||
"""When the stored dim differs from the current model, update must force a rebuild."""
|
||||
mocker.patch("paperless_ai.indexing.embedding_dim_mismatch", return_value=True)
|
||||
mocker.patch("paperless_ai.indexing.llm_index_exists", return_value=True)
|
||||
mock_store = MagicMock()
|
||||
mocker.patch(
|
||||
"paperless_ai.indexing.write_store",
|
||||
return_value=mocker.MagicMock(
|
||||
__enter__=mocker.MagicMock(return_value=mock_store),
|
||||
__exit__=mocker.MagicMock(return_value=False),
|
||||
),
|
||||
)
|
||||
mock_qs = MagicMock()
|
||||
mock_qs.exists.return_value = True
|
||||
mock_qs.__iter__ = MagicMock(return_value=iter([]))
|
||||
mocker.patch("paperless_ai.indexing.Document.objects.all", return_value=mock_qs)
|
||||
|
||||
indexing.update_llm_index(rebuild=False)
|
||||
|
||||
mock_store.drop_table.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
class TestLanceDbIndexing:
|
||||
|
||||
@@ -106,6 +106,23 @@ class TestPaperlessLanceVectorStoreCrud:
|
||||
)
|
||||
assert nodes == []
|
||||
|
||||
def test_get_nodes_returns_empty_when_no_table(
|
||||
self,
|
||||
store: PaperlessLanceVectorStore,
|
||||
) -> None:
|
||||
result = store.get_nodes(
|
||||
filters=MetadataFilters(
|
||||
filters=[
|
||||
MetadataFilter(
|
||||
key="document_id",
|
||||
operator=FilterOperator.IN,
|
||||
value=["1"],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
assert result == []
|
||||
|
||||
def test_fresh_instance_filters_existing_table(
|
||||
self,
|
||||
tmp_path: Path,
|
||||
|
||||
@@ -194,7 +194,7 @@ class PaperlessLanceVectorStore(BasePydanticVectorStore):
|
||||
filters: MetadataFilters | None = None,
|
||||
**kwargs: Any,
|
||||
) -> list[BaseNode]:
|
||||
if node_ids is not None:
|
||||
if node_ids is not None: # pragma: no cover
|
||||
# node_ids lookup is not implemented; see class docstring.
|
||||
raise NotImplementedError(
|
||||
"PaperlessLanceVectorStore does not support node_ids lookup",
|
||||
@@ -255,7 +255,7 @@ class PaperlessLanceVectorStore(BasePydanticVectorStore):
|
||||
# Embedding dim from the schema's fixed-size list column.
|
||||
dim = self._table.schema.field("vector").type.list_size
|
||||
try:
|
||||
if dim % ANN_PQ_SUB_VECTORS == 0:
|
||||
if dim % ANN_PQ_SUB_VECTORS == 0: # pragma: no cover
|
||||
self._table.create_index(
|
||||
metric="l2",
|
||||
num_partitions=num_partitions,
|
||||
|
||||
Reference in New Issue
Block a user