Commit bb35a3557c for woocommerce
commit bb35a3557c495c186eef32f8725f2164761e18d1
Author: Chi-Hsuan Huang <chihsuan.tw@gmail.com>
Date: Thu Apr 24 17:07:23 2025 +0800
[Blueprint] Fix php warnings and improve error handling (#57268)
* Enhance UseWPFunctions trait with additional filesystem methods and improved documentation
- Added `wp_filesystem_get_contents` method for reading file contents.
- Updated return types in existing methods for clarity.
- Improved documentation comments for better understanding of method behaviors.
* Refactor ExportCli to utilize UseWPFunctions for filesystem operations
- Integrated UseWPFunctions trait into ExportCli class.
- Replaced direct file_put_contents call with wp_filesystem_put_contents for improved filesystem handling.
- Enhanced error handling for file saving operations.
* Refactor ResourceStorages class to improve parameter naming and enhance clarity
- Updated method parameters from `$resource` to `$resource_type` for better understanding.
- Adjusted logic in `is_supported_resource` and `download` methods to reflect the new parameter naming.
- Improved code readability by removing unnecessary comments and ensuring consistent formatting.
* Enhance OrgPluginResourceStorage class with improved error handling in download methods
- Updated return types in the `download` and `download_url` methods for clarity, changing from nullable types to more explicit error handling.
- Added checks for `WP_Error` to ensure robust error management during plugin downloads.
- Improved documentation comments to reflect the changes in return types and enhance understanding of method behaviors.
* Improve error handling in OrgThemeResourceStorage class by checking for WP_Error before accessing download link
- Added a check for WP_Error to return null if an error occurs, enhancing the robustness of the download link retrieval process.
- This change ensures that the method handles errors gracefully, preventing potential issues when accessing the download link.
* Update documentation for plugin activation and deletion methods in UsePluginHelpers trait
- Revised return type annotations for `activate_plugin_by_slug` and `delete_plugin_by_slug` methods to provide clearer expectations.
- Updated comments to reflect the possibility of returning `WP_Error` and `null`, enhancing understanding of error handling in these methods.
* Refactor plugin and theme activation processes for improved clarity
- Updated comments in `ImportActivatePlugin` to clarify the use of non-snake case property names.
- Modified `ImportActivateTheme` to remove the unnecessary return value from `wp_switch_theme`, enhancing code readability and understanding of the method's behavior.
* Refactor theme installation method for improved clarity
- Updated method parameter name from `$local_plugin_path` to `$local_path` to accurately reflect its purpose.
- Revised documentation comments to clarify that the method installs a theme from the local path, enhancing understanding of its functionality.
* Improve error handling in ImportDeactivatePlugin by checking for WP_Error after deactivating a plugin
- Added a check for WP_Error when attempting to deactivate a plugin, providing clearer feedback on success or failure.
- Updated the response messages to inform users whether the deactivation was successful or if an error occurred.
* Enhance JsonSchema class with improved error handling and filesystem integration
- Integrated UseWPFunctions trait to utilize WordPress filesystem functions.
- Added checks for valid schema path and improved error handling for JSON file reading.
- Updated validation to ensure 'steps' field is an array, enhancing schema integrity.
* Add changelog
* Refactor theme activation process to improve clarity and remove unnecessary return value
- Removed the return value from the `wp_switch_theme` method in `ImportActivateTheme`, enhancing code readability.
- Added a check to confirm the theme switch was successful before logging the debug message, improving the accuracy of feedback provided to users.
* Add tests for JsonSchema class to improve error handling coverage
- Introduced new test methods to validate exception handling for invalid paths and unreadable files.
- Utilized Mockery to simulate filesystem behavior, enhancing the robustness of the tests.
- Ensured that the JsonSchema class correctly throws exceptions for various error scenarios, improving overall error handling.
* Enhance ImportInstallPlugin with improved error handling and clarity
- Added checks to skip installation if the plugin is already installed and to validate resource types.
- Improved error handling during plugin installation and activation, providing clearer feedback on success or failure.
- Updated method documentation to reflect the possibility of returning WP_Error on failure.
* Implement error handling in ImportCli for schema file creation
- Added try-catch block in the run method to handle exceptions when creating the blueprint from the schema file.
- Improved user feedback by utilizing WP_CLI::error to display error messages, enhancing the robustness of the import process.
---------
Co-authored-by: Vladimir Reznichenko <kalessil@gmail.com>
diff --git a/packages/php/blueprint/changelog/wooplug-3933-fix-blueprint-type-warnings-and-improve-error-handling b/packages/php/blueprint/changelog/wooplug-3933-fix-blueprint-type-warnings-and-improve-error-handling
new file mode 100644
index 0000000000..da57cd3652
--- /dev/null
+++ b/packages/php/blueprint/changelog/wooplug-3933-fix-blueprint-type-warnings-and-improve-error-handling
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix blueprint php warnings and improve error handling
diff --git a/packages/php/blueprint/src/Cli/ExportCli.php b/packages/php/blueprint/src/Cli/ExportCli.php
index cf20067df6..2f25a503ec 100644
--- a/packages/php/blueprint/src/Cli/ExportCli.php
+++ b/packages/php/blueprint/src/Cli/ExportCli.php
@@ -3,6 +3,7 @@
namespace Automattic\WooCommerce\Blueprint\Cli;
use Automattic\WooCommerce\Blueprint\ExportSchema;
+use Automattic\WooCommerce\Blueprint\UseWPFunctions;
/**
* Class ExportCli
@@ -12,6 +13,8 @@ use Automattic\WooCommerce\Blueprint\ExportSchema;
* @package Automattic\WooCommerce\Blueprint\Cli
*/
class ExportCli {
+ use UseWPFunctions;
+
/**
* The path where the exported schema will be saved.
*
@@ -40,11 +43,10 @@ class ExportCli {
$exporter = new ExportSchema();
- $schema = $exporter->export( $args['steps'] );
+ $schema = $exporter->export( $args['steps'] );
+ $is_saved = $this->wp_filesystem_put_contents( $this->save_to, wp_json_encode( $schema, JSON_PRETTY_PRINT ) );
- // phpcs:ignore
- $save = file_put_contents( $this->save_to, json_encode( $schema, JSON_PRETTY_PRINT ) );
- if ( false === $save ) {
+ if ( false === $is_saved ) {
\WP_CLI::error( "Failed to save to {$this->save_to}" );
} else {
\WP_CLI::success( "Exported JSON to {$this->save_to}" );
diff --git a/packages/php/blueprint/src/Cli/ImportCli.php b/packages/php/blueprint/src/Cli/ImportCli.php
index b2e6af952f..2dc519c25e 100644
--- a/packages/php/blueprint/src/Cli/ImportCli.php
+++ b/packages/php/blueprint/src/Cli/ImportCli.php
@@ -33,8 +33,14 @@ class ImportCli {
* @return void
*/
public function run( $optional_args ) {
- $blueprint = ImportSchema::create_from_file( $this->schema_path );
- $results = $blueprint->import();
+ try {
+ $blueprint = ImportSchema::create_from_file( $this->schema_path );
+ } catch ( \Exception $e ) {
+ \WP_CLI::error( $e->getMessage() );
+ return;
+ }
+
+ $results = $blueprint->import();
$result_formatter = new CliResultFormatter( $results );
$is_success = $result_formatter->is_success();
diff --git a/packages/php/blueprint/src/Importers/ImportActivatePlugin.php b/packages/php/blueprint/src/Importers/ImportActivatePlugin.php
index 75c4d5de58..e475b5cb31 100644
--- a/packages/php/blueprint/src/Importers/ImportActivatePlugin.php
+++ b/packages/php/blueprint/src/Importers/ImportActivatePlugin.php
@@ -23,8 +23,8 @@ class ImportActivatePlugin implements StepProcessor {
public function process( $schema ): StepProcessorResult {
$result = StepProcessorResult::success( ActivatePlugin::get_step_name() );
- // phpcs:ignore
- $plugin_path = $schema->pluginPath;
+ // Not snake case because it's a property of the schema.
+ $plugin_path = $schema->pluginPath; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
$activate = $this->wp_activate_plugin( $plugin_path );
diff --git a/packages/php/blueprint/src/Importers/ImportActivateTheme.php b/packages/php/blueprint/src/Importers/ImportActivateTheme.php
index 8475782d0d..286c964a39 100644
--- a/packages/php/blueprint/src/Importers/ImportActivateTheme.php
+++ b/packages/php/blueprint/src/Importers/ImportActivateTheme.php
@@ -30,8 +30,13 @@ class ImportActivateTheme implements StepProcessor {
// phpcs:ignore
$name = $schema->themeName;
- $switch = $this->wp_switch_theme( $name );
- $switch && $result->add_debug( "Switched theme to '{$name}'." );
+ $this->wp_switch_theme( $name );
+
+ $current_theme = $this->wp_get_theme()->get_stylesheet();
+
+ if ( $current_theme === $name ) {
+ $result->add_debug( "Switched theme to '$name'." );
+ }
return $result;
}
diff --git a/packages/php/blueprint/src/Importers/ImportDeactivatePlugin.php b/packages/php/blueprint/src/Importers/ImportDeactivatePlugin.php
index e66e201bda..c3e589693b 100644
--- a/packages/php/blueprint/src/Importers/ImportDeactivatePlugin.php
+++ b/packages/php/blueprint/src/Importers/ImportDeactivatePlugin.php
@@ -25,8 +25,13 @@ class ImportDeactivatePlugin implements StepProcessor {
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
$name = $schema->pluginName;
- $this->deactivate_plugin_by_slug( $name );
- $result->add_info( "Deactivated {$name}." );
+ $deactivated = $this->deactivate_plugin_by_slug( $name );
+
+ if ( $this->is_wp_error( $deactivated ) ) {
+ $result->add_error( "Unable to deactivate {$name}." );
+ } else {
+ $result->add_info( "Deactivated {$name}." );
+ }
return $result;
}
diff --git a/packages/php/blueprint/src/Importers/ImportInstallPlugin.php b/packages/php/blueprint/src/Importers/ImportInstallPlugin.php
index d32802128e..4c969544d6 100644
--- a/packages/php/blueprint/src/Importers/ImportInstallPlugin.php
+++ b/packages/php/blueprint/src/Importers/ImportInstallPlugin.php
@@ -60,34 +60,46 @@ class ImportInstallPlugin implements StepProcessor {
return $result;
}
+ // If the plugin is already installed, skip the installation.
if ( isset( $installed_plugins[ $plugin->slug ] ) ) {
$result->add_info( "Skipped installing {$plugin->slug}. It is already installed." );
return $result;
}
+
+ // If the resource type is not supported, return an error.
if ( $this->storage->is_supported_resource( $plugin->resource ) === false ) {
$result->add_error( "Invalid resource type for {$plugin->slug}." );
return $result;
}
+ // Download the plugin.
$downloaded_path = $this->storage->download( $plugin->slug, $plugin->resource );
if ( ! $downloaded_path ) {
$result->add_error( "Unable to download {$plugin->slug} with {$plugin->resource} resource type." );
return $result;
}
+ // Install the plugin.
$install = $this->install( $downloaded_path );
- $install && $result->add_info( "Installed {$plugin->slug}." );
- if ( isset( $schema->options, $schema->options->activate ) && true === $schema->options->activate ) {
+ if ( is_wp_error( $install ) ) {
+ $result->add_error( "Failed to install {$plugin->slug}." );
+ return $result;
+ }
+
+ $result->add_info( "Installed {$plugin->slug}." );
+
+ // If the plugin should be activated, activate it.
+ $should_activate = isset( $schema->options, $schema->options->activate ) && true === $schema->options->activate;
+ if ( $should_activate ) {
$activate = $this->activate( $plugin->slug );
if ( $activate instanceof \WP_Error ) {
$result->add_error( "Failed to activate {$plugin->slug}." );
+ return $result;
}
- if ( null === $activate ) {
- $result->add_info( "Activated {$plugin->slug}." );
- }
+ $result->add_info( "Activated {$plugin->slug}." );
}
return $result;
@@ -97,7 +109,7 @@ class ImportInstallPlugin implements StepProcessor {
* Installs a plugin from the given local path.
*
* @param string $local_plugin_path Path to the local plugin file.
- * @return bool True on success, false on failure.
+ * @return bool|WP_Error True on success, WP_Error on failure.
*/
protected function install( $local_plugin_path ) {
if ( ! class_exists( 'Plugin_Upgrader' ) ) {
diff --git a/packages/php/blueprint/src/Importers/ImportInstallTheme.php b/packages/php/blueprint/src/Importers/ImportInstallTheme.php
index 5e88593307..4ad2e1836f 100644
--- a/packages/php/blueprint/src/Importers/ImportInstallTheme.php
+++ b/packages/php/blueprint/src/Importers/ImportInstallTheme.php
@@ -120,14 +120,14 @@ class ImportInstallTheme implements StepProcessor {
/**
- * Install the theme from the local plugin path.
+ * Install the theme from the local path.
*
- * @param string $local_plugin_path The local path of the plugin to be installed.
+ * @param string $local_path The local path of the theme to be installed.
*
* @return bool True if the installation was successful, false otherwise.
*/
- protected function install( $local_plugin_path ) {
- $unzip_result = $this->wp_unzip_file( $local_plugin_path, $this->wp_get_theme_root() );
+ protected function install( $local_path ) {
+ $unzip_result = $this->wp_unzip_file( $local_path, $this->wp_get_theme_root() );
if ( $this->is_wp_error( $unzip_result ) ) {
return false;
diff --git a/packages/php/blueprint/src/ResourceStorages.php b/packages/php/blueprint/src/ResourceStorages.php
index 98876c3212..7daa294ec7 100644
--- a/packages/php/blueprint/src/ResourceStorages.php
+++ b/packages/php/blueprint/src/ResourceStorages.php
@@ -33,32 +33,30 @@ class ResourceStorages {
/**
* Check if the resource is supported.
*
- * @param string $resource The resource to check.
+ * @param string $resource_type The resource type to check.
*
* @return bool
*/
- // phpcs:ignore
- public function is_supported_resource( $resource ) {
- return isset( $this->storages[ $resource ] );
+ public function is_supported_resource( $resource_type ) {
+ return isset( $this->storages[ $resource_type ] );
}
/**
* Download the resource.
*
* @param string $slug The slug of the resource to download.
- * @param string $resource The resource to download.
+ * @param string $resource_type The resource type to download.
*
* @return false|string
*/
- // phpcs:ignore
- public function download( $slug, $resource ) {
- if ( ! isset( $this->storages[ $resource ] ) ) {
+ public function download( $slug, $resource_type ) {
+ if ( ! isset( $this->storages[ $resource_type ] ) ) {
return false;
}
- $storages = $this->storages[ $resource ];
+ $storages = $this->storages[ $resource_type ];
foreach ( $storages as $storage ) {
- // phpcs:ignore
- if ( $found = $storage->download( $slug ) ) {
+ $found = $storage->download( $slug );
+ if ( $found ) {
return $found;
}
}
diff --git a/packages/php/blueprint/src/ResourceStorages/OrgPluginResourceStorage.php b/packages/php/blueprint/src/ResourceStorages/OrgPluginResourceStorage.php
index c36f28c8cf..7beaa09e5f 100644
--- a/packages/php/blueprint/src/ResourceStorages/OrgPluginResourceStorage.php
+++ b/packages/php/blueprint/src/ResourceStorages/OrgPluginResourceStorage.php
@@ -19,14 +19,20 @@ class OrgPluginResourceStorage implements ResourceStorage {
*
* @param string $slug The slug of the plugin to be downloaded.
*
- * @return string|null The path to the downloaded plugin file, or null on failure.
+ * @return string|false The path to the downloaded plugin file, or false on failure.
*/
public function download( $slug ): ?string {
$download_link = $this->get_download_link( $slug );
+
if ( ! $download_link ) {
return false;
}
- return $this->download_url( $download_link );
+ $result = $this->download_url( $download_link );
+
+ if ( is_wp_error( $result ) ) {
+ return false;
+ }
+ return $result;
}
/**
@@ -34,7 +40,7 @@ class OrgPluginResourceStorage implements ResourceStorage {
*
* @param string $url The URL to download the file from.
*
- * @return string|null The path to the downloaded file, or null on failure.
+ * @return string|WP_Error The path to the downloaded file, or WP_Error on failure.
*/
protected function download_url( $url ) {
return $this->wp_download_url( $url );
@@ -58,6 +64,10 @@ class OrgPluginResourceStorage implements ResourceStorage {
)
);
+ if ( is_wp_error( $info ) ) {
+ return null;
+ }
+
if ( is_object( $info ) && isset( $info->download_link ) ) {
return $info->download_link;
}
diff --git a/packages/php/blueprint/src/ResourceStorages/OrgThemeResourceStorage.php b/packages/php/blueprint/src/ResourceStorages/OrgThemeResourceStorage.php
index 6c116e9488..0133c6a2eb 100644
--- a/packages/php/blueprint/src/ResourceStorages/OrgThemeResourceStorage.php
+++ b/packages/php/blueprint/src/ResourceStorages/OrgThemeResourceStorage.php
@@ -24,6 +24,10 @@ class OrgThemeResourceStorage extends OrgPluginResourceStorage {
)
);
+ if ( is_wp_error( $info ) ) {
+ return null;
+ }
+
if ( isset( $info->download_link ) ) {
return $info->download_link;
}
diff --git a/packages/php/blueprint/src/Schemas/JsonSchema.php b/packages/php/blueprint/src/Schemas/JsonSchema.php
index c38b35c979..84807389e0 100644
--- a/packages/php/blueprint/src/Schemas/JsonSchema.php
+++ b/packages/php/blueprint/src/Schemas/JsonSchema.php
@@ -2,10 +2,14 @@
namespace Automattic\WooCommerce\Blueprint\Schemas;
+use Automattic\WooCommerce\Blueprint\UseWPFunctions;
+
/**
* Class JsonSchema
*/
class JsonSchema {
+ use UseWPFunctions;
+
/**
* The schema.
*
@@ -17,11 +21,24 @@ class JsonSchema {
* JsonSchema constructor.
*
* @param string $json_path The path to the JSON file.
+ *
+ * @throws \RuntimeException If the JSON file cannot be read.
* @throws \InvalidArgumentException If the JSON is invalid or missing 'steps' field.
*/
public function __construct( $json_path ) {
- // phpcs:ignore
- $schema = json_decode( file_get_contents( $json_path ) );
+ $real_path = realpath( $json_path );
+
+ if ( false === $real_path ) {
+ throw new \InvalidArgumentException( 'Invalid schema path' );
+ }
+
+ $contents = $this->wp_filesystem_get_contents( $real_path );
+
+ if ( false === $contents ) {
+ throw new \RuntimeException( "Failed to read the JSON file at {$real_path}." );
+ }
+
+ $schema = json_decode( $contents );
$this->schema = $schema;
if ( ! $this->validate() ) {
@@ -69,7 +86,7 @@ class JsonSchema {
return false;
}
- if ( ! isset( $this->schema->steps ) ) {
+ if ( ! isset( $this->schema->steps ) || ! is_array( $this->schema->steps ) ) {
return false;
}
diff --git a/packages/php/blueprint/src/UsePluginHelpers.php b/packages/php/blueprint/src/UsePluginHelpers.php
index a5f92d3bdc..9c96c02f38 100644
--- a/packages/php/blueprint/src/UsePluginHelpers.php
+++ b/packages/php/blueprint/src/UsePluginHelpers.php
@@ -13,7 +13,7 @@ trait UsePluginHelpers {
*
* @param string $slug The slug of the plugin to activate.
*
- * @return bool True if the plugin was activated, false otherwise.
+ * @return false|null|WP_Error Null on success, WP_Error on invalid file, false if not found.
*/
public function activate_plugin_by_slug( $slug ) {
// Get all installed plugins.
@@ -59,7 +59,7 @@ trait UsePluginHelpers {
*
* @param string $slug The slug of the plugin to delete.
*
- * @return bool True if the plugin was deleted, false otherwise.
+ * @return bool|WP_Error True if the plugin was deleted, false otherwise.
*/
public function delete_plugin_by_slug( $slug ) {
// Get all installed plugins.
diff --git a/packages/php/blueprint/src/UseWPFunctions.php b/packages/php/blueprint/src/UseWPFunctions.php
index a80debf9fb..27e38a1039 100644
--- a/packages/php/blueprint/src/UseWPFunctions.php
+++ b/packages/php/blueprint/src/UseWPFunctions.php
@@ -2,6 +2,9 @@
namespace Automattic\WooCommerce\Blueprint;
+use WP_Error;
+use WP_Theme;
+
/**
* Trait UseWPFunctions
*/
@@ -146,7 +149,7 @@ trait UseWPFunctions {
* @param string $redirect Optional. URL to redirect to after activation.
* @param bool $network_wide Optional. Whether to enable the plugin for all sites in the network.
* @param bool $silent Optional. Whether to prevent calling activation hooks.
- * @return \WP_Error|null WP_Error on failure, null on success.
+ * @return WP_Error|null WP_Error on failure, null on success.
*/
public function wp_activate_plugin( $plugin, $redirect = '', $network_wide = false, $silent = false ) {
if ( ! function_exists( 'activate_plugin' ) ) {
@@ -160,7 +163,7 @@ trait UseWPFunctions {
* Deletes plugins.
*
* @param array $plugins List of plugins to delete.
- * @return array|WP_Error Array of results or WP_Error on failure.
+ * @return array|WP_Error|null Array of results or WP_Error on failure, null if filesystem credentials are required to proceed.
*/
public function wp_delete_plugins( $plugins ) {
if ( ! function_exists( 'delete_plugins' ) ) {
@@ -202,7 +205,7 @@ trait UseWPFunctions {
if ( ! function_exists( 'switch_theme' ) ) {
require_once ABSPATH . 'wp-admin/includes/theme.php';
}
- return switch_theme( $name );
+ switch_theme( $name );
}
/**
@@ -216,8 +219,9 @@ trait UseWPFunctions {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
- WP_Filesystem();
- $this->filesystem_initialized = true;
+ $initialized = WP_Filesystem();
+ $this->filesystem_initialized = $initialized;
+ return $initialized;
}
return true;
@@ -282,12 +286,29 @@ trait UseWPFunctions {
* @param string $file_path The path to the file to write.
* @param mixed $content The data to write to the file.
*
- * @return mixed
+ * @return bool True on success, false on failure.
*/
public function wp_filesystem_put_contents( $file_path, $content ) {
global $wp_filesystem;
- $this->wp_init_filesystem();
+ if ( ! $this->wp_init_filesystem() ) {
+ return false;
+ }
return $wp_filesystem->put_contents( $file_path, $content );
}
+
+ /**
+ * Alias for WP_Filesystem::get_contents().
+ *
+ * @param string $file_path The path to the file to read.
+ * @return string|false The contents of the file, or false on failure.
+ */
+ public function wp_filesystem_get_contents( $file_path ) {
+ global $wp_filesystem;
+ if ( ! $this->wp_init_filesystem() ) {
+ return false;
+ }
+
+ return $wp_filesystem->get_contents( $file_path );
+ }
}
diff --git a/packages/php/blueprint/tests/Unit/Importers/ImportActivateThemeTest.php b/packages/php/blueprint/tests/Unit/Importers/ImportActivateThemeTest.php
index 839b0f0060..ec8ed4f2b2 100644
--- a/packages/php/blueprint/tests/Unit/Importers/ImportActivateThemeTest.php
+++ b/packages/php/blueprint/tests/Unit/Importers/ImportActivateThemeTest.php
@@ -2,11 +2,13 @@
namespace Automattic\WooCommerce\Blueprint\Tests\Unit\Importers;
+use PHPUnit\Framework\TestCase;
+use Mockery;
+
use Automattic\WooCommerce\Blueprint\Importers\ImportActivateTheme;
use Automattic\WooCommerce\Blueprint\StepProcessorResult;
use Automattic\WooCommerce\Blueprint\Steps\ActivateTheme;
-use Mockery;
-use PHPUnit\Framework\TestCase;
+
/**
* Test the ImportActivateTheme class.
@@ -43,8 +45,12 @@ class ImportActivateThemeTest extends TestCase {
// Mock the wp_switch_theme method.
$import_activate_theme->shouldReceive( 'wp_switch_theme' )
- ->with( $theme_name )
- ->andReturn( true );
+ ->with( $theme_name );
+
+ // Mock the wp_get_theme method to return a mock object with a get_stylesheet method.
+ $theme_mock = Mockery::mock();
+ $theme_mock->shouldReceive( 'get_stylesheet' )->andReturn( $theme_name );
+ $import_activate_theme->shouldReceive( 'wp_get_theme' )->andReturn( $theme_mock );
// Execute the process method.
$result = $import_activate_theme->process( $schema );
@@ -81,8 +87,12 @@ class ImportActivateThemeTest extends TestCase {
// Mock the wp_switch_theme method.
$import_activate_theme->shouldReceive( 'wp_switch_theme' )
- ->with( $theme_name )
- ->andReturn( false );
+ ->with( $theme_name );
+
+ // Mock the wp_get_theme method to return a mock object with a get_stylesheet method.
+ $theme_mock = Mockery::mock();
+ $theme_mock->shouldReceive( 'get_stylesheet' )->andReturn( 'different-theme' );
+ $import_activate_theme->shouldReceive( 'wp_get_theme' )->andReturn( $theme_mock );
// Execute the process method.
$result = $import_activate_theme->process( $schema );
diff --git a/packages/php/blueprint/tests/Unit/Schemas/JsonSchemaTest.php b/packages/php/blueprint/tests/Unit/Schemas/JsonSchemaTest.php
index 7e8ca9a7fc..792b3f4e03 100644
--- a/packages/php/blueprint/tests/Unit/Schemas/JsonSchemaTest.php
+++ b/packages/php/blueprint/tests/Unit/Schemas/JsonSchemaTest.php
@@ -2,6 +2,7 @@
namespace Automattic\WooCommerce\Blueprint\Tests\Unit\Schemas;
+use Mockery;
use Automattic\WooCommerce\Blueprint\Schemas\JsonSchema;
use Automattic\WooCommerce\Blueprint\Tests\TestCase;
@@ -45,4 +46,30 @@ class JsonSchemaTest extends TestCase {
$this->expectException( \InvalidArgumentException::class );
new JsonSchema( $this->get_fixture_path( 'invalid-json.json' ) );
}
+
+ /**
+ * Test that it throws an invalid argument exception with an invalid path.
+ *
+ * @return void
+ */
+ public function test_it_throws_invalid_argument_exception_with_invalid_path() {
+ $this->expectException( \InvalidArgumentException::class );
+ new JsonSchema( $this->get_fixture_path( 'invalid-path.json' ) );
+ }
+
+ /**
+ * Test that it throws a runtime exception when the file is not readable.
+ *
+ * @return void
+ */
+ public function test_it_throws_runtime_exception_when_file_is_not_readable() {
+ $this->expectException( \RuntimeException::class );
+
+ $mock = Mockery::mock( JsonSchema::class )->makePartial();
+ $mock->shouldReceive( 'wp_filesystem_get_contents' )
+ ->once()
+ ->andReturn( false );
+
+ $mock->__construct( $this->get_fixture_path( 'invalid-json.json' ) );
+ }
}