feat: add sync context and operation state

This commit is contained in:
Keith Solomon
2026-04-28 13:51:38 -05:00
parent 90cb78b712
commit b176a37457
6 changed files with 334 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
<?php
/**
* Tests for sync operation context.
*
* @package WPContentSync
*/
namespace WPContentSync\Tests\Unit\Sync;
use PHPUnit\Framework\TestCase;
use WPContentSync\Sync\SyncContext;
class SyncContextTest extends TestCase {
public function test_it_builds_import_context_from_package_sites(): void {
$context = SyncContext::forImport(
array( 'site_url' => 'https://source.test' ),
array( 'site_url' => 'https://destination.test' ),
'last_write_wins',
'operation-1'
);
self::assertSame( 'import', $context->direction() );
self::assertSame( 'operation-1', $context->operationId() );
self::assertSame( 'last_write_wins', $context->conflictStrategy() );
self::assertSame( 'https://source.test', $context->sourceUrl() );
self::assertSame( 'https://destination.test', $context->destinationUrl() );
self::assertSame(
array( 'https://source.test' => 'https://destination.test' ),
$context->urlMappings()
);
}
public function test_it_falls_back_to_last_write_wins_for_invalid_strategy(): void {
$context = SyncContext::forImport( array(), array(), 'surprise', 'operation-2' );
self::assertSame( 'last_write_wins', $context->conflictStrategy() );
}
}
@@ -0,0 +1,46 @@
<?php
/**
* Tests for sync state persistence.
*
* @package WPContentSync
*/
namespace WPContentSync\Tests\Unit\Sync;
use PHPUnit\Framework\TestCase;
use WPContentSync\Sync\SyncOperationState;
use WPContentSync\Sync\SyncStateRepository;
class SyncStateRepositoryTest extends TestCase {
protected function tearDown(): void {
unset( $GLOBALS['wpcs_test_transients'], $GLOBALS['wpcs_test_transient_expiration'] );
parent::tearDown();
}
public function test_it_saves_and_reads_operation_state(): void {
$repository = new SyncStateRepository();
$state = SyncOperationState::running( 'operation-1', 'posts', 2, 10 );
$repository->save( $state );
$loaded = $repository->get( 'operation-1' );
self::assertInstanceOf( SyncOperationState::class, $loaded );
self::assertSame( 'operation-1', $loaded->operationId() );
self::assertSame( 'posts', $loaded->currentBucket() );
self::assertSame( 2, $loaded->processed() );
self::assertSame( 10, $loaded->total() );
self::assertSame( 'running', $loaded->status() );
}
public function test_it_deletes_operation_state(): void {
$repository = new SyncStateRepository();
$repository->save( SyncOperationState::completed( 'operation-1', 10, 10 ) );
$repository->delete( 'operation-1' );
self::assertNull( $repository->get( 'operation-1' ) );
self::assertArrayNotHasKey( 'wpcs_sync_state_operation-1', $GLOBALS['wpcs_test_transient_expiration'] );
}
}