"""Tests for Manifest dataclass.""" import tempfile from datetime import datetime from pathlib import Path from src.core.file_entry import FileEntry from src.core.manifest import Location, Manifest class TestLocation: """Tests for Location dataclass.""" def test_create_location(self) -> None: """Test creating a Location instance.""" now = datetime.now() loc = Location( path="/mnt/disk1/vault.vault", last_seen=now, status="active", ) assert loc.path == "/mnt/disk1/vault.vault" assert loc.last_seen == now assert loc.status == "active" def test_to_dict(self) -> None: """Test serialization to dictionary.""" time = datetime(2026, 1, 28, 15, 45, 0) loc = Location( path="/mnt/disk1/vault.vault", last_seen=time, status="active", ) result = loc.to_dict() assert result == { "path": "/mnt/disk1/vault.vault", "last_seen": "2026-01-28T15:45:00", "status": "active", } def test_from_dict(self) -> None: """Test deserialization from dictionary.""" data = { "path": "/mnt/nas/vault.vault", "last_seen": "2026-01-25T08:00:00", "status": "unreachable", } loc = Location.from_dict(data) assert loc.path == "/mnt/nas/vault.vault" assert loc.last_seen == datetime(2026, 1, 25, 8, 0, 0) assert loc.status == "unreachable" class TestManifest: """Tests for Manifest dataclass.""" def test_create_new_manifest(self) -> None: """Test creating a new manifest.""" manifest = Manifest.create_new( vault_name="My Vault", image_size_mb=1024, location_path="/mnt/disk1/myvault.vault", ) assert manifest.vault_name == "My Vault" assert manifest.image_size_mb == 1024 assert manifest.version == 1 assert len(manifest.locations) == 1 assert manifest.locations[0].path == "/mnt/disk1/myvault.vault" assert manifest.locations[0].status == "active" assert len(manifest.files) == 0 assert manifest.vault_id # UUID should be set def test_to_dict(self) -> None: """Test serialization to dictionary.""" manifest = Manifest.create_new( vault_name="Test Vault", image_size_mb=512, location_path="/test/vault.vault", ) result = manifest.to_dict() assert result["vault_name"] == "Test Vault" assert result["image_size_mb"] == 512 assert result["version"] == 1 assert len(result["locations"]) == 1 assert len(result["files"]) == 0 assert "vault_id" in result assert "created" in result assert "last_modified" in result def test_from_dict(self) -> None: """Test deserialization from dictionary.""" data = { "vault_id": "550e8400-e29b-41d4-a716-446655440000", "vault_name": "My Vault", "version": 1, "created": "2026-01-28T10:30:00", "last_modified": "2026-01-28T15:45:00", "image_size_mb": 10240, "locations": [ { "path": "/mnt/disk1/myvault.vault", "last_seen": "2026-01-28T15:45:00", "status": "active", } ], "files": [ { "path": "documents/file.txt", "hash": "sha256:abc123", "size": 1234, "created": "2026-01-28T10:30:00", "modified": "2026-01-28T14:20:00", } ], } manifest = Manifest.from_dict(data) assert manifest.vault_id == "550e8400-e29b-41d4-a716-446655440000" assert manifest.vault_name == "My Vault" assert manifest.image_size_mb == 10240 assert len(manifest.locations) == 1 assert len(manifest.files) == 1 assert manifest.files[0].path == "documents/file.txt" def test_save_and_load(self) -> None: """Test saving and loading manifest to/from file.""" with tempfile.TemporaryDirectory() as tmpdir: mount_point = Path(tmpdir) # Create and save manifest = Manifest.create_new( vault_name="Test Vault", image_size_mb=512, location_path="/test/vault.vault", ) manifest.save(mount_point) # Verify file exists manifest_path = mount_point / ".vault" / "manifest.json" assert manifest_path.exists() # Load and verify loaded = Manifest.load(mount_point) assert loaded.vault_id == manifest.vault_id assert loaded.vault_name == manifest.vault_name assert loaded.image_size_mb == manifest.image_size_mb def test_add_location(self) -> None: """Test adding a new location.""" manifest = Manifest.create_new( vault_name="Test", image_size_mb=512, location_path="/disk1/vault.vault", ) original_modified = manifest.last_modified manifest.add_location("/disk2/vault.vault") assert len(manifest.locations) == 2 assert manifest.locations[1].path == "/disk2/vault.vault" assert manifest.locations[1].status == "active" assert manifest.last_modified >= original_modified def test_update_location_status(self) -> None: """Test updating location status.""" manifest = Manifest.create_new( vault_name="Test", image_size_mb=512, location_path="/disk1/vault.vault", ) manifest.update_location_status("/disk1/vault.vault", "unreachable") assert manifest.locations[0].status == "unreachable" def test_add_file(self) -> None: """Test adding a file entry.""" manifest = Manifest.create_new( vault_name="Test", image_size_mb=512, location_path="/disk1/vault.vault", ) now = datetime.now() file_entry = FileEntry( path="test.txt", hash="sha256:abc", size=100, created=now, modified=now, ) manifest.add_file(file_entry) assert len(manifest.files) == 1 assert manifest.files[0].path == "test.txt" def test_add_file_updates_existing(self) -> None: """Test that adding a file with same path updates it.""" manifest = Manifest.create_new( vault_name="Test", image_size_mb=512, location_path="/disk1/vault.vault", ) now = datetime.now() # Add first version entry1 = FileEntry( path="test.txt", hash="sha256:old", size=100, created=now, modified=now ) manifest.add_file(entry1) # Add updated version entry2 = FileEntry( path="test.txt", hash="sha256:new", size=200, created=now, modified=now ) manifest.add_file(entry2) assert len(manifest.files) == 1 assert manifest.files[0].hash == "sha256:new" assert manifest.files[0].size == 200 def test_remove_file(self) -> None: """Test removing a file entry.""" manifest = Manifest.create_new( vault_name="Test", image_size_mb=512, location_path="/disk1/vault.vault", ) now = datetime.now() entry = FileEntry( path="test.txt", hash="sha256:abc", size=100, created=now, modified=now ) manifest.add_file(entry) manifest.remove_file("test.txt") assert len(manifest.files) == 0 def test_get_file(self) -> None: """Test getting a file entry by path.""" manifest = Manifest.create_new( vault_name="Test", image_size_mb=512, location_path="/disk1/vault.vault", ) now = datetime.now() entry = FileEntry( path="test.txt", hash="sha256:abc", size=100, created=now, modified=now ) manifest.add_file(entry) found = manifest.get_file("test.txt") not_found = manifest.get_file("nonexistent.txt") assert found is not None assert found.path == "test.txt" assert not_found is None