feat: apply packages during imports
This commit is contained in:
@@ -8,15 +8,18 @@
|
|||||||
namespace WPContentSync\Admin;
|
namespace WPContentSync\Admin;
|
||||||
|
|
||||||
use WPContentSync\Logging\LoggerInterface;
|
use WPContentSync\Logging\LoggerInterface;
|
||||||
|
use WPContentSync\Sync\SyncEngine;
|
||||||
use WPContentSync\Transport\FileTransportInterface;
|
use WPContentSync\Transport\FileTransportInterface;
|
||||||
|
|
||||||
final class FileImportController {
|
final class FileImportController {
|
||||||
private FileTransportInterface $transport;
|
private FileTransportInterface $transport;
|
||||||
private LoggerInterface $logger;
|
private LoggerInterface $logger;
|
||||||
|
private SyncEngine $sync_engine;
|
||||||
|
|
||||||
public function __construct( FileTransportInterface $transport, LoggerInterface $logger ) {
|
public function __construct( FileTransportInterface $transport, LoggerInterface $logger, SyncEngine $sync_engine ) {
|
||||||
$this->transport = $transport;
|
$this->transport = $transport;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
|
$this->sync_engine = $sync_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function register(): void {
|
public function register(): void {
|
||||||
@@ -67,13 +70,23 @@ final class FileImportController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logger->info(
|
$result = $this->sync_engine->importPackage( $package );
|
||||||
'Validated imported content package.',
|
|
||||||
|
if ( ! $result->isSuccessful() ) {
|
||||||
|
$this->logger->error(
|
||||||
|
'Imported content package failed.',
|
||||||
|
$result->toArray()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->redirectToDashboard(
|
||||||
array(
|
array(
|
||||||
'schema_version' => $package->schemaVersion(),
|
'wpcs_import_error' => implode( ' ', $result->errors() ),
|
||||||
'manifest' => $package->manifest(),
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->info( 'Imported content package.', $result->toArray() );
|
||||||
|
|
||||||
$this->redirectToDashboard(
|
$this->redirectToDashboard(
|
||||||
array(
|
array(
|
||||||
|
|||||||
+86
-2
@@ -9,11 +9,18 @@ namespace WPContentSync;
|
|||||||
|
|
||||||
use WPContentSync\Admin\AdminPage;
|
use WPContentSync\Admin\AdminPage;
|
||||||
use WPContentSync\Admin\FileImportController;
|
use WPContentSync\Admin\FileImportController;
|
||||||
|
use WPContentSync\Content\ContentHandlerRegistry;
|
||||||
|
use WPContentSync\Content\ContentRecordNormalizer;
|
||||||
|
use WPContentSync\Content\MediaContentHandler;
|
||||||
|
use WPContentSync\Content\PostContentHandler;
|
||||||
|
use WPContentSync\Content\TermContentHandler;
|
||||||
use WPContentSync\Logging\LoggerInterface;
|
use WPContentSync\Logging\LoggerInterface;
|
||||||
use WPContentSync\Logging\OptionLogger;
|
use WPContentSync\Logging\OptionLogger;
|
||||||
use WPContentSync\Package\PackageValidator;
|
use WPContentSync\Package\PackageValidator;
|
||||||
use WPContentSync\Rest\RestPackageController;
|
use WPContentSync\Rest\RestPackageController;
|
||||||
use WPContentSync\Settings\SettingsRepository;
|
use WPContentSync\Settings\SettingsRepository;
|
||||||
|
use WPContentSync\Sync\SyncEngine;
|
||||||
|
use WPContentSync\Sync\SyncStateRepository;
|
||||||
use WPContentSync\Transport\FileTransportInterface;
|
use WPContentSync\Transport\FileTransportInterface;
|
||||||
use WPContentSync\Transport\JsonFileTransport;
|
use WPContentSync\Transport\JsonFileTransport;
|
||||||
use WPContentSync\Transport\RestTransportClient;
|
use WPContentSync\Transport\RestTransportClient;
|
||||||
@@ -67,6 +74,81 @@ final class Plugin {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$container->factory(
|
||||||
|
ContentRecordNormalizer::class,
|
||||||
|
static function (): ContentRecordNormalizer {
|
||||||
|
return new ContentRecordNormalizer();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$container->factory(
|
||||||
|
PostContentHandler::class,
|
||||||
|
static function () use ( $container ): PostContentHandler {
|
||||||
|
return new PostContentHandler(
|
||||||
|
$container->get( ContentRecordNormalizer::class ),
|
||||||
|
$container->get( UrlTransformer::class ),
|
||||||
|
$container->get( MetadataUrlTransformer::class ),
|
||||||
|
$container->get( LoggerInterface::class )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$container->factory(
|
||||||
|
TermContentHandler::class,
|
||||||
|
static function () use ( $container ): TermContentHandler {
|
||||||
|
return new TermContentHandler(
|
||||||
|
$container->get( ContentRecordNormalizer::class ),
|
||||||
|
$container->get( UrlTransformer::class ),
|
||||||
|
$container->get( MetadataUrlTransformer::class ),
|
||||||
|
$container->get( LoggerInterface::class )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$container->factory(
|
||||||
|
MediaContentHandler::class,
|
||||||
|
static function () use ( $container ): MediaContentHandler {
|
||||||
|
return new MediaContentHandler(
|
||||||
|
$container->get( ContentRecordNormalizer::class ),
|
||||||
|
$container->get( UrlTransformer::class ),
|
||||||
|
$container->get( MetadataUrlTransformer::class ),
|
||||||
|
$container->get( LoggerInterface::class )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$container->factory(
|
||||||
|
ContentHandlerRegistry::class,
|
||||||
|
static function () use ( $container ): ContentHandlerRegistry {
|
||||||
|
return new ContentHandlerRegistry(
|
||||||
|
array(
|
||||||
|
$container->get( PostContentHandler::class ),
|
||||||
|
$container->get( TermContentHandler::class ),
|
||||||
|
$container->get( MediaContentHandler::class ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$container->factory(
|
||||||
|
SyncStateRepository::class,
|
||||||
|
static function (): SyncStateRepository {
|
||||||
|
return new SyncStateRepository();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
$container->factory(
|
||||||
|
SyncEngine::class,
|
||||||
|
static function () use ( $container ): SyncEngine {
|
||||||
|
return new SyncEngine(
|
||||||
|
$container->get( ContentHandlerRegistry::class ),
|
||||||
|
$container->get( SyncStateRepository::class ),
|
||||||
|
$container->get( SettingsRepository::class ),
|
||||||
|
$container->get( LoggerInterface::class )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$container->factory(
|
$container->factory(
|
||||||
FileTransportInterface::class,
|
FileTransportInterface::class,
|
||||||
static function () use ( $container ): FileTransportInterface {
|
static function () use ( $container ): FileTransportInterface {
|
||||||
@@ -81,7 +163,8 @@ final class Plugin {
|
|||||||
static function () use ( $container ): FileImportController {
|
static function () use ( $container ): FileImportController {
|
||||||
return new FileImportController(
|
return new FileImportController(
|
||||||
$container->get( FileTransportInterface::class ),
|
$container->get( FileTransportInterface::class ),
|
||||||
$container->get( LoggerInterface::class )
|
$container->get( LoggerInterface::class ),
|
||||||
|
$container->get( SyncEngine::class )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -97,7 +180,8 @@ final class Plugin {
|
|||||||
RestPackageController::class,
|
RestPackageController::class,
|
||||||
static function () use ( $container ): RestPackageController {
|
static function () use ( $container ): RestPackageController {
|
||||||
return new RestPackageController(
|
return new RestPackageController(
|
||||||
$container->get( PackageValidator::class )
|
$container->get( PackageValidator::class ),
|
||||||
|
$container->get( SyncEngine::class )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -9,12 +9,15 @@ namespace WPContentSync\Rest;
|
|||||||
|
|
||||||
use WPContentSync\Package\ContentPackage;
|
use WPContentSync\Package\ContentPackage;
|
||||||
use WPContentSync\Package\PackageValidator;
|
use WPContentSync\Package\PackageValidator;
|
||||||
|
use WPContentSync\Sync\SyncEngine;
|
||||||
|
|
||||||
final class RestPackageController {
|
final class RestPackageController {
|
||||||
private PackageValidator $validator;
|
private PackageValidator $validator;
|
||||||
|
private SyncEngine $sync_engine;
|
||||||
|
|
||||||
public function __construct( PackageValidator $validator ) {
|
public function __construct( PackageValidator $validator, SyncEngine $sync_engine ) {
|
||||||
$this->validator = $validator;
|
$this->validator = $validator;
|
||||||
|
$this->sync_engine = $sync_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function register(): void {
|
public function register(): void {
|
||||||
@@ -82,11 +85,13 @@ final class RestPackageController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$package = ContentPackage::fromArray( $data['package'] );
|
$package = ContentPackage::fromArray( $data['package'] );
|
||||||
|
$import = $this->sync_engine->importPackage( $package );
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'accepted' => true,
|
'accepted' => $import->isSuccessful(),
|
||||||
'schema_version' => $package->schemaVersion(),
|
'schema_version' => $package->schemaVersion(),
|
||||||
'manifest' => $package->manifest(),
|
'manifest' => $package->manifest(),
|
||||||
|
'import' => $import->toArray(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,25 @@ namespace WPContentSync\Tests\Unit\Admin;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use WPContentSync\Admin\FileImportController;
|
use WPContentSync\Admin\FileImportController;
|
||||||
|
use WPContentSync\Content\ContentHandlerInterface;
|
||||||
|
use WPContentSync\Content\ContentHandlerRegistry;
|
||||||
use WPContentSync\Logging\LoggerInterface;
|
use WPContentSync\Logging\LoggerInterface;
|
||||||
use WPContentSync\Package\PackageChecksum;
|
use WPContentSync\Package\PackageChecksum;
|
||||||
use WPContentSync\Package\PackageValidator;
|
use WPContentSync\Package\PackageValidator;
|
||||||
|
use WPContentSync\Settings\SettingsRepository;
|
||||||
|
use WPContentSync\Sync\SyncContext;
|
||||||
|
use WPContentSync\Sync\SyncEngine;
|
||||||
|
use WPContentSync\Sync\SyncResult;
|
||||||
|
use WPContentSync\Sync\SyncStateRepository;
|
||||||
use WPContentSync\Transport\JsonFileTransport;
|
use WPContentSync\Transport\JsonFileTransport;
|
||||||
|
|
||||||
class FileImportControllerTest extends TestCase {
|
class FileImportControllerTest extends TestCase {
|
||||||
/** @var array<int, string> */
|
/** @var array<int, string> */
|
||||||
private array $temporary_files = array();
|
private array $temporary_files = array();
|
||||||
|
|
||||||
|
/** @var array<int, array<string, mixed>> */
|
||||||
|
private array $logs = array();
|
||||||
|
|
||||||
protected function tearDown(): void {
|
protected function tearDown(): void {
|
||||||
foreach ( $this->temporary_files as $file ) {
|
foreach ( $this->temporary_files as $file ) {
|
||||||
if ( is_file( $file ) ) {
|
if ( is_file( $file ) ) {
|
||||||
@@ -21,8 +31,17 @@ class FileImportControllerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unset( $GLOBALS['wpcs_current_user_can'], $GLOBALS['wpcs_nonce_valid'], $GLOBALS['wpcs_redirect_location'] );
|
unset(
|
||||||
|
$GLOBALS['wpcs_current_user_can'],
|
||||||
|
$GLOBALS['wpcs_nonce_valid'],
|
||||||
|
$GLOBALS['wpcs_redirect_location'],
|
||||||
|
$GLOBALS['wpcs_test_options'],
|
||||||
|
$GLOBALS['wpcs_test_option_autoloads'],
|
||||||
|
$GLOBALS['wpcs_test_transients'],
|
||||||
|
$GLOBALS['wpcs_test_transient_expiration']
|
||||||
|
);
|
||||||
$_FILES = array();
|
$_FILES = array();
|
||||||
|
$this->logs = array();
|
||||||
|
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
@@ -69,7 +88,7 @@ class FileImportControllerTest extends TestCase {
|
|||||||
$controller->handleImport();
|
$controller->handleImport();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_it_imports_valid_uploaded_packages_without_mutating_content(): void {
|
public function test_it_imports_valid_uploaded_packages_with_sync_engine(): void {
|
||||||
$file = $this->createTemporaryPackageFile( $this->validJson() );
|
$file = $this->createTemporaryPackageFile( $this->validJson() );
|
||||||
|
|
||||||
$_FILES['wpcs_package_file'] = array(
|
$_FILES['wpcs_package_file'] = array(
|
||||||
@@ -80,6 +99,22 @@ class FileImportControllerTest extends TestCase {
|
|||||||
$this->controller()->handleImport();
|
$this->controller()->handleImport();
|
||||||
|
|
||||||
self::assertStringContainsString( 'wpcs_imported=1', $GLOBALS['wpcs_redirect_location'] );
|
self::assertStringContainsString( 'wpcs_imported=1', $GLOBALS['wpcs_redirect_location'] );
|
||||||
|
self::assertSame( 'Imported content package.', $this->logs[2]['message'] );
|
||||||
|
self::assertSame( 0, $this->logs[2]['context']['created'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_it_redirects_with_error_when_sync_engine_import_fails(): void {
|
||||||
|
$file = $this->createTemporaryPackageFile( $this->validJson() );
|
||||||
|
|
||||||
|
$_FILES['wpcs_package_file'] = array(
|
||||||
|
'tmp_name' => $file,
|
||||||
|
'error' => UPLOAD_ERR_OK,
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->controller( SyncResult::failure( array( 'Posts failed.' ) ) )->handleImport();
|
||||||
|
|
||||||
|
self::assertStringContainsString( 'wpcs_import_error=', $GLOBALS['wpcs_redirect_location'] );
|
||||||
|
self::assertStringContainsString( 'Posts+failed.', $GLOBALS['wpcs_redirect_location'] );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_it_redirects_with_error_for_invalid_uploaded_packages(): void {
|
public function test_it_redirects_with_error_for_invalid_uploaded_packages(): void {
|
||||||
@@ -96,33 +131,84 @@ class FileImportControllerTest extends TestCase {
|
|||||||
self::assertStringContainsString( 'not+valid+JSON', $GLOBALS['wpcs_redirect_location'] );
|
self::assertStringContainsString( 'not+valid+JSON', $GLOBALS['wpcs_redirect_location'] );
|
||||||
}
|
}
|
||||||
|
|
||||||
private function controller(): FileImportController {
|
private function controller( ?SyncResult $result = null ): FileImportController {
|
||||||
|
$logger = $this->logger();
|
||||||
|
|
||||||
return new FileImportController(
|
return new FileImportController(
|
||||||
new JsonFileTransport( new PackageValidator() ),
|
new JsonFileTransport( new PackageValidator() ),
|
||||||
new class() implements LoggerInterface {
|
$logger,
|
||||||
/**
|
$this->syncEngine( $result ?? SyncResult::success() )
|
||||||
* @param array<string, mixed> $context Context.
|
|
||||||
*/
|
|
||||||
public function error( string $message, array $context = array() ): void {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array<string, mixed> $context Context.
|
|
||||||
*/
|
|
||||||
public function warning( string $message, array $context = array() ): void {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array<string, mixed> $context Context.
|
|
||||||
*/
|
|
||||||
public function info( string $message, array $context = array() ): void {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array<string, mixed> $context Context.
|
|
||||||
*/
|
|
||||||
public function debug( string $message, array $context = array() ): void {}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function syncEngine( SyncResult $result ): SyncEngine {
|
||||||
|
return new SyncEngine(
|
||||||
|
new ContentHandlerRegistry( array( $this->handler( $result ) ) ),
|
||||||
|
new SyncStateRepository(),
|
||||||
|
new SettingsRepository(),
|
||||||
|
$this->logger()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handler( SyncResult $result ): ContentHandlerInterface {
|
||||||
|
return new class( $result ) implements ContentHandlerInterface {
|
||||||
|
private SyncResult $result;
|
||||||
|
|
||||||
|
public function __construct( SyncResult $result ) {
|
||||||
|
$this->result = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bucket(): string {
|
||||||
|
return 'posts';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function importRecords( array $records, SyncContext $context ): SyncResult {
|
||||||
|
return $this->result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private function logger(): LoggerInterface {
|
||||||
|
return new class( $this->logs ) implements LoggerInterface {
|
||||||
|
/** @var array<int, array<string, mixed>> */
|
||||||
|
private array $logs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int, array<string, mixed>> $logs Logs.
|
||||||
|
*/
|
||||||
|
public function __construct( array &$logs ) {
|
||||||
|
$this->logs = &$logs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function error( string $message, array $context = array() ): void {
|
||||||
|
$this->record( 'error', $message, $context );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function warning( string $message, array $context = array() ): void {
|
||||||
|
$this->record( 'warning', $message, $context );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function info( string $message, array $context = array() ): void {
|
||||||
|
$this->record( 'info', $message, $context );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function debug( string $message, array $context = array() ): void {
|
||||||
|
$this->record( 'debug', $message, $context );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $context Context.
|
||||||
|
*/
|
||||||
|
private function record( string $level, string $message, array $context ): void {
|
||||||
|
$this->logs[] = array(
|
||||||
|
'level' => $level,
|
||||||
|
'message' => $message,
|
||||||
|
'context' => $context,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private function validJson(): string {
|
private function validJson(): string {
|
||||||
$records = array(
|
$records = array(
|
||||||
'posts' => array(),
|
'posts' => array(),
|
||||||
|
|||||||
@@ -4,9 +4,16 @@ namespace WPContentSync\Tests\Unit;
|
|||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use WPContentSync\Admin\FileImportController;
|
use WPContentSync\Admin\FileImportController;
|
||||||
|
use WPContentSync\Content\ContentHandlerRegistry;
|
||||||
|
use WPContentSync\Content\ContentRecordNormalizer;
|
||||||
|
use WPContentSync\Content\MediaContentHandler;
|
||||||
|
use WPContentSync\Content\PostContentHandler;
|
||||||
|
use WPContentSync\Content\TermContentHandler;
|
||||||
use WPContentSync\Container;
|
use WPContentSync\Container;
|
||||||
use WPContentSync\Plugin;
|
use WPContentSync\Plugin;
|
||||||
use WPContentSync\Rest\RestPackageController;
|
use WPContentSync\Rest\RestPackageController;
|
||||||
|
use WPContentSync\Sync\SyncEngine;
|
||||||
|
use WPContentSync\Sync\SyncStateRepository;
|
||||||
use WPContentSync\Transport\FileTransportInterface;
|
use WPContentSync\Transport\FileTransportInterface;
|
||||||
use WPContentSync\Transport\RestTransportClient;
|
use WPContentSync\Transport\RestTransportClient;
|
||||||
use WPContentSync\Url\MetadataUrlTransformer;
|
use WPContentSync\Url\MetadataUrlTransformer;
|
||||||
@@ -57,6 +64,18 @@ class PluginTest extends TestCase {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_it_registers_sync_engine_and_content_handlers(): void {
|
||||||
|
$container = $this->getPluginContainer( Plugin::create() );
|
||||||
|
|
||||||
|
self::assertInstanceOf( ContentRecordNormalizer::class, $container->get( ContentRecordNormalizer::class ) );
|
||||||
|
self::assertInstanceOf( PostContentHandler::class, $container->get( PostContentHandler::class ) );
|
||||||
|
self::assertInstanceOf( TermContentHandler::class, $container->get( TermContentHandler::class ) );
|
||||||
|
self::assertInstanceOf( MediaContentHandler::class, $container->get( MediaContentHandler::class ) );
|
||||||
|
self::assertInstanceOf( ContentHandlerRegistry::class, $container->get( ContentHandlerRegistry::class ) );
|
||||||
|
self::assertInstanceOf( SyncStateRepository::class, $container->get( SyncStateRepository::class ) );
|
||||||
|
self::assertInstanceOf( SyncEngine::class, $container->get( SyncEngine::class ) );
|
||||||
|
}
|
||||||
|
|
||||||
public function test_it_hooks_rest_package_controller_on_register(): void {
|
public function test_it_hooks_rest_package_controller_on_register(): void {
|
||||||
unset( $GLOBALS['wpcs_test_actions'] );
|
unset( $GLOBALS['wpcs_test_actions'] );
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,17 @@
|
|||||||
namespace WPContentSync\Tests\Unit\Rest;
|
namespace WPContentSync\Tests\Unit\Rest;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use WPContentSync\Content\ContentHandlerInterface;
|
||||||
|
use WPContentSync\Content\ContentHandlerRegistry;
|
||||||
|
use WPContentSync\Logging\LoggerInterface;
|
||||||
use WPContentSync\Package\PackageChecksum;
|
use WPContentSync\Package\PackageChecksum;
|
||||||
use WPContentSync\Package\PackageValidator;
|
use WPContentSync\Package\PackageValidator;
|
||||||
use WPContentSync\Rest\RestPackageController;
|
use WPContentSync\Rest\RestPackageController;
|
||||||
|
use WPContentSync\Settings\SettingsRepository;
|
||||||
|
use WPContentSync\Sync\SyncContext;
|
||||||
|
use WPContentSync\Sync\SyncEngine;
|
||||||
|
use WPContentSync\Sync\SyncResult;
|
||||||
|
use WPContentSync\Sync\SyncStateRepository;
|
||||||
|
|
||||||
class RestPackageControllerTest extends TestCase {
|
class RestPackageControllerTest extends TestCase {
|
||||||
protected function setUp(): void {
|
protected function setUp(): void {
|
||||||
@@ -20,13 +28,21 @@ class RestPackageControllerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown(): void {
|
protected function tearDown(): void {
|
||||||
unset( $GLOBALS['wpcs_rest_routes'], $GLOBALS['wpcs_current_user_can'], $GLOBALS['wpcs_test_actions'] );
|
unset(
|
||||||
|
$GLOBALS['wpcs_rest_routes'],
|
||||||
|
$GLOBALS['wpcs_current_user_can'],
|
||||||
|
$GLOBALS['wpcs_test_actions'],
|
||||||
|
$GLOBALS['wpcs_test_options'],
|
||||||
|
$GLOBALS['wpcs_test_option_autoloads'],
|
||||||
|
$GLOBALS['wpcs_test_transients'],
|
||||||
|
$GLOBALS['wpcs_test_transient_expiration']
|
||||||
|
);
|
||||||
|
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_it_hooks_route_registration_to_rest_api_init(): void {
|
public function test_it_hooks_route_registration_to_rest_api_init(): void {
|
||||||
$controller = new RestPackageController( new PackageValidator() );
|
$controller = $this->controller();
|
||||||
$controller->register();
|
$controller->register();
|
||||||
|
|
||||||
self::assertSame(
|
self::assertSame(
|
||||||
@@ -36,7 +52,7 @@ class RestPackageControllerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function test_it_registers_status_and_package_routes(): void {
|
public function test_it_registers_status_and_package_routes(): void {
|
||||||
$controller = new RestPackageController( new PackageValidator() );
|
$controller = $this->controller();
|
||||||
$controller->registerRoutes();
|
$controller->registerRoutes();
|
||||||
|
|
||||||
self::assertArrayHasKey( 'wp-content-sync/v1/status', $GLOBALS['wpcs_rest_routes'] );
|
self::assertArrayHasKey( 'wp-content-sync/v1/status', $GLOBALS['wpcs_rest_routes'] );
|
||||||
@@ -45,13 +61,13 @@ class RestPackageControllerTest extends TestCase {
|
|||||||
|
|
||||||
public function test_it_requires_manage_options_permission(): void {
|
public function test_it_requires_manage_options_permission(): void {
|
||||||
$GLOBALS['wpcs_current_user_can']['manage_options'] = false;
|
$GLOBALS['wpcs_current_user_can']['manage_options'] = false;
|
||||||
$controller = new RestPackageController( new PackageValidator() );
|
$controller = $this->controller();
|
||||||
|
|
||||||
self::assertFalse( $controller->canReceivePackage() );
|
self::assertFalse( $controller->canReceivePackage() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_it_returns_status_payload(): void {
|
public function test_it_returns_status_payload(): void {
|
||||||
$controller = new RestPackageController( new PackageValidator() );
|
$controller = $this->controller();
|
||||||
|
|
||||||
self::assertSame(
|
self::assertSame(
|
||||||
array(
|
array(
|
||||||
@@ -64,7 +80,7 @@ class RestPackageControllerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function test_it_accepts_valid_packages(): void {
|
public function test_it_accepts_valid_packages(): void {
|
||||||
$controller = new RestPackageController( new PackageValidator() );
|
$controller = $this->controller();
|
||||||
|
|
||||||
self::assertSame(
|
self::assertSame(
|
||||||
$this->acceptedResponse(),
|
$this->acceptedResponse(),
|
||||||
@@ -77,7 +93,7 @@ class RestPackageControllerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function test_it_accepts_rest_request_like_objects(): void {
|
public function test_it_accepts_rest_request_like_objects(): void {
|
||||||
$controller = new RestPackageController( new PackageValidator() );
|
$controller = $this->controller();
|
||||||
$request = new class(
|
$request = new class(
|
||||||
array(
|
array(
|
||||||
'package' => $this->validPackage(),
|
'package' => $this->validPackage(),
|
||||||
@@ -105,7 +121,7 @@ class RestPackageControllerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function test_it_rejects_invalid_package_shapes(): void {
|
public function test_it_rejects_invalid_package_shapes(): void {
|
||||||
$controller = new RestPackageController( new PackageValidator() );
|
$controller = $this->controller();
|
||||||
|
|
||||||
self::assertSame(
|
self::assertSame(
|
||||||
array(
|
array(
|
||||||
@@ -116,6 +132,36 @@ class RestPackageControllerTest extends TestCase {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_it_returns_rejected_response_when_sync_import_fails(): void {
|
||||||
|
$controller = $this->controller( SyncResult::failure( array( 'Posts failed.' ) ) );
|
||||||
|
|
||||||
|
self::assertSame(
|
||||||
|
array(
|
||||||
|
'accepted' => false,
|
||||||
|
'schema_version' => '1.0',
|
||||||
|
'manifest' => array(
|
||||||
|
'posts' => 0,
|
||||||
|
'terms' => 0,
|
||||||
|
'media' => 0,
|
||||||
|
'custom_post_types' => 0,
|
||||||
|
),
|
||||||
|
'import' => array(
|
||||||
|
'successful' => false,
|
||||||
|
'created' => 0,
|
||||||
|
'updated' => 0,
|
||||||
|
'skipped' => 0,
|
||||||
|
'conflicts' => 0,
|
||||||
|
'errors' => array( 'Posts failed.' ),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
$controller->receivePackage(
|
||||||
|
array(
|
||||||
|
'package' => $this->validPackage(),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
@@ -129,9 +175,63 @@ class RestPackageControllerTest extends TestCase {
|
|||||||
'media' => 0,
|
'media' => 0,
|
||||||
'custom_post_types' => 0,
|
'custom_post_types' => 0,
|
||||||
),
|
),
|
||||||
|
'import' => array(
|
||||||
|
'successful' => true,
|
||||||
|
'created' => 0,
|
||||||
|
'updated' => 0,
|
||||||
|
'skipped' => 0,
|
||||||
|
'conflicts' => 0,
|
||||||
|
'errors' => array(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function controller( ?SyncResult $result = null ): RestPackageController {
|
||||||
|
return new RestPackageController(
|
||||||
|
new PackageValidator(),
|
||||||
|
$this->syncEngine( $result ?? SyncResult::success() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function syncEngine( SyncResult $result ): SyncEngine {
|
||||||
|
return new SyncEngine(
|
||||||
|
new ContentHandlerRegistry( array( $this->handler( $result ) ) ),
|
||||||
|
new SyncStateRepository(),
|
||||||
|
new SettingsRepository(),
|
||||||
|
$this->logger()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handler( SyncResult $result ): ContentHandlerInterface {
|
||||||
|
return new class( $result ) implements ContentHandlerInterface {
|
||||||
|
private SyncResult $result;
|
||||||
|
|
||||||
|
public function __construct( SyncResult $result ) {
|
||||||
|
$this->result = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bucket(): string {
|
||||||
|
return 'posts';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function importRecords( array $records, SyncContext $context ): SyncResult {
|
||||||
|
return $this->result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private function logger(): LoggerInterface {
|
||||||
|
return new class() implements LoggerInterface {
|
||||||
|
public function error( string $message, array $context = array() ): void {}
|
||||||
|
|
||||||
|
public function warning( string $message, array $context = array() ): void {}
|
||||||
|
|
||||||
|
public function info( string $message, array $context = array() ): void {}
|
||||||
|
|
||||||
|
public function debug( string $message, array $context = array() ): void {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<string, mixed>
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user