Add test to lock in obscure custom join handling
authoreileen <emcnaughton@wikimedia.org>
Mon, 4 Nov 2019 00:16:43 +0000 (13:16 +1300)
committereileen <emcnaughton@wikimedia.org>
Mon, 4 Nov 2019 03:33:38 +0000 (16:33 +1300)
tests/phpunit/CRM/Contact/BAO/QueryTest.php
tests/phpunit/CRM/Core/BAO/CustomFieldTest.php
tests/phpunit/CRM/Core/BAO/CustomQueryTest.php
tests/phpunit/CRMTraits/Custom/CustomDataTrait.php

index 9d4f0a578b32f5934e91ee4cb69727ed538d8836..cebffbf5e3edef6337757dd6277d4d705c38f970 100644 (file)
@@ -719,6 +719,8 @@ class CRM_Contact_BAO_QueryTest extends CiviUnitTestCase {
 
   /**
    * Test Relationship Clause
+   *
+   * @throws \CRM_Core_Exception
    */
   public function testRelationshipClause() {
     $today = date('Ymd');
index 53c1456ea6e112c36671bdd3c37cff6f4063a5d0..c11ad96b5b94ab95d74659da21c4f58c2380dd78 100644 (file)
@@ -586,7 +586,7 @@ class CRM_Core_BAO_CustomFieldTest extends CiviUnitTestCase {
         'text_length' => NULL,
         'data_type' => 'Date',
         'html_type' => 'Select Date',
-        'is_search_range' => '0',
+        'is_search_range' => '1',
         'date_format' => 'mm/dd/yy',
         'time_format' => '1',
         'id' => $this->getCustomFieldID('select_date'),
@@ -639,6 +639,38 @@ class CRM_Core_BAO_CustomFieldTest extends CiviUnitTestCase {
         'extends_table' => 'civicrm_contact',
         'search_table' => 'contact_a',
       ],
+      $this->getCustomFieldName('int') => [
+        'name' => $this->getCustomFieldName('int'),
+        'type' => CRM_Utils_Type::T_INT,
+        'title' => 'Enter integer here',
+        'headerPattern' => '//',
+        'import' => 1,
+        'custom_field_id' => $this->getCustomFieldID('int'),
+        'options_per_line' => NULL,
+        'text_length' => NULL,
+        'data_type' => 'Int',
+        'html_type' => 'Text',
+        'is_search_range' => '1',
+        'id' => $this->getCustomFieldID('int'),
+        'label' => 'Enter integer here',
+        'groupTitle' => 'Custom Group',
+        'default_value' => '4',
+        'custom_group_id' => $customGroupID,
+        'extends' => 'Contact',
+        'extends_entity_column_value' => NULL,
+        'extends_entity_column_id' => NULL,
+        'is_view' => '0',
+        'is_multiple' => '0',
+        'option_group_id' => NULL,
+        'date_format' => NULL,
+        'time_format' => NULL,
+        'is_required' => '1',
+        'table_name' => 'civicrm_value_custom_group_' . $customGroupID,
+        'column_name' => $this->getCustomFieldColumnName('int'),
+        'where' => 'civicrm_value_custom_group_' . $customGroupID . '.' . $this->getCustomFieldColumnName('int'),
+        'extends_table' => 'civicrm_contact',
+        'search_table' => 'contact_a',
+      ],
     ];
     $this->assertEquals($expected, CRM_Core_BAO_CustomField::getFieldsForImport());
   }
index 649969971af823e0d3ea35855a80b2b321f8d143..dc9f057997f5f08b6ad1c1ee817947d30d663fe8 100644 (file)
@@ -5,6 +5,7 @@
  * @group headless
  */
 class CRM_Core_BAO_CustomQueryTest extends CiviUnitTestCase {
+  use CRMTraits_Custom_CustomDataTrait;
 
   /**
    * Restore database to empty state.
@@ -23,6 +24,8 @@ class CRM_Core_BAO_CustomQueryTest extends CiviUnitTestCase {
 
   /**
    * Test filtering by relative custom data dates.
+   *
+   * @throws \CRM_Core_Exception
    */
   public function testSearchCustomDataDateRelative() {
     $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'ContactTestTest');
@@ -87,6 +90,8 @@ class CRM_Core_BAO_CustomQueryTest extends CiviUnitTestCase {
 
   /**
    * Test filtering by relative custom data dates.
+   *
+   * @throws \CRM_Core_Exception
    */
   public function testSearchCustomDataDateFromTo() {
     $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'ContactTestTest');
@@ -108,7 +113,7 @@ class CRM_Core_BAO_CustomQueryTest extends CiviUnitTestCase {
 
     $params[$dateCustomField['id']] = CRM_Contact_BAO_Query::convertFormValues($formValues);
     $queryObj = new CRM_Core_BAO_CustomQuery($params);
-    $queryObj->Query();
+    $queryObj->query();
     $this->assertEquals(
       'civicrm_value_testsearchcus_1.date_field_2 BETWEEN "20140606000000" AND "20150606235959"',
       $queryObj->_where[0][0]
@@ -153,7 +158,7 @@ class CRM_Core_BAO_CustomQueryTest extends CiviUnitTestCase {
 
       $params = [$customField['id'] => CRM_Contact_BAO_Query::convertFormValues($formValues)];
       $queryObj = new CRM_Core_BAO_CustomQuery($params);
-      $queryObj->Query();
+      $queryObj->query();
       $this->assertEquals(
         "civicrm_value_testsearchcus_1." . strtolower($type) . "_field_{$customField['id']} BETWEEN \"$from\" AND \"$to\"",
         $queryObj->_where[0][0]
@@ -200,7 +205,7 @@ class CRM_Core_BAO_CustomQueryTest extends CiviUnitTestCase {
 
       $params = [$customField['id'] => CRM_Contact_BAO_Query::convertFormValues($formValues)];
       $queryObj = new CRM_Core_BAO_CustomQuery($params);
-      $queryObj->Query();
+      $queryObj->query();
       $wierdStringThatMeansGreaterEquals = chr(226) . chr(137) . chr(164);
 
       $this->assertEquals(
@@ -218,7 +223,7 @@ class CRM_Core_BAO_CustomQueryTest extends CiviUnitTestCase {
 
       $params = [$customField['id'] => CRM_Contact_BAO_Query::convertFormValues($formValues)];
       $queryObj = new CRM_Core_BAO_CustomQuery($params);
-      $queryObj->Query();
+      $queryObj->query();
       $wierdStringThatMeansLessThanEquals = chr(226) . chr(137) . chr(165);
 
       $expectedValue = ($isDate) ? '"20150606000000"' : $expectedValue;
@@ -235,6 +240,8 @@ class CRM_Core_BAO_CustomQueryTest extends CiviUnitTestCase {
 
   /**
    * Test filtering by relative custom data dates.
+   *
+   * @throws \CRM_Core_Exception
    */
   public function testSearchCustomDataDateEquals() {
     $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'ContactTestTest');
@@ -253,7 +260,7 @@ class CRM_Core_BAO_CustomQueryTest extends CiviUnitTestCase {
     $formValues = [$dateCustomFieldName => '2015-06-06'];
     $params[$dateCustomField['id']] = CRM_Contact_BAO_Query::convertFormValues($formValues);
     $queryObj = new CRM_Core_BAO_CustomQuery($params);
-    $queryObj->Query();
+    $queryObj->query();
 
     $this->assertEquals(
       "civicrm_value_testsearchcus_1.date_field_2 = '2015-06-06'",
@@ -262,4 +269,36 @@ class CRM_Core_BAO_CustomQueryTest extends CiviUnitTestCase {
     $this->assertEquals($queryObj->_qill[0][0], "date field = 'June 6th, 2015'");
   }
 
+  /**
+   * Test search builder style query including custom address fields.
+   *
+   * @throws \CRM_Core_Exception
+   */
+  public function testAddressCustomFields() {
+    $this->createCustomGroupWithFieldOfType(['extends' => 'Address'], 'int');
+    $individualID = $this->individualCreate();
+    $this->callAPISuccess('Address', 'create', [
+      'contact_id' => $individualID,
+      'street_address' => '10 Downing Street',
+      'location_type_id' => 'Home',
+      $this->getCustomFieldName('int') => 5,
+    ]);
+
+    $queryObject = new CRM_Contact_BAO_Query(
+      [[$this->getCustomFieldName('int') . '-1', '=', 5, 1, 0]],
+      ['contact_type' => 1, 'location' => ['Home' => ['location_type' => 1, $this->getCustomFieldName('int') => 1]]]
+    );
+    $queryObject->query();
+    $tableName = $this->getCustomGroupTable();
+    $fieldName = $this->getCustomFieldColumnName('int');
+
+    $this->assertEquals([], $queryObject->_where[0]);
+    $this->assertEquals($tableName . '.' . $fieldName . ' = 5', implode(', ', $queryObject->_where[1]));
+    $this->assertEquals(1, $queryObject->_whereTables['civicrm_contact']);
+    $this->assertEquals('LEFT JOIN civicrm_address `Home-address` ON (`Home-address`.contact_id = contact_a.id AND `Home-address`.location_type_id = 1)', trim($queryObject->_whereTables['Home-address']));
+    $this->assertEquals("LEFT JOIN {$tableName} ON {$tableName}.entity_id = `Home-address`.id", trim($queryObject->_whereTables[$tableName]));
+    $this->assertEquals([], $queryObject->_qill[0]);
+    $this->assertEquals(['Enter integer here = 5'], $queryObject->_qill[1]);
+  }
+
 }
index 002000891be31e5174b5cc53bae4d554d1c53ab6..f282af1d54edab08418d022a05bcfc4933624606 100644 (file)
@@ -52,13 +52,37 @@ trait CRMTraits_Custom_CustomDataTrait {
   public function createCustomGroup($params = []) {
     $params = array_merge([
       'title' => 'Custom Group',
-      'extends' => [$this->entity],
+      'extends' => [$this->entity ?? 'Contact'],
       'weight' => 5,
       'style' => 'Inline',
       'max_multiple' => 0,
     ], $params);
-    $this->ids['CustomGroup'][$params['title']] = $this->callAPISuccess('CustomGroup', 'create', $params)['id'];
-    return $this->ids['CustomGroup'][$params['title']];
+    $identifier = $params['name'] ?? $params['title'];
+    $this->ids['CustomGroup'][$identifier] = $this->callAPISuccess('CustomGroup', 'create', $params)['id'];
+    return $this->ids['CustomGroup'][$identifier];
+  }
+
+  /**
+   * Get the table_name for the specified custom group.
+   *
+   * @param string $identifier
+   *
+   * @return string
+   */
+  public function getCustomGroupTable($identifier = 'Custom Group') {
+    return $this->callAPISuccessGetValue('CustomGroup', ['id' => $this->ids['CustomGroup'][$identifier], 'return' => 'table_name']);
+  }
+
+  /**
+   * Get the the column name for the identified custom field.
+   *
+   * @param string $key
+   *   Identifier - generally keys map to data type - eg. 'text', 'int' etc.
+   *
+   * @return string
+   */
+  protected function getCustomFieldColumnName($key) {
+    return $this->callAPISuccessGetValue('CustomField', ['id' => $this->getCustomFieldID($key), 'return' => 'column_name']);
   }
 
   /**
@@ -71,24 +95,29 @@ trait CRMTraits_Custom_CustomDataTrait {
    *
    * @throws \CRM_Core_Exception
    */
-  public function createCustomGroupWithFieldOfType($groupParams = [], $customFieldType = 'text', $identifier = '') {
-    $supported = ['text', 'select', 'date'];
-    if (!in_array($customFieldType, $supported)) {
+  public function createCustomGroupWithFieldOfType($groupParams = [], $customFieldType = 'text', $identifier = NULL) {
+    $supported = ['text', 'select', 'date', 'int'];
+    if (!in_array($customFieldType, $supported, TRUE)) {
       throw new CRM_Core_Exception('we have not yet extracted other custom field types from createCustomFieldsOfAllTypes, Use consistent syntax when you do');
     }
     $groupParams['title'] = empty($groupParams['title']) ? $identifier . 'Group with field ' . $customFieldType : $groupParams['title'];
+    $groupParams['name'] = $identifier ?? 'Custom Group';
     $this->createCustomGroup($groupParams);
     switch ($customFieldType) {
       case 'text':
-        $customField = $this->createTextCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['title']]]);
+        $customField = $this->createTextCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['name']]]);
         break;
 
       case 'select':
-        $customField = $this->createSelectCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['title']]]);
+        $customField = $this->createSelectCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['name']]]);
+        break;
+
+      case 'int':
+        $customField = $this->createIntCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['name']]]);
         break;
 
       case 'date':
-        $customField = $this->createDateCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['title']]]);
+        $customField = $this->createDateCustomField(['custom_group_id' => $this->ids['CustomGroup'][$groupParams['name']]]);
         break;
     }
     $this->ids['CustomField'][$identifier . $customFieldType] = $customField['id'];
@@ -107,8 +136,11 @@ trait CRMTraits_Custom_CustomDataTrait {
     $ids['select_string'] = $customField['id'];
 
     $customField = $this->createDateCustomField(['custom_group_id' => $customGroupID]);
-
     $ids['select_date'] = $customField['id'];
+
+    $customField = $this->createIntCustomField(['custom_group_id' => $customGroupID]);
+    $ids['int'] = $customField['id'];
+
     $params = [
       'custom_group_id' => $customGroupID,
       'name' => 'test_link',
@@ -157,8 +189,7 @@ trait CRMTraits_Custom_CustomDataTrait {
    * @return string
    */
   protected function getCustomFieldName($key) {
-    $linkField = 'custom_' . $this->getCustomFieldID($key);
-    return $linkField;
+    return 'custom_' . $this->getCustomFieldID($key);
   }
 
   /**
@@ -173,8 +204,31 @@ trait CRMTraits_Custom_CustomDataTrait {
    * @return string
    */
   protected function getCustomFieldID($key) {
-    $linkField = $this->ids['CustomField'][$key];
-    return $linkField;
+    return $this->ids['CustomField'][$key];
+  }
+
+  /**
+   * Create a custom text fields.
+   *
+   * @param array $params
+   *   Parameter overrides, must include custom_group_id.
+   *
+   * @return array
+   */
+  protected function createIntCustomField($params = []) {
+    $params = array_merge([
+      'label' => 'Enter integer here',
+      'html_type' => 'Text',
+      'data_type' => 'Int',
+      'default_value' => '4',
+      'weight' => 1,
+      'is_required' => 1,
+      'sequential' => 1,
+      'is_searchable' => 1,
+      'is_search_range' => 1,
+    ], $params);
+
+    return $this->callAPISuccess('CustomField', 'create', $params)['values'][0];
   }
 
   /**
@@ -261,6 +315,8 @@ trait CRMTraits_Custom_CustomDataTrait {
       'data_type' => 'Date',
       'default_value' => '20090711',
       'weight' => 3,
+      'is_searchable' => 1,
+      'is_search_range' => 1,
       'time_format' => 1,
     ], $params);