"""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 == []