mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-31 18:22:22 +01:00
75 lines
3.7 KiB
Python
75 lines
3.7 KiB
Python
"""Literal punctuation in library queries must not become SQL wildcards."""
|
|
|
|
from types import SimpleNamespace
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
from core.database import Document
|
|
from routes.document import document_routes
|
|
from tests.helpers.database import disposable_database
|
|
|
|
|
|
CASES = [
|
|
("100%", "100% complete", "1000 complete"),
|
|
("a_b", "a_b", "axb"),
|
|
("%", "price 10%", "price 100"),
|
|
("_", "a_b", "axb"),
|
|
(r"path\notes", r"path\notes", "pathnotes"),
|
|
(r"path\_tag", r"path\_tag", r"path\Xtag"),
|
|
("50%_done", "50%_done", "500Xdone"),
|
|
("can't", "can't stop", "cannot stop"),
|
|
("mixed case", "Case ordered Mixed", "Mixed without"),
|
|
]
|
|
|
|
|
|
@pytest.mark.parametrize("column", ["title", "current_content"])
|
|
@pytest.mark.parametrize("query,literal,lookalike", CASES)
|
|
@pytest.mark.asyncio
|
|
async def test_library_search_matches_literal_tokens(tmp_path, monkeypatch, column, query, literal, lookalike):
|
|
with disposable_database(tmp_path) as factory:
|
|
monkeypatch.setattr(document_routes, "SessionLocal", factory)
|
|
with factory() as db:
|
|
for doc_id, text, owner, active, archived in [
|
|
("literal", literal, "alice", True, False),
|
|
("lookalike", lookalike, "alice", True, False),
|
|
("foreign", literal, "bob", True, False),
|
|
("inactive", literal, "alice", False, False),
|
|
("archived", literal, "alice", True, True),
|
|
]:
|
|
fields = {"title": "Document", "current_content": "Body", column: text}
|
|
db.add(Document(id=doc_id, owner=owner, is_active=active, archived=archived,
|
|
language="text", version_count=1, **fields))
|
|
db.commit()
|
|
router = document_routes.setup_document_routes(MagicMock())
|
|
endpoint = next(r.endpoint for r in router.routes if r.path == "/api/documents/library")
|
|
request = SimpleNamespace(state=SimpleNamespace(current_user="alice"))
|
|
result = await endpoint(request, search=query, language=None, sort="recent", offset=0, limit=20, archived=False)
|
|
assert result["total"] == 1
|
|
assert [row["id"] for row in result["documents"]] == ["literal"]
|
|
archived = await endpoint(request, search=query, language=None, sort="recent", offset=0, limit=20, archived=True)
|
|
assert [row["id"] for row in archived["documents"]] == ["archived"]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_literal_search_keeps_cross_field_and_pagination_behavior(tmp_path, monkeypatch):
|
|
with disposable_database(tmp_path) as factory:
|
|
monkeypatch.setattr(document_routes, "SessionLocal", factory)
|
|
with factory() as db:
|
|
for doc_id, title, content in [
|
|
("first", "100% ready", "done"),
|
|
("second", "done", "100% ready"),
|
|
("lookalike", "1000 ready", "done"),
|
|
("missing-term", "100% ready", "waiting"),
|
|
]:
|
|
db.add(Document(id=doc_id, owner="alice", title=title, current_content=content,
|
|
is_active=True, archived=False, language="text", version_count=1))
|
|
db.commit()
|
|
router = document_routes.setup_document_routes(MagicMock())
|
|
endpoint = next(r.endpoint for r in router.routes if r.path == "/api/documents/library")
|
|
request = SimpleNamespace(state=SimpleNamespace(current_user="alice"))
|
|
results = [await endpoint(request, search="100% done", language="text", sort="alpha",
|
|
offset=offset, limit=1, archived=False) for offset in [0, 1]]
|
|
assert all(result["total"] == 2 for result in results)
|
|
assert {row["id"] for result in results for row in result["documents"]} == {"first", "second"}
|