FIx tests caling AdditionalPayment form to use full flow, add getContributionID(...
authorEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 4 Dec 2023 00:44:39 +0000 (13:44 +1300)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 4 Dec 2023 08:35:51 +0000 (21:35 +1300)
CRM/Contribute/Form/AdditionalPayment.php
tests/phpunit/CRM/Contribute/Form/ContributionTest.php
tests/phpunit/CRM/Member/Form/MembershipTest.php

index 92d5794ab0b984232960351d8d946eeca0621484..7a707d09f268ce1fabe5e7f3a242b9f814cd85d3 100644 (file)
@@ -15,6 +15,8 @@
  * @copyright CiviCRM LLC https://civicrm.org/licensing
  */
 
+use Civi\Payment\Exception\PaymentProcessorException;
+
 /**
  * This form records additional payments needed when event/contribution is partially paid.
  */
@@ -48,7 +50,14 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
 
   protected $_paymentType = NULL;
 
-  protected $_contributionId = NULL;
+  /**
+   * Internal property for contribution ID - use getContributionID().
+   *
+   * @var int
+   *
+   * @internal
+   */
+  protected $_contributionId;
 
   protected $fromEmailId = NULL;
 
@@ -72,17 +81,11 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
     $this->assign('id', $this->_id);
     $this->assign('suppressPaymentFormButtons', $this->isBeingCalledFromSelectorContext());
 
-    if ($this->_view == 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
+    if ($this->_view === 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
       $title = $this->assignPaymentInfoBlock();
       $this->setTitle($title);
       return;
     }
-    if ($this->_component == 'event') {
-      $this->_contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_id, 'contribution_id', 'participant_id');
-    }
-    else {
-      $this->_contributionId = $this->_id;
-    }
 
     $paymentAmt = $this->getAmountDue();
 
@@ -96,7 +99,7 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
       throw new CRM_Core_Exception(ts('Credit card payment is not for Refund payments use'));
     }
 
-    list($this->_contributorDisplayName, $this->_contributorEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
+    [$this->_contributorDisplayName, $this->_contributorEmail] = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
 
     $this->assign('contributionMode', $this->_mode);
     $this->assign('contactId', $this->_contactID);
@@ -134,7 +137,7 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
    * @throws \CRM_Core_Exception
    */
   public function setDefaultValues() {
-    if ($this->_view == 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
+    if ($this->_view === 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
       return NULL;
     }
     $defaults = [];
@@ -309,9 +312,6 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
   public function submit($submittedValues) {
     $this->_params = $submittedValues;
     $this->beginPostProcess();
-    // _contributorContactID may no longer need to be set - setting it here
-    // was for use in processBillingAddress
-    $this->_contributorContactID = $this->_contactID;
     $this->processBillingAddress($this->_contactID, (string) $this->_contributorEmail);
     $participantId = NULL;
     if ($this->_component === 'event') {
@@ -334,13 +334,13 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
     $trxnsData['is_send_contribution_notification'] = FALSE;
     $paymentID = civicrm_api3('Payment', 'create', $trxnsData)['id'];
 
-    if ($this->_contributionId && CRM_Core_Permission::access('CiviMember')) {
+    if ($this->getContributionID() && CRM_Core_Permission::access('CiviMember')) {
       $membershipPaymentCount = civicrm_api3('MembershipPayment', 'getCount', ['contribution_id' => $this->_contributionId]);
       if ($membershipPaymentCount) {
         $this->ajaxResponse['updateTabs']['#tab_member'] = CRM_Contact_BAO_Contact::getCountComponent('membership', $this->_contactID);
       }
     }
-    if ($this->_contributionId && CRM_Core_Permission::access('CiviEvent')) {
+    if ($this->getContributionID() && CRM_Core_Permission::access('CiviEvent')) {
       $participantPaymentCount = civicrm_api3('ParticipantPayment', 'getCount', ['contribution_id' => $this->_contributionId]);
       if ($participantPaymentCount) {
         $this->ajaxResponse['updateTabs']['#tab_participant'] = CRM_Contact_BAO_Contact::getCountComponent('participant', $this->_contactID);
@@ -359,7 +359,7 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
     CRM_Core_Session::setStatus($statusMsg, ts('Saved'), 'success');
   }
 
-  public function processCreditCard() {
+  public function processCreditCard(): ?array {
     $config = CRM_Core_Config::singleton();
     $session = CRM_Core_Session::singleton();
 
@@ -409,11 +409,11 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
 
     if ($paymentParams['amount'] > 0.0) {
       try {
-        // force a reset of the payment processor in case the form changed it, CRM-7179
-        $payment = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
+        // Re-retrieve the payment processor in case the form changed it, CRM-7179
+        $payment = \Civi\Payment\System::singleton()->getById($this->getPaymentProcessorID());
         $result = $payment->doPayment($paymentParams);
       }
-      catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
+      catch (PaymentProcessorException $e) {
         Civi::log()->error('Payment processor exception: ' . $e->getMessage());
         $urlParams = "action=add&cid={$this->_contactId}&id={$this->_contributionId}&component={$this->_component}&mode={$this->_mode}";
         CRM_Core_Error::statusBounce($e->getMessage(), CRM_Utils_System::url('civicrm/payment/add', $urlParams));
@@ -425,20 +425,18 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
     }
 
     $this->set('params', $this->_params);
-
-    // set source if not set
-    if (empty($this->_params['source'])) {
-      $userID = $session->get('userID');
-      $userSortName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $userID,
-        'sort_name'
-      );
-      $this->_params['source'] = ts('Submit Credit Card Payment by: %1', [1 => $userSortName]);
-    }
+    return [
+      'fee_amount' => $result['fee_amount'] ?? 0,
+      'trxn_id' => $result['trxn_id'] ?? NULL,
+      'trxn_result_code' => $result['trxn_result_code'] ?? NULL,
+    ];
   }
 
   /**
    * Wrapper for unit testing the post process submit function.
    *
+   * @deprecated since 5.69 will be removed around 5.75
+   *
    * @param array $params
    * @param string|null $creditCardMode
    * @param string $entityType
@@ -446,6 +444,7 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
    * @throws \CRM_Core_Exception
    */
   public function testSubmit($params, $creditCardMode = NULL, $entityType = 'contribute') {
+    CRM_Core_Error::deprecatedFunctionWarning('use FormTrait in tests');
     $this->_bltID = 5;
     // Required because processCreditCard calls set method on this.
     $_SERVER['REQUEST_METHOD'] = 'GET';
@@ -516,9 +515,40 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract
    */
   protected function getAmountDue(): float {
     if (!isset($this->amountDue)) {
-      $this->amountDue = CRM_Contribute_BAO_Contribution::getContributionBalance($this->_contributionId);
+      $this->amountDue = CRM_Contribute_BAO_Contribution::getContributionBalance($this->getContributionID());
     }
     return $this->amountDue;
   }
 
+  /**
+   * 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->_contributionId) {
+      $component = CRM_Utils_Request::retrieve('component', 'String', $this, FALSE, 'contribution');
+      if ($component === 'event') {
+        $this->_contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_id, 'contribution_id', 'participant_id');
+      }
+      else {
+        $this->_contributionId = $this->_id;
+      }
+    }
+    return (int) $this->_contributionId;
+  }
+
+  /**
+   * Get the payment processor ID.
+   *
+   * @return int
+   */
+  public function getPaymentProcessorID(): int {
+    return (int) ($this->getSubmittedValue('payment_processor_id') ?: $this->_paymentProcessor['id']);
+  }
+
 }
index 379cc0f708cd8336470458f2e7c140e1db64de89..b6912091f69a0b6cf8d01da8564f1e7a21f26988 100644 (file)
@@ -959,8 +959,6 @@ Receipt Date: ' . date('m/d/Y'),
 
   /**
    * Test the submit function that completes the partially paid payment using Credit Card
-   *
-   * @throws \CRM_Core_Exception
    */
   public function testPartialPaymentWithCreditCard(): void {
     // create a partially paid contribution by using back-office form
@@ -979,11 +977,7 @@ Receipt Date: ' . date('m/d/Y'),
     $this->callAPISuccess('Payment', 'create', ['contribution_id' => $contribution['id'], 'total_amount' => 10, 'payment_instrument_id' => 'Cash']);
     $contribution = $this->callAPISuccessGetSingle('Contribution', ['id' => $contribution['id']]);
     $this->assertEquals('Partially paid', $contribution['contribution_status']);
-    // pay additional amount by using Credit Card
-    $form = new CRM_Contribute_Form_AdditionalPayment();
-    $form->testSubmit([
-      'contribution_id' => $contribution['id'],
-      'contact_id' => $this->_individualId,
+    $form = $this->getTestForm('CRM_Contribute_Form_AdditionalPayment', [
       'total_amount' => 40,
       'currency' => 'USD',
       'financial_type_id' => 1,
@@ -998,7 +992,8 @@ Receipt Date: ' . date('m/d/Y'),
       'billing_postal_code-5' => 1321312,
       'billing_country_id-5' => 1228,
       'trxn_date' => '2017-04-11 13:05:11',
-    ], 'live');
+    ], ['id' => $contribution['id'], 'mode' => 'live'])->processForm();
+    $this->assertEquals($contribution['id'], $form->getContributionID());
     $contribution = $this->callAPISuccessGetSingle('Contribution', []);
     $this->assertNotEmpty($contribution);
     $this->assertEquals('Completed', $contribution['contribution_status']);
index 88c2aed05095ad7e4b4eaae6b1ebe38e05cb7139..a267692b430dd40a0ca16086c85fc3b595dadfbd 100644 (file)
@@ -21,6 +21,7 @@ use Civi\Api4\FinancialType;
 use Civi\Api4\Membership;
 use Civi\Api4\MembershipType;
 use Civi\Api4\PriceFieldValue;
+use Civi\Test\FormTrait;
 
 /**
  *  Test CRM_Member_Form_Membership functions.
@@ -32,6 +33,7 @@ class CRM_Member_Form_MembershipTest extends CiviUnitTestCase {
 
   use CRMTraits_Financial_OrderTrait;
   use CRMTraits_Financial_PriceSetTrait;
+  use FormTrait;
 
   /**
    * @var int
@@ -799,20 +801,18 @@ class CRM_Member_Form_MembershipTest extends CiviUnitTestCase {
 
     // Step 2: submit the other half of the partial payment
     //  via AdditionalPayment form to complete the related contribution
-    $form = new CRM_Contribute_Form_AdditionalPayment();
-    $submitParams = [
-      'contribution_id' => $contribution['contribution_id'],
-      'contact_id' => $this->_individualId,
-      'total_amount' => $this->formatMoneyInput(25),
-      'currency' => 'USD',
-      'financial_type_id' => 2,
-      'receive_date' => '2015-04-21 23:27:00',
+    $this->getTestForm('CRM_Contribute_Form_AdditionalPayment', [
+      'total_amount' => 150.00,
       'trxn_date' => '2017-04-11 13:05:11',
-      'payment_processor_id' => 0,
-      'payment_instrument_id' => array_search('Check', $this->paymentInstruments, TRUE),
+      'payment_instrument_id' => CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_FinancialTrxn', 'payment_instrument_id', 'Check'),
       'check_number' => 'check-12345',
-    ];
-    $form->testSubmit($submitParams);
+      'trxn_id' => '',
+      'currency' => 'USD',
+      'fee_amount' => '',
+      'net_amount' => '',
+      'payment_processor_id' => 0,
+      'contact_id' => $this->_individualId,
+    ], ['id' => $contribution['id']])->processForm();
     $membership = $this->callAPISuccessGetSingle('Membership', ['contact_id' => $this->_individualId]);
     // check the membership status after additional payment, if its changed to 'New'
     $this->assertEquals(array_search('New', CRM_Member_PseudoConstant::membershipStatus(), TRUE), $membership['status_id']);
@@ -1511,7 +1511,7 @@ Expires: ',
       'price_' . $fieldOption['price_field_id'] => $fieldOption['id'],
       'total_amount' => 55,
       'receive_date' => date('Y-m-d') . ' 20:36:00',
-      'payment_instrument_id' => array_search('Check', $this->paymentInstruments, TRUE),
+      'payment_instrument_id' => CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_FinancialTrxn', 'payment_instrument_id', 'Check'),
       'contribution_status_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'),
       //Member dues, see data.xml
       'financial_type_id' => 2,
@@ -1648,16 +1648,15 @@ Expires: ',
       'contact_id' => $this->_individualId,
     ]);
     $endDate = (new DateTime(date('Y-m-d')))->modify('+3 years')->modify('-1 day');
-    $endDate = $endDate->format("Y-m-d");
+    $endDate = $endDate->format('Y-m-d');
 
     $this->assertEquals($endDate, $membership['end_date'], 'Membership Expiration Date should be ' . $endDate);
-    $this->assertEquals(1, count($contribution['values']), 'Pending contribution should be created.');
+    $this->assertCount(1, $contribution['values'], 'Pending contribution should be created.');
     $contribution = $contribution['values'][$contribution['id']];
-    $additionalPaymentForm = new CRM_Contribute_Form_AdditionalPayment();
-    $additionalPaymentForm->testSubmit([
+    $this->getTestForm('CRM_Contribute_Form_AdditionalPayment', [
       'total_amount' => 150.00,
-      'trxn_date' => date("Y-m-d H:i:s"),
-      'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
+      'trxn_date' => date('Y-m-d H:i:s'),
+      'payment_instrument_id' => CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_FinancialTrxn', 'payment_instrument_id', 'Check'),
       'check_number' => 'check-12345',
       'trxn_id' => '',
       'currency' => 'USD',
@@ -1666,8 +1665,7 @@ Expires: ',
       'net_amount' => '',
       'payment_processor_id' => 0,
       'contact_id' => $this->_individualId,
-      'contribution_id' => $contribution['id'],
-    ]);
+    ], ['id' => $contribution['id']])->processForm();
     $membership = $this->callAPISuccessGetSingle('Membership', ['contact_id' => $this->_individualId]);
     $contribution = $this->callAPISuccess('Contribution', 'get', [
       'contact_id' => $this->_individualId,