From e4d31fb38fcce5a2b33fa8568b188d2f814e5989 Mon Sep 17 00:00:00 2001 From: Eileen McNaughton Date: Sun, 10 Sep 2023 11:39:16 +1200 Subject: [PATCH] Add email helper to new form test helper --- Civi/Test/FormWrapper.php | 62 ++++++++++++++-- .../CRM/Event/Form/ParticipantTest.php | 71 ++++++++----------- .../Event/Form/Registration/ConfirmTest.php | 24 +++---- 3 files changed, 95 insertions(+), 62 deletions(-) diff --git a/Civi/Test/FormWrapper.php b/Civi/Test/FormWrapper.php index f9af7110a1..737ebb9389 100644 --- a/Civi/Test/FormWrapper.php +++ b/Civi/Test/FormWrapper.php @@ -36,10 +36,32 @@ class FormWrapper { private $mail; + /** + * @return null|array + */ + public function getMail(): ?array { + return $this->mail; + } + + /** + * @return array + */ + public function getFirstMail(): array { + return $this->mail ? (array) reset($this->mail) : []; + } + + public function getFirstMailBody() : string { + return $this->getFirstMail()['body'] ?? ''; + } + private $redirects; + private $mailSpoolID; + private $validation; + private $originalMailSetting; + public const CONSTRUCTED = 0; public const PREPROCESSED = 1; public const BUILT = 3; @@ -79,12 +101,7 @@ class FormWrapper { $this->validation = $this->form->validate(); } if ($state > self::VALIDATED) { - $this->form->postProcess(); - foreach ($this->subsequentForms as $form) { - $form->preProcess(); - $form->buildForm(); - $form->postProcess(); - } + $this->postProcess(); } return $this; } @@ -138,7 +155,14 @@ class FormWrapper { * @return $this */ public function postProcess(): self { + $this->startTrackingMail(); $this->form->postProcess(); + foreach ($this->subsequentForms as $form) { + $form->preProcess(); + $form->buildForm(); + $form->postProcess(); + } + $this->stopTrackingMail(); return $this; } @@ -289,4 +313,30 @@ class FormWrapper { } } + /** + * Start tracking any emails sent by this form. + * + * @noinspection PhpUnhandledExceptionInspection + */ + private function startTrackingMail(): void { + $this->originalMailSetting = \Civi::settings()->get('mailing_backend'); + \Civi::settings() + ->set('mailing_backend', array_merge((array) $this->originalMailSetting, ['outBound_option' => \CRM_Mailing_Config::OUTBOUND_OPTION_REDIRECT_TO_DB])); + $this->mailSpoolID = (int) \CRM_Core_DAO::singleValueQuery('SELECT MAX(id) FROM civicrm_mailing_spool'); + } + + /** + * Store any mails sent & revert to pre-test behaviour. + * + * @noinspection PhpUnhandledExceptionInspection + */ + private function stopTrackingMail(): void { + $dao = \CRM_Core_DAO::executeQuery('SELECT headers, body FROM civicrm_mailing_spool WHERE id > ' . $this->mailSpoolID . ' ORDER BY id'); + \CRM_Core_DAO::executeQuery('DELETE FROM civicrm_mailing_spool WHERE id > ' . $this->mailSpoolID); + while ($dao->fetch()) { + $this->mail[] = ['headers' => $dao->headers, 'body' => $dao->body]; + } + \Civi::settings()->set('mailing_backend', $this->originalMailSetting); + } + } diff --git a/tests/phpunit/CRM/Event/Form/ParticipantTest.php b/tests/phpunit/CRM/Event/Form/ParticipantTest.php index c807431602..6c2fe8f3b6 100644 --- a/tests/phpunit/CRM/Event/Form/ParticipantTest.php +++ b/tests/phpunit/CRM/Event/Form/ParticipantTest.php @@ -37,29 +37,12 @@ class CRM_Event_Form_ParticipantTest extends CiviUnitTestCase { $form = $this->getForm([], [ 'register_date' => date('Ymd'), 'status_id' => 1, - 'role_id' => 1, + 'role_id' => [CRM_Core_PseudoConstant::getKey('CRM_Event_BAO_Participant', 'role_id', 'Attendee')], ])->postProcess(); $this->assertEquals($this->getEventID(), $form->getEventID()); $this->callAPISuccessGetSingle('Participant', ['id' => $form->getParticipantID()]); } - /** - * Test an unpaid event, test role displays in receipt - */ - public function testSubmitUnPaidEvent(): void { - $this->getForm(['is_monetary' => FALSE], [ - 'status_id' => 1, - 'send_receipt' => 1, - 'from_email_address' => 'admin@example.com', - 'register_date' => date('Y-m-d H:i:s'), - 'role_id' => [ - CRM_Core_PseudoConstant::getKey('CRM_Event_BAO_Participant', 'role_id', 'Volunteer'), - CRM_Core_PseudoConstant::getKey('CRM_Event_BAO_Participant', 'role_id', 'Speaker'), - ], - ])->postProcess(); - $this->callAPISuccessGetCount('Participant', [], 1); - } - /** * Test financial items pending transaction is later altered. * @@ -268,7 +251,6 @@ class CRM_Event_Form_ParticipantTest extends CiviUnitTestCase { $this->setCurrencySeparators($thousandSeparator); $this->swapMessageTemplateForTestTemplate('event_offline_receipt', 'text'); $this->swapMessageTemplateForTestTemplate('event_offline_receipt'); - $mut = new CiviMailUtils($this, TRUE); // Create an email associated with the logged in contact $loggedInContactID = $this->createLoggedInUser(); $email = $this->callAPISuccess('Email', 'create', [ @@ -299,11 +281,11 @@ class CRM_Event_Form_ParticipantTest extends CiviUnitTestCase { $_REQUEST['mode'] = 'Live'; $submitParams = $this->getSubmitParamsForCreditCardPayment($paymentProcessorID); $submitParams['from_email_address'] = $email['id']; - $this->submitForm(['is_monetary' => 1, 'financial_type_id' => 1, 'pay_later_receipt' => 'pay us'], $submitParams, TRUE); + $message = $this->submitForm(['is_monetary' => 1, 'financial_type_id' => 1, 'pay_later_receipt' => 'pay us'], $submitParams, TRUE)->getFirstMail(); $participantID = Participant::get()->addWhere('event_id', '=', $this->getEventID('PaidEvent'))->execute()->first()['id']; //Check if type is correctly populated in mails. //Also check the string email is present not numeric from. - $mut->checkMailLog([ + $this->assertStringContainsStrings($message['headers'] . $message['body'], [ 'contactID:::' . $this->getContactID(), 'contact.id:::' . $this->getContactID(), 'eventID:::' . $this->getEventID('PaidEvent'), @@ -340,6 +322,12 @@ London,', $this->callAPISuccess('Email', 'delete', ['id' => $email['id']]); } + public function assertStringContainsStrings($string, $expectedStrings) { + foreach ($expectedStrings as $expectedString) { + $this->assertStringContainsString($expectedString, $string); + } + } + /** * Get prepared form object. * @@ -349,7 +337,8 @@ London,', * * @return \Civi\Test\FormWrappers\EventFormParticipant * - * @throws \CRM_Core_Exception + * + * @noinspection PhpDocMissingThrowsInspection */ protected function getForm(array $eventParams = [], array $submittedValues = [], bool $isQuickConfig = FALSE): EventFormParticipant { $submittedValues['contact_id'] = $this->ids['Contact']['event'] = $this->individualCreate(); @@ -379,11 +368,12 @@ London,', * @param array $submittedValues * @param bool $isQuickConfig * - * @throws \CRM_Core_Exception + * @return \Civi\Test\FormWrappers\EventFormParticipant */ - protected function submitForm(array $eventParams = [], array $submittedValues = [], bool $isQuickConfig = FALSE): void { + protected function submitForm(array $eventParams = [], array $submittedValues = [], bool $isQuickConfig = FALSE): EventFormParticipant { $form = $this->getForm($eventParams, $submittedValues, $isQuickConfig); $form->postProcess(); + return $form; } /** @@ -509,8 +499,7 @@ London,', * @throws \CRM_Core_Exception */ public function testSubmitPartialPayment(bool $isQuickConfig): void { - $mailUtil = new CiviMailUtils($this, TRUE); - $this->submitForm(['is_monetary' => 1, 'start_date' => '2023-02-15 15:00', 'end_date' => '2023-02-15 18:00'], [ + $email = $this->submitForm(['is_monetary' => 1, 'start_date' => '2023-02-15 15:00', 'end_date' => '2023-02-15 18:00'], [ 'contribution_status_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'), 'total_amount' => '20', 'send_receipt' => '1', @@ -520,8 +509,8 @@ London,', 'status_id' => CRM_Core_PseudoConstant::getKey('CRM_Event_BAO_Participant', 'status_id', 'Partially paid'), 'source' => 'I wrote this', 'note' => 'I wrote a note', - ], $isQuickConfig); - $this->assertPartialPaymentResult($isQuickConfig, $mailUtil); + ], $isQuickConfig)->getFirstMail(); + $this->assertPartialPaymentResult($isQuickConfig, $email); } /** @@ -534,15 +523,14 @@ London,', * @throws \CRM_Core_Exception */ public function testSubmitPendingPartiallyPaidAddPayment(bool $isQuickConfig): void { - $mailUtil = new CiviMailUtils($this, TRUE); - $this->submitForm(['is_monetary' => 1, 'start_date' => '2023-02-15 15:00', 'end_date' => '2023-02-15 18:00'], [], $isQuickConfig); + $message = $this->submitForm(['is_monetary' => 1, 'start_date' => '2023-02-15 15:00', 'end_date' => '2023-02-15 18:00'], [], $isQuickConfig)->getFirstMail(); $this->callAPISuccess('Payment', 'create', [ 'contribution_id' => $this->callAPISuccessGetValue('Contribution', ['return' => 'id']), 'total_amount' => 20, 'check_number' => 879, 'payment_instrument_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Check'), ]); - $this->assertPartialPaymentResult($isQuickConfig, $mailUtil, FALSE); + $this->assertPartialPaymentResult($isQuickConfig, $message, FALSE); } /** @@ -557,24 +545,23 @@ London,', * @throws \CRM_Core_Exception */ public function testSubmitPendingAddPayment(bool $isQuickConfig): void { - $mailUtil = new CiviMailUtils($this, TRUE); - $this->submitForm(['is_monetary' => 1, 'start_date' => '2023-02-15 15:00', 'end_date' => '2023-02-15 18:00'], [], $isQuickConfig); + $message = $this->submitForm(['is_monetary' => 1, 'start_date' => '2023-02-15 15:00', 'end_date' => '2023-02-15 18:00'], [], $isQuickConfig)->getFirstMail(); $this->callAPISuccess('Payment', 'create', [ 'contribution_id' => $this->callAPISuccessGetValue('Contribution', ['return' => 'id']), 'total_amount' => 20, 'check_number' => 879, 'payment_instrument_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Check'), ]); - $this->assertPartialPaymentResult($isQuickConfig, $mailUtil, FALSE); + $this->assertPartialPaymentResult($isQuickConfig, $message, FALSE); } /** * @param bool $isQuickConfig - * @param \CiviMailUtils $mut + * @param array $message * @param bool $isAmountPaidOnForm * Was the amount paid entered on the form (if so this should be on the receipt) */ - protected function assertPartialPaymentResult(bool $isQuickConfig, CiviMailUtils $mut, bool $isAmountPaidOnForm = TRUE): void { + protected function assertPartialPaymentResult(bool $isQuickConfig, array $message, bool $isAmountPaidOnForm = TRUE): void { $paymentInstrumentID = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Check'); $contribution = $this->callAPISuccessGetSingle('Contribution', []); $expected = [ @@ -647,7 +634,7 @@ London,', 'financial_account_id' => 4, ], $financialItem); - $mut->checkMailLog([ + $this->assertStringContainsStrings($message['headers'] . $message['body'], [ 'From: "FIXME" ', 'To: "Mr. Anthony Anderson II" ', 'Subject: Event Confirmation - Annual CiviCRM meet - Mr. Anthony Anderson II', @@ -720,7 +707,7 @@ London,', 'hidden_custom' => '1', 'hidden_custom_group_count' => ['' => 1], 'register_date' => '2020-01-31 00:50:00', - 'role_id' => [0 => CRM_Core_PseudoConstant::getKey('CRM_Event_BAO_Participant', 'role_id', 'Attendee')], + 'role_id' => [CRM_Core_PseudoConstant::getKey('CRM_Event_BAO_Participant', 'role_id', 'Attendee')], 'status_id' => CRM_Core_PseudoConstant::getKey('CRM_Event_BAO_Participant', 'status_id', $participantStatus), 'source' => 'I wrote this', 'note' => 'I wrote a note', @@ -733,7 +720,6 @@ London,', * @throws \CRM_Core_Exception */ public function testTransferParticipantRegistration(): void { - $mut = new CiviMailUtils($this); $this->swapMessageTemplateForInput('event_online_receipt', '{domain.name} {contact.first_name}'); $this->createEventOrder(); @@ -744,14 +730,13 @@ London,', $contribution = $this->callAPISuccessGetSingle('Contribution', ['return' => 'id']); $toContactID = $this->individualCreate([], 'to'); $participantId = CRM_Core_DAO::getFieldValue('CRM_Event_BAO_ParticipantPayment', $contribution['id'], 'participant_id', 'contribution_id'); - $this->getTestForm('CRM_Event_Form_SelfSvcTransfer', [ + $mail = $this->getTestForm('CRM_Event_Form_SelfSvcTransfer', [ 'contact_id' => $toContactID, ], [ 'pid' => $participantId, 'is_backoffice' => 1, - ])->processForm(); - $mut->checkAllMailLog(['Default Domain Name Anthony']); - $mut->clearMessages(); + ])->processForm()->getFirstMailBody(); + $this->assertStringContainsString('Default Domain Name Anthony', $mail); $this->revertTemplateToReservedTemplate(); //Assert participant is transferred to $toContactId. diff --git a/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php b/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php index a6d6c79502..b529b561af 100644 --- a/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php +++ b/tests/phpunit/CRM/Event/Form/Registration/ConfirmTest.php @@ -292,12 +292,10 @@ class CRM_Event_Form_Registration_ConfirmTest extends CiviUnitTestCase { */ public function testTaxMultipleParticipant(): void { $this->swapMessageTemplateForTestTemplate('event_online_receipt', 'text'); - - $mut = new CiviMailUtils($this); $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', [ + $form = $this->getTestForm('CRM_Event_Form_Registration_Register', [ 'first_name' => 'Participant1', 'last_name' => 'LastName', 'email-Primary' => 'participant1@example.com', @@ -336,23 +334,23 @@ class CRM_Event_Form_Registration_ConfirmTest extends CiviUnitTestCase { $this->assertContains(' (multiple participants)', $contribution['amount_level']); $this->assertEquals(90, $contribution['tax_amount'], 'Invalid Tax amount.'); $this->assertEquals(990, $contribution['total_amount'], 'Invalid Tax amount.'); - $mailSent = $mut->getAllMessages(); + $mailSent = $form->getMail(); $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->assertStringContainsString('contactID:::' . $contribution['contact_id'], $mailSent[0]['body']); + $this->assertStringContainsString('contactID:::' . ($contribution['contact_id'] + 1), $mailSent[1]['body']); + $mut = new CiviMailUtils($this); $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); + $this->assertCount(3, $mailSent); - $this->assertStringContainsString('participant_status:::Registered', $mailSent[3]); - $this->assertStringContainsString('Dear Participant2', $mailSent[3]); + $this->assertStringContainsString('participant_status:::Registered', $mailSent[0]); + $this->assertStringContainsString('Dear Participant2', $mailSent[0]); - $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->assertStringContainsString('contactID:::' . ($contribution['contact_id'] + 1), $mailSent[0]); + $this->assertStringContainsString('contactID:::' . ($contribution['contact_id'] + 2), $mailSent[1]); + $this->assertStringContainsString('contactID:::' . $contribution['contact_id'], $mailSent[2]); } /** -- 2.25.1