267 lines
8.4 KiB
Python
267 lines
8.4 KiB
Python
"""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
|