Merge pull request #16469 from civicrm/5.22
[civicrm-core.git] / tests / phpunit / api / v3 / RelationshipTest.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 contains api test cases for "civicrm_relationship"
14 * @group headless
15 */
16 class api_v3_RelationshipTest extends CiviUnitTestCase {
17
18 use CRMTraits_Custom_CustomDataTrait;
19
20 protected $_cId_a;
21 /**
22 * Second individual.
23 *
24 * @var int
25 */
26 protected $_cId_a_2;
27 protected $_cId_b;
28 /**
29 * Second organization contact.
30 *
31 * @var int
32 */
33 protected $_cId_b2;
34 protected $_relTypeID;
35 protected $_ids = [];
36 protected $_customFieldId = NULL;
37 protected $_params;
38
39 protected $entity;
40
41 /**
42 * Set up function.
43 */
44 public function setUp() {
45 parent::setUp();
46 $this->_cId_a = $this->individualCreate();
47 $this->_cId_a_2 = $this->individualCreate([
48 'last_name' => 'c2',
49 'email' => 'c@w.com',
50 'contact_type' => 'Individual',
51 ]);
52 $this->_cId_b = $this->organizationCreate();
53 $this->_cId_b2 = $this->organizationCreate(['organization_name' => ' Org 2']);
54 $this->entity = 'Relationship';
55 //Create a relationship type.
56 $relTypeParams = [
57 'name_a_b' => 'Relation 1 for delete',
58 'name_b_a' => 'Relation 2 for delete',
59 'description' => 'Testing relationship type',
60 'contact_type_a' => 'Individual',
61 'contact_type_b' => 'Organization',
62 'is_reserved' => 1,
63 'is_active' => 1,
64 ];
65
66 $this->_relTypeID = $this->relationshipTypeCreate($relTypeParams);
67 $this->_params = [
68 'contact_id_a' => $this->_cId_a,
69 'contact_id_b' => $this->_cId_b,
70 'relationship_type_id' => $this->_relTypeID,
71 'start_date' => '2008-12-20',
72 'is_active' => 1,
73 ];
74
75 }
76
77 /**
78 * Tear down function.
79 *
80 * @throws \Exception
81 */
82 public function tearDown() {
83 $this->contactDelete($this->_cId_a);
84 $this->contactDelete($this->_cId_a_2);
85 $this->contactDelete($this->_cId_b);
86 $this->contactDelete($this->_cId_b2);
87 $this->quickCleanup(['civicrm_relationship'], TRUE);
88 $this->relationshipTypeDelete($this->_relTypeID);
89 parent::tearDown();
90 }
91
92 /**
93 * Check with empty array.
94 * @param int $version
95 * @dataProvider versionThreeAndFour
96 */
97 public function testRelationshipCreateEmpty($version) {
98 $this->_apiversion = $version;
99 $this->callAPIFailure('relationship', 'create', []);
100 }
101
102 /**
103 * Test Current Employer is correctly set.
104 *
105 * @throws \CRM_Core_Exception
106 */
107 public function testCurrentEmployerRelationship() {
108 $employerRelationshipID = $this->callAPISuccessGetValue('RelationshipType', [
109 'return' => 'id',
110 'name_b_a' => 'Employer Of',
111 ]);
112 $employerRelationship = $this->callAPISuccess('Relationship', 'create', [
113 'contact_id_a' => $this->_cId_a,
114 'contact_id_b' => $this->_cId_b,
115 'relationship_type_id' => $employerRelationshipID,
116 'is_current_employer' => 1,
117 ]);
118
119 //Check if current employer is correctly set.
120 $employer = $this->callAPISuccessGetValue('Contact', [
121 'return' => 'current_employer',
122 'id' => $this->_cId_a,
123 ]);
124 $organisation = $this->callAPISuccessGetValue('Contact', [
125 'return' => "sort_name",
126 'id' => $this->_cId_b,
127 ]);
128 $this->assertEquals($employer, $organisation);
129
130 //Update relationship type
131 $update = $this->callAPISuccess('Relationship', 'create', [
132 'id' => $employerRelationship['id'],
133 'relationship_type_id' => $this->_relTypeID,
134 ]);
135 $employeeContact = $this->callAPISuccessGetSingle('Contact', [
136 'return' => ['current_employer'],
137 'id' => $this->_cId_a,
138 ]);
139 //current employer should be removed.
140 $this->assertEmpty($employeeContact['current_employer']);
141 }
142
143 /**
144 * Check if required fields are not passed.
145 * @param int $version
146 * @dataProvider versionThreeAndFour
147 */
148 public function testRelationshipCreateWithoutRequired($version) {
149 $this->_apiversion = $version;
150 $params = [
151 'start_date' => ['d' => '10', 'M' => '1', 'Y' => '2008'],
152 'end_date' => ['d' => '10', 'M' => '1', 'Y' => '2009'],
153 'is_active' => 1,
154 ];
155
156 $this->callAPIFailure('relationship', 'create', $params);
157 }
158
159 /**
160 * Check with incorrect required fields.
161 * @param int $version
162 * @dataProvider versionThreeAndFour
163 */
164 public function testRelationshipCreateWithIncorrectData($version) {
165 $this->_apiversion = $version;
166
167 $params = [
168 'contact_id_a' => $this->_cId_a,
169 'contact_id_b' => $this->_cId_b,
170 'relationship_type_id' => 'Breaking Relationship',
171 ];
172
173 $this->callAPIFailure('relationship', 'create', $params);
174
175 //contact id is not an integer
176 $params = [
177 'contact_id_a' => 'invalid',
178 'contact_id_b' => $this->_cId_b,
179 'relationship_type_id' => $this->_relTypeID,
180 'start_date' => ['d' => '10', 'M' => '1', 'Y' => '2008'],
181 'is_active' => 1,
182 ];
183 $this->callAPIFailure('relationship', 'create', $params);
184
185 // Contact id does not exist.
186 $params['contact_id_a'] = 999;
187 $this->callAPIFailure('relationship', 'create', $params);
188
189 //invalid date
190 $params['contact_id_a'] = $this->_cId_a;
191 $params['start_date'] = ['d' => '1', 'M' => '1'];
192 $this->callAPIFailure('relationship', 'create', $params);
193 }
194
195 /**
196 * Check relationship creation with invalid Relationship.
197 * @param int $version
198 * @dataProvider versionThreeAndFour
199 */
200 public function testRelationshipCreateInvalidRelationship($version) {
201 $this->_apiversion = $version;
202 // Both have the contact type Individual.
203 $params = [
204 'contact_id_a' => $this->_cId_a,
205 'contact_id_b' => $this->_cId_a,
206 'relationship_type_id' => $this->_relTypeID,
207 'start_date' => '2008-01-10',
208 'is_active' => 1,
209 ];
210
211 $this->callAPIFailure('relationship', 'create', $params);
212
213 // both the contact of type Organization
214 $params = [
215 'contact_id_a' => $this->_cId_b,
216 'contact_id_b' => $this->_cId_b,
217 'relationship_type_id' => $this->_relTypeID,
218 'start_date' => '2008-01-10',
219 'is_active' => 1,
220 ];
221
222 $this->callAPIFailure('relationship', 'create', $params);
223 }
224
225 /**
226 * Check relationship already exists.
227 * @param int $version
228 * @dataProvider versionThreeAndFour
229 */
230 public function testRelationshipCreateAlreadyExists($version) {
231 $this->_apiversion = $version;
232 $params = [
233 'contact_id_a' => $this->_cId_a,
234 'contact_id_b' => $this->_cId_b,
235 'relationship_type_id' => $this->_relTypeID,
236 'start_date' => '2008-12-20',
237 'end_date' => NULL,
238 'is_active' => 1,
239 ];
240 $relationship = $this->callAPISuccess('relationship', 'create', $params);
241
242 $params = [
243 'contact_id_a' => $this->_cId_a,
244 'contact_id_b' => $this->_cId_b,
245 'relationship_type_id' => $this->_relTypeID,
246 'start_date' => '2008-12-20',
247 'is_active' => 1,
248 ];
249 $this->callAPIFailure('relationship', 'create', $params, 'Duplicate Relationship');
250
251 $params['id'] = $relationship['id'];
252 $this->callAPISuccess('relationship', 'delete', $params);
253 }
254
255 /**
256 * Check relationship already exists.
257 * @param int $version
258 * @dataProvider versionThreeAndFour
259 */
260 public function testRelationshipCreateUpdateAlreadyExists($version) {
261 $this->_apiversion = $version;
262 $params = [
263 'contact_id_a' => $this->_cId_a,
264 'contact_id_b' => $this->_cId_b,
265 'relationship_type_id' => $this->_relTypeID,
266 'start_date' => '2008-12-20',
267 'end_date' => NULL,
268 'is_active' => 1,
269
270 ];
271 $relationship = $this->callAPISuccess('relationship', 'create', $params);
272 $params = [
273 'id' => $relationship['id'],
274 'is_active' => 0,
275 'debug' => 1,
276 ];
277 $this->callAPISuccess('relationship', 'create', $params);
278 $this->callAPISuccess('relationship', 'get', $params);
279 $params['id'] = $relationship['id'];
280 $this->callAPISuccess('relationship', 'delete', $params);
281 }
282
283 /**
284 * Check update doesn't reset stuff badly - CRM-11789.
285 * @param int $version
286 * @dataProvider versionThreeAndFour
287 */
288 public function testRelationshipCreateUpdateDoesNotMangle($version) {
289 $this->_apiversion = $version;
290 $params = [
291 'contact_id_a' => $this->_cId_a,
292 'contact_id_b' => $this->_cId_b,
293 'relationship_type_id' => $this->_relTypeID,
294 'start_date' => '2008-12-20',
295 'is_active' => 1,
296 'is_permission_a_b' => 1,
297 'description' => 'my desc',
298 ];
299 $relationship = $this->callAPISuccess('relationship', 'create', $params);
300
301 $updateParams = [
302 'id' => $relationship['id'],
303 'relationship_type_id' => $this->_relTypeID,
304 ];
305 $this->callAPISuccess('relationship', 'create', $updateParams);
306
307 //make sure the orig params didn't get changed
308 $this->getAndCheck($params, $relationship['id'], 'relationship');
309
310 }
311
312 /**
313 * Check relationship creation.
314 * @param int $version
315 * @dataProvider versionThreeAndFour
316 */
317 public function testRelationshipCreate($version) {
318 $this->_apiversion = $version;
319 $params = [
320 'contact_id_a' => $this->_cId_a,
321 'contact_id_b' => $this->_cId_b,
322 'relationship_type_id' => $this->_relTypeID,
323 'start_date' => '2010-10-30',
324 'end_date' => '2010-12-30',
325 'is_active' => 1,
326 'note' => 'note',
327 ];
328
329 $result = $this->callAPIAndDocument('relationship', 'create', $params, __FUNCTION__, __FILE__);
330 $this->assertNotNull($result['id']);
331 $relationParams = [
332 'id' => $result['id'],
333 ];
334
335 // assertDBState compares expected values in $result to actual values in the DB
336 $this->assertDBState('CRM_Contact_DAO_Relationship', $result['id'], $relationParams);
337 $result = $this->callAPISuccess('relationship', 'get', ['id' => $result['id']]);
338 $values = $result['values'][$result['id']];
339 foreach ($params as $key => $value) {
340 if ($key == 'note') {
341 continue;
342 }
343 $this->assertEquals($value, $values[$key], $key . " doesn't match " . print_r($values, TRUE));
344 }
345 $params['id'] = $result['id'];
346 $this->callAPISuccess('relationship', 'delete', $params);
347 }
348
349 /**
350 * Ensure disabling works.
351 * @param int $version
352 * @dataProvider versionThreeAndFour
353 */
354 public function testRelationshipUpdate($version) {
355 $this->_apiversion = $version;
356 $result = $this->callAPISuccess('relationship', 'create', $this->_params);
357 $relID = $result['id'];
358 $result = $this->callAPISuccess('relationship', 'create', ['id' => $relID, 'description' => 'blah']);
359 $this->assertEquals($relID, $result['id']);
360
361 $this->assertEquals('blah', $result['values'][$result['id']]['description']);
362
363 $result = $this->callAPISuccess('relationship', 'create', ['id' => $relID, 'is_permission_b_a' => 1]);
364 $this->assertEquals(1, $result['values'][$result['id']]['is_permission_b_a']);
365 $result = $this->callAPISuccess('relationship', 'create', ['id' => $result['id'], 'is_active' => 0]);
366 $result = $this->callAPISuccess('relationship', 'get', ['id' => $result['id']]);
367 $this->assertEquals(0, $result['values'][$result['id']]['is_active']);
368 $this->assertEquals('blah', $result['values'][$result['id']]['description']);
369 $this->assertEquals(1, $result['values'][$result['id']]['is_permission_b_a']);
370 }
371
372 /**
373 * Check relationship creation.
374 * @param int $version
375 * @dataProvider versionThreeAndFour
376 */
377 public function testRelationshipCreateEmptyEndDate($version) {
378 $this->_apiversion = $version;
379 $params = [
380 'contact_id_a' => $this->_cId_a,
381 'contact_id_b' => $this->_cId_b,
382 'relationship_type_id' => $this->_relTypeID,
383 'start_date' => '2010-10-30',
384 'end_date' => '',
385 'is_active' => 1,
386 'note' => 'note',
387 ];
388
389 $result = $this->callAPISuccess('relationship', 'create', $params);
390 $this->assertNotNull($result['id']);
391 $relationParams = [
392 'id' => $result['id'],
393 ];
394
395 // assertDBState compares expected values in $result to actual values in the DB
396 $this->assertDBState('CRM_Contact_DAO_Relationship', $result['id'], $relationParams);
397 $result = $this->callAPISuccess('relationship', 'get', ['id' => $result['id']]);
398 $values = $result['values'][$result['id']];
399 foreach ($params as $key => $value) {
400 if ($key == 'note') {
401 continue;
402 }
403 if ($key == 'end_date') {
404 $this->assertTrue(empty($values[$key]));
405 continue;
406 }
407 $this->assertEquals($value, $values[$key], $key . " doesn't match " . print_r($values, TRUE) . 'in line' . __LINE__);
408 }
409 $params['id'] = $result['id'];
410 $this->callAPISuccess('relationship', 'delete', $params);
411 }
412
413 /**
414 * Check relationship creation with custom data.
415 * FIXME: Api4
416 */
417 public function testRelationshipCreateEditWithCustomData() {
418 $this->createCustomGroupWithFieldsOfAllTypes();
419 //few custom Values for comparing
420 $custom_params = [
421 $this->getCustomFieldName('text') => 'Hello! this is custom data for relationship',
422 $this->getCustomFieldName('select_string') => 'Y',
423 $this->getCustomFieldName('select_date') => '2009-07-11 00:00:00',
424 $this->getCustomFieldName('link') => 'http://example.com',
425 ];
426
427 $params = [
428 'contact_id_a' => $this->_cId_a,
429 'contact_id_b' => $this->_cId_b,
430 'relationship_type_id' => $this->_relTypeID,
431 'start_date' => '2008-12-20',
432 'is_active' => 1,
433 ];
434 $params = array_merge($params, $custom_params);
435 $result = $this->callAPISuccess('relationship', 'create', $params);
436
437 $relationParams = ['id' => $result['id']];
438 $this->assertDBState('CRM_Contact_DAO_Relationship', $result['id'], $relationParams);
439
440 //Test Edit of custom field from the form.
441 $getParams = ['id' => $result['id']];
442 $updateParams = array_merge($getParams, [
443 $this->getCustomFieldName('text') => 'Edited Text Value',
444 'relationship_type_id' => $this->_relTypeID . '_b_a',
445 'related_contact_id' => $this->_cId_a,
446 ]);
447 $reln = new CRM_Contact_Form_Relationship();
448 $reln->_action = CRM_Core_Action::UPDATE;
449 $reln->_relationshipId = $result['id'];
450 $reln->submit($updateParams);
451
452 $check = $this->callAPISuccess('relationship', 'get', $getParams);
453 $this->assertEquals("Edited Text Value", $check['values'][$check['id']][$this->getCustomFieldName('text')]);
454
455 $params['id'] = $result['id'];
456 $this->callAPISuccess('relationship', 'delete', $params);
457 $this->relationshipTypeDelete($this->_relTypeID);
458 }
459
460 /**
461 * Check with complete array + custom field
462 * Note that the test is written on purpose without any
463 * variables specific to participant so it can be replicated into other entities
464 * and / or moved to the automated test suite
465 * FIXME: Api4
466 */
467 public function testGetWithCustom() {
468 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
469
470 $params = $this->_params;
471 $params['custom_' . $ids['custom_field_id']] = "custom string";
472
473 $result = $this->callAPISuccess($this->entity, 'create', $params);
474 $this->assertEquals($result['id'], $result['values'][$result['id']]['id']);
475
476 $getParams = ['id' => $result['id']];
477 $check = $this->callAPIAndDocument($this->entity, 'get', $getParams, __FUNCTION__, __FILE__);
478 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
479
480 $this->customFieldDelete($ids['custom_field_id']);
481 $this->customGroupDelete($ids['custom_group_id']);
482 }
483
484 /**
485 * Check if required fields are not passed.
486 * @param int $version
487 * @dataProvider versionThreeAndFour
488 */
489 public function testRelationshipDeleteWithoutRequired($version) {
490 $this->_apiversion = $version;
491 $params = [
492 'start_date' => '2008-12-20',
493 'end_date' => '2009-12-20',
494 'is_active' => 1,
495 ];
496
497 $this->callAPIFailure('relationship', 'delete', $params);
498 }
499
500 /**
501 * Check with incorrect required fields.
502 */
503 public function testRelationshipDeleteWithIncorrectData() {
504 $params = [
505 'contact_id_a' => $this->_cId_a,
506 'contact_id_b' => $this->_cId_b,
507 'relationship_type_id' => 'Breaking Relationship',
508 ];
509
510 $this->callAPIFailure('relationship', 'delete', $params, 'Mandatory key(s) missing from params array: id');
511
512 $params['id'] = "Invalid";
513 $this->callAPIFailure('relationship', 'delete', $params, 'id is not a valid integer');
514 }
515
516 /**
517 * Check relationship creation.
518 * @param int $version
519 * @dataProvider versionThreeAndFour
520 */
521 public function testRelationshipDelete($version) {
522 $this->_apiversion = $version;
523 $params = [
524 'contact_id_a' => $this->_cId_a,
525 'contact_id_b' => $this->_cId_b,
526 'relationship_type_id' => $this->_relTypeID,
527 'start_date' => '2008-12-20',
528 'is_active' => 1,
529 ];
530
531 $result = $this->callAPISuccess('relationship', 'create', $params);
532 $params = ['id' => $result['id']];
533 $this->callAPIAndDocument('relationship', 'delete', $params, __FUNCTION__, __FILE__);
534 $this->relationshipTypeDelete($this->_relTypeID);
535 }
536
537 ///////////////// civicrm_relationship_update methods
538
539 /**
540 * Check with empty array.
541 * @param int $version
542 * @dataProvider versionThreeAndFour
543 */
544 public function testRelationshipUpdateEmpty($version) {
545 $this->_apiversion = $version;
546 $this->callAPIFailure('relationship', 'create', [],
547 'contact_id_a, contact_id_b, relationship_type_id');
548 }
549
550 /**
551 * Check if required fields are not passed.
552 */
553
554 /**
555 * Check relationship update.
556 * @param int $version
557 * @dataProvider versionThreeAndFour
558 */
559 public function testRelationshipCreateDuplicate($version) {
560 $this->_apiversion = $version;
561 $relParams = [
562 'contact_id_a' => $this->_cId_a,
563 'contact_id_b' => $this->_cId_b,
564 'relationship_type_id' => $this->_relTypeID,
565 'start_date' => '20081214',
566 'end_date' => '20091214',
567 'is_active' => 1,
568 ];
569
570 $result = $this->callAPISuccess('relationship', 'create', $relParams);
571
572 $this->assertNotNull($result['id']);
573
574 $params = [
575 'contact_id_a' => $this->_cId_a,
576 'contact_id_b' => $this->_cId_b,
577 'relationship_type_id' => $this->_relTypeID,
578 'start_date' => '20081214',
579 'end_date' => '20091214',
580 'is_active' => 0,
581 ];
582
583 $this->callAPIFailure('relationship', 'create', $params, 'Duplicate Relationship');
584
585 $this->callAPISuccess('relationship', 'delete', ['id' => $result['id']]);
586 $this->relationshipTypeDelete($this->_relTypeID);
587 }
588
589 /**
590 * CRM-13725 - Two relationships of same type with same start and end date
591 * should be OK if the custom field values differ.
592 * FIXME: Api4
593 */
594 public function testRelationshipCreateDuplicateWithCustomFields() {
595 $this->createCustomGroupWithFieldsOfAllTypes();
596
597 $custom_params_1 = [
598 $this->getCustomFieldName('text') => 'Hello! this is custom data for relationship',
599 $this->getCustomFieldName('select_string') => 'Y',
600 $this->getCustomFieldName('select_date') => '2009-07-11 00:00:00',
601 $this->getCustomFieldName('link') => 'http://example.com',
602 ];
603
604 $custom_params_2 = [
605 $this->getCustomFieldName('text') => 'Hello! this is other custom data',
606 $this->getCustomFieldName('select_string') => 'Y',
607 $this->getCustomFieldName('select_date') => '2009-07-11 00:00:00',
608 $this->getCustomFieldName('link') => 'http://example.org',
609 ];
610
611 $params = [
612 'contact_id_a' => $this->_cId_a,
613 'contact_id_b' => $this->_cId_b,
614 'relationship_type_id' => $this->_relTypeID,
615 'start_date' => '2008-12-20',
616 'is_active' => 1,
617 ];
618
619 $params_1 = array_merge($params, $custom_params_1);
620 $params_2 = array_merge($params, $custom_params_2);
621
622 $result_1 = $this->callAPISuccess('relationship', 'create', $params_1);
623 $result_2 = $this->callAPISuccess('relationship', 'create', $params_2);
624
625 $this->assertNotNull($result_2['id']);
626 $this->assertEquals(0, $result_2['is_error']);
627
628 $this->relationshipTypeDelete($this->_relTypeID);
629 }
630
631 /**
632 * CRM-13725 - Two relationships of same type with same start and end date
633 * should be OK if the custom field values differ. In this case, the
634 * existing relationship does not have custom values, but the new one
635 * does.
636 * FIXME: Api4
637 */
638 public function testRelationshipCreateDuplicateWithCustomFields2() {
639 $this->createCustomGroupWithFieldsOfAllTypes();
640
641 $custom_params_2 = [
642 $this->getCustomFieldName('text') => 'Hello! this is other custom data',
643 $this->getCustomFieldName('select_string') => 'Y',
644 $this->getCustomFieldName('select_date') => '2009-07-11 00:00:00',
645 $this->getCustomFieldName('link') => 'http://example.org',
646 ];
647
648 $params_1 = [
649 'contact_id_a' => $this->_cId_a,
650 'contact_id_b' => $this->_cId_b,
651 'relationship_type_id' => $this->_relTypeID,
652 'start_date' => '2008-12-20',
653 'is_active' => 1,
654 ];
655
656 $params_2 = array_merge($params_1, $custom_params_2);
657
658 $this->callAPISuccess('relationship', 'create', $params_1);
659 $result_2 = $this->callAPISuccess('relationship', 'create', $params_2);
660
661 $this->assertNotNull($result_2['id']);
662 $this->assertEquals(0, $result_2['is_error']);
663
664 $this->relationshipTypeDelete($this->_relTypeID);
665 }
666
667 /**
668 * CRM-13725 - Two relationships of same type with same start and end date
669 * should be OK if the custom field values differ. In this case, the
670 * existing relationship does have custom values, but the new one
671 * does not.
672 * FIXME: Api4
673 */
674 public function testRelationshipCreateDuplicateWithCustomFields3() {
675 $this->createCustomGroupWithFieldsOfAllTypes();
676
677 $custom_params_1 = [
678 $this->getCustomFieldName('text') => 'Hello! this is other custom data',
679 $this->getCustomFieldName('select_string') => 'Y',
680 $this->getCustomFieldName('select_date') => '2009-07-11 00:00:00',
681 $this->getCustomFieldName('link') => 'http://example.org',
682 ];
683
684 $params_2 = [
685 'contact_id_a' => $this->_cId_a,
686 'contact_id_b' => $this->_cId_b,
687 'relationship_type_id' => $this->_relTypeID,
688 'start_date' => '2008-12-20',
689 'is_active' => 1,
690 ];
691
692 $params_1 = array_merge($params_2, $custom_params_1);
693
694 $this->callAPISuccess('relationship', 'create', $params_1);
695 $result_2 = $this->callAPISuccess('relationship', 'create', $params_2);
696
697 $this->assertNotNull($result_2['id']);
698 $this->assertEquals(0, $result_2['is_error']);
699
700 $this->relationshipTypeDelete($this->_relTypeID);
701 }
702
703 /**
704 * Check with valid params array.
705 */
706 public function testRelationshipsGet() {
707 $relParams = [
708 'contact_id_a' => $this->_cId_a,
709 'contact_id_b' => $this->_cId_b,
710 'relationship_type_id' => $this->_relTypeID,
711 'start_date' => '2011-01-01',
712 'end_date' => '2013-01-01',
713 'is_active' => 1,
714 ];
715
716 $this->callAPISuccess('relationship', 'create', $relParams);
717
718 //get relationship
719 $params = [
720 'contact_id' => $this->_cId_b,
721 ];
722 $result = $this->callAPISuccess('relationship', 'get', $params);
723 $this->assertEquals($result['count'], 1);
724 $params = [
725 'contact_id_a' => $this->_cId_a,
726 ];
727 $result = $this->callAPISuccess('relationship', 'get', $params);
728 $this->assertEquals($result['count'], 1);
729 // contact_id_a is wrong so should be no matches
730 $params = [
731 'contact_id_a' => $this->_cId_b,
732 ];
733 $result = $this->callAPISuccess('relationship', 'get', $params);
734 $this->assertEquals($result['count'], 0);
735 }
736
737 /**
738 * Chain Relationship.get and to Contact.get.
739 * @param int $version
740 * @dataProvider versionThreeAndFour
741 */
742 public function testRelationshipGetWithChainedCall($version) {
743 $this->_apiversion = $version;
744 // Create a relationship.
745 $createResult = $this->callAPISuccess('relationship', 'create', $this->_params);
746 $id = $createResult['id'];
747
748 // Try to retrieve it using chaining.
749 $params = [
750 'relationship_type_id' => $this->_relTypeID,
751 'id' => $id,
752 'api.Contact.get' => [
753 'id' => '$value.contact_id_b',
754 ],
755 ];
756
757 $result = $this->callAPISuccess('relationship', 'get', $params);
758
759 $this->assertEquals(1, $result['count']);
760 $relationship = CRM_Utils_Array::first($result['values']);
761 $this->assertEquals(1, $relationship['api.Contact.get']['count']);
762 $contact = CRM_Utils_Array::first($relationship['api.Contact.get']['values']);
763 $this->assertEquals($this->_cId_b, $contact['id']);
764 }
765
766 /**
767 * Chain Contact.get to Relationship.get and again to Contact.get.
768 * @param int $version
769 * @dataProvider versionThreeAndFour
770 */
771 public function testRelationshipGetInChainedCall($version) {
772 $this->_apiversion = $version;
773 // Create a relationship.
774 $this->callAPISuccess('relationship', 'create', $this->_params);
775
776 // Try to retrieve it using chaining.
777 $params = [
778 'id' => $this->_cId_a,
779 'api.Relationship.get' => [
780 'relationship_type_id' => $this->_relTypeID,
781 'contact_id_a' => '$value.id',
782 'api.Contact.get' => [
783 'id' => '$value.contact_id_b',
784 ],
785 ],
786 ];
787
788 $result = $this->callAPISuccess('contact', 'get', $params);
789 $this->assertEquals(1, $result['count']);
790 $contact = CRM_Utils_Array::first($result['values']);
791 $this->assertEquals(1, $contact['api.Relationship.get']['count']);
792 $relationship = CRM_Utils_Array::first($contact['api.Relationship.get']['values']);
793 $this->assertEquals(1, $relationship['api.Contact.get']['count']);
794 $contact = CRM_Utils_Array::first($relationship['api.Contact.get']['values']);
795 $this->assertEquals($this->_cId_b, $contact['id']);
796 }
797
798 /**
799 * Check with valid params array.
800 * (The get function will behave differently without 'contact_id' passed
801 * @param int $version
802 * @dataProvider versionThreeAndFour
803 */
804 public function testRelationshipsGetGeneric($version) {
805 $this->_apiversion = $version;
806 $relParams = [
807 'contact_id_a' => $this->_cId_a,
808 'contact_id_b' => $this->_cId_b,
809 'relationship_type_id' => $this->_relTypeID,
810 'start_date' => '2011-01-01',
811 'end_date' => '2013-01-01',
812 'is_active' => 1,
813 ];
814
815 $this->callAPISuccess('relationship', 'create', $relParams);
816
817 //get relationship
818 $params = [
819 'contact_id_b' => $this->_cId_b,
820 ];
821 $this->callAPISuccess('relationship', 'get', $params);
822 }
823
824 /**
825 * Test retrieving only current relationships.
826 * @param int $version
827 * @dataProvider versionThreeAndFour
828 */
829 public function testGetIsCurrent($version) {
830 $this->_apiversion = $version;
831 $rel2Params = [
832 'contact_id_a' => $this->_cId_a,
833 'contact_id_b' => $this->_cId_b2,
834 'relationship_type_id' => $this->_relTypeID,
835 'start_date' => '2008-12-20',
836 'is_active' => 0,
837 ];
838 $rel0 = $this->callAPISuccess('relationship', 'create', $rel2Params);
839 $rel1 = $this->callAPISuccess('relationship', 'create', $this->_params);
840
841 $getParams = ['filters' => ['is_current' => 1]];
842 $description = "Demonstrates is_current filter.";
843 $subfile = 'filterIsCurrent';
844 $result = $this->callAPIAndDocument('relationship', 'get', $getParams, __FUNCTION__, __FILE__, $description, $subfile);
845 $this->assertEquals($result['count'], 1);
846 $this->AssertEquals($rel1['id'], $result['id']);
847
848 // now try not started
849 $rel2Params['is_active'] = 1;
850 $rel2Params['start_date'] = 'tomorrow';
851 $rel2 = $this->callAPISuccess('relationship', 'create', $rel2Params);
852
853 // now try finished
854 $rel2Params['start_date'] = 'last week';
855 $rel2Params['end_date'] = 'yesterday';
856 $rel3 = $this->callAPISuccess('relationship', 'create', $rel2Params);
857
858 $result = $this->callAPISuccess('relationship', 'get', $getParams);
859 $this->assertEquals($result['count'], 1);
860 $this->AssertEquals($rel1['id'], $result['id']);
861
862 foreach ([$rel0, $rel1, $rel2, $rel3] as $rel) {
863 $this->callAPISuccess('Relationship', 'delete', $rel);
864 }
865 }
866
867 /**
868 * Test using various operators.
869 * @param int $version
870 * @dataProvider versionThreeAndFour
871 */
872 public function testGetTypeOperators($version) {
873 $this->_apiversion = $version;
874 $relTypeParams = [
875 'name_a_b' => 'Relation 3 for delete',
876 'name_b_a' => 'Relation 6 for delete',
877 'description' => 'Testing relationship type 2',
878 'contact_type_a' => 'Individual',
879 'contact_type_b' => 'Organization',
880 'is_reserved' => 1,
881 'is_active' => 1,
882 ];
883 $relationType2 = $this->relationshipTypeCreate($relTypeParams);
884 $relTypeParams = [
885 'name_a_b' => 'Relation 8 for delete',
886 'name_b_a' => 'Relation 9 for delete',
887 'description' => 'Testing relationship type 7',
888 'contact_type_a' => 'Individual',
889 'contact_type_b' => 'Organization',
890 'is_reserved' => 1,
891 'is_active' => 1,
892 ];
893 $relationType3 = $this->relationshipTypeCreate($relTypeParams);
894
895 $relTypeParams = [
896 'name_a_b' => 'Relation 6 for delete',
897 'name_b_a' => 'Relation 88for delete',
898 'description' => 'Testing relationship type 00',
899 'contact_type_a' => 'Individual',
900 'contact_type_b' => 'Organization',
901 'is_reserved' => 1,
902 'is_active' => 1,
903 ];
904 $relationType4 = $this->relationshipTypeCreate($relTypeParams);
905
906 $rel1 = $this->callAPISuccess('relationship', 'create', $this->_params);
907 $rel2 = $this->callAPISuccess('relationship', 'create', array_merge($this->_params,
908 ['relationship_type_id' => $relationType2]));
909 $rel3 = $this->callAPISuccess('relationship', 'create', array_merge($this->_params,
910 ['relationship_type_id' => $relationType3]));
911 $rel4 = $this->callAPISuccess('relationship', 'create', array_merge($this->_params,
912 ['relationship_type_id' => $relationType4]));
913
914 $getParams = [
915 'relationship_type_id' => ['IN' => [$relationType2, $relationType3]],
916 ];
917
918 $description = "Demonstrates use of IN filter.";
919 $subfile = 'INRelationshipType';
920
921 $result = $this->callAPIAndDocument('relationship', 'get', $getParams, __FUNCTION__, __FILE__, $description, $subfile);
922 $this->assertEquals($result['count'], 2);
923 $this->AssertEquals([$rel2['id'], $rel3['id']], array_keys($result['values']));
924
925 $description = "Demonstrates use of NOT IN filter.";
926 $subfile = 'NotInRelationshipType';
927 $getParams = [
928 'relationship_type_id' => ['NOT IN' => [$relationType2, $relationType3]],
929 ];
930 $result = $this->callAPIAndDocument('relationship', 'get', $getParams, __FUNCTION__, __FILE__, $description, $subfile);
931 $this->assertEquals($result['count'], 2);
932 $this->AssertEquals([$rel1['id'], $rel4['id']], array_keys($result['values']));
933
934 $description = "Demonstrates use of BETWEEN filter.";
935 $subfile = 'BetweenRelationshipType';
936 $getParams = [
937 'relationship_type_id' => ['BETWEEN' => [$relationType2, $relationType4]],
938 ];
939 $result = $this->callAPIAndDocument('relationship', 'get', $getParams, __FUNCTION__, __FILE__, $description, $subfile);
940 $this->assertEquals($result['count'], 3);
941 $this->AssertEquals([$rel2['id'], $rel3['id'], $rel4['id']], array_keys($result['values']));
942
943 $description = "Demonstrates use of Not BETWEEN filter.";
944 $subfile = 'NotBetweenRelationshipType';
945 $getParams = [
946 'relationship_type_id' => ['NOT BETWEEN' => [$relationType2, $relationType4]],
947 ];
948 $result = $this->callAPIAndDocument('relationship', 'get', $getParams, __FUNCTION__, __FILE__, $description, $subfile);
949 $this->assertEquals($result['count'], 1);
950 $this->AssertEquals([$rel1['id']], array_keys($result['values']));
951
952 foreach ([$relationType2, $relationType3, $relationType4] as $id) {
953 $this->callAPISuccess('RelationshipType', 'delete', ['id' => $id]);
954 }
955 }
956
957 /**
958 * Check with invalid relationshipType Id.
959 */
960 public function testRelationshipTypeAddInvalidId() {
961 $relTypeParams = [
962 'id' => 'invalid',
963 'name_a_b' => 'Relation 1 for delete',
964 'name_b_a' => 'Relation 2 for delete',
965 'contact_type_a' => 'Individual',
966 'contact_type_b' => 'Organization',
967 ];
968 $this->callAPIFailure('relationship_type', 'create', $relTypeParams,
969 'id is not a valid integer');
970 }
971
972 /**
973 * Check with valid data with contact_b.
974 */
975 public function testGetRelationshipWithContactB() {
976 $relParams = [
977 'contact_id_a' => $this->_cId_a,
978 'contact_id_b' => $this->_cId_b,
979 'relationship_type_id' => $this->_relTypeID,
980 'start_date' => '2011-01-01',
981 'end_date' => '2013-01-01',
982 'is_active' => 1,
983 ];
984
985 $relationship = $this->callAPISuccess('relationship', 'create', $relParams);
986
987 $contacts = [
988 'contact_id' => $this->_cId_a,
989 ];
990
991 $result = $this->callAPISuccess('relationship', 'get', $contacts);
992 $this->assertGreaterThan(0, $result['count']);
993 $params = [
994 'id' => $relationship['id'],
995 ];
996 $this->callAPISuccess('relationship', 'delete', $params);
997 $this->relationshipTypeDelete($this->_relTypeID);
998 }
999
1000 /**
1001 * Check with valid data with relationshipTypes.
1002 */
1003 public function testGetRelationshipWithRelTypes() {
1004 $relParams = [
1005 'contact_id_a' => $this->_cId_a,
1006 'contact_id_b' => $this->_cId_b,
1007 'relationship_type_id' => $this->_relTypeID,
1008 'start_date' => '2011-01-01',
1009 'end_date' => '2013-01-01',
1010 'is_active' => 1,
1011 ];
1012
1013 $relationship = $this->callAPISuccess('relationship', 'create', $relParams);
1014
1015 $contact_a = [
1016 'contact_id' => $this->_cId_a,
1017 ];
1018 $this->callAPISuccess('relationship', 'get', $contact_a);
1019
1020 $params = [
1021 'id' => $relationship['id'],
1022 ];
1023 $this->callAPISuccess('relationship', 'delete', $params);
1024 $this->relationshipTypeDelete($this->_relTypeID);
1025 }
1026
1027 /**
1028 * Checks that passing in 'contact_id' + a relationship type
1029 * will filter by relationship type (relationships go in both directions)
1030 * as relationship api does a reciprocal check if contact_id provided
1031 *
1032 * We should get 1 result without or with correct relationship type id & 0 with
1033 * an incorrect one
1034 */
1035 public function testGetRelationshipByTypeReciprocal() {
1036 $created = $this->callAPISuccess($this->entity, 'create', $this->_params);
1037 $result = $this->callAPISuccess($this->entity, 'get', [
1038 'contact_id' => $this->_cId_a,
1039 'relationship_type_id' => $this->_relTypeID,
1040 ]);
1041 $this->assertEquals(1, $result['count']);
1042 $result = $this->callAPISuccess($this->entity, 'get', [
1043 'contact_id' => $this->_cId_a,
1044 'relationship_type_id' => $this->_relTypeID + 1,
1045 ]);
1046 $this->assertEquals(0, $result['count']);
1047 $this->callAPISuccess($this->entity, 'delete', ['id' => $created['id']]);
1048 }
1049
1050 /**
1051 * Checks that passing in 'contact_id_b' + a relationship type
1052 * will filter by relationship type for contact b
1053 *
1054 * We should get 1 result without or with correct relationship type id & 0 with
1055 * an incorrect one
1056 * @param int $version
1057 * @dataProvider versionThreeAndFour
1058 */
1059 public function testGetRelationshipByTypeDAO($version) {
1060 $this->_apiversion = $version;
1061 $this->_ids['relationship'] = $this->callAPISuccess($this->entity, 'create', ['format.only_id' => TRUE] +
1062 $this->_params);
1063 $this->callAPISuccess($this->entity, 'getcount', [
1064 'contact_id_a' => $this->_cId_a,
1065 ], 1);
1066 $result = $this->callAPISuccess($this->entity, 'get', [
1067 'contact_id_a' => $this->_cId_a,
1068 'relationship_type_id' => $this->_relTypeID,
1069 ]);
1070 $this->assertEquals(1, $result['count']);
1071 $result = $this->callAPISuccess($this->entity, 'get', [
1072 'contact_id_a' => $this->_cId_a,
1073 'relationship_type_id' => $this->_relTypeID + 1,
1074 ]);
1075 $this->assertEquals(0, $result['count']);
1076 }
1077
1078 /**
1079 * Checks that passing in 'contact_id_b' + a relationship type
1080 * will filter by relationship type for contact b
1081 *
1082 * We should get 1 result without or with correct relationship type id & 0 with
1083 * an incorrect one
1084 * @param int $version
1085 * @dataProvider versionThreeAndFour
1086 */
1087 public function testGetRelationshipByTypeArrayDAO($version) {
1088 $this->_apiversion = $version;
1089 $this->callAPISuccess($this->entity, 'create', $this->_params);
1090 $org3 = $this->organizationCreate();
1091 // lets just assume built in ones aren't being messed with!
1092 $relType2 = 5;
1093 // lets just assume built in ones aren't being messed with!
1094 $relType3 = 6;
1095
1096 // Relationship 2.
1097 $this->callAPISuccess($this->entity, 'create',
1098 array_merge($this->_params, [
1099 'relationship_type_id' => $relType2,
1100 'contact_id_b' => $this->_cId_b2,
1101 ])
1102 );
1103
1104 // Relationship 3.
1105 $this->callAPISuccess($this->entity, 'create',
1106 array_merge($this->_params, [
1107 'relationship_type_id' => $relType3,
1108 'contact_id_b' => $org3,
1109 ])
1110 );
1111
1112 $result = $this->callAPISuccess($this->entity, 'get', [
1113 'contact_id_a' => $this->_cId_a,
1114 'relationship_type_id' => ['IN' => [$this->_relTypeID, $relType3]],
1115 ]);
1116
1117 $this->assertEquals(2, $result['count']);
1118 foreach ($result['values'] as $key => $value) {
1119 $this->assertTrue(in_array($value['relationship_type_id'], [$this->_relTypeID, $relType3]));
1120 }
1121 }
1122
1123 /**
1124 * Checks that passing in 'contact_id_b' + a relationship type
1125 * will filter by relationship type for contact b
1126 *
1127 * We should get 1 result without or with correct relationship type id & 0 with
1128 * an incorrect one
1129 */
1130 public function testGetRelationshipByTypeArrayReciprocal() {
1131 $this->callAPISuccess($this->entity, 'create', $this->_params);
1132 $org3 = $this->organizationCreate();
1133 // lets just assume built in ones aren't being messed with!
1134 $relType2 = 5;
1135 $relType3 = 6;
1136
1137 // Relationship 2.
1138 $this->callAPISuccess($this->entity, 'create',
1139 array_merge($this->_params, [
1140 'relationship_type_id' => $relType2,
1141 'contact_id_b' => $this->_cId_b2,
1142 ])
1143 );
1144
1145 // Relationship 3.
1146 $this->callAPISuccess($this->entity, 'create',
1147 array_merge($this->_params, [
1148 'relationship_type_id' => $relType3,
1149 'contact_id_b' => $org3,
1150 ])
1151 );
1152
1153 $result = $this->callAPISuccess($this->entity, 'get', [
1154 'contact_id' => $this->_cId_a,
1155 'relationship_type_id' => ['IN' => [$this->_relTypeID, $relType3]],
1156 ]);
1157
1158 $this->assertEquals(2, $result['count']);
1159 foreach ($result['values'] as $key => $value) {
1160 $this->assertTrue(in_array($value['relationship_type_id'], [$this->_relTypeID, $relType3]));
1161 }
1162 }
1163
1164 /**
1165 * Test relationship get by membership type.
1166 *
1167 * Checks that passing in 'contact_id_b' + a relationship type
1168 * will filter by relationship type for contact b
1169 *
1170 * We should get 1 result without or with correct relationship type id & 0 with
1171 * an incorrect one
1172 * @param int $version
1173 * @dataProvider versionThreeAndFour
1174 */
1175 public function testGetRelationshipByMembershipTypeDAO($version) {
1176 $this->_apiversion = $version;
1177 $this->callAPISuccess($this->entity, 'create', $this->_params);
1178 $org3 = $this->organizationCreate();
1179
1180 // lets just assume built in ones aren't being messed with!
1181 $relType2 = 5;
1182 // lets just assume built in ones aren't being messed with!
1183 $relType3 = 6;
1184 $relType1 = 1;
1185 $memberType = $this->membershipTypeCreate([
1186 'relationship_type_id' => CRM_Core_DAO::VALUE_SEPARATOR . $relType1 . CRM_Core_DAO::VALUE_SEPARATOR . $relType3 . CRM_Core_DAO::VALUE_SEPARATOR,
1187 'relationship_direction' => CRM_Core_DAO::VALUE_SEPARATOR . 'a_b' . CRM_Core_DAO::VALUE_SEPARATOR . 'b_a' . CRM_Core_DAO::VALUE_SEPARATOR,
1188 ]);
1189
1190 // Relationship 2.
1191 $this->callAPISuccess($this->entity, 'create',
1192 array_merge($this->_params, [
1193 'relationship_type_id' => $relType2,
1194 'contact_id_b' => $this->_cId_b2,
1195 ])
1196 );
1197
1198 // Relationship 3.
1199 $this->callAPISuccess($this->entity, 'create',
1200 array_merge($this->_params, [
1201 'relationship_type_id' => $relType3,
1202 'contact_id_b' => $org3,
1203 ])
1204 );
1205
1206 // Relationship 4 with reversal.
1207 $this->callAPISuccess($this->entity, 'create',
1208 array_merge($this->_params, [
1209 'relationship_type_id' => $relType1,
1210 'contact_id_a' => $this->_cId_a,
1211 'contact_id_b' => $this->_cId_a_2,
1212 ])
1213 );
1214
1215 $result = $this->callAPISuccess($this->entity, 'get', [
1216 'contact_id_a' => $this->_cId_a,
1217 'membership_type_id' => $memberType,
1218 ]);
1219 // although our contact has more than one relationship we have passed them in as contact_id_a & can't get reciprocal
1220 $this->assertEquals(1, $result['count']);
1221 foreach ($result['values'] as $key => $value) {
1222 $this->assertTrue(in_array($value['relationship_type_id'], [$relType1]));
1223 }
1224 }
1225
1226 /**
1227 * Checks that passing in 'contact_id_b' + a relationship type
1228 * will filter by relationship type for contact b
1229 *
1230 * We should get 1 result without or with correct relationship type id & 0 with
1231 * an incorrect one
1232 * @param int $version
1233 * @dataProvider versionThreeAndFour
1234 */
1235 public function testGetRelationshipByMembershipTypeReciprocal($version) {
1236 $this->_apiversion = $version;
1237 $this->callAPISuccess($this->entity, 'create', $this->_params);
1238 $org3 = $this->organizationCreate();
1239
1240 // Let's just assume built in ones aren't being messed with!
1241 $relType2 = 5;
1242 $relType3 = 6;
1243 $relType1 = 1;
1244 $memberType = $this->membershipTypeCreate([
1245 'relationship_type_id' => CRM_Core_DAO::VALUE_SEPARATOR . $relType1 . CRM_Core_DAO::VALUE_SEPARATOR . $relType3 . CRM_Core_DAO::VALUE_SEPARATOR,
1246 'relationship_direction' => CRM_Core_DAO::VALUE_SEPARATOR . 'a_b' . CRM_Core_DAO::VALUE_SEPARATOR . 'b_a' . CRM_Core_DAO::VALUE_SEPARATOR,
1247 ]);
1248
1249 // Relationship 2.
1250 $this->callAPISuccess($this->entity, 'create',
1251 array_merge($this->_params, [
1252 'relationship_type_id' => $relType2,
1253 'contact_id_b' => $this->_cId_b2,
1254 ])
1255 );
1256
1257 // Relationship 4.
1258 $this->callAPISuccess($this->entity, 'create',
1259 array_merge($this->_params, [
1260 'relationship_type_id' => $relType3,
1261 'contact_id_b' => $org3,
1262 ])
1263 );
1264
1265 // Relationship 4 with reversal.
1266 $this->callAPISuccess($this->entity, 'create',
1267 array_merge($this->_params, [
1268 'relationship_type_id' => $relType1,
1269 'contact_id_a' => $this->_cId_a,
1270 'contact_id_b' => $this->_cId_a_2,
1271 ])
1272 );
1273
1274 $result = $this->callAPISuccess($this->entity, 'get', [
1275 'contact_id' => $this->_cId_a,
1276 'membership_type_id' => $memberType,
1277 ]);
1278 // Although our contact has more than one relationship we have passed them in as contact_id_a & can't get reciprocal
1279 $this->assertEquals(2, $result['count']);
1280
1281 foreach ($result['values'] as $key => $value) {
1282 $this->assertTrue(in_array($value['relationship_type_id'], [$relType1, $relType3]));
1283 }
1284 }
1285
1286 /**
1287 * Check for e-notices on enable & disable as reported in CRM-14350
1288 *
1289 * @param int $version
1290 *
1291 * @dataProvider versionThreeAndFour
1292 *
1293 * @throws \CRM_Core_Exception
1294 */
1295 public function testSetActive($version) {
1296 $this->_apiversion = $version;
1297 $relationship = $this->callAPISuccess($this->entity, 'create', $this->_params);
1298 $this->callAPISuccess($this->entity, 'create', ['id' => $relationship['id'], 'is_active' => 0]);
1299 $this->callAPISuccess($this->entity, 'create', ['id' => $relationship['id'], 'is_active' => 1]);
1300 }
1301
1302 /**
1303 * Test creating related memberships.
1304 *
1305 * @param int $version
1306 *
1307 * @dataProvider versionThreeAndFour
1308 *
1309 * @throws \CRM_Core_Exception
1310 */
1311 public function testCreateRelatedMembership($version) {
1312 $this->_apiversion = $version;
1313 $relatedMembershipType = $this->callAPISuccess('MembershipType', 'create', [
1314 'name' => 'Membership with Related',
1315 'member_of_contact_id' => 1,
1316 'financial_type_id' => 1,
1317 'minimum_fee' => 0.00,
1318 'duration_unit' => 'year',
1319 'duration_interval' => 1,
1320 'period_type' => 'rolling',
1321 'relationship_type_id' => $this->_relTypeID,
1322 'relationship_direction' => 'b_a',
1323 'visibility' => 'Public',
1324 'auto_renew' => 0,
1325 'is_active' => 1,
1326 'domain_id' => CRM_Core_Config::domainID(),
1327 ]);
1328 $originalMembership = $this->callAPISuccess('Membership', 'create', [
1329 'membership_type_id' => $relatedMembershipType['id'],
1330 'contact_id' => $this->_cId_b,
1331 ]);
1332 $this->callAPISuccess('Relationship', 'create', [
1333 'relationship_type_id' => $this->_relTypeID,
1334 'contact_id_a' => $this->_cId_a,
1335 'contact_id_b' => $this->_cId_b,
1336 ]);
1337 $contactAMembership = $this->callAPISuccessGetSingle('membership', ['contact_id' => $this->_cId_a]);
1338 $this->assertEquals($originalMembership['id'], $contactAMembership['owner_membership_id']);
1339
1340 // Adding a relationship with a future start date should NOT create a membership
1341 $this->callAPISuccess('Relationship', 'create', [
1342 'relationship_type_id' => $this->_relTypeID,
1343 'contact_id_a' => $this->_cId_a_2,
1344 'contact_id_b' => $this->_cId_b,
1345 'start_date' => 'now + 1 week',
1346 ]);
1347 $this->callAPISuccessGetCount('membership', ['contact_id' => $this->_cId_a_2], 0);
1348
1349 // Deleting the organization should cause the related membership to be deleted.
1350 $this->callAPISuccess('contact', 'delete', ['id' => $this->_cId_b]);
1351 $this->callAPISuccessGetCount('membership', ['contact_id' => $this->_cId_a], 0);
1352 }
1353
1354 /**
1355 * Test api respects is_current_employer.
1356 *
1357 * @throws \CRM_Core_Exception
1358 */
1359 public function testRelationshipCreateWithEmployerData() {
1360 // CASE A: Create a current employee relationship without setting end date, ensure that employer field is set
1361 $params = [
1362 'relationship_type_id' => '5_a_b',
1363 'related_contact_id' => $this->_cId_b,
1364 'start_date' => '2008-12-20',
1365 'end_date' => NULL,
1366 'is_active' => 1,
1367 'is_current_employer' => 1,
1368 'is_permission_a_b' => 0,
1369 'is_permission_b_a' => 0,
1370 ];
1371 $reln = new CRM_Contact_Form_Relationship();
1372 $reln->_action = CRM_Core_Action::ADD;
1373 $reln->_contactId = $this->_cId_a;
1374 list ($params, $relationshipIds) = $reln->submit($params);
1375 $this->assertEquals(
1376 $this->_cId_b,
1377 $this->callAPISuccess('Contact', 'getvalue', [
1378 'id' => $this->_cId_a,
1379 'return' => 'current_employer_id',
1380 ]));
1381 // CASE B: Create a past employee relationship by setting end date of past, ensure that employer field is cleared
1382 $params = [
1383 'relationship_type_id' => '5_a_b',
1384 'related_contact_id' => $this->_cId_b,
1385 // set date to past date
1386 'end_date' => '2010-12-20',
1387 ];
1388 $reln->_action = CRM_Core_Action::UPDATE;
1389 $reln->_relationshipId = $relationshipIds[0];
1390 list ($params, $relationshipIds) = $reln->submit($params);
1391 $this->assertEmpty($this->callAPISuccess('Contact', 'getvalue', [
1392 'id' => $this->_cId_a,
1393 'return' => 'current_employer_id',
1394 ]));
1395 $this->callAPISuccess('relationship', 'delete', ['id' => $relationshipIds[0]]);
1396 }
1397
1398 /**
1399 * Test disabling an expired relationship does not incorrectly clear employer_id.
1400 *
1401 * See https://lab.civicrm.org/dev/core/issues/470
1402 *
1403 * @throws \CRM_Core_Exception
1404 * @throws \CiviCRM_API3_Exception
1405 */
1406 public function testDisableExpiredRelationships() {
1407 // Step 1: Create a current employer relationship with Org A
1408 $params = [
1409 'relationship_type_id' => '5',
1410 'contact_id_a' => $this->_cId_a,
1411 'contact_id_b' => $this->_cId_b,
1412 'start_date' => '2008-12-20',
1413 'end_date' => NULL,
1414 'is_active' => 1,
1415 'is_current_employer' => 1,
1416 'is_permission_a_b' => 0,
1417 'is_permission_b_a' => 0,
1418 ];
1419 $this->callAPISuccess('Relationship', 'create', $params);
1420
1421 // ensure that the employer_id field is sucessfully set
1422 $this->assertEquals(
1423 $this->_cId_b,
1424 $this->callAPISuccess('Contact', 'getvalue', [
1425 'id' => $this->_cId_a,
1426 'return' => 'current_employer_id',
1427 ]));
1428 // Step 2: Create a PAST employer relationship with Org B, and setting is_current_employer = FALSE
1429 $orgID2 = $this->organizationCreate();
1430 $params = [
1431 'relationship_type_id' => '5',
1432 'contact_id_a' => $this->_cId_a,
1433 'contact_id_b' => $orgID2,
1434 'start_date' => '2008-12-20',
1435 'end_date' => '2008-12-22',
1436 'is_active' => 1,
1437 'is_current_employer' => 0,
1438 'is_permission_a_b' => 0,
1439 'is_permission_b_a' => 0,
1440 ];
1441
1442 $relationshipB = $this->callAPISuccess('Relationship', 'create', $params);
1443 // ensure that the employer_id field is still set to contact b
1444 $this->assertEquals(
1445 $this->_cId_b,
1446 $this->callAPISuccess('Contact', 'getvalue', [
1447 'id' => $this->_cId_a,
1448 'return' => 'current_employer_id',
1449 ]));
1450
1451 // Step 3: Call schedule job disable_expired_relationships
1452 CRM_Contact_BAO_Relationship::disableExpiredRelationships();
1453
1454 // Result A: Ensure that employer field is not cleared
1455 $this->assertEquals(
1456 $this->_cId_b,
1457 $this->callAPISuccess('Contact', 'getvalue', [
1458 'id' => $this->_cId_a,
1459 'return' => 'current_employer_id',
1460 ]));
1461 // Result B: Ensure that the previous employer relationship with Org B is successfully disabled
1462 $this->assertEquals(
1463 FALSE,
1464 (bool) $this->callAPISuccess('Relationship', 'getvalue', [
1465 'id' => $relationshipB['id'],
1466 'return' => 'is_active',
1467 ]));
1468 }
1469
1470 }