Merge remote-tracking branch 'upstream/4.6' into 4.6-master-2015-09-15-10-14-22
[civicrm-core.git] / tests / phpunit / api / v3 / ContactTest.php
index e8660cc92e400f1f93d8bcf9d57e7f39beec3eab..137496eb71a5c505b211a0e8c9580d2e29dc594d 100644 (file)
@@ -84,6 +84,7 @@ class api_v3_ContactTest extends CiviUnitTestCase {
       'civicrm_relationship',
       'civicrm_uf_match',
       'civicrm_phone',
+      'civicrm_address',
     );
 
     $this->quickCleanup($tablesToTruncate, TRUE);
@@ -406,8 +407,8 @@ class api_v3_ContactTest extends CiviUnitTestCase {
 
     $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
     $customFldId = $result['values'][$result['id']]['api.CustomField.create']['id'];
-    $this->assertNotNull($result['id'], 'in line ' . __LINE__);
-    $this->assertNotNull($customFldId, 'in line ' . __LINE__);
+    $this->assertNotNull($result['id']);
+    $this->assertNotNull($customFldId);
 
     $params = array(
       'id' => $result['id'],
@@ -416,9 +417,9 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     );
 
     $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
-    $this->assertNotNull($result['id'], 'in line ' . __LINE__);
+    $this->assertNotNull($result['id']);
     $customFldDate = date("YmdHis", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
-    $this->assertNotNull($customFldDate, 'in line ' . __LINE__);
+    $this->assertNotNull($customFldDate);
     $this->assertEquals($dateTime, $customFldDate);
     $customValueId = $result['values'][$result['id']]['api.CustomValue.get']['values'][0]['id'];
     $dateTime = date('Ymd');
@@ -439,10 +440,10 @@ class api_v3_ContactTest extends CiviUnitTestCase {
       'api.CustomValue.get' => 1,
     );
     $result = $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
-    $this->assertNotNull($result['id'], 'in line ' . __LINE__);
+    $this->assertNotNull($result['id']);
     $customFldDate = date("Ymd", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
     $customFldTime = date("His", strtotime($result['values'][$result['id']]['api.CustomValue.get']['values'][0]['latest']));
-    $this->assertNotNull($customFldDate, 'in line ' . __LINE__);
+    $this->assertNotNull($customFldDate);
     $this->assertEquals($dateTime, $customFldDate);
     $this->assertEquals(000000, $customFldTime);
     $this->callAPIAndDocument('Contact', 'create', $params, __FUNCTION__, __FILE__);
@@ -1658,7 +1659,6 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     $params['custom_' . $ids['custom_field_id']] = "custom string";
 
     $moreIDs = $this->CustomGroupMultipleCreateWithFields();
-
     $params = array(
       'sequential' => 1,
       'first_name' => 'abc3',
@@ -2018,10 +2018,9 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     $this->createContactFromXML();
     $description = "This demonstrates use of the 'getCount' action.
       This param causes the count of the only function to be returned as an integer.";
-    $subfile = "GetCountContact";
     $params = array('id' => 17);
     $result = $this->callAPIAndDocument('Contact', 'GetCount', $params, __FUNCTION__, __FILE__, $description,
-      $subfile);
+      'GetCountContact');
     $this->assertEquals('1', $result);
     $this->callAPISuccess('Contact', 'Delete', $params);
   }
@@ -2143,7 +2142,7 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     );
 
     $result = $this->callAPISuccess('address', 'create', $params);
-    $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
+    $this->assertEquals(1, $result['count']);
 
     // now do a proximity search with a close enough geocode and hope to match
     // that specific contact only!
@@ -2154,7 +2153,7 @@ class api_v3_ContactTest extends CiviUnitTestCase {
       'distance' => 10,
     );
     $result = $this->callAPISuccess('contact', 'proximity', $proxParams);
-    $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
+    $this->assertEquals(1, $result['count']);
   }
 
   /**
@@ -2171,6 +2170,289 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     $this->callAPISuccess('contact', 'getquick', array('name' => 'b', 'check_permissions' => TRUE));
   }
 
+  /**
+   * Test that getquick returns contacts with an exact first name match first.
+   *
+   * The search string 'b' & 'bob' both return ordered by sort_name if includeOrderByClause
+   * is true (default) but if it is false then matches are returned in ID order.
+   */
+  public function testGetQuickExactFirst() {
+    $this->getQuickSearchSampleData();
+    $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'b'));
+    $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
+    $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
+    $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
+    $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
+    $this->assertEquals('B Bobby, Bobby', $result['values'][1]['sort_name']);
+    $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
+    $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
+    $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
+    $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
+  }
+
+  /**
+   * Test that getquick returns contacts with an exact first name match first.
+   */
+  public function testGetQuickEmail() {
+    $this->getQuickSearchSampleData();
+    $userID = $this->createLoggedInUser();
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'c',
+    ));
+    $expectedData = array(
+      'Bob, Bob :: bob@bob.com',
+      'C Bobby, Bobby',
+      'E Bobby, Bobby :: bob@bobby.com',
+      'H Bobby, Bobby :: bob@h.com',
+    );
+    $this->assertEquals(5, $result['count']);
+    foreach ($expectedData as $index => $value) {
+      $this->assertEquals($value, $result['values'][$index]['data']);
+    }
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'h.',
+    ));
+    $expectedData = array(
+      'H Bobby, Bobby :: bob@h.com',
+    );
+    foreach ($expectedData as $index => $value) {
+      $this->assertEquals($value, $result['values'][$index]['data']);
+    }
+    $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => FALSE));
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'h.',
+    ));
+    $this->callAPISuccess('Setting', 'create', array('includeWildCardInName' => TRUE));
+    $this->assertEquals(0, $result['count']);
+  }
+
+  /**
+   * Test that getquick returns contacts with an exact first name match first.
+   */
+  public function testGetQuickEmailACL() {
+    $this->getQuickSearchSampleData();
+    $userID = $this->createLoggedInUser();
+    CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'c',
+    ));
+    $this->assertEquals(0, $result['count']);
+
+    $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
+    CRM_Contact_BAO_Contact_Permission::cache($userID, CRM_Core_Permission::VIEW, TRUE);
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'c',
+    ));
+    // Without the acl it would be 5 like the previous email getquick test.
+    $this->assertEquals(4, $result['count']);
+    $expectedData = array(
+      'Bob, Bob :: bob@bob.com',
+      'C Bobby, Bobby',
+      'E Bobby, Bobby :: bob@bobby.com',
+    );
+    foreach ($expectedData as $index => $value) {
+      $this->assertEquals($value, $result['values'][$index]['data']);
+    }
+  }
+
+  /**
+   * Test that getquick returns contacts with an exact first name match first.
+   */
+  public function testGetQuickExternalID() {
+    $this->getQuickSearchSampleData();
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'b',
+      'field_name' => 'external_identifier',
+      'table_name' => 'cc',
+    ));
+    $this->assertEquals(0, $result['count']);
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'abc',
+      'field_name' => 'external_identifier',
+      'table_name' => 'cc',
+    ));
+    $this->assertEquals(1, $result['count']);
+    $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
+  }
+
+  /**
+   * Test that getquick returns contacts with an exact first name match first.
+   */
+  public function testGetQuickID() {
+    $this->getQuickSearchSampleData();
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 2,
+      'field_name' => 'id',
+      'table_name' => 'cc',
+    ));
+    $this->assertEquals(1, $result['count']);
+    $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 2,
+      'field_name' => 'contact_id',
+      'table_name' => 'cc',
+    ));
+    $this->assertEquals(1, $result['count']);
+    $this->assertEquals('A Bobby, Bobby', $result['values'][0]['sort_name']);
+  }
+
+  /**
+   * Test that getquick returns contacts with an exact first name match first.
+   *
+   * Depending on the setting the sort name sort might click in next or not - test!
+   */
+  public function testGetQuickFirstName() {
+    $this->getQuickSearchSampleData();
+    $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'Bob',
+      'field_name' => 'first_name',
+      'table_name' => 'cc',
+    ));
+    $expected = array(
+      'Bob, Bob',
+      'K Bobby, Bob',
+      'A Bobby, Bobby',
+    );
+
+    foreach ($expected as $index => $value) {
+      $this->assertEquals($value, $result['values'][$index]['sort_name']);
+    }
+    $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
+    $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
+    $this->assertEquals('Bob, Bob', $result['values'][0]['sort_name']);
+    $this->assertEquals('A Bobby, Bobby', $result['values'][1]['sort_name']);
+  }
+
+  /**
+   * Test that getquick applies ACLs.
+   */
+  public function testGetQuickFirstNameACLs() {
+    $this->getQuickSearchSampleData();
+    $userID = $this->createLoggedInUser();
+    $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
+    CRM_Core_Config::singleton()->userPermissionClass->permissions = array();
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'Bob',
+      'field_name' => 'first_name',
+      'table_name' => 'cc',
+    ));
+    $this->assertEquals(0, $result['count']);
+
+    $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereNoBobH'));
+    CRM_Contact_BAO_Contact_Permission::cache($userID, CRM_Core_Permission::VIEW, TRUE);
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'Bob',
+      'field_name' => 'first_name',
+      'table_name' => 'cc',
+    ));
+    $this->assertEquals('K Bobby, Bob', $result['values'][1]['sort_name']);
+    // Without the ACL 9 would be bob@h.com.
+    $this->assertEquals('I Bobby, Bobby', $result['values'][9]['sort_name']);
+  }
+
+  /**
+   * Full results returned.
+   * @implements CRM_Utils_Hook::aclWhereClause
+   *
+   * @param string $type
+   * @param array $tables
+   * @param array $whereTables
+   * @param int $contactID
+   * @param string $where
+   */
+  public function aclWhereNoBobH($type, &$tables, &$whereTables, &$contactID, &$where) {
+    $where = " (email <> 'bob@h.com' OR email IS NULL) ";
+    $whereTables['civicrm_email'] = "LEFT JOIN civicrm_email e ON contact_a.id = e.contact_id";
+  }
+
+  /**
+   * Test that getquick returns contacts with an exact last name match first.
+   */
+  public function testGetQuickLastName() {
+    $this->getQuickSearchSampleData();
+    $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => TRUE));
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'Bob',
+      'field_name' => 'last_name',
+      'table_name' => 'cc',
+    ));
+    $expected = array(
+      'Bob, Bob',
+      'A Bobby, Bobby',
+      'B Bobby, Bobby',
+    );
+
+    foreach ($expected as $index => $value) {
+      $this->assertEquals($value, $result['values'][$index]['sort_name']);
+    }
+    $this->callAPISuccess('Setting', 'create', array('includeOrderByClause' => FALSE));
+    $result = $this->callAPISuccess('contact', 'getquick', array('name' => 'bob'));
+    $this->assertEquals('Bob, Bob :: bob@bob.com', $result['values'][0]['data']);
+  }
+
+  /**
+   * Test that getquick returns contacts by city.
+   */
+  public function testGetQuickCity() {
+    $this->getQuickSearchSampleData();
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'o',
+      'field_name' => 'city',
+      'table_name' => 'sts',
+    ));
+    $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
+    $result = $this->callAPISuccess('contact', 'getquick', array(
+      'name' => 'n',
+      'field_name' => 'city',
+      'table_name' => 'sts',
+    ));
+    $this->assertEquals('B Bobby, Bobby :: Toronto', $result['values'][0]['data']);
+    $this->assertEquals('C Bobby, Bobby :: Whanganui', $result['values'][1]['data']);
+  }
+
+  /**
+   * Set up some sample data for testing quicksearch.
+   */
+  public function getQuickSearchSampleData() {
+    $contacts = array(
+      array('first_name' => 'Bob', 'last_name' => 'Bob', 'external_identifier' => 'abc', 'email' => 'bob@bob.com'),
+      array('first_name' => 'Bobby', 'last_name' => 'A Bobby', 'external_identifier' => 'abcd'),
+      array(
+        'first_name' => 'Bobby',
+        'last_name' => 'B Bobby',
+        'external_identifier' => 'bcd',
+        'api.address.create' => array(
+          'street_address' => 'Sesame Street',
+          'city' => 'Toronto',
+          'location_type_id' => 1,
+        ),
+      ),
+      array(
+        'first_name' => 'Bobby',
+        'last_name' => 'C Bobby',
+        'external_identifier' => 'bcde',
+        'api.address.create' => array(
+          'street_address' => 'Te huarahi',
+          'city' => 'Whanganui',
+          'location_type_id' => 1,
+        ),
+      ),
+      array('first_name' => 'Bobby', 'last_name' => 'D Bobby', 'external_identifier' => 'efg'),
+      array('first_name' => 'Bobby', 'last_name' => 'E Bobby', 'external_identifier' => 'hij', 'email' => 'bob@bobby.com'),
+      array('first_name' => 'Bobby', 'last_name' => 'F Bobby', 'external_identifier' => 'klm'),
+      array('first_name' => 'Bobby', 'last_name' => 'G Bobby', 'external_identifier' => 'nop'),
+      array('first_name' => 'Bobby', 'last_name' => 'H Bobby', 'external_identifier' => 'qrs', 'email' => 'bob@h.com'),
+      array('first_name' => 'Bobby', 'last_name' => 'I Bobby'),
+      array('first_name' => 'Bobby', 'last_name' => 'J Bobby'),
+      array('first_name' => 'Bob', 'last_name' => 'K Bobby', 'external_identifier' => 'bcdef'),
+    );
+    foreach ($contacts as $type => $contact) {
+      $contact['contact_type'] = 'Individual';
+      $this->callAPISuccess('Contact', 'create', $contact);
+    }
+  }
+
   /**
    * Test get ref api - gets a list of references to an entity.
    */
@@ -2305,14 +2587,14 @@ class api_v3_ContactTest extends CiviUnitTestCase {
     $this->individualCreate(array('last_name' => $name, 'is_deleted' => 1));
     // We should get all but the deleted contact.
     $result = $this->callAPISuccess('contact', 'getlist', array('input' => $name));
-    $this->assertEquals(2, $result['count'], 'In line ' . __LINE__);
+    $this->assertEquals(2, $result['count']);
     // Force-exclude the deceased contact.
     $result = $this->callAPISuccess('contact', 'getlist', array(
       'input' => $name,
       'params' => array('is_deceased' => 0),
     ));
-    $this->assertEquals(1, $result['count'], 'In line ' . __LINE__);
-    $this->assertEquals($contact, $result['values'][0]['id'], 'In line ' . __LINE__);
+    $this->assertEquals(1, $result['count']);
+    $this->assertEquals($contact, $result['values'][0]['id']);
   }
 
   /**