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