diff --git a/wp_api/src/api_error.rs b/wp_api/src/api_error.rs index 155502995..7acfa259b 100644 --- a/wp_api/src/api_error.rs +++ b/wp_api/src/api_error.rs @@ -41,10 +41,20 @@ pub struct UnrecognizedWPRestError { pub enum WPRestErrorCode { #[serde(rename = "rest_cannot_create_user")] CannotCreateUser, + #[serde(rename = "rest_cannot_delete_active_plugin")] + CannotDeleteActivePlugin, #[serde(rename = "rest_cannot_edit")] CannotEdit, #[serde(rename = "rest_cannot_edit_roles")] CannotEditRoles, + #[serde(rename = "rest_cannot_install_plugin")] + CannotInstallPlugin, + #[serde(rename = "rest_cannot_manage_plugins")] + CannotManagePlugins, + #[serde(rename = "rest_cannot_view_plugin")] + CannotViewPlugin, + #[serde(rename = "rest_cannot_view_plugins")] + CannotViewPlugins, #[serde(rename = "rest_forbidden_context")] ForbiddenContext, #[serde(rename = "rest_forbidden_orderby")] @@ -53,6 +63,8 @@ pub enum WPRestErrorCode { ForbiddenWho, #[serde(rename = "rest_invalid_param")] InvalidParam, + #[serde(rename = "rest_plugin_not_found")] + PluginNotFound, #[serde(rename = "rest_not_logged_in")] Unauthorized, #[serde(rename = "rest_user_cannot_delete")] @@ -69,19 +81,82 @@ pub enum WPRestErrorCode { UserInvalidRole, #[serde(rename = "rest_user_invalid_slug")] UserInvalidSlug, + // --- // Tested, but we believe these errors are imppossible to get unless the requests are manually modified + // --- #[serde(rename = "rest_user_exists")] UserExists, #[serde(rename = "rest_user_invalid_argument")] UserInvalidArgument, #[serde(rename = "rest_trash_not_supported")] TrashNotSupported, + // --- // Untested, because we believe these errors require multisite + // --- + #[serde(rename = "rest_cannot_manage_network_plugins")] + CannotManageNetworkPlugins, + #[serde(rename = "rest_network_only_plugin")] + NetworkOnlyPlugin, #[serde(rename = "rest_user_create")] UserCreate, + // --- // Untested, because we believe these errors are impossible to get + // --- + /// Happens while activating a plugin without the `activate_plugin` permission. + /// However, in a default setup a prior check of `activate_plugins` will fail + /// resulting in `CannotManagePlugins` error instead. + #[serde(rename = "rest_cannot_activate_plugin")] + CannotActivatePlugin, + /// Happens while deactivating a plugin without the `deactivate_plugin` permission. + /// However, in a default setup a prior check of `activate_plugins` will fail + /// resulting in `CannotManagePlugins` error instead. + #[serde(rename = "rest_cannot_deactivate_plugin")] + CannotDeactivatePlugin, #[serde(rename = "rest_user_invalid_username")] UserInvalidUsername, #[serde(rename = "rest_user_invalid_password")] UserInvalidPassword, } + +// All internal errors _should_ be wrapped as a `WPRestErrorCode` by the server. However, there +// is a good chance that some internal errors do make it into the response, so these error types +// are provided. +// +// Currently, we don't parse the response for these error types, but we could consider adding it +// as a fallback. For the moment, clients can manually try parsing an `Unrecognized` error +// into this type. +#[derive(Debug, Deserialize, PartialEq, Eq, uniffi::Error)] +pub enum WPInternalErrorCode { + #[serde(rename = "fs_error")] + FsError, + #[serde(rename = "fs_no_plugins_dir")] + FsNoPluginsDir, + #[serde(rename = "fs_unavailable")] + FsUnavailable, + #[serde(rename = "could_not_remove_plugin")] + CouldNotRemovePlugin, + #[serde(rename = "could_not_resume_plugin")] + CouldNotResumePlugin, + #[serde(rename = "no_plugin_header")] + NoPluginHeader, + #[serde(rename = "plugin_missing_dependencies")] + PluginMissingDependencies, + #[serde(rename = "plugin_not_found")] + PluginNotFound, + #[serde(rename = "plugin_invalid")] + PluginInvalid, + #[serde(rename = "plugin_php_incompatible")] + PluginPhpIncompatible, + #[serde(rename = "plugin_wp_incompatible")] + PluginWpIncompatible, + #[serde(rename = "plugin_wp_php_incompatible")] + PluginWpPhpIncompatible, + #[serde(rename = "plugins_invalid")] + PluginsInvalid, + #[serde(rename = "unable_to_connect_to_filesystem")] + UnableToConnectToFilesystem, + #[serde(rename = "unable_to_determine_installed_plugin")] + UnableToDetermineInstalledPlugin, + #[serde(rename = "unexpected_output")] + UnexpectedOutput, +} diff --git a/wp_api/src/lib.rs b/wp_api/src/lib.rs index 69cbb068d..b95b4da34 100644 --- a/wp_api/src/lib.rs +++ b/wp_api/src/lib.rs @@ -267,7 +267,7 @@ impl WPApiHelper { pub fn update_plugin_request( &self, plugin: &PluginSlug, - params: PluginUpdateParams, + params: &PluginUpdateParams, ) -> WPNetworkRequest { WPNetworkRequest { method: RequestMethod::POST, diff --git a/wp_networking/tests/test_helpers.rs b/wp_networking/tests/test_helpers.rs index b2f9847b8..ea5bd5aed 100644 --- a/wp_networking/tests/test_helpers.rs +++ b/wp_networking/tests/test_helpers.rs @@ -128,12 +128,22 @@ pub fn read_test_credentials_from_file() -> TestCredentials { fn expected_status_code_for_wp_rest_error_code(error_code: &WPRestErrorCode) -> u16 { match error_code { + WPRestErrorCode::CannotActivatePlugin => 403, WPRestErrorCode::CannotCreateUser => 403, + WPRestErrorCode::CannotDeactivatePlugin => 403, + WPRestErrorCode::CannotDeleteActivePlugin => 400, WPRestErrorCode::CannotEdit => 403, WPRestErrorCode::CannotEditRoles => 403, + WPRestErrorCode::CannotInstallPlugin => 403, + WPRestErrorCode::CannotManageNetworkPlugins => 403, + WPRestErrorCode::CannotManagePlugins => 403, + WPRestErrorCode::CannotViewPlugin => 403, + WPRestErrorCode::CannotViewPlugins => 403, WPRestErrorCode::ForbiddenContext => 403, WPRestErrorCode::ForbiddenOrderBy => 403, WPRestErrorCode::ForbiddenWho => 403, + WPRestErrorCode::NetworkOnlyPlugin => 400, + WPRestErrorCode::PluginNotFound => 404, WPRestErrorCode::InvalidParam => 400, WPRestErrorCode::TrashNotSupported => 501, WPRestErrorCode::Unauthorized => 401, diff --git a/wp_networking/tests/test_plugins_err.rs b/wp_networking/tests/test_plugins_err.rs new file mode 100644 index 000000000..6d6a6a31b --- /dev/null +++ b/wp_networking/tests/test_plugins_err.rs @@ -0,0 +1,87 @@ +use wp_api::{PluginCreateParams, PluginStatus, PluginUpdateParams, WPContext, WPRestErrorCode}; + +use crate::test_helpers::{ + api, api_as_subscriber, AssertWpError, WPNetworkRequestExecutor, WPNetworkResponseParser, + HELLO_DOLLY_PLUGIN_SLUG, WP_ORG_PLUGIN_SLUG_CLASSIC_WIDGETS, +}; + +pub mod test_helpers; + +#[tokio::test] +async fn create_plugin_err_cannot_install_plugin() { + api_as_subscriber() + .create_plugin_request(&PluginCreateParams { + slug: WP_ORG_PLUGIN_SLUG_CLASSIC_WIDGETS.into(), + status: PluginStatus::Active, + }) + .execute() + .await + .unwrap() + .parse(wp_api::parse_create_plugin_response) + .assert_wp_error(WPRestErrorCode::CannotInstallPlugin); +} + +#[tokio::test] +async fn delete_plugin_err_cannot_delete_active_plugin() { + api() + .delete_plugin_request(&HELLO_DOLLY_PLUGIN_SLUG.into()) + .execute() + .await + .unwrap() + .parse(wp_api::parse_delete_plugin_response) + .assert_wp_error(WPRestErrorCode::CannotDeleteActivePlugin); +} + +#[tokio::test] +async fn list_plugins_err_cannot_view_plugins() { + api_as_subscriber() + .list_plugins_request(WPContext::Edit, &None) + .execute() + .await + .unwrap() + .parse(wp_api::parse_retrieve_plugin_response_with_edit_context) + .assert_wp_error(WPRestErrorCode::CannotViewPlugins); +} + +#[tokio::test] +async fn retrieve_plugin_err_cannot_view_plugin() { + api_as_subscriber() + .retrieve_plugin_request(WPContext::Edit, &HELLO_DOLLY_PLUGIN_SLUG.into()) + .execute() + .await + .unwrap() + .parse(wp_api::parse_retrieve_plugin_response_with_edit_context) + .assert_wp_error(WPRestErrorCode::CannotViewPlugin); +} + +#[tokio::test] +async fn update_plugin_err_plugin_not_found() { + api() + .update_plugin_request( + &"foo".into(), + &PluginUpdateParams { + status: PluginStatus::Active, + }, + ) + .execute() + .await + .unwrap() + .parse(wp_api::parse_update_plugin_response) + .assert_wp_error(WPRestErrorCode::PluginNotFound); +} + +#[tokio::test] +async fn update_plugin_err_cannot_manage_plugins() { + api_as_subscriber() + .update_plugin_request( + &HELLO_DOLLY_PLUGIN_SLUG.into(), + &PluginUpdateParams { + status: PluginStatus::Active, + }, + ) + .execute() + .await + .unwrap() + .parse(wp_api::parse_update_plugin_response) + .assert_wp_error(WPRestErrorCode::CannotManagePlugins); +} diff --git a/wp_networking/tests/test_plugins_mut.rs b/wp_networking/tests/test_plugins_mut.rs index cc4b571e6..690f2f3a2 100644 --- a/wp_networking/tests/test_plugins_mut.rs +++ b/wp_networking/tests/test_plugins_mut.rs @@ -38,7 +38,7 @@ async fn update_plugin() { let updated_plugin = api() .update_plugin_request( &HELLO_DOLLY_PLUGIN_SLUG.into(), - PluginUpdateParams { status }, + &PluginUpdateParams { status }, ) .execute() .await