"""Tests for dashboard entries Path-related functionality.""" from __future__ import annotations from pathlib import Path import tempfile from unittest.mock import MagicMock import pytest import pytest_asyncio from esphome.core import CORE from esphome.dashboard.entries import DashboardEntries, DashboardEntry def create_cache_key() -> tuple[int, int, float, int]: """Helper to create a valid DashboardCacheKeyType.""" return (0, 0, 0.0, 0) @pytest.fixture(autouse=True) def setup_core(): """Set up CORE for testing.""" with tempfile.TemporaryDirectory() as tmpdir: CORE.config_path = Path(tmpdir) / "test.yaml" yield CORE.reset() @pytest.fixture def mock_settings() -> MagicMock: """Create mock dashboard settings.""" settings = MagicMock() settings.config_dir = "/test/config" settings.absolute_config_dir = Path("/test/config") return settings @pytest_asyncio.fixture async def dashboard_entries(mock_settings: MagicMock) -> DashboardEntries: """Create a DashboardEntries instance for testing.""" return DashboardEntries(mock_settings) def test_dashboard_entry_path_initialization() -> None: """Test DashboardEntry initializes with path correctly.""" test_path = Path("/test/config/device.yaml") cache_key = create_cache_key() entry = DashboardEntry(test_path, cache_key) assert entry.path == test_path assert entry.cache_key == cache_key def test_dashboard_entry_path_with_absolute_path() -> None: """Test DashboardEntry handles absolute paths.""" # Use a truly absolute path for the platform test_path = Path.cwd() / "absolute" / "path" / "to" / "config.yaml" cache_key = create_cache_key() entry = DashboardEntry(test_path, cache_key) assert entry.path == test_path assert entry.path.is_absolute() def test_dashboard_entry_path_with_relative_path() -> None: """Test DashboardEntry handles relative paths.""" test_path = Path("configs/device.yaml") cache_key = create_cache_key() entry = DashboardEntry(test_path, cache_key) assert entry.path == test_path assert not entry.path.is_absolute() @pytest.mark.asyncio async def test_dashboard_entries_get_by_path( dashboard_entries: DashboardEntries, ) -> None: """Test getting entry by path.""" test_path = Path("/test/config/device.yaml") entry = DashboardEntry(test_path, create_cache_key()) dashboard_entries._entries[str(test_path)] = entry result = dashboard_entries.get(str(test_path)) assert result == entry @pytest.mark.asyncio async def test_dashboard_entries_get_nonexistent_path( dashboard_entries: DashboardEntries, ) -> None: """Test getting non-existent entry returns None.""" result = dashboard_entries.get("/nonexistent/path.yaml") assert result is None @pytest.mark.asyncio async def test_dashboard_entries_path_normalization( dashboard_entries: DashboardEntries, ) -> None: """Test that paths are handled consistently.""" path1 = Path("/test/config/device.yaml") entry = DashboardEntry(path1, create_cache_key()) dashboard_entries._entries[str(path1)] = entry result = dashboard_entries.get(str(path1)) assert result == entry @pytest.mark.asyncio async def test_dashboard_entries_path_with_spaces( dashboard_entries: DashboardEntries, ) -> None: """Test handling paths with spaces.""" test_path = Path("/test/config/my device.yaml") entry = DashboardEntry(test_path, create_cache_key()) dashboard_entries._entries[str(test_path)] = entry result = dashboard_entries.get(str(test_path)) assert result == entry assert result.path == test_path @pytest.mark.asyncio async def test_dashboard_entries_path_with_special_chars( dashboard_entries: DashboardEntries, ) -> None: """Test handling paths with special characters.""" test_path = Path("/test/config/device-01_test.yaml") entry = DashboardEntry(test_path, create_cache_key()) dashboard_entries._entries[str(test_path)] = entry result = dashboard_entries.get(str(test_path)) assert result == entry def test_dashboard_entries_windows_path() -> None: """Test handling Windows-style paths.""" test_path = Path(r"C:\Users\test\esphome\device.yaml") cache_key = create_cache_key() entry = DashboardEntry(test_path, cache_key) assert entry.path == test_path @pytest.mark.asyncio async def test_dashboard_entries_path_to_cache_key_mapping( dashboard_entries: DashboardEntries, ) -> None: """Test internal entries storage with paths and cache keys.""" path1 = Path("/test/config/device1.yaml") path2 = Path("/test/config/device2.yaml") entry1 = DashboardEntry(path1, create_cache_key()) entry2 = DashboardEntry(path2, (1, 1, 1.0, 1)) dashboard_entries._entries[str(path1)] = entry1 dashboard_entries._entries[str(path2)] = entry2 assert str(path1) in dashboard_entries._entries assert str(path2) in dashboard_entries._entries assert dashboard_entries._entries[str(path1)].cache_key == create_cache_key() assert dashboard_entries._entries[str(path2)].cache_key == (1, 1, 1.0, 1) def test_dashboard_entry_path_property() -> None: """Test that path property returns expected value.""" test_path = Path("/test/config/device.yaml") entry = DashboardEntry(test_path, create_cache_key()) assert entry.path == test_path assert isinstance(entry.path, Path) @pytest.mark.asyncio async def test_dashboard_entries_all_returns_entries_with_paths( dashboard_entries: DashboardEntries, ) -> None: """Test that all() returns entries with their paths intact.""" paths = [ Path("/test/config/device1.yaml"), Path("/test/config/device2.yaml"), Path("/test/config/subfolder/device3.yaml"), ] for path in paths: entry = DashboardEntry(path, create_cache_key()) dashboard_entries._entries[str(path)] = entry all_entries = dashboard_entries.async_all() assert len(all_entries) == len(paths) retrieved_paths = [entry.path for entry in all_entries] assert set(retrieved_paths) == set(paths)