insertUser($random_number); $subscriber = Subscriber::createOrUpdate([ 'email' => 'user-sync-test' . $random_number . '@example.com', 'status' => Subscriber::STATUS_SUBSCRIBED, 'wp_user_id' => $id, ]); WP::synchronizeUser($id); $db_subscriber = Subscriber::findOne($subscriber->id); expect($db_subscriber->status)->equals(Subscriber::STATUS_SUBSCRIBED); } function testSynchronizeUserStatusIsSubscribedForNewUserWithSignUpConfirmationDisabled() { $this->settings->set('signup_confirmation', ['enabled' => '0']); $random_number = rand(); $id = $this->insertUser($random_number); WP::synchronizeUser($id); $wp_subscriber = Segment::getWPSegment()->subscribers()->where('wp_user_id', $id)->findOne(); expect($wp_subscriber->status)->equals(Subscriber::STATUS_SUBSCRIBED); } function testSynchronizeUserStatusIsUnconfirmedForNewUserWithSignUpConfirmationEnabled() { $this->settings->set('signup_confirmation', ['enabled' => '1']); $random_number = rand(); $id = $this->insertUser($random_number); WP::synchronizeUser($id); $wp_subscriber = Segment::getWPSegment()->subscribers()->where('wp_user_id', $id)->findOne(); expect($wp_subscriber->status)->equals(Subscriber::STATUS_UNCONFIRMED); } function testSynchronizeUsersStatusIsSubscribedForNewUsersWithSignUpConfirmationDisabled() { $this->settings->set('signup_confirmation', ['enabled' => '0']); $this->insertUser(); $this->insertUser(); WP::synchronizeUsers(); $subscribers = Subscriber::whereLike("email", "user-sync-test%")->findMany(); expect(count($subscribers))->equals(2); expect($subscribers[0]->status)->equals(Subscriber::STATUS_SUBSCRIBED); expect($subscribers[1]->status)->equals(Subscriber::STATUS_SUBSCRIBED); } function testSynchronizeUsersStatusIsUnconfirmedForNewUsersWithSignUpConfirmationEnabled() { $this->settings->set('signup_confirmation', ['enabled' => '1']); $this->insertUser(); $this->insertUser(); WP::synchronizeUsers(); $subscribers = Subscriber::whereLike("email", "user-sync-test%")->findMany(); expect(count($subscribers))->equals(2); expect($subscribers[0]->status)->equals(Subscriber::STATUS_UNCONFIRMED); expect($subscribers[1]->status)->equals(Subscriber::STATUS_UNCONFIRMED); } function testItSynchronizeNewUsers() { $this->insertUser(); $this->insertUser(); WP::synchronizeUsers(); $this->insertUser(); WP::synchronizeUsers(); $subscribersCount = $this->getSubscribersCount(); expect($subscribersCount)->equals(3); } function testItSynchronizesPresubscribedUsers() { $random_number = 12345; $subscriber = Subscriber::createOrUpdate([ 'email' => 'user-sync-test' . $random_number . '@example.com', 'status' => Subscriber::STATUS_SUBSCRIBED, ]); $id = $this->insertUser($random_number); WP::synchronizeUsers(); $wp_subscriber = Segment::getWPSegment()->subscribers()->where('wp_user_id', $id)->findOne(); expect($wp_subscriber)->notEmpty(); expect($wp_subscriber->id)->equals($subscriber->id); expect($wp_subscriber->status)->equals(Subscriber::STATUS_SUBSCRIBED); } function testItSynchronizeEmails() { $id = $this->insertUser(); WP::synchronizeUsers(); $this->updateWPUserEmail($id, 'user-sync-test-xx@email.com'); WP::synchronizeUsers(); $subscriber = Subscriber::where('wp_user_id', $id)->findOne(); expect($subscriber->email)->equals('user-sync-test-xx@email.com'); } function testRemovesUsersWithEmptyEmailsFromSunscribersDuringSynchronization() { $id = $this->insertUser(); WP::synchronizeUsers(); $this->updateWPUserEmail($id, ''); WP::synchronizeUsers(); expect(Subscriber::where('wp_user_id', $id)->count())->equals(0); $this->deleteWPUser($id); } function testRemovesUsersWithInvalidEmailsFromSunscribersDuringSynchronization() { $id = $this->insertUser(); WP::synchronizeUsers(); $this->updateWPUserEmail($id, 'ivalid.@email.com'); WP::synchronizeUsers(); expect(Subscriber::where('wp_user_id', $id)->count())->equals(0); $this->deleteWPUser($id); } function testItDoesNotSynchronizeEmptyEmailsForNewUsers() { $id = $this->insertUser(); $this->updateWPUserEmail($id, ''); WP::synchronizeUsers(); $subscriber = Subscriber::where('wp_user_id', $id)->findOne(); expect($subscriber)->isEmpty(); $this->deleteWPUser($id); } function testItSynchronizeFirstNames() { $id = $this->insertUser(); WP::synchronizeUsers(); update_user_meta($id, 'first_name', 'First name'); WP::synchronizeUsers(); $subscriber = Subscriber::where('wp_user_id', $id)->findOne(); expect($subscriber->first_name)->equals('First name'); } function testItSynchronizeLastNames() { $id = $this->insertUser(); WP::synchronizeUsers(); update_user_meta($id, 'last_name', 'Last name'); WP::synchronizeUsers(); $subscriber = Subscriber::where('wp_user_id', $id)->findOne(); expect($subscriber->last_name)->equals('Last name'); } function testItSynchronizeFirstNamesUsingDisplayName() { $id = $this->insertUser(); WP::synchronizeUsers(); $this->updateWPUserDisplayName($id, 'First name'); WP::synchronizeUsers(); $subscriber = Subscriber::where('wp_user_id', $id)->findOne(); expect($subscriber->first_name)->equals('First name'); } function testItSynchronizeFirstNamesFromMetaNotDisplayName() { $id = $this->insertUser(); update_user_meta($id, 'first_name', 'First name'); $this->updateWPUserDisplayName($id, 'display_name'); WP::synchronizeUsers(); $subscriber = Subscriber::where('wp_user_id', $id)->findOne(); expect($subscriber->first_name)->equals('First name'); } function testItSynchronizeSegment() { $this->insertUser(); $this->insertUser(); $this->insertUser(); WP::synchronizeUsers(); $subscribers = Segment::getWPSegment()->subscribers()->whereIn('wp_user_id', $this->userIds); expect($subscribers->count())->equals(3); } function testItRemovesUsersFromTrash() { $id = $this->insertUser(); WP::synchronizeUsers(); $subscriber = Subscriber::where("wp_user_id", $id)->findOne(); $subscriber->deleted_at = Carbon::now(); $subscriber->save(); WP::synchronizeUsers(); $subscriber = Subscriber::where("wp_user_id", $id)->findOne(); expect($subscriber->deleted_at)->null(); } function testItSynchronizesDeletedWPUsersUsingHooks() { $id = $this->insertUser(); $this->insertUser(); WP::synchronizeUsers(); $subscribersCount = $this->getSubscribersCount(); expect($subscribersCount)->equals(2); wp_delete_user($id); $subscribersCount = $this->getSubscribersCount(); expect($subscribersCount)->equals(1); } function testItRemovesOrphanedSubscribers() { $this->insertUser(); $id = $this->insertUser(); WP::synchronizeUsers(); $this->deleteWPUser($id); WP::synchronizeUsers(); $subscribers = Segment::getWPSegment()->subscribers()->whereIn('wp_user_id', $this->userIds); expect($subscribers->count())->equals(1); } function testItDoesntDeleteNonWPData() { $this->insertUser(); // wp_user_id is null $subscriber = Subscriber::create(); $subscriber->hydrate([ 'first_name' => 'John', 'last_name' => 'John', 'email' => 'user-sync-test' . rand() . '@example.com', ]); $subscriber->status = Subscriber::STATUS_UNCONFIRMED; $subscriber->save(); // wp_user_id is zero $subscriber2 = Subscriber::create(); $subscriber2->hydrate([ 'first_name' => 'Mike', 'last_name' => 'Mike', 'email' => 'user-sync-test2' . rand() . '@example.com', 'wp_user_id' => 0, ]); $subscriber2->status = Subscriber::STATUS_SUBSCRIBED; $subscriber2->save(); // email is empty $subscriber3 = Subscriber::create(); $subscriber3->hydrate([ 'first_name' => 'Dave', 'last_name' => 'Dave', 'email' => 'user-sync-test3' . rand() . '@example.com', // need to pass validation ]); $subscriber3->status = Subscriber::STATUS_SUBSCRIBED; $subscriber3->save(); $this->clearEmail($subscriber3); WP::synchronizeUsers(); $subscribersCount = $this->getSubscribersCount(); expect($subscribersCount)->equals(3); $db_subscriber = Subscriber::findOne($subscriber3->id); expect($db_subscriber)->notEmpty(); $subscriber3->delete(); } function testItRemovesSubscribersInWPSegmentWithoutWPId() { $subscriber = Subscriber::create(); $subscriber->hydrate([ 'first_name' => 'Mike', 'last_name' => 'Mike', 'email' => 'user-sync-test' . rand() . '@example.com', 'wp_user_id' => null, ]); $subscriber->status = Subscriber::STATUS_SUBSCRIBED; $subscriber->save(); $wp_segment = Segment::getWPSegment(); $association = SubscriberSegment::create(); $association->subscriber_id = $subscriber->id; $association->segment_id = $wp_segment->id; $association->save(); $subscribersCount = $this->getSubscribersCount(); expect($subscribersCount)->equals(1); WP::synchronizeUsers(); $subscribersCount = $this->getSubscribersCount(0); expect($subscribersCount)->equals(0); } function testItRemovesSubscribersInWPSegmentWithoutEmail() { $id = $this->insertUser(); $this->updateWPUserEmail($id, ''); $subscriber = Subscriber::create(); $subscriber->hydrate([ 'first_name' => 'Mike', 'last_name' => 'Mike', 'email' => 'user-sync-test' . rand() . '@example.com', // need to pass validation 'wp_user_id' => $id, ]); $subscriber->status = Subscriber::STATUS_SUBSCRIBED; $subscriber->save(); $this->clearEmail($subscriber); $wp_segment = Segment::getWPSegment(); $association = SubscriberSegment::create(); $association->subscriber_id = $subscriber->id; $association->segment_id = $wp_segment->id; $association->save(); $db_subscriber = Subscriber::findOne($subscriber->id); expect($db_subscriber)->notEmpty(); WP::synchronizeUsers(); $db_subscriber = Subscriber::findOne($subscriber->id); expect($db_subscriber)->isEmpty(); } function testItMarksSpammySubscribersAsUnconfirmed() { $random_number = rand(); $id = $this->insertUser($random_number); $subscriber = Subscriber::createOrUpdate([ 'email' => 'user-sync-test' . $random_number . '@example.com', 'status' => Subscriber::STATUS_SUBSCRIBED, 'wp_user_id' => $id, ]); update_user_meta($id, 'default_password_nag', '1'); WP::synchronizeUsers(); $db_subscriber = Subscriber::findOne($subscriber->id); expect($db_subscriber->status)->equals(Subscriber::STATUS_UNCONFIRMED); } function testItMarksSpammySubscribersWithUserStatus2AsUnconfirmed() { global $wpdb; $column_exists = $wpdb->query(sprintf('SHOW COLUMNS FROM `%s` LIKE "user_status"', $wpdb->users)); if (!$column_exists) { // This column is deprecated in WP, is no longer used by the core // and either may not be present, or may be removed in the future. return false; } $random_number = rand(); $id = $this->insertUser($random_number); $subscriber = Subscriber::createOrUpdate([ 'email' => 'user-sync-test' . $random_number . '@example.com', 'status' => Subscriber::STATUS_SUBSCRIBED, 'wp_user_id' => $id, ]); wp_update_user(['ID' => $id, 'user_status' => 2]); $db = \ORM::getDb(); $db->exec(sprintf('UPDATE %s SET `user_status` = 2 WHERE ID = %s', $wpdb->users, $id)); WP::synchronizeUsers(); $db_subscriber = Subscriber::findOne($subscriber->id); expect($db_subscriber->status)->equals(Subscriber::STATUS_UNCONFIRMED); } function _before() { parent::_before(); $this->settings = ContainerWrapper::getInstance()->get(SettingsController::class); $this->cleanData(); } function _after() { $this->cleanData(); } private function cleanData() { \ORM::raw_execute('TRUNCATE ' . Segment::$_table); \ORM::raw_execute('TRUNCATE ' . SubscriberSegment::$_table); global $wpdb; $db = \ORM::getDb(); $db->exec(sprintf(' DELETE FROM %s WHERE subscriber_id IN (select id from %s WHERE email LIKE "user-sync-test%%") ', SubscriberSegment::$_table, Subscriber::$_table)); $db->exec(sprintf(' DELETE FROM %s WHERE user_id IN (select id from %s WHERE user_email LIKE "user-sync-test%%") ', $wpdb->usermeta, $wpdb->users)); $db->exec(sprintf(' DELETE FROM %s WHERE user_email LIKE "user-sync-test%%" OR user_login LIKE "user-sync-test%%" ', $wpdb->users)); $db->exec(sprintf(' DELETE FROM %s WHERE email LIKE "user-sync-test%%" ', Subscriber::$_table)); } private function getSubscribersCount($a = null) { return Subscriber::whereLike("email", "user-sync-test%")->count(); } /** * Insert a user without invoking wp hooks. * Those tests are testing user synchronisation, so we need data in wp_users table which has not been synchronised to * mailpoet database yet. We cannot use wp_insert_user functions because they would do the sync on insert. * * @return string */ private function insertUser($number = null) { global $wpdb; $db = \ORM::getDb(); $number_sql = !is_null($number) ? (int)$number : 'rand()'; $db->exec(sprintf(' INSERT INTO %s (user_login, user_email, user_registered) VALUES ( CONCAT("user-sync-test", ' . $number_sql . '), CONCAT("user-sync-test", ' . $number_sql . ', "@example.com"), "2017-01-02 12:31:12" )', $wpdb->users)); $id = $db->lastInsertId(); $this->userIds[] = $id; return $id; } private function updateWPUserEmail($id, $email) { global $wpdb; $db = \ORM::getDb(); $db->exec(sprintf(' UPDATE %s SET user_email = "%s" WHERE id = %s ', $wpdb->users, $email, $id)); } private function updateWPUserDisplayName($id, $name) { global $wpdb; $db = \ORM::getDb(); $db->exec(sprintf(' UPDATE %s SET display_name = "%s" WHERE id = %s ', $wpdb->users, $name, $id)); } private function deleteWPUser($id) { global $wpdb; $db = \ORM::getDb(); $db->exec(sprintf(' DELETE FROM %s WHERE id = %s ', $wpdb->users, $id)); } private function clearEmail($subscriber) { \ORM::raw_execute(' UPDATE ' . MP_SUBSCRIBERS_TABLE . ' SET `email` = "" WHERE `id` = ' . $subscriber->id ); } }