"""Tests for image_manager module.""" import tempfile from pathlib import Path import pytest from src.core.image_manager import ( ImageError, create_sparse_image, delete_image, get_image_info, resize_image, ) class TestCreateSparseImage: """Tests for create_sparse_image function.""" def test_create_sparse_image(self) -> None: """Test creating a sparse image.""" with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) / "test.vault" create_sparse_image(path, size_mb=10) assert path.exists() # File should be 10MB in logical size assert path.stat().st_size == 10 * 1024 * 1024 def test_create_sparse_image_is_sparse(self) -> None: """Test that created image is actually sparse (uses less disk space).""" with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) / "test.vault" create_sparse_image(path, size_mb=100) stat = path.stat() # Actual disk usage should be much less than logical size # st_blocks is in 512-byte units actual_size = stat.st_blocks * 512 logical_size = stat.st_size # Actual size should be less than 10% of logical size for a sparse file # (exFAT metadata takes some space, so not 0) assert actual_size < logical_size * 0.1 def test_create_sparse_image_already_exists(self) -> None: """Test that creating image fails if file exists.""" with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) / "test.vault" path.touch() with pytest.raises(ImageError, match="already exists"): create_sparse_image(path, size_mb=10) def test_create_sparse_image_invalid_path(self) -> None: """Test that creating image fails for invalid path.""" path = Path("/nonexistent/directory/test.vault") with pytest.raises(ImageError): create_sparse_image(path, size_mb=10) class TestResizeImage: """Tests for resize_image function.""" def test_resize_image(self) -> None: """Test resizing an image.""" with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) / "test.vault" create_sparse_image(path, size_mb=10) resize_image(path, new_size_mb=20) assert path.stat().st_size == 20 * 1024 * 1024 def test_resize_image_smaller_fails(self) -> None: """Test that shrinking an image fails.""" with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) / "test.vault" create_sparse_image(path, size_mb=20) with pytest.raises(ImageError, match="must be larger"): resize_image(path, new_size_mb=10) def test_resize_image_same_size_fails(self) -> None: """Test that resizing to same size fails.""" with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) / "test.vault" create_sparse_image(path, size_mb=10) with pytest.raises(ImageError, match="must be larger"): resize_image(path, new_size_mb=10) def test_resize_nonexistent_image(self) -> None: """Test that resizing nonexistent image fails.""" path = Path("/nonexistent/test.vault") with pytest.raises(ImageError, match="not found"): resize_image(path, new_size_mb=20) class TestGetImageInfo: """Tests for get_image_info function.""" def test_get_image_info(self) -> None: """Test getting image info.""" with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) / "test.vault" create_sparse_image(path, size_mb=50) info = get_image_info(path) assert info["path"] == str(path) assert info["size_mb"] == 50 assert info["actual_size_mb"] < 50 # Sparse file assert 0 < info["sparse_ratio"] < 1 def test_get_image_info_nonexistent(self) -> None: """Test getting info for nonexistent image.""" path = Path("/nonexistent/test.vault") with pytest.raises(ImageError, match="not found"): get_image_info(path) class TestDeleteImage: """Tests for delete_image function.""" def test_delete_image(self) -> None: """Test deleting an image.""" with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) / "test.vault" create_sparse_image(path, size_mb=10) assert path.exists() delete_image(path) assert not path.exists() def test_delete_nonexistent_image(self) -> None: """Test deleting nonexistent image fails.""" path = Path("/nonexistent/test.vault") with pytest.raises(ImageError, match="not found"): delete_image(path)