@@ -287,6 +287,54 @@ public function test_accept_with_non_array_pending_meta() {
287287 \wp_delete_post ( $ post_id );
288288 }
289289
290+ /**
291+ * Test follow returns existing outbox activity when already following.
292+ *
293+ * @covers ::follow
294+ */
295+ public function test_follow_returns_existing_activity_when_already_following () {
296+ \add_filter ( 'activitypub_pre_http_get_remote_object ' , array ( $ this , 'mock_remote_actor ' ), 10 , 2 );
297+
298+ $ user_id = self ::factory ()->user ->create ( array ( 'role ' => 'administrator ' ) );
299+ \get_user_by ( 'id ' , $ user_id )->add_cap ( 'activitypub ' );
300+
301+ // First follow creates the relationship and outbox activity.
302+ $ first_result = follow ( 'https://example.com/actor/1 ' , $ user_id );
303+ $ this ->assertIsInt ( $ first_result , 'First follow should return an outbox activity ID ' );
304+
305+ // Second follow should return the same outbox activity ID.
306+ $ second_result = follow ( 'https://example.com/actor/1 ' , $ user_id );
307+ $ this ->assertIsInt ( $ second_result , 'Second follow should return an outbox activity ID ' );
308+ $ this ->assertEquals ( $ first_result , $ second_result , 'Should return the same outbox activity ID ' );
309+
310+ \remove_filter ( 'activitypub_pre_http_get_remote_object ' , array ( $ this , 'mock_remote_actor ' ) );
311+ }
312+
313+ /**
314+ * Test follow returns error when metadata exists but outbox activity is missing.
315+ *
316+ * @covers ::follow
317+ */
318+ public function test_follow_returns_error_on_inconsistent_state () {
319+ // Create a remote actor post.
320+ $ post_id = self ::factory ()->post ->create (
321+ array (
322+ 'post_title ' => 'Test Remote Actor ' ,
323+ 'post_status ' => 'publish ' ,
324+ 'post_type ' => Remote_Actors::POST_TYPE ,
325+ )
326+ );
327+
328+ // Manually add metadata to simulate following without an outbox activity.
329+ \add_post_meta ( $ post_id , Following::PENDING_META_KEY , '1 ' );
330+
331+ // Attempt to follow should return an error due to inconsistent state.
332+ $ result = Following::follow ( $ post_id , 1 );
333+
334+ $ this ->assertWPError ( $ result , 'Should return WP_Error for inconsistent state ' );
335+ $ this ->assertEquals ( 'activitypub_already_following ' , $ result ->get_error_code () );
336+ }
337+
290338 /**
291339 * Test unfollow removes user from following list.
292340 *
@@ -306,16 +354,16 @@ public function test_unfollow_removes_user() {
306354
307355 // Use global follow() function to add a follow request.
308356 $ remote_actor_url = \get_post ( $ post_id )->guid ;
309- \ Activitypub \ follow ( $ remote_actor_url , $ user_id );
357+ follow ( $ remote_actor_url , $ user_id );
310358 \clean_post_cache ( $ post_id );
311359
312360 // Verify user is in following list (pending or following).
313- $ following = \get_post_meta ( $ post_id , \ Activitypub \ Collection \ Following::FOLLOWING_META_KEY , false );
314- $ pending = \get_post_meta ( $ post_id , \ Activitypub \ Collection \ Following::PENDING_META_KEY , false );
361+ $ following = \get_post_meta ( $ post_id , Following::FOLLOWING_META_KEY , false );
362+ $ pending = \get_post_meta ( $ post_id , Following::PENDING_META_KEY , false );
315363 $ this ->assertTrue ( in_array ( (string ) $ user_id , $ following , true ) || in_array ( (string ) $ user_id , $ pending , true ) );
316364
317365 // Remove following.
318- $ result = \ Activitypub \ Collection \ Following::unfollow ( $ post_id , $ user_id );
366+ $ result = Following::unfollow ( $ post_id , $ user_id );
319367
320368 \clean_post_cache ( $ post_id );
321369
@@ -324,8 +372,8 @@ public function test_unfollow_removes_user() {
324372 $ this ->assertEquals ( $ post_id , $ result ->ID );
325373
326374 // User should no longer be in following list.
327- $ following = \get_post_meta ( $ post_id , \ Activitypub \ Collection \ Following::FOLLOWING_META_KEY , false );
328- $ pending = \get_post_meta ( $ post_id , \ Activitypub \ Collection \ Following::PENDING_META_KEY , false );
375+ $ following = \get_post_meta ( $ post_id , Following::FOLLOWING_META_KEY , false );
376+ $ pending = \get_post_meta ( $ post_id , Following::PENDING_META_KEY , false );
329377
330378 $ this ->assertNotContains ( (string ) $ user_id , $ following );
331379 $ this ->assertNotContains ( (string ) $ user_id , $ pending );
0 commit comments