Files
kb/tests/test_management.py
T
2026-03-23 20:38:42 +00:00

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()