From adbe76d4a1359a64d8e419287cc5402b093e883a Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Wed, 25 Oct 2023 14:04:15 +1300 Subject: [PATCH] Fix test on secondary membership contribution to use full form flow 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 | 16 ++--- CRM/Contribute/Form/ContributionBase.php | 26 +++++++- Civi/Test/FormWrapper.php | 8 +++ .../Form/Contribution/ConfirmTest.php | 62 ++++++++++++------- .../CRMTraits/Financial/PriceSetTrait.php | 2 +- 5 files changed, 80 insertions(+), 34 deletions(-) diff --git a/CRM/Contribute/Form/Contribution/Main.php b/CRM/Contribute/Form/Contribution/Main.php index 8b78716d93..c2bdaa48c9 100644 --- a/CRM/Contribute/Form/Contribution/Main.php +++ b/CRM/Contribute/Form/Contribution/Main.php @@ -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 diff --git a/CRM/Contribute/Form/ContributionBase.php b/CRM/Contribute/Form/ContributionBase.php index 1b0b80b786..3ac8a81fda 100644 --- a/CRM/Contribute/Form/ContributionBase.php +++ b/CRM/Contribute/Form/ContributionBase.php @@ -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; + } + } diff --git a/Civi/Test/FormWrapper.php b/Civi/Test/FormWrapper.php index 0989d4c09d..e20b031061 100644 --- a/Civi/Test/FormWrapper.php +++ b/Civi/Test/FormWrapper.php @@ -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; } diff --git a/tests/phpunit/CRM/Contribute/Form/Contribution/ConfirmTest.php b/tests/phpunit/CRM/Contribute/Form/Contribution/ConfirmTest.php index f0569f2c27..1bbbc194e3 100644 --- a/tests/phpunit/CRM/Contribute/Form/Contribution/ConfirmTest.php +++ b/tests/phpunit/CRM/Contribute/Form/Contribution/ConfirmTest.php @@ -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; + } + } diff --git a/tests/phpunit/CRMTraits/Financial/PriceSetTrait.php b/tests/phpunit/CRMTraits/Financial/PriceSetTrait.php index 84a0de4ed7..95a7a5cf57 100644 --- a/tests/phpunit/CRMTraits/Financial/PriceSetTrait.php +++ b/tests/phpunit/CRMTraits/Financial/PriceSetTrait.php @@ -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', -- 2.25.1