From 92c6725cc0bece67aa430df45d89d14a738bf950 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Fri, 25 Aug 2023 14:01:29 -0400 Subject: [PATCH 01/27] fix: preventing loss of fact that a guest author might also be a WP_User --- co-authors-plus.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/co-authors-plus.php b/co-authors-plus.php index 4dd8c953..84f84365 100755 --- a/co-authors-plus.php +++ b/co-authors-plus.php @@ -339,6 +339,8 @@ public function get_coauthor_by( $key, $value, $force = false ) { if ( $this->is_guest_authors_enabled() && isset( $this->guest_authors ) ) { $guest_author = $this->guest_authors->get_guest_author_by( 'linked_account', $user->user_login ); if ( is_object( $guest_author ) ) { + $guest_author->is_wp_user = true; // Important not to lose the fact that this is a WP user. + $guest_author->wp_user = $user; $user = $guest_author; } } @@ -1001,8 +1003,8 @@ public function add_coauthors( $post_id, $coauthors, $append = false, $query_typ if ( empty( $post_author_user ) || ! in_array( $post_author_user->user_login, $coauthors ) ) { foreach ( $coauthor_objects as $coauthor_object ) { - if ( 'wpuser' == $coauthor_object->type ) { - $new_author = $coauthor_object; + if ( isset( $coauthor_object->is_wp_user ) && $coauthor_object->is_wp_user ) { + $new_author = $coauthor_object->wp_user; break; } } From b6a0598a656328247a35581a29a623816504fcf7 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Fri, 25 Aug 2023 22:19:18 -0400 Subject: [PATCH 02/27] fix: making the update operation dependent on $append flag. This might be a problematic decision. But the way I justify this change is that if you are appending co-authors, there may already be a WP_User set as the author. So we don't really have to care whether one is passed or not. Because of this, we do not need to forcibly return a `false` flag since that is confusing to the caller, especially because we actually do save the guest authors which are given in the call! Instead, if the $append flag is false, we should expect that at least one user will be a WP_User. In that case, if none is passed in, then there is a mismatch of the intended authors. Because now, the `wp_posts.post_author` column will have an old `wp_users.ID` which remains set and most likely isn't the intent of the caller. --- co-authors-plus.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/co-authors-plus.php b/co-authors-plus.php index 84f84365..9d1ad275 100755 --- a/co-authors-plus.php +++ b/co-authors-plus.php @@ -1008,8 +1008,15 @@ public function add_coauthors( $post_id, $coauthors, $append = false, $query_typ break; } } - // Uh oh, no WP_Users assigned to the post - if ( empty( $new_author ) ) { + + /* + * If setting a fresh group of authors for a post, (i.e. $append === false), + * then perhaps one of those authors should be a WP_USER. However, + * if $append === true, and we are perhaps unable to find a + * WP_USER (perhaps none was given), we don't really + * care whether post_author should be updated. + * */ + if ( false === $append && empty( $new_author ) ) { return false; } From 017dc74fb50fc53ea9155dc177e52a0d37705418 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Fri, 25 Aug 2023 22:20:42 -0400 Subject: [PATCH 03/27] fix: attempting DB update only when $new_author is not empty. Also, returning the actual response from the DB, to make this call even more accurate in terms of what is actually happen at the DB layer. --- co-authors-plus.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/co-authors-plus.php b/co-authors-plus.php index 9d1ad275..973735f9 100755 --- a/co-authors-plus.php +++ b/co-authors-plus.php @@ -1020,8 +1020,15 @@ public function add_coauthors( $post_id, $coauthors, $append = false, $query_typ return false; } - $wpdb->update( $wpdb->posts, array( 'post_author' => $new_author->ID ), array( 'ID' => $post_id ) ); - clean_post_cache( $post_id ); + + if ( ! empty( $new_author ) ) { + $update = $wpdb->update( $wpdb->posts, array( 'post_author' => $new_author->ID ), array( 'ID' => $post_id ) ); + clean_post_cache( $post_id ); + + if ( is_bool( $update ) ) { + return $update; + } + } } return true; From a0635df3a5e52a0cd976c3f16e2afa3808c63478 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Fri, 25 Aug 2023 22:22:43 -0400 Subject: [PATCH 04/27] fix: need to ensure pure WP_User is processed correctly as post_author. A pure WP_User (i.e. a WP_User that IS NOT linked to a Guest Author) needs to be handled specially. --- co-authors-plus.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/co-authors-plus.php b/co-authors-plus.php index 973735f9..1e85a356 100755 --- a/co-authors-plus.php +++ b/co-authors-plus.php @@ -1003,7 +1003,10 @@ public function add_coauthors( $post_id, $coauthors, $append = false, $query_typ if ( empty( $post_author_user ) || ! in_array( $post_author_user->user_login, $coauthors ) ) { foreach ( $coauthor_objects as $coauthor_object ) { - if ( isset( $coauthor_object->is_wp_user ) && $coauthor_object->is_wp_user ) { + if ( $coauthor_object instanceof WP_User ) { + $new_author = $coauthor_object; + break; + } else if ( isset( $coauthor_object->is_wp_user ) && $coauthor_object->is_wp_user ) { $new_author = $coauthor_object->wp_user; break; } From da28669d10499a92ad944811f354aa1eef0bcd04 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Wed, 30 Aug 2023 20:05:05 -0400 Subject: [PATCH 05/27] fix: a necessary refactor of the `get_coauthor_by` function. This refactor is absolutely necessary in order for all the previous fixes to work as expected. Without this fix, what happens is that when you use `get_coauthor_by` by searching with a Guest Author, if that Guest Author has a valid link to a WP_User, it is summarily ignored. Functions like `add_coauthors` expect at least one coauthor to be a valid WP_User so that the `wp_posts.post_author` column can be appropriately updated. The only case where this function is returning an expected value is when you search by the WP_User first. When it arrives at `$guest_author = $this->guest_authors->get_guest_author_by( $key, $value, $force );`, `$guest_author === false`. It is then forced to move to the switch statement to find a user via their WP_User data. With this refactor, `get_coauthor_by` will now check if the `linked_account` attribute is set. If so, it will attempt to find the corresponding user for the Guest Account. It still gives priority to returning a Guest Author. When a Guest Author is not found, it will search for a WP_User. If found, it will also search to see if a linked Guest Author account exists. If it does, it will return that Guest Author object instead, without losing the fact that this account also has a WP_User associated with it. --- co-authors-plus.php | 95 ++++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 35 deletions(-) diff --git a/co-authors-plus.php b/co-authors-plus.php index 1e85a356..d9520742 100755 --- a/co-authors-plus.php +++ b/co-authors-plus.php @@ -304,51 +304,76 @@ public function get_coauthor_by( $key, $value, $force = false ) { if ( $this->is_guest_authors_enabled() && isset( $this->guest_authors ) ) { $guest_author = $this->guest_authors->get_guest_author_by( $key, $value, $force ); if ( is_object( $guest_author ) ) { - return $guest_author; - } - } + if ( isset( $guest_author->linked_account ) ) { + $user = $this->get_user_by( 'login', $guest_author->linked_account ); - switch ( $key ) { - case 'id': - case 'login': - case 'user_login': - case 'email': - case 'user_nicename': - case 'user_email': - if ( 'user_login' == $key ) { - $key = 'login'; - } - if ( 'user_email' == $key ) { - $key = 'email'; - } - if ( 'user_nicename' == $key ) { - $key = 'slug'; - } - $user = get_user_by( $key, $value ); - if ( ! $user && ( 'login' == $key || 'slug' == $key ) ) { - // Re-try lookup without prefixed value if no results found. - $value = preg_replace( '#^cap\-#', '', $value ); - $user = get_user_by( $key, $value ); + if ( ! is_null( $user ) ) { + $guest_author->is_wp_user = true; // Important not to lose the fact that this is a WP user. + $guest_author->wp_user = $user; + } } - if ( ! $user ) { + + return $guest_author; + } else { + // Guest Author was not found, so let's see if we are searching for a WP_User + $user = $this->get_user_by( $key, $value ); + + if ( is_null( $user ) ) { return false; } + + // At this point we have a valid $user. $user->type = 'wpuser'; - // However, if guest authors are enabled and there's a guest author linked to this - // user account, we want to use that instead - if ( $this->is_guest_authors_enabled() && isset( $this->guest_authors ) ) { - $guest_author = $this->guest_authors->get_guest_author_by( 'linked_account', $user->user_login ); - if ( is_object( $guest_author ) ) { - $guest_author->is_wp_user = true; // Important not to lose the fact that this is a WP user. - $guest_author->wp_user = $user; - $user = $guest_author; - } + + $guest_author = $this->guest_authors->get_guest_author_by( 'linked_account', $user->user_login ); + if ( is_object( $guest_author ) ) { + $guest_author->is_wp_user = true; // Important not to lose the fact that this is a WP user. + $guest_author->wp_user = $user; + $user = $guest_author; } + return $user; - break; + } } + return false; + } + + /** + * @param string $key Key to search by, i.e. 'id', 'login', 'user_login', 'email', 'user_email', 'user_nicename' + * @param string $value Value to search for. + * + * @return WP_User|null + */ + protected function get_user_by( $key, $value ) { + $acceptable_keys = [ + 'id' => 'id', + 'login' => 'login', + 'user_login' => 'login', + 'email' => 'email', + 'user_email' => 'email', + 'user_nicename' => 'slug', + ]; + + if ( ! array_key_exists( $key, $acceptable_keys ) ) { + return null; + } + + $key = $acceptable_keys[ $key ]; + + $user = get_user_by( $key, $value ); + + if ( ! $user && ( 'login' == $key || 'slug' == $key ) ) { + // Re-try lookup without prefixed value if no results found. + $value = preg_replace( '#^cap\-#', '', $value ); + $user = get_user_by( $key, $value ); + } + + if ( false === $user ) { + return null; + } + return $user; } /** From b71ea29f48cb91c0270bf6202970d98f7f81e28b Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Wed, 30 Aug 2023 20:48:11 -0400 Subject: [PATCH 06/27] fix: returning a plain WP_User if guest authors is not enabled. I forgot to run tests on my previous commit. This satisfies the test Test_CoAuthors_Plus::test_get_coauthor_by_when_guest_authors_not_enabled which is expecting a WP_User when the plugin is not enabled. --- co-authors-plus.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/co-authors-plus.php b/co-authors-plus.php index d9520742..be0aa917 100755 --- a/co-authors-plus.php +++ b/co-authors-plus.php @@ -334,9 +334,17 @@ public function get_coauthor_by( $key, $value, $force = false ) { return $user; } - } + } else { + $user = $this->get_user_by( $key, $value ); - return false; + if ( is_null( $user ) ) { + return false; + } + + $user->type = 'wpuser'; + + return $user; + } } /** From fbf208792f9598e5f07115e6ac449e93c4975a75 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Fri, 8 Sep 2023 12:46:30 -0400 Subject: [PATCH 07/27] feat: adding additional tests for co-authors-plus.php functionality. --- tests/test-coauthors-plus.php | 1448 +++++++++++++++++++++++++++++++++ 1 file changed, 1448 insertions(+) diff --git a/tests/test-coauthors-plus.php b/tests/test-coauthors-plus.php index d4a7911f..406b72ed 100644 --- a/tests/test-coauthors-plus.php +++ b/tests/test-coauthors-plus.php @@ -3,6 +3,11 @@ class Test_CoAuthors_Plus extends CoAuthorsPlus_TestCase { private $author1; + + private $author2; + + private $author3; + private $editor1; private $post; @@ -16,6 +21,21 @@ public function set_up() { 'user_login' => 'author1', ) ); + + $this->author2 = $this->factory()->user->create_and_get( + array( + 'role' => 'author', + 'user_login' => 'author2', + ) + ); + + $this->author3 = $this->factory()->user->create_and_get( + array( + 'role' => 'author', + 'user_login' => 'author3', + ) + ); + $this->editor1 = $this->factory()->user->create_and_get( array( 'role' => 'editor', @@ -679,6 +699,1434 @@ public function test_update_author_term_when_author_term_not_exist() { $coauthors_plus->coauthor_taxonomy = $taxonomy_backup; } + /** + * This is a basic test to ensure that any authors being assigned to a post + * using the CoAuthors_Plus::add_coauthors() method are appropriately + * associated to the post. Some of the things the add_coauthors() + * method should do are: + * + * 1. Ensure that the post_author is set to the first author in the list + * 2. This is done internally by calling CoAuthors_Plus::get_coauthor_by(), + * which should return a WP_User in this instance (since the author is not linked to a coauthor account) + * 3. Since this coauthor is not linked, create the author's coauthor term, and associate it to the post. + * + * @return void + */ + public function test_assign_post_author_from_author_who_has_not_been_linked() { + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->author2->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query1 = new WP_Query( + array( + 'p' => $post_id + ) + ); + + $this->assertEquals( 1, $query1->found_posts ); + $this->assertEquals( $this->author2->ID, $query1->posts[0]->post_author ); + + $first_added_authors = $this->_cap->add_coauthors( $post_id, array( $this->author3->user_login ) ); + $this->assertTrue( $first_added_authors ); + + $query2 = new WP_Query( + array( + 'p' => $post_id + ) + ); + + $this->assertEquals( 1, $query2->found_posts ); + $this->assertEquals( $this->author3->ID, $query2->posts[0]->post_author ); + + $author3_term = $this->_cap->get_author_term( $this->author3 ); + + $this->assertInstanceOf( WP_Term::class, $author3_term ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms) ); + $this->assertCount( 1, $post_author_terms ); + $this->assertInstanceOf( WP_Term::class, $post_author_terms[0] ); + $this->assertEquals( 'cap-' . $this->author3->user_login, $post_author_terms[0]->slug ); + + // Confirming that now $author2 does have an author term + $second_added_authors = $this->_cap->add_coauthors( $post_id, array( $this->author2->user_login ) ); + $this->assertTrue( $second_added_authors ); + $author2_term = $this->_cap->get_author_term( $this->author2 ); + $this->assertInstanceOf( WP_Term::class, $author2_term ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 1, $post_author_terms ); + $this->assertInstanceOf( WP_Term::class, $post_author_terms[0] ); + $this->assertEquals( 'cap-' . $this->author2->user_login, $post_author_terms[0]->slug ); + } + + /** + * This test should not affect the post_author field, since we + * are simply appending an author to a post. + * + * @return void + */ + public function test_append_post_author_who_has_not_been_linked( ) { + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->author2->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $this->_cap->add_coauthors( $post_id, array( $this->author3->user_login ), true ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->author2->ID, $query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 2, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author2->user_login, + 'cap-' . $this->author3->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + + /** + * Here we are assigning multiple authors who have not been + * linked to a coauthor to a post. Since we are not + * appending authors to the post, we should + * expect the post_author to change. + * + * @return void + */ + public function test_assign_post_authors_from_authors_who_have_not_been_linked() { + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->author1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $this->_cap->add_coauthors( + $post_id, + array( + $this->author3->user_login, + $this->editor1->user_login, + $this->author2->user_login, + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->author3->ID, $query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 3, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author3->user_login, + 'cap-' . $this->editor1->user_login, + 'cap-' . $this->author2->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + + /** + * Here we are creating guest authors (coauthors) and assigning them to a post, + * which was created by a WP_User. Since the guest authors have not been + * linked to a WP_User, the wp_post.post_author column should not + * change, and the response from CoAuthors_Plus::add_coauthors() + * should be false, since no WP_User could be found. + * + * @return void + */ + public function test_assign_post_authors_from_coauthors_who_have_not_been_linked() { + $random_username = 'random_user_' . rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_1_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + /** + * By using CoAuthors_Plus::get_coauthor_by(), we are ensuring + * that the recent changes to the code will prioritize + * returning a Guest Author when one is found. + */ + $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + + $this->assertIsObject( $guest_author_1 ); + $this->assertThat( + $guest_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $random_username = 'random_user_' . rand( 1001, 2000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_2_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_2 = $this->_cap->get_coauthor_by( 'id', $guest_author_2_id ); + + $this->assertIsObject( $guest_author_2 ); + $this->assertThat( + $guest_author_2, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->author1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->author1->ID, $query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id, + array( + $guest_author_1->user_login, + $guest_author_2->user_login, + ) + ); + + /* + * This is false because we are NOT appending any coauthors who are linked to a WP_User to the post. + * */ + $this->assertFalse( $result ); + + $second_query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $second_query->found_posts ); + $this->assertEquals( $this->author1->ID, $second_query->posts[0]->post_author ); + } + + /** + * This test is similar to above, but instead here, we are appending coauthors. + * This means that the wp_posts.post_author column is not expected to change, + * and so the response from CoAuthors_Plus::add_coauthors() should be true. + * + * @return void + */ + public function test_append_post_authors_from_coauthors_who_have_not_been_linked() { + $random_username = 'random_user_' . rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_1_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + + $this->assertIsObject( $guest_author_1 ); + $this->assertThat( + $guest_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $random_username = 'random_user_' . rand( 1001, 2000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_2_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_2 = $this->_cap->get_coauthor_by( 'id', $guest_author_2_id ); + + $this->assertIsObject( $guest_author_2 ); + $this->assertThat( + $guest_author_2, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->author1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->author1->ID, $query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id, + array( + $guest_author_1->user_login, + $guest_author_2->user_login, + ), + true + ); + + $this->assertTrue( $result ); + + $second_query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $second_query->found_posts ); + $this->assertEquals( $this->author1->ID, $second_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertIsArray( $post_author_terms ); + $this->assertCount( 3, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author1->user_login, + 'cap-' . $guest_author_1->user_login, + 'cap-' . $guest_author_2->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + + /** + * Here we are assigning one coauthor and one WP_User who have not been linked. + * The result should be true, since the WP_User will be assigned as the + * post_author. There should only be 2 WP_Terms for the authors. + * + * @return void + */ + public function test_assign_coauthors_from_coauthors_and_user_who_have_not_been_linked() { + $random_username = 'random_user_' . rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_1_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + + $this->assertIsObject( $guest_author_1 ); + $this->assertThat( + $guest_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->author1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->author1->ID, $query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id, + array( + $guest_author_1->user_login, + $this->author3->user_login, + ) + ); + + $this->assertTrue( $result ); + + $second_query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $second_query->found_posts ); + $this->assertEquals( $this->author3->ID, $second_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 2, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author3->user_login, + 'cap-' . $guest_author_1->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + + /** + * Similar to above, but we are appending instead. The wp_posts.post_author should + * not be changed, but we should see 3 WP_Terms for the authors now. + * + * @return void + */ + public function test_append_coauthors_from_coauthors_and_user_who_have_not_been_linked() { + $random_username = 'random_user_' . rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_1_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + + $this->assertIsObject( $guest_author_1 ); + $this->assertThat( + $guest_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->author1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->author1->ID, $query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id, + array( + $guest_author_1->user_login, + $this->author3->user_login, + ), + true + ); + + $this->assertTrue( $result ); + + $second_query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $second_query->found_posts ); + $this->assertEquals( $this->author1->ID, $second_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 3, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author1->user_login, + 'cap-' . $this->author3->user_login, + 'cap-' . $guest_author_1->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + + /** + * This is where we test many moving parts of the CoAuthorsPlugin all at once. We are creating a guest author from a + * WP_User, and then assigning that guest author to a post. Since the guest author is linked to a WP_User, the + * function CoAuthors_Plus::get_coauthor_by() should return a guest author object along with meta data + * indicating that the object is linked to a WP_User. The wp_posts.post_author column should change, + * and the response from CoAuthors_Plus::add_coauthors() should be true. + * @return void + */ + public function test_assign_post_authors_from_coauthors_who_are_linked() { + $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author2->ID ); + $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); + + $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author2->ID ); + $this->assertIsObject( $linked_author_1 ); + $this->assertThat( + $linked_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + $this->assertObjectHasProperty( 'type', $linked_author_1 ); + $this->assertEquals( 'guest-author', $linked_author_1->type ); + $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( $linked_author_1->is_wp_user ); + $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); + $this->assertEquals( $this->author2->ID, $linked_author_1->wp_user->ID ); + + $linked_author_2 = $this->_cap->get_coauthor_by( 'user_login', $this->author3->user_login ); + $this->assertIsObject( $linked_author_2 ); + $this->assertThat( + $linked_author_2, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + $this->assertObjectHasProperty( 'type', $linked_author_2 ); + $this->assertEquals( 'guest-author', $linked_author_2->type ); + $this->assertObjectHasProperty( 'is_wp_user', $linked_author_2 ); + $this->assertTrue( $linked_author_2->is_wp_user ); + $this->assertObjectHasProperty( 'wp_user', $linked_author_2 ); + $this->assertInstanceOf( WP_User::class, $linked_author_2->wp_user ); + $this->assertEquals( $this->author3->ID, $linked_author_2->wp_user->ID ); + + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->editor1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->editor1->ID, $query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id, + array( + $linked_author_1->user_login, + $linked_author_2->user_login, + ) + ); + + $this->assertTrue( $result ); + + $second_query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $second_query->found_posts ); + $this->assertEquals( $this->author2->ID, $second_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 2, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author2->user_login, + 'cap-' . $this->author3->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + + /** + * Very similar test as before. The only difference is that we are appending, + * so the wp_posts.post_author column should not change, but we should + * see 3 WP_Terms for the authors now. + * + * @return void + */ + public function test_append_post_authors_from_coauthors_one_of_whom_is_linked() { + $random_username = 'random_user_' . rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_1_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + + $this->assertIsObject( $guest_author_1 ); + $this->assertThat( + $guest_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); + + $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); + $this->assertIsObject( $linked_author_1 ); + $this->assertThat( + $linked_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + $this->assertObjectHasProperty( 'type', $linked_author_1 ); + $this->assertEquals( 'guest-author', $linked_author_1->type ); + $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( $linked_author_1->is_wp_user ); + $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); + $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); + + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->editor1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->editor1->ID, $query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id, + array( + $guest_author_1->user_login, + $linked_author_1->user_login, + ), + true + ); + + $this->assertTrue( $result ); + + $second_query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $second_query->found_posts ); + $this->assertEquals( $this->editor1->ID, $second_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 3, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->editor1->user_login, + 'cap-' . $guest_author_1->user_login, + 'cap-' . $this->author3->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + + /** + * This is testing that multiple coauthors can be correctly assigned to a post. + * The wp_posts.post_author column should be set to the first WP_User in + * the array, which is $author1. The response from CoAuthors_Plus::add_coauthors() + * should be true, and there should be 3 author terms associated with the post. + * + * @return void + */ + public function test_assign_multiple_post_authors_wp_user_guest_author_linked_user( ) { + $random_username = 'random_user_' . rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_1_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + + $this->assertIsObject( $guest_author_1 ); + $this->assertThat( + $guest_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); + + $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); + $this->assertIsObject( $linked_author_1 ); + $this->assertThat( + $linked_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->editor1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->editor1->ID, $query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id, + array( + $this->author1->user_login, + $guest_author_1->user_login, + $linked_author_1->user_login, + ) + ); + + $this->assertTrue( $result ); + + $second_query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $second_query->found_posts ); + $this->assertEquals( $this->author1->ID, $second_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 3, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author1->user_login, + 'cap-' . $guest_author_1->user_login, + 'cap-' . $this->author3->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + + /** + * With this test we are confirming that no matter the order in which a linked user is + * passed in the array, the wp_posts.post_author column will be set to the linked user. + * + * @return void + */ + public function test_assign_multiple_post_authors_only_one_linked_passed_last() { + $random_username = 'random_user_' . rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_1_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + + $this->assertIsObject( $guest_author_1 ); + $this->assertThat( + $guest_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $random_username = 'random_user_' . rand( 1001, 2000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_2_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_2 = $this->_cap->get_coauthor_by( 'id', $guest_author_2_id ); + + $this->assertIsObject( $guest_author_2 ); + $this->assertThat( + $guest_author_2, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); + + $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); + $this->assertIsObject( $linked_author_1 ); + $this->assertThat( + $linked_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( $linked_author_1->is_wp_user ); + $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); + $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); + + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->editor1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->editor1->ID, $query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id, + array( + $guest_author_1->user_login, + $guest_author_2->user_login, + // Linked user is passed last in array. + // Placement within array should not matter. + // It should get picked up, and used to set wp_posts.post_author + $linked_author_1->user_login, + ) + ); + + $this->assertTrue( $result ); + + $second_query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $second_query->found_posts ); + $this->assertEquals( $this->author3->ID, $second_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 3, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author3->user_login, + 'cap-' . $guest_author_1->user_login, + 'cap-' . $guest_author_2->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + + /** + * Same as above, except we will pass a WP_User before the linked user. The wp_posts.post_author + * should be set to the WP_User, and there should be 3 WP_Terms for the authors. + * + * @return void + */ + public function test_assign_multiple_post_authors_one_user_before_one_linked_passed_last() { + $random_username = 'random_user_' . rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_1_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + + $this->assertIsObject( $guest_author_1 ); + $this->assertThat( + $guest_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); + + $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); + $this->assertIsObject( $linked_author_1 ); + $this->assertThat( + $linked_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( $linked_author_1->is_wp_user ); + $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); + $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); + + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->editor1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->editor1->ID, $query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id, + array( + $guest_author_1->user_login, + $this->author2->user_login, + $linked_author_1->user_login, + ) + ); + + $this->assertTrue( $result ); + + $second_query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $second_query->found_posts ); + $this->assertEquals( $this->author2->ID, $second_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 3, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author2->user_login, + 'cap-' . $this->author3->user_login, + 'cap-' . $guest_author_1->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + + /** + * Same as above, except not the linked user is passed up front. This should result in + * the wp_posts.post_author column being set to the linked user, and there should be + * 3 WP_Terms for the authors. + * + * @return void + */ + public function test_assign_multiple_post_authors_one_linked_passed_first() { + $random_username = 'random_user_' . rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_1_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + + $this->assertIsObject( $guest_author_1 ); + $this->assertThat( + $guest_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); + + $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); + $this->assertIsObject( $linked_author_1 ); + $this->assertThat( + $linked_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( $linked_author_1->is_wp_user ); + $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); + $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); + + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->editor1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->editor1->ID, $query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id, + array( + $linked_author_1->user_login, + $this->author2->user_login, + $guest_author_1->user_login, + ) + ); + + $this->assertTrue( $result ); + + $second_query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $second_query->found_posts ); + $this->assertEquals( $this->author3->ID, $second_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 3, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author2->user_login, + 'cap-' . $this->author3->user_login, + 'cap-' . $guest_author_1->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + + /** + * Here we are testing a similar scenario as above, except we are passing the linked user's WP_User login field + * instead when assigning the post authors. The result should be that the correct GA account + * is located and used to set the author's for the post. + * + * @return void + */ + public function test_assign_multiple_post_authors_one_linked_passed_using_user_login_to_assign() { + $random_username = 'random_user_' . rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_1_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + + $this->assertIsObject( $guest_author_1 ); + $this->assertThat( + $guest_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); + + $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); + $this->assertIsObject( $linked_author_1 ); + $this->assertThat( + $linked_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( $linked_author_1->is_wp_user ); + $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); + $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); + + $post_id = $this->factory()->post->create( + array( + 'post_author' => $this->editor1->ID, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( $this->editor1->ID, $query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id, + array( + $guest_author_1->user_login, + // This should be converted to the corresponding GA account for linked user. + $this->author3->user_login, + $this->author2->user_login, + ) + ); + + $this->assertTrue( $result ); + + $second_query = new WP_Query( + array( + 'p' => $post_id, + ) + ); + + $this->assertEquals( 1, $second_query->found_posts ); + $this->assertEquals( $this->author3->ID, $second_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 3, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author2->user_login, + 'cap-' . $this->author3->user_login, + 'cap-' . $guest_author_1->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + + $guest_author_term = wp_get_post_terms( $linked_author_1->ID, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $guest_author_term ) ); + $this->assertCount( 1, $guest_author_term ); + $this->assertEquals( 'cap-' . $linked_author_1->user_login, $guest_author_term[0]->slug ); + } + + /** + * This test is a combination of a few different aspects that establish some expected plugin behavior. + * Two posts are created to test with. Both have no WP_User as the author (i.e. wp_posts.post_author = 0). + * For the first post: + * 1. A guest author is created, and assigned to the post. + * 2. Since there is no WP_User which is passed, and the GA is NOT being appended, the result should be false. + * 3. The wp_posts.post_author column should still be 0 since this is a GA and not a WP_User or a linked GA. + * + * For the second post: + * 1. A guest author is created, and appended to the post. + * 2. Since we are appending a coauthor, it does not matter if there was already a WP_User author, so result should be true. + * 3. The wp_posts.post_author column should still be 0 since this is a GA and not a WP_User or a linked GA. + * + * Going back to the first post: + * 1. A linked user and a WP_User are created and assigned to this post. + * 2. Result should be true since here we essentially have 2 WP_Users. + * 3. Since there is a WP_User, and it is passed first, the wp_posts.post_author column should be set to the ID for that WP_User. + * 4. There should only be 2 author terms for this post, one for the WP_User, and one for the linked account. + * The term for the GA which was previously assigned is deleted. + * + * Finally, going back to the second post: + * 1. A linked user and a WP_User are created and appended to this post. + * 2. Result should be true since we have 2 WP_Users. + * 3. Here we passed the linked author first, so the wp_posts.post_author column should match the ID for the linked WP_user account. + * 4. There should be 3 author terms for this post, one for the GA, the WP_user, and linked account. + * @return void + */ + public function test_assign_post_authors_from_post_with_no_author() { + $post_id_1 = $this->factory()->post->create( + array( + 'post_author' => 0, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $query = new WP_Query( + array( + 'p' => $post_id_1, + ) + ); + + $this->assertEquals( 1, $query->found_posts ); + $this->assertEquals( 0, $query->posts[0]->post_author ); + + $post_id_2 = $this->factory()->post->create( + array( + 'post_author' => 0, + 'post_status' => 'publish', + 'post_type' => 'post', + ) + ); + + $second_post_query = new WP_Query( + array( + 'p' => $post_id_2, + ) + ); + + $this->assertEquals( 1, $second_post_query->found_posts ); + $this->assertEquals( 0, $second_post_query->posts[0]->post_author ); + + $random_username = 'random_user_' . rand( 90000, 100000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $guest_author_1_id = $this->_cap->guest_authors->create( + array( + 'user_login' => $random_username, + 'display_name' => $display_name, + ) + ); + $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + + $this->assertIsObject( $guest_author_1 ); + $this->assertThat( + $guest_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + + $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); + + $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); + $this->assertIsObject( $linked_author_1 ); + $this->assertThat( + $linked_author_1, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( $linked_author_1->is_wp_user ); + $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); + $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); + + $result = $this->_cap->add_coauthors( + $post_id_1, + array( + $guest_author_1->user_login, + ) + ); + + $this->assertFalse( $result ); + + $post_1_author_terms = wp_get_post_terms( $post_id_1, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_1_author_terms ) ); + $this->assertCount( 1, $post_1_author_terms ); + $this->assertEquals( 'cap-' . $guest_author_1->user_login, $post_1_author_terms[0]->slug ); + + $third_post_query = new WP_Query( + array( + 'p' => $post_id_1, + ) + ); + + $this->assertEquals( 1, $third_post_query->found_posts ); + $this->assertEquals( 0, $third_post_query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id_2, + array( + $guest_author_1->user_login, + ), + true + ); + + $this->assertTrue( $result ); + + $fourth_post_query = new WP_Query( + array( + 'p' => $post_id_2, + ) + ); + + $this->assertEquals( 1, $fourth_post_query->found_posts ); + $this->assertEquals( 0, $fourth_post_query->posts[0]->post_author ); + + $result = $this->_cap->add_coauthors( + $post_id_1, + array( + $this->author2->user_login, + $linked_author_1->user_login, + ) + ); + + $this->assertTrue( $result ); + + $fifth_post_query = new WP_Query( + array( + 'p' => $post_id_1, + ) + ); + + $this->assertEquals( 1, $fifth_post_query->found_posts ); + $this->assertEquals( $this->author2->ID, $fifth_post_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id_1, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 2, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $this->author2->user_login, + 'cap-' . $linked_author_1->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + + $result = $this->_cap->add_coauthors( + $post_id_2, + array( + $linked_author_1->user_login, + $this->author2->user_login, + ), + true + ); + + $this->assertTrue( $result ); + + $sixth_post_query = new WP_Query( + array( + 'p' => $post_id_2, + ) + ); + + $this->assertEquals( 1, $sixth_post_query->found_posts ); + $this->assertEquals( $this->author3->ID, $sixth_post_query->posts[0]->post_author ); + + $post_author_terms = wp_get_post_terms( $post_id_2, $this->_cap->coauthor_taxonomy ); + + $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertCount( 3, $post_author_terms ); + + $author_slugs = array( + 'cap-' . $guest_author_1->user_login, + 'cap-' . $this->author2->user_login, + 'cap-' . $linked_author_1->user_login, + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $author_slugs ); + } + } + /** * @covers CoAuthors_Plus::is_block_editor() */ From e64921ebda8c70ea8bfc5e118d9ef34564d3d22d Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Sat, 9 Sep 2023 11:59:42 -0400 Subject: [PATCH 08/27] fix: preventing loss of fact that a guest author might also be a WP_User --- php/class-coauthors-plus.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/php/class-coauthors-plus.php b/php/class-coauthors-plus.php index 57896031..0b20be37 100644 --- a/php/class-coauthors-plus.php +++ b/php/class-coauthors-plus.php @@ -307,6 +307,8 @@ public function get_coauthor_by( $key, $value, $force = false ) { if ( isset( $this->guest_authors ) && $this->is_guest_authors_enabled() ) { $guest_author = $this->guest_authors->get_guest_author_by( 'linked_account', $user->user_login ); if ( is_object( $guest_author ) ) { + $guest_author->is_wp_user = true; // Important not to lose the fact that this is a WP user. + $guest_author->wp_user = $user; $user = $guest_author; } } @@ -968,8 +970,8 @@ public function add_coauthors( $post_id, $coauthors, $append = false, $query_typ if ( empty( $post_author_user ) || ! in_array( $post_author_user->user_login, $coauthors ) ) { foreach ( $coauthor_objects as $coauthor_object ) { - if ( 'wpuser' === $coauthor_object->type ) { - $new_author = $coauthor_object; + if ( isset( $coauthor_object->is_wp_user ) && $coauthor_object->is_wp_user ) { + $new_author = $coauthor_object->wp_user; break; } } From c0344dbcce9aff54a46909a4554af6d48cbc0f47 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Sat, 9 Sep 2023 12:01:18 -0400 Subject: [PATCH 09/27] fix: making the update operation dependent on $append flag. This might be a problematic decision. But the way I justify this change is that if you are appending co-authors, there may already be a WP_User set as the author. So we don't really have to care whether one is passed or not. Because of this, we do not need to forcibly return a `false` flag since that is confusing to the caller, especially because we actually do save the guest authors which are given in the call! Instead, if the $append flag is false, we should expect that at least one user will be a WP_User. In that case, if none is passed in, then there is a mismatch of the intended authors. Because now, the `wp_posts.post_author` column will have an old `wp_users.ID` which remains set and most likely isn't the intent of the caller. --- php/class-coauthors-plus.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/php/class-coauthors-plus.php b/php/class-coauthors-plus.php index 0b20be37..f617aa0b 100644 --- a/php/class-coauthors-plus.php +++ b/php/class-coauthors-plus.php @@ -975,8 +975,15 @@ public function add_coauthors( $post_id, $coauthors, $append = false, $query_typ break; } } - // Uh oh, no WP_Users assigned to the post - if ( empty( $new_author ) ) { + + /* + * If setting a fresh group of authors for a post, (i.e. $append === false), + * then perhaps one of those authors should be a WP_USER. However, + * if $append === true, and we are perhaps unable to find a + * WP_USER (perhaps none was given), we don't really + * care whether post_author should be updated. + * */ + if ( false === $append && empty( $new_author ) ) { return false; } From 7ece2ab2bf6b240a4039426b30c33bf94533104c Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Sat, 9 Sep 2023 12:03:10 -0400 Subject: [PATCH 10/27] fix: attempting DB update only when $new_author is not empty. Also, returning the actual response from the DB, to make this call even more accurate in terms of what is actually happen at the DB layer. --- php/class-coauthors-plus.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/php/class-coauthors-plus.php b/php/class-coauthors-plus.php index f617aa0b..b906b59b 100644 --- a/php/class-coauthors-plus.php +++ b/php/class-coauthors-plus.php @@ -987,8 +987,14 @@ public function add_coauthors( $post_id, $coauthors, $append = false, $query_typ return false; } - $wpdb->update( $wpdb->posts, array( 'post_author' => $new_author->ID ), array( 'ID' => $post_id ) ); - clean_post_cache( $post_id ); + if ( ! empty( $new_author ) ) { + $update = $wpdb->update( $wpdb->posts, array( 'post_author' => $new_author->ID ), array( 'ID' => $post_id ) ); + clean_post_cache( $post_id ); + + if ( is_bool( $update ) ) { + return $update; + } + } } return true; From 741c0537603dcbf0fcbe83e7e6027e2b270ba12e Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Sat, 9 Sep 2023 12:05:13 -0400 Subject: [PATCH 11/27] fix: need to ensure pure WP_User is processed correctly as post_author. A pure WP_User (i.e. a WP_User that IS NOT linked to a Guest Author) needs to be handled specially. --- php/class-coauthors-plus.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/php/class-coauthors-plus.php b/php/class-coauthors-plus.php index b906b59b..484cd688 100644 --- a/php/class-coauthors-plus.php +++ b/php/class-coauthors-plus.php @@ -970,7 +970,10 @@ public function add_coauthors( $post_id, $coauthors, $append = false, $query_typ if ( empty( $post_author_user ) || ! in_array( $post_author_user->user_login, $coauthors ) ) { foreach ( $coauthor_objects as $coauthor_object ) { - if ( isset( $coauthor_object->is_wp_user ) && $coauthor_object->is_wp_user ) { + if ( $coauthor_object instanceof WP_User ) { + $new_author = $coauthor_object; + break; + } else if ( isset( $coauthor_object->is_wp_user ) && $coauthor_object->is_wp_user ) { $new_author = $coauthor_object->wp_user; break; } From e9e76afa767bc325123c137df3ad7af169401b1f Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Sat, 9 Sep 2023 12:18:10 -0400 Subject: [PATCH 12/27] fix: a necessary refactor of the get_coauthor_by function. This refactor is absolutely necessary in order for all the previous fixes to work as expected. Without this fix, what happens is that when you use `get_coauthor_by` by searching with a Guest Author, any link to a WP_User the Guest Author may have is summarily ignored. Functions like `add_coauthors` expect at least one coauthor to be a valid WP_User so that the `wp_posts.post_author` column can be appropriately updated. The only case where this function is currently returning an expected value is when you search by a WP_User account/field first. When it arrives at `$guest_author = $this->guest_authors->get_guest_author_by( $key, $value, $force );`, `$guest_author === false`. It is then forced to move to the switch statement to find a user via their WP_User data. With this refactor, `get_coauthor_by` will now check if the `linked_account` attribute is set. If so, it will then attempt to find the corresponding WP_User for the Guest Author. Crucially, it still gives priority to returning a Guest Author. When a Guest Author is not found, it will then attempt to search for a WP_User. If found, it will also search to see if a linked Guest Author account exists. If it does, it will return that Guest Author object instead, without losing the fact that this account also has a WP_User associated with it. --- php/class-coauthors-plus.php | 106 +++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 36 deletions(-) diff --git a/php/class-coauthors-plus.php b/php/class-coauthors-plus.php index 484cd688..4b343cf2 100644 --- a/php/class-coauthors-plus.php +++ b/php/class-coauthors-plus.php @@ -269,53 +269,87 @@ public function is_guest_authors_enabled() { public function get_coauthor_by( $key, $value, $force = false ) { // If Guest Authors are enabled, prioritize those profiles - if ( isset( $this->guest_authors ) && $this->is_guest_authors_enabled() ) { + if ( $this->is_guest_authors_enabled() && isset( $this->guest_authors ) ) { $guest_author = $this->guest_authors->get_guest_author_by( $key, $value, $force ); if ( is_object( $guest_author ) ) { - return $guest_author; - } - } + if ( isset( $guest_author->linked_account ) ) { + $user = $this->get_user_by( 'login', $guest_author->linked_account ); - switch ( $key ) { - case 'id': - case 'login': - case 'user_login': - case 'email': - case 'user_nicename': - case 'user_email': - if ( 'user_login' === $key ) { - $key = 'login'; - } - if ( 'user_email' === $key ) { - $key = 'email'; - } - if ( 'user_nicename' === $key ) { - $key = 'slug'; - } - $user = get_user_by( $key, $value ); - if ( ! $user && ( 'login' === $key || 'slug' === $key ) ) { - // Re-try lookup without prefixed value if no results found. - $value = preg_replace( '#^cap\-#', '', $value ); - $user = get_user_by( $key, $value ); + if ( ! is_null( $user ) ) { + $guest_author->is_wp_user = true; // Important not to lose the fact that this is a WP user. + $guest_author->wp_user = $user; + } } - if ( ! $user ) { + + return $guest_author; + } else { + // Guest Author was not found, so let's see if we are searching for a WP_User + $user = $this->get_user_by( $key, $value ); + + if ( is_null( $user ) ) { return false; } + + // At this point we have a valid $user. $user->type = 'wpuser'; - // However, if guest authors are enabled and there's a guest author linked to this - // user account, we want to use that instead - if ( isset( $this->guest_authors ) && $this->is_guest_authors_enabled() ) { - $guest_author = $this->guest_authors->get_guest_author_by( 'linked_account', $user->user_login ); - if ( is_object( $guest_author ) ) { - $guest_author->is_wp_user = true; // Important not to lose the fact that this is a WP user. - $guest_author->wp_user = $user; - $user = $guest_author; - } + + $guest_author = $this->guest_authors->get_guest_author_by( 'linked_account', $user->user_login ); + if ( is_object( $guest_author ) ) { + $guest_author->is_wp_user = true; // Important not to lose the fact that this is a WP user. + $guest_author->wp_user = $user; + $user = $guest_author; } + return $user; + } + } else { + $user = $this->get_user_by( $key, $value ); + + if ( is_null( $user ) ) { + return false; + } + + $user->type = 'wpuser'; + + return $user; + } + } + + /** + * @param string $key Key to search by, i.e. 'id', 'login', 'user_login', 'email', 'user_email', 'user_nicename' + * @param string $value Value to search for. + * + * @return WP_User|null + */ + protected function get_user_by( $key, $value ) { + $acceptable_keys = [ + 'id' => 'id', + 'login' => 'login', + 'user_login' => 'login', + 'email' => 'email', + 'user_email' => 'email', + 'user_nicename' => 'slug', + ]; + + if ( ! array_key_exists( $key, $acceptable_keys ) ) { + return null; + } + + $key = $acceptable_keys[ $key ]; + + $user = get_user_by( $key, $value ); + + if ( ! $user && ( 'login' == $key || 'slug' == $key ) ) { + // Re-try lookup without prefixed value if no results found. + $value = preg_replace( '#^cap\-#', '', $value ); + $user = get_user_by( $key, $value ); + } + + if ( false === $user ) { + return null; } - return false; + return $user; } /** From e7c779253d7b1aa1b35fd3e1e9ef04d06fbaf20e Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Sat, 9 Sep 2023 13:20:35 -0400 Subject: [PATCH 13/27] fix: renaming user_login's for new authors introduced for new tests. These user_login's were causing other tests to fail because you cannot create another user with the same user_login. --- tests/test-coauthors-plus.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-coauthors-plus.php b/tests/test-coauthors-plus.php index 1a5bf11b..49942554 100644 --- a/tests/test-coauthors-plus.php +++ b/tests/test-coauthors-plus.php @@ -25,14 +25,14 @@ public function set_up() { $this->author2 = $this->factory()->user->create_and_get( array( 'role' => 'author', - 'user_login' => 'author2', + 'user_login' => 'author20', ) ); $this->author3 = $this->factory()->user->create_and_get( array( 'role' => 'author', - 'user_login' => 'author3', + 'user_login' => 'author30', ) ); From b6b959b9bd7e58831e3e147beb12bcbf21706e13 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Sat, 9 Sep 2023 13:22:35 -0400 Subject: [PATCH 14/27] fix: removing use of assertObjectHasProperty Older version of PHPUnit do not have this function available. Updating to workaround: `assertTrue( property_exists( $obj, 'prop' ) )` --- tests/test-coauthors-plus.php | 38 +++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/test-coauthors-plus.php b/tests/test-coauthors-plus.php index 49942554..4e44c079 100644 --- a/tests/test-coauthors-plus.php +++ b/tests/test-coauthors-plus.php @@ -1233,11 +1233,11 @@ public function test_assign_post_authors_from_coauthors_who_are_linked() { $this->isInstanceOf( WP_User::class ) ) ); - $this->assertObjectHasProperty( 'type', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'type' ) ); $this->assertEquals( 'guest-author', $linked_author_1->type ); - $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->asserTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); $this->assertEquals( $this->author2->ID, $linked_author_1->wp_user->ID ); @@ -1249,11 +1249,11 @@ public function test_assign_post_authors_from_coauthors_who_are_linked() { $this->isInstanceOf( WP_User::class ) ) ); - $this->assertObjectHasProperty( 'type', $linked_author_2 ); + $this->assertTrue( property_exists( $linked_author_2, 'type' ) ); $this->assertEquals( 'guest-author', $linked_author_2->type ); - $this->assertObjectHasProperty( 'is_wp_user', $linked_author_2 ); + $this->assertTrue( property_exists( $linked_author_2, 'is_wp_user' ) ); $this->assertTrue( $linked_author_2->is_wp_user ); - $this->assertObjectHasProperty( 'wp_user', $linked_author_2 ); + $this->assertTrue( property_exists( $linked_author_2, 'wp_user' ) ); $this->assertInstanceOf( WP_User::class, $linked_author_2->wp_user ); $this->assertEquals( $this->author3->ID, $linked_author_2->wp_user->ID ); @@ -1346,11 +1346,11 @@ public function test_append_post_authors_from_coauthors_one_of_whom_is_linked() $this->isInstanceOf( WP_User::class ) ) ); - $this->assertObjectHasProperty( 'type', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'type' ) ); $this->assertEquals( 'guest-author', $linked_author_1->type ); - $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); @@ -1556,9 +1556,9 @@ public function test_assign_multiple_post_authors_only_one_linked_passed_last() $this->isInstanceOf( WP_User::class ) ) ); - $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); @@ -1655,9 +1655,9 @@ public function test_assign_multiple_post_authors_one_user_before_one_linked_pas $this->isInstanceOf( WP_User::class ) ) ); - $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); @@ -1752,9 +1752,9 @@ public function test_assign_multiple_post_authors_one_linked_passed_first() { $this->isInstanceOf( WP_User::class ) ) ); - $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); @@ -1849,9 +1849,9 @@ public function test_assign_multiple_post_authors_one_linked_passed_using_user_l $this->isInstanceOf( WP_User::class ) ) ); - $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); @@ -2007,9 +2007,9 @@ public function test_assign_post_authors_from_post_with_no_author() { $this->isInstanceOf( WP_User::class ) ) ); - $this->assertObjectHasProperty( 'is_wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertObjectHasProperty( 'wp_user', $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); From 41006b36f803abedd4344dd4c40f56e80d61e62b Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Sat, 9 Sep 2023 13:24:39 -0400 Subject: [PATCH 15/27] fix: typo in function call --- tests/test-coauthors-plus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-coauthors-plus.php b/tests/test-coauthors-plus.php index 4e44c079..edce5135 100644 --- a/tests/test-coauthors-plus.php +++ b/tests/test-coauthors-plus.php @@ -1235,7 +1235,7 @@ public function test_assign_post_authors_from_coauthors_who_are_linked() { ); $this->assertTrue( property_exists( $linked_author_1, 'type' ) ); $this->assertEquals( 'guest-author', $linked_author_1->type ); - $this->asserTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); + $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); From 7e4bd8e0f22e8899f5630088c2367fed97cb1d44 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Tue, 17 Oct 2023 12:14:02 -0400 Subject: [PATCH 16/27] fix: using strict comparison instead of function call `is_null` --- php/class-coauthors-plus.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/php/class-coauthors-plus.php b/php/class-coauthors-plus.php index 813179b9..03eaae5d 100644 --- a/php/class-coauthors-plus.php +++ b/php/class-coauthors-plus.php @@ -313,8 +313,7 @@ public function get_coauthor_by( $key, $value, $force = false ) { if ( isset( $guest_author->linked_account ) ) { $user = $this->get_user_by( 'login', $guest_author->linked_account ); - if ( ! is_null( $user ) ) { - $guest_author->is_wp_user = true; // Important not to lose the fact that this is a WP user. + if ( null !== $user ) { $guest_author->wp_user = $user; } } @@ -324,7 +323,7 @@ public function get_coauthor_by( $key, $value, $force = false ) { // Guest Author was not found, so let's see if we are searching for a WP_User $user = $this->get_user_by( $key, $value ); - if ( is_null( $user ) ) { + if ( null === $user ) { return false; } @@ -343,7 +342,7 @@ public function get_coauthor_by( $key, $value, $force = false ) { } else { $user = $this->get_user_by( $key, $value ); - if ( is_null( $user ) ) { + if ( null === $user ) { return false; } From aacd37b3450272c103c28403e2fa9218f0d50e9e Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Tue, 17 Oct 2023 12:19:10 -0400 Subject: [PATCH 17/27] fix: using more descriptive assertion for array validation. --- tests/Integration/CoAuthorsPlusTest.php | 34 ++++++++++++------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/Integration/CoAuthorsPlusTest.php b/tests/Integration/CoAuthorsPlusTest.php index 45f2622f..e181bda0 100644 --- a/tests/Integration/CoAuthorsPlusTest.php +++ b/tests/Integration/CoAuthorsPlusTest.php @@ -750,7 +750,7 @@ public function test_assign_post_author_from_author_who_has_not_been_linked() { $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 1, $post_author_terms ); $this->assertInstanceOf( WP_Term::class, $post_author_terms[0] ); $this->assertEquals( 'cap-' . $this->author3->user_login, $post_author_terms[0]->slug ); @@ -763,7 +763,7 @@ public function test_assign_post_author_from_author_who_has_not_been_linked() { $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 1, $post_author_terms ); $this->assertInstanceOf( WP_Term::class, $post_author_terms[0] ); $this->assertEquals( 'cap-' . $this->author2->user_login, $post_author_terms[0]->slug ); @@ -797,7 +797,7 @@ public function test_append_post_author_who_has_not_been_linked( ) { $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 2, $post_author_terms ); $author_slugs = array( @@ -848,7 +848,7 @@ public function test_assign_post_authors_from_authors_who_have_not_been_linked() $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 3, $post_author_terms ); $author_slugs = array( @@ -1121,7 +1121,7 @@ public function test_assign_coauthors_from_coauthors_and_user_who_have_not_been_ $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 2, $post_author_terms ); $author_slugs = array( @@ -1200,7 +1200,7 @@ public function test_append_coauthors_from_coauthors_and_user_who_have_not_been_ $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 3, $post_author_terms ); $author_slugs = array( @@ -1297,7 +1297,7 @@ public function test_assign_post_authors_from_coauthors_who_are_linked() { $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 2, $post_author_terms ); $author_slugs = array( @@ -1395,7 +1395,7 @@ public function test_append_post_authors_from_coauthors_one_of_whom_is_linked() $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 3, $post_author_terms ); $author_slugs = array( @@ -1488,7 +1488,7 @@ public function test_assign_multiple_post_authors_wp_user_guest_author_linked_us $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 3, $post_author_terms ); $author_slugs = array( @@ -1606,7 +1606,7 @@ public function test_assign_multiple_post_authors_only_one_linked_passed_last() $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 3, $post_author_terms ); $author_slugs = array( @@ -1702,7 +1702,7 @@ public function test_assign_multiple_post_authors_one_user_before_one_linked_pas $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 3, $post_author_terms ); $author_slugs = array( @@ -1799,7 +1799,7 @@ public function test_assign_multiple_post_authors_one_linked_passed_first() { $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 3, $post_author_terms ); $author_slugs = array( @@ -1897,7 +1897,7 @@ public function test_assign_multiple_post_authors_one_linked_passed_using_user_l $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 3, $post_author_terms ); $author_slugs = array( @@ -1913,7 +1913,7 @@ public function test_assign_multiple_post_authors_one_linked_passed_using_user_l $guest_author_term = wp_get_post_terms( $linked_author_1->ID, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $guest_author_term ) ); + $this->assertIsArray( $guest_author_term ); $this->assertCount( 1, $guest_author_term ); $this->assertEquals( 'cap-' . $linked_author_1->user_login, $guest_author_term[0]->slug ); } @@ -2026,7 +2026,7 @@ public function test_assign_post_authors_from_post_with_no_author() { $post_1_author_terms = wp_get_post_terms( $post_id_1, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_1_author_terms ) ); + $this->assertIsArray( $post_1_author_terms ); $this->assertCount( 1, $post_1_author_terms ); $this->assertEquals( 'cap-' . $guest_author_1->user_login, $post_1_author_terms[0]->slug ); @@ -2079,7 +2079,7 @@ public function test_assign_post_authors_from_post_with_no_author() { $post_author_terms = wp_get_post_terms( $post_id_1, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 2, $post_author_terms ); $author_slugs = array( @@ -2114,7 +2114,7 @@ public function test_assign_post_authors_from_post_with_no_author() { $post_author_terms = wp_get_post_terms( $post_id_2, $this->_cap->coauthor_taxonomy ); - $this->assertTrue( is_array( $post_author_terms ) ); + $this->assertIsArray( $post_author_terms ); $this->assertCount( 3, $post_author_terms ); $author_slugs = array( From fc05f9d3749578c7da26375ee1172bd33a1fc57a Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Tue, 17 Oct 2023 12:20:35 -0400 Subject: [PATCH 18/27] fix: using `create_and_get` post factory func, to avoid query call. --- tests/Integration/CoAuthorsPlusTest.php | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tests/Integration/CoAuthorsPlusTest.php b/tests/Integration/CoAuthorsPlusTest.php index e181bda0..bd80d2ad 100644 --- a/tests/Integration/CoAuthorsPlusTest.php +++ b/tests/Integration/CoAuthorsPlusTest.php @@ -715,22 +715,14 @@ public function test_update_author_term_when_author_term_not_exist() { * @return void */ public function test_assign_post_author_from_author_who_has_not_been_linked() { - $post_id = $this->factory()->post->create( + $post = $this->factory()->post->create_and_get( array( 'post_author' => $this->author2->ID, 'post_status' => 'publish', 'post_type' => 'post', ) ); - - $query1 = new WP_Query( - array( - 'p' => $post_id - ) - ); - - $this->assertEquals( 1, $query1->found_posts ); - $this->assertEquals( $this->author2->ID, $query1->posts[0]->post_author ); + $post_id = $post->ID; $first_added_authors = $this->_cap->add_coauthors( $post_id, array( $this->author3->user_login ) ); $this->assertTrue( $first_added_authors ); From a0b808a27a7d912bdf21e6be516a028d25c2a548 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Tue, 17 Oct 2023 12:24:21 -0400 Subject: [PATCH 19/27] fix: removing use of newly introduced is_wp_user property. Relying instead on wp_user property which has already been used before. --- php/class-coauthors-plus.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/php/class-coauthors-plus.php b/php/class-coauthors-plus.php index 03eaae5d..006d035f 100644 --- a/php/class-coauthors-plus.php +++ b/php/class-coauthors-plus.php @@ -332,9 +332,8 @@ public function get_coauthor_by( $key, $value, $force = false ) { $guest_author = $this->guest_authors->get_guest_author_by( 'linked_account', $user->user_login ); if ( is_object( $guest_author ) ) { - $guest_author->is_wp_user = true; // Important not to lose the fact that this is a WP user. $guest_author->wp_user = $user; - $user = $guest_author; + $user = $guest_author; } return $user; @@ -1044,7 +1043,7 @@ public function add_coauthors( $post_id, $coauthors, $append = false, $query_typ if ( $coauthor_object instanceof WP_User ) { $new_author = $coauthor_object; break; - } else if ( isset( $coauthor_object->is_wp_user ) && $coauthor_object->is_wp_user ) { + } elseif ( isset( $coauthor_object->wp_user ) && $coauthor_object->wp_user instanceof WP_User ) { $new_author = $coauthor_object->wp_user; break; } From e3a120af125480fcc451682e80ab5072d5cd1356 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Tue, 17 Oct 2023 12:25:19 -0400 Subject: [PATCH 20/27] fix: PHPCS fixes and added commentary/descriptions to docblocks. --- php/class-coauthors-plus.php | 11 +++++++---- tests/Integration/CoAuthorsPlusTest.php | 15 ++++++++++----- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/php/class-coauthors-plus.php b/php/class-coauthors-plus.php index 006d035f..80f6af2e 100644 --- a/php/class-coauthors-plus.php +++ b/php/class-coauthors-plus.php @@ -320,7 +320,7 @@ public function get_coauthor_by( $key, $value, $force = false ) { return $guest_author; } else { - // Guest Author was not found, so let's see if we are searching for a WP_User + // Guest Author was not found, so let's see if we are searching for a WP_User. $user = $this->get_user_by( $key, $value ); if ( null === $user ) { @@ -352,7 +352,10 @@ public function get_coauthor_by( $key, $value, $force = false ) { } /** - * @param string $key Key to search by, i.e. 'id', 'login', 'user_login', 'email', 'user_email', 'user_nicename' + * Searches for authors by way of the WP_User table using a specific list of data points. If login or slug + * are provided as search parameters, this function will remove `cap-` from the search value, if present. + * + * @param string $key Key to search by, i.e. 'id', 'login', 'user_login', 'email', 'user_email', 'user_nicename'. * @param string $value Value to search for. * * @return WP_User|null @@ -375,10 +378,10 @@ protected function get_user_by( $key, $value ) { $user = get_user_by( $key, $value ); - if ( ! $user && ( 'login' == $key || 'slug' == $key ) ) { + if ( ! $user && ( 'login' === $key || 'slug' === $key ) ) { // Re-try lookup without prefixed value if no results found. $value = preg_replace( '#^cap\-#', '', $value ); - $user = get_user_by( $key, $value ); + $user = get_user_by( $key, $value ); } if ( false === $user ) { diff --git a/tests/Integration/CoAuthorsPlusTest.php b/tests/Integration/CoAuthorsPlusTest.php index bd80d2ad..7e7d1983 100644 --- a/tests/Integration/CoAuthorsPlusTest.php +++ b/tests/Integration/CoAuthorsPlusTest.php @@ -2,6 +2,9 @@ namespace Automattic\CoAuthorsPlus\Tests\Integration; +use WP_Query; +use WP_Term; + class CoAuthorsPlusTest extends TestCase { private $author1; @@ -725,16 +728,18 @@ public function test_assign_post_author_from_author_who_has_not_been_linked() { $post_id = $post->ID; $first_added_authors = $this->_cap->add_coauthors( $post_id, array( $this->author3->user_login ) ); + // add_coauthors should return true because CAP will treat this user as an Author with the + // extra step of setting wp_post.post_author equal to this user's wp_user.ID. $this->assertTrue( $first_added_authors ); - $query2 = new WP_Query( + $query1 = new WP_Query( array( - 'p' => $post_id + 'p' => $post_id, ) ); - $this->assertEquals( 1, $query2->found_posts ); - $this->assertEquals( $this->author3->ID, $query2->posts[0]->post_author ); + // Checking that the wp_post.post_author column has indeed been updated. + $this->assertEquals( $this->author3->ID, $query1->posts[0]->post_author ); $author3_term = $this->_cap->get_author_term( $this->author3 ); @@ -747,7 +752,7 @@ public function test_assign_post_author_from_author_who_has_not_been_linked() { $this->assertInstanceOf( WP_Term::class, $post_author_terms[0] ); $this->assertEquals( 'cap-' . $this->author3->user_login, $post_author_terms[0]->slug ); - // Confirming that now $author2 does have an author term + // Confirming that now $author2 does have an author term. $second_added_authors = $this->_cap->add_coauthors( $post_id, array( $this->author2->user_login ) ); $this->assertTrue( $second_added_authors ); $author2_term = $this->_cap->get_author_term( $this->author2 ); From 6afab358717e5929e01e9fc7709fe1cb924f73e5 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Wed, 25 Oct 2023 11:49:36 +0200 Subject: [PATCH 21/27] fix: some small quick fixes for formatting and documentation --- tests/Integration/CoAuthorsPlusTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/Integration/CoAuthorsPlusTest.php b/tests/Integration/CoAuthorsPlusTest.php index 7e7d1983..ef2cdb3f 100644 --- a/tests/Integration/CoAuthorsPlusTest.php +++ b/tests/Integration/CoAuthorsPlusTest.php @@ -772,7 +772,7 @@ public function test_assign_post_author_from_author_who_has_not_been_linked() { * * @return void */ - public function test_append_post_author_who_has_not_been_linked( ) { + public function test_append_post_author_who_has_not_been_linked() { $post_id = $this->factory()->post->create( array( 'post_author' => $this->author2->ID, @@ -781,6 +781,7 @@ public function test_append_post_author_who_has_not_been_linked( ) { ) ); + // Immediately update the co-authors, adding $author3 to the existing $author2. $this->_cap->add_coauthors( $post_id, array( $this->author3->user_login ), true ); $query = new WP_Query( @@ -790,6 +791,7 @@ public function test_append_post_author_who_has_not_been_linked( ) { ); $this->assertEquals( 1, $query->found_posts ); + // Although we added a co-author, the wp_posts.post_author column should still be attributed to $author2. $this->assertEquals( $this->author2->ID, $query->posts[0]->post_author ); $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); From de55e39c66d739fcba6e1d4cd1dbd85e1d4220ec Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Tue, 2 Jul 2024 18:14:09 -0400 Subject: [PATCH 22/27] fix: removing repetitive test. --- tests/Integration/CoAuthorsPlusTest.php | 211 ------------------------ 1 file changed, 211 deletions(-) diff --git a/tests/Integration/CoAuthorsPlusTest.php b/tests/Integration/CoAuthorsPlusTest.php index 15a4e149..016fa5ae 100644 --- a/tests/Integration/CoAuthorsPlusTest.php +++ b/tests/Integration/CoAuthorsPlusTest.php @@ -1917,217 +1917,6 @@ public function test_assign_multiple_post_authors_one_linked_passed_using_user_l $this->assertEquals( 'cap-' . $linked_author_1->user_login, $guest_author_term[0]->slug ); } - /** - * This test is a combination of a few different aspects that establish some expected plugin behavior. - * Two posts are created to test with. Both have no WP_User as the author (i.e. wp_posts.post_author = 0). - * For the first post: - * 1. A guest author is created, and assigned to the post. - * 2. Since there is no WP_User which is passed, and the GA is NOT being appended, the result should be false. - * 3. The wp_posts.post_author column should still be 0 since this is a GA and not a WP_User or a linked GA. - * - * For the second post: - * 1. A guest author is created, and appended to the post. - * 2. Since we are appending a coauthor, it does not matter if there was already a WP_User author, so result should be true. - * 3. The wp_posts.post_author column should still be 0 since this is a GA and not a WP_User or a linked GA. - * - * Going back to the first post: - * 1. A linked user and a WP_User are created and assigned to this post. - * 2. Result should be true since here we essentially have 2 WP_Users. - * 3. Since there is a WP_User, and it is passed first, the wp_posts.post_author column should be set to the ID for that WP_User. - * 4. There should only be 2 author terms for this post, one for the WP_User, and one for the linked account. - * The term for the GA which was previously assigned is deleted. - * - * Finally, going back to the second post: - * 1. A linked user and a WP_User are created and appended to this post. - * 2. Result should be true since we have 2 WP_Users. - * 3. Here we passed the linked author first, so the wp_posts.post_author column should match the ID for the linked WP_user account. - * 4. There should be 3 author terms for this post, one for the GA, the WP_user, and linked account. - * @return void - */ - public function test_assign_post_authors_from_post_with_no_author() { - $post_id_1 = $this->factory()->post->create( - array( - 'post_author' => 0, - 'post_status' => 'publish', - 'post_type' => 'post', - ) - ); - - $query = new WP_Query( - array( - 'p' => $post_id_1, - ) - ); - - $this->assertEquals( 1, $query->found_posts ); - $this->assertEquals( 0, $query->posts[0]->post_author ); - - $post_id_2 = $this->factory()->post->create( - array( - 'post_author' => 0, - 'post_status' => 'publish', - 'post_type' => 'post', - ) - ); - - $second_post_query = new WP_Query( - array( - 'p' => $post_id_2, - ) - ); - - $this->assertEquals( 1, $second_post_query->found_posts ); - $this->assertEquals( 0, $second_post_query->posts[0]->post_author ); - - $random_username = 'random_user_' . rand( 90000, 100000 ); - $display_name = str_replace( '_', ' ', $random_username ); - - $guest_author_1_id = $this->_cap->guest_authors->create( - array( - 'user_login' => $random_username, - 'display_name' => $display_name, - ) - ); - $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); - - $this->assertIsObject( $guest_author_1 ); - $this->assertThat( - $guest_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); - - $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); - - $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); - $this->assertIsObject( $linked_author_1 ); - $this->assertThat( - $linked_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); - $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); - $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); - $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); - $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); - - $result = $this->_cap->add_coauthors( - $post_id_1, - array( - $guest_author_1->user_login, - ) - ); - - $this->assertFalse( $result ); - - $post_1_author_terms = wp_get_post_terms( $post_id_1, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_1_author_terms ); - $this->assertCount( 1, $post_1_author_terms ); - $this->assertEquals( 'cap-' . $guest_author_1->user_login, $post_1_author_terms[0]->slug ); - - $third_post_query = new WP_Query( - array( - 'p' => $post_id_1, - ) - ); - - $this->assertEquals( 1, $third_post_query->found_posts ); - $this->assertEquals( 0, $third_post_query->posts[0]->post_author ); - - $result = $this->_cap->add_coauthors( - $post_id_2, - array( - $guest_author_1->user_login, - ), - true - ); - - $this->assertTrue( $result ); - - $fourth_post_query = new WP_Query( - array( - 'p' => $post_id_2, - ) - ); - - $this->assertEquals( 1, $fourth_post_query->found_posts ); - $this->assertEquals( 0, $fourth_post_query->posts[0]->post_author ); - - $result = $this->_cap->add_coauthors( - $post_id_1, - array( - $this->author2->user_login, - $linked_author_1->user_login, - ) - ); - - $this->assertTrue( $result ); - - $fifth_post_query = new WP_Query( - array( - 'p' => $post_id_1, - ) - ); - - $this->assertEquals( 1, $fifth_post_query->found_posts ); - $this->assertEquals( $this->author2->ID, $fifth_post_query->posts[0]->post_author ); - - $post_author_terms = wp_get_post_terms( $post_id_1, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 2, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author2->user_login, - 'cap-' . $linked_author_1->user_login, - ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } - - $result = $this->_cap->add_coauthors( - $post_id_2, - array( - $linked_author_1->user_login, - $this->author2->user_login, - ), - true - ); - - $this->assertTrue( $result ); - - $sixth_post_query = new WP_Query( - array( - 'p' => $post_id_2, - ) - ); - - $this->assertEquals( 1, $sixth_post_query->found_posts ); - $this->assertEquals( $this->author3->ID, $sixth_post_query->posts[0]->post_author ); - - $post_author_terms = wp_get_post_terms( $post_id_2, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 3, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $guest_author_1->user_login, - 'cap-' . $this->author2->user_login, - 'cap-' . $linked_author_1->user_login, - ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } - } - /** * @covers CoAuthors_Plus::is_block_editor() */ From 8dd6d6799f3e85b442c20cfc7bd8c31786c3ef40 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Wed, 3 Jul 2024 17:34:31 -0400 Subject: [PATCH 23/27] add: new assertion func that determines if an obj is not a WP_User class --- tests/Integration/CoAuthorsPlusTest.php | 192 ++++++------------------ 1 file changed, 45 insertions(+), 147 deletions(-) diff --git a/tests/Integration/CoAuthorsPlusTest.php b/tests/Integration/CoAuthorsPlusTest.php index 016fa5ae..d8c40356 100644 --- a/tests/Integration/CoAuthorsPlusTest.php +++ b/tests/Integration/CoAuthorsPlusTest.php @@ -704,6 +704,26 @@ public function test_update_author_term_when_author_term_not_exist(): void { $coauthors_plus->coauthor_taxonomy = $taxonomy_backup; } + /** + * Convenience function which makes sure an author object is not a WP_User. This is because we don't have + * an actual "Guest Author" object. + * + * @param object $author The author object. + * + * @return void + */ + public function assertIsGuestAuthorNotWpUser( object $author ): void { + // Perhaps we can further assert that the required properties exist on the object or is that overkill? + + $this->assertThat( + $author, + $this->logicalNot( + $this->isInstanceOf( WP_User::class ) + ) + ); + } + + /** * This is a basic test to ensure that any authors being assigned to a post * using the CoAuthors_Plus::add_coauthors() method are appropriately @@ -888,13 +908,7 @@ public function test_assign_post_authors_from_coauthors_who_have_not_been_linked */ $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); - $this->assertIsObject( $guest_author_1 ); - $this->assertThat( - $guest_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); $random_username = 'random_user_' . rand( 1001, 2000 ); $display_name = str_replace( '_', ' ', $random_username ); @@ -907,13 +921,7 @@ public function test_assign_post_authors_from_coauthors_who_have_not_been_linked ); $guest_author_2 = $this->_cap->get_coauthor_by( 'id', $guest_author_2_id ); - $this->assertIsObject( $guest_author_2 ); - $this->assertThat( - $guest_author_2, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_2 ); $post_id = $this->factory()->post->create( array( @@ -974,13 +982,7 @@ public function test_append_post_authors_from_coauthors_who_have_not_been_linked ); $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); - $this->assertIsObject( $guest_author_1 ); - $this->assertThat( - $guest_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); $random_username = 'random_user_' . rand( 1001, 2000 ); $display_name = str_replace( '_', ' ', $random_username ); @@ -993,13 +995,7 @@ public function test_append_post_authors_from_coauthors_who_have_not_been_linked ); $guest_author_2 = $this->_cap->get_coauthor_by( 'id', $guest_author_2_id ); - $this->assertIsObject( $guest_author_2 ); - $this->assertThat( - $guest_author_2, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_2 ); $post_id = $this->factory()->post->create( array( @@ -1074,13 +1070,7 @@ public function test_assign_coauthors_from_coauthors_and_user_who_have_not_been_ ); $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); - $this->assertIsObject( $guest_author_1 ); - $this->assertThat( - $guest_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); $post_id = $this->factory()->post->create( array( @@ -1152,13 +1142,7 @@ public function test_append_coauthors_from_coauthors_and_user_who_have_not_been_ ); $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); - $this->assertIsObject( $guest_author_1 ); - $this->assertThat( - $guest_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); $post_id = $this->factory()->post->create( array( @@ -1227,13 +1211,7 @@ public function test_assign_post_authors_from_coauthors_who_are_linked() { $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author2->ID ); - $this->assertIsObject( $linked_author_1 ); - $this->assertThat( - $linked_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); $this->assertTrue( property_exists( $linked_author_1, 'type' ) ); $this->assertEquals( 'guest-author', $linked_author_1->type ); $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); @@ -1243,13 +1221,7 @@ public function test_assign_post_authors_from_coauthors_who_are_linked() { $this->assertEquals( $this->author2->ID, $linked_author_1->wp_user->ID ); $linked_author_2 = $this->_cap->get_coauthor_by( 'user_login', $this->author3->user_login ); - $this->assertIsObject( $linked_author_2 ); - $this->assertThat( - $linked_author_2, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $linked_author_2 ); $this->assertTrue( property_exists( $linked_author_2, 'type' ) ); $this->assertEquals( 'guest-author', $linked_author_2->type ); $this->assertTrue( property_exists( $linked_author_2, 'is_wp_user' ) ); @@ -1329,24 +1301,12 @@ public function test_append_post_authors_from_coauthors_one_of_whom_is_linked() ); $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); - $this->assertIsObject( $guest_author_1 ); - $this->assertThat( - $guest_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); - $this->assertIsObject( $linked_author_1 ); - $this->assertThat( - $linked_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); $this->assertTrue( property_exists( $linked_author_1, 'type' ) ); $this->assertEquals( 'guest-author', $linked_author_1->type ); $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); @@ -1429,24 +1389,12 @@ public function test_assign_multiple_post_authors_wp_user_guest_author_linked_us ); $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); - $this->assertIsObject( $guest_author_1 ); - $this->assertThat( - $guest_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); - $this->assertIsObject( $linked_author_1 ); - $this->assertThat( - $linked_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); $post_id = $this->factory()->post->create( array( @@ -1520,13 +1468,7 @@ public function test_assign_multiple_post_authors_only_one_linked_passed_last() ); $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); - $this->assertIsObject( $guest_author_1 ); - $this->assertThat( - $guest_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); $random_username = 'random_user_' . rand( 1001, 2000 ); $display_name = str_replace( '_', ' ', $random_username ); @@ -1539,24 +1481,13 @@ public function test_assign_multiple_post_authors_only_one_linked_passed_last() ); $guest_author_2 = $this->_cap->get_coauthor_by( 'id', $guest_author_2_id ); - $this->assertIsObject( $guest_author_2 ); - $this->assertThat( - $guest_author_2, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_2 ); $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); - $this->assertIsObject( $linked_author_1 ); - $this->assertThat( - $linked_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); @@ -1638,24 +1569,13 @@ public function test_assign_multiple_post_authors_one_user_before_one_linked_pas ); $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); - $this->assertIsObject( $guest_author_1 ); - $this->assertThat( - $guest_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); - $this->assertIsObject( $linked_author_1 ); - $this->assertThat( - $linked_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); @@ -1735,24 +1655,13 @@ public function test_assign_multiple_post_authors_one_linked_passed_first() { ); $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); - $this->assertIsObject( $guest_author_1 ); - $this->assertThat( - $guest_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); - $this->assertIsObject( $linked_author_1 ); - $this->assertThat( - $linked_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); @@ -1832,24 +1741,13 @@ public function test_assign_multiple_post_authors_one_linked_passed_using_user_l ); $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); - $this->assertIsObject( $guest_author_1 ); - $this->assertThat( - $guest_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); - $this->assertIsObject( $linked_author_1 ); - $this->assertThat( - $linked_author_1, - $this->logicalNot( - $this->isInstanceOf( WP_User::class ) - ) - ); + $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); + $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); $this->assertTrue( $linked_author_1->is_wp_user ); $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); From db9a6d7c041431fd9a3b95ef4578254bca32aceb Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Wed, 3 Jul 2024 18:08:52 -0400 Subject: [PATCH 24/27] add: new assertion to help determine if a Post has the correct Authors --- tests/Integration/CoAuthorsPlusTest.php | 283 ++++++++++-------------- 1 file changed, 118 insertions(+), 165 deletions(-) diff --git a/tests/Integration/CoAuthorsPlusTest.php b/tests/Integration/CoAuthorsPlusTest.php index d8c40356..0405b6bd 100644 --- a/tests/Integration/CoAuthorsPlusTest.php +++ b/tests/Integration/CoAuthorsPlusTest.php @@ -2,6 +2,7 @@ namespace Automattic\CoAuthorsPlus\Tests\Integration; +use PHPUnit\Framework\InvalidArgumentException; use WP_Query; use WP_Term; @@ -723,6 +724,42 @@ public function assertIsGuestAuthorNotWpUser( object $author ): void { ); } + /** + * This function handles asserting that a post has the authors specified, and the correct number of authors. + * + * @param int $post_id The Post ID. + * @param array $authors The authors to check that are assigned to a post. + * + * @return void + * @throws InvalidArgumentException Throws exception if $authors is not a valid Guest Author or WP_User object or a string. + */ + public function assertPostHasCoAuthors( int $post_id, array $authors ) { + $authors = array_map( + function ( $author ) { + if ( is_object( $author ) ) { + return 'cap-' . $author->user_login; + } elseif ( is_string( $author ) ) { + return $author; // Assuming that caller is giving author slug. + } else { + throw InvalidArgumentException::create( 2, 'Authors should be string, Guest Author Object, or WP_User' ); + } + }, + $authors + ); + + $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); + + $this->assertIsArray( $post_author_terms ); + $this->assertSameSize( + $authors, + $post_author_terms + ); + + foreach ( $post_author_terms as $term ) { + $this->assertInstanceOf( WP_Term::class, $term ); + $this->assertContains( $term->slug, $authors ); + } + } /** * This is a basic test to ensure that any authors being assigned to a post @@ -814,20 +851,13 @@ public function test_append_post_author_who_has_not_been_linked() { // Although we added a co-author, the wp_posts.post_author column should still be attributed to $author2. $this->assertEquals( $this->author2->ID, $query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 2, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author2->user_login, - 'cap-' . $this->author3->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->author2->user_login, + $this->author3->user_login, + ] ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } } /** @@ -865,21 +895,14 @@ public function test_assign_post_authors_from_authors_who_have_not_been_linked() $this->assertEquals( 1, $query->found_posts ); $this->assertEquals( $this->author3->ID, $query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 3, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author3->user_login, - 'cap-' . $this->editor1->user_login, - 'cap-' . $this->author2->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->author3->user_login, + $this->editor1->user_login, + $this->author2->user_login, + ] ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } } /** @@ -1034,21 +1057,14 @@ public function test_append_post_authors_from_coauthors_who_have_not_been_linked $this->assertEquals( 1, $second_query->found_posts ); $this->assertEquals( $this->author1->ID, $second_query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 3, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author1->user_login, - 'cap-' . $guest_author_1->user_login, - 'cap-' . $guest_author_2->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->author1->user_login, + $guest_author_1->user_login, + $guest_author_2->user_login, + ] ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } } /** @@ -1108,20 +1124,13 @@ public function test_assign_coauthors_from_coauthors_and_user_who_have_not_been_ $this->assertEquals( 1, $second_query->found_posts ); $this->assertEquals( $this->author3->ID, $second_query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 2, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author3->user_login, - 'cap-' . $guest_author_1->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->author3->user_login, + $guest_author_1->user_login, + ] ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } } /** @@ -1181,21 +1190,14 @@ public function test_append_coauthors_from_coauthors_and_user_who_have_not_been_ $this->assertEquals( 1, $second_query->found_posts ); $this->assertEquals( $this->author1->ID, $second_query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 3, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author1->user_login, - 'cap-' . $this->author3->user_login, - 'cap-' . $guest_author_1->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->author1->user_login, + $this->author3->user_login, + $guest_author_1->user_login, + ] ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } } /** @@ -1266,20 +1268,13 @@ public function test_assign_post_authors_from_coauthors_who_are_linked() { $this->assertEquals( 1, $second_query->found_posts ); $this->assertEquals( $this->author2->ID, $second_query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 2, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author2->user_login, - 'cap-' . $this->author3->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->author2->user_login, + $this->author3->user_login, + ] ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } } /** @@ -1352,21 +1347,14 @@ public function test_append_post_authors_from_coauthors_one_of_whom_is_linked() $this->assertEquals( 1, $second_query->found_posts ); $this->assertEquals( $this->editor1->ID, $second_query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 3, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->editor1->user_login, - 'cap-' . $guest_author_1->user_login, - 'cap-' . $this->author3->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->editor1->user_login, + $guest_author_1->user_login, + $this->author3->user_login, + ] ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } } /** @@ -1433,21 +1421,14 @@ public function test_assign_multiple_post_authors_wp_user_guest_author_linked_us $this->assertEquals( 1, $second_query->found_posts ); $this->assertEquals( $this->author1->ID, $second_query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 3, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author1->user_login, - 'cap-' . $guest_author_1->user_login, - 'cap-' . $this->author3->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->author1->user_login, + $guest_author_1->user_login, + $this->author3->user_login, + ] ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } } /** @@ -1534,21 +1515,14 @@ public function test_assign_multiple_post_authors_only_one_linked_passed_last() $this->assertEquals( 1, $second_query->found_posts ); $this->assertEquals( $this->author3->ID, $second_query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 3, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author3->user_login, - 'cap-' . $guest_author_1->user_login, - 'cap-' . $guest_author_2->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->author3->user_login, + $guest_author_1->user_login, + $guest_author_2->user_login, + ] ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } } /** @@ -1619,21 +1593,14 @@ public function test_assign_multiple_post_authors_one_user_before_one_linked_pas $this->assertEquals( 1, $second_query->found_posts ); $this->assertEquals( $this->author2->ID, $second_query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 3, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author2->user_login, - 'cap-' . $this->author3->user_login, - 'cap-' . $guest_author_1->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->author2->user_login, + $this->author3->user_login, + $guest_author_1->user_login, + ] ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } } /** @@ -1705,21 +1672,14 @@ public function test_assign_multiple_post_authors_one_linked_passed_first() { $this->assertEquals( 1, $second_query->found_posts ); $this->assertEquals( $this->author3->ID, $second_query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 3, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author2->user_login, - 'cap-' . $this->author3->user_login, - 'cap-' . $guest_author_1->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->author2->user_login, + $this->author3->user_login, + $guest_author_1->user_login, + ] ); - - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } } /** @@ -1792,22 +1752,15 @@ public function test_assign_multiple_post_authors_one_linked_passed_using_user_l $this->assertEquals( 1, $second_query->found_posts ); $this->assertEquals( $this->author3->ID, $second_query->posts[0]->post_author ); - $post_author_terms = wp_get_post_terms( $post_id, $this->_cap->coauthor_taxonomy ); - - $this->assertIsArray( $post_author_terms ); - $this->assertCount( 3, $post_author_terms ); - - $author_slugs = array( - 'cap-' . $this->author2->user_login, - 'cap-' . $this->author3->user_login, - 'cap-' . $guest_author_1->user_login, + $this->assertPostHasCoAuthors( + $post_id, + [ + $this->author2->user_login, + $this->author3->user_login, + $guest_author_1->user_login, + ] ); - foreach ( $post_author_terms as $term ) { - $this->assertInstanceOf( WP_Term::class, $term ); - $this->assertContains( $term->slug, $author_slugs ); - } - $guest_author_term = wp_get_post_terms( $linked_author_1->ID, $this->_cap->coauthor_taxonomy ); $this->assertIsArray( $guest_author_term ); From bbfc79a0c8fac43ecf2c917af7798cda01066ac6 Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Thu, 4 Jul 2024 11:47:36 -0400 Subject: [PATCH 25/27] add: new test solely for CoAuthorPlus::get_coauthor_by(). By fully testing CoAuthorPlus::get_coauthor_by(), we can remove some repetitive assertions that don't directly relate to what's being tested. --- tests/Integration/CoAuthorsPlusTest.php | 143 ++++++++++++++++-------- 1 file changed, 94 insertions(+), 49 deletions(-) diff --git a/tests/Integration/CoAuthorsPlusTest.php b/tests/Integration/CoAuthorsPlusTest.php index 0405b6bd..89c27f76 100644 --- a/tests/Integration/CoAuthorsPlusTest.php +++ b/tests/Integration/CoAuthorsPlusTest.php @@ -5,6 +5,7 @@ use PHPUnit\Framework\InvalidArgumentException; use WP_Query; use WP_Term; +use WP_User; class CoAuthorsPlusTest extends TestCase { @@ -144,26 +145,26 @@ public function test_get_coauthor_by_when_guest_authors_not_enabled(): void { $coauthor = $coauthors_plus->get_coauthor_by( 'id', $this->author1->ID ); - $this->assertInstanceOf( \WP_User::class, $coauthor ); + $this->assertInstanceOf( WP_User::class, $coauthor ); $this->assertObjectHasProperty( 'ID', $coauthor ); $this->assertEquals( $this->author1->ID, $coauthor->ID ); $this->assertEquals( 'wpuser', $coauthor->type ); $coauthor = $coauthors_plus->get_coauthor_by( 'user_login', $this->author1->user_login ); - $this->assertInstanceOf( \WP_User::class, $coauthor ); + $this->assertInstanceOf( WP_User::class, $coauthor ); $this->assertObjectHasProperty( 'user_login', $coauthor->data ); $this->assertEquals( $this->author1->user_login, $coauthor->user_login ); $coauthor = $coauthors_plus->get_coauthor_by( 'user_nicename', $this->author1->user_nicename ); - $this->assertInstanceOf( \WP_User::class, $coauthor ); + $this->assertInstanceOf( WP_User::class, $coauthor ); $this->assertObjectHasProperty( 'user_nicename', $coauthor->data ); $this->assertEquals( $this->author1->user_nicename, $coauthor->user_nicename ); $coauthor = $coauthors_plus->get_coauthor_by( 'user_email', $this->author1->user_email ); - $this->assertInstanceOf( \WP_User::class, $coauthor ); + $this->assertInstanceOf( WP_User::class, $coauthor ); $this->assertObjectHasProperty( 'user_email', $coauthor->data ); $this->assertEquals( $this->author1->user_email, $coauthor->user_email ); @@ -761,6 +762,95 @@ function ( $author ) { } } + /** + * This test fully validates the expected behavior of the @return void + * @see CoAuthorPlus::get_coauthor_by function. + * + */ + public function test_get_coauthor_by() { + $author = $this->factory()->user->create_and_get( + [ + 'role' => 'author', + 'user_login' => 'i_am_batman', + 'display_name' => 'Bruce Wayne', + 'first_name' => 'Bruce', + 'last_name' => 'Wayne', + ] + ); + + $first_author_retrieval = $this->_cap->get_coauthor_by( 'user_nicename', $author->user_nicename ); + $this->assertInstanceOf( WP_User::class, $first_author_retrieval ); + $this->assertEquals( + $author->ID, + $first_author_retrieval->ID + ); + + $maybe_guest_author_id = $this->_cap->guest_authors->create_guest_author_from_user_id( $author->ID ); + + $this->assertIsInt( $maybe_guest_author_id ); + + $guest_author = $this->_cap->guest_authors->get_guest_author_by( 'id', $maybe_guest_author_id, true ); + + $this->assertIsGuestAuthorNotWpUser( $guest_author ); + $this->assertNotSame( $author->user_login, $guest_author->user_login ); + $this->assertNotSame( $author->user_nicename, $guest_author->user_nicename ); + $this->assertObjectHasProperty( 'type', $guest_author ); + $this->assertEquals( 'guest-author', $guest_author->type ); + + $third_author_retrieval = $this->_cap->get_coauthor_by( 'user_nicename', $guest_author->user_nicename ); + $this->assertIsGuestAuthorNotWpUser( $third_author_retrieval ); + $this->assertObjectHasProperty( 'wp_user', $third_author_retrieval ); + $this->assertInstanceOf( WP_User::class, $third_author_retrieval->wp_user ); + $this->assertEquals( $author->ID, $third_author_retrieval->wp_user->ID ); + + $fourth_author_retrieval = $this->_cap->get_coauthor_by( 'user_nicename', $author->user_nicename ); + $this->assertIsGuestAuthorNotWpUser( $fourth_author_retrieval ); + $this->assertEquals( 'guest-author', $fourth_author_retrieval->type ); + $this->assertObjectHasProperty( 'wp_user', $fourth_author_retrieval ); + $this->assertInstanceOf( WP_User::class, $fourth_author_retrieval->wp_user ); + $this->assertEquals( $author->data->ID, $fourth_author_retrieval->wp_user->data->ID ); + $this->assertEquals( $author->data->user_login, $fourth_author_retrieval->wp_user->data->user_login ); + $this->assertEquals( $author->data->user_nicename, $fourth_author_retrieval->wp_user->data->user_nicename ); + + $random_username = 'random_user_' . wp_rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); + + $this->_cap->guest_authors->create( + [ + 'user_login' => $random_username, + 'display_name' => $display_name, + ] + ); + $fifth_author_retrieval = $this->_cap->get_coauthor_by( 'user_login', $random_username ); + $this->assertIsGuestAuthorNotWpUser( $fifth_author_retrieval ); + $this->assertObjectNotHasProperty( 'wp_user', $fifth_author_retrieval ); + + // Simulating a broken linked_account relationship. + $random_login = 'random_user_' . wp_rand( 1001, 2000 ); + update_post_meta( $fifth_author_retrieval->ID, 'cap-linked_account', $random_login ); + $fifth_author_retrieval = $this->_cap->get_coauthor_by( 'user_login', $random_username ); + $this->assertObjectHasProperty( 'linked_account', $fifth_author_retrieval ); + $this->assertEquals( $random_login, $fifth_author_retrieval->linked_account ); + $this->assertObjectNotHasProperty( 'wp_user', $fifth_author_retrieval ); + + add_filter( 'coauthors_guest_authors_enabled', '__return_false' ); + + $sixth_author_retrieval = $this->_cap->get_coauthor_by( 'user_nicename', $guest_author->user_nicename ); + + $this->assertFalse( $sixth_author_retrieval ); + + $seventh_author_retrieval = $this->_cap->get_coauthor_by( 'user_nicename', $author->user_nicename ); + + $this->assertInstanceOf( WP_User::class, $seventh_author_retrieval ); + $this->assertEquals( $author->data->ID, $seventh_author_retrieval->data->ID ); + $this->assertEquals( $author->data->user_login, $seventh_author_retrieval->data->user_login ); + $this->assertEquals( $author->data->user_nicename, $seventh_author_retrieval->data->user_nicename ); + + $eigth_author_retrieval = $this->_cap->get_coauthor_by( 'user_login', $random_username ); + + $this->assertFalse( $eigth_author_retrieval ); + } + /** * This is a basic test to ensure that any authors being assigned to a post * using the CoAuthors_Plus::add_coauthors() method are appropriately @@ -1214,23 +1304,9 @@ public function test_assign_post_authors_from_coauthors_who_are_linked() { $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author2->ID ); $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); - $this->assertTrue( property_exists( $linked_author_1, 'type' ) ); - $this->assertEquals( 'guest-author', $linked_author_1->type ); - $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); - $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); - $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); - $this->assertEquals( $this->author2->ID, $linked_author_1->wp_user->ID ); $linked_author_2 = $this->_cap->get_coauthor_by( 'user_login', $this->author3->user_login ); $this->assertIsGuestAuthorNotWpUser( $linked_author_2 ); - $this->assertTrue( property_exists( $linked_author_2, 'type' ) ); - $this->assertEquals( 'guest-author', $linked_author_2->type ); - $this->assertTrue( property_exists( $linked_author_2, 'is_wp_user' ) ); - $this->assertTrue( $linked_author_2->is_wp_user ); - $this->assertTrue( property_exists( $linked_author_2, 'wp_user' ) ); - $this->assertInstanceOf( WP_User::class, $linked_author_2->wp_user ); - $this->assertEquals( $this->author3->ID, $linked_author_2->wp_user->ID ); $post_id = $this->factory()->post->create( array( @@ -1302,13 +1378,6 @@ public function test_append_post_authors_from_coauthors_one_of_whom_is_linked() $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); - $this->assertTrue( property_exists( $linked_author_1, 'type' ) ); - $this->assertEquals( 'guest-author', $linked_author_1->type ); - $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); - $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); - $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); - $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); $post_id = $this->factory()->post->create( array( @@ -1469,12 +1538,6 @@ public function test_assign_multiple_post_authors_only_one_linked_passed_last() $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); - $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); - $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); - $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); - $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); - $post_id = $this->factory()->post->create( array( 'post_author' => $this->editor1->ID, @@ -1550,12 +1613,6 @@ public function test_assign_multiple_post_authors_one_user_before_one_linked_pas $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); - $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); - $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); - $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); - $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); - $post_id = $this->factory()->post->create( array( 'post_author' => $this->editor1->ID, @@ -1629,12 +1686,6 @@ public function test_assign_multiple_post_authors_one_linked_passed_first() { $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); - $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); - $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); - $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); - $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); - $post_id = $this->factory()->post->create( array( 'post_author' => $this->editor1->ID, @@ -1708,12 +1759,6 @@ public function test_assign_multiple_post_authors_one_linked_passed_using_user_l $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); - $this->assertTrue( property_exists( $linked_author_1, 'is_wp_user' ) ); - $this->assertTrue( $linked_author_1->is_wp_user ); - $this->assertTrue( property_exists( $linked_author_1, 'wp_user' ) ); - $this->assertInstanceOf( WP_User::class, $linked_author_1->wp_user ); - $this->assertEquals( $this->author3->ID, $linked_author_1->wp_user->ID ); - $post_id = $this->factory()->post->create( array( 'post_author' => $this->editor1->ID, From 312d519ba3482f02bdc4591eee400b07d6a317ac Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Thu, 4 Jul 2024 13:47:04 -0400 Subject: [PATCH 26/27] fix: was passing string values when I should've been passing Author objs --- tests/Integration/CoAuthorsPlusTest.php | 66 ++++++++++++------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/tests/Integration/CoAuthorsPlusTest.php b/tests/Integration/CoAuthorsPlusTest.php index 89c27f76..25172ed6 100644 --- a/tests/Integration/CoAuthorsPlusTest.php +++ b/tests/Integration/CoAuthorsPlusTest.php @@ -944,8 +944,8 @@ public function test_append_post_author_who_has_not_been_linked() { $this->assertPostHasCoAuthors( $post_id, [ - $this->author2->user_login, - $this->author3->user_login, + $this->author2, + $this->author3, ] ); } @@ -988,9 +988,9 @@ public function test_assign_post_authors_from_authors_who_have_not_been_linked() $this->assertPostHasCoAuthors( $post_id, [ - $this->author3->user_login, - $this->editor1->user_login, - $this->author2->user_login, + $this->author3, + $this->editor1, + $this->author2, ] ); } @@ -1150,9 +1150,9 @@ public function test_append_post_authors_from_coauthors_who_have_not_been_linked $this->assertPostHasCoAuthors( $post_id, [ - $this->author1->user_login, - $guest_author_1->user_login, - $guest_author_2->user_login, + $this->author1, + $guest_author_1, + $guest_author_2, ] ); } @@ -1217,8 +1217,8 @@ public function test_assign_coauthors_from_coauthors_and_user_who_have_not_been_ $this->assertPostHasCoAuthors( $post_id, [ - $this->author3->user_login, - $guest_author_1->user_login, + $this->author3, + $guest_author_1, ] ); } @@ -1283,9 +1283,9 @@ public function test_append_coauthors_from_coauthors_and_user_who_have_not_been_ $this->assertPostHasCoAuthors( $post_id, [ - $this->author1->user_login, - $this->author3->user_login, - $guest_author_1->user_login, + $this->author1, + $this->author3, + $guest_author_1, ] ); } @@ -1347,8 +1347,8 @@ public function test_assign_post_authors_from_coauthors_who_are_linked() { $this->assertPostHasCoAuthors( $post_id, [ - $this->author2->user_login, - $this->author3->user_login, + $this->author2, + $this->author3, ] ); } @@ -1419,9 +1419,9 @@ public function test_append_post_authors_from_coauthors_one_of_whom_is_linked() $this->assertPostHasCoAuthors( $post_id, [ - $this->editor1->user_login, - $guest_author_1->user_login, - $this->author3->user_login, + $this->editor1, + $guest_author_1, + $this->author3, ] ); } @@ -1493,9 +1493,9 @@ public function test_assign_multiple_post_authors_wp_user_guest_author_linked_us $this->assertPostHasCoAuthors( $post_id, [ - $this->author1->user_login, - $guest_author_1->user_login, - $this->author3->user_login, + $this->author1, + $guest_author_1, + $this->author3, ] ); } @@ -1581,9 +1581,9 @@ public function test_assign_multiple_post_authors_only_one_linked_passed_last() $this->assertPostHasCoAuthors( $post_id, [ - $this->author3->user_login, - $guest_author_1->user_login, - $guest_author_2->user_login, + $this->author3, + $guest_author_1, + $guest_author_2, ] ); } @@ -1653,9 +1653,9 @@ public function test_assign_multiple_post_authors_one_user_before_one_linked_pas $this->assertPostHasCoAuthors( $post_id, [ - $this->author2->user_login, - $this->author3->user_login, - $guest_author_1->user_login, + $this->author2, + $this->author3, + $guest_author_1, ] ); } @@ -1726,9 +1726,9 @@ public function test_assign_multiple_post_authors_one_linked_passed_first() { $this->assertPostHasCoAuthors( $post_id, [ - $this->author2->user_login, - $this->author3->user_login, - $guest_author_1->user_login, + $this->author2, + $this->author3, + $guest_author_1, ] ); } @@ -1800,9 +1800,9 @@ public function test_assign_multiple_post_authors_one_linked_passed_using_user_l $this->assertPostHasCoAuthors( $post_id, [ - $this->author2->user_login, - $this->author3->user_login, - $guest_author_1->user_login, + $this->author2, + $this->author3, + $guest_author_1, ] ); From 961ce40a3b304fe2a0245ebb08fb49e61425a24f Mon Sep 17 00:00:00 2001 From: Eddie Carrasco Date: Wed, 2 Oct 2024 17:48:51 -0400 Subject: [PATCH 27/27] fix: using a data provider for very similar tests --- tests/Integration/CoAuthorsPlusTest.php | 254 +++++++++++++++--------- 1 file changed, 165 insertions(+), 89 deletions(-) diff --git a/tests/Integration/CoAuthorsPlusTest.php b/tests/Integration/CoAuthorsPlusTest.php index 25172ed6..8e13807e 100644 --- a/tests/Integration/CoAuthorsPlusTest.php +++ b/tests/Integration/CoAuthorsPlusTest.php @@ -1290,94 +1290,125 @@ public function test_append_coauthors_from_coauthors_and_user_who_have_not_been_ ); } + /** + * Provides the different permutations of assigning authors to a post. + * + * @return array[] + */ + public function provide_data_for_assign_post_authors_test() { + return [ + 'setting_linked_coauthors' => [ + 'author_set' => [ + 'author_1' => 'linked', + 'author_2' => 'linked', + ], + 'all_authors_linked' => true, + 'append' => false, + ], + 'appending_linked_coauthors' => [ + 'author_set' => [ + 'author_1' => 'linked', + 'author_2' => 'linked', + ], + 'all_authors_linked' => true, + 'append' => true, + ], + 'setting_linked_and_unlinked_coauthors' => [ + 'author_set' => [ + 'author_1' => 'guest', + 'author_2' => 'linked', + ], + 'all_authors_linked' => false, + 'append' => false, + ], + 'appending_linked_and_unlinked_coauthors' => [ + 'author_set' => [ + 'author_1' => 'linked', + 'author_2' => 'guest', + ], + 'all_authors_linked' => false, + 'append' => true, + ], + 'setting_unlinked_coauthors' => [ + 'author_set' => [ + 'author_1' => 'user', + 'author_2' => 'guest', + ], + 'all_authors_linked' => false, + 'append' => false, + ], + 'appending_unlinked_coauthors' => [ + 'author_set' => [ + 'author_1' => 'guest', + 'author_2' => 'user', + ], + 'all_authors_linked' => false, + 'append' => true, + ], + ]; + } + /** * This is where we test many moving parts of the CoAuthorsPlugin all at once. We are creating a guest author from a * WP_User, and then assigning that guest author to a post. Since the guest author is linked to a WP_User, the * function CoAuthors_Plus::get_coauthor_by() should return a guest author object along with meta data * indicating that the object is linked to a WP_User. The wp_posts.post_author column should change, * and the response from CoAuthors_Plus::add_coauthors() should be true. + * @dataProvider provide_data_for_assign_post_authors_test * @return void */ - public function test_assign_post_authors_from_coauthors_who_are_linked() { - $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author2->ID ); - $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); + public function test_assign_post_authors_from_coauthors( $author_set, $all_authors_linked, $append ) { + $coauthors = []; - $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author2->ID ); - $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); + foreach ( $author_set as $author_key => $link_type ) { + if ( in_array( $link_type, [ 'linked', 'user' ], true ) ) { + $author = $this->factory()->user->create_and_get( + [ + 'role' => 'author', + 'user_login' => wp_rand( 1, 1000 ) . '_author_' . $author_key, + 'display_name' => 'Author ' . $author_key, + 'first_name' => 'Author', + 'last_name' => $author_key, + ] + ); - $linked_author_2 = $this->_cap->get_coauthor_by( 'user_login', $this->author3->user_login ); - $this->assertIsGuestAuthorNotWpUser( $linked_author_2 ); + if ( 'linked' === $link_type ) { - $post_id = $this->factory()->post->create( - array( - 'post_author' => $this->editor1->ID, - 'post_status' => 'publish', - 'post_type' => 'post', - ) - ); + $this->_cap->guest_authors->create_guest_author_from_user_id( $author->ID ); - $query = new WP_Query( - array( - 'p' => $post_id, - ) - ); + $linked_author = $this->_cap->get_coauthor_by( 'id', $author->ID ); - $this->assertEquals( 1, $query->found_posts ); - $this->assertEquals( $this->editor1->ID, $query->posts[0]->post_author ); + $this->assertIsGuestAuthorNotWpUser( $linked_author ); - $result = $this->_cap->add_coauthors( - $post_id, - array( - $linked_author_1->user_login, - $linked_author_2->user_login, - ) - ); - - $this->assertTrue( $result ); - - $second_query = new WP_Query( - array( - 'p' => $post_id, - ) - ); - - $this->assertEquals( 1, $second_query->found_posts ); - $this->assertEquals( $this->author2->ID, $second_query->posts[0]->post_author ); - - $this->assertPostHasCoAuthors( - $post_id, - [ - $this->author2, - $this->author3, - ] - ); - } - - /** - * Very similar test as before. The only difference is that we are appending, - * so the wp_posts.post_author column should not change, but we should - * see 3 WP_Terms for the authors now. - * - * @return void - */ - public function test_append_post_authors_from_coauthors_one_of_whom_is_linked() { - $random_username = 'random_user_' . rand( 1, 1000 ); - $display_name = str_replace( '_', ' ', $random_username ); + $coauthors[] = [ + 'user' => $author, + 'coauthor' => $linked_author, + ]; + } else { + $coauthors[] = [ + 'user' => $author, + ]; + } + } else { + $random_username = 'random_user_' . wp_rand( 1001, 2000 ); + $display_name = str_replace( '_', ' ', $random_username ); - $guest_author_1_id = $this->_cap->guest_authors->create( - array( - 'user_login' => $random_username, - 'display_name' => $display_name, - ) - ); - $guest_author_1 = $this->_cap->get_coauthor_by( 'id', $guest_author_1_id ); + $guest_author_id = $this->_cap->guest_authors->create( + [ + 'user_login' => $random_username, + 'display_name' => $display_name, + ] + ); - $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); + $guest_author = $this->_cap->get_coauthor_by( 'id', $guest_author_id ); - $this->_cap->guest_authors->create_guest_author_from_user_id( $this->author3->ID ); + $this->assertIsGuestAuthorNotWpUser( $guest_author ); - $linked_author_1 = $this->_cap->get_coauthor_by( 'id', $this->author3->ID ); - $this->assertIsGuestAuthorNotWpUser( $linked_author_1 ); + $coauthors[] = [ + 'coauthor' => $guest_author, + ]; + } + } $post_id = $this->factory()->post->create( array( @@ -1398,11 +1429,17 @@ public function test_append_post_authors_from_coauthors_one_of_whom_is_linked() $result = $this->_cap->add_coauthors( $post_id, - array( - $guest_author_1->user_login, - $linked_author_1->user_login, + array_map( + function ( $coauthor ) { + if ( isset( $coauthor['coauthor'] ) ) { + return $coauthor['coauthor']->user_login; + } + + return $coauthor['user']->user_login; + }, + $coauthors ), - true + $append ); $this->assertTrue( $result ); @@ -1414,16 +1451,55 @@ public function test_append_post_authors_from_coauthors_one_of_whom_is_linked() ); $this->assertEquals( 1, $second_query->found_posts ); - $this->assertEquals( $this->editor1->ID, $second_query->posts[0]->post_author ); - $this->assertPostHasCoAuthors( - $post_id, - [ - $this->editor1, - $guest_author_1, - $this->author3, - ] + $assigned_authors = array_map( + function ( $coauthor ) { + if ( isset( $coauthor['coauthor'] ) ) { + return $coauthor['coauthor']; + } + + return $coauthor['user']; + }, + $coauthors ); + + $first_user_account = null; + foreach ( $coauthors as $coauthor ) { + if ( isset( $coauthor['user'] ) ) { + $first_user_account = $coauthor['user']; + break; + } + } + + if ( $all_authors_linked ) { + if ( $append ) { + $this->assertEquals( $this->editor1->ID, $second_query->posts[0]->post_author ); + $this->assertPostHasCoAuthors( $post_id, array_merge( [ $this->editor1 ], $assigned_authors ) ); + } else { + if ( $first_user_account ) { + $this->assertEquals( $first_user_account->ID, $second_query->posts[0]->post_author ); + } + $this->assertPostHasCoAuthors( $post_id, $assigned_authors ); + } + } else { + if ( $append ) { + $this->assertEquals( $this->editor1->ID, $second_query->posts[0]->post_author ); + $this->assertPostHasCoAuthors( + $post_id, + array_merge( + [ + $this->editor1, + ], + $assigned_authors + ) + ); + } else { + if ( $first_user_account ) { + $this->assertEquals( $first_user_account->ID, $second_query->posts[0]->post_author ); + } + $this->assertPostHasCoAuthors( $post_id, $assigned_authors ); + } + } } /** @@ -1435,8 +1511,8 @@ public function test_append_post_authors_from_coauthors_one_of_whom_is_linked() * @return void */ public function test_assign_multiple_post_authors_wp_user_guest_author_linked_user( ) { - $random_username = 'random_user_' . rand( 1, 1000 ); - $display_name = str_replace( '_', ' ', $random_username ); + $random_username = 'random_user_' . wp_rand( 1, 1000 ); + $display_name = str_replace( '_', ' ', $random_username ); $guest_author_1_id = $this->_cap->guest_authors->create( array( @@ -1507,7 +1583,7 @@ public function test_assign_multiple_post_authors_wp_user_guest_author_linked_us * @return void */ public function test_assign_multiple_post_authors_only_one_linked_passed_last() { - $random_username = 'random_user_' . rand( 1, 1000 ); + $random_username = 'random_user_' . wp_rand( 1, 1000 ); $display_name = str_replace( '_', ' ', $random_username ); $guest_author_1_id = $this->_cap->guest_authors->create( @@ -1520,7 +1596,7 @@ public function test_assign_multiple_post_authors_only_one_linked_passed_last() $this->assertIsGuestAuthorNotWpUser( $guest_author_1 ); - $random_username = 'random_user_' . rand( 1001, 2000 ); + $random_username = 'random_user_' . wp_rand( 1001, 2000 ); $display_name = str_replace( '_', ' ', $random_username ); $guest_author_2_id = $this->_cap->guest_authors->create( @@ -1595,7 +1671,7 @@ public function test_assign_multiple_post_authors_only_one_linked_passed_last() * @return void */ public function test_assign_multiple_post_authors_one_user_before_one_linked_passed_last() { - $random_username = 'random_user_' . rand( 1, 1000 ); + $random_username = 'random_user_' . wp_rand( 1, 1000 ); $display_name = str_replace( '_', ' ', $random_username ); $guest_author_1_id = $this->_cap->guest_authors->create( @@ -1668,7 +1744,7 @@ public function test_assign_multiple_post_authors_one_user_before_one_linked_pas * @return void */ public function test_assign_multiple_post_authors_one_linked_passed_first() { - $random_username = 'random_user_' . rand( 1, 1000 ); + $random_username = 'random_user_' . wp_rand( 1, 1000 ); $display_name = str_replace( '_', ' ', $random_username ); $guest_author_1_id = $this->_cap->guest_authors->create( @@ -1741,7 +1817,7 @@ public function test_assign_multiple_post_authors_one_linked_passed_first() { * @return void */ public function test_assign_multiple_post_authors_one_linked_passed_using_user_login_to_assign() { - $random_username = 'random_user_' . rand( 1, 1000 ); + $random_username = 'random_user_' . wp_rand( 1, 1000 ); $display_name = str_replace( '_', ' ', $random_username ); $guest_author_1_id = $this->_cap->guest_authors->create(