import sys from unittest.mock import AsyncMock, MagicMock import pytest from scripts import manage_vectorstore as cli @pytest.fixture def calls(monkeypatch): calls = [] monkeypatch.setattr(cli, "delete_all_documents", lambda: calls.append("delete_all")) monkeypatch.setattr( cli, "delete_documents_by_metadata", lambda k, v: calls.append(f"delete {k}={v}"), ) monkeypatch.setattr( cli, "fetch_documents_from_paperless_ngx", AsyncMock(side_effect=lambda: calls.append("fetch") or ["doc"]), ) monkeypatch.setattr( cli, "index_documents", AsyncMock(side_effect=lambda *docs: calls.append(f"paperless {list(docs)}")), ) monkeypatch.setattr( cli, "index_obsidian_documents", AsyncMock(side_effect=lambda: calls.append("obsidian")), ) monkeypatch.setattr(cli, "stats", MagicMock()) return calls @pytest.mark.parametrize( "command, expected", [ # A full reindex must not drop Obsidian notes after wiping everything. # Fetch before deleting, then index the fetched documents (no refetch). ("reindex", ["fetch", "delete_all", "paperless [['doc']]", "obsidian"]), ("reindex-obsidian", ["delete source=obsidian", "obsidian"]), ], ) def test_reindex_commands(calls, monkeypatch, command, expected): monkeypatch.setattr(sys, "argv", ["manage_vectorstore", command]) cli.main() assert calls == expected @pytest.mark.parametrize( "failure", [ AsyncMock(side_effect=ConnectionError("Name or service not known")), AsyncMock(return_value=[]), ], ) def test_reindex_leaves_index_untouched_when_paperless_fails( calls, monkeypatch, failure ): monkeypatch.setattr(cli, "fetch_documents_from_paperless_ngx", failure) monkeypatch.setattr(sys, "argv", ["manage_vectorstore", "reindex"]) with pytest.raises(SystemExit): cli.main() assert "delete_all" not in calls