CRM-16373 - CRM_Core_Config - Use `Runtime` and `MagicMerge`
[civicrm-core.git] / tests / phpunit / CiviTest / CiviUnitTestCase.php
index b896aac5bb0a92c58fce0cb9797ee2ceb90e5197..10fb69f97694da28bb044e9625bcc91ec4c0a084 100755 (executable)
@@ -118,11 +118,6 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    */
   public static $populateOnce = FALSE;
 
-  /**
-   * Allow classes to state E-notice compliance
-   */
-  public $_eNoticeCompliant = TRUE;
-
   /**
    * @var boolean DBResetRequired allows skipping DB reset
    *               in specific test case. If you still need
@@ -401,19 +396,8 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     // "initialize" CiviCRM to avoid problems when running single tests
     // FIXME: look at it closer in second stage
 
-    // initialize the object once db is loaded
-    CRM_Core_Config::$_mail = NULL;
-    $config = CRM_Core_Config::singleton();
-
-    // when running unit tests, use mockup user framework
-    $config->setUserFramework('UnitTests');
-    $this->hookClass = CRM_Utils_Hook::singleton(TRUE);
-    // also fix the fatal error handler to throw exceptions,
-    // rather than exit
-    $config->fatalErrorHandler = 'CiviUnitTestCase_fatalErrorHandler';
-
-    // enable backtrace to get meaningful errors
-    $config->backtrace = 1;
+    $GLOBALS['civicrm_setting']['domain']['fatalErrorHandler'] = 'CiviUnitTestCase_fatalErrorHandler';
+    $GLOBALS['civicrm_setting']['domain']['backtrace'] = 1;
 
     // disable any left-over test extensions
     CRM_Core_DAO::executeQuery('DELETE FROM civicrm_extension WHERE full_name LIKE "test.%"');
@@ -421,24 +405,27 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     // reset all the caches
     CRM_Utils_System::flushCache();
 
+    // initialize the object once db is loaded
+    \Civi::reset();
+    $config = CRM_Core_Config::singleton(TRUE, TRUE); // ugh, performance
+
+    // when running unit tests, use mockup user framework
+    $config->setUserFramework('UnitTests');
+    $this->hookClass = CRM_Utils_Hook::singleton(TRUE);
+
     // 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;
 
     //flush component settings
     CRM_Core_Component::getEnabledComponents(TRUE);
 
-    if ($this->_eNoticeCompliant) {
-      error_reporting(E_ALL);
-    }
-    else {
-      error_reporting(E_ALL & ~E_NOTICE);
-    }
+    error_reporting(E_ALL);
+
     $this->_sethtmlGlobals();
   }
 
@@ -473,6 +460,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(
@@ -481,9 +471,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() {
@@ -525,7 +521,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();
     }
@@ -908,6 +904,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
@@ -1397,6 +1426,35 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
     return $result['id'];
   }
 
+  /**
+   * Create test Authorize.net instance.
+   *
+   * @param array $params
+   *
+   * @return mixed
+   */
+  public function paymentProcessorAuthorizeNetCreate($params = array()) {
+    $params = array_merge(array(
+      'name' => 'Authorize',
+      'domain_id' => CRM_Core_Config::domainID(),
+      'payment_processor_type_id' => 'AuthNet',
+      'title' => 'AuthNet',
+      'is_active' => 1,
+      'is_default' => 0,
+      'is_test' => 1,
+      'is_recur' => 1,
+      'user_name' => '4y5BfuW7jm',
+      'password' => '4cAmW927n8uLf5J8',
+      'url_site' => 'https://test.authorize.net/gateway/transact.dll',
+      'url_recur' => 'https://apitest.authorize.net/xml/v1/request.api',
+      'class_name' => 'Payment_AuthorizeNet',
+      'billing_mode' => 1,
+    ), $params);
+
+    $result = $this->callAPISuccess('PaymentProcessor', 'create', $params);
+    return $result['id'];
+  }
+
   /**
    * Create Participant.
    *
@@ -1432,7 +1490,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * Create Payment Processor.
    *
    * @return CRM_Financial_DAO_PaymentProcessor
-   *   instance of Payment Processsor
+   *   instance of Payment Processor
    */
   public function processorCreate() {
     $processorParams = array(
@@ -1440,14 +1498,27 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
       'name' => 'Dummy',
       'payment_processor_type_id' => 10,
       'financial_account_id' => 12,
+      'is_test' => TRUE,
       'is_active' => 1,
       'user_name' => '',
       'url_site' => 'http://dummy.com',
       'url_recur' => 'http://dummy.com',
       'billing_mode' => 1,
     );
-    $paymentProcessor = CRM_Financial_BAO_PaymentProcessor::create($processorParams);
-    return $paymentProcessor;
+    return CRM_Financial_BAO_PaymentProcessor::create($processorParams);
+  }
+
+  /**
+   * Create Payment Processor.
+   *
+   * @param array $processorParams
+   *
+   * @return \CRM_Core_Payment_Dummy
+   *    Instance of Dummy Payment Processor
+   */
+  public function dummyProcessorCreate($processorParams = array()) {
+    $paymentProcessor = $this->processorCreate($processorParams);
+    return Civi\Payment\System::singleton()->getById($paymentProcessor->id);
   }
 
   /**
@@ -1564,38 +1635,34 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
   /**
    * Create contribution.
    *
-   * @param int $cID
-   *   Contact_id.
+   * @param array $params
+   *   Array of parameters.
    * @param int $cTypeID
    *   Id of financial type.
    * @param int $invoiceID
    * @param int $trxnID
    * @param int $paymentInstrumentID
-   * @param bool $isFee
    *
    * @return int
    *   id of created contribution
    */
-  public function contributionCreate($cID, $cTypeID = 1, $invoiceID = 67890, $trxnID = 12345, $paymentInstrumentID = 1, $isFee = TRUE) {
-    $params = array(
+  public function contributionCreate($params, $cTypeID = 1, $invoiceID = 67890, $trxnID = 12345,
+    $paymentInstrumentID = 1) {
+
+    $params = array_merge(array(
       'domain_id' => 1,
-      'contact_id' => $cID,
       'receive_date' => date('Ymd'),
       'total_amount' => 100.00,
-      'financial_type_id' => empty($cTypeID) ? 1 : $cTypeID,
+      'fee_amount' => 5.00,
+      'net_ammount' => 95.00,
+      'financial_type_id' => $cTypeID,
       'payment_instrument_id' => empty($paymentInstrumentID) ? 1 : $paymentInstrumentID,
       'non_deductible_amount' => 10.00,
       'trxn_id' => $trxnID,
       'invoice_id' => $invoiceID,
       'source' => 'SSF',
       'contribution_status_id' => 1,
-      // 'note'                   => 'Donating for Nobel Cause', *Fixme
-    );
-
-    if ($isFee) {
-      $params['fee_amount'] = 5.00;
-      $params['net_amount'] = 95.00;
-    }
+    ), $params);
 
     $result = $this->callAPISuccess('contribution', 'create', $params);
     return $result['id'];
@@ -1759,7 +1826,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
         'is_primary' => 1,
         'name' => 'Saint Helier St',
         'county' => 'Marin',
-        'country' => 'United States',
+        'country' => 'UNITED STATES',
         'state_province' => 'Michigan',
         'supplemental_address_1' => 'Hallmark Ct',
         'supplemental_address_2' => 'Jersey Village',
@@ -2280,7 +2347,7 @@ class CiviUnitTestCase extends PHPUnit_Extensions_Database_TestCase {
    * @param string $description
    *   Descriptive text for the example file.
    * @param string $exampleName
-   *   Name for this example file (CamelCase) - if ommitted the action name will be substituted.
+   *   Name for this example file (CamelCase) - if omitted the action name will be substituted.
    */
   private function documentMe($entity, $action, $params, $result, $testFunction, $testFile, $description = "", $exampleName = NULL) {
     if (defined('DONT_DOCUMENT_TEST_CONFIG') && DONT_DOCUMENT_TEST_CONFIG) {
@@ -2529,8 +2596,11 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
    */
   public function quickCleanUpFinancialEntities() {
     $tablesToTruncate = array(
+      'civicrm_activity',
+      'civicrm_activity_contact',
       'civicrm_contribution',
       'civicrm_contribution_soft',
+      'civicrm_contribution_product',
       'civicrm_financial_trxn',
       'civicrm_financial_item',
       'civicrm_contribution_recur',
@@ -2560,6 +2630,7 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
   }
 
   public function restoreDefaultPriceSetConfig() {
+    CRM_Core_DAO::executeQuery('DELETE FROM civicrm_price_set WHERE id > 2');
     CRM_Core_DAO::executeQuery("INSERT INTO `civicrm_price_field` (`id`, `price_set_id`, `name`, `label`, `html_type`, `is_enter_qty`, `help_pre`, `help_post`, `weight`, `is_display_amounts`, `options_per_line`, `is_active`, `is_required`, `active_on`, `expire_on`, `javascript`, `visibility_id`) VALUES (1, 1, 'contribution_amount', 'Contribution Amount', 'Text', 0, NULL, NULL, 1, 1, 1, 1, 1, NULL, NULL, NULL, 1)");
     CRM_Core_DAO::executeQuery("INSERT INTO `civicrm_price_field_value` (`id`, `price_field_id`, `name`, `label`, `description`, `amount`, `count`, `max_value`, `weight`, `membership_type_id`, `membership_num_terms`, `is_default`, `is_active`, `financial_type_id`, `deductible_amount`) VALUES (1, 1, 'contribution_amount', 'Contribution Amount', NULL, '1', NULL, NULL, 1, NULL, NULL, 0, 1, 1, 0.00)");
   }
@@ -2567,7 +2638,7 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
    * Function does a 'Get' on the entity & compares the fields in the Params with those returned
    * Default behaviour is to also delete the entity
    * @param array $params
-   *   Params array to check agains.
+   *   Params array to check against.
    * @param int $id
    *   Id of the entity concerned.
    * @param string $entity
@@ -2983,7 +3054,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;
 
@@ -3005,36 +3076,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);
+    }
   }
 
   /**
@@ -3075,7 +3162,7 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
    * @todo this isn't a great place to put it - but really it belongs on a class that extends
    * this parent class & we don't have a structure for that yet
    * There is another function to this effect on the PaypalPro test but it appears to be silently failing
-   * & the best protection agains that is the functions this class affords
+   * & the best protection against that is the functions this class affords
    * @param array $params
    * @return int $result['id'] payment processor id
    */
@@ -3132,6 +3219,7 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
         'contact_id' => $this->_contactID,
         'contribution_page_id' => $this->_contributionPageID,
         'payment_processor_id' => $this->_paymentProcessorID,
+        'is_test' => 0,
       ),
     ));
     $this->_contributionRecurID = $contributionRecur['id'];
@@ -3144,7 +3232,10 @@ AND    ( TABLE_NAME LIKE 'civicrm_value_%' )
   public function setupMembershipRecurringPaymentProcessorTransaction() {
     $this->ids['membership_type'] = $this->membershipTypeCreate();
     //create a contribution so our membership & contribution don't both have id = 1
-    $this->contributionCreate($this->_contactID, 1, 'abcd', '345j');
+    $this->contributionCreate(array(
+      'contact_id' => $this->_contactID,
+      'is_test' => 1),
+      1, 'abcd', '345j');
     $this->setupRecurringPaymentProcessorTransaction();
 
     $this->ids['membership'] = $this->callAPISuccess('membership', 'create', array(