Ejegg has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/383905 )
Change subject: Merge branch 'master' into deployment ...................................................................... Merge branch 'master' into deployment 24d996100 Manage merge on has-postal-suffix vs no-has-postal-suffix. 0312ac0c1 Allow importing gateway and Contribution Tracking ID c03944475 Add editorconfig to various drupal dirs with drupal whitespace standard a8e86ee45 Drop addresses without country Change-Id: Ia56ce1a613a129c9f4551924d344352b8961ab5f --- D sites/all/modules/metrics_reporting/tests/phpunit/PrometheusReporterTest.php D sites/all/modules/offline2civicrm/tests/WmfImportTest.php D sites/all/modules/orphan_slayer/tests/phpunit/OrphanSlayerTest.php D sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php 4 files changed, 0 insertions(+), 2,037 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/wikimedia/fundraising/crm refs/changes/05/383905/1 diff --git a/sites/all/modules/metrics_reporting/tests/phpunit/PrometheusReporterTest.php b/sites/all/modules/metrics_reporting/tests/phpunit/PrometheusReporterTest.php deleted file mode 100644 index 7df123f..0000000 --- a/sites/all/modules/metrics_reporting/tests/phpunit/PrometheusReporterTest.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php - -/** - * @group Metrics - */ -class PrometheusReporterTest extends BaseWmfDrupalPhpUnitTestCase { - public function testReportMetrics() { - $dir = CRM_Utils_File::tempdir(); - $reporter = new PrometheusReporter( $dir ); - $metrics = array( - 'daisies_picked' => 157, - 'orcs_befriended' => 3, - 'prisoners_freed' => 5, - ); - $reporter->reportMetrics( 'foo', $metrics ); - $filename = $dir . DIRECTORY_SEPARATOR . 'foo' . - PrometheusReporter::$extension; - $this->assertFileExists( $filename ); - // don't want the trailing newline - $written = rtrim( file_get_contents( $filename ) ); - $split = explode( "\n", $written ); - foreach ( $split as $metric ) { - list( $name, $value ) = explode( ' ', $metric ); - $this->assertEquals( $metrics[$name], $value ); - unset( $metrics[$name] ); - } - $this->assertEmpty( $metrics, 'A metric was left unwritten' ); - unlink( $filename ); - rmdir( $dir ); - } -} diff --git a/sites/all/modules/offline2civicrm/tests/WmfImportTest.php b/sites/all/modules/offline2civicrm/tests/WmfImportTest.php deleted file mode 100644 index b1f480c..0000000 --- a/sites/all/modules/offline2civicrm/tests/WmfImportTest.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php - -use Wikimedia\TestingAccessWrapper; - -/** - * @group Import - * @group Offline2Civicrm - */ -class WmfImportTest extends BaseChecksFileTest { - - /** - * Existing contribution_tracking row is updated with contribution_id - */ - function testImportExistingTracking() { - $contribution_tracking_id = wmf_civicrm_insert_contribution_tracking( array( - 'utm_source' => 'Blah_source', - 'utm_medium' => 'civicrm', - 'utm_campaign' => 'test_campaign', - 'ts' => wmf_common_date_unix_to_sql( time() ) - ) ); - - $this->trxn_id = mt_rand(); - $this->gateway = 'globalcollect'; - $data = array( - 'City' => 'blah city', - 'Contribution Tracking ID' => $contribution_tracking_id, - 'Country' => 'AR', - 'Email' => 'em...@phony.com', - 'External Batch Number' => mt_rand(), - 'First Name' => 'Test_first_name', - 'Gift Source' => 'Community GIft', - 'Last Name' => 'Test_last_name', - 'Original Amount' => '123', - 'Original Currency' => 'USD', - 'Payment Gateway' => $this->gateway, - 'Payment Instrument' => 'Cash', - 'Postal Code' => '90210', - 'Postmark Date' => '2012-02-02', - 'Received Date' => '2017-07-07', - 'State' => 'CA', - 'Street Address' => '123 Sunset Boulevard', - 'Transaction ID' => $this->trxn_id, - ); - $importer = new WmfImportFile( "no URI" ); - $exposed = TestingAccessWrapper::newFromObject( $importer ); - $message = $exposed->parseRow( $data ); - $exposed->doImport( $message ); - $contributions = wmf_civicrm_get_contributions_from_gateway_id( - $this->gateway, $this->trxn_id - ); - $this->assertEquals( 1, count( $contributions ) ); - $contribution = $contributions[0]; - $this->assertEquals( $this->gateway, $contribution['gateway'] ); - $ct = db_select( 'contribution_tracking', 'contribution_tracking' ) - ->fields( 'contribution_tracking' ) - ->condition( 'id', $contribution_tracking_id ) - ->execute() - ->fetchAssoc(); - $this->assertEquals( $contribution['id'], $ct['contribution_id'] ); - // TODO: should update existing c_t row with country! - // $this->assertEquals( 'AR', $ct['country'] ); - } -} diff --git a/sites/all/modules/orphan_slayer/tests/phpunit/OrphanSlayerTest.php b/sites/all/modules/orphan_slayer/tests/phpunit/OrphanSlayerTest.php deleted file mode 100644 index 04efe0b..0000000 --- a/sites/all/modules/orphan_slayer/tests/phpunit/OrphanSlayerTest.php +++ /dev/null @@ -1,84 +0,0 @@ -<?php - -use SmashPig\Core\Context; -use SmashPig\Tests\TestingContext; -use SmashPig\Tests\TestingGlobalConfiguration; -use SmashPig\Core\DataStores\PendingDatabase; - -/** - * @group OrphanSlayer - */ - -class OrphanSlayerTest extends PHPUnit_Framework_TestCase { - - public function setUp() { - parent::setUp(); - - // Initialize SmashPig with a fake context object - $config = TestingGlobalConfiguration::create(); - TestingContext::init( $config ); - - if ( !defined( 'DRUPAL_ROOT' ) ) { - throw new Exception( "Define DRUPAL_ROOT somewhere before running unit tests." ); - } - - global $user, $_exchange_rate_cache; - $GLOBALS['_PEAR_default_error_mode'] = NULL; - $GLOBALS['_PEAR_default_error_options'] = NULL; - $_exchange_rate_cache = array(); - - $user = new stdClass(); - $user->name = "foo_who"; - $user->uid = "321"; - $user->roles = array( DRUPAL_AUTHENTICATED_RID => 'authenticated user' ); - } - - public function tearDown() { - Context::set( null ); // Nullify any SmashPig context for the next run - parent::tearDown(); - } - - - public function testGetOldest(){ - $slayer = new OrphanSlayer('paypal_ec'); - $orphan = $this->createTestOrphan('paypal_ec'); - $result = $slayer->get_oldest(); - $this->assertEquals($orphan['contribution_tracking_id'], $result['contribution_tracking_id'], "Cannot get orphan"); - PendingDatabase::get()->deleteMessage([$orphan]); - } - - public function testrectify() { - $slayer = new OrphanSlayer('paypal_ec'); - $orphan = $this->createTestOrphan($slayer->gateway); - TestingPaypalExpressAdapter::setDummyGatewayResponseCode('OK'); - $result = $slayer->rectify($orphan); - $this->assertEquals(array(), $result->getErrors(), "rectify_orphan returned errors: " . print_r($result->getErrors(), true)); - $result = PendingDatabase::get()->fetchMessageByGatewayOrderId( 'paypal_ec', $orphan['order_id'] ); - $this->assertEquals($result, null, "Orphan was not deleted"); - } - - protected function createTestOrphan($gateway = 'test'){ - $uniq = mt_rand(); - $message = array( - 'contribution_tracking_id' => $uniq, - 'country' => 'US', - 'first_name' => 'Flighty', - 'last_name' => 'Dono', - 'email' => 'test+...@eff.org', - 'gateway' => $gateway, - 'gateway_txn_id' => "txn-{$uniq}", - 'gateway_session_id' => mt_rand(), - 'order_id' => "order-{$uniq}", - 'gateway_account' => 'default', - 'payment_method' => 'paypal', - 'payment_submethod' => 'mc', - // Defaults to a magic 25 minutes ago, within the process window. - 'date' => time() - 25 * 60, - 'gross' => 123, - 'currency' => 'EUR', - ); - - PendingDatabase::get()->storeMessage($message); - return $message; - } -} diff --git a/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php b/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php deleted file mode 100644 index 00fc242..0000000 --- a/sites/all/modules/wmf_civicrm/tests/phpunit/MergeTest.php +++ /dev/null @@ -1,1859 +0,0 @@ -<<<<<<< HEAD (47de97 Merge branch 'master' of https://gerrit.wikimedia.org/r/wiki) -======= -<?php - -/** - * @group Pipeline - * @group WmfCivicrm - */ -class MergeTest extends BaseWmfDrupalPhpUnitTestCase { - - /** - * Id of the contact created in the setup function. - * - * @var int - */ - protected $contactID; - - /** - * Id of the contact created in the setup function. - * - * @var int - */ - protected $contactID2; - - public function setUp() { - parent::setUp(); - civicrm_initialize(); - $this->imitateAdminUser(); - $this->doDuckHunt(); - // Run through the merge first to make sure there aren't pre-existing contacts in the DB - // that will ruin the tests. - $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - - $this->contactID = $this->breedDuck(array(wmf_civicrm_get_custom_field_name('do_not_solicit') => 0)); - $this->contactID2 = $this->breedDuck(array(wmf_civicrm_get_custom_field_name('do_not_solicit') => 1)); - } - - public function tearDown() { - $this->callAPISuccess('Contribution', 'get', array( - 'contact_id' => array('IN' => array($this->contactID, $this->contactID2)), - 'api.Contribution.delete' => 1, - )); - $this->callAPISuccess('Contact', 'delete', array('id' => $this->contactID)); - $this->callAPISuccess('Contact', 'delete', array('id' => $this->contactID2)); - parent::tearDown(); - } - - /** - * Test that the merge hook causes our custom fields to not be treated as conflicts. - * - * We also need to check the custom data fields afterwards. - */ - public function testMergeHook() { - $this->callAPISuccess('Contribution', 'create', array( - 'contact_id' => $this->contactID, - 'financial_type_id' => 'Cash', - 'total_amount' => 10, - 'currency' => 'USD', - // Should cause 'is_2014 to be true. - 'receive_date' => '2014-08-04', - wmf_civicrm_get_custom_field_name('original_currency') => 'NZD', - wmf_civicrm_get_custom_field_name('original_amount') => 8, - )); - $this->callAPISuccess('Contribution', 'create', array( - 'contact_id' => $this->contactID2, - 'financial_type_id' => 'Cash', - 'total_amount' => 5, - 'currency' => 'USD', - // Should cause 'is_2012_donor to be true. - 'receive_date' => '2013-01-04', - )); - $this->callAPISuccess('Contribution', 'create', array( - 'contact_id' => $this->contactID2, - 'financial_type_id' => 'Cash', - 'total_amount' => 9, - 'currency' => 'NZD', - // Should cause 'is_2015_donor to be true. - 'receive_date' => '2016-04-04', - )); - $contact = $this->callAPISuccess('Contact', 'get', array( - 'id' => $this->contactID, - 'sequential' => 1, - 'return' => array(wmf_civicrm_get_custom_field_name('lifetime_usd_total'), wmf_civicrm_get_custom_field_name('do_not_solicit')), - )); - $this->assertEquals(10, $contact['values'][0][wmf_civicrm_get_custom_field_name('lifetime_usd_total')]); - $result = $this->callAPISuccess('Job', 'process_batch_merge', array( - 'criteria' => array('contact' => array('id' => array('IN' => array($this->contactID, $this->contactID2)))), - )); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccess('Contact', 'get', array( - 'id' => $this->contactID, - 'sequential' => 1, - 'return' => array( - wmf_civicrm_get_custom_field_name('lifetime_usd_total'), - wmf_civicrm_get_custom_field_name('do_not_solicit'), - wmf_civicrm_get_custom_field_name('last_donation_amount'), - wmf_civicrm_get_custom_field_name('last_donation_currency'), - wmf_civicrm_get_custom_field_name('last_donation_usd'), - wmf_civicrm_get_custom_field_name('last_donation_date'), - wmf_civicrm_get_custom_field_name('is_2011_donor'), - wmf_civicrm_get_custom_field_name('is_2012_donor'), - wmf_civicrm_get_custom_field_name('is_2013_donor'), - wmf_civicrm_get_custom_field_name('is_2014_donor'), - wmf_civicrm_get_custom_field_name('is_2015_donor'), - wmf_civicrm_get_custom_field_name('is_2016_donor'), - ), - )); - $this->assertEquals(24, $contact['values'][0][wmf_civicrm_get_custom_field_name('lifetime_usd_total')]); - $this->assertEquals(1, $contact['values'][0][wmf_civicrm_get_custom_field_name('do_not_solicit')]); - $this->assertEquals(0, $contact['values'][0][wmf_civicrm_get_custom_field_name('is_2011_donor')]); - $this->assertEquals(1, $contact['values'][0][wmf_civicrm_get_custom_field_name('is_2012_donor')]); - $this->assertEquals(0, $contact['values'][0][wmf_civicrm_get_custom_field_name('is_2013_donor')]); - $this->assertEquals(1, $contact['values'][0][wmf_civicrm_get_custom_field_name('is_2014_donor')]); - $this->assertEquals(1, $contact['values'][0][wmf_civicrm_get_custom_field_name('is_2015_donor')]); - $this->assertEquals(0, $contact['values'][0][wmf_civicrm_get_custom_field_name('is_2016_donor')]); - $this->assertEquals(9, $contact['values'][0][wmf_civicrm_get_custom_field_name('last_donation_amount')]); - $this->assertEquals(9, $contact['values'][0][wmf_civicrm_get_custom_field_name('last_donation_usd')]); - $this->assertEquals('2016-04-04 00:00:00', $contact['values'][0][wmf_civicrm_get_custom_field_name('last_donation_date')]); - $this->assertEquals('NZD', $contact['values'][0][wmf_civicrm_get_custom_field_name('last_donation_currency')]); - - // Now lets check the one to be deleted has a do_not_solicit = 0. - $this->callAPISuccess('Contact', 'create', array( - 'contact_type' => 'Individual', - 'first_name' => 'Donald', - 'last_name' => 'Duck', - 'email' => 'the_...@duckland.com', - wmf_civicrm_get_custom_field_name('do_not_solicit') => 0, - )); - $result = $this->callAPISuccess('Job', 'process_batch_merge', array( - 'criteria' => array('contact' => array('id' => $this->contactID)), - )); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccess('Contact', 'get', array( - 'id' => $this->contactID, - 'sequential' => 1, - 'return' => array(wmf_civicrm_get_custom_field_name('lifetime_usd_total'), wmf_civicrm_get_custom_field_name('do_not_solicit')), - )); - $this->assertEquals(1, $contact['values'][0][wmf_civicrm_get_custom_field_name('do_not_solicit')]); - } - - /** - * Test altering the address decision by hook. - * - * I feel I did something a bit sneaky here. I actually wrote both the test and - * the hook against the core repo and committed in in this test. - * - * I figured that made core more robust & helped future proof us. - * - * https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/JobTest.php#L584 - * https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/JobTest.php#L643 - * - * However, I'm replicating the test into our repo to test it still works distilled - * into our hook. - * - * Tested scenarios: Note these apply to addresses, phones & emails. - * - * 1) (Fill data) both contacts have the same primary with the same location (Home). The first has an additional address (Mailing). - * Outcome: common primary is retained as the Home address & additional Mailing address is retained on the merged contact. - * Notes: our behaviour is the same as core. - * 2) (Fill data) (reverse of 1) both contacts have the same primary with the same location (Home). - * The second has an additional address (Mailing). - * Outcome: common primary is retained & additional Mailing address is retained on the merged contact. - * Notes: our behaviour is the same as core. - * 3) (Fill data) only one contact has an address (Home) - first contact. - * Outcome: address retained - * Notes: our behaviour is the same as core. - * 4) (Fill data) (reverse of 3) only one contact has an address (Home) - second contact. - * Outcome: address retained - * Notes: our behaviour is the same as core. - * 5) (Resolve Data) Contacts have different primary addresses with different - * location types. ie. first has a primary Home address. Second has a primary - * Mailing address. Addresses Differ. - * Outcome: keep both addresses. Use the address of the later donor as the primary. - * Notes: differs from core behaviour which would keep the address of the contact - * with the lower contact_id as the primary - * 6) (Resolve Data) (reverse of 5) Contacts have different primary addresses with different - * location types. ie. first has a primary Mailing address. Second has a primary - * Home address. Addresses Differ. - * Outcome: keep both addresses. Use the address of the later donor as the primary. - * Notes: differs from core behaviour which would keep the address of the contact - * with the lower contact_id as the primary - * 7) (Resolve Data) Contacts have the same Home address. For the first the Home - * address is primary. For the second a (different) mailing address is. - * Outcome: both addresses kept. The one that is primary for the later donor is primary. - * Notes: same as 5 & 6 but with an additional address. Differs from core which - * would set primary to match to lower contact_id. - * 8) (Resolve Data) (reverse of 7) Contacts have the same Mailing address. For the first - * the Mailing address is primary. For the second a (different) home address is. - * Outcome: both addresses kept. The one that is primary for the later donor is primary. - * Notes: same as 5 & 6 but with an additional address. Differs from core which - * would set primary to match to lower contact_id. - * 9) (Resolve Data) Contacts have the same primary address but for the first - * contact is is Home whereas for the second is is Mailing. - * Outcome: keep the address. Use the Mailing location of the later donor (the second). - * Notes: differs from core behaviour which would keep 2 copies of the address with - * 2 locations. - * 10) (Resolve Data) (reverse of 9) Contacts have the same primary address but for the first - * contact is is Mailing whereas for the second is is Home. - * Outcome: keep the address. Use the Home location of the later donor (the second). - * Notes: differs from core behaviour which would keep 2 copies of the address with - * 2 locations. - * 11) (Throw conflict) Contacts have conflicting home address. Total giving = $500. - * Outcome: conflict - do not merge. - * Notes: This is like core, but for us less than 500 will merge. - * 12) (Resolve Data) Contacts have conflicting home address. Total giving < $500. - * Outcome: merge - only keep home address of latest donor. - * Notes: differs from core. - * 13) (Throw conflict) Contacts have conflicting home address and matching primary (Mailing). Total giving = $500. - * Outcome: conflict - do not merge. - * Notes: This is like core, but for us less than 500 will merge. - * 14) (Resolve Data) Contacts have conflicting home address. Total giving < $500. - * Outcome: merge - only keep home address of latest donor. Keep Mailing. - * Notes: differs from core. - * - * @dataProvider getMergeLocationData - * - * @param array $dataSet - */ - public function testBatchMergesAddressesHook($dataSet) { - $this->contributionCreate(array('contact_id' => $this->contactID, 'receive_date' => '2010-01-01', 'invoice_id' => 1, 'trxn_id' => 1)); - $this->contributionCreate(array('contact_id' => $this->contactID2, 'receive_date' => '2012-01-01', 'invoice_id' => 2, 'trxn_id' => 2)); - if ($dataSet['is_major_gifts']) { - $this->contributionCreate(array('contact_id' => $this->contactID2, 'receive_date' => '2012-01-01', 'total_amount' => 300)); - } - foreach ($dataSet['contact_1'] as $address) { - $this->callAPISuccess($dataSet['entity'], 'create', array_merge(array('contact_id' => $this->contactID), $address)); - } - foreach ($dataSet['contact_2'] as $address) { - $this->callAPISuccess($dataSet['entity'], 'create', array_merge(array('contact_id' => $this->contactID2), $address)); - } - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - - $this->assertEquals($dataSet['skipped'], count($result['values']['skipped'])); - $this->assertEquals($dataSet['merged'], count($result['values']['merged'])); - $addresses = $this->callAPISuccess($dataSet['entity'], 'get', array('contact_id' => $this->contactID, 'sequential' => 1)); - $this->assertEquals(count($dataSet['expected_hook']), $addresses['count']); - $locationTypes = $this->callAPISuccess($dataSet['entity'], 'getoptions', array('field' => 'location_type_id')); - foreach ($dataSet['expected_hook'] as $index => $expectedAddress) { - foreach ($expectedAddress as $key => $value) { - if ($key == 'location_type_id') { - $this->assertEquals($locationTypes['values'][$addresses['values'][$index][$key]], $value); - } - else { - $this->assertEquals($value, $addresses['values'][$index][$key], $dataSet['entity'] . ': Unexpected value for ' . $key . (!empty($dataSet['description']) ? " on dataset {$dataSet['description']}" : '')); - } - } - } - } - - /** - * Do address tests with contact ids reversed. - * - * Since the higher ID merges into the lower ID we were seeing accidental successes despite an error. - * - * This reversal of the previous test set forces it to work on logic not id co-incidence. - * - * @dataProvider getMergeLocationData - * - * @param array $dataSet - */ - public function testBatchMergesAddressesHookLowerIDMoreRecentDonor($dataSet) { - // here the lower contact ID has the higher receive_date as opposed to the previous test. - $this->contributionCreate(array('contact_id' => $this->contactID2, 'receive_date' => '2010-01-01', 'invoice_id' => 1, 'trxn_id' => 1)); - $this->contributionCreate(array('contact_id' => $this->contactID, 'receive_date' => '2012-01-01', 'invoice_id' => 2, 'trxn_id' => 2)); - if ($dataSet['is_major_gifts']) { - $this->contributionCreate(array('contact_id' => $this->contactID, 'receive_date' => '2012-01-01', 'total_amount' => 300)); - } - foreach ($dataSet['contact_1'] as $address) { - $this->callAPISuccess($dataSet['entity'], 'create', array_merge(array('contact_id' => $this->contactID2), $address)); - } - foreach ($dataSet['contact_2'] as $address) { - $this->callAPISuccess($dataSet['entity'], 'create', array_merge(array('contact_id' => $this->contactID), $address)); - } - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - - $this->assertEquals($dataSet['skipped'], count($result['values']['skipped'])); - $this->assertEquals($dataSet['merged'], count($result['values']['merged'])); - if ($dataSet['merged']) { - // higher contact merged into this so we are interested in this contact. - $keptContact = $this->contactID; - } - else { - // ie. no merge has taken place, so we just going to check our contact2 is unchanged. - $keptContact = $this->contactID2; - } - $addresses = $this->callAPISuccess($dataSet['entity'], 'get', array( - 'contact_id' => $keptContact, - 'sequential' => 1, - )); - - if (!empty($dataSet['fix_required_for_reverse'])) { - return; - } - $this->assertEquals(count($dataSet['expected_hook']), $addresses['count']); - $locationTypes = $this->callAPISuccess($dataSet['entity'], 'getoptions', array('field' => 'location_type_id')); - foreach ($dataSet['expected_hook'] as $index => $expectedAddress) { - foreach ($addresses['values'] as $index => $address) { - // compared to the previous test the addresses are in a different order (for some datasets. - // so, first find the matching address and then check it fully matches. - // by unsetting afterwards we should find them all gone by the end. - if (!empty($address['street_address']) && $address['street_address'] == $expectedAddress['street_address'] - || !empty($address['phone']) && $address['phone'] == $expectedAddress['phone'] - || !empty($address['email']) && $address['email'] == $expectedAddress['email'] - ) { - foreach ($expectedAddress as $key => $value) { - if ($key == 'location_type_id') { - $this->assertEquals($locationTypes['values'][$addresses['values'][$index][$key]], $value); - } - else { - $this->assertEquals($value, $addresses['values'][$index][$key], $dataSet['entity'] . ': Unexpected value for ' . $key . (!empty($dataSet['description']) ? " on dataset {$dataSet['description']}" : '')); - } - } - unset($addresses['values'][$index]); - // break to find a match for the next $expected address. - continue 2; - } - } - } - $this->assertEmpty($addresses['values']); - } - - /** - * Test that a conflict on 'on_hold' is handled. - */ - public function testBatchMergeConflictOnHold() { - $emailDuck1 = $this->callAPISuccess('Email', 'get', array('contact_id' => $this->contactID, 'return' => 'id')); - $emailDuck2 = $this->callAPISuccess('Email', 'get', array('contact_id' => $this->contactID2, 'return' => 'id')); - - $this->callAPISuccess('Email', 'create', array('id' => $emailDuck1['id'], 'on_hold' => 1)); - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['skipped'])); - $this->assertEquals(0, count($result['values']['merged'])); - - $this->callAPISuccess('Email', 'create', array('id' => $emailDuck1['id'], 'on_hold' => 0)); - $this->callAPISuccess('Email', 'create', array('id' => $emailDuck2['id'], 'on_hold' => 1)); - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['skipped'])); - $this->assertEquals(0, count($result['values']['merged'])); - - $this->callAPISuccess('Email', 'create', array('id' => $emailDuck1['id'], 'on_hold' => 1)); - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(0, count($result['values']['skipped'])); - $this->assertEquals(1, count($result['values']['merged'])); - } - - /** - * Test that a conflict on communication preferences is handled. - */ - public function testBatchMergeConflictCommunicationPreferences() { - $this->callAPISuccess('Contact', 'create', array('id' => $this->contactID, 'do_not_email' => FALSE, 'is_opt_out' => TRUE)); - $this->callAPISuccess('Contact', 'create', array('id' => $this->contactID2, 'do_not_email' => TRUE, 'is_opt_out' => FALSE)); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(0, count($result['values']['skipped'])); - $this->assertEquals(1, count($result['values']['merged'])); - - $contact = $this->callAPISuccess('Contact', 'get', array('id' => $this->contactID, 'sequential' => 1)); - $this->assertEquals(1, $contact['values'][0]['is_opt_out']); - $this->assertEquals(1, $contact['values'][0]['do_not_email']); - } - - - /** - * Test that a conflict on communication preferences is handled. - * - * @dataProvider getLanguageCombos - */ - public function testBatchMergeConflictPreferredLanguage($dataSet) { - // Can't use api if we are trying to use invalid data. - wmf_civicrm_ensure_language_exists('en'); - wmf_civicrm_ensure_language_exists('en_NZ'); - CRM_Core_DAO::executeQuery("UPDATE civicrm_contact SET preferred_language = '{$dataSet['languages'][0]}' WHERE id = $this->contactID"); - CRM_Core_DAO::executeQuery("UPDATE civicrm_contact SET preferred_language = '{$dataSet['languages'][1]}' WHERE id = $this->contactID2"); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - if ($dataSet['is_conflict']) { - $this->assertEquals(1, count($result['values']['skipped'])); - } - else { - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccess('Contact', 'get', array( - 'id' => $this->contactID, - 'sequential' => 1 - )); - $this->assertEquals($dataSet['selected'], $contact['values'][0]['preferred_language']); - } - } - - /** - * Test that a conflict on communication preferences is handled. - * - * @dataProvider getDifferentLanguageCombos - * - * @param string $language1 - * @param string $language2 - */ - public function testBatchMergeConflictDifferentPreferredLanguage($language1, $language2) { - // Can't use api if we are trying to use invalid data. - $this->contributionCreate(array('contact_id' => $this->contactID, 'receive_date' => '2010-01-01', 'invoice_id' => 1, 'trxn_id' => 1)); - $this->contributionCreate(array('contact_id' => $this->contactID2, 'receive_date' => '2012-01-01', 'invoice_id' => 2, 'trxn_id' => 2)); - - wmf_civicrm_ensure_language_exists('en_US'); - wmf_civicrm_ensure_language_exists('fr_FR'); - CRM_Core_DAO::executeQuery("UPDATE civicrm_contact SET preferred_language = '$language1' WHERE id = $this->contactID"); - CRM_Core_DAO::executeQuery("UPDATE civicrm_contact SET preferred_language = '$language2' WHERE id = $this->contactID2"); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccess('Contact', 'get', array( - 'id' => $this->contactID, - 'sequential' => 1 - )); - $this->assertEquals($language2, $contact['values'][0]['preferred_language']); - } - - /** - * Test that a conflict on communication preferences is handled. - * - * This is the same as the other test except the contact with the lower id is - * the later donor. - * - * @dataProvider getDifferentLanguageCombos - * - * @param string $language1 - * @param string $language2 - */ - public function testBatchMergeConflictDifferentPreferredLanguageReverse($language1, $language2) { - // Can't use api if we are trying to use invalid data. - $this->contributionCreate(array('contact_id' => $this->contactID, 'receive_date' => '2012-01-01', 'invoice_id' => 1, 'trxn_id' => 1)); - $this->contributionCreate(array('contact_id' => $this->contactID2, 'receive_date' => '2010-01-01', 'invoice_id' => 2, 'trxn_id' => 2)); - - wmf_civicrm_ensure_language_exists('en_US'); - wmf_civicrm_ensure_language_exists('fr_FR'); - CRM_Core_DAO::executeQuery("UPDATE civicrm_contact SET preferred_language = '$language1' WHERE id = $this->contactID"); - CRM_Core_DAO::executeQuery("UPDATE civicrm_contact SET preferred_language = '$language2' WHERE id = $this->contactID2"); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccess('Contact', 'get', array( - 'id' => $this->contactID, - 'sequential' => 1 - )); - $this->assertEquals($language1, $contact['values'][0]['preferred_language']); - } - - /** - * Get combinations of languages for comparison. - * - * @return array - */ - public function getLanguageCombos() { - $dataSet = array( - // Choose longer. - array(array('languages' => array('en', 'en_US'), 'is_conflict' => FALSE, 'selected' => 'en_US')), - array(array('languages' => array('en_US', 'en'), 'is_conflict' => FALSE, 'selected' => 'en_US')), - // Choose valid. - array(array('languages' => array('en_XX', 'en_US'), 'is_conflict' => FALSE, 'selected' => 'en_US')), - array(array('languages' => array('en_US', 'en_XX'), 'is_conflict' => FALSE, 'selected' => 'en_US')), - // Chose one with a 'real' label (more valid). - array(array('languages' => array('en_US', 'en_NZ'), 'is_conflict' => FALSE, 'selected' => 'en_US')), - array(array('languages' => array('en_NZ', 'en_US'), 'is_conflict' => FALSE, 'selected' => 'en_US')), - // Chose either - feels like the return on coding any decision making now is negligible. - // Could go for most recent donor but feels like no return on effort. - // we will usually get the most recent donor anyway by default - as it merges higher number to smaller. - array(array('languages' => array('en_GB', 'en_US'), 'is_conflict' => FALSE, 'selected' => 'en_US')), - array(array('languages' => array('en_US', 'en_GB'), 'is_conflict' => FALSE, 'selected' => 'en_GB')) - ); - return $dataSet; - } - - /** - * Get combinations of languages for comparison. - * - * @return array - */ - public function getDifferentLanguageCombos() { - $dataSet = array( - // Choose longer. - array('fr_FR', 'en_US'), - array('en_US', 'fr_FR'), - ); - return $dataSet; - } - - /** - * Test that source conflicts are ignored. - * - * We don't care enough about source it seems to do much with it. - * - * Bug T146946 - */ - public function testBatchMergeConflictSource() { - $this->breedDuck(array('id' => $this->contactID, 'source' => 'egg')); - $this->breedDuck(array('id' => $this->contactID2, 'source' => 'chicken')); - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(0, count($result['values']['skipped'])); - $this->assertEquals(1, count($result['values']['merged'])); - } - - /** - * Test that whitespace conflicts are resolved. - * - * Bug T146946 - */ - public function testBatchMergeResolvableConflictWhiteSpace() { - $this->breedDuck(array('id' => $this->contactID, 'first_name' => 'alter ego')); - $this->breedDuck(array('id' => $this->contactID2, 'first_name' => 'alterego')); - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccessGetSingle('Contact', array('email' => 'the_...@duckland.com')); - $this->assertEquals('alter ego', $contact['first_name']); - } - - /** - * Test that punctuation conflicts are ignored. - * - * Bug T175748 - */ - public function testBatchMergeResolvableConflictPunctuation() { - $this->breedDuck(array('id' => $this->contactID, 'first_name' => 'alter. ego')); - $this->breedDuck(array('id' => $this->contactID2, 'first_name' => 'alterego')); - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccessGetSingle('Contact', array('email' => 'the_...@duckland.com')); - $this->assertEquals('alter. ego', $contact['first_name']); - } - - /** - * Test that we ignore numbers as names. - * - * Bug T175747 - */ - public function testBatchMergeResolvableConflictNumbersAreNotPeople() { - $this->breedDuck(array('id' => $this->contactID, 'first_name' => 'alter. ego')); - $this->breedDuck(array('id' => $this->contactID2, 'first_name' => '1')); - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccessGetSingle('Contact', array('email' => 'the_...@duckland.com')); - $this->assertEquals('alter. ego', $contact['first_name']); - } - - /** - * Test that we don't see country only as conflicting with country plus. - * - * Bug T176699 - */ - public function testBatchMergeResolvableConflictCountryVsFullAddress() { - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID, - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID2, - 'street_address' => 'First on the left after you cross the border', - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID2, - 'street_address' => 'A different address', - 'location_type_id' => 2, - )); - $this->contributionCreate(array('contact_id' => $this->contactID2, 'receive_date' => '2010-01-01', 'total_amount' => 500)); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccessGetSingle('Contact', array('email' => 'the_...@duckland.com')); - $this->assertEquals('Mexico', $contact['country']); - $this->assertEquals('First on the left after you cross the border', $contact['street_address']); - $address = $this->callAPISuccessGetSingle('Address', array('street_address' => 'A different address')); - $this->assertEquals($contact['id'], $address['contact_id']); - } - - /** - * Test that we don't see country only as conflicting with country plus. - * - * In this variant the most recent donor is the one with the lower contact - * ID (the one we are going to keep). Real world this is pretty rare but - * perhaps after some merging in strange orders it could happen. - * - * Bug T176699 - */ - public function testBatchMergeResolvableConflictCountryVsFullAddressOutOfOrder() { - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID, - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID2, - 'street_address' => 'First on the left after you cross the border', - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID2, - 'street_address' => 'A different address', - 'location_type_id' => 2, - )); - // this is the change. - $this->contributionCreate(array('contact_id' => $this->contactID, 'receive_date' => '2010-01-01', 'total_amount' => 500)); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccessGetSingle('Contact', array('email' => 'the_...@duckland.com')); - $this->assertEquals('Mexico', $contact['country']); - $this->assertEquals('First on the left after you cross the border', $contact['street_address']); - $address = $this->callAPISuccessGetSingle('Address', array('street_address' => 'A different address')); - $this->assertEquals($contact['id'], $address['contact_id']); - } - - /** - * Test that we don't see country only as conflicting with country plus. - * - * In this case the 'keeper' is against the second contact. - * - * Bug T176699 - */ - public function testBatchMergeResolvableConflictCountryVsFullAddressReverse() { - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID2, - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID, - 'street_address' => 'First on the left after you cross the border', - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID, - 'street_address' => 'A different address', - 'location_type_id' => 2, - )); - $this->contributionCreate(array('contact_id' => $this->contactID2, 'receive_date' => '2010-01-01', 'total_amount' => 500)); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccessGetSingle('Contact', array('email' => 'the_...@duckland.com')); - $this->assertEquals('Mexico', $contact['country']); - $this->assertEquals('First on the left after you cross the border', $contact['street_address']); - $address = $this->callAPISuccessGetSingle('Address', array('street_address' => 'A different address')); - $this->assertEquals($contact['id'], $address['contact_id']); - } - - /** - * Test that we don't see country only as conflicting with country plus. - * - * In this case the 'keeper' is against the second contact. - * - * Bug T176699 - */ - public function testBatchMergeResolvableConflictCountryVsFullAddressReverseOutOfOrder() { - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID2, - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID, - 'street_address' => 'First on the left after you cross the border', - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID, - 'street_address' => 'A different address', - 'location_type_id' => 2, - )); - $this->contributionCreate(array('contact_id' => $this->contactID, 'receive_date' => '2010-01-01', 'total_amount' => 500)); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccessGetSingle('Contact', array('email' => 'the_...@duckland.com')); - $this->assertEquals('Mexico', $contact['country']); - $this->assertEquals('First on the left after you cross the border', $contact['street_address']); - $address = $this->callAPISuccessGetSingle('Address', array('street_address' => 'A different address')); - $this->assertEquals($contact['id'], $address['contact_id']); - } - - /** - * Test that we don't see a city named after a country as the same as a country. - * - * Bug T176699 - */ - public function testBatchMergeResolvableConflictCityLooksCountryishWithCounty() { - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'US', - 'contact_id' => $this->contactID2, - 'city' => 'Mexico', - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID, - 'street_address' => 'First on the left after you cross the border', - 'location_type_id' => 1, - )); - $this->contributionCreate(array('contact_id' => $this->contactID, 'receive_date' => '2010-01-01', 'total_amount' => 500)); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['skipped'])); - $this->assertEquals(0, count($result['values']['merged'])); - } - - /** - * Test that we don't see a city named after a country as the same as a country - * when it has no country. - * - * Bug T176699 - */ - public function testBatchMergeResolvableConflictCityLooksCountryishNoCountry() { - $this->callAPISuccess('Address', 'create', array( - 'contact_id' => $this->contactID2, - 'city' => 'Mexico', - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID, - 'street_address' => 'First on the left after you cross the border', - 'location_type_id' => 1, - )); - $this->contributionCreate(array('contact_id' => $this->contactID, 'receive_date' => '2010-01-01', 'total_amount' => 500)); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['skipped'])); - $this->assertEquals(0, count($result['values']['merged'])); - } - - /** - * Test that we still cope when there is no address conflict.... - * - * Bug T176699 - */ - public function testBatchMergeNoRealConflictOnAddressButAnotherConflictResolved() { - $this->callAPISuccess('Address', 'create', array( - 'contact_id' => $this->contactID2, - 'country' => 'Korea, Republic of', - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'contact_id' => $this->contactID, - 'country' => 'Korea, Republic of', - 'location_type_id' => 1, - )); - $this->contributionCreate(array('contact_id' => $this->contactID, 'receive_date' => '2010-01-01', 'total_amount' => 500)); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(0, count($result['values']['skipped'])); - $this->assertEquals(1, count($result['values']['merged'])); - } - - /** - * Test that we don't see a city named after a country as the same as a country - * when it has no country. - * - * Bug T176699 - */ - public function testBatchMergeResolvableConflictRealConflict() { - $this->callAPISuccess('Address', 'create', array( - 'contact_id' => $this->contactID2, - 'city' => 'Poland', - 'country_id' => 'US', - 'state_province' => 'ME', - 'location_type_id' => 1, - )); - $this->callAPISuccess('Address', 'create', array( - 'country' => 'Poland', - 'contact_id' => $this->contactID, - 'location_type_id' => 1, - )); - $this->contributionCreate(array('contact_id' => $this->contactID, 'receive_date' => '2010-01-01', 'total_amount' => 500)); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['skipped'])); - $this->assertEquals(0, count($result['values']['merged'])); - } - - /** - * Test that we don't the addition of a postal suffix only as a conflict. - * - * Bug T177807 - */ - public function testBatchMergeResolvableConflictPostalSuffixExists() { - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID2, - 'location_type_id' => 1, - 'street_address' => 'First on the left after you cross the border', - 'postal_code' => 90210, - 'postal_code_suffix' => 6666, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID, - 'street_address' => 'First on the left after you cross the border', - 'postal_code' => 90210, - 'location_type_id' => 1, - )); - $this->contributionCreate(array('contact_id' => $this->contactID2, 'receive_date' => '2010-01-01', 'total_amount' => 500)); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccessGetSingle('Contact', array('email' => 'the_...@duckland.com')); - $this->assertEquals('Mexico', $contact['country']); - $this->assertEquals('6666', $contact['postal_code_suffix']); - $this->assertEquals('90210', $contact['postal_code']); - $this->assertEquals('First on the left after you cross the border', $contact['street_address']); - } - - /** - * Test that we don't the addition of a postal suffix only as a conflict. - * - * Bug T177807 - */ - public function testBatchMergeResolvableConflictPostalSuffixExistsReverse() { - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID2, - 'location_type_id' => 1, - 'street_address' => 'First on the left after you cross the border', - 'postal_code' => 90210, - )); - $this->callAPISuccess('Address', 'create', array( - 'country_id' => 'MX', - 'contact_id' => $this->contactID, - 'street_address' => 'First on the left after you cross the border', - 'postal_code' => 90210, - 'location_type_id' => 1, - 'postal_code_suffix' => 6666, - )); - $this->contributionCreate(array('contact_id' => $this->contactID2, 'receive_date' => '2010-01-01', 'total_amount' => 500)); - - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(1, count($result['values']['merged'])); - $contact = $this->callAPISuccessGetSingle('Contact', array('email' => 'the_...@duckland.com')); - $this->assertEquals('Mexico', $contact['country']); - $this->assertEquals('6666', $contact['postal_code_suffix']); - $this->assertEquals('90210', $contact['postal_code']); - $this->assertEquals('First on the left after you cross the border', $contact['street_address']); - } - - /** - * Test that a conflict on casing in first names is handled. - * - * We do a best effort on this to get the more correct on assuming that 1 capital letter in a - * name is most likely to be deliberate. We prioritise less capital letters over more, except that - * all lower case is at the end of the queue. - * - * This won't necessarily give us the best results for 'La Plante' vs 'la Plante' but we should bear in mind - * - both variants have been entered by the user at some point so they have not 'chosen' one. - * - having 2 variants of the spelling of a name with more than one upper case letter in our - * db is an edge case. - */ - public function testBatchMergeConflictNameCasing() { - $this->callAPISuccess('Contact', 'create', array('id' => $this->contactID, 'first_name' => 'donald', 'last_name' => 'Duck')); - $this->callAPISuccess('Contact', 'create', array('id' => $this->contactID2, 'first_name' => 'Donald', 'last_name' => 'duck')); - $this->breedDuck(array('first_name' => 'DONALD', 'last_name' => 'DUCK')); - $this->breedDuck(array('first_name' => 'DonalD', 'last_name' => 'DUck')); - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(0, count($result['values']['skipped'])); - $this->assertEquals(3, count($result['values']['merged'])); - - $contact = $this->callAPISuccess('Contact', 'get', array('id' => $this->contactID, 'sequential' => 1)); - $this->assertEquals('Donald', $contact['values'][0]['first_name']); - $this->assertEquals('Duck', $contact['values'][0]['last_name']); - } - - /** - * Make sure José whomps Jose. - * - * Test diacritic matches are resolved to the one using 'authentic' characters. - * - * @param array $names - * @param bool $isMatch - * @param string $preferredName - * - * @dataProvider getDiacriticData - */ - public function testBatchMergeConflictNameDiacritic($names, $isMatch, $preferredName) { - $this->callAPISuccess('Contact', 'create', array( - 'id' => $this->contactID, - 'first_name' => $names[0], - )); - - $this->callAPISuccess('Contact', 'create', array( - 'id' => $this->contactID2, - 'first_name' => $names[1], - )); - $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - $this->assertEquals(!$isMatch, count($result['values']['skipped'])); - $this->assertEquals($isMatch, count($result['values']['merged'])); - - if ($isMatch) { - $contacts = $this->callAPISuccess('Contact', 'get', array( - 'email' => 'the_...@duckland.com', - 'sequential' => 1 - )); - $this->assertEquals($preferredName, $contacts['values'][0]['first_name']); - } - } - - /** - * Get names with different character sets. - */ - public function getDiacriticData() { - $dataSet = array(); - $dataSet['cyrilic_dissimilar_hyphenated'] = array( - 'pair' => array('Леони-́дович', 'ни́-тский'), - 'is_match' => FALSE, - 'choose' => NULL, - ); - $dataSet['germanic'] = array( - 'pair' => array('Boß', 'Boss'), - 'is_match' => TRUE, - 'choose' => 'Boß', - ); - $dataSet['germanic_reverse'] = array( - 'pair' => array('Boss', 'Boß'), - 'is_match' => TRUE, - 'choose' => 'Boß', - ); - $dataSet['accent_vs_no_accent'] = array( - 'pair' => array('Jose', 'Josè'), - 'is_match' => TRUE, - 'choose' => 'Josè', - ); - $dataSet['accent_vs_no_accent_revese'] = array( - 'pair' => array('José', 'Jose'), - 'is_match' => TRUE, - 'choose' => 'José', - ); - $dataSet['different_direction_accent'] = array( - 'pair' => array('Josè', 'José'), - 'is_match' => TRUE, - // No preference applied, first wins. - 'choose' => 'Josè', - ); - $dataSet['no_way_jose'] = array( - 'pair' => array('Jose', 'Josà'), - 'is_match' => FALSE, - 'choose' => NULL, - ); - $dataSet['cyric_sergei'] = array( - 'pair' => array('Серге́й', 'Sergei'), - // Actually this is a real translation but will not - // match at our level of sophistication. - 'is_match' => FALSE, - 'choose' => NULL, - ); - $dataSet['cyric_sergai'] = array( - 'pair' => array('Серге́й', 'Sergi'), - // Actually this is a real translation but will not - // match at our level of sophistication. - 'is_match' => FALSE, - 'choose' => NULL, - ); - $dataSet['cyrilic_different_length'] = array( - 'pair' => array('Серге́й', 'Серге'), - 'is_match' => FALSE, - 'choose' => NULL, - ); - $dataSet['cyrilic_dissimilar'] = array( - 'pair' => array('Леони́дович', 'ни́тский'), - 'is_match' => FALSE, - 'choose' => NULL, - ); - return $dataSet; - } - - /** - * Get address combinations for the merge test. - * - * @return array - */ - public function getMergeLocationData() { - $address1 = array('street_address' => 'Buckingham Palace', 'city' => 'London'); - $address2 = array('street_address' => 'The Doghouse', 'supplemental_address_1' => 'under the blanket'); - $address3 = array('street_address' => 'Downton Abbey'); - $data = $this->getMergeLocations($address1, $address2, $address3, 'Address'); - $data = array_merge($data, $this->getMergeLocations( - array('phone' => '12345', 'phone_type_id' => 1), - array('phone' => '678910', 'phone_type_id' => 1), - array('phone' => '999888', 'phone_type_id' => 1), - 'Phone') - ); - $data = array_merge($data, $this->getMergeLocations(array('phone' => '12345'), array('phone' => '678910'), array('phone' => '678999'), 'Phone')); - $data = array_merge($data, $this->getMergeLocations( - array('email' => 'm...@me.com'), - array('email' => 'm...@me.org'), - array('email' => 'm...@me.co.nz'), - 'Email', - array(array( - 'email' => 'the_...@duckland.com', - 'location_type_id' => 'Work', - )))); - return $data; - - } - - /** - * Get the location data set. - * - * @param array $locationParams1 - * @param array $locationParams2 - * @param string $entity - * @param array $additionalExpected - * - * @return array - */ - public function getMergeLocations($locationParams1, $locationParams2, $locationParams3, $entity, $additionalExpected = array()) { - $data = array( - 'matching_primary' => array( - 'matching_primary' => array( - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 1, - 'description' => 'Same behaviour with & without the hook, matching primary AND other address maintained', - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - )), - ), - ), - 'matching_primary_reverse' => array( - 'matching_primary_reverse' => array( - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 1, - 'description' => 'Same behaviour with & without the hook, matching primary AND other address maintained', - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - )), - ), - ), - 'only_one_has_address' => array( - 'only_one_has_address' => array( - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 1, - 'description' => 'Same behaviour with & without the hook, address is maintained', - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - ), - 'contact_2' => array(), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - // When dealing with email we don't have a clean slate - the existing - // primary will be primary. - 'is_primary' => ($entity == 'Email' ? 0 : 1), - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - )), - ), - ), - 'only_one_has_address_reverse' => array( - 'only_one_has_address_reverse' => array( - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 1, - 'description' => 'Same behaviour with & without the hook, address is maintained', - 'entity' => $entity, - 'contact_1' => array(), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - )), - ), - ), - 'different_primaries_with_different_location_type' => array( - 'different_primaries_with_different_location_type' => array( - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 1, - 'description' => 'Primaries are different with different location. Keep both addresses. Set primary to be that of more recent donor', - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - )), - ), - ), - 'different_primaries_with_different_location_type_reverse' => array( - 'different_primaries_with_different_location_type_reverse' => array( - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 1, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - )), - ), - ), - 'different_primaries_location_match_only_one_address' => array( - 'different_primaries_location_match_only_one_address' => array( - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 1, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - )), - ), - ), - 'different_primaries_location_match_only_one_address_reverse' => array( - 'different_primaries_location_match_only_one_address_reverse' => array( - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 1, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 0, - ), $locationParams2), - )), - ), - ), - 'same_primaries_different_location' => array( - 'same_primaries_different_location' => array( - 'fix_required_for_reverse' => 1, - 'comment' => 'core is not identifying this as an address conflict in reverse order' - . ' this is not an issue at the moment as it only happens in reverse from the' - . 'form merge - where we do not intervene', - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 1, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams1), - - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams1), - )), - ), - ), - 'same_primaries_different_location_reverse' => array( - 'same_primaries_different_location_reverse' => array( - 'fix_required_for_reverse' => 1, - 'comment' => 'core is not identifying this as an address conflict in reverse order' - . ' this is not an issue at the moment as it only happens in reverse from the' - . 'form merge - where we do not intervene', - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 1, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams1), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - )), - ), - ), - 'conflicting_home_address_major_gifts' => array( - 'conflicting_home_address_major_gifts' => array( - 'merged' => 0, - 'skipped' => 1, - 'is_major_gifts' => 1, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams2), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - )), - ), - ), - 'conflicting_home_address_not_major_gifts' => array( - 'conflicting_home_address_not_major_gifts' => array( - 'fix_required_for_reverse' => 1, - 'comment' => 'our code needs an update as both are being kept' - . ' this is not an issue at the moment as it only happens in reverse from the' - . 'form merge - where we do not intervene', - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 0, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams2), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams2), - )), - ), - ), - 'conflicting_home_address_one_more_major_gifts' => array( - 'conflicting_home_address_one_more_major_gifts' => array( - 'merged' => 0, - 'skipped' => 1, - 'is_major_gifts' => 1, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams3), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - )), - ), - ), - 'conflicting_home_address__one_more_not_major_gifts' => array( - 'conflicting_home_address__one_more_not_major_gifts' => array( - 'fix_required_for_reverse' => 1, - 'comment' => 'our code needs an update as an extra 1 is being kept' - . ' this is not an issue at the moment as it only happens in reverse from the' - . 'form merge - where we do not intervene', - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 0, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams3), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams3), - array_merge(array( - 'location_type_id' => 'Mailing', - 'is_primary' => 1, - ), $locationParams2), - )), - ), - ), - 'duplicate_home_address_on_one_contact' => array( - 'duplicate_home_address_on_one_contact' => array( - 'fix_required_for_reverse' => 1, - 'comment' => 'our code needs an update as an extra 1 is being kept' - . ' this is not an issue at the moment as it only happens in reverse from the' - . 'form merge - where we do not intervene', - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 0, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - )), - ), - ), - 'duplicate_home_address_on_one_contact_second_primary' => array( - 'duplicate_home_address_on_one_contact_second_primary' => array( - 'fix_required_for_reverse' => 1, - 'comment' => 'our code needs an update as an extra 1 is being kept' - . ' this is not an issue at the moment as it only happens in reverse from the' - . 'form merge - where we do not intervene', - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 0, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 1, - ), $locationParams1), - )), - ), - ), - 'duplicate_mixed_address_on_one_contact' => array( - 'duplicate_mixed_address_on_one_contact' => array( - 'merged' => 1, - 'skipped' => 0, - 'comment' => 'We want to be sure we still have a primary. Ideally we would squash - matching addresses here too but currently that only happens on the to-merge contact. - (no high priority improvement)', - 'is_major_gifts' => 0, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Main', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Main', - 'is_primary' => 1, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - )), - ), - ), - 'duplicate_mixed_address_on_one_contact_second_primary' => array( - 'duplicate_mixedaddress_on_one_contact_second_primary' => array( - 'comment' => 'check we do not lose the primary. Matching addresses are squashed.', - 'merged' => 1, - 'skipped' => 0, - 'is_major_gifts' => 0, - 'entity' => $entity, - 'contact_1' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - ), - 'contact_2' => array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Main', - 'is_primary' => 1, - ), $locationParams1), - ), - 'expected_hook' => array_merge($additionalExpected, array( - array_merge(array( - 'location_type_id' => 'Home', - 'is_primary' => 0, - ), $locationParams1), - array_merge(array( - 'location_type_id' => 'Main', - 'is_primary' => 1, - ), $locationParams1), - )), - ), - ), - ); - return $data; - } - - - /** - * Clean up previous runs. - * - * Also get rid of the nest. - */ - protected function doDuckHunt() { - CRM_Core_DAO::executeQuery(' - DELETE c, e - FROM civicrm_contact c - LEFT JOIN civicrm_email e ON e.contact_id = c.id - WHERE display_name = "Donald Duck" OR email = "the_...@duckland.com"'); - CRM_Core_DAO::executeQuery('DELETE FROM civicrm_prevnext_cache'); - } - - /** - * Create contribution. - * - * @param array $params - * Array of parameters. - * - * @return int - * id of created contribution - */ - public function contributionCreate($params) { - - $params = array_merge(array( - 'receive_date' => date('Ymd'), - 'total_amount' => 100.00, - 'fee_amount' => 5.00, - 'net_ammount' => 95.00, - 'financial_type_id' => 1, - 'payment_instrument_id' => 1, - 'non_deductible_amount' => 10.00, - 'contribution_status_id' => 1, - ), $params); - - $result = $this->callAPISuccess('contribution', 'create', $params); - return $result['id']; - } - - /** - * Create a test duck. - * - * @param array $extraParams - * Any overrides to be added to the create call. - * - * @return int - */ - public function breedDuck($extraParams = array()) { - $contact = $this->callAPISuccess('Contact', 'create', array_merge(array( - 'contact_type' => 'Individual', - 'first_name' => 'Donald', - 'last_name' => 'Duck', - 'api.email.create' => array( - 'email' => 'the_...@duckland.com', - 'location_type_id' => 'Work' - ), - ), $extraParams)); - return $contact['id']; - } - - /** - * Test recovery where a blank email has overwritten a non-blank email on merge. - * - * In this case an email existed during merge that held no data. It was used - * on the merge, but now we want the lost data. - */ - public function testRepairBlankedAddressOnMerge() { - $this->prepareForBlankAddressTests(); - $this->replicateBlankedAddress(); - - $address = $this->callAPISuccessGetSingle('Address', array('contact_id' => $this->contactID)); - $this->assertTrue(empty($address['street_address'])); - - wmf_civicrm_fix_blanked_address($address['id']); - $address = $this->callAPISuccessGetSingle('Address', array('contact_id' => $this->contactID)); - $this->assertEquals('25 Mousey Way', $address['street_address']); - - $this->cleanupFromBlankAddressRepairTests(); - } - - /** - * Test recovery where a blank email has overwritten a non-blank email on merge. - * - * In this case an email existed during merge that held no data. It was used - * on the merge, but now we want the lost data. It underwent 2 merges. - */ - public function testRepairBlankedAddressOnMergeDoubleWhammy() { - $this->prepareForBlankAddressTests(); - $contact3 = $this->breedDuck( - array('api.address.create' => array( - 'street_address' => '25 Ducky Way', - 'country_id' => 'US', - 'contact_id' => $this->contactID, - 'location_type_id' => 'Main', - ))); - $this->replicateBlankedAddress(); - - $address = $this->callAPISuccessGetSingle('Address', array('contact_id' => $this->contactID)); - $this->assertTrue(empty($address['street_address'])); - - wmf_civicrm_fix_blanked_address($address['id']); - $address = $this->callAPISuccessGetSingle('Address', array('contact_id' => $this->contactID)); - $this->assertEquals('25 Mousey Way', $address['street_address']); - - $this->cleanupFromBlankAddressRepairTests(); - } - - - /** - * Test recovery where an always-blank email has been transferred to another contact on merge. - * - * We have established the address was always blank and still exists. Lets - * anihilate it. - */ - public function testRemoveEternallyBlankMergedAddress() { - $this->prepareForBlankAddressTests(); - - $this->replicateBlankedAddress(array( - 'street_address' => NULL, - 'country_id' => NULL, - 'location_type_id' => 'Main', - )); - - $address = $this->callAPISuccessGetSingle('Address', array('contact_id' => $this->contactID)); - $this->assertTrue(empty($address['street_address'])); - - wmf_civicrm_fix_blanked_address($address['id']); - $address = $this->callAPISuccess('Address', 'get', array('contact_id' => $this->contactID)); - $this->assertEquals(0, $address['count']); - - $this->cleanupFromBlankAddressRepairTests(); - } - - /** - * Test recovery where a secondary always-blank email has been transferred to another contact on merge. - * - * We have established the address was always blank and still exists, and there is - * a valid other address. Lets annihilate it. - */ - public function testRemoveEternallyBlankNonPrimaryMergedAddress() { - $this->prepareForBlankAddressTests(); - $this->createContributions(); - - $this->callAPISuccess('Address', 'create', array( - 'street_address' => '25 Mousey Way', - 'country_id' => 'US', - 'contact_id' => $this->contactID, - 'location_type_id' => 'Main', - )); - $this->callAPISuccess('Address', 'create', array( - 'street_address' => 'something', - 'contact_id' => $this->contactID2, - 'location_type_id' => 'Main', - )); - $this->callAPISuccess('Address', 'create', array( - 'street_address' => '', - 'contact_id' => $this->contactID2, - 'location_type_id' => 'Main', - )); - $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - - $address = $this->callAPISuccess('Address', 'get', array('contact_id' => $this->contactID, 'sequential' => 1)); - $this->assertEquals(2, $address['count']); - $this->assertTrue(empty($address['values'][1]['street_address'])); - - wmf_civicrm_fix_blanked_address($address['values'][1]['id']); - $address = $this->callAPISuccessGetSingle('Address', array('contact_id' => $this->contactID)); - $this->assertEquals('something', $address['street_address']); - - $this->cleanupFromBlankAddressRepairTests(); - } - - /** - * Replicate the merge that would result in a blanked address. - * - * @param array $overrides - */ - protected function replicateBlankedAddress($overrides = array()) { - $this->createContributions(); - $this->callAPISuccess('Address', 'create', array_merge(array( - 'street_address' => '25 Mousey Way', - 'country_id' => 'US', - 'contact_id' => $this->contactID, - 'location_type_id' => 'Main', - ), $overrides)); - $this->callAPISuccess('Address', 'create', array( - 'street_address' => NULL, - 'contact_id' => $this->contactID2, - 'location_type_id' => 'Main', - )); - $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); - } - - /** - * Common code for testing blank address repairs. - */ - protected function prepareForBlankAddressTests() { - civicrm_api3('Setting', 'create', array( - 'logging_no_trigger_permission' => 0, - )); - civicrm_api3('Setting', 'create', array('logging' => 1)); - - CRM_Core_DAO::executeQuery('DROP TABLE IF EXISTS blank_addresses'); - require_once __DIR__ . '/../../wmf_civicrm.install'; - require_once __DIR__ . '/../../update_restore_addresses.php'; - wmf_civicrm_update_7475(); - } - - protected function cleanupFromBlankAddressRepairTests() { - CRM_Core_DAO::executeQuery('DROP TABLE blank_addresses'); - - civicrm_api3('Setting', 'create', array( - 'logging_no_trigger_permission' => 1, - )); - } - - protected function createContributions() { - $this->contributionCreate(array( - 'contact_id' => $this->contactID, - 'receive_date' => '2010-01-01', - 'invoice_id' => 1, - 'trxn_id' => 1 - )); - $this->contributionCreate(array( - 'contact_id' => $this->contactID2, - 'receive_date' => '2012-01-01', - 'invoice_id' => 2, - 'trxn_id' => 2 - )); - } - -} ->>>>>>> BRANCH (a8e86e Drop addresses without country) -- To view, visit https://gerrit.wikimedia.org/r/383905 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ia56ce1a613a129c9f4551924d344352b8961ab5f Gerrit-PatchSet: 1 Gerrit-Project: wikimedia/fundraising/crm Gerrit-Branch: deployment Gerrit-Owner: Ejegg <ej...@ejegg.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits