Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete /tags endpoint #466

Merged
merged 1 commit into from
Jan 16, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -62,4 +62,13 @@ class TagsEndpointTest {
}.assertSuccessAndRetrieveData().data
assertNull(tag.description)
}

@Test
fun deleteTagRequest() = runTest {
val deletedTag = client.request { requestBuilder ->
requestBuilder.tags().delete(tagId = TAG_ID_100)
}.assertSuccessAndRetrieveData().data
assert(deletedTag.deleted)
restoreTestServer()
}
}
11 changes: 11 additions & 0 deletions wp_api/src/request/endpoint/tags_endpoint.rs
Original file line number Diff line number Diff line change
@@ -14,9 +14,20 @@ enum TagsRequest {
List,
#[contextual_get(url = "/tags/<tag_id>", output = crate::tags::SparseTag, filter_by = crate::tags::SparseTagField)]
Retrieve,
#[delete(url = "/tags/<tag_id>", output = crate::tags::TagDeleteResponse)]
Delete,
}

impl DerivedRequest for TagsRequest {
fn additional_query_pairs(&self) -> Vec<(&str, String)> {
match self {
// The server always returns an error when `force=false`, so a separate `Trash` action
// is not implemented.
Self::Delete => vec![("force", true.to_string())],
_ => vec![],
}
}

fn namespace() -> impl AsNamespace {
WpNamespace::WpV2
}
6 changes: 6 additions & 0 deletions wp_api/src/tags.rs
Original file line number Diff line number Diff line change
@@ -192,6 +192,12 @@ impl FromUrlQueryPairs for TagListParams {
}
}

#[derive(Debug, Serialize, Deserialize, uniffi::Record)]
pub struct TagDeleteResponse {
pub deleted: bool,
pub previous: TagWithEditContext,
}

#[derive(Debug, Serialize, Deserialize, uniffi::Record, WpContextual)]
pub struct SparseTag {
#[WpContext(edit, embed, view)]
16 changes: 14 additions & 2 deletions wp_api_integration_tests/src/backend.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use serde::{de::DeserializeOwned, Serialize};
use wp_api::{comments::CommentId, posts::PostId, users::UserId};
use wp_cli::{WpCliComment, WpCliPost, WpCliSiteSettings, WpCliUser, WpCliUserMeta};
use wp_api::{comments::CommentId, posts::PostId, tags::TagId, users::UserId};
use wp_cli::{WpCliComment, WpCliPost, WpCliSiteSettings, WpCliTag, WpCliUser, WpCliUserMeta};

const BACKEND_ADDRESS: &str = "http://127.0.0.1:4000";
const BACKEND_PATH_RESTORE: &str = "/restore";
@@ -9,6 +9,8 @@ const BACKEND_PATH_COMMENTS: &str = "/wp-cli/comments";
const BACKEND_PATH_SITE_SETTINGS: &str = "/wp-cli/site-settings";
const BACKEND_PATH_POST: &str = "/wp-cli/post";
const BACKEND_PATH_POSTS: &str = "/wp-cli/posts";
const BACKEND_PATH_TAG: &str = "/wp-cli/tag";
const BACKEND_PATH_TAGS: &str = "/wp-cli/tags";
const BACKEND_PATH_USER: &str = "/wp-cli/user";
const BACKEND_PATH_USERS: &str = "/wp-cli/users";
const BACKEND_PATH_USER_META: &str = "/wp-cli/user-meta";
@@ -60,6 +62,16 @@ impl Backend {
.await
.expect("Failed to parse fetched posts from wp_cli")
}
pub async fn tag(tag_id: &TagId) -> WpCliTag {
Self::get(format!("{}?tag_id={}", BACKEND_PATH_TAG, tag_id))
.await
.expect("Failed to parse fetched tag from wp_cli")
}
pub async fn tags() -> Vec<WpCliTag> {
Self::get(BACKEND_PATH_TAGS)
.await
.expect("Failed to parse fetched tags from wp_cli")
}
pub async fn user(user_id: &UserId) -> WpCliUser {
Self::get(format!("{}?user_id={}", BACKEND_PATH_USER, user_id))
.await
23 changes: 23 additions & 0 deletions wp_api_integration_tests/tests/test_tags_mut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use serial_test::serial;
use wp_api_integration_tests::backend::{Backend, RestoreServer};
use wp_api_integration_tests::{api_client, TAG_ID_100};

#[tokio::test]
#[serial]
async fn delete_tag() {
// Delete the tag using the API and ensure it's successful
let tag_delete_response = api_client().tags().delete(&TAG_ID_100).await;
assert!(tag_delete_response.is_ok(), "{:#?}", tag_delete_response);
assert!(tag_delete_response.unwrap().data.deleted);

// Assert that the tag was deleted
assert!(
!Backend::tags()
.await
.into_iter()
.any(|u| u.id == TAG_ID_100.0),
"Tag wasn't deleted"
);

RestoreServer::db().await;
}
18 changes: 17 additions & 1 deletion wp_api_integration_tests_backend/src/main.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ use std::io;
use std::path::Path;
use wp_cli::{
WpCliComment, WpCliCommentListArguments, WpCliPost, WpCliPostListArguments, WpCliSiteSettings,
WpCliUser, WpCliUserMeta,
WpCliTag, WpCliUser, WpCliUserMeta,
};

pub(crate) const TEST_SITE_WP_CONTENT_PATH: &str = "/var/www/html/wp-content";
@@ -53,6 +53,20 @@ fn wp_cli_posts(post_status: Option<String>) -> Result<Json<Vec<WpCliPost>>, Err
.map_err(|e| Error::AsString(e.to_string()))
}

#[get("/tag?<tag_id>")]
fn wp_cli_tag(tag_id: i64) -> Result<Json<WpCliTag>, Error> {
WpCliTag::get(tag_id)
.map(Json)
.map_err(|e| Error::AsString(e.to_string()))
}

#[get("/tags")]
fn wp_cli_tags() -> Result<Json<Vec<WpCliTag>>, Error> {
WpCliTag::list()
.map(Json)
.map_err(|e| Error::AsString(e.to_string()))
}

#[get("/user?<user_id>")]
fn wp_cli_user(user_id: i64) -> Result<Json<WpCliUser>, Error> {
WpCliUser::get(user_id)
@@ -100,6 +114,8 @@ fn rocket() -> _ {
.mount("/wp-cli/", routes![wp_cli_site_settings])
.mount("/wp-cli/", routes![wp_cli_post])
.mount("/wp-cli/", routes![wp_cli_posts])
.mount("/wp-cli/", routes![wp_cli_tag])
.mount("/wp-cli/", routes![wp_cli_tags])
.mount("/wp-cli/", routes![wp_cli_user])
.mount("/wp-cli/", routes![wp_cli_users])
.mount("/wp-cli/", routes![wp_cli_user_meta])
2 changes: 2 additions & 0 deletions wp_cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -3,11 +3,13 @@ use std::{collections::HashMap, ffi::OsStr, process::Command};
mod wp_cli_comments;
mod wp_cli_posts;
mod wp_cli_settings;
mod wp_cli_tags;
mod wp_cli_users;

pub use wp_cli_comments::*;
pub use wp_cli_posts::*;
pub use wp_cli_settings::*;
pub use wp_cli_tags::*;
pub use wp_cli_users::*;

const BACKUP_PATH: &str = "/var/www/html/wp-content/dump.sql";
41 changes: 41 additions & 0 deletions wp_cli/src/wp_cli_tags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use wp_serde_helper::deserialize_i64_or_string;

use crate::run_wp_cli_command;

const TAGS_FIELDS_ARG: &str = "--fields=term_id,count,description,name,slug,taxonomy";

#[derive(Debug, Serialize, Deserialize)]
pub struct WpCliTag {
#[serde(rename = "term_id")]
#[serde(deserialize_with = "deserialize_i64_or_string")]
pub id: i64,
#[serde(deserialize_with = "deserialize_i64_or_string")]
pub count: i64,
pub description: String,
pub name: String,
pub slug: String,
pub taxonomy: String,
}

impl WpCliTag {
pub fn get(tag_id: i64) -> Result<Self> {
let output = run_wp_cli_command([
"term",
"get",
"post_tag",
tag_id.to_string().as_str(),
TAGS_FIELDS_ARG,
]);
serde_json::from_slice::<Self>(&output.stdout).with_context(|| {
"Failed to parse `wp term get post_tag {tag_id} {TAGS_FIELDS_ARG} --format=json` into `WpCliTag`"
})
}
pub fn list() -> Result<Vec<Self>> {
let output = run_wp_cli_command(["term", "list", "post_tag", TAGS_FIELDS_ARG]);
serde_json::from_slice::<Vec<Self>>(&output.stdout).with_context(|| {
"Failed to parse `wp term list post_tag --format=json` into Vec<WpCliTag>"
})
}
}