diff --git a/scripts/setup-test-site.sh b/scripts/setup-test-site.sh index 7db40e48f..e019ce0f7 100755 --- a/scripts/setup-test-site.sh +++ b/scripts/setup-test-site.sh @@ -99,6 +99,7 @@ create_test_credentials () { local INTEGRATION_TEST_CUSTOM_TEMPLATE_ID SITE_URL="http://localhost" ADMIN_USERNAME="test@example.com" + ADMIN_USER_ID="$(wp user get "$ADMIN_USERNAME" --field=ID)" ADMIN_PASSWORD="$(wp user application-password create test@example.com test --porcelain)" ADMIN_PASSWORD_UUID="$(wp user application-password list test@example.com --fields=uuid --format=csv | sed -n '2 p')" SUBSCRIBER_USERNAME="themedemos" @@ -130,8 +131,10 @@ create_test_credentials () { REVISIONED_POST_ID="$(wp post create --post_type=post --post_title=Revisioned_POST_FOR_INTEGRATION_TESTS --porcelain)" for i in {1..10}; do - curl --user "$ADMIN_USERNAME":"$ADMIN_PASSWORD" -H "Content-Type: application/json" -d "{\"content\":\"content_revision_$i\"}" "http://localhost/wp-json/wp/v2/posts/$REVISIONED_POST_ID" + curl --silent --user "$ADMIN_USERNAME":"$ADMIN_PASSWORD" -H "Content-Type: application/json" -d "{\"content\":\"content_revision_$i\", \"author\": $ADMIN_USER_ID}" "http://localhost/wp-json/wp/v2/posts/$REVISIONED_POST_ID" done + # Generating revisions don't return an id, but since we just created the `REVISIONED_POST_ID`, we can use it to calculate the revision id + REVISION_ID_FOR_REVISIONED_POST_ID=$((REVISIONED_POST_ID + 1)) rm -rf /app/test_credentials.json jo -p \ @@ -154,6 +157,7 @@ create_test_credentials () { wordpress_core_version="\"$WORDPRESS_VERSION\"" \ integration_test_custom_template_id="$INTEGRATION_TEST_CUSTOM_TEMPLATE_ID" \ revisioned_post_id="$REVISIONED_POST_ID" \ + revision_id_for_revisioned_post_id="$REVISION_ID_FOR_REVISIONED_POST_ID" \ > /app/test_credentials.json } create_test_credentials diff --git a/wordpress.Dockerfile b/wordpress.Dockerfile index b622853ce..3bd7b6190 100644 --- a/wordpress.Dockerfile +++ b/wordpress.Dockerfile @@ -12,11 +12,11 @@ RUN wget -O - https://apt.corretto.aws/corretto.key | gpg --dearmor -o /usr/shar echo "deb [signed-by=/usr/share/keyrings/corretto-keyring.gpg] https://apt.corretto.aws stable main" | tee /etc/apt/sources.list.d/corretto.list RUN apt-get update \ - && apt-get install -y java-21-amazon-corretto-jdk android-sdk wget default-mysql-client less libssl-dev jo \ + && apt-get install -y java-21-amazon-corretto-jdk android-sdk wget default-mysql-client less libssl-dev jo jq \ && apt-get -y autoclean # Install wp-cli -RUN curl -L https://github.com/wp-cli/wp-cli/releases/download/v2.6.0/wp-cli-2.6.0.phar --output /usr/bin/wp +RUN curl -L https://github.com/wp-cli/wp-cli/releases/download/v2.12.0/wp-cli-2.12.0.phar --output /usr/bin/wp RUN chmod +x /usr/bin/wp # Create wpcli working directory diff --git a/wp_api/src/request/endpoint/post_revisions_endpoint.rs b/wp_api/src/request/endpoint/post_revisions_endpoint.rs index fe8f8c0c4..315c8e3b3 100644 --- a/wp_api/src/request/endpoint/post_revisions_endpoint.rs +++ b/wp_api/src/request/endpoint/post_revisions_endpoint.rs @@ -2,7 +2,7 @@ use super::{AsNamespace, DerivedRequest, WpNamespace}; use crate::{ SparseField, post_revisions::{ - PostRevisionListParams, SparsePostRevisionFieldWithEditContext, + PostRevisionId, PostRevisionListParams, SparsePostRevisionFieldWithEditContext, SparsePostRevisionFieldWithEmbedContext, SparsePostRevisionFieldWithViewContext, }, posts::PostId, @@ -13,6 +13,8 @@ use wp_derive_request_builder::WpDerivedRequest; enum PostRevisionsRequest { #[contextual_paged(url = "/posts//revisions", params = &PostRevisionListParams, output = Vec, filter_by = crate::post_revisions::SparsePostRevisionField)] List, + #[contextual_get(url = "/posts//revisions/", output = crate::post_revisions::SparsePostRevision, filter_by = crate::post_revisions::SparsePostRevisionField)] + Retrieve, } impl DerivedRequest for PostRevisionsRequest { @@ -126,6 +128,40 @@ mod tests { } } + #[rstest] + fn retrieve_post_revision(endpoint: PostRevisionsRequestEndpoint) { + let post_id = PostId(777); + let revision_id = PostRevisionId(888); + let expected_path = + |context: &str| format!("/posts/{post_id}/revisions/{revision_id}?context={context}"); + validate_wp_v2_endpoint( + endpoint.retrieve_with_edit_context(&post_id, &revision_id), + &expected_path("edit"), + ); + validate_wp_v2_endpoint( + endpoint.retrieve_with_embed_context(&post_id, &revision_id), + &expected_path("embed"), + ); + validate_wp_v2_endpoint( + endpoint.retrieve_with_view_context(&post_id, &revision_id), + &expected_path("view"), + ); + } + + #[rstest] + #[case(&[], "/posts/777/revisions/888?context=edit&_fields=")] + #[case(&[SparsePostRevisionFieldWithEditContext::Date], "/posts/777/revisions/888?context=edit&_fields=date")] + fn filter_retrieve_post_revision_with_edit_context( + endpoint: PostRevisionsRequestEndpoint, + #[case] fields: &[SparsePostRevisionFieldWithEditContext], + #[case] expected_path: &str, + ) { + validate_wp_v2_endpoint( + endpoint.filter_retrieve_with_edit_context(&PostId(777), &PostRevisionId(888), fields), + expected_path, + ); + } + const EXPECTED_QUERY_PAIRS_FOR_ALL_SPARSE_POST_REVISION_FIELDS_WITH_EDIT_CONTEXT: &str = "_fields=id%2Cauthor%2Cdate%2Cdate_gmt%2Cmodified%2Cmodified_gmt%2Cparent%2Cslug%2Cguid%2Ctitle%2Ccontent%2Cexcerpt%2Cmeta"; const ALL_SPARSE_POST_REVISION_FIELDS_WITH_EDIT_CONTEXT: &[SparsePostRevisionFieldWithEditContext; 13] = &[ diff --git a/wp_api_integration_tests/src/lib.rs b/wp_api_integration_tests/src/lib.rs index 485fdfab4..e97859a98 100644 --- a/wp_api_integration_tests/src/lib.rs +++ b/wp_api_integration_tests/src/lib.rs @@ -28,6 +28,7 @@ pub struct TestCredentials { pub wordpress_core_version: &'static str, pub integration_test_custom_template_id: &'static str, pub revisioned_post_id: i64, + pub revision_id_for_revisioned_post_id: i64, } impl TestCredentials { diff --git a/wp_api_integration_tests/tests/test_post_revisions_immut.rs b/wp_api_integration_tests/tests/test_post_revisions_immut.rs index 93b4bac71..cf3091f19 100644 --- a/wp_api_integration_tests/tests/test_post_revisions_immut.rs +++ b/wp_api_integration_tests/tests/test_post_revisions_immut.rs @@ -41,10 +41,44 @@ async fn list_with_view_context(#[case] params: PostRevisionListParams) { .assert_response(); } +#[tokio::test] +#[parallel] +async fn retrieve_with_edit_context() { + api_client() + .post_revisions() + .retrieve_with_edit_context(&revisioned_post_id(), &revision_id_for_revisioned_post_id()) + .await + .assert_response(); +} + +#[tokio::test] +#[parallel] +async fn retrieve_with_embed_context() { + api_client() + .post_revisions() + .retrieve_with_embed_context(&revisioned_post_id(), &revision_id_for_revisioned_post_id()) + .await + .assert_response(); +} + +#[tokio::test] +#[parallel] +async fn retrieve_with_view_context() { + api_client() + .post_revisions() + .retrieve_with_view_context(&revisioned_post_id(), &revision_id_for_revisioned_post_id()) + .await + .assert_response(); +} + fn revisioned_post_id() -> PostId { PostId(TestCredentials::instance().revisioned_post_id) } +fn revision_id_for_revisioned_post_id() -> PostRevisionId { + PostRevisionId(TestCredentials::instance().revision_id_for_revisioned_post_id) +} + #[template] #[rstest] #[case::default(PostRevisionListParams::default())] @@ -139,4 +173,64 @@ mod filter { post.assert_that_instance_fields_nullability_match_provided_fields(fields) }); } + + #[apply(sparse_post_revision_field_with_edit_context_test_cases)] + #[case(&[SparsePostRevisionFieldWithEditContext::Id, SparsePostRevisionFieldWithEditContext::Author])] + #[tokio::test] + #[parallel] + async fn filter_retrieve_with_edit_context( + #[case] fields: &[SparsePostRevisionFieldWithEditContext], + ) { + api_client() + .post_revisions() + .filter_retrieve_with_edit_context( + &revisioned_post_id(), + &revision_id_for_revisioned_post_id(), + fields, + ) + .await + .assert_response() + .data + .assert_that_instance_fields_nullability_match_provided_fields(fields); + } + + #[apply(sparse_post_revision_field_with_embed_context_test_cases)] + #[case(&[SparsePostRevisionFieldWithEmbedContext::Id, SparsePostRevisionFieldWithEmbedContext::Author])] + #[tokio::test] + #[parallel] + async fn filter_retrieve_with_embed_context( + #[case] fields: &[SparsePostRevisionFieldWithEmbedContext], + ) { + api_client() + .post_revisions() + .filter_retrieve_with_embed_context( + &revisioned_post_id(), + &revision_id_for_revisioned_post_id(), + fields, + ) + .await + .assert_response() + .data + .assert_that_instance_fields_nullability_match_provided_fields(fields); + } + + #[apply(sparse_post_revision_field_with_view_context_test_cases)] + #[case(&[SparsePostRevisionFieldWithViewContext::Id, SparsePostRevisionFieldWithViewContext::Author])] + #[tokio::test] + #[parallel] + async fn filter_retrieve_with_view_context( + #[case] fields: &[SparsePostRevisionFieldWithViewContext], + ) { + api_client() + .post_revisions() + .filter_retrieve_with_view_context( + &revisioned_post_id(), + &revision_id_for_revisioned_post_id(), + fields, + ) + .await + .assert_response() + .data + .assert_that_instance_fields_nullability_match_provided_fields(fields); + } }