157 lines
5.0 KiB
Python
157 lines
5.0 KiB
Python
"""Tests for document management commands via Click test runner."""
|
|
|
|
import json
|
|
|
|
import pytest
|
|
from click.testing import CliRunner
|
|
|
|
from kb_search.cli import main
|
|
from kb_search.database import (
|
|
SCHEMA_VERSION,
|
|
get_connection,
|
|
init_schema,
|
|
insert_chunk,
|
|
insert_document,
|
|
insert_embedding,
|
|
set_db_config,
|
|
tag_document,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def kb_env(tmp_path, monkeypatch):
|
|
"""Set up a test KB environment."""
|
|
data_dir = tmp_path / ".kb"
|
|
data_dir.mkdir()
|
|
db_path = data_dir / "kb.db"
|
|
|
|
conn = get_connection(db_path)
|
|
init_schema(conn, 384)
|
|
set_db_config(conn, "schema_version", str(SCHEMA_VERSION))
|
|
set_db_config(conn, "model_name", "all-MiniLM-L6-v2")
|
|
set_db_config(conn, "embedding_dim", "384")
|
|
|
|
# Add a test document
|
|
doc_id = insert_document(conn, "Test Doc", "/tmp/test.pdf", "abc123", "pdf")
|
|
insert_chunk(conn, doc_id, 0, "This is chunk zero about Python")
|
|
insert_chunk(conn, doc_id, 1, "This is chunk one about testing")
|
|
tag_document(conn, doc_id, ["test", "pdf"])
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
monkeypatch.setenv("KB_DATA_DIR", str(data_dir))
|
|
return data_dir
|
|
|
|
|
|
class TestList:
|
|
def test_json_output(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["list", "--format", "json"])
|
|
assert result.exit_code == 0
|
|
data = json.loads(result.output)
|
|
assert len(data) == 1
|
|
assert data[0]["title"] == "Test Doc"
|
|
assert data[0]["type"] == "pdf"
|
|
|
|
def test_human_output(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["list", "--format", "human"])
|
|
assert result.exit_code == 0
|
|
assert "Test Doc" in result.output
|
|
|
|
def test_filter_type(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["list", "--type", "markdown", "--format", "json"])
|
|
assert result.exit_code == 0
|
|
data = json.loads(result.output)
|
|
assert len(data) == 0
|
|
|
|
def test_filter_tags(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["list", "--tags", "test", "--format", "json"])
|
|
assert result.exit_code == 0
|
|
data = json.loads(result.output)
|
|
assert len(data) == 1
|
|
|
|
|
|
class TestInfo:
|
|
def test_json_output(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["info", "1", "--format", "json"])
|
|
assert result.exit_code == 0
|
|
data = json.loads(result.output)
|
|
assert data["title"] == "Test Doc"
|
|
assert data["chunk_count"] == 2
|
|
assert "test" in data["tags"]
|
|
|
|
def test_not_found(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["info", "999"])
|
|
assert result.exit_code != 0
|
|
assert "not found" in result.output.lower()
|
|
|
|
|
|
class TestRemove:
|
|
def test_remove_with_yes(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["remove", "1", "--yes"])
|
|
assert result.exit_code == 0
|
|
assert "Removed" in result.output
|
|
|
|
# Verify gone
|
|
result = runner.invoke(main, ["list", "--format", "json"])
|
|
data = json.loads(result.output)
|
|
assert len(data) == 0
|
|
|
|
def test_remove_not_found(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["remove", "999", "--yes"])
|
|
assert result.exit_code != 0
|
|
|
|
|
|
class TestTags:
|
|
def test_list_tags(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["tags", "--format", "json"])
|
|
assert result.exit_code == 0
|
|
data = json.loads(result.output)
|
|
names = [t["name"] for t in data]
|
|
assert "test" in names
|
|
assert "pdf" in names
|
|
|
|
def test_add_tag(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["tag", "1", "--add", "new"])
|
|
assert result.exit_code == 0
|
|
assert "Added" in result.output
|
|
|
|
def test_remove_tag(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["tag", "1", "--remove", "test"])
|
|
assert result.exit_code == 0
|
|
assert "Removed" in result.output
|
|
|
|
|
|
class TestStatus:
|
|
def test_json_output(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["status", "--format", "json"])
|
|
assert result.exit_code == 0
|
|
data = json.loads(result.output)
|
|
assert data["model_name"] == "all-MiniLM-L6-v2"
|
|
assert data["total_documents"] == 1
|
|
assert data["total_chunks"] == 2
|
|
|
|
def test_human_output(self, kb_env):
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["status", "--format", "human"])
|
|
assert result.exit_code == 0
|
|
assert "all-MiniLM-L6-v2" in result.output
|
|
|
|
def test_not_initialised(self, tmp_path, monkeypatch):
|
|
monkeypatch.setenv("KB_DATA_DIR", str(tmp_path / "nonexistent"))
|
|
runner = CliRunner()
|
|
result = runner.invoke(main, ["status"])
|
|
assert result.exit_code != 0
|
|
assert "not initialised" in result.output.lower()
|