Merge pull request #6037 from colemanw/CRM-16512
[civicrm-core.git] / tests / phpunit / CiviTest / CiviUnitTestCase.php
index 7f4f3b509050f0f5d3a22aeb6daf82ce6c9ca03c..bb9fe0502073e6b87a8eb715d2033b220516bcb0 100755 (executable)
@@ -375,9 +375,6 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
 
     // also set this global hack
     $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array();
-
-    $env = new CRM_Utils_Check_Env();
-    CRM_Utils_Check::singleton()->assertValid($env->checkMysqlTime());
   }
 
   /**
@@ -424,6 +421,11 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     // reset all the caches
     CRM_Utils_System::flushCache();
 
+    // Make sure the DB connection is setup properly
+    $config->userSystem->setMySQLTimeZone();
+    $env = new CRM_Utils_Check_Env();
+    CRM_Utils_Check::singleton()->assertValid($env->checkMysqlTime());
+
     // clear permissions stub to not check permissions
     $config = CRM_Core_Config::singleton();
     $config->userPermissionClass->permissions = NULL;
@@ -471,6 +473,9 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * Emulate a logged in user since certain functions use that.
    * value to store a record in the DB (like activity)
    * CRM-8180
+   *
+   * @return int
+   *   Contact ID of the created user.
    */
   public function createLoggedInUser() {
     $params = array(
@@ -479,9 +484,15 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
       'contact_type' => 'Individual',
     );
     $contactID = $this->individualCreate($params);
+    $this->callAPISuccess('UFMatch', 'create', array(
+      'contact_id' => $contactID,
+      'uf_name' => 'superman',
+      'uf_id' => 6,
+    ));
 
     $session = CRM_Core_Session::singleton();
     $session->set('userID', $contactID);
+    return $contactID;
   }
 
   public function cleanDB() {
@@ -523,7 +534,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
       CRM_Core_Transaction::forceRollbackIfEnabled();
       \Civi\Core\Transaction\Manager::singleton(TRUE);
 
-      $tablesToTruncate = array('civicrm_contact');
+      $tablesToTruncate = array('civicrm_contact', 'civicrm_uf_match');
       $this->quickCleanup($tablesToTruncate);
       $this->createDomainContacts();
     }
@@ -906,6 +917,39 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     return civicrm_api($entity, $action, $params);
   }
 
+  /**
+   * Create a batch of external API calls which can
+   * be executed concurrently.
+   *
+   * @code
+   * $calls = $this->createExternalAPI()
+   *    ->addCall('Contact', 'get', ...)
+   *    ->addCall('Contact', 'get', ...)
+   *    ...
+   *    ->run()
+   *    ->getResults();
+   * @endcode
+   *
+   * @return \Civi\API\ExternalBatch
+   * @throws PHPUnit_Framework_SkippedTestError
+   */
+  public function createExternalAPI() {
+    global $civicrm_root;
+    $defaultParams = array(
+      'version' => $this->_apiversion,
+      'debug' => 1,
+    );
+
+    $calls = new \Civi\API\ExternalBatch($defaultParams);
+    $calls->setSettingsPath("$civicrm_root/tests/phpunit/CiviTest/civicrm.settings.cli.php");
+
+    if (!$calls->isSupported()) {
+      $this->markTestSkipped('The test relies on Civi\API\ExternalBatch. This is unsupported in the local environment.');
+    }
+
+    return $calls;
+  }
+
   /**
    * wrap api functions.
    * so we can ensure they succeed & throw exceptions without litterering the test with checks
@@ -1050,14 +1094,14 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * @param string $file
    *   Pass this in to create a generated example.
    * @param string $description
-   * @param string|null $subfile
-   * @param string|null $actionName
+   * @param string|null $exampleName
+   *
    * @return array|int
    */
-  public function callAPIAndDocument($entity, $action, $params, $function, $file, $description = "", $subfile = NULL, $actionName = NULL) {
+  public function callAPIAndDocument($entity, $action, $params, $function, $file, $description = "", $exampleName = NULL) {
     $params['version'] = $this->_apiversion;
     $result = $this->callAPISuccess($entity, $action, $params);
-    $this->documentMe($params, $result, $function, $file, $description, $subfile, $actionName);
+    $this->documentMe($entity, $action, $params, $result, $function, $file, $description, $exampleName);
     return $result;
   }
 
@@ -1950,6 +1994,22 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     crm_add_uf_join($params);
   }
 
+  /**
+   * @param array $params
+   *   Optional parameters.
+   *
+   * @return int
+   *   Campaign ID.
+   */
+  public function campaignCreate($params = array()) {
+    $this->enableCiviCampaign();
+    $campaign = $this->callAPISuccess('campaign', 'create', array_merge(array(
+      'name' => 'big_campaign',
+      'title' => 'Campaign',
+    ), $params));
+    return $campaign['id'];
+  }
+
   /**
    * Create Group for a contact.
    *
@@ -2249,120 +2309,72 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * define(DONT_DOCUMENT_TEST_CONFIG ,1);
    * in your settings file
    *
+   * @param string $entity
+   * @param string $action
    * @param array $params
    *   Array as passed to civicrm_api function.
    * @param array $result
    *   Array as received from the civicrm_api function.
-   * @param string $function
+   * @param string $testFunction
    *   Calling function - generally __FUNCTION__.
-   * @param string $filename
+   * @param string $testFile
    *   Called from file - generally __FILE__.
    * @param string $description
    *   Descriptive text for the example file.
-   * @param string $subfile
-   *   Name for subfile - if this is completed the example will be put in a subfolder (named by the entity).
-   * @param string $action
-   *   Optional action - otherwise taken from function name.
+   * @param string $exampleName
+   *   Name for this example file (CamelCase) - if ommitted the action name will be substituted.
    */
-  public function documentMe($params, $result, $function, $filename, $description = "", $subfile = NULL, $action = NULL) {
+  private function documentMe($entity, $action, $params, $result, $testFunction, $testFile, $description = "", $exampleName = NULL) {
     if (defined('DONT_DOCUMENT_TEST_CONFIG') && DONT_DOCUMENT_TEST_CONFIG) {
       return;
     }
-    $entity = substr(basename($filename), 0, strlen(basename($filename)) - 8);
-    //todo - this is a bit cludgey
-    if (empty($action)) {
-      if (strstr($function, 'Create')) {
-        $action = empty($action) ? 'create' : $action;
-        $entityAction = 'Create';
-      }
-      elseif (strstr($function, 'GetSingle')) {
-        $action = empty($action) ? 'getsingle' : $action;
-        $entityAction = 'GetSingle';
-      }
-      elseif (strstr($function, 'GetValue')) {
-        $action = empty($action) ? 'getvalue' : $action;
-        $entityAction = 'GetValue';
-      }
-      elseif (strstr($function, 'GetCount')) {
-        $action = empty($action) ? 'getcount' : $action;
-        $entityAction = 'GetCount';
-      }
-      elseif (strstr($function, 'GetFields')) {
-        $action = empty($action) ? 'getfields' : $action;
-        $entityAction = 'GetFields';
-      }
-      elseif (strstr($function, 'GetList')) {
-        $action = empty($action) ? 'getlist' : $action;
-        $entityAction = 'GetList';
-      }
-      elseif (strstr($function, 'GetActions')) {
-        $action = empty($action) ? 'getactions' : $action;
-        $entityAction = 'GetActions';
-      }
-      elseif (strstr($function, 'Get')) {
-        $action = empty($action) ? 'get' : $action;
-        $entityAction = 'Get';
-      }
-      elseif (strstr($function, 'Delete')) {
-        $action = empty($action) ? 'delete' : $action;
-        $entityAction = 'Delete';
-      }
-      elseif (strstr($function, 'Update')) {
-        $action = empty($action) ? 'update' : $action;
-        $entityAction = 'Update';
-      }
-      elseif (strstr($function, 'Subscribe')) {
-        $action = empty($action) ? 'subscribe' : $action;
-        $entityAction = 'Subscribe';
-      }
-      elseif (strstr($function, 'Submit')) {
-        $action = empty($action) ? 'submit' : $action;
-        $entityAction = 'Submit';
-      }
-      elseif (strstr($function, 'Apply')) {
-        $action = empty($action) ? 'apply' : $action;
-        $entityAction = 'Apply';
-      }
-      elseif (strstr($function, 'Replace')) {
-        $action = empty($action) ? 'replace' : $action;
-        $entityAction = 'Replace';
+    $entity = _civicrm_api_get_camel_name($entity);
+    $action = strtolower($action);
+
+    if (empty($exampleName)) {
+      // Attempt to convert lowercase action name to CamelCase.
+      // This is clunky/imperfect due to the convention of all lowercase actions.
+      $exampleName = CRM_Utils_String::convertStringToCamel($action);
+      $knownPrefixes = array(
+        'Get',
+        'Set',
+        'Create',
+        'Update',
+        'Send',
+      );
+      foreach ($knownPrefixes as $prefix) {
+        if (strpos($exampleName, $prefix) === 0 && $prefix != $exampleName) {
+          $exampleName[strlen($prefix)] = strtoupper($exampleName[strlen($prefix)]);
+        }
       }
     }
-    else {
-      $entityAction = ucwords($action);
-    }
 
     $this->tidyExampleResult($result);
     if (isset($params['version'])) {
       unset($params['version']);
     }
-    // a cleverer person than me would do it in a single regex
-    if (strstr($entity, 'UF')) {
-      $fnPrefix = strtolower(preg_replace('/(?<! )(?<!^)(?<=UF)[A-Z]/', '_$0', $entity));
-    }
-    else {
-      $fnPrefix = strtolower(preg_replace('/(?<! )(?<!^)[A-Z]/', '_$0', $entity));
+    // Format multiline description as array
+    $desc = array();
+    if (is_string($description) && strlen($description)) {
+      foreach (explode("\n", $description) as $line) {
+        $desc[] = trim($line);
+      }
     }
     $smarty = CRM_Core_Smarty::singleton();
-    $smarty->assign('testfunction', $function);
-    $function = $fnPrefix . "_" . strtolower($action);
-    $smarty->assign('function', $function);
-    $smarty->assign('fnPrefix', $fnPrefix);
+    $smarty->assign('testFunction', $testFunction);
+    $smarty->assign('function', _civicrm_api_get_entity_name_from_camel($entity) . "_$action");
     $smarty->assign('params', $params);
     $smarty->assign('entity', $entity);
-    $smarty->assign('filename', basename($filename));
-    $smarty->assign('description', $description);
+    $smarty->assign('testFile', basename($testFile));
+    $smarty->assign('description', $desc);
     $smarty->assign('result', $result);
-
     $smarty->assign('action', $action);
-    if (empty($subfile)) {
-      $subfile = $entityAction;
-    }
+
     if (file_exists('../tests/templates/documentFunction.tpl')) {
       if (!is_dir("../api/v3/examples/$entity")) {
         mkdir("../api/v3/examples/$entity");
       }
-      $f = fopen("../api/v3/examples/$entity/$subfile.php", "w+b");
+      $f = fopen("../api/v3/examples/$entity/$exampleName.php", "w+b");
       fwrite($f, $smarty->fetch('../tests/templates/documentFunction.tpl'));
       fclose($f);
     }
@@ -3013,7 +3025,7 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
    *   $this->_permissionedDisabledGroup = $this->groupCreate(array('title' => 'pick-me-disabled', 'is_active' => 0, 'name' => 'pick-me-disabled'));
    *   $this->_permissionedGroup = $this->groupCreate(array('title' => 'pick-me-active', 'is_active' => 1, 'name' => 'pick-me-active'));
    */
-  public function setupACL() {
+  public function setupACL($isProfile = FALSE) {
     global $_REQUEST;
     $_REQUEST = $this->_params;
 
@@ -3035,36 +3047,52 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
 
     CRM_Core_DAO::executeQuery("
     INSERT INTO civicrm_acl_entity_role (
-    `acl_role_id`, `entity_table`, `entity_id`
-    ) VALUES (55, 'civicrm_group', {$this->_permissionedGroup});
+    `acl_role_id`, `entity_table`, `entity_id`, `is_active`
+    ) VALUES (55, 'civicrm_group', {$this->_permissionedGroup}, 1);
     ");
 
-    CRM_Core_DAO::executeQuery("
-    INSERT INTO civicrm_acl (
-    `name`, `entity_table`, `entity_id`, `operation`, `object_table`, `object_id`, `is_active`
-    )
-    VALUES (
-    'view picked', 'civicrm_group', $this->_permissionedGroup , 'Edit', 'civicrm_saved_search', {$this->_permissionedGroup}, 1
-    );
-    ");
+    if ($isProfile) {
+      CRM_Core_DAO::executeQuery("
+      INSERT INTO civicrm_acl (
+      `name`, `entity_table`, `entity_id`, `operation`, `object_table`, `object_id`, `is_active`
+      )
+      VALUES (
+      'view picked', 'civicrm_acl_role', 55, 'Edit', 'civicrm_uf_group', 0, 1
+      );
+      ");
+    }
+    else {
+      CRM_Core_DAO::executeQuery("
+      INSERT INTO civicrm_acl (
+      `name`, `entity_table`, `entity_id`, `operation`, `object_table`, `object_id`, `is_active`
+      )
+      VALUES (
+      'view picked', 'civicrm_group', $this->_permissionedGroup , 'Edit', 'civicrm_saved_search', {$this->_permissionedGroup}, 1
+      );
+      ");
+
+      CRM_Core_DAO::executeQuery("
+      INSERT INTO civicrm_acl (
+      `name`, `entity_table`, `entity_id`, `operation`, `object_table`, `object_id`, `is_active`
+      )
+      VALUES (
+      'view picked', 'civicrm_group',  $this->_permissionedGroup, 'Edit', 'civicrm_saved_search', {$this->_permissionedDisabledGroup}, 1
+      );
+      ");
+    }
 
-    CRM_Core_DAO::executeQuery("
-    INSERT INTO civicrm_acl (
-    `name`, `entity_table`, `entity_id`, `operation`, `object_table`, `object_id`, `is_active`
-    )
-    VALUES (
-    'view picked', 'civicrm_group',  $this->_permissionedGroup, 'Edit', 'civicrm_saved_search', {$this->_permissionedDisabledGroup}, 1
-    );
-    ");
     $this->_loggedInUser = CRM_Core_Session::singleton()->get('userID');
     $this->callAPISuccess('group_contact', 'create', array(
       'group_id' => $this->_permissionedGroup,
       'contact_id' => $this->_loggedInUser,
     ));
-    //flush cache
-    CRM_ACL_BAO_Cache::resetCache();
-    CRM_Contact_BAO_Group::getPermissionClause(TRUE);
-    CRM_ACL_API::groupPermission('whatever', 9999, NULL, 'civicrm_saved_search', NULL, NULL, TRUE);
+
+    if (!$isProfile) {
+      //flush cache
+      CRM_ACL_BAO_Cache::resetCache();
+      CRM_Contact_BAO_Group::getPermissionClause(TRUE);
+      CRM_ACL_API::groupPermission('whatever', 9999, NULL, 'civicrm_saved_search', NULL, NULL, TRUE);
+    }
   }
 
   /**
@@ -3226,7 +3254,7 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
   public function createMailing() {
     $params = array(
       'subject' => 'maild' . rand(),
-      'body_text' => 'bdkfhdskfhduew',
+      'body_text' => 'bdkfhdskfhduew{domain.address}{action.optOutUrl}',
       'name' => 'mailing name' . rand(),
       'created_id' => 1,
     );