Skip to content

Commit

Permalink
Merge pull request #1159 from alleyinteractive/feature/issue-1154/sup…
Browse files Browse the repository at this point in the history
…port-handling-deleted-articles

Issue-1154: Add Support for Handling Deleted Articles
  • Loading branch information
renatonascalves authored Oct 2, 2024
2 parents 74bb65a + 280b298 commit 554125e
Show file tree
Hide file tree
Showing 15 changed files with 303 additions and 64 deletions.
13 changes: 13 additions & 0 deletions admin/apple-actions/class-api-action.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,17 @@ protected function is_api_configuration_valid() {

return true;
}

/**
* Resets the API postmeta for a given post ID.
*
* @param int $post_id The post ID to reset.
*/
protected function delete_post_meta( $post_id ): void {
delete_post_meta( $post_id, 'apple_news_api_id' );
delete_post_meta( $post_id, 'apple_news_api_revision' );
delete_post_meta( $post_id, 'apple_news_api_created_at' );
delete_post_meta( $post_id, 'apple_news_api_modified_at' );
delete_post_meta( $post_id, 'apple_news_api_share_url' );
}
}
7 changes: 2 additions & 5 deletions admin/apple-actions/index/class-delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,11 @@ private function delete() {
* @param int $post_id The post ID from WordPress.
*/
do_action( 'apple_news_before_delete', $remote_id, $this->id );

$this->get_api()->delete_article( $remote_id );

// Delete the API references and mark as deleted.
delete_post_meta( $this->id, 'apple_news_api_id' );
delete_post_meta( $this->id, 'apple_news_api_revision' );
delete_post_meta( $this->id, 'apple_news_api_created_at' );
delete_post_meta( $this->id, 'apple_news_api_modified_at' );
delete_post_meta( $this->id, 'apple_news_api_share_url' );
$this->delete_post_meta( $this->id );
update_post_meta( $this->id, 'apple_news_api_deleted', time() );

// Clear the cache for post status.
Expand Down
23 changes: 15 additions & 8 deletions admin/apple-actions/index/class-get.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,17 @@
class Get extends API_Action {

/**
* Current content ID being retrieved.
* Post ID of the content being retrieved.
*
* @var int
* @access private
*/
private $id;

/**
* Constructor.
*
* @param \Apple_Exporter\Settings $settings Settings in use during this run.
* @param int $id Current content ID being retrieved.
* @access public
* @param int $id Post ID of the content being retrieved.
*/
public function __construct( $settings, $id ) {
parent::__construct( $settings );
Expand All @@ -43,18 +41,28 @@ public function __construct( $settings, $id ) {
/**
* Get the post data from Apple News.
*
* @access public
* @return object
* @return object|null
*/
public function perform() {
// Ensure we have a valid ID.
$apple_id = get_post_meta( $this->id, 'apple_news_api_id', true );

if ( empty( $apple_id ) ) {
return null;
}

// Get the article from the API.
$article = $this->get_api()->get_article( $apple_id );
try {
$article = $this->get_api()->get_article( $apple_id );
} catch ( \Apple_Push_API\Request\Request_Exception $e ) {
$article = $e->getMessage();

// Reset the API postmeta if the article is deleted in Apple News.
if ( is_string( $article ) && str_contains( $article, 'NOT_FOUND (keyPath articleId)' ) ) {
$this->delete_post_meta( $this->id );
}
}

if ( empty( $article->data ) ) {
return null;
}
Expand All @@ -67,7 +75,6 @@ public function perform() {
*
* @param string $key The key to look up in the data.
* @param string $default Optional. The default value to fall back to. Defaults to null.
* @access public
* @return mixed
*/
public function get_data( $key, $default = null ) {
Expand Down
62 changes: 41 additions & 21 deletions includes/REST/apple-news-get-published-state.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,60 @@

namespace Apple_News\REST;

/**
* Get API response.
*
* @param array $data data from query args.
* @return array updated response.
*/
function get_published_state_response( $data ) {
$response = [];

// Ensure Apple News is first initialized.
\Apple_News::has_uninitialized_error();

if ( ! empty( get_current_user_id() ) ) {
$response['publishState'] = \Admin_Apple_News::get_post_status( $data['id'] );
}

return $response;
}
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

/**
* Initialize this REST Endpoint.
*/
add_action(
'rest_api_init',
function () {
// Register route count argument.
register_rest_route(
'apple-news/v1',
'/get-published-state/(?P<id>\d+)',
[
'methods' => 'GET',
'methods' => WP_REST_Server::READABLE,
'callback' => __NAMESPACE__ . '\get_published_state_response',
'permission_callback' => '__return_true',
]
'schema' => [
'description' => __( 'Get the published state of a post.', 'apple-news' ),
'type' => 'object',
'properties' => [
'publishState' => [
'type' => 'string',
'description' => __( 'The published state of the post.', 'apple-news' ),
],
],
],
],
);
}
);

/**
* Get the published state of a post.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
function get_published_state_response( $request ): WP_REST_Response|WP_Error {
$id = $request->get_param( 'id' );

// Ensure Apple News is first initialized.
$retval = \Apple_News::has_uninitialized_error();

if ( is_wp_error( $retval ) ) {
return $retval;
}

$response = [];

if ( ! empty( get_current_user_id() ) ) {
$response['publishState'] = \Admin_Apple_News::get_post_status( $id );
}

return rest_ensure_response( $response );
}
5 changes: 2 additions & 3 deletions includes/apple-push-api/request/class-request.php
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ private function parse_response( $response, $json = true, $type = 'post', $meta
if ( json_last_error() !== JSON_ERROR_NONE ) {
throw new Request_Exception( esc_html( __( 'Unable to decode JSON from the response:', 'apple-news' ) ) );
}

if ( ! empty( $response_decoded->errors ) && is_array( $response_decoded->errors ) ) {
$message = '';
$messages = [];
Expand Down Expand Up @@ -408,7 +409,7 @@ private function request( $verb, $url, $data = [] ) {
}

// Parse the response.
$response = $this->parse_response(
return $this->parse_response(
$response,
true,
strtolower( $verb ),
Expand All @@ -417,8 +418,6 @@ private function request( $verb, $url, $data = [] ) {
! empty( $data['article'] ) ? $data['article'] : '',
'POST' === $verb ? $this->mime_builder->get_debug_content( $args ) : ''
);

return $response;
}

/**
Expand Down
1 change: 1 addition & 0 deletions includes/class-apple-news.php
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ public static function is_initialized(): bool {
self::$is_initialized = $has_api_settings || $has_api_config;
}


return self::$is_initialized;
}

Expand Down
2 changes: 0 additions & 2 deletions tests/admin/apple-actions/index/test-class-delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
* @subpackage Tests
*/

use Apple_Actions\Index\Delete;

/**
* A class to test the functionality of the Apple_Actions\Index\Delete class.
*
Expand Down
99 changes: 99 additions & 0 deletions tests/admin/apple-actions/index/test-class-get.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php
/**
* Publish to Apple News tests: Apple_News_Admin_Action_Index_Get_Test class
*
* @package Apple_News
* @subpackage Tests
*/

/**
* A class to test the functionality of the Apple_Actions\Index\Get class.
*
* @package Apple_News
* @subpackage Tests
*/
class Apple_News_Admin_Action_Index_Get_Test extends Apple_News_Testcase {

/**
* Tests the behavior of the get action without an API ID assigned to the post.
*/
public function test_get_action_without_api_id(): void {
$post_id = self::factory()->post->create();
$action = new Apple_Actions\Index\Get( $this->settings, $post_id );

$this->assertNull( $action->perform() );
}

/**
* Test the behavior of the get action with an API ID assigned to the post.
*/
public function test_get_action(): void {
$api_id = 'def456';
$post_id = self::factory()->post
->with_meta( [ 'apple_news_api_id' => $api_id ] )
->create();

$response = $this->fake_article_response( [ 'id' => $api_id ] );

// Fake the API response for the GET request.
$this->add_http_response(
verb: 'GET',
url: 'https://news-api.apple.com/articles/' . $api_id,
body: wp_json_encode( $response ),
response: [
'code' => 200,
'message' => 'OK',
]
);

$action = new Apple_Actions\Index\Get( $this->settings, $post_id );
$data = $action->perform();

$this->assertNotEmpty( $data );
$this->assertSame( $api_id, $data->data->id );
$this->assertSame( $response['data']['createdAt'], $data->data->createdAt );
$this->assertSame( $response['data']['modifiedAt'], $data->data->modifiedAt );
$this->assertSame( $response['data']['shareUrl'], $data->data->shareUrl );
$this->assertSame( $response['data']['revision'], $data->data->revision );
$this->assertSame( $response['data']['type'], $data->data->type );
}

/**
* Test the behavior of the get action with a deleted Apple News article assigned to the post.
*/
public function test_get_deleted_article(): void {
$api_id = 'def456';
$post_id = self::factory()->post->create();
$action = new Apple_Actions\Index\Get( $this->settings, $post_id );

$this->assertNull( $action->perform() );

add_post_meta( $post_id, 'apple_news_api_id', $api_id );

// Fake the API response for the GET request.
$this->add_http_response(
verb: 'GET',
url: 'https://news-api.apple.com/articles/' . $api_id,
body: wp_json_encode(
[
'errors' => [
[
'code' => 'NOT_FOUND',
'keyPath' => [ 'articleId' ],
'value' => $api_id,
],
],
]
),
response: [
'code' => 404,
'message' => 'Not Found',
]
);

$action = new Apple_Actions\Index\Get( $this->settings, $post_id );

$this->assertNull( $action->perform() );
$this->assertEmpty( get_post_meta( $post_id, 'apple_news_api_id', true ) );
}
}
1 change: 0 additions & 1 deletion tests/admin/apple-actions/index/test-class-push.php
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,6 @@ public function test_update() {
$this->assertEquals( null, get_post_meta( $post->ID, 'apple_news_api_deleted', true ) );

// Try to sync the post again, and verify that it bails out before attempting the sync.
$exception = false;
try {
$this->get_request_for_post( $post->ID );
} catch ( Action_Exception $e ) {
Expand Down
10 changes: 5 additions & 5 deletions tests/admin/test-class-admin-apple-index-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ public function test_reset() {
$index_page->page_router();

// Ensure values were deleted.
$this->assertEquals( false, get_post_meta( $post_id, 'apple_news_api_pending', true ) );
$this->assertEquals( false, get_post_meta( $post_id, 'apple_news_api_async_in_progress', true ) );
$this->assertEquals( false, get_post_meta( $post_id, 'apple_news_api_bundle', true ) );
$this->assertEquals( false, get_post_meta( $post_id, 'apple_news_api_json', true ) );
$this->assertEquals( false, get_post_meta( $post_id, 'apple_news_api_errors', true ) );
$this->assertEmpty( get_post_meta( $post_id, 'apple_news_api_pending', true ) );
$this->assertEmpty( get_post_meta( $post_id, 'apple_news_api_async_in_progress', true ) );
$this->assertEmpty( get_post_meta( $post_id, 'apple_news_api_bundle', true ) );
$this->assertEmpty( get_post_meta( $post_id, 'apple_news_api_json', true ) );
$this->assertEmpty( get_post_meta( $post_id, 'apple_news_api_errors', true ) );
}
}
12 changes: 6 additions & 6 deletions tests/admin/test-class-admin-apple-meta-boxes.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ class Apple_News_Admin_Apple_Meta_Boxes_Test extends Apple_News_Testcase {
*/
public function test_save_no_auto_sync() {
// Set API settings to not auto sync and to enable the meta box.
$this->settings->set( 'api_autosync', 'no' );
$this->settings->set( 'show_metabox', 'yes' );
$this->settings->__set( 'api_autosync', 'no' );
$this->settings->__set( 'show_metabox', 'yes' );

// Create post.
$post_id = $this->factory->post->create();
Expand All @@ -46,7 +46,7 @@ public function test_save_no_auto_sync() {

// Create the meta box class and simulate a save.
$meta_box = new Admin_Apple_Meta_Boxes( $this->settings );
if ( 'yes' === $this->settings->get( 'show_metabox' ) ) {
if ( 'yes' === $this->settings->__get( 'show_metabox' ) ) {
$meta_box->do_publish( $post_id, get_post( $post_id ) );
}

Expand All @@ -66,8 +66,8 @@ public function test_save_no_auto_sync() {
*/
public function test_save_with_auto_sync() {
// Set API settings to not auto sync and to enable the meta box.
$this->settings->set( 'api_autosync', 'yes' );
$this->settings->set( 'show_metabox', 'yes' );
$this->settings->__set( 'api_autosync', 'yes' );
$this->settings->__set( 'show_metabox', 'yes' );

// Create post.
$post_id = $this->factory->post->create();
Expand All @@ -91,7 +91,7 @@ public function test_save_with_auto_sync() {

// Create the meta box class and simulate a save.
$meta_box = new Admin_Apple_Meta_Boxes( $this->settings );
if ( 'yes' === $this->settings->get( 'show_metabox' ) ) {
if ( 'yes' === $this->settings->__get( 'show_metabox' ) ) {
$meta_box->do_publish( $post_id, get_post( $post_id ) );
}

Expand Down
2 changes: 0 additions & 2 deletions tests/admin/test-class-admin-apple-themes.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
* @subpackage Tests
*/

use Apple_Exporter\Exporter;
use Apple_Exporter\Exporter_Content;
use Apple_Exporter\Theme;

/**
Expand Down
Loading

0 comments on commit 554125e

Please sign in to comment.