Archived
102 lines
4.5 KiB
Python
102 lines
4.5 KiB
Python
"""The service must not be able to mutate its document mount."""
|
|
|
|
import os
|
|
import subprocess
|
|
import time
|
|
import uuid
|
|
from collections.abc import Callable
|
|
from pathlib import Path
|
|
|
|
import httpx
|
|
import pytest
|
|
|
|
|
|
def test_document_mount_is_read_only(
|
|
compose_exec: Callable[[list[str]], subprocess.CompletedProcess[str]],
|
|
) -> None:
|
|
result = compose_exec(["sh", "-c", "touch /documents/must-fail"])
|
|
assert result.returncode != 0
|
|
|
|
|
|
def test_generated_corpus_indexes_and_searches(
|
|
compose_exec: Callable[[list[str]], subprocess.CompletedProcess[str]],
|
|
) -> None:
|
|
corpus_file = os.environ.get("RECOLL_MODERN_TEST_CORPUS_FILE")
|
|
if corpus_file is None:
|
|
document_root = os.environ.get("RECOLL_MODERN_DOCUMENTS")
|
|
if document_root is None:
|
|
pytest.fail("RECOLL_MODERN_DOCUMENTS is required for generated-corpus verification")
|
|
relative = Path(f"recoll-modern-test-{uuid.uuid4().hex}") / "probe.txt"
|
|
file = Path(document_root) / relative
|
|
file.parent.mkdir(parents=True)
|
|
file.write_text("Unique zebraplatypus integration corpus.\n")
|
|
corpus_file = relative.as_posix()
|
|
assert compose_exec(["test", "-f", f"/documents/{corpus_file}"]).returncode == 0
|
|
port = os.environ.get("RECOLL_MODERN_PUBLISH_PORT", "8000")
|
|
username = os.environ["RECOLL_MODERN_ADMIN_USERNAME"]
|
|
password = os.environ["RECOLL_MODERN_ADMIN_PASSWORD"]
|
|
prefix = os.environ.get("RECOLL_MODERN_ROOT_PATH", "/").rstrip("/")
|
|
with httpx.Client(base_url=f"http://127.0.0.1:{port}{prefix}", timeout=10) as client:
|
|
login = client.post("/auth/login", json={"username": username, "password": password})
|
|
assert login.status_code == 200, login.text
|
|
csrf = login.json()["csrf_token"]
|
|
cookie = login.cookies.get("recoll_modern_session")
|
|
assert cookie
|
|
headers = {"X-CSRF-Token": csrf, "Cookie": f"recoll_modern_session={cookie}"}
|
|
created = client.post(
|
|
"/collections", json={"name": f"Integration {time.time_ns()}"}, headers=headers
|
|
)
|
|
assert created.status_code == 201, created.text
|
|
collection_id = created.json()["id"]
|
|
queued = client.post(
|
|
f"/collections/{collection_id}/memberships", headers=headers,
|
|
json={"sources": [{"type": "file", "path": corpus_file}]},
|
|
)
|
|
assert queued.status_code == 202, queued.text
|
|
job_id = queued.json()["job"]["id"]
|
|
deadline = time.monotonic() + 30
|
|
while time.monotonic() < deadline:
|
|
job = client.get(f"/jobs/{job_id}", headers=headers).json()["job"]
|
|
if job["state"] not in ("queued", "running"):
|
|
break
|
|
time.sleep(0.1)
|
|
assert job["state"] == "completed", job
|
|
result = client.get(
|
|
"/search", params={"q": "zebraplatypus", "collections": collection_id},
|
|
headers=headers,
|
|
)
|
|
assert result.status_code == 200, result.text
|
|
assert result.json()["hits"], result.json()
|
|
document_id = result.json()["hits"][0]["document_id"]
|
|
second = client.post(
|
|
"/collections", json={"name": f"Integration second {time.time_ns()}"},
|
|
headers=headers,
|
|
)
|
|
assert second.status_code == 201, second.text
|
|
second_id = second.json()["id"]
|
|
second_job = client.post(
|
|
f"/collections/{second_id}/memberships", headers=headers,
|
|
json={"sources": [{"type": "file", "path": corpus_file}]},
|
|
)
|
|
assert second_job.status_code == 202, second_job.text
|
|
second_job_id = second_job.json()["job"]["id"]
|
|
deadline = time.monotonic() + 30
|
|
while time.monotonic() < deadline:
|
|
job = client.get(f"/jobs/{second_job_id}", headers=headers).json()["job"]
|
|
if job["state"] not in ("queued", "running"):
|
|
break
|
|
time.sleep(0.1)
|
|
assert job["state"] == "completed", job
|
|
combined = client.get(
|
|
"/search", params=[
|
|
("q", "zebraplatypus"), ("collections", collection_id),
|
|
("collections", second_id), ("fields", "collections"),
|
|
], headers=headers,
|
|
)
|
|
assert combined.status_code == 200, combined.text
|
|
assert len(combined.json()["hits"]) == 1
|
|
assert set(combined.json()["hits"][0]["collections"]) >= {collection_id, second_id}
|
|
extracted = client.get(f"/documents/{document_id}/text", headers=headers)
|
|
assert extracted.status_code == 200, extracted.text
|
|
assert "zebraplatypus" in extracted.json()["text"]
|