Skip to content

Conversation

@abdullah-kasim
Copy link
Contributor

@abdullah-kasim abdullah-kasim commented Dec 3, 2025

Description

So this PR should help handle post deletions/unpublishing. It still won't handle the case where a deletion has occurred out of band - i.e. a deletion using a SQL query. That'll come later, in the form of a wp command for forcing deletions.

Requires #8 to be merged.

Pre-review checklist

Please make sure the items below have been covered before requesting a review:

  • This change works and has been tested locally or in Codespaces (or has an appropriate fallback).
  • This change has relevant unit tests (if applicable).
  • This change has relevant documentation additions / updates (if applicable).
  • I've created a changelog description that aligns with the provided examples.

Pre-deploy checklist

  • VIP staff: Ensure any alerts added/updated conform to internal standards (see internal documentation).

Steps to Test

Click here to view testing steps

Manual Testing: Post Deletion from Salesforce

Prerequisites

  • VIP dev-env running: vip dev-env start
  • Plugin activated on the dev environment
  • Logger output: /wp/log/debug.log . Clear it out before running any of the tests below. i.e.
    vip dev-env shell -- truncate -s 0 /wp/log/debug.log
  • error_log() output: appears in terminal (not debug.log)
  • Enable debug logging by adding to vip-agentforce.php:
    add_filter( 'enable_wp_debug_mode_checks', '__return_true' );

Test 1: Unpublish Triggers Deletion (publish � draft)

Goal: Verify unpublishing a post triggers deletion from Salesforce.

  1. Add opt-in filter to vip-agentforce.php:
// TEST: Opt-in filter - remove after testing
add_filter( 'vip_agentforce_should_ingest_post', '__return_true' );
  1. Create a published post:
vip dev-env shell -- wp post create --post_title="Test Unpublish" --post_status=publish --porcelain

Note the returned post ID (e.g., 123).

  1. Change post to draft:
vip dev-env shell -- wp post update 123 --post_status=draft
  1. Check the debug log:
vip dev-env shell -- grep -E "(Attempting to delete|deleted from Salesforce successfully)" /wp/log/debug.log

Expected: Log shows Attempting to delete post from Salesforce followed by Post deleted from Salesforce successfully.


Test 2: Trash Triggers Deletion (publish � trash)

Goal: Verify trashing a post triggers deletion from Salesforce.

  1. Keep the filter from Test 1 in place

  2. Create a published post:

vip dev-env shell -- wp post create --post_title="Test Trash" --post_status=publish --porcelain

Note the returned post ID.

  1. Trash the post (without --force):
vip dev-env shell -- wp post delete 124
  1. Check the debug log:
vip dev-env shell -- grep "Post deleted from Salesforce successfully" /wp/log/debug.log

Expected: Log shows Post deleted from Salesforce successfully - trashing triggers deletion.


Test 3: Permanent Delete Triggers Deletion

Goal: Verify permanently deleting a published post triggers deletion.

  1. Keep the filter from Test 1 in place

  2. Create a published post:

vip dev-env shell -- wp post create --post_title="Test Delete" --post_status=publish --porcelain

Note the returned post ID.

  1. Permanently delete (with --force):
vip dev-env shell -- wp post delete 125 --force
  1. Check the debug log:
vip dev-env shell -- grep "Post deleted from Salesforce successfully" /wp/log/debug.log

Expected: Log shows deletion success - permanent deletion of published post triggers Salesforce deletion.


Test 4: No Deletion Without Ingestion Meta

Goal: Verify no deletion occurs when post was never ingested (no tracking meta).

  1. Remove the test filter from vip-agentforce.php

  2. Clear the debug log:

vip dev-env shell -- truncate -s 0 /wp/log/debug.log
  1. Create a published post:
vip dev-env shell -- wp post create --post_title="Test No Filter" --post_status=publish --porcelain

Note the returned post ID.

  1. Change post to draft:
vip dev-env shell -- wp post update 126 --post_status=draft
  1. Check the debug log:
vip dev-env shell -- grep "not previously ingested" /wp/log/debug.log

Expected: Log shows Post was not previously ingested, skipping deletion - post has no ingestion tracking meta, so no deletion is attempted.


Test 5: Draft Delete Doesn't Trigger Deletion

Goal: Verify deleting a draft post doesn't trigger Salesforce deletion.

  1. Add the opt-in filter back to vip-agentforce.php:
add_filter( 'vip_agentforce_should_ingest_post', '__return_true' );
  1. Clear the debug log:
vip dev-env shell -- truncate -s 0 /wp/log/debug.log
  1. Create a draft post:
vip dev-env shell -- wp post create --post_title="Test Draft Delete" --post_status=draft --porcelain

Note the returned post ID.

  1. Permanently delete it:
vip dev-env shell -- wp post delete 127 --force
  1. Check the debug log:
vip dev-env shell -- grep "not published" /wp/log/debug.log

Expected: Log shows Deleted post was not published, skipping Salesforce deletion - draft posts were never in Salesforce, so no deletion needed.


Test 6: Deletion Failure Hook Fires on API Error

Goal: Verify vip_agentforce_post_deletion_failed action fires when deletion fails.

  1. Comment out Ingestion::init() at the bottom of modules/ingestion/class-ingestion.php (line 461):
// Ingestion::init();  // TEST: Commented out for failure testing
  1. Add test code to vip-agentforce.php (after the module requires):
// TEST: Opt-in filter - remove after testing
add_filter( 'vip_agentforce_should_ingest_post', '__return_true' );

// TEST: Extend Ingestion class to simulate API failure - remove after testing
class Test_Failing_Ingestion extends \Automattic\VIP\Salesforce\Agentforce\Ingestion\Ingestion {
    public static function init(): void {
        // Override to use static::class for proper late static binding
        add_action( 'save_post', [ static::class, 'ingest_post' ], 10, 2 );
        add_action( 'transition_post_status', [ static::class, 'handle_post_unpublished' ], 10, 3 );
        add_action( 'before_delete_post', [ static::class, 'handle_post_deleted' ], 10, 2 );
    }

    public static function delete_from_api( \WP_Post $post ): array {
        return [
            'success'       => false,
            'error_code'    => 'simulated_failure',
            'error_message' => 'Simulated delete API failure for testing',
        ];
    }
}
Test_Failing_Ingestion::init();

// TEST: Log when deletion fails - remove after testing
add_action( 'vip_agentforce_post_deletion_failed', function( $failure ) {
    error_log( 'DELETION FAILED HOOK FIRED: ' . wp_json_encode( $failure->to_array() ) );
}, 10, 1 );
  1. Clear the debug log:
vip dev-env shell -- truncate -s 0 /wp/log/debug.log
  1. Create a draft post, then publish it (this sets the ingestion tracking meta):
vip dev-env shell -- wp post create --post_title="Test Deletion Failure" --post_status=draft --porcelain

Note the returned post ID, then publish it:

vip dev-env shell -- wp post update <POST_ID> --post_status=publish
  1. Change post to draft (triggers deletion attempt via the extended class):
vip dev-env shell -- wp post update <POST_ID> --post_status=draft
  1. Check terminal output for the failure hook (error_log outputs to terminal, not debug.log):

Expected: Terminal shows DELETION FAILED HOOK FIRED with JSON containing failure_code, post_id, record_id, and error_message.


Test 7: Deletion Failure Contains Correct Data

Goal: Verify the Deletion_Failure object contains expected properties.

  1. Keep the test code from Test 6 in place

  2. Clear the debug log:

vip dev-env shell -- truncate -s 0 /wp/log/debug.log
  1. Create a draft post, publish it (to set meta), then unpublish:
vip dev-env shell -- wp post create --post_title="Test Failure Data" --post_status=draft --porcelain

Note the post ID, then:

vip dev-env shell -- wp post update <POST_ID> --post_status=publish
vip dev-env shell -- wp post update <POST_ID> --post_status=draft
  1. Check terminal output for failure data.

Expected: The JSON output should contain:

  • failure_code: "delete_api_error"
  • post_id: The post ID you created
  • record_id: Format 101_1_<POST_ID> (site_blog_post)
  • error_code: "vip_agentforce_delete_api_error"
  • error_message: "Simulated delete API failure for testing"

Cleanup

  1. Uncomment Ingestion::init() in modules/ingestion/class-ingestion.php (line 461)

  2. Remove the test code from vip-agentforce.php

  3. Delete test posts (enter shell interactively):

vip dev-env shell
wp post delete $(wp post list --post_status=any --format=ids --posts_per_page=100) --force
exit
  1. Clear debug log:
vip dev-env shell -- truncate -s 0 /wp/log/debug.log

Copilot AI review requested due to automatic review settings December 3, 2025 07:51
@abdullah-kasim abdullah-kasim changed the title feat: Handle cases feat: Remove data from Salesforce when posts are deleted/unpublished Dec 3, 2025
Copilot finished reviewing on behalf of abdullah-kasim December 3, 2025 07:55
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements post deletion handling for the Salesforce Agentforce integration, enabling the system to remove posts from Salesforce when they are unpublished or permanently deleted in WordPress. The implementation tracks ingested posts via metadata and provides comprehensive failure handling through a new Deletion_Failure class.

Key Changes:

  • Added post deletion tracking via meta key to identify previously ingested posts
  • Implemented deletion hooks for unpublishing (transition_post_status) and permanent deletion (before_delete_post)
  • Created Deletion_Failure class for structured error reporting, mirroring the existing Ingestion_Failure pattern

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
vip-agentforce.php Added require statement for the new Deletion_Failure class
modules/ingestion/class-ingestion.php Added meta tracking constant, deletion hooks, and helper methods for handling post unpublishing and deletion from Salesforce
modules/ingestion/class-deletion-failure.php New data class to encapsulate deletion failure information with structured error reporting
tests/phpunit/test-ingestion-deletion.php Comprehensive test suite covering deletion scenarios, meta tracking, hook registration, and failure handling
tests/phpunit/doubles/class-ingestion-with-failing-delete-api.php Test double that simulates API deletion failures for testing error handling

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants