From: eileen Date: Wed, 29 Jun 2016 08:19:41 +0000 (+1200) Subject: CRM-19029 Additional tests for merge function X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=5d8b37be5cf92c5bc93c62cfaf5dcc17ce838654;p=civicrm-core.git CRM-19029 Additional tests for merge function --- diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index f0beda43de..fa83348512 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -1165,16 +1165,17 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase { * @return mixed */ public function contactMembershipCreate($params) { - $pre = array( + $params = array_merge(array( 'join_date' => '2007-01-21', 'start_date' => '2007-01-21', 'end_date' => '2007-12-21', 'source' => 'Payment', - ); - - foreach ($pre as $key => $val) { - if (!isset($params[$key])) { - $params[$key] = $val; + 'membership_type_id' => 'General', + ), $params); + if (!is_numeric($params['membership_type_id'])) { + $membershipTypes = $this->callAPISuccess('Membership', 'getoptions', array('action' => 'create', 'field' => 'membership_type_id')); + if (!in_array($params['membership_type_id'], $membershipTypes['values'])) { + $this->membershipTypeCreate(array('name' => $params['membership_type_id'])); } } @@ -1957,40 +1958,37 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase { * @param array $params * @return array|int */ - public function activityCreate($params = NULL) { - - if ($params === NULL) { - $individualSourceID = $this->individualCreate(); - - $contactParams = array( + public function activityCreate($params = array()) { + $params = array_merge(array( + 'subject' => 'Discussion on warm beer', + 'activity_date_time' => date('Ymd'), + 'duration_hours' => 30, + 'duration_minutes' => 20, + 'location' => 'Baker Street', + 'details' => 'Lets schedule a meeting', + 'status_id' => 1, + 'activity_name' => 'Meeting', + ), $params); + if (!isset($params['source_contact_id'])) { + $params['source_contact_id'] = $this->individualCreate(); + } + if (!isset($params['target_contact_id'])) { + $params['target_contact_id'] = $this->individualCreate(array( 'first_name' => 'Julia', 'Last_name' => 'Anderson', 'prefix' => 'Ms.', 'email' => 'julia_anderson@civicrm.org', 'contact_type' => 'Individual', - ); - - $individualTargetID = $this->individualCreate($contactParams); - - $params = array( - 'source_contact_id' => $individualSourceID, - 'target_contact_id' => array($individualTargetID), - 'assignee_contact_id' => array($individualTargetID), - 'subject' => 'Discussion on warm beer', - 'activity_date_time' => date('Ymd'), - 'duration_hours' => 30, - 'duration_minutes' => 20, - 'location' => 'Baker Street', - 'details' => 'Lets schedule a meeting', - 'status_id' => 1, - 'activity_name' => 'Meeting', - ); + )); + } + if (!isset($params['assignee_contact_id'])) { + $params['assignee_contact_id'] = $params['target_contact_id']; } $result = $this->callAPISuccess('Activity', 'create', $params); - $result['target_contact_id'] = $individualTargetID; - $result['assignee_contact_id'] = $individualTargetID; + $result['target_contact_id'] = $params['target_contact_id']; + $result['assignee_contact_id'] = $params['assignee_contact_id']; return $result; } diff --git a/tests/phpunit/api/v3/JobTest.php b/tests/phpunit/api/v3/JobTest.php index fe4f3a0871..975b44ee29 100644 --- a/tests/phpunit/api/v3/JobTest.php +++ b/tests/phpunit/api/v3/JobTest.php @@ -46,9 +46,18 @@ class api_v3_JobTest extends CiviUnitTestCase { public $DBResetRequired = FALSE; public $_entity = 'Job'; public $_params = array(); + /** + * Created membership type. + * + * Must be created outside the transaction due to it breaking the transaction. + * + * @var + */ + public $membershipTypeID; public function setUp() { parent::setUp(); + $this->membershipTypeID = $this->membershipTypeCreate(array('name' => 'General')); $this->useTransaction(TRUE); $this->_params = array( 'sequential' => 1, @@ -62,6 +71,11 @@ class api_v3_JobTest extends CiviUnitTestCase { ); } + public function tearDown() { + parent::tearDown(); + $this->membershipTypeDelete(array('id' => $this->membershipTypeID)); + } + /** * Check with no name. */ @@ -344,15 +358,123 @@ class api_v3_JobTest extends CiviUnitTestCase { $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => $dataSet['mode'])); $this->assertEquals($dataSet['skipped'], count($result['values']['skipped']), 'Failed to skip the right number:' . $dataSet['skipped']); $this->assertEquals($dataSet['merged'], count($result['values']['merged'])); - $result = $this->callAPISuccess('Contact', 'get', array('contact_sub_type' => 'Student', 'sequential' => 1)); + $result = $this->callAPISuccess('Contact', 'get', array( + 'contact_sub_type' => 'Student', + 'sequential' => 1, + 'options' => array('sort' => 'id ASC'), + )); $this->assertEquals(count($dataSet['expected']), $result['count']); foreach ($dataSet['expected'] as $index => $contact) { foreach ($contact as $key => $value) { + // Handle the fact it's in a different field in the return value. + if ($key == 'gender_id') { + $key = 'gender'; + } $this->assertEquals($value, $result['values'][$index][$key]); } } } + /** + * Check that the merge carries across various related entities. + * + * Note the group combinations & expected results: + */ + public function testBatchMergeWithAssets() { + $contactID = $this->individualCreate(); + $contact2ID = $this->individualCreate(); + $this->contributionCreate(array('contact_id' => $contactID)); + $this->contributionCreate(array('contact_id' => $contact2ID, 'invoice_id' => '2', 'trxn_id' => 2)); + $this->contactMembershipCreate(array('contact_id' => $contactID)); + $this->contactMembershipCreate(array('contact_id' => $contact2ID)); + $this->activityCreate(array('source_contact_id' => $contactID, 'target_contact_id' => $contactID, 'assignee_contact_id' => $contactID)); + $this->activityCreate(array('source_contact_id' => $contact2ID, 'target_contact_id' => $contact2ID, 'assignee_contact_id' => $contact2ID)); + $this->tagCreate(array('name' => 'Tall')); + $this->tagCreate(array('name' => 'Short')); + $this->entityTagAdd(array('contact_id' => $contactID, 'tag_id' => 'Tall')); + $this->entityTagAdd(array('contact_id' => $contact2ID, 'tag_id' => 'Short')); + $this->entityTagAdd(array('contact_id' => $contact2ID, 'tag_id' => 'Tall')); + $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); + $this->assertEquals(0, count($result['values']['skipped'])); + $this->assertEquals(1, count($result['values']['merged'])); + $this->callAPISuccessGetCount('Contribution', array('contact_id' => $contactID), 2); + $this->callAPISuccessGetCount('Contribution', array('contact_id' => $contact2ID), 0); + $this->callAPISuccessGetCount('FinancialItem', array('contact_id' => $contactID), 2); + $this->callAPISuccessGetCount('FinancialItem', array('contact_id' => $contact2ID), 0); + $this->callAPISuccessGetCount('Membership', array('contact_id' => $contactID), 2); + $this->callAPISuccessGetCount('Membership', array('contact_id' => $contact2ID), 0); + $this->callAPISuccessGetCount('EntityTag', array('contact_id' => $contactID), 2); + $this->callAPISuccessGetCount('EntityTag', array('contact_id' => $contact2ID), 0); + // 12 activities is one for each contribution (2), one for each membership (+2 = 4) + // 3 for each of the added activities as there are 3 roles (+6 = 10 + // 2 for the (source & target) contact merged activity (+2 = 12) + $this->callAPISuccessGetCount('ActivityContact', array('contact_id' => $contactID), 12); + // 2 for the connection to the deleted by merge activity (source & target) + $this->callAPISuccessGetCount('ActivityContact', array('contact_id' => $contact2ID), 2); + } + + /** + * Check that the merge carries across various related entities. + * + * Note the group combinations 'expected' results: + * + * Group 0 Added null Added + * Group 1 Added Added Added + * Group 2 Added Removed **** Added + * Group 3 Removed null **** null + * Group 4 Removed Added **** Added + * Group 5 Removed Removed **** null + * Group 6 null Added Added + * Group 7 null Removed **** null + * + * The ones with **** are the ones where I think a case could be made to change the behaviour. + */ + public function testBatchMergeMergesGroups() { + $contactID = $this->individualCreate(); + $contact2ID = $this->individualCreate(); + $groups = array(); + for ($i = 0; $i < 8; $i++) { + $groups[] = $this->groupCreate(array('name' => 'mergeGroup' . $i, 'title' => 'merge group' . $i)); + } + + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contactID, 'group_id' => $groups[0])); + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contactID, 'group_id' => $groups[1])); + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contactID, 'group_id' => $groups[2])); + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contactID, 'group_id' => $groups[3], 'status' => 'Removed')); + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contactID, 'group_id' => $groups[4], 'status' => 'Removed')); + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contactID, 'group_id' => $groups[5], 'status' => 'Removed')); + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contact2ID, 'group_id' => $groups[1])); + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contact2ID, 'group_id' => $groups[2], 'status' => 'Removed')); + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contact2ID, 'group_id' => $groups[4])); + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contact2ID, 'group_id' => $groups[5], 'status' => 'Removed')); + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contact2ID, 'group_id' => $groups[6])); + $this->callAPISuccess('GroupContact', 'create', array('contact_id' => $contact2ID, 'group_id' => $groups[7], 'status' => 'Removed')); + $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'safe')); + $this->assertEquals(0, count($result['values']['skipped'])); + $this->assertEquals(1, count($result['values']['merged'])); + $groupResult = $this->callAPISuccess('GroupContact', 'get', array()); + $this->assertEquals(5, $groupResult['count']); + $expectedGroups = array($groups[0], $groups[1], $groups[2], $groups[4], $groups[6]); + foreach ($groupResult['values'] as $groupValues) { + $this->assertEquals($contactID, $groupValues['contact_id']); + $this->assertEquals('Added', $groupValues['status']); + $this->assertTrue(in_array($groupValues['group_id'], $expectedGroups)); + } + } + + /** + * Test the organization will not be matched to an individual. + */ + public function testBatchMergeWillNotMergeOrganizationToIndividual() { + $individual = $this->callAPISuccess('Contact', 'create', array('contact_type' => 'Individual', 'organization_name' => 'Anon', 'email' => 'anonymous@hacker.com')); + $organization = $this->callAPISuccess('Contact', 'create', array('contact_type' => 'Organization', 'organization_name' => 'Anon', 'email' => 'anonymous@hacker.com')); + $result = $this->callAPISuccess('Job', 'process_batch_merge', array('mode' => 'aggressive')); + $this->assertEquals(0, count($result['values']['skipped'])); + $this->assertEquals(0, count($result['values']['merged'])); + $this->callAPISuccessGetSingle('Contact', array('id' => $individual['id'])); + $this->callAPISuccessGetSingle('Contact', array('id' => $organization['id'])); + } + /** * Test the batch merge does not create duplicate emails. * @@ -755,6 +877,42 @@ class api_v3_JobTest extends CiviUnitTestCase { ), ), ); + + $conflictPairs = array( + 'first_name' => 'Dianna', + 'last_name' => 'McAndrew', + 'middle_name' => 'Prancer', + 'birth_date' => '2015-12-25', + 'gender_id' => 'Female', + 'job_title' => 'Thriller', + ); + + foreach ($conflictPairs as $key => $value) { + $contactParams = array( + 'first_name' => 'Michael', + 'middle_name' => 'Dancer', + 'last_name' => 'Jackson', + 'birth_date' => '2015-02-25', + 'email' => 'michael@neverland.com', + 'contact_type' => 'Individual', + 'contact_sub_type' => array('Student'), + 'gender_id' => 'Male', + 'job_title' => 'Entertainer', + ); + $contact2 = $contactParams; + + $contact2[$key] = $value; + $data[$key . '_conflict'] = array( + array( + 'mode' => 'safe', + 'contacts' => array($contactParams, $contact2), + 'skipped' => 1, + 'merged' => 0, + 'expected' => array($contactParams, $contact2), + ), + ); + } + return $data; } diff --git a/tests/phpunit/api/v3/MembershipTest.php b/tests/phpunit/api/v3/MembershipTest.php index dbc4a5458c..9132aa3563 100644 --- a/tests/phpunit/api/v3/MembershipTest.php +++ b/tests/phpunit/api/v3/MembershipTest.php @@ -62,6 +62,7 @@ class api_v3_MembershipTest extends CiviUnitTestCase { 'fixed_period_start_day' => '301', // Ie. 11 Nov. 'fixed_period_rollover_day' => '1111', + 'name' => 'Another one', )); $this->_membershipStatusID = $this->membershipStatusCreate('test status'); @@ -531,7 +532,7 @@ class api_v3_MembershipTest extends CiviUnitTestCase { 'id' => $OrganizationMembershipID, 'max_related' => 3, ); - $this->contactMembershipCreate($params); + $this->callAPISuccess('Membership', 'create', $params); // Check that the employee inherited the membership $params = array( @@ -1398,7 +1399,7 @@ class api_v3_MembershipTest extends CiviUnitTestCase { */ public function testGetOptionsMembershipTypeID() { $options = $this->callAPISuccess('Membership', 'getoptions', array('field' => 'membership_type_id')); - $this->assertEquals('General', array_pop($options['values'])); + $this->assertEquals('Another one', array_pop($options['values'])); $this->assertEquals('General', array_pop($options['values'])); $this->assertEquals(NULL, array_pop($options['values'])); }