Commit | Line | Data |
---|---|---|
14d24938 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
7d61e75f | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
14d24938 | 5 | | | |
7d61e75f TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
14d24938 TO |
9 | +--------------------------------------------------------------------+ |
10 | */ | |
11 | ||
0eea664b | 12 | /** |
a6c57fee TO |
13 | * Class CRM_Contribute_ActionMapping_ByTypeTest |
14 | * @group ActionSchedule | |
15 | * | |
16 | * This class tests various configurations of scheduled-reminders, with a focus on | |
17 | * reminders for *contribution types*. It follows a design/pattern described in | |
18 | * AbstractMappingTest. | |
19 | * | |
20 | * @see \Civi\ActionSchedule\AbstractMappingTest | |
acb109b7 | 21 | * @group headless |
0eea664b | 22 | */ |
14d24938 TO |
23 | class CRM_Contribute_ActionMapping_ByTypeTest extends \Civi\ActionSchedule\AbstractMappingTest { |
24 | ||
25 | /** | |
26 | * Generate a list of test cases, where each is a distinct combination of | |
27 | * data, schedule-rules, and schedule results. | |
28 | * | |
29 | * @return array | |
30 | * - targetDate: string; eg "2015-02-01 00:00:01" | |
31 | * - setupFuncs: string, space-separated list of setup functions | |
32 | * - messages: array; each item is a message that's expected to be sent | |
33 | * each message may include keys: | |
34 | * - time: approximate time (give or take a few seconds) | |
35 | * - recipients: array of emails | |
36 | * - subject: regex | |
37 | */ | |
38 | public function createTestCases() { | |
9099cab3 | 39 | $cs = []; |
14d24938 | 40 | |
cdc402cd TO |
41 | // FIXME: CRM-19415: The right email content goes out, but it appears that the dates are incorrect. |
42 | // $cs[] = array( | |
43 | // '2015-02-01 00:00:00', | |
44 | // 'addAliceDues scheduleForAny startOnTime useHelloFirstName alsoRecipientBob', | |
45 | // array( | |
46 | // array( | |
47 | // 'time' => '2015-02-01 00:00:00', | |
48 | // 'to' => array('alice@example.org'), | |
49 | // 'subject' => '/Hello, Alice.*via subject/', | |
50 | // ), | |
51 | // array( | |
52 | // 'time' => '2015-02-01 00:00:00', | |
53 | // 'to' => array('bob@example.org'), | |
54 | // 'subject' => '/Hello, Bob.*via subject/', | |
55 | // // It might make more sense to get Alice's details... but path of least resistance... | |
56 | // ), | |
57 | // ), | |
58 | // ); | |
a6c57fee | 59 | |
9099cab3 | 60 | $cs[] = [ |
a6c57fee TO |
61 | '2015-02-01 00:00:00', |
62 | 'addAliceDues scheduleForAny startOnTime useHelloFirstName limitToRecipientBob', | |
9099cab3 CW |
63 | [], |
64 | ]; | |
a6c57fee | 65 | |
9099cab3 | 66 | $cs[] = [ |
a6c57fee TO |
67 | '2015-02-01 00:00:00', |
68 | 'addAliceDues scheduleForAny startOnTime useHelloFirstName limitToRecipientAlice', | |
9099cab3 CW |
69 | [ |
70 | [ | |
a6c57fee | 71 | 'time' => '2015-02-01 00:00:00', |
9099cab3 | 72 | 'to' => ['alice@example.org'], |
a6c57fee | 73 | 'subject' => '/Hello, Alice.*via subject/', |
9099cab3 CW |
74 | ], |
75 | ], | |
76 | ]; | |
a6c57fee | 77 | |
9099cab3 | 78 | $cs[] = [ |
a6c57fee TO |
79 | '2015-02-01 00:00:00', |
80 | // 'addAliceDues addBobDonation scheduleForDues startOnTime useHelloFirstName', | |
1774b40a | 81 | 'addAliceDues addBobDonation scheduleForDues startOnTime useHelloFirstNameStatus', |
9099cab3 CW |
82 | [ |
83 | [ | |
14d24938 | 84 | 'time' => '2015-02-01 00:00:00', |
9099cab3 | 85 | 'to' => ['alice@example.org'], |
1774b40a | 86 | 'subject' => '/Hello, Alice. @Completed.*via subject/', |
9099cab3 CW |
87 | ], |
88 | ], | |
89 | ]; | |
14d24938 | 90 | |
9099cab3 | 91 | $cs[] = [ |
14d24938 TO |
92 | '2015-02-01 00:00:00', |
93 | 'addAliceDues addBobDonation scheduleForAny startOnTime useHelloFirstName', | |
9099cab3 CW |
94 | [ |
95 | [ | |
14d24938 | 96 | 'time' => '2015-02-01 00:00:00', |
9099cab3 | 97 | 'to' => ['alice@example.org'], |
14d24938 | 98 | 'subject' => '/Hello, Alice.*via subject/', |
9099cab3 CW |
99 | ], |
100 | [ | |
14d24938 | 101 | 'time' => '2015-02-01 00:00:00', |
9099cab3 | 102 | 'to' => ['bob@example.org'], |
14d24938 | 103 | 'subject' => '/Hello, Bob.*via subject/', |
9099cab3 CW |
104 | ], |
105 | ], | |
106 | ]; | |
14d24938 | 107 | |
9099cab3 | 108 | $cs[] = [ |
14d24938 TO |
109 | '2015-02-02 00:00:00', |
110 | 'addAliceDues addBobDonation scheduleForDonation startWeekBefore repeatTwoWeeksAfter useHelloFirstName', | |
9099cab3 CW |
111 | [ |
112 | [ | |
14d24938 | 113 | 'time' => '2015-01-26 00:00:00', |
9099cab3 | 114 | 'to' => ['bob@example.org'], |
14d24938 | 115 | 'subject' => '/Hello, Bob.*via subject/', |
9099cab3 CW |
116 | ], |
117 | [ | |
14d24938 | 118 | 'time' => '2015-02-02 00:00:00', |
9099cab3 | 119 | 'to' => ['bob@example.org'], |
14d24938 | 120 | 'subject' => '/Hello, Bob.*via subject/', |
9099cab3 CW |
121 | ], |
122 | [ | |
14d24938 | 123 | 'time' => '2015-02-09 00:00:00', |
9099cab3 | 124 | 'to' => ['bob@example.org'], |
14d24938 | 125 | 'subject' => '/Hello, Bob.*via subject/', |
9099cab3 CW |
126 | ], |
127 | [ | |
14d24938 | 128 | 'time' => '2015-02-16 00:00:00', |
9099cab3 | 129 | 'to' => ['bob@example.org'], |
14d24938 | 130 | 'subject' => '/Hello, Bob.*via subject/', |
9099cab3 CW |
131 | ], |
132 | ], | |
133 | ]; | |
14d24938 | 134 | |
9099cab3 | 135 | $cs[] = [ |
14d24938 TO |
136 | '2015-02-03 00:00:00', |
137 | 'addAliceDues addBobDonation scheduleForSoftCreditor startWeekAfter useHelloFirstName', | |
9099cab3 CW |
138 | [ |
139 | [ | |
14d24938 | 140 | 'time' => '2015-02-10 00:00:00', |
9099cab3 | 141 | 'to' => ['carol@example.org'], |
14d24938 | 142 | 'subject' => '/Hello, Carol.*via subject/', |
9099cab3 CW |
143 | ], |
144 | ], | |
145 | ]; | |
14d24938 TO |
146 | |
147 | return $cs; | |
148 | } | |
149 | ||
9c2c0cdd TO |
150 | /** |
151 | * Create a contribution record for Alice with type "Member Dues". | |
152 | */ | |
14d24938 | 153 | public function addAliceDues() { |
9b3cb77d | 154 | $this->ids['Contribution']['alice'] = $this->callAPISuccess('Contribution', 'create', [ |
14d24938 TO |
155 | 'contact_id' => $this->contacts['alice']['id'], |
156 | 'receive_date' => date('Ymd', strtotime($this->targetDate)), | |
157 | 'total_amount' => '100', | |
158 | 'financial_type_id' => 1, | |
159 | 'non_deductible_amount' => '10', | |
160 | 'fee_amount' => '5', | |
161 | 'net_amount' => '95', | |
162 | 'source' => 'SSF', | |
163 | 'contribution_status_id' => 1, | |
9099cab3 CW |
164 | 'soft_credit' => [ |
165 | '1' => [ | |
14d24938 TO |
166 | 'contact_id' => $this->contacts['carol']['id'], |
167 | 'amount' => 50, | |
168 | 'soft_credit_type_id' => 3, | |
9099cab3 CW |
169 | ], |
170 | ], | |
9b3cb77d | 171 | ])['id']; |
14d24938 TO |
172 | } |
173 | ||
9c2c0cdd TO |
174 | /** |
175 | * Create a contribution record for Bob with type "Donation". | |
176 | */ | |
14d24938 | 177 | public function addBobDonation() { |
9099cab3 | 178 | $this->callAPISuccess('Contribution', 'create', [ |
14d24938 TO |
179 | 'contact_id' => $this->contacts['bob']['id'], |
180 | 'receive_date' => date('Ymd', strtotime($this->targetDate)), | |
181 | 'total_amount' => '150', | |
182 | 'financial_type_id' => 2, | |
183 | 'non_deductible_amount' => '10', | |
184 | 'fee_amount' => '5', | |
185 | 'net_amount' => '145', | |
186 | 'source' => 'SSF', | |
187 | 'contribution_status_id' => 2, | |
9099cab3 | 188 | ]); |
14d24938 TO |
189 | } |
190 | ||
9c2c0cdd TO |
191 | /** |
192 | * Schedule message delivery for contributions of type "Member Dues". | |
193 | */ | |
14d24938 TO |
194 | public function scheduleForDues() { |
195 | $this->schedule->mapping_id = CRM_Contribute_ActionMapping_ByType::MAPPING_ID; | |
196 | $this->schedule->start_action_date = 'receive_date'; | |
9099cab3 CW |
197 | $this->schedule->entity_value = CRM_Utils_Array::implodePadded([1]); |
198 | $this->schedule->entity_status = CRM_Utils_Array::implodePadded([1]); | |
14d24938 TO |
199 | } |
200 | ||
9c2c0cdd TO |
201 | /** |
202 | * Schedule message delivery for contributions of type "Donation". | |
203 | */ | |
14d24938 TO |
204 | public function scheduleForDonation() { |
205 | $this->schedule->mapping_id = CRM_Contribute_ActionMapping_ByType::MAPPING_ID; | |
206 | $this->schedule->start_action_date = 'receive_date'; | |
9099cab3 | 207 | $this->schedule->entity_value = CRM_Utils_Array::implodePadded([2]); |
14d24938 TO |
208 | $this->schedule->entity_status = CRM_Utils_Array::implodePadded(NULL); |
209 | } | |
210 | ||
9c2c0cdd TO |
211 | /** |
212 | * Schedule message delivery for any contribution, regardless of type. | |
213 | */ | |
14d24938 TO |
214 | public function scheduleForAny() { |
215 | $this->schedule->mapping_id = CRM_Contribute_ActionMapping_ByType::MAPPING_ID; | |
216 | $this->schedule->start_action_date = 'receive_date'; | |
217 | $this->schedule->entity_value = CRM_Utils_Array::implodePadded(NULL); | |
218 | $this->schedule->entity_status = CRM_Utils_Array::implodePadded(NULL); | |
219 | } | |
220 | ||
9c2c0cdd TO |
221 | /** |
222 | * Schedule message delivery to the 'soft credit' assignee. | |
223 | */ | |
14d24938 TO |
224 | public function scheduleForSoftCreditor() { |
225 | $this->schedule->mapping_id = CRM_Contribute_ActionMapping_ByType::MAPPING_ID; | |
226 | $this->schedule->start_action_date = 'receive_date'; | |
227 | $this->schedule->entity_value = CRM_Utils_Array::implodePadded(NULL); | |
228 | $this->schedule->entity_status = CRM_Utils_Array::implodePadded(NULL); | |
229 | $this->schedule->limit_to = 1; | |
230 | $this->schedule->recipient = 'soft_credit_type'; | |
9099cab3 | 231 | $this->schedule->recipient_listing = CRM_Utils_Array::implodePadded([3]); |
14d24938 TO |
232 | } |
233 | ||
1774b40a TO |
234 | public function useHelloFirstNameStatus() { |
235 | $this->schedule->subject = 'Hello, {contact.first_name}. @{contribution.status}. (via subject)'; | |
236 | $this->schedule->body_html = '<p>Hello, {contact.first_name}. @{contribution.status}. (via body_html)</p>'; | |
cb31dd27 EM |
237 | $this->schedule->body_text = 'Hello, {contact.first_name}. @{contribution.status} (via body_text)'; |
238 | } | |
239 | ||
9b3cb77d EM |
240 | /** |
241 | * Test that reconciled tokens are rendered the same via multiple code paths. | |
242 | * | |
243 | * We expect that the list of tokens from the processor class === the selectValues function. | |
244 | * - once this is verified to be true selectValues can call the processor function internally. | |
245 | * | |
246 | * We also expect that rendering action action schedules will do the same as the | |
247 | * legacy processor function. Once this is true we can expose the listener on the | |
248 | * token processor for contribution and call it internally from the legacy code. | |
249 | * | |
250 | * @throws \CiviCRM_API3_Exception | |
251 | */ | |
252 | public function testTokenRendering(): void { | |
cb31dd27 EM |
253 | $this->targetDate = '20150201000107'; |
254 | \CRM_Utils_Time::setTime('2015-02-01 00:00:00'); | |
255 | $this->addAliceDues(); | |
256 | $this->scheduleForAny(); | |
257 | $this->startOnTime(); | |
258 | $this->schedule->save(); | |
259 | $this->schedule->body_text = ' | |
260 | first name = {contact.first_name} | |
261 | receive_date = {contribution.receive_date} | |
262 | contribution status id = {contribution.contribution_status_id} | |
9b3cb77d EM |
263 | legacy style status = {contribution.status} |
264 | new style status = {contribution.contribution_status_id:name}'; | |
cb31dd27 EM |
265 | $this->schedule->save(); |
266 | $this->callAPISuccess('job', 'send_reminder', []); | |
9b3cb77d | 267 | $expected = [ |
cb31dd27 EM |
268 | 'first name = Alice', |
269 | 'receive_date = February 1st, 2015 12:00 AM', | |
270 | 'contribution status id = 1', | |
9b3cb77d | 271 | 'new style status = Completed', |
cb31dd27 | 272 | 'legacy style status = Completed', |
9b3cb77d EM |
273 | ]; |
274 | $this->mut->checkMailLog($expected); | |
275 | ||
276 | $messageToken = CRM_Utils_Token::getTokens($this->schedule->body_text); | |
277 | ||
278 | $contributionDetails = CRM_Contribute_BAO_Contribution::replaceContributionTokens( | |
279 | [$this->ids['Contribution']['alice']], | |
280 | $this->schedule->body_text, | |
281 | $messageToken, | |
282 | $this->schedule->body_text, | |
283 | $this->schedule->body_text, | |
284 | $messageToken, | |
285 | TRUE | |
286 | ); | |
287 | $expected = [ | |
288 | 'receive_date = February 1st, 2015 12:00 AM', | |
289 | 'new style status = Completed', | |
290 | 'contribution status id = 1', | |
291 | ]; | |
292 | foreach ($expected as $string) { | |
293 | $this->assertStringContainsString($string, $contributionDetails[$this->contacts['alice']['id']]['html']); | |
294 | } | |
295 | $tokens = ['contribution_status_id', 'contribution_status_id:name', 'contribution_status_id:label']; | |
296 | $processor = new CRM_Contribute_Tokens(); | |
297 | foreach ($tokens as $token) { | |
298 | $this->assertEquals(CRM_Core_SelectValues::contributionTokens()['{contribution.' . $token . '}'], $processor->tokenNames[$token]); | |
299 | } | |
1774b40a TO |
300 | } |
301 | ||
14d24938 | 302 | } |