Fix test on secondary membership contribution to use full form flow
authorEileen McNaughton <emcnaughton@wikimedia.org>
Wed, 25 Oct 2023 01:04:15 +0000 (14:04 +1300)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Wed, 25 Oct 2023 05:02:30 +0000 (18:02 +1300)
This includes minor standardisation on the priceSetID references - the
variable is being referred to from both the get & within params but the
getter is the primary source

CRM/Contribute/Form/Contribution/Main.php
CRM/Contribute/Form/ContributionBase.php
Civi/Test/FormWrapper.php
tests/phpunit/CRM/Contribute/Form/Contribution/ConfirmTest.php
tests/phpunit/CRMTraits/Financial/PriceSetTrait.php

index 8b78716d933349b9ccf793cac02e7330d0cd3dbe..c2bdaa48c91dd30f704be7e640a7657bfaf9e7fd 100644 (file)
@@ -1290,11 +1290,11 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
       $this->set('amount_level', CRM_Utils_Array::value('amount_level', $params));
     }
 
-    $priceSetId = $params['priceSetId'] ?? NULL;
+    $priceSetID = $this->getPriceSetID();
     if (!empty($this->_ccid)) {
       $this->set('lineItem', [$this->getPriceSetID() => $this->getExistingContributionLineItems()]);
     }
-    elseif ($priceSetId) {
+    elseif ($priceSetID) {
       $lineItem = [];
       if ($this->isQuickConfig()) {
         foreach ($this->_values['fee'] as $key => & $val) {
@@ -1314,17 +1314,17 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu
       }
 
       if ($this->_membershipBlock) {
-        $this->processAmountAndGetAutoRenew($this->_values['fee'], $params, $lineItem[$priceSetId], $priceSetId);
+        $this->processAmountAndGetAutoRenew($this->_values['fee'], $params, $lineItem[$priceSetID]);
       }
       else {
-        CRM_Price_BAO_PriceSet::processAmount($this->_values['fee'], $params, $lineItem[$priceSetId], $priceSetId);
+        CRM_Price_BAO_PriceSet::processAmount($this->_values['fee'], $params, $lineItem[$priceSetID], $priceSetID);
       }
 
       if ($proceFieldAmount) {
-        $lineItem[$params['priceSetId']][$fieldOption]['unit_price'] = $proceFieldAmount;
-        $lineItem[$params['priceSetId']][$fieldOption]['line_total'] = $proceFieldAmount;
-        if (isset($lineItem[$params['priceSetId']][$fieldOption]['tax_amount'])) {
-          $proceFieldAmount += $lineItem[$params['priceSetId']][$fieldOption]['tax_amount'];
+        $lineItem[$priceSetID][$fieldOption]['unit_price'] = $proceFieldAmount;
+        $lineItem[$priceSetID][$fieldOption]['line_total'] = $proceFieldAmount;
+        if (isset($lineItem[$priceSetID][$fieldOption]['tax_amount'])) {
+          $proceFieldAmount += $lineItem[$priceSetID][$fieldOption]['tax_amount'];
         }
         if (!$this->_membershipBlock['is_separate_payment']) {
           //require when separate membership not used
index 1b0b80b78694ce5a4b7b0092d30f039ae419f785..3ac8a81fda9fcfb40dee202184264663255234e5 100644 (file)
@@ -1093,10 +1093,9 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
    *   Params reflecting form input e.g with fields 'price_5' => 7, 'price_8' => array(7, 8)
    * @param $lineItems
    *   Line item array to be altered.
-   * @param int $priceSetID
    */
-  public function processAmountAndGetAutoRenew($fields, &$params, &$lineItems, $priceSetID = NULL) {
-    CRM_Price_BAO_PriceSet::processAmount($fields, $params, $lineItems, $priceSetID);
+  public function processAmountAndGetAutoRenew($fields, &$params, &$lineItems) {
+    CRM_Price_BAO_PriceSet::processAmount($fields, $params, $lineItems, $this->getPriceSetID());
     $autoRenew = [];
     $autoRenew[0] = $autoRenew[1] = $autoRenew[2] = 0;
     foreach ($lineItems as $lineItem) {
@@ -1257,4 +1256,25 @@ class CRM_Contribute_Form_ContributionBase extends CRM_Core_Form {
     return $this->_pcpId ? (int) $this->_pcpId : NULL;
   }
 
+  /**
+   * Get the selected Contribution ID.
+   *
+   * @api This function will not change in a minor release and is supported for
+   * use outside of core. This annotation / external support for properties
+   * is only given where there is specific test cover.
+   *
+   * @noinspection PhpUnhandledExceptionInspection
+   */
+  public function getContributionID(): ?int {
+    if ($this->getExistingContributionID()) {
+      return $this->getExistingContributionID();
+    }
+    if (property_exists($this, '_contributionID')) {
+      // Available on Confirm form (which is tested), so this avoids
+      // accessing that directly & will work for ThankYou in time.
+      return $this->_contributionID;
+    }
+    return NULL;
+  }
+
 }
index 0989d4c09d1c89686e1e93ab5cf5e02019342729..e20b031061e8328967b4bae74f107f17ddc8f653 100644 (file)
@@ -63,6 +63,13 @@ class FormWrapper {
     return $this->getFirstMail()['body'] ?? '';
   }
 
+  /**
+   * @return array
+   */
+  public function getTemplateVariables(): array {
+    return $this->templateVariables;
+  }
+
   private $redirects;
 
   private $mailSpoolID;
@@ -112,6 +119,7 @@ class FormWrapper {
     if ($state > self::VALIDATED) {
       $this->postProcess();
     }
+    $this->templateVariables = $this->form->get_template_vars();
     return $this;
   }
 
index f0569f2c2791cf3e376fed10c72cb6d536a2251b..1bbbc194e35adf720fb31aabea50d3d9c1d6f7ab 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 use Civi\Api4\PriceSetEntity;
+use Civi\Test\FormTrait;
 
 /**
  *  Test APIv3 civicrm_contribute_* functions
@@ -21,6 +22,7 @@ use Civi\Api4\PriceSetEntity;
 class CRM_Contribute_Form_Contribution_ConfirmTest extends CiviUnitTestCase {
 
   use CRMTraits_Financial_PriceSetTrait;
+  use FormTrait;
 
   /**
    * Clean up DB.
@@ -194,9 +196,14 @@ class CRM_Contribute_Form_Contribution_ConfirmTest extends CiviUnitTestCase {
    */
   public function testSeparatePaymentConfirm(): void {
     $paymentProcessorID = $this->paymentProcessorCreate(['payment_processor_type_id' => 'Dummy', 'is_test' => FALSE]);
-    $contributionPageID = $this->createContributionPage(['payment_processor' => $paymentProcessorID]);
+    $contributionPageID = $this->createContributionPage(['payment_processor' => $paymentProcessorID], FALSE);
     $this->setUpMembershipBlockPriceSet(['minimum_fee' => 100]);
-    $this->callAPISuccess('membership_block', 'create', [
+    $this->createTestEntity('PriceSetEntity', [
+      'entity_table' => 'civicrm_contribution_page',
+      'entity_id' => $contributionPageID,
+      'price_set_id' => $this->ids['PriceSet']['membership_block'],
+    ]);
+    $this->callAPISuccess('MembershipBlock', 'create', [
       'entity_id' => $contributionPageID,
       'entity_table' => 'civicrm_contribution_page',
       'is_required' => TRUE,
@@ -204,36 +211,31 @@ class CRM_Contribute_Form_Contribution_ConfirmTest extends CiviUnitTestCase {
       'is_separate_payment' => TRUE,
       'membership_type_default' => $this->ids['MembershipType'],
     ]);
-    /** @var CRM_Contribute_Form_Contribution_Confirm $form */
-    $_REQUEST['id'] = $contributionPageID;
-    $form = $this->getFormObject('CRM_Contribute_Form_Contribution_Confirm', [
+
+    $submittedValues = [
       'credit_card_number' => 4111111111111111,
       'cvv2' => 234,
       'credit_card_exp_date' => [
         'M' => 2,
         'Y' => (int) (CRM_Utils_Time::date('Y')) + 1,
       ],
-      $this->getPriceFieldLabelForContributionPage($contributionPageID) => 100,
-      'priceSetId' => $this->ids['PriceSet']['contribution_page' . $contributionPageID],
+      'price_' . $this->ids['PriceField']['membership'] => $this->ids['PriceFieldValue']['membership_general'],
+      'other_amount' => 100,
+      'priceSetId' => $this->ids['PriceSet']['membership_block'],
       'credit_card_type' => 'Visa',
       'email-5' => 'test@test.com',
       'payment_processor_id' => $paymentProcessorID,
       'year' => 2021,
       'month' => 2,
-    ]);
-    // @todo - the way amount is handled is crazy so we have to set here
-    // but it should be calculated from submit variables.
-    $form->set('amount', 100);
-    $form->preProcess();
-    $form->buildQuickForm();
-    $form->postProcess();
-    $financialTrxnId = $this->callAPISuccess('EntityFinancialTrxn', 'get', ['entity_id' => $form->_contributionID, 'entity_table' => 'civicrm_contribution', 'sequential' => 1])['values'][0]['financial_trxn_id'];
+    ];
+    $form = $this->submitOnlineContributionForm($submittedValues, $contributionPageID);
+    $financialTrxnId = $this->callAPISuccess('EntityFinancialTrxn', 'get', ['entity_id' => $form->getContributionID(), 'entity_table' => 'civicrm_contribution', 'sequential' => 1])['values'][0]['financial_trxn_id'];
     $financialTrxn = $this->callAPISuccess('FinancialTrxn', 'get', [
       'id' => $financialTrxnId,
     ])['values'][$financialTrxnId];
     $this->assertEquals('1111', $financialTrxn['pan_truncation']);
     $this->assertEquals(1, $financialTrxn['card_type_id']);
-    $assignedVariables = $form->get_template_vars();
+    $assignedVariables = $form->getTemplateVariables();
     $this->assertTrue($assignedVariables['is_separate_payment']);
   }
 
@@ -241,13 +243,14 @@ class CRM_Contribute_Form_Contribution_ConfirmTest extends CiviUnitTestCase {
    * Create a basic contribution page.
    *
    * @param array $params
+   * @param bool $isDefaultContributionPriceSet
    *
    * @return int
    *
    * @noinspection PhpDocMissingThrowsInspection
    * @noinspection PhpUnhandledExceptionInspection
    */
-  protected function createContributionPage(array $params): int {
+  protected function createContributionPage(array $params, $isDefaultContributionPriceSet = TRUE): int {
     $contributionPageID = (int) $this->callAPISuccess('ContributionPage', 'create', array_merge([
       'title' => 'Test Contribution Page',
       'financial_type_id' => 'Campaign Contribution',
@@ -258,12 +261,27 @@ class CRM_Contribute_Form_Contribution_ConfirmTest extends CiviUnitTestCase {
       'min_amount' => 20,
       'max_amount' => 2000,
     ], $params))['id'];
-    PriceSetEntity::create(FALSE)->setValues([
-      'entity_table' => 'civicrm_contribution_page',
-      'entity_id' => $contributionPageID,
-      'price_set_id:name' => 'default_contribution_amount',
-    ])->execute();
+    if ($isDefaultContributionPriceSet) {
+      PriceSetEntity::create(FALSE)->setValues([
+        'entity_table' => 'civicrm_contribution_page',
+        'entity_id' => $contributionPageID,
+        'price_set_id:name' => 'default_contribution_amount',
+      ])->execute();
+    }
     return $contributionPageID;
   }
 
+  /**
+   * @param array $submittedValues
+   * @param int $contributionPageID
+   *
+   * @return \Civi\Test\FormWrapper|\Civi\Test\FormWrappers\EventFormOnline|\Civi\Test\FormWrappers\EventFormParticipant|null
+   */
+  protected function submitOnlineContributionForm(array $submittedValues, int $contributionPageID) {
+    $form = $this->getTestForm('CRM_Contribute_Form_Contribution_Main', $submittedValues, ['id' => $contributionPageID])
+      ->addSubsequentForm('CRM_Contribute_Form_Contribution_Confirm');
+    $form->processForm();
+    return $form;
+  }
+
 }
index 84a0de4ed704aa881916705fccf353dc7ffea21b..95a7a5cf574d90b14ac7eda4a751a1922a049211 100644 (file)
@@ -168,7 +168,7 @@ trait CRMTraits_Financial_PriceSetTrait {
       ], $membershipTypeParams);
       $this->ids['MembershipType'] = [$this->membershipTypeCreate($membershipTypeParams)];
     }
-    $priceField = $this->callAPISuccess('price_field', 'create', [
+    $priceField = $this->callAPISuccess('PriceField', 'create', [
       'price_set_id' => $this->ids['PriceSet']['membership_block'],
       'name' => 'membership_amount',
       'label' => 'Membership Amount',