Merge pull request #13252 from jmcclelland/issue586
[civicrm-core.git] / tests / phpunit / api / v3 / ReportTemplateTest.php
index 87ba2a7e0ceea9b77b96085cc3793402bc3079e5..00b257d998c4ee3bd639817efcb099e58dabfa67 100644 (file)
@@ -3,7 +3,7 @@
  +--------------------------------------------------------------------+
  | CiviCRM version 5                                                  |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2018                                |
+ | Copyright CiviCRM LLC (c) 2004-2019                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
  * @group headless
  */
 class api_v3_ReportTemplateTest extends CiviUnitTestCase {
+
+  use CRMTraits_ACL_PermissionTrait;
+  use CRMTraits_PCP_PCPTestTrait;
+
   protected $_apiversion = 3;
 
   protected $contactIDs = [];
@@ -192,7 +196,7 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase {
    */
   public function testReportTemplateGetRowsContactSummary() {
     $description = "Retrieve rows from a report template (optionally providing the instance_id).";
-    $result = $this->callAPIAndDocument('report_template', 'getrows', array(
+    $result = $this->callApiSuccess('report_template', 'getrows', array(
       'report_id' => 'contact/summary',
       'options' => array('metadata' => array('labels', 'title')),
     ), __FUNCTION__, __FILE__, $description, 'Getrows');
@@ -211,6 +215,44 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase {
      */
   }
 
+  /**
+   * Test getrows on Mailing Opened report.
+   */
+  public function testReportTemplateGetRowsMailingUniqueOpened() {
+    $description = "Retrieve rows from a mailing opened report template.";
+    $op = new PHPUnit_Extensions_Database_Operation_Insert();
+    $op->execute($this->_dbconn,
+      $this->createFlatXMLDataSet(
+        dirname(__FILE__) . '/../../CRM/Mailing/BAO/queryDataset.xml'
+      )
+    );
+
+    // Check total rows without distinct
+    global $_REQUEST;
+    $_REQUEST['distinct'] = 0;
+    $result = $this->callAPIAndDocument('report_template', 'getrows', array(
+      'report_id' => 'Mailing/opened',
+      'options' => array('metadata' => array('labels', 'title')),
+    ), __FUNCTION__, __FILE__, $description, 'Getrows');
+    $this->assertEquals(14, $result['count']);
+
+    // Check total rows with distinct
+    $_REQUEST['distinct'] = 1;
+    $result = $this->callAPIAndDocument('report_template', 'getrows', array(
+      'report_id' => 'Mailing/opened',
+      'options' => array('metadata' => array('labels', 'title')),
+    ), __FUNCTION__, __FILE__, $description, 'Getrows');
+    $this->assertEquals(5, $result['count']);
+
+    // Check total rows with distinct by passing NULL value to distinct parameter
+    $_REQUEST['distinct'] = NULL;
+    $result = $this->callAPIAndDocument('report_template', 'getrows', array(
+      'report_id' => 'Mailing/opened',
+      'options' => array('metadata' => array('labels', 'title')),
+    ), __FUNCTION__, __FILE__, $description, 'Getrows');
+    $this->assertEquals(5, $result['count']);
+  }
+
   /**
    * Test api to get rows from reports.
    *
@@ -431,15 +473,19 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase {
 
     $this->assertEquals(2, $rows['count'], "Report failed - the sql used to generate the results was " . print_r($rows['metadata']['sql'], TRUE));
 
-    $expected = 'DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
+    $expected = preg_replace('/\s+/', ' ', 'DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
       SELECT SQL_CALC_FOUND_ROWS contact_civireport.id as cid  FROM civicrm_contact contact_civireport    INNER JOIN civicrm_contribution contribution_civireport USE index (received_date) ON contribution_civireport.contact_id = contact_civireport.id
          AND contribution_civireport.is_test = 0
          AND contribution_civireport.receive_date BETWEEN \'20140701000000\' AND \'20150630235959\'
-
-       LEFT JOIN civicrm_contribution cont_exclude ON cont_exclude.contact_id = contact_civireport.id
-         AND cont_exclude.receive_date BETWEEN \'2015-7-1\' AND \'20160630235959\' WHERE cont_exclude.id IS NULL AND 1 AND ( contribution_civireport.contribution_status_id IN (1) )
-      GROUP BY contact_civireport.id';
-    $this->assertContains(preg_replace('/\s+/', ' ', $expected), preg_replace('/\s+/', ' ', $rows['metadata']['sql'][0]));
+         WHERE contact_civireport.id NOT IN (
+      SELECT cont_exclude.contact_id
+          FROM civicrm_contribution cont_exclude
+          WHERE cont_exclude.receive_date BETWEEN \'2015-7-1\' AND \'20160630235959\')
+          AND ( contribution_civireport.contribution_status_id IN (1) )
+      GROUP BY contact_civireport.id');
+    // Exclude whitespace in comparison as we don't care if it changes & this allows us to make the above readable.
+    $whitespacelessSql = preg_replace('/\s+/', ' ', $rows['metadata']['sql'][0]);
+    $this->assertContains($expected, $whitespacelessSql);
   }
 
   /**
@@ -526,6 +572,31 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase {
     );
   }
 
+  /**
+   * Test the amount column is populated on soft credit details.
+   */
+  public function testContributionDetailSoftCreditsOnly() {
+    $contactID = $this->individualCreate();
+    $contactID2 = $this->individualCreate();
+    $this->contributionCreate(['contact_id' => $contactID, 'api.ContributionSoft.create' => ['amount' => 5, 'contact_id' => $contactID2]]);
+    $template = 'contribute/detail';
+    $rows = $this->callAPISuccess('report_template', 'getrows', array(
+      'report_id' => $template,
+      'contribution_or_soft_value' => 'soft_credits_only',
+      'fields' => [
+        'sort_name' => '1',
+        'email' => '1',
+        'financial_type_id' => '1',
+        'receive_date' => '1',
+        'total_amount' => '1',
+      ],
+      'options' => array('metadata' => ['sql', 'labels']),
+    ));
+    foreach (array_keys($rows['metadata']['labels']) as $header) {
+      $this->assertTrue(!empty($rows['values'][0][$header]));
+    }
+  }
+
   /**
    * Test the group filter works on the various reports.
    *
@@ -1001,4 +1072,125 @@ class api_v3_ReportTemplateTest extends CiviUnitTestCase {
     ));
   }
 
+  /**
+   * Test PCP report to ensure total donors and total committed is accurate.
+   */
+  public function testPcpReportTotals() {
+    $donor1ContactId = $this->individualCreate();
+    $donor2ContactId = $this->individualCreate();
+    $donor3ContactId = $this->individualCreate();
+
+    // We are going to create two PCP pages. We will create two contributions
+    // on the first PCP page and one contribution on the second PCP page.
+    //
+    // Then, we will ensure that the first PCP page reports a total of both
+    // contributions (but not the contribution made on the second PCP page).
+
+    // A PCP page requires three components:
+    // 1. A contribution page
+    // 2. A PCP Block
+    // 3. A PCP page
+
+    // pcpBLockParams creates a contribution page and returns the parameters
+    // necessary to create a PBP Block.
+    $blockParams = $this->pcpBlockParams();
+    $pcpBlock = CRM_PCP_BAO_PCPBlock::create($blockParams);
+
+    // Keep track of the contribution page id created. We will use this
+    // contribution page id for all the PCP pages.
+    $contribution_page_id = $pcpBlock->entity_id;
+
+    // pcpParams returns the parameters needed to create a PCP page.
+    $pcpParams = $this->pcpParams();
+    // Keep track of the owner of the page so we can properly apply the
+    // soft credit.
+    $pcpOwnerContact1Id = $pcpParams['contact_id'];
+    $pcpParams['pcp_block_id'] = $pcpBlock->id;
+    $pcpParams['page_id'] = $contribution_page_id;
+    $pcpParams['page_type'] = 'contribute';
+    $pcp1 = CRM_PCP_BAO_PCP::create($pcpParams);
+
+    // Nice work. Now, let's create a second PCP page.
+    $pcpParams = $this->pcpParams();
+    // Keep track of the owner of the page.
+    $pcpOwnerContact2Id = $pcpParams['contact_id'];
+    // We're using the same pcpBlock id and contribution page that we created above.
+    $pcpParams['pcp_block_id'] = $pcpBlock->id;
+    $pcpParams['page_id'] = $contribution_page_id;
+    $pcpParams['page_type'] = 'contribute';
+    $pcp2 = CRM_PCP_BAO_PCP::create($pcpParams);
+
+    // Get soft credit types, with the name column as the key.
+    $soft_credit_types = CRM_Contribute_BAO_ContributionSoft::buildOptions("soft_credit_type_id", NULL, array("flip" => TRUE, 'labelColumn' => 'name'));
+    $pcp_soft_credit_type_id = $soft_credit_types['pcp'];
+
+    // Create two contributions assigned to this contribution page and
+    // assign soft credits appropriately.
+    // FIRST...
+    $contribution1params = array(
+      'contact_id' => $donor1ContactId,
+      'contribution_page_id' => $contribution_page_id,
+      'total_amount' => '75.00',
+    );
+    $c1 = $this->contributionCreate($contribution1params);
+    // Now the soft contribution.
+    $p = array(
+      'contribution_id' => $c1,
+      'pcp_id' => $pcp1->id,
+      'contact_id' => $pcpOwnerContact1Id,
+      'amount' => 75.00,
+      'currency' => 'USD',
+      'soft_credit_type_id' => $pcp_soft_credit_type_id,
+    );
+    $this->callAPISuccess('contribution_soft', 'create', $p);
+    // SECOND...
+    $contribution2params = array(
+      'contact_id' => $donor2ContactId,
+      'contribution_page_id' => $contribution_page_id,
+      'total_amount' => '25.00',
+    );
+    $c2 = $this->contributionCreate($contribution2params);
+    // Now the soft contribution.
+    $p = array(
+      'contribution_id' => $c2,
+      'pcp_id' => $pcp1->id,
+      'contact_id' => $pcpOwnerContact1Id,
+      'amount' => 25.00,
+      'currency' => 'USD',
+      'soft_credit_type_id' => $pcp_soft_credit_type_id,
+    );
+    $this->callAPISuccess('contribution_soft', 'create', $p);
+
+    // Create one contributions assigned to the second PCP page
+    $contribution3params = array(
+      'contact_id' => $donor3ContactId,
+      'contribution_page_id' => $contribution_page_id,
+      'total_amount' => '200.00',
+    );
+    $c3 = $this->contributionCreate($contribution3params);
+    // Now the soft contribution.
+    $p = array(
+      'contribution_id' => $c3,
+      'pcp_id' => $pcp2->id,
+      'contact_id' => $pcpOwnerContact2Id,
+      'amount' => 200.00,
+      'currency' => 'USD',
+      'soft_credit_type_id' => $pcp_soft_credit_type_id,
+    );
+    $this->callAPISuccess('contribution_soft', 'create', $p);
+
+    $template = 'contribute/pcp';
+    $rows = $this->callAPISuccess('report_template', 'getrows', array(
+      'report_id' => $template,
+      'title' => 'My PCP',
+      'fields' => [
+        'amount_1' => '1',
+        'soft_id' => '1',
+       ],
+    ));
+    $values = $rows['values'][0];
+    $this->assertEquals(100.00, $values['civicrm_contribution_soft_amount_1_sum'], "Total commited should be $100");
+    $this->assertEquals(2, $values['civicrm_contribution_soft_soft_id_count'], "Total donors should be 2");
+  }
+
 }