Merge pull request #16469 from civicrm/5.22
[civicrm-core.git] / tests / phpunit / api / v3 / EmailTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
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 |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 * Class api_v3_EmailTest
14 *
15 * @group headless
16 */
17 class api_v3_EmailTest extends CiviUnitTestCase {
18 protected $_contactID;
19 protected $_locationType;
20 protected $locationType2;
21 protected $_entity;
22 protected $_params;
23
24 public function setUp() {
25 $this->_entity = 'Email';
26 parent::setUp();
27 $this->useTransaction(TRUE);
28
29 $this->_contactID = $this->organizationCreate(NULL);
30 $this->_locationType = $this->locationTypeCreate(NULL);
31 $this->locationType2 = $this->locationTypeCreate([
32 'name' => 'New Location Type 2',
33 'vcard_name' => 'New Location Type 2',
34 'description' => 'Another Location Type',
35 'is_active' => 1,
36 ]);
37 $this->_params = [
38 'contact_id' => $this->_contactID,
39 'location_type_id' => $this->_locationType->id,
40 'email' => 'api@a-team.com',
41 'is_primary' => 1,
42
43 //TODO email_type_id
44 ];
45 }
46
47 /**
48 * Test create email.
49 *
50 * @param int $version
51 *
52 * @dataProvider versionThreeAndFour
53 * @throws \CRM_Core_Exception
54 */
55 public function testCreateEmail($version) {
56 $this->_apiversion = $version;
57 $params = $this->_params;
58 //check there are no emails to start with
59 $get = $this->callAPISuccess('email', 'get', [
60 'location_type_id' => $this->_locationType->id,
61 ]);
62 $this->assertEquals(0, $get['count'], 'Contact not successfully deleted.');
63
64 $result = $this->callAPIAndDocument('email', 'create', $params, __FUNCTION__, __FILE__);
65 $this->assertEquals(1, $result['count']);
66 $this->assertNotNull($result['id']);
67 $this->assertNotNull($result['values'][$result['id']]['id']);
68 $this->callAPISuccess('email', 'delete', ['id' => $result['id']]);
69 }
70
71 /**
72 * If no location is specified when creating a new email, it should default to
73 * the LocationType default
74 *
75 * @param int $version
76 *
77 * @dataProvider versionThreeAndFour
78 * @throws \CRM_Core_Exception
79 */
80 public function testCreateEmailDefaultLocation($version) {
81 $this->_apiversion = $version;
82 $params = $this->_params;
83 unset($params['location_type_id']);
84 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__);
85 $this->assertEquals(CRM_Core_BAO_LocationType::getDefault()->id, $result['values'][$result['id']]['location_type_id']);
86 $this->callAPISuccess($this->_entity, 'delete', ['id' => $result['id']]);
87 }
88
89 /**
90 * If a new email is set to is_primary the prev should no longer be.
91 *
92 * If is_primary is not set then it should become is_primary is no others exist
93 *
94 * @param int $version
95 *
96 * @dataProvider versionThreeAndFour
97 * @throws \CRM_Core_Exception
98 */
99 public function testCreateEmailPrimaryHandlingChangeToPrimary($version) {
100 $this->_apiversion = $version;
101 $params = $this->_params;
102 unset($params['is_primary']);
103 $email1 = $this->callAPISuccess('email', 'create', $params);
104 //now we check & make sure it has been set to primary
105 $expected = 1;
106 $this->callAPISuccess('email', 'getcount', [
107 'is_primary' => 1,
108 'id' => $email1['id'],
109 ],
110 $expected
111 );
112 }
113
114 /**
115 * @param int $version
116 *
117 * @dataProvider versionThreeAndFour
118 * @throws \CRM_Core_Exception
119 */
120 public function testCreateEmailPrimaryHandlingChangeExisting($version) {
121 $this->_apiversion = $version;
122 $this->callAPISuccess('email', 'create', $this->_params);
123 $this->callAPISuccess('email', 'create', $this->_params);
124 $check = $this->callAPISuccess('email', 'getcount', [
125 'is_primary' => 1,
126 'contact_id' => $this->_contactID,
127 ]);
128 $this->assertEquals(1, $check);
129 }
130
131 /**
132 * @param int $version
133 * @dataProvider versionThreeAndFour
134 */
135 public function testCreateEmailWithoutEmail($version) {
136 $this->_apiversion = $version;
137 $result = $this->callAPIFailure('Email', 'Create', ['contact_id' => 4]);
138 $this->assertContains('missing', $result['error_message']);
139 $this->assertContains('email', $result['error_message']);
140 }
141
142 /**
143 * @param int $version
144 *
145 * @dataProvider versionThreeAndFour
146 * @throws \CRM_Core_Exception
147 */
148 public function testGetEmail($version) {
149 $this->_apiversion = $version;
150 $result = $this->callAPISuccess('email', 'create', $this->_params);
151 $get = $this->callAPISuccess('email', 'create', $this->_params);
152 $this->assertEquals($get['count'], 1);
153 $get = $this->callAPISuccess('email', 'create', $this->_params + ['debug' => 1]);
154 $this->assertEquals($get['count'], 1);
155 $get = $this->callAPISuccess('email', 'create', $this->_params + ['debug' => 1, 'action' => 'get']);
156 $this->assertEquals($get['count'], 1);
157 $this->callAPISuccess('email', 'delete', ['id' => $result['id']]);
158 }
159
160 /**
161 * @param int $version
162 *
163 * @dataProvider versionThreeAndFour
164 * @throws \CRM_Core_Exception
165 */
166 public function testDeleteEmail($version) {
167 $this->_apiversion = $version;
168 $params = [
169 'contact_id' => $this->_contactID,
170 'location_type_id' => $this->_locationType->id,
171 'email' => 'api@a-team.com',
172 'is_primary' => 1,
173
174 //TODO email_type_id
175 ];
176 //check there are no emails to start with
177 $get = $this->callAPISuccess('email', 'get', [
178 'location_type_id' => $this->_locationType->id,
179 ]);
180 $this->assertEquals(0, $get['count'], 'email already exists');
181
182 //create one
183 $create = $this->callAPISuccess('email', 'create', $params);
184
185 $result = $this->callAPIAndDocument('email', 'delete', ['id' => $create['id']], __FUNCTION__, __FILE__);
186 $this->assertEquals(1, $result['count']);
187 $get = $this->callAPISuccess('email', 'get', [
188 'location_type_id' => $this->_locationType->id,
189 ]);
190 $this->assertEquals(0, $get['count'], 'Contact not successfully deleted');
191 }
192
193 /**
194 * @param int $version
195 *
196 * @dataProvider versionThreeAndFour
197 * @throws \CRM_Core_Exception
198 */
199 public function testReplaceEmail($version) {
200 $this->_apiversion = $version;
201 // check there are no emails to start with
202 $get = $this->callAPISuccess('email', 'get', [
203 'contact_id' => $this->_contactID,
204 ]);
205 $this->assertEquals(0, $get['count'], 'email already exists');
206
207 // initialize email list with three emails at loc #1 and two emails at loc #2
208 $replace1Params = [
209 'contact_id' => $this->_contactID,
210 'values' => [
211 [
212 'location_type_id' => $this->_locationType->id,
213 'email' => '1-1@example.com',
214 'is_primary' => 1,
215 ],
216 [
217 'location_type_id' => $this->_locationType->id,
218 'email' => '1-2@example.com',
219 'is_primary' => 0,
220 ],
221 [
222 'location_type_id' => $this->_locationType->id,
223 'email' => '1-3@example.com',
224 'is_primary' => 0,
225 ],
226 [
227 'location_type_id' => $this->locationType2->id,
228 'email' => '2-1@example.com',
229 'is_primary' => 0,
230 ],
231 [
232 'location_type_id' => $this->locationType2->id,
233 'email' => '2-2@example.com',
234 'is_primary' => 0,
235 ],
236 ],
237 ];
238 $replace1 = $this->callAPIAndDocument('email', 'replace', $replace1Params, __FUNCTION__, __FILE__);
239 $this->assertEquals(5, $replace1['count']);
240
241 // check emails at location #1 or #2
242 $get = $this->callAPISuccess('email', 'get', [
243 'contact_id' => $this->_contactID,
244 ]);
245 $this->assertEquals(5, $get['count'], 'Incorrect email count');
246
247 // replace the subset of emails in location #1, but preserve location #2
248 $replace2Params = [
249 'contact_id' => $this->_contactID,
250 'location_type_id' => $this->_locationType->id,
251 'values' => [
252 [
253 'email' => '1-4@example.com',
254 'is_primary' => 1,
255 ],
256 ],
257 ];
258 $replace2 = $this->callAPISuccess('email', 'replace', $replace2Params);
259 $this->assertEquals(1, $replace2['count']);
260
261 // check emails at location #1 -- all three replaced by one
262 $get = $this->callAPISuccess('email', 'get', [
263 'contact_id' => $this->_contactID,
264 'location_type_id' => $this->_locationType->id,
265 ]);
266 $this->assertEquals(1, $get['count'], 'Incorrect email count');
267
268 // check emails at location #2 -- preserve the original two
269 $get = $this->callAPISuccess('email', 'get', [
270 'contact_id' => $this->_contactID,
271 'location_type_id' => $this->locationType2->id,
272 ]);
273
274 $this->assertEquals(2, $get['count'], 'Incorrect email count');
275
276 // replace the set of emails with an empty set
277 $replace3Params = [
278 'contact_id' => $this->_contactID,
279 'values' => [],
280 ];
281 $replace3 = $this->callAPISuccess('email', 'replace', $replace3Params);
282 $this->assertEquals(0, $replace3['count']);
283
284 // check emails
285 $get = $this->callAPISuccess('email', 'get', [
286
287 'contact_id' => $this->_contactID,
288 ]);
289 $this->assertAPISuccess($get);
290 $this->assertEquals(0, $get['count'], 'Incorrect email count');
291 }
292
293 /**
294 * @param int $version
295 *
296 * @dataProvider versionThreeAndFour
297 * @throws \CRM_Core_Exception
298 */
299 public function testReplaceEmailsInChain($version) {
300 $this->_apiversion = $version;
301 // check there are no emails to start with
302 $get = $this->callAPISuccess('email', 'get', [
303
304 'contact_id' => $this->_contactID,
305 ]);
306 $this->assertAPISuccess($get);
307 $this->assertEquals(0, $get['count'], 'email already exists');
308 $description = 'Demonstrates use of Replace in a nested API call.';
309 $subfile = 'NestedReplaceEmail';
310 // initialize email list with three emails at loc #1 and two emails at loc #2
311 $getReplace1Params = [
312
313 'id' => $this->_contactID,
314 'api.email.replace' => [
315 'values' => [
316 [
317 'location_type_id' => $this->_locationType->id,
318 'email' => '1-1@example.com',
319 'is_primary' => 1,
320 ],
321 [
322 'location_type_id' => $this->_locationType->id,
323 'email' => '1-2@example.com',
324 'is_primary' => 0,
325 ],
326 [
327 'location_type_id' => $this->_locationType->id,
328 'email' => '1-3@example.com',
329 'is_primary' => 0,
330 ],
331 [
332 'location_type_id' => $this->locationType2->id,
333 'email' => '2-1@example.com',
334 'is_primary' => 0,
335 ],
336 [
337 'location_type_id' => $this->locationType2->id,
338 'email' => '2-2@example.com',
339 'is_primary' => 0,
340 ],
341 ],
342 ],
343 ];
344 $getReplace1 = $this->callAPIAndDocument('contact', 'get', $getReplace1Params, __FUNCTION__, __FILE__, $description, $subfile);
345 $this->assertEquals(5, $getReplace1['values'][$this->_contactID]['api.email.replace']['count']);
346
347 // check emails at location #1 or #2
348 $get = $this->callAPISuccess('email', 'get', [
349 'contact_id' => $this->_contactID,
350 ]);
351 $this->assertEquals(5, $get['count'], 'Incorrect email count');
352
353 // replace the subset of emails in location #1, but preserve location #2
354 $getReplace2Params = [
355 'id' => $this->_contactID,
356 'api.email.replace' => [
357 'location_type_id' => $this->_locationType->id,
358 'values' => [
359 [
360 'email' => '1-4@example.com',
361 'is_primary' => 1,
362 ],
363 ],
364 ],
365 ];
366 $getReplace2 = $this->callAPISuccess('contact', 'get', $getReplace2Params);
367 $this->assertEquals(0, $getReplace2['values'][$this->_contactID]['api.email.replace']['is_error']);
368 $this->assertEquals(1, $getReplace2['values'][$this->_contactID]['api.email.replace']['count']);
369
370 // check emails at location #1 -- all three replaced by one
371 $get = $this->callAPISuccess('email', 'get', [
372 'contact_id' => $this->_contactID,
373 'location_type_id' => $this->_locationType->id,
374 ]);
375
376 $this->assertEquals(1, $get['count'], 'Incorrect email count');
377
378 // check emails at location #2 -- preserve the original two
379 $get = $this->callAPISuccess('email', 'get', [
380 'contact_id' => $this->_contactID,
381 'location_type_id' => $this->locationType2->id,
382 ]);
383 $this->assertEquals(2, $get['count'], 'Incorrect email count');
384 }
385
386 /**
387 * @param int $version
388 *
389 * @dataProvider versionThreeAndFour
390 * @throws \CRM_Core_Exception
391 */
392 public function testReplaceEmailWithId($version) {
393 $this->_apiversion = $version;
394 // check there are no emails to start with
395 $get = $this->callAPISuccess('email', 'get', [
396 'contact_id' => $this->_contactID,
397 ]);
398 $this->assertEquals(0, $get['count'], 'email already exists ' . __LINE__);
399
400 // initialize email address
401 $replace1Params = [
402 'contact_id' => $this->_contactID,
403 'values' => [
404 [
405 'location_type_id' => $this->_locationType->id,
406 'email' => '1-1@example.com',
407 'is_primary' => 1,
408 'on_hold' => 1,
409 ],
410 ],
411 ];
412 $replace1 = $this->callAPISuccess('email', 'replace', $replace1Params);
413 $this->assertEquals(1, $replace1['count']);
414
415 $keys = array_keys($replace1['values']);
416 $emailID = array_shift($keys);
417
418 // update the email address, but preserve any other fields
419 $replace2Params = [
420 'contact_id' => $this->_contactID,
421 'values' => [
422 [
423 'id' => $emailID,
424 'email' => '1-2@example.com',
425 ],
426 ],
427 ];
428 $replace2 = $this->callAPISuccess('email', 'replace', $replace2Params);
429 $this->assertEquals(1, $replace2['count']);
430
431 // ensure the 'email' was updated while other fields were preserved
432 $get = $this->callAPISuccess('email', 'get', [
433 'contact_id' => $this->_contactID,
434 'location_type_id' => $this->_locationType->id,
435 ]);
436
437 $this->assertEquals(1, $get['count'], 'Incorrect email count at ' . __LINE__);
438 $this->assertEquals(1, $get['values'][$emailID]['is_primary']);
439 $this->assertEquals(1, $get['values'][$emailID]['on_hold']);
440 $this->assertEquals('1-2@example.com', $get['values'][$emailID]['email']);
441 }
442
443 /**
444 * Test updates affecting on hold emails.
445 *
446 * @throws \CRM_Core_Exception
447 */
448 public function testEmailOnHold() {
449 $params = [
450 'contact_id' => $this->_contactID,
451 'email' => 'api@a-team.com',
452 'on_hold' => '2',
453 ];
454 $result = $this->callAPIAndDocument('email', 'create', $params, __FUNCTION__, __FILE__);
455 $this->assertEquals(1, $result['count']);
456 $this->assertNotNull($result['id']);
457 $this->assertNotNull($result['values'][$result['id']]['id']);
458 $this->assertEquals(2, $result['values'][$result['id']]['on_hold']);
459 $this->assertEquals(date('Y-m-d H:i'), date('Y-m-d H:i', strtotime($result['values'][$result['id']]['hold_date'])));
460
461 // set on_hold is '0'
462 // if isMultipleBulkMail is active, the value in On-hold select is string
463 $params_change = [
464 'id' => $result['id'],
465 'contact_id' => $this->_contactID,
466 'email' => 'api@a-team.com',
467 'is_primary' => 1,
468 'on_hold' => '0',
469 ];
470 $result_change = $this->callAPISuccess('email', 'create', $params_change + ['action' => 'get']);
471 $this->assertEquals(1, $result_change['count']);
472 $this->assertEquals($result['id'], $result_change['id']);
473 $this->assertEmpty($result_change['values'][$result_change['id']]['on_hold']);
474 $this->assertEquals(date('Y-m-d H:i'), date('Y-m-d H:i', strtotime($result_change['values'][$result_change['id']]['reset_date'])));
475 $this->assertEmpty($result_change['values'][$result_change['id']]['hold_date']);
476
477 $this->callAPISuccess('email', 'delete', ['id' => $result['id']]);
478 }
479
480 /**
481 * Test setting a bulk email unsets others on the contact.
482 *
483 * @throws \CRM_Core_Exception
484 */
485 public function testSetBulkEmail() {
486 $individualID = $this->individualCreate([]);
487 $email = $this->callAPISuccessGetSingle('Email', ['contact_id' => $individualID]);
488 $this->assertEquals(0, $email['is_bulkmail']);
489 $this->callAPISuccess('Email', 'create', ['id' => $email['id'], 'is_bulkmail' => 1]);
490 $email = $this->callAPISuccessGetSingle('Email', ['contact_id' => $individualID]);
491 $this->assertEquals(1, $email['is_bulkmail']);
492 $email2 = $this->callAPISuccess('Email', 'create', ['contact_id' => $individualID, 'email' => 'mail@Example.com', 'is_bulkmail' => 1]);
493 $emails = $this->callAPISuccess('Email', 'get', ['contact_id' => $individualID])['values'];
494 $this->assertEquals(0, $emails[$email['id']]['is_bulkmail']);
495 $this->assertEquals(1, $emails[$email2['id']]['is_bulkmail']);
496 }
497
498 }