All checks were successful
Python CI / test (push) Successful in 1m20s
Lint / lint (push) Successful in 1m4s
Tests / test (3.11) (push) Successful in 1m27s
Tests / test (3.12) (push) Successful in 2m25s
Tests / test (3.13) (push) Successful in 2m52s
Tests / test (3.14) (push) Successful in 1m9s
162 lines
6.2 KiB
Python
Executable File
162 lines
6.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Test script for v2.0 to v3.0 migration
|
|
|
|
This script creates a v2.0 project, saves it, then loads it back
|
|
to verify that the migration to v3.0 works correctly.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
import json
|
|
import zipfile
|
|
from datetime import datetime
|
|
|
|
# Add pyPhotoAlbum to path
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
|
|
|
|
from pyPhotoAlbum.project import Project, Page
|
|
from pyPhotoAlbum.models import ImageData, TextBoxData
|
|
from pyPhotoAlbum.project_serializer import save_to_zip, load_from_zip
|
|
from pyPhotoAlbum.version_manager import CURRENT_DATA_VERSION
|
|
|
|
|
|
def create_v2_project_json():
|
|
"""Create a v2.0 project JSON (without UUIDs, timestamps, project_id)"""
|
|
return {
|
|
"name": "Test Project v2.0",
|
|
"folder_path": "./test_project",
|
|
"page_size_mm": [140, 140],
|
|
"working_dpi": 300,
|
|
"export_dpi": 300,
|
|
"has_cover": False,
|
|
"data_version": "2.0",
|
|
"pages": [
|
|
{
|
|
"page_number": 1,
|
|
"is_cover": False,
|
|
"is_double_spread": False,
|
|
"manually_sized": False,
|
|
"layout": {
|
|
"size": [140, 140],
|
|
"background_color": [1.0, 1.0, 1.0],
|
|
"elements": [
|
|
{
|
|
"type": "textbox",
|
|
"position": [10, 10],
|
|
"size": [100, 50],
|
|
"rotation": 0,
|
|
"z_index": 0,
|
|
"text_content": "Hello v2.0",
|
|
"font_settings": {"family": "Arial", "size": 12, "color": [0, 0, 0]},
|
|
"alignment": "left",
|
|
}
|
|
],
|
|
"snapping_system": {"snap_threshold_mm": 5.0, "grid_size_mm": 10.0},
|
|
},
|
|
}
|
|
],
|
|
"history": {"undo_stack": [], "redo_stack": [], "max_history": 100},
|
|
"asset_manager": {"reference_counts": {}},
|
|
}
|
|
|
|
|
|
def test_migration():
|
|
"""Test v2.0 to v3.0 migration"""
|
|
print("=" * 60)
|
|
print("Testing v2.0 to v3.0 Migration")
|
|
print("=" * 60)
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
# Create a fake v2.0 .ppz file
|
|
v2_file = os.path.join(temp_dir, "test_v2.ppz")
|
|
|
|
print(f"\n1. Creating v2.0 project file: {v2_file}")
|
|
v2_data = create_v2_project_json()
|
|
|
|
with zipfile.ZipFile(v2_file, "w", zipfile.ZIP_DEFLATED) as zipf:
|
|
project_json = json.dumps(v2_data, indent=2)
|
|
zipf.writestr("project.json", project_json)
|
|
|
|
print(f" ✓ Created v2.0 project with {len(v2_data['pages'])} page(s)")
|
|
print(f" ✓ Version: {v2_data['data_version']}")
|
|
|
|
# Load the v2.0 file (should trigger migration)
|
|
print(f"\n2. Loading v2.0 project (migration should occur)...")
|
|
|
|
try:
|
|
project = load_from_zip(v2_file)
|
|
print(f" ✓ Project loaded successfully")
|
|
print(f" ✓ Project name: {project.name}")
|
|
|
|
# Verify migration
|
|
print(f"\n3. Verifying migration to v3.0...")
|
|
|
|
# Check project-level fields
|
|
assert hasattr(project, "project_id"), "Missing project_id"
|
|
assert hasattr(project, "created"), "Missing created timestamp"
|
|
assert hasattr(project, "last_modified"), "Missing last_modified timestamp"
|
|
print(f" ✓ Project has project_id: {project.project_id}")
|
|
print(f" ✓ Project has created: {project.created}")
|
|
print(f" ✓ Project has last_modified: {project.last_modified}")
|
|
|
|
# Check page-level fields
|
|
assert len(project.pages) > 0, "No pages in project"
|
|
page = project.pages[0]
|
|
assert hasattr(page, "uuid"), "Page missing uuid"
|
|
assert hasattr(page, "created"), "Page missing created"
|
|
assert hasattr(page, "last_modified"), "Page missing last_modified"
|
|
assert hasattr(page, "deleted"), "Page missing deleted flag"
|
|
print(f" ✓ Page 1 has uuid: {page.uuid}")
|
|
print(f" ✓ Page 1 has timestamps and deletion tracking")
|
|
|
|
# Check element-level fields
|
|
assert len(page.layout.elements) > 0, "No elements in page"
|
|
element = page.layout.elements[0]
|
|
assert hasattr(element, "uuid"), "Element missing uuid"
|
|
assert hasattr(element, "created"), "Element missing created"
|
|
assert hasattr(element, "last_modified"), "Element missing last_modified"
|
|
assert hasattr(element, "deleted"), "Element missing deleted flag"
|
|
print(f" ✓ Element has uuid: {element.uuid}")
|
|
print(f" ✓ Element has timestamps and deletion tracking")
|
|
|
|
# Save as v3.0 and verify
|
|
print(f"\n4. Saving migrated project as v3.0...")
|
|
v3_file = os.path.join(temp_dir, "test_v3.ppz")
|
|
success, error = save_to_zip(project, v3_file)
|
|
assert success, f"Save failed: {error}"
|
|
print(f" ✓ Saved to: {v3_file}")
|
|
|
|
# Verify v3.0 file structure
|
|
with zipfile.ZipFile(v3_file, "r") as zipf:
|
|
project_json = zipf.read("project.json").decode("utf-8")
|
|
v3_data = json.loads(project_json)
|
|
|
|
assert v3_data.get("data_version") == "3.0", "Wrong version"
|
|
assert "project_id" in v3_data, "Missing project_id in saved file"
|
|
assert "created" in v3_data, "Missing created in saved file"
|
|
assert "uuid" in v3_data["pages"][0], "Missing page uuid in saved file"
|
|
|
|
print(f" ✓ Saved file version: {v3_data.get('data_version')}")
|
|
print(f" ✓ All v3.0 fields present in saved file")
|
|
|
|
print(f"\n{'=' * 60}")
|
|
print("✅ Migration test PASSED")
|
|
print(f"{'=' * 60}\n")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"\n{'=' * 60}")
|
|
print(f"❌ Migration test FAILED: {e}")
|
|
print(f"{'=' * 60}\n")
|
|
import traceback
|
|
|
|
traceback.print_exc()
|
|
return False
|
|
|
|
|
|
if __name__ == "__main__":
|
|
success = test_migration()
|
|
sys.exit(0 if success else 1)
|