180 lines
5.2 KiB
PHP
180 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace WPContentSync\Tests\Unit\Admin;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use WPContentSync\Admin\FileImportController;
|
|
use WPContentSync\Logging\LoggerInterface;
|
|
use WPContentSync\Package\PackageChecksum;
|
|
use WPContentSync\Package\PackageValidator;
|
|
use WPContentSync\Transport\JsonFileTransport;
|
|
|
|
class FileImportControllerTest extends TestCase {
|
|
/** @var array<int, string> */
|
|
private array $temporary_files = array();
|
|
|
|
protected function tearDown(): void {
|
|
foreach ( $this->temporary_files as $file ) {
|
|
if ( is_file( $file ) ) {
|
|
// phpcs:ignore WordPress.WP.AlternativeFunctions.unlink_unlink -- Removing a PHPUnit temp file.
|
|
unlink( $file );
|
|
}
|
|
}
|
|
|
|
unset( $GLOBALS['wpcs_current_user_can'], $GLOBALS['wpcs_nonce_valid'], $GLOBALS['wpcs_redirect_location'] );
|
|
$_FILES = array();
|
|
|
|
parent::tearDown();
|
|
}
|
|
|
|
public function test_it_rejects_users_without_manage_options(): void {
|
|
$GLOBALS['wpcs_current_user_can']['manage_options'] = false;
|
|
$controller = $this->controller();
|
|
|
|
$this->expectException( \RuntimeException::class );
|
|
$this->expectExceptionMessage( 'You do not have permission to import content packages.' );
|
|
|
|
$controller->handleImport();
|
|
}
|
|
|
|
public function test_it_rejects_invalid_nonces(): void {
|
|
$GLOBALS['wpcs_nonce_valid']['wpcs_import_package']['wpcs_import_package_nonce'] = false;
|
|
$controller = $this->controller();
|
|
|
|
$this->expectException( \RuntimeException::class );
|
|
$this->expectExceptionMessage( 'The import request could not be verified.' );
|
|
|
|
$controller->handleImport();
|
|
}
|
|
|
|
public function test_it_rejects_missing_uploads(): void {
|
|
$controller = $this->controller();
|
|
|
|
$this->expectException( \RuntimeException::class );
|
|
$this->expectExceptionMessage( 'Choose a package JSON file before importing.' );
|
|
|
|
$controller->handleImport();
|
|
}
|
|
|
|
public function test_it_rejects_failed_uploads(): void {
|
|
$_FILES['wpcs_package_file'] = array(
|
|
'tmp_name' => '',
|
|
'error' => UPLOAD_ERR_INI_SIZE,
|
|
);
|
|
$controller = $this->controller();
|
|
|
|
$this->expectException( \RuntimeException::class );
|
|
$this->expectExceptionMessage( 'The package file could not be uploaded.' );
|
|
|
|
$controller->handleImport();
|
|
}
|
|
|
|
public function test_it_imports_valid_uploaded_packages_without_mutating_content(): void {
|
|
$file = $this->createTemporaryPackageFile( $this->validJson() );
|
|
|
|
$_FILES['wpcs_package_file'] = array(
|
|
'tmp_name' => $file,
|
|
'error' => UPLOAD_ERR_OK,
|
|
);
|
|
|
|
$this->controller()->handleImport();
|
|
|
|
self::assertStringContainsString( 'wpcs_imported=1', $GLOBALS['wpcs_redirect_location'] );
|
|
}
|
|
|
|
public function test_it_redirects_with_error_for_invalid_uploaded_packages(): void {
|
|
$file = $this->createTemporaryPackageFile( '{"schema_version":' );
|
|
|
|
$_FILES['wpcs_package_file'] = array(
|
|
'tmp_name' => $file,
|
|
'error' => UPLOAD_ERR_OK,
|
|
);
|
|
|
|
$this->controller()->handleImport();
|
|
|
|
self::assertStringContainsString( 'wpcs_import_error=', $GLOBALS['wpcs_redirect_location'] );
|
|
self::assertStringContainsString( 'not+valid+JSON', $GLOBALS['wpcs_redirect_location'] );
|
|
}
|
|
|
|
private function controller(): FileImportController {
|
|
return new FileImportController(
|
|
new JsonFileTransport( new PackageValidator() ),
|
|
new class() implements LoggerInterface {
|
|
/**
|
|
* @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 validJson(): string {
|
|
$records = array(
|
|
'posts' => array(),
|
|
'terms' => array(),
|
|
'media' => array(),
|
|
'custom_post_types' => array(),
|
|
);
|
|
|
|
$json = wp_json_encode(
|
|
array(
|
|
'schema_version' => '1.0',
|
|
'generated_at' => '2026-04-26T20:30:00+00:00',
|
|
'source' => array(
|
|
'site_url' => 'https://example.test',
|
|
'name' => 'Example',
|
|
),
|
|
'destination' => array(
|
|
'site_url' => 'https://staging.example.test',
|
|
'name' => 'Staging',
|
|
),
|
|
'manifest' => array(
|
|
'posts' => 0,
|
|
'terms' => 0,
|
|
'media' => 0,
|
|
'custom_post_types' => 0,
|
|
),
|
|
'records' => $records,
|
|
'checksums' => array(
|
|
'records' => PackageChecksum::records( $records ),
|
|
),
|
|
)
|
|
);
|
|
|
|
if ( false === $json ) {
|
|
throw new \RuntimeException( 'Unable to create package JSON fixture.' );
|
|
}
|
|
|
|
return $json;
|
|
}
|
|
|
|
private function createTemporaryPackageFile( string $contents ): string {
|
|
$file = tempnam( sys_get_temp_dir(), 'wpcs-package-' );
|
|
|
|
if ( false === $file ) {
|
|
throw new \RuntimeException( 'Unable to create temporary package file.' );
|
|
}
|
|
|
|
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- Creating a PHPUnit temp fixture.
|
|
file_put_contents( $file, $contents );
|
|
$this->temporary_files[] = $file;
|
|
|
|
return $file;
|
|
}
|
|
}
|