From 6876b7be158b17634ee77cc1976a39459ca5bf3b Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Mon, 4 Dec 2023 13:44:39 +1300 Subject: [PATCH] FIx tests caling AdditionalPayment form to use full flow, add getContributionID() function --- CRM/Contribute/Form/AdditionalPayment.php | 88 +++++++++++++------ .../CRM/Contribute/Form/ContributionTest.php | 11 +-- .../CRM/Member/Form/MembershipTest.php | 40 ++++----- 3 files changed, 81 insertions(+), 58 deletions(-) diff --git a/CRM/Contribute/Form/AdditionalPayment.php b/CRM/Contribute/Form/AdditionalPayment.php index 92d5794ab0..7a707d09f2 100644 --- a/CRM/Contribute/Form/AdditionalPayment.php +++ b/CRM/Contribute/Form/AdditionalPayment.php @@ -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']); + } + } diff --git a/tests/phpunit/CRM/Contribute/Form/ContributionTest.php b/tests/phpunit/CRM/Contribute/Form/ContributionTest.php index 379cc0f708..b6912091f6 100644 --- a/tests/phpunit/CRM/Contribute/Form/ContributionTest.php +++ b/tests/phpunit/CRM/Contribute/Form/ContributionTest.php @@ -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']); diff --git a/tests/phpunit/CRM/Member/Form/MembershipTest.php b/tests/phpunit/CRM/Member/Form/MembershipTest.php index 88c2aed050..a267692b43 100644 --- a/tests/phpunit/CRM/Member/Form/MembershipTest.php +++ b/tests/phpunit/CRM/Member/Form/MembershipTest.php @@ -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, -- 2.25.1