From e7f75a4962657986c93c07009ba68f61163b39e7 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Mon, 4 Sep 2023 14:19:21 +1200 Subject: [PATCH] Update one of our complex confirm tests to use full form flow, fix discovered additional payments bug --- CRM/Contribute/BAO/Contribution.php | 5 +- .../Registration/AdditionalParticipant.php | 1 + CRM/Event/Form/Registration/Register.php | 1 + Civi/Test/FormTrait.php | 4 + Civi/Test/FormWrapper.php | 43 ++++--- Civi/Test/FormWrappers/EventFormOnline.php | 36 ++++++ .../Event/Form/Registration/ConfirmTest.php | 110 +++++++----------- tests/phpunit/CiviTest/CiviUnitTestCase.php | 2 + 8 files changed, 121 insertions(+), 81 deletions(-) create mode 100644 Civi/Test/FormWrappers/EventFormOnline.php diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index d3ff989685..2e7859ea92 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -2063,7 +2063,10 @@ LEFT JOIN civicrm_contribution contribution ON ( componentPayment.contribution_ LEFT JOIN civicrm_participant p ON pp.participant_id = p.id LEFT JOIN civicrm_membership m ON m.id = mp.membership_id LEFT JOIN civicrm_pledge_payment pgp ON pgp.contribution_id = c.id - WHERE c.id = $contributionId"; + WHERE c.id = $contributionId + -- only get the primary recipient + AND (p.registered_by_id IS NULL OR p.registered_by_id = 0) + "; $dao = CRM_Core_DAO::executeQuery($query); $componentDetails = []; diff --git a/CRM/Event/Form/Registration/AdditionalParticipant.php b/CRM/Event/Form/Registration/AdditionalParticipant.php index 7d3baa4cc1..81ee3e4d07 100644 --- a/CRM/Event/Form/Registration/AdditionalParticipant.php +++ b/CRM/Event/Form/Registration/AdditionalParticipant.php @@ -673,6 +673,7 @@ class CRM_Event_Form_Registration_AdditionalParticipant extends CRM_Event_Form_R $params['amount'] = $this->_values['discount'][$discountId][$params['amount']]['value']; } elseif (empty($params['priceSetId'])) { + CRM_Core_Error::deprecatedWarning('unreachable code, prices set always passed as hidden field for monetary events'); $params['amount'] = $this->_values['fee'][$params['amount']]['value']; } else { diff --git a/CRM/Event/Form/Registration/Register.php b/CRM/Event/Form/Registration/Register.php index 82219a43d2..82321a0cde 100644 --- a/CRM/Event/Form/Registration/Register.php +++ b/CRM/Event/Form/Registration/Register.php @@ -1043,6 +1043,7 @@ class CRM_Event_Form_Registration_Register extends CRM_Event_Form_Registration { $params['amount'] = $this->_values['discount'][$discountId][$params['amount']]['value']; } elseif (empty($params['priceSetId'])) { + CRM_Core_Error::deprecatedWarning('unreachable code price set is always set here - passed as a hidden field although we could just load...'); if (!empty($params['amount'])) { $params['amount'] = $this->_values['fee'][$params['amount']]['value']; } diff --git a/Civi/Test/FormTrait.php b/Civi/Test/FormTrait.php index 4a49fcd255..799a586a2b 100644 --- a/Civi/Test/FormTrait.php +++ b/Civi/Test/FormTrait.php @@ -11,6 +11,7 @@ namespace Civi\Test; +use Civi\Test\FormWrappers\EventFormOnline; use Civi\Test\FormWrappers\EventFormParticipant; /** @@ -29,6 +30,9 @@ trait FormTrait { if ($formName === 'CRM_Event_Form_Participant') { return new EventFormParticipant($formName, $submittedValues, $urlParameters); } + if ($formName === 'CRM_Event_Form_Registration_Register') { + return new EventFormOnline($formName, $submittedValues, $urlParameters); + } return new FormWrapper($formName, $submittedValues, $urlParameters); } diff --git a/Civi/Test/FormWrapper.php b/Civi/Test/FormWrapper.php index d888f1c994..308cd4d269 100644 --- a/Civi/Test/FormWrapper.php +++ b/Civi/Test/FormWrapper.php @@ -15,16 +15,6 @@ use Civi\Api4\Utils\ReflectionUtils; class FormWrapper { - /** - * @var string - */ - private $formName; - - /** - * @var array - */ - private $urlParameters; - /** * @var array */ @@ -35,6 +25,11 @@ class FormWrapper { */ protected $form; + /** + * @var \CRM_Core_Form[] + */ + protected $subsequentForms; + private $output; private $templateVariables; @@ -62,9 +57,8 @@ class FormWrapper { * @param array $urlParameters */ public function __construct(string $formName, array $formValues = [], array $urlParameters = []) { - $this->formName = $formName; - $this->urlParameters = $urlParameters; $this->formValues = $formValues; + $this->setFormObject($formName, $this->formValues, $urlParameters); } /** @@ -75,7 +69,6 @@ class FormWrapper { * @return \Civi\Test\FormWrapper */ public function processForm(int $state = self::SUBMITTED): self { - $this->setFormObject($this->formName, $this->formValues, $this->urlParameters); if ($state > self::CONSTRUCTED) { $this->form->preProcess(); } @@ -87,10 +80,32 @@ class FormWrapper { } if ($state > self::VALIDATED) { $this->form->postProcess(); + foreach ($this->subsequentForms as $form) { + $form->preProcess(); + $form->buildForm(); + $form->postProcess(); + } } return $this; } + /** + * Add another form to process. + * + * @param string $formName + * @param array $formValues + * + * @return $this + */ + public function addSubsequentForm(string $formName, array $formValues = []): FormWrapper { + /* @var \CRM_Core_Form */ + $form = new $formName(); + $form->controller = $this->form->controller; + $_SESSION['_' . $this->form->controller->_name . '_container']['values'][$form->getName()] = $formValues; + $this->subsequentForms[$form->getName()] = $form; + return $this; + } + /** * Call a function declared as externally accessible on the form. * @@ -139,7 +154,7 @@ class FormWrapper { * * @param array $urlParameters */ - private function setFormObject(string $class, array $formValues = [], array $urlParameters = []) { + private function setFormObject(string $class, array $formValues = [], array $urlParameters = []): void { $_POST = $formValues; $this->form = new $class(); $_SERVER['REQUEST_METHOD'] = 'GET'; diff --git a/Civi/Test/FormWrappers/EventFormOnline.php b/Civi/Test/FormWrappers/EventFormOnline.php new file mode 100644 index 0000000000..be3ae7e81c --- /dev/null +++ b/Civi/Test/FormWrappers/EventFormOnline.php @@ -0,0 +1,36 @@ +subsequentForms['Participant_' . $formNumber])) { + $formNumber++; + } + /* @var \CRM_Core_Form */ + $form = new $formName(NULL, \CRM_Core_Action::NONE, 'post', 'Participant_' . $formNumber); + $form->controller = $this->form->controller; + $_SESSION['_' . $this->form->controller->_name . '_container']['values'][$form->getName()] = $formValues; + $this->subsequentForms[$form->getName()] = $form; + return $this; + } + +} diff --git a/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php b/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php index 4054a1f6d9..916a726458 100644 --- a/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php +++ b/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php @@ -1,5 +1,7 @@ useTransaction(); + public function tearDown(): void { + $this->revertTemplateToReservedTemplate(); + $this->quickCleanUpFinancialEntities(); + parent::tearDown(); } /** @@ -314,67 +318,40 @@ class CRM_Event_Form_Registration_ConfirmTest extends CiviUnitTestCase { * @throws \CRM_Core_Exception */ public function testTaxMultipleParticipant(): void { - // @todo - figure out why this doesn't pass validate financials + $this->swapMessageTemplateForTestTemplate('event_online_receipt', 'text'); $this->isValidateFinancialsOnPostAssert = FALSE; $mut = new CiviMailUtils($this); - $event = $this->eventCreatePaid(); - $this->swapMessageTemplateForTestTemplate('event_online_receipt', 'text'); - CRM_Event_Form_Registration_Confirm::testSubmit([ - 'id' => $event['id'], - 'contributeMode' => 'direct', - 'registerByID' => $this->createLoggedInUser(), - 'totalAmount' => 440, - 'event' => $event, - 'params' => [ - [ - 'first_name' => 'Participant1', - 'last_name' => 'LastName', - 'email-Primary' => 'participant1@example.com', - 'additional_participants' => 2, - 'payment_processor_id' => 0, - 'bypass_payment' => '', - 'is_primary' => 1, - 'is_pay_later' => 1, - 'campaign_id' => NULL, - 'defaultRole' => 1, - 'participant_role_id' => '1', - 'currencyID' => 'USD', - 'amount_level' => 'Tiny-tots (ages 5-8) - 1', - 'amount' => '100.00', - 'tax_amount' => 10, - 'ip_address' => '127.0.0.1', - 'invoiceID' => '57adc34957a29171948e8643ce906332', - 'trxn_id' => '123456789', - 'button' => '_qf_Register_upload', - ], - [ - 'entryURL' => "http://dmaster.local/civicrm/event/register?reset=1&id={$event['id']}", - 'first_name' => 'Participant2', - 'last_name' => 'LastName', - 'email-Primary' => 'participant2@example.com', - 'campaign_id' => NULL, - 'is_pay_later' => 1, - 'participant_role_id' => '1', - 'currencyID' => 'USD', - 'amount_level' => 'Tiny-tots (ages 9-18) - 1', - 'amount' => '200.00', - 'tax_amount' => 20, - ], - [ - 'entryURL' => "http://dmaster.local/civicrm/event/register?reset=1&id={$event['id']}", - 'first_name' => 'Participant3', - 'last_name' => 'LastName', - 'email-Primary' => 'participant3@example.com', - 'campaign_id' => NULL, - 'is_pay_later' => 1, - 'participant_role_id' => '1', - 'currencyID' => 'USD', - 'amount_level' => 'Tiny-tots (ages 5-8) - 1', - 'amount' => '100.00', - 'tax_amount' => 10, - ], - ], - ]); + $this->createLoggedInUser(); + $this->eventCreatePaid(); + $this->addTaxAccountToFinancialType(CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Event Fee')); + $this->getTestForm('CRM_Event_Form_Registration_Register', [ + 'first_name' => 'Participant1', + 'last_name' => 'LastName', + 'email-Primary' => 'participant1@example.com', + 'additional_participants' => 2, + 'payment_processor_id' => 0, + 'priceSetId' => $this->getPriceSetID('PaidEvent'), + 'price_' . $this->ids['PriceField']['PaidEvent'] => $this->ids['PriceFieldValue']['PaidEvent_standard'], + 'defaultRole' => 1, + 'participant_role_id' => '1', + 'button' => '_qf_Register_upload', + ], ['id' => $this->getEventID()]) + ->addSubsequentForm('CRM_Event_Form_Registration_AdditionalParticipant', [ + 'first_name' => 'Participant2', + 'last_name' => 'LastName', + 'email-Primary' => 'participant2@example.com', + 'priceSetId' => $this->getPriceSetID('PaidEvent'), + 'price_' . $this->ids['PriceField']['PaidEvent'] => $this->ids['PriceFieldValue']['PaidEvent_standard'], + ])->addSubsequentForm('CRM_Event_Form_Registration_AdditionalParticipant', [ + 'first_name' => 'Participant3', + 'last_name' => 'LastName', + 'email-Primary' => 'participant3@example.com', + 'priceSetId' => $this->getPriceSetID('PaidEvent'), + 'price_' . $this->ids['PriceField']['PaidEvent'] => $this->ids['PriceFieldValue']['PaidEvent_standard'], + ]) + ->addSubsequentForm('CRM_Event_Form_Registration_Confirm') + ->processForm(); + $participants = $this->callAPISuccess('Participant', 'get', [])['values']; $this->assertCount(3, $participants); $contribution = $this->callAPISuccessGetSingle( @@ -384,14 +361,16 @@ class CRM_Event_Form_Registration_ConfirmTest extends CiviUnitTestCase { ] ); $this->assertContains(' (multiple participants)', $contribution['amount_level']); - $this->assertEquals(40, $contribution['tax_amount'], 'Invalid Tax amount.'); - $this->assertEquals(440, $contribution['total_amount'], 'Invalid Tax amount.'); + $this->assertEquals(90, $contribution['tax_amount'], 'Invalid Tax amount.'); + $this->assertEquals(990, $contribution['total_amount'], 'Invalid Tax amount.'); $mailSent = $mut->getAllMessages(); $this->assertCount(3, $mailSent, 'Three mails should have been sent to the 3 participants.'); $this->assertStringContainsString('contactID:::' . $contribution['contact_id'], $mailSent[0]); $this->assertStringContainsString('contactID:::' . ($contribution['contact_id'] + 1), $mailSent[1]); - $this->callAPISuccess('Payment', 'create', ['total_amount' => 100, 'payment_type_id' => 'Cash', 'contribution_id' => $contribution['id']]); + $this->validateAllContributions(); + $this->validateAllPayments(); + $this->callAPISuccess('Payment', 'create', ['total_amount' => 990, 'payment_type_id' => 'Cash', 'contribution_id' => $contribution['id']]); $mailSent = $mut->getAllMessages(); $this->assertCount(6, $mailSent); @@ -401,7 +380,6 @@ class CRM_Event_Form_Registration_ConfirmTest extends CiviUnitTestCase { $this->assertStringContainsString('contactID:::' . ($contribution['contact_id'] + 1), $mailSent[3]); $this->assertStringContainsString('contactID:::' . ($contribution['contact_id'] + 2), $mailSent[4]); $this->assertStringContainsString('contactID:::' . $contribution['contact_id'], $mailSent[5]); - $this->revertTemplateToReservedTemplate(); } /** diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index f03297cb62..72ac8e794e 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -2767,6 +2767,8 @@ class CiviUnitTestCase extends PHPUnit\Framework\TestCase { * @noinspection PhpDocMissingThrowsInspection */ protected function addTaxAccountToFinancialType(int $financialTypeID, array $accountParams = []): CRM_Financial_DAO_EntityFinancialAccount { + Civi::settings()->set('invoicing', TRUE); + unset(\Civi::$statics['CRM_Price_BAO_PriceField']); $params = array_merge([ 'name' => 'Sales tax account - test - ' . $financialTypeID, 'financial_account_type_id' => key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Liability' ")), -- 2.25.1