_individualId = $this->individualCreate(array('first_name' => 'Anthony', 'last_name' => 'Collins')); $this->_docTypes = CRM_Core_SelectValues::documentApplicationType(); } /** * Clean up after each test. */ public function tearDown() { $this->quickCleanUpFinancialEntities(); $this->quickCleanup(array('civicrm_uf_match')); CRM_Utils_Hook::singleton()->reset(); } /** * Test the buildContributionArray function. */ public function testBuildContributionArray() { $this->_individualId = $this->individualCreate(); $customGroup = $this->callAPISuccess('CustomGroup', 'create', array( 'title' => 'Test Custom Set for Contribution', 'extends' => 'Contribution', 'is_active' => TRUE, )); $params = array( 'custom_group_id' => $customGroup['id'], 'label' => 'Text field', 'html_type' => 'Text', 'data_type' => 'String', 'weight' => 1, 'is_active' => 1, ); $customField = $this->callAPISuccess('CustomField', 'create', $params); $customFieldKey = 'custom_' . $customField['id']; $campaignTitle = 'Test Campaign ' . substr(sha1(rand()), 0, 7); $params = array( 'contact_id' => $this->_individualId, 'total_amount' => 6, 'campaign_id' => $this->campaignCreate(array('title' => $campaignTitle), FALSE), 'financial_type_id' => 'Donation', $customFieldKey => 'Text_' . substr(sha1(rand()), 0, 7), ); $contributionIDs = $returnProperties = array(); $result = $this->callAPISuccess('Contribution', 'create', $params); $contributionIDs[] = $result['id']; $this->hookClass->setHook('civicrm_tokenValues', array($this, 'hookTokenValues')); // assume that there are two token {contribution.financial_type} and // {contribution.custom_N} in message content $messageToken = array( 'contribution' => array( 'financial_type', 'payment_instrument', 'campaign', $customFieldKey, ), ); list($contributions, $contacts) = CRM_Contribute_Form_Task_PDFLetterCommon::buildContributionArray('contact_id', $contributionIDs, $returnProperties, TRUE, TRUE, $messageToken, 'test', '**', FALSE); $this->assertEquals('Anthony', $contacts[$this->_individualId]['first_name']); $this->assertEquals('emo', $contacts[$this->_individualId]['favourite_emoticon']); $this->assertEquals('Donation', $contributions[$result['id']]['financial_type']); $this->assertEquals($campaignTitle, $contributions[$result['id']]['campaign']); $this->assertEquals('Check', $contributions[$result['id']]['payment_instrument']); // CRM-20359: assert that contribution custom field token is rightfully replaced by its value $this->assertEquals($params[$customFieldKey], $contributions[$result['id']][$customFieldKey]); $this->customFieldDelete($customField['id']); $this->customGroupDelete($customGroup['id']); } /** * Implement token values hook. * * @param array $details * @param array $contactIDs * @param int $jobID * @param array $tokens * @param string $className */ public function hookTokenValues(&$details, $contactIDs, $jobID, $tokens, $className) { foreach ($details as $index => $detail) { $details[$index]['favourite_emoticon'] = 'emo'; } } /** * Test contribution token replacement in * html returned by postProcess function. */ public function testPostProcess() { $this->createLoggedInUser(); $this->_individualId = $this->individualCreate(); foreach (array('docx', 'odt') as $docType) { $formValues = array( 'is_unit_test' => TRUE, 'group_by' => NULL, 'document_file' => array( 'name' => __DIR__ . "/sample_documents/Template.$docType", 'type' => $this->_docTypes[$docType], ), ); $contributionParams = array( 'contact_id' => $this->_individualId, 'total_amount' => 100, 'financial_type_id' => 'Donation', ); $contribution = $this->callAPISuccess('Contribution', 'create', $contributionParams); $contributionId = $contribution['id']; $form = new CRM_Contribute_Form_Task_PDFLetter(); $form->setContributionIds(array($contributionId)); $format = Civi::settings()->get('dateformatFull'); $date = CRM_Utils_Date::getToday(); $displayDate = CRM_Utils_Date::customFormat($date, $format); $html = CRM_Contribute_Form_Task_PDFLetterCommon::postProcess($form, $formValues); $expectedValues = array( 'Hello Anthony Collins', '$ 100.00', $displayDate, 'Donation', ); foreach ($expectedValues as $val) { $this->assertTrue(strpos($html[$contributionId], $val) !== 0); } } } /** * Test assignment of variables when using the group by function. * * We are looking to see that the contribution aggregate and contributions arrays reflect the most * recent contact rather than a total aggregate, since we are using group by. */ public function testPostProcessGroupByContact() { $this->createLoggedInUser(); $this->hookClass->setHook('civicrm_tokenValues', array($this, 'hook_aggregateTokenValues')); $this->hookClass->setHook('civicrm_tokens', array($this, 'hook_tokens')); $this->mut = new CiviMailUtils($this, TRUE); $this->_individualId = $this->individualCreate(); $this->_individualId2 = $this->individualCreate(); $htmlMessage = "{aggregate.rendered_token}"; $formValues = array( 'is_unit_test' => TRUE, 'group_by' => 'contact_id', 'html_message' => $htmlMessage, 'email_options' => 'both', 'subject' => 'Testy test test', 'from' => 'info@example.com', ); $contributionIDs = array(); $contribution = $this->callAPISuccess('Contribution', 'create', array( 'contact_id' => $this->_individualId, 'total_amount' => 100, 'financial_type_id' => 'Donation', 'receive_date' => '2016-12-25', )); $contributionIDs[] = $contribution['id']; $contribution = $this->callAPISuccess('Contribution', 'create', array( 'contact_id' => $this->_individualId2, 'total_amount' => 10, 'financial_type_id' => 'Donation', 'receive_date' => '2016-12-25', )); $contributionIDs[] = $contribution['id']; $contribution = $this->callAPISuccess('Contribution', 'create', array( 'contact_id' => $this->_individualId2, 'total_amount' => 1, 'financial_type_id' => 'Donation', 'receive_date' => '2016-12-25', )); $contributionIDs[] = $contribution['id']; $form = new CRM_Contribute_Form_Task_PDFLetter(); $form->setContributionIds($contributionIDs); $html = CRM_Contribute_Form_Task_PDFLetterCommon::postProcess($form, $formValues); $this->assertEquals("
Date Amount Financial Type Source
25 December 2016 $ 100.00 Donation
Total $ 100.00
", $html[1]); $this->assertEquals("
Date Amount Financial Type Source
25 December 2016 $ 10.00 Donation
25 December 2016 $ 1.00 Donation
Total $ 11.00
", $html[2]); $activities = $this->callAPISuccess('Activity', 'get', array('activity_type_id' => 'Print PDF Letter', 'sequential' => 1)); $this->assertEquals(2, $activities['count']); $this->assertEquals($html[1], $activities['values'][0]['details']); $this->assertEquals($html[2], $activities['values'][1]['details']); // Checking it is not called multiple times. // once for each contact create + once for the activities. $this->assertEquals(3, $this->hookTokensCalled); $this->mut->checkAllMailLog($html); } /** * Implements civicrm_tokens(). */ public function hook_tokens(&$tokens) { $this->hookTokensCalled++; $tokens['aggregate'] = array('rendered_token' => 'rendered_token'); } /** * Get the html message. * * @return string */ public function getHtmlMessage() { return '{assign var=\'contact_aggregate\' value=0}
Date Amount Financial Type Source
{$date} {$contribution.total_amount|crmMoney} {$contribution.financial_type}
Total {$contact_aggregate|crmMoney}
'; } /** * Implements CiviCRM hook. * * @param array $values * @param array $contactIDs * @param null $job * @param array $tokens * @param null $context */ public function hook_aggregateTokenValues(&$values, $contactIDs, $job = NULL, $tokens = array(), $context = NULL) { foreach ($contactIDs as $contactID) { CRM_Core_Smarty::singleton()->assign('messageContactID', $contactID); $values[$contactID]['aggregate.rendered_token'] = CRM_Core_Smarty::singleton() ->fetch('string:' . $this->getHtmlMessage()); } } /** * @param string $token * @param string $entity * @param string $textToSearch * @param bool $expected * * @dataProvider isHtmlTokenInTableCellProvider */ public function testIsHtmlTokenInTableCell($token, $entity, $textToSearch, $expected) { $this->assertEquals($expected, CRM_Contribute_Form_Task_PDFLetterCommon::isHtmlTokenInTableCell($token, $entity, $textToSearch) ); } public function isHtmlTokenInTableCellProvider() { return [ 'simplest TRUE' => [ 'token', 'entity', '{entity.token}', TRUE, ], 'simplest FALSE' => [ 'token', 'entity', '{entity.token}', FALSE, ], 'token between two tables' => [ 'token', 'entity', '
Top
{entity.token}
Bottom
', FALSE, ], 'token in two tables' => [ 'token', 'entity', '
{entity.token}
foo
{entity.token}
foo
', TRUE, ], 'token outside of table and inside of table' => [ 'token', 'entity', ' {entity.token}
{entity.token}
foo
', FALSE, ], 'token inside more complicated table' => [ 'token', 'entity', '
{entity.token}
', TRUE, ], 'token inside something that looks like table cell' => [ 'token', 'entity', ' {entity.token}
Bottom
', FALSE, ], ]; } }