/** * Tests the guessContactIdsByNameAndEmail method with deleted contacts in the * mix. * */ public function testGuessContactIdsByNameAndEmailIgnoresDeletedContacts() { // // Test 1: Primary case: only one contact matches on name+email but it's // deleted. Should not match. // CRM_Mailchimp_Sync::createTemporaryTableForMailchimp(); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_m (email, first_name, last_name)\n VALUES (%1, %2, %3);", [1 => [static::$civicrm_contact_1['email'], 'String'], 2 => [static::$civicrm_contact_1['first_name'], 'String'], 3 => [static::$civicrm_contact_1['last_name'], 'String']]); // Delete (trash) the contact. civicrm_api3('Contact', 'delete', ['contact_id' => static::$civicrm_contact_1['contact_id']]); $result = CRM_Mailchimp_Sync::guessContactIdsByNameAndEmail(); $this->assertEquals(0, $result); // // Test 2: Check if contact 2 shares the email address and name // // Contact 2 should be matched. // change contact2's name. civicrm_api3('Contact', 'create', ['contact_id' => static::$civicrm_contact_2['contact_id'], 'first_name' => static::$civicrm_contact_1['first_name'], 'last_name' => static::$civicrm_contact_1['last_name']]); // and email. civicrm_api3('Email', 'create', ['contact_id' => static::$civicrm_contact_2['contact_id'], 'email' => static::$civicrm_contact_1['email'], 'is_billing' => 1]); CRM_Mailchimp_Sync::dropTemporaryTables(); CRM_Mailchimp_Sync::createTemporaryTableForMailchimp(); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_m (email, first_name, last_name)\n VALUES (%1, %2, %3);", [1 => [static::$civicrm_contact_1['email'], 'String'], 2 => [static::$civicrm_contact_1['first_name'], 'String'], 3 => [static::$civicrm_contact_1['last_name'], 'String']]); $result = CRM_Mailchimp_Sync::guessContactIdsByNameAndEmail(); $this->assertEquals(1, $result); // Check the matched record did match contact 2. $result = CRM_Core_DAO::singleValueQuery('SELECT COUNT(*) c FROM tmp_mailchimp_push_m WHERE email = %1 AND cid_guess = ' . static::$civicrm_contact_2['contact_id'], [1 => [static::$civicrm_contact_1['email'], 'String']]); $this->assertEquals(1, $result); // Test 3: a third contact matches name and email - no longer unique, should // not match. $contact3 = civicrm_api3('Contact', 'create', ['contact_type' => 'Individual', 'first_name' => static::C_CONTACT_1_FIRST_NAME, 'last_name' => static::C_CONTACT_1_LAST_NAME, 'email' => static::$civicrm_contact_1['email']]); CRM_Mailchimp_Sync::dropTemporaryTables(); CRM_Mailchimp_Sync::createTemporaryTableForMailchimp(); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_m (email, first_name, last_name)\n VALUES (%1, %2, %3);", [1 => [static::$civicrm_contact_1['email'], 'String'], 2 => [static::$civicrm_contact_1['first_name'], 'String'], 3 => [static::$civicrm_contact_1['last_name'], 'String']]); $result = CRM_Mailchimp_Sync::guessContactIdsByNameAndEmail(); // Remove 3rd contact. civicrm_api3('Contact', 'delete', ['contact_id' => $contact3['id'], 'skip_undelete' => 1]); // check it did not match. $this->assertEquals(0, $result); }
/** * Tests the removeInSync method. * */ public function testRemoveInSync() { // Create empty tables. CRM_Mailchimp_Sync::createTemporaryTableForMailchimp(); CRM_Mailchimp_Sync::createTemporaryTableForCiviCRM(); // Prepare the mock for the subscription the post hook will do. $api_prophecy = $this->prophesize('CRM_Mailchimp_Api3'); CRM_Mailchimp_Utils::setMailchimpApi($api_prophecy->reveal()); $api_prophecy->get('/lists/dummylistid/interest-categories', Argument::any())->willReturn(json_decode('{"http_code":200,"data":{"categories":[{"id":"categoryid","title":"' . static::MC_INTEREST_CATEGORY_TITLE . '"}]}}')); $api_prophecy->get("/lists/dummylistid/interest-categories/categoryid/interests", Argument::any())->willReturn(json_decode('{"http_code":200,"data":{"interests":[{"id":"interestId1","name":"' . static::MC_INTEREST_NAME_1 . '"},{"id":"interestId2","name":"' . static::MC_INTEREST_NAME_2 . '"}]}}')); $api_prophecy->get('/lists', ['fields' => 'lists.id,lists.name', 'count' => 10000])->willReturn(json_decode(json_encode(['http_code' => 200, 'data' => ['lists' => []]]))); $sync = new CRM_Mailchimp_Sync(static::$test_list_id); // Test 1. // // Delete records from both tables when there's a cid_guess--contact link // and the hash is the same. CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_c (email, hash, contact_id) VALUES\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', 1),\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', 2);"); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_m (email, hash, cid_guess) VALUES\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', 1),\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', 2);"); $result = $sync->removeInSync('pull'); $this->assertEquals(2, $result); $this->assertEquals(0, $sync->countMailchimpMembers()); $this->assertEquals(0, $sync->countCiviCrmMembers()); // Test 2. // // Check different hashes stops removals. CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_c (email, hash, contact_id) VALUES\n ('*****@*****.**', 'different', 1),\n ('*****@*****.**', 'different', 2);"); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_m (email, hash, cid_guess) VALUES\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', 1),\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', 2);"); $result = $sync->removeInSync('pull'); $this->assertEquals(0, $result); $this->assertEquals(2, $sync->countMailchimpMembers()); $this->assertEquals(2, $sync->countCiviCrmMembers()); // Test 3. // // Check nothing removed if no cid-contact match. CRM_Mailchimp_Sync::createTemporaryTableForMailchimp(); CRM_Mailchimp_Sync::createTemporaryTableForCiviCRM(); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_c (email, hash, contact_id) VALUES\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', 1),\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', 2);"); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_m (email, hash, cid_guess) VALUES\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', 0),\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', NULL);"); $result = $sync->removeInSync('pull'); $this->assertEquals(0, $result); $this->assertEquals(2, $sync->countMailchimpMembers()); $this->assertEquals(2, $sync->countCiviCrmMembers()); // Test 4. // // Check duplicate civi contact deleted. CRM_Mailchimp_Sync::createTemporaryTableForMailchimp(); CRM_Mailchimp_Sync::createTemporaryTableForCiviCRM(); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_c (email, hash, contact_id) VALUES\n ('*****@*****.**', 'Xaaaaaaaaaaaaaaa', 1),\n ('*****@*****.**', 'Yaaaaaaaaaaaaaaa', 2);"); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_m (email, hash, cid_guess) VALUES\n ('*****@*****.**', 'bbbbbbbbbbbbbbbb', 1);"); $result = $sync->removeInSync('push'); $this->assertEquals(1, $result); $this->assertEquals(1, $sync->countMailchimpMembers()); $this->assertEquals(1, $sync->countCiviCrmMembers()); // Test 5. // // Check duplicate civi contact NOT deleted when in pull mode. CRM_Mailchimp_Sync::createTemporaryTableForMailchimp(); CRM_Mailchimp_Sync::createTemporaryTableForCiviCRM(); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_c (email, hash, contact_id) VALUES\n ('*****@*****.**', 'Xaaaaaaaaaaaaaaa', 1),\n ('*****@*****.**', 'Yaaaaaaaaaaaaaaa', 2);"); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_m (email, hash, cid_guess) VALUES\n ('*****@*****.**', 'bbbbbbbbbbbbbbbb', 1);"); $result = $sync->removeInSync('pull'); $this->assertEquals(0, $result); $this->assertEquals(1, $sync->countMailchimpMembers()); $this->assertEquals(2, $sync->countCiviCrmMembers()); // Test 5: one contact should be removed because it's in sync, the other // because it's a duplicate. // // Check duplicate civi contact deleted. CRM_Mailchimp_Sync::createTemporaryTableForMailchimp(); CRM_Mailchimp_Sync::createTemporaryTableForCiviCRM(); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_c (email, hash, contact_id) VALUES\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', 1),\n ('*****@*****.**', 'Yaaaaaaaaaaaaaaa', 2);"); CRM_Core_DAO::executeQuery("INSERT INTO tmp_mailchimp_push_m (email, hash, cid_guess) VALUES\n ('*****@*****.**', 'aaaaaaaaaaaaaaaa', 1);"); $result = $sync->removeInSync('push'); $this->assertEquals(2, $result); $this->assertEquals(0, $sync->countMailchimpMembers()); $this->assertEquals(0, $sync->countCiviCrmMembers()); CRM_Mailchimp_Sync::dropTemporaryTables(); }
/** * Test pull does not update groups from interests not configured to allow * this. * * @group pull */ public function testPullChangesNonPullInterests() { $api = CRM_Mailchimp_Utils::getMailchimpApi(); try { // Alter the group to remove the permission for Mailchimp to update // CiviCRM. $result = civicrm_api3('Group', 'create', ['id' => static::$civicrm_group_id_interest_1, static::$custom_is_mc_update_grouping => 0]); // Add contact 1 to interest1, then subscribe contact 1. $this->joinGroup(static::$civicrm_contact_1, static::$civicrm_group_id_interest_1, TRUE); $this->joinMembershipGroup(static::$civicrm_contact_1); // Change interests at Mailchimp: de-select interest1 $result = $api->patch('/lists/' . static::$test_list_id . '/members/' . static::$civicrm_contact_1['subscriber_hash'], ['interests' => [static::$test_interest_id_1 => FALSE]]); $this->assertEquals(200, $result->http_code); // Collect data from Mailchimp and CiviCRM. $sync = new CRM_Mailchimp_Sync(static::$test_list_id); $sync->collectCiviCrm('pull'); $sync->collectMailchimp('pull'); $matches = $sync->matchMailchimpMembersToContacts(); $this->assertEquals(['bySubscribers' => 1, 'byUniqueEmail' => 0, 'byNameEmail' => 0, 'bySingle' => 0, 'totalMatched' => 1, 'newContacts' => 0, 'failures' => 0], $matches); // Remove in-sync things - should be 1 because except for this change // we're not allowed to change, nothing has changed. $in_sync = $sync->removeInSync('pull'); $this->assertEquals(1, $in_sync); CRM_Mailchimp_Sync::dropTemporaryTables(); } catch (CRM_Mailchimp_Exception $e) { // Spit out request and response for debugging. print "Request:\n"; print_r($e->request); print "Response:\n"; print_r($e->response); // re-throw exception. throw $e; } }