Files
tracker-cli/tests/test_storage.py
Daniel Arroyo 2735562b65 Add comprehensive test suite for MVP-1 Personal Tracker CLI
Implements 72 tests covering:
- Model tests (Project, Session, Note, Change)
- ProjectService tests (create, get, list, ensure structure)
- SessionService tests (active session management)
- FileStorage tests (read/write operations)
- Complete flow tests (init -> start -> note -> stop -> show)
- Note consolidation tests

Uses pytest with tmp_path fixtures for isolated testing.
2026-03-23 09:40:46 -03:00

194 lines
6.6 KiB
Python

"""Tests for FileStorage."""
import json
from datetime import datetime
from pathlib import Path
import pytest
import yaml
from tracker.models import Session
from tracker.storage import FileStorage
class TestReadWriteProjectMeta:
"""Tests for read/write project meta operations."""
def test_write_and_read_project_meta(self, tmp_project_dir):
"""Test writing and reading project meta."""
storage = FileStorage(tmp_project_dir)
slug = "test-project"
meta_data = {
"id": "test-id",
"name": "Test Project",
"slug": slug,
"description": "A test project",
"type": "code",
"status": "active",
"tags": ["python"],
"created_at": datetime(2024, 1, 15, 10, 0, 0).isoformat(),
"updated_at": datetime(2024, 1, 15, 10, 0, 0).isoformat(),
}
storage.write_project_meta(slug, meta_data)
result = storage.read_project_meta(slug)
assert result["name"] == "Test Project"
assert result["slug"] == slug
assert result["type"] == "code"
def test_read_project_meta_creates_parent_directories(self, tmp_project_dir):
"""Test that write_project_meta creates parent directories."""
storage = FileStorage(tmp_project_dir)
slug = "new-project"
meta_data = {"id": "test-id", "name": "Test", "slug": slug}
storage.write_project_meta(slug, meta_data)
meta_path = tmp_project_dir / slug / "meta" / "project.yaml"
assert meta_path.exists()
def test_read_project_meta_raises_for_nonexistent(self, tmp_project_dir):
"""Test that reading nonexistent project raises error."""
storage = FileStorage(tmp_project_dir)
with pytest.raises(FileNotFoundError):
storage.read_project_meta("nonexistent")
class TestAppendToLog:
"""Tests for append_to_log operations."""
def test_append_to_log_creates_log_file(self, tmp_project_dir):
"""Test that append_to_log creates LOG.md if it doesn't exist."""
storage = FileStorage(tmp_project_dir)
slug = "test-project"
# Create project directory first
(tmp_project_dir / slug).mkdir(parents=True)
storage.append_to_log(slug, "# Test Log Entry\n")
log_path = tmp_project_dir / slug / "LOG.md"
assert log_path.exists()
def test_append_to_log_appends_content(self, tmp_project_dir):
"""Test that append_to_log appends content to LOG.md."""
storage = FileStorage(tmp_project_dir)
slug = "test-project"
# Create project directory first
(tmp_project_dir / slug).mkdir(parents=True)
storage.append_to_log(slug, "# First Entry\n")
storage.append_to_log(slug, "# Second Entry\n")
content = storage.read_log(slug)
assert "# First Entry" in content
assert "# Second Entry" in content
def test_read_log_returns_empty_string_for_nonexistent(self, tmp_project_dir):
"""Test that read_log returns empty string for nonexistent log."""
storage = FileStorage(tmp_project_dir)
result = storage.read_log("nonexistent")
assert result == ""
class TestActiveSessionStorage:
"""Tests for active session storage operations."""
def test_write_and_read_active_session(self, tmp_project_dir, mock_session):
"""Test writing and reading active session."""
storage = FileStorage(tmp_project_dir)
session_data = mock_session.model_dump(mode="json")
session_data["started_at"] = mock_session.started_at.isoformat()
if mock_session.ended_at:
session_data["ended_at"] = mock_session.ended_at.isoformat()
storage.write_active_session(session_data)
result = storage.read_active_session()
assert result is not None
assert result["id"] == mock_session.id
def test_read_active_session_returns_none_when_not_exists(self, tmp_project_dir):
"""Test that read_active_session returns None when file doesn't exist."""
storage = FileStorage(tmp_project_dir)
result = storage.read_active_session()
assert result is None
def test_delete_active_session(self, tmp_project_dir, mock_session):
"""Test deleting active session."""
storage = FileStorage(tmp_project_dir)
session_data = mock_session.model_dump(mode="json")
session_data["started_at"] = mock_session.started_at.isoformat()
storage.write_active_session(session_data)
storage.delete_active_session()
result = storage.read_active_session()
assert result is None
def test_delete_active_session_when_not_exists(self, tmp_project_dir):
"""Test deleting active session when it doesn't exist doesn't error."""
storage = FileStorage(tmp_project_dir)
storage.delete_active_session()
class TestProjectExistence:
"""Tests for project existence checks."""
def test_project_exists_returns_true_for_existing_project(self, tmp_project_dir):
"""Test that project_exists returns True for existing project."""
storage = FileStorage(tmp_project_dir)
slug = "test-project"
(tmp_project_dir / slug).mkdir()
assert storage.project_exists(slug) is True
def test_project_exists_returns_false_for_nonexistent(self, tmp_project_dir):
"""Test that project_exists returns False for nonexistent project."""
storage = FileStorage(tmp_project_dir)
assert storage.project_exists("nonexistent") is False
class TestListProjects:
"""Tests for listing projects."""
def test_list_projects_returns_all_projects(self, tmp_project_dir):
"""Test that list_projects returns all project slugs."""
storage = FileStorage(tmp_project_dir)
(tmp_project_dir / "project-1").mkdir()
(tmp_project_dir / "project-2").mkdir()
projects = storage.list_projects()
assert "project-1" in projects
assert "project-2" in projects
def test_list_projects_excludes_hidden_directories(self, tmp_project_dir):
"""Test that list_projects excludes hidden directories."""
storage = FileStorage(tmp_project_dir)
(tmp_project_dir / "project-1").mkdir()
(tmp_project_dir / ".hidden").mkdir()
projects = storage.list_projects()
assert "project-1" in projects
assert ".hidden" not in projects
def test_list_projects_returns_empty_list_when_no_projects(self, tmp_project_dir):
"""Test that list_projects returns empty list when no projects exist."""
storage = FileStorage(tmp_project_dir)
projects = storage.list_projects()
assert projects == []