Files
basicmachines-co-basic-memory/tests/cli/test_project_commands.py
T
Paul Hernandez e6496df595 feat: Beta work (#17)
feat: Add multiple projects support 
feat: enhanced read_note for when initial result is not found
fix: merge frontmatter when updating note
fix: handle directory removed on sync watch
2025-03-05 18:46:04 -06:00

159 lines
5.1 KiB
Python

"""Tests for project CLI commands."""
import json
import os
from pathlib import Path
from tempfile import TemporaryDirectory
import pytest
from typer.testing import CliRunner
from basic_memory.cli.main import app
from basic_memory.config import ConfigManager, DATA_DIR_NAME, CONFIG_FILE_NAME
@pytest.fixture
def temp_home(monkeypatch):
"""Create a temporary directory for testing."""
with TemporaryDirectory() as tempdir:
temp_home = Path(tempdir)
monkeypatch.setattr(Path, "home", lambda: temp_home)
# Ensure config directory exists
config_dir = temp_home / DATA_DIR_NAME
config_dir.mkdir(parents=True, exist_ok=True)
yield temp_home
@pytest.fixture
def cli_runner():
"""Create a CLI runner for testing."""
return CliRunner()
def test_project_list_empty(cli_runner, temp_home):
"""Test listing projects when none are configured."""
# Create empty config but with main project (will always be present)
config_file = temp_home / DATA_DIR_NAME / CONFIG_FILE_NAME
config_file.write_text(json.dumps({"projects": {}, "default_project": "main"}))
# Run command
result = cli_runner.invoke(app, ["project", "list"])
assert result.exit_code == 0
# The test will always have at least the "main" project due to auto-initialization
assert "main" in result.stdout
def test_project_list(cli_runner, temp_home):
"""Test listing projects."""
# Create config with projects
config_file = temp_home / DATA_DIR_NAME / CONFIG_FILE_NAME
config_data = {
"projects": {
"main": str(temp_home / "basic-memory"),
"work": str(temp_home / "work-memory"),
},
"default_project": "main",
}
config_file.write_text(json.dumps(config_data))
# Run command
result = cli_runner.invoke(app, ["project", "list"])
assert result.exit_code == 0
assert "main" in result.stdout
assert "work" in result.stdout
assert "basic-memory" in result.stdout
assert "work-memory" in result.stdout
def test_project_add(cli_runner, temp_home):
"""Test adding a project."""
# Create config manager to initialize config
config_manager = ConfigManager()
# Create a project directory
test_project_dir = temp_home / "test-project"
# Run command
result = cli_runner.invoke(app, ["project", "add", "test", str(test_project_dir)])
assert result.exit_code == 0
assert "Project 'test' added at" in result.stdout
# Verify project was added
config_manager = ConfigManager()
assert "test" in config_manager.projects
assert Path(config_manager.projects["test"]) == test_project_dir
def test_project_add_existing(cli_runner, temp_home):
"""Test adding a project that already exists."""
# Create config manager and add a project
config_manager = ConfigManager()
config_manager.add_project("test", str(temp_home / "test-project"))
# Try to add the same project again
result = cli_runner.invoke(app, ["project", "add", "test", str(temp_home / "another-path")])
assert result.exit_code == 1
assert "Error: Project 'test' already exists" in result.stdout
def test_project_remove(cli_runner, temp_home):
"""Test removing a project."""
# Create config manager and add a project
config_manager = ConfigManager()
config_manager.add_project("test", str(temp_home / "test-project"))
# Remove the project
result = cli_runner.invoke(app, ["project", "remove", "test"])
assert result.exit_code == 0
assert "Project 'test' removed" in result.stdout
# Verify project was removed
config_manager = ConfigManager()
assert "test" not in config_manager.projects
def test_project_default(cli_runner, temp_home):
"""Test setting the default project."""
# Create config manager and add a project
config_manager = ConfigManager()
config_manager.add_project("test", str(temp_home / "test-project"))
# Set as default
result = cli_runner.invoke(app, ["project", "default", "test"])
assert result.exit_code == 0
assert "Project 'test' set as default" in result.stdout
# Verify default was set
config_manager = ConfigManager()
assert config_manager.default_project == "test"
def test_project_current(cli_runner, temp_home):
"""Test showing the current project."""
# Set as default
result = cli_runner.invoke(app, ["project", "current"])
assert result.exit_code == 0
assert "Current project: main" in result.stdout
assert "Path:" in result.stdout
assert "Database:" in result.stdout
def test_project_option(cli_runner, temp_home, monkeypatch):
"""Test using the --project option."""
# Create config manager and add a project
config_manager = ConfigManager()
config_manager.add_project("test", str(temp_home / "test-project"))
# Mock environment to capture the set variable
env_vars = {}
monkeypatch.setattr(os, "environ", env_vars)
# Run command with --project option
cli_runner.invoke(app, ["--project", "test", "project", "current"])
# Verify environment variable was set
assert env_vars.get("BASIC_MEMORY_PROJECT") == "test"