From: Eileen McNaughton Date: Thu, 27 Jul 2023 23:14:02 +0000 (+1200) Subject: Update ContributionMainTest to use full form flow X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=de72e40b1999f9c4193fe14c3e97210cfba7b16b;p=civicrm-core.git Update ContributionMainTest to use full form flow This updates the test to use postProcess and to check is_recur is passed to the preApprove function rather than proxy that check by checking if is_recur is set in the _params property (which is not used again after the preApprove --- diff --git a/CRM/Contribute/Form/Contribution/Main.php b/CRM/Contribute/Form/Contribution/Main.php index d8c9960760..2a712ad4d5 100644 --- a/CRM/Contribute/Form/Contribution/Main.php +++ b/CRM/Contribute/Form/Contribution/Main.php @@ -1370,6 +1370,9 @@ class CRM_Contribute_Form_Contribution_Main extends CRM_Contribute_Form_Contribu /** * Function for unit tests on the postProcess function. * + * @deprecated - we are ditching this approach in favour of 'full form flow' + * = ie simulating postProcess. + * * @param array $params * * @throws \CRM_Core_Exception diff --git a/CRM/Core/Payment/Dummy.php b/CRM/Core/Payment/Dummy.php index 4b6735d819..d2d3195c68 100644 --- a/CRM/Core/Payment/Dummy.php +++ b/CRM/Core/Payment/Dummy.php @@ -167,6 +167,21 @@ class CRM_Core_Payment_Dummy extends CRM_Core_Payment { return $this->supports['CancelRecurringNotifyOptional']; } + /** + * Does this processor support pre-approval. + * + * This would generally look like a redirect to enter credentials which can then be used in a later payment call. + * + * Currently Paypal express supports this, with a redirect to paypal after the 'Main' form is submitted in the + * contribution page. This token can then be processed at the confirm phase. Although this flow 'looks' like the + * 'notify' flow a key difference is that in the notify flow they don't have to return but in this flow they do. + * + * @return bool + */ + protected function supportsPreApproval(): bool { + return $this->supports['PreApproval'] ?? FALSE; + } + /** * Set the return value of support functions. By default it is TRUE * @@ -261,6 +276,21 @@ class CRM_Core_Payment_Dummy extends CRM_Core_Payment { */ public function doRefund(&$params) {} + /** + * Function to action pre-approval if supported + * + * @param array $params + * Parameters from the form + * + * This function returns an array which should contain + * - pre_approval_parameters (this will be stored on the calling form & available later) + * - redirect_url (if set the browser will be redirected to this. + */ + public function doPreApproval(&$params): void { + // We set this here to allow the test to check what is set. + \Civi::$statics[__CLASS__][__FUNCTION__] = $params; + } + /** * This function checks to see if we have the right config values. * diff --git a/tests/phpunit/CRM/Contribute/Form/Contribution/MainTest.php b/tests/phpunit/CRM/Contribute/Form/Contribution/MainTest.php index e450e5ce40..0bb03f4988 100644 --- a/tests/phpunit/CRM/Contribute/Form/Contribution/MainTest.php +++ b/tests/phpunit/CRM/Contribute/Form/Contribution/MainTest.php @@ -9,6 +9,8 @@ +--------------------------------------------------------------------+ */ +use Civi\Api4\PriceField; + /** * Test APIv3 civicrm_contribute_* functions * @@ -41,8 +43,8 @@ class CRM_Contribute_Form_Contribution_MainTest extends CiviUnitTestCase { /** * Given a membership type ID, return the price field value. */ - private function getPriceFieldValue($membershipTypeId) { - return $this->callAPISuccessGetValue('PriceFieldValue', ['membership_type_id' => $membershipTypeId, 'return' => 'id']); + private function getPriceFieldValue($membershipTypeID): int { + return (int) $this->callAPISuccessGetSingle('PriceFieldValue', ['membership_type_id' => $membershipTypeID, 'return' => 'id', 'price_field_id' => $this->ids['PriceField']['membership']])['id']; } /** @@ -61,7 +63,7 @@ class CRM_Contribute_Form_Contribution_MainTest extends CiviUnitTestCase { 'credit_card_exp_date' => ['M' => 9, 'Y' => 2040], 'cvv2' => 123, 'auto_renew' => 1, - 'priceSetId' => $this->priceSetId, + 'priceSetId' => $this->ids['PriceSet']['membership'], ]; } @@ -69,53 +71,40 @@ class CRM_Contribute_Form_Contribution_MainTest extends CiviUnitTestCase { * Test that the membership is set to recurring if the membership type is always autorenew. */ public function testSetRecurFunction(): void { - $membershipTypeID = $this->membershipTypeCreate(['auto_renew' => 2, 'minimum_fee' => 80]); + $this->membershipTypeCreate(['auto_renew' => 2, 'minimum_fee' => 80]); $form = $this->getContributionForm(); - $priceFieldValueId = $this->getPriceFieldValue($membershipTypeID); - $form->testSubmit(array_merge($this->getSubmitParams(), [ - 'price_' . $this->priceSetId => $priceFieldValueId, - ])); - $this->assertEquals(1, $form->_params['is_recur']); + $form->postProcess(); + $this->assertIsRecur(1); } /** * Test that the membership is set to recurring if the membership type is optionally autorenew and is_recur is true. */ public function testSetRecurFunctionOptionalYes(): void { - $membershipTypeID = $this->membershipTypeCreate(['auto_renew' => 1, 'minimum_fee' => 80]); + $this->membershipTypeCreate(['auto_renew' => 1, 'minimum_fee' => 80]); $form = $this->getContributionForm(); - $priceFieldValueId = $this->getPriceFieldValue($membershipTypeID); - $form->testSubmit(array_merge($this->getSubmitParams(), [ - 'price_' . $this->priceSetId => $priceFieldValueId, - ])); - $this->assertEquals(1, $form->_params['is_recur']); + $form->postProcess(); + $this->assertIsRecur(1); } /** * Test that the membership is not set to recurring if the membership type is optionally autorenew and is_recur is false. */ public function testSetRecurFunctionOptionalNo(): void { - $membershipTypeID = $this->membershipTypeCreate(['auto_renew' => 1, 'minimum_fee' => 80]); - $form = $this->getContributionForm(); - $priceFieldValueId = $this->getPriceFieldValue($membershipTypeID); - $form->testSubmit(array_merge($this->getSubmitParams(), [ - 'price_' . $this->priceSetId => $priceFieldValueId, - 'auto_renew' => 0, - ])); - $this->assertEquals(0, $form->_params['is_recur']); + $this->membershipTypeCreate(['auto_renew' => 1, 'minimum_fee' => 80]); + $form = $this->getContributionForm(['auto_renew' => 0]); + $form->postProcess(); + $this->assertIsRecur(0); } /** * Test that the membership doesn't have an "is_recur" key if the membership type can never autorenew. */ - public function testSetRecurFunctionNotAvailable() { - $membershipTypeID = $this->membershipTypeCreate(['auto_renew' => 0, 'minimum_fee' => 80]); + public function testSetRecurFunctionNotAvailable(): void { + $this->membershipTypeCreate(['auto_renew' => 0, 'minimum_fee' => 80]); $form = $this->getContributionForm(); - $priceFieldValueId = $this->getPriceFieldValue($membershipTypeID); - $form->testSubmit(array_merge($this->getSubmitParams(), [ - 'price_' . $this->priceSetId => $priceFieldValueId, - ])); - $this->assertArrayNotHasKey('is_recur', $form->_params); + $form->postProcess(); + $this->assertIsRecur(NULL); } /** @@ -128,10 +117,11 @@ class CRM_Contribute_Form_Contribution_MainTest extends CiviUnitTestCase { */ protected function getContributionForm(array $submittedValues = [], $params = []): CRM_Contribute_Form_Contribution_Main { try { - $this->priceSetId = $params['priceSetID'] ?? $this->callAPISuccessGetValue('PriceSet', [ + $this->ids['PriceSet']['membership'] = $params['priceSetID'] ?? $this->callAPISuccessGetValue('PriceSet', [ 'name' => 'default_membership_type_amount', 'return' => 'id', ]); + $this->ids['PriceField']['membership'] = PriceField::get(FALSE)->addWhere('price_set_id', '=', $this->ids['PriceSet']['membership'])->execute()->first()['id']; $paymentProcessor = $submittedValues['payment_processor_id'] = $this->paymentProcessorCreate([ 'payment_processor_type_id' => 'Dummy', @@ -150,12 +140,16 @@ class CRM_Contribute_Form_Contribution_MainTest extends CiviUnitTestCase { 'amount_block_is_active' => 1, ])); $contributionPage = $this->contributionPageCreate($contributionPageParams); + CRM_Price_BAO_PriceSet::addTo('civicrm_contribution_page', $contributionPage['id'], $this->ids['PriceSet']['membership']); + + $submittedValues = array_merge($this->getSubmitParams(), [ + 'price_' . $this->ids['PriceField']['membership'] => $this->getPriceFieldValue($this->ids['MembershipType']['test']), + ], $submittedValues); $submittedValues['id'] = $_REQUEST['id'] = (int) $contributionPage['id']; /** @var \CRM_Contribute_Form_Contribution_Main $form */ $form = $this->getFormObject('CRM_Contribute_Form_Contribution_Main', $submittedValues); - $form->set('id', $contributionPage['id']); - CRM_Price_BAO_PriceSet::addTo('civicrm_contribution_page', $contributionPage['id'], $this->priceSetId); $form->preProcess(); + $form->_paymentProcessor['object']->setSupports(['PreApproval' => TRUE, 'BackOffice' => TRUE]); $form->buildQuickForm(); // Need these values to create more realistic submit params (in getSubmitParams). $this->paymentProcessorId = $paymentProcessor; @@ -167,7 +161,7 @@ class CRM_Contribute_Form_Contribution_MainTest extends CiviUnitTestCase { } /** - * Test expired priceset are not returned from buildPriceSet() Function + * Test expired priceset are not returned from buildPriceSet() Function. */ public function testExpiredPriceSet(): void { $priceSetParams1 = [ @@ -179,39 +173,38 @@ class CRM_Contribute_Form_Contribution_MainTest extends CiviUnitTestCase { 'is_quick_config' => 1, 'is_reserved' => 1, ]; - $priceSet = $this->callAPISuccess('price_set', 'create', $priceSetParams1); + $priceSet = $this->createTestEntity('PriceSet', $priceSetParams1); // Create valid price field. $params = [ - 'price_set_id' => $priceSet['id'], - 'name' => 'testvalidpf', - 'label' => 'test valid pf', + 'price_set_id' => $this->ids['PriceSet']['default'], + 'name' => 'test_valid_price_field', + 'label' => 'test valid price field', 'html_type' => 'Radio', 'is_enter_qty' => 1, 'is_active' => 1, ]; - $priceField1 = $this->callAPISuccess('PriceField', 'create', $params); + $priceField1 = $this->createTestEntity('PriceField', $params); // Create expired price field. $params = [ 'price_set_id' => $priceSet['id'], - 'name' => 'testexpiredpf', - 'label' => 'test expired pf', + 'name' => 'test_expired_price_field', + 'label' => 'test expired price field', 'html_type' => 'Radio', 'is_enter_qty' => 1, 'is_active' => 1, - 'expire_on' => date('Y-m-d', strtotime("-1 days")), + 'expire_on' => date('Y-m-d', strtotime('-1 days')), ]; - $priceField2 = $this->callAPISuccess('PriceField', 'create', $params); + $priceField2 = $this->createTestEntity('PriceField', $params, 'expired'); //Create price options. - $membershipOrgId = $this->organizationCreate(); - $memtype = $this->membershipTypeCreate(['member_of_contact_id' => $membershipOrgId]); + $this->membershipTypeCreate(['member_of_contact_id' => $this->organizationCreate()]); foreach ([$priceField1, $priceField2] as $priceField) { $priceFieldValueParams = [ 'price_field_id' => $priceField['id'], 'name' => 'rye grass', - 'membership_type_id' => $memtype, + 'membership_type_id' => $this->ids['MembershipType']['test'], 'label' => 'juicy and healthy', 'amount' => 1, 'membership_num_terms' => 2, @@ -221,8 +214,8 @@ class CRM_Contribute_Form_Contribution_MainTest extends CiviUnitTestCase { } $form = $this->getContributionForm([], ['priceSetID' => $priceSet['id']]); - foreach ($form->_priceSet['fields'] as $pField) { - foreach ($pField['options'] as $opId => $opValues) { + foreach ($form->_priceSet['fields'] as $priceField) { + foreach ($priceField['options'] as $opValues) { $membershipTypeIds[$opValues['membership_type_id']] = $opValues['membership_type_id']; } } @@ -231,9 +224,17 @@ class CRM_Contribute_Form_Contribution_MainTest extends CiviUnitTestCase { //This function should not update form priceSet with the expired one. CRM_Price_BAO_PriceSet::buildPriceSet($form); - $this->assertEquals(1, count($form->_priceSet['fields'])); + $this->assertCount(1, $form->_priceSet['fields']); $field = current($form->_priceSet['fields']); - $this->assertEquals('testvalidpf', $field['name']); + $this->assertEquals('test_valid_price_field', $field['name']); + } + + /** + * @param int|null $expected + */ + protected function assertIsRecur(?int $expected): void { + $isRecur = \Civi::$statics['CRM_Core_Payment_Dummy']['doPreApproval']['is_recur'] ?? NULL; + $this->assertEquals($expected, $isRecur); } } diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index abc2e372c1..973a120a5f 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -563,10 +563,11 @@ class CiviUnitTestCase extends PHPUnit\Framework\TestCase { /** * @param array $params + * @param string $identifer * * @return int */ - public function membershipTypeCreate($params = []) { + public function membershipTypeCreate(array $params = [], $identifer = 'test'): int { CRM_Member_PseudoConstant::flush('membershipType'); CRM_Core_Config::clearDBCache(); $this->setupIDs['contact'] = $memberOfOrganization = $this->organizationCreate(); @@ -587,7 +588,7 @@ class CiviUnitTestCase extends PHPUnit\Framework\TestCase { CRM_Member_PseudoConstant::flush('membershipType'); CRM_Utils_Cache::singleton()->flush(); - + $this->ids['MembershipType'][$identifer] = (int) $result['id']; return (int) $result['id']; }