Major improvements to WooNooW Page Editor system: Schema & Architecture: - Canonical section schema with unified sectionSchema.ts - Normalized feature-grid to use items (not features) - Standardized default values across all section types - Schema versioning with automatic migration on read Backend (PHP): - Enhanced PlaceholderRenderer with typed output contracts - Added fallback behavior for empty/invalid dynamic sources - Added caching support for post data resolution - New SchemaMigration class for backward compatibility - New Features class for feature flags - Enhanced PageSSR with full style support - Removed controller-level special-casing for related_posts Frontend (Admin SPA): - Updated CanvasRenderer with schema-aware transformation - Enhanced InspectorPanel with canonical schema metadata - Added new section renderers Frontend (Customer SPA): - New section components: BentoCategoryGrid, MarqueeBanner, ProductCarousel, ShoppableImage - Updated FeatureGridSection for items prop contract Testing: - Add PHP tests: SchemaMigrationTest, PlaceholderRendererTest, PageSSRTest - Add TypeScript tests: schema-integration, feature-grid-regression - Add parity tests for React vs SSR content matching - Add CI script: check-schema-drift.mjs - Add VERIFICATION_CHECKLIST.md Documentation: - RELEASE_NOTES-v1.0.md with full release notes - docs/PAGE_EDITOR_SECTION_SCHEMA_V1.md - docs/PAGE_EDITOR_SSR_COVERAGE_AUDIT.md
207 lines
5.9 KiB
PHP
207 lines
5.9 KiB
PHP
<?php
|
|
/**
|
|
* Schema Migration Tests
|
|
* Tests for backward compatibility and migration of legacy structures
|
|
*/
|
|
|
|
namespace WooNooW\Tests;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use WooNooW\Frontend\SchemaMigration;
|
|
|
|
class SchemaMigrationTest extends TestCase
|
|
{
|
|
/**
|
|
* Test that v1 structures don't need migration
|
|
*/
|
|
public function test_v1_structures_dont_need_migration()
|
|
{
|
|
$structure = [
|
|
'type' => 'page',
|
|
'schemaVersion' => 1,
|
|
'sections' => [],
|
|
];
|
|
|
|
$this->assertFalse(SchemaMigration::needs_migration($structure));
|
|
}
|
|
|
|
/**
|
|
* Test that structures without version need migration
|
|
*/
|
|
public function test_structures_without_version_need_migration()
|
|
{
|
|
$structure = [
|
|
'type' => 'page',
|
|
'sections' => [],
|
|
];
|
|
|
|
$this->assertTrue(SchemaMigration::needs_migration($structure));
|
|
}
|
|
|
|
/**
|
|
* Test migration of feature-grid with legacy features key
|
|
*/
|
|
public function test_migrate_feature_grid_features_to_items()
|
|
{
|
|
$structure = [
|
|
'schemaVersion' => 0,
|
|
'sections' => [
|
|
[
|
|
'type' => 'feature-grid',
|
|
'props' => [
|
|
'heading' => ['type' => 'static', 'value' => 'Test'],
|
|
'features' => [
|
|
['title' => 'Feature 1', 'description' => 'Desc 1'],
|
|
['title' => 'Feature 2', 'description' => 'Desc 2'],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$migrated = SchemaMigration::migrate($structure);
|
|
|
|
$this->assertEquals(1, $migrated['schemaVersion']);
|
|
$this->assertArrayHasKey('items', $migrated['sections'][0]['props']);
|
|
$this->assertEquals($structure['sections'][0]['props']['features'], $migrated['sections'][0]['props']['items']);
|
|
}
|
|
|
|
/**
|
|
* Test migration of feature-grid with empty features string
|
|
*/
|
|
public function test_migrate_feature_grid_empty_features_to_items()
|
|
{
|
|
$structure = [
|
|
'schemaVersion' => 0,
|
|
'sections' => [
|
|
[
|
|
'type' => 'feature-grid',
|
|
'props' => [
|
|
'heading' => ['type' => 'static', 'value' => 'Test'],
|
|
'features' => '',
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$migrated = SchemaMigration::migrate($structure);
|
|
|
|
$this->assertEquals([], $migrated['sections'][0]['props']['items']);
|
|
}
|
|
|
|
/**
|
|
* Test migration of container_width to contentWidth
|
|
*/
|
|
public function test_migrate_container_width_to_content_width()
|
|
{
|
|
$structure = [
|
|
'schemaVersion' => 0,
|
|
'sections' => [
|
|
[
|
|
'type' => 'hero',
|
|
'styles' => [
|
|
'container_width' => 'full',
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$migrated = SchemaMigration::migrate($structure);
|
|
|
|
$this->assertArrayHasKey('contentWidth', $migrated['sections'][0]['styles']);
|
|
$this->assertEquals('full', $migrated['sections'][0]['styles']['contentWidth']);
|
|
$this->assertArrayNotHasKey('container_width', $migrated['sections'][0]['styles']);
|
|
}
|
|
|
|
/**
|
|
* Test migration of background image without type
|
|
*/
|
|
public function test_migrate_background_image_adds_type()
|
|
{
|
|
$structure = [
|
|
'schemaVersion' => 0,
|
|
'sections' => [
|
|
[
|
|
'type' => 'hero',
|
|
'styles' => [
|
|
'backgroundImage' => 'https://example.com/image.jpg',
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$migrated = SchemaMigration::migrate($structure);
|
|
|
|
$this->assertEquals('image', $migrated['sections'][0]['styles']['backgroundType']);
|
|
}
|
|
|
|
/**
|
|
* Test migration of height to heightPreset
|
|
*/
|
|
public function test_migrate_height_to_height_preset()
|
|
{
|
|
$structure = [
|
|
'schemaVersion' => 0,
|
|
'sections' => [
|
|
[
|
|
'type' => 'hero',
|
|
'styles' => [
|
|
'height' => 'screen',
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$migrated = SchemaMigration::migrate($structure);
|
|
|
|
$this->assertArrayHasKey('heightPreset', $migrated['sections'][0]['styles']);
|
|
$this->assertEquals('fullscreen', $migrated['sections'][0]['styles']['heightPreset']);
|
|
$this->assertArrayNotHasKey('height', $migrated['sections'][0]['styles']);
|
|
}
|
|
|
|
/**
|
|
* Test migration adds default backgroundType
|
|
*/
|
|
public function test_migrate_adds_default_background_type()
|
|
{
|
|
$structure = [
|
|
'schemaVersion' => 0,
|
|
'sections' => [
|
|
[
|
|
'type' => 'hero',
|
|
'styles' => [],
|
|
],
|
|
],
|
|
];
|
|
|
|
$migrated = SchemaMigration::migrate($structure);
|
|
|
|
$this->assertEquals('solid', $migrated['sections'][0]['styles']['backgroundType']);
|
|
}
|
|
|
|
/**
|
|
* Test batch migration
|
|
*/
|
|
public function test_migrate_all()
|
|
{
|
|
$structures = [
|
|
['schemaVersion' => 0, 'sections' => []],
|
|
['schemaVersion' => 1, 'sections' => []],
|
|
['schemaVersion' => 0, 'sections' => []],
|
|
];
|
|
|
|
$migrated = SchemaMigration::migrate_all($structures);
|
|
|
|
$this->assertEquals(1, $migrated[0]['schemaVersion']);
|
|
$this->assertEquals(1, $migrated[1]['schemaVersion']);
|
|
$this->assertEquals(1, $migrated[2]['schemaVersion']);
|
|
}
|
|
|
|
/**
|
|
* Test current version is returned
|
|
*/
|
|
public function test_get_current_version()
|
|
{
|
|
$this->assertEquals(1, SchemaMigration::get_current_version());
|
|
}
|
|
} |