3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
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 +--------------------------------------------------------------------+
13 * Class contains api test cases for "civicrm_relationship"
16 class api_v3_RelationshipTest
extends CiviUnitTestCase
{
18 use CRMTraits_Custom_CustomDataTrait
;
29 * Second organization contact.
34 protected $_relTypeID;
36 protected $_customFieldId = NULL;
44 public function setUp() {
46 $this->_cId_a
= $this->individualCreate();
47 $this->_cId_a_2
= $this->individualCreate([
50 'contact_type' => 'Individual',
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.
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',
66 $this->_relTypeID
= $this->relationshipTypeCreate($relTypeParams);
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',
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
);
93 * Check with empty array.
95 * @dataProvider versionThreeAndFour
97 public function testRelationshipCreateEmpty($version) {
98 $this->_apiversion
= $version;
99 $this->callAPIFailure('relationship', 'create', []);
103 * Test Current Employer is correctly set.
105 * @throws \CRM_Core_Exception
107 public function testCurrentEmployerRelationship() {
108 $employerRelationshipID = $this->callAPISuccessGetValue('RelationshipType', [
110 'name_b_a' => 'Employer Of',
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,
119 //Check if current employer is correctly set.
120 $employer = $this->callAPISuccessGetValue('Contact', [
121 'return' => 'current_employer',
122 'id' => $this->_cId_a
,
124 $organisation = $this->callAPISuccessGetValue('Contact', [
125 'return' => "sort_name",
126 'id' => $this->_cId_b
,
128 $this->assertEquals($employer, $organisation);
130 //Update relationship type
131 $update = $this->callAPISuccess('Relationship', 'create', [
132 'id' => $employerRelationship['id'],
133 'relationship_type_id' => $this->_relTypeID
,
135 $employeeContact = $this->callAPISuccessGetSingle('Contact', [
136 'return' => ['current_employer'],
137 'id' => $this->_cId_a
,
139 //current employer should be removed.
140 $this->assertEmpty($employeeContact['current_employer']);
144 * Check if required fields are not passed.
145 * @param int $version
146 * @dataProvider versionThreeAndFour
148 public function testRelationshipCreateWithoutRequired($version) {
149 $this->_apiversion
= $version;
151 'start_date' => ['d' => '10', 'M' => '1', 'Y' => '2008'],
152 'end_date' => ['d' => '10', 'M' => '1', 'Y' => '2009'],
156 $this->callAPIFailure('relationship', 'create', $params);
160 * Check with incorrect required fields.
161 * @param int $version
162 * @dataProvider versionThreeAndFour
164 public function testRelationshipCreateWithIncorrectData($version) {
165 $this->_apiversion
= $version;
168 'contact_id_a' => $this->_cId_a
,
169 'contact_id_b' => $this->_cId_b
,
170 'relationship_type_id' => 'Breaking Relationship',
173 $this->callAPIFailure('relationship', 'create', $params);
175 //contact id is not an integer
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'],
183 $this->callAPIFailure('relationship', 'create', $params);
185 // Contact id does not exist.
186 $params['contact_id_a'] = 999;
187 $this->callAPIFailure('relationship', 'create', $params);
190 $params['contact_id_a'] = $this->_cId_a
;
191 $params['start_date'] = ['d' => '1', 'M' => '1'];
192 $this->callAPIFailure('relationship', 'create', $params);
196 * Check relationship creation with invalid Relationship.
197 * @param int $version
198 * @dataProvider versionThreeAndFour
200 public function testRelationshipCreateInvalidRelationship($version) {
201 $this->_apiversion
= $version;
202 // Both have the contact type Individual.
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',
211 $this->callAPIFailure('relationship', 'create', $params);
213 // both the contact of type Organization
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',
222 $this->callAPIFailure('relationship', 'create', $params);
226 * Check relationship already exists.
227 * @param int $version
228 * @dataProvider versionThreeAndFour
230 public function testRelationshipCreateAlreadyExists($version) {
231 $this->_apiversion
= $version;
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',
240 $relationship = $this->callAPISuccess('relationship', 'create', $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',
249 $this->callAPIFailure('relationship', 'create', $params, 'Duplicate Relationship');
251 $params['id'] = $relationship['id'];
252 $this->callAPISuccess('relationship', 'delete', $params);
256 * Check relationship already exists.
257 * @param int $version
258 * @dataProvider versionThreeAndFour
260 public function testRelationshipCreateUpdateAlreadyExists($version) {
261 $this->_apiversion
= $version;
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',
271 $relationship = $this->callAPISuccess('relationship', 'create', $params);
273 'id' => $relationship['id'],
277 $this->callAPISuccess('relationship', 'create', $params);
278 $this->callAPISuccess('relationship', 'get', $params);
279 $params['id'] = $relationship['id'];
280 $this->callAPISuccess('relationship', 'delete', $params);
284 * Check update doesn't reset stuff badly - CRM-11789.
285 * @param int $version
286 * @dataProvider versionThreeAndFour
288 public function testRelationshipCreateUpdateDoesNotMangle($version) {
289 $this->_apiversion
= $version;
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',
296 'is_permission_a_b' => 1,
297 'description' => 'my desc',
299 $relationship = $this->callAPISuccess('relationship', 'create', $params);
302 'id' => $relationship['id'],
303 'relationship_type_id' => $this->_relTypeID
,
305 $this->callAPISuccess('relationship', 'create', $updateParams);
307 //make sure the orig params didn't get changed
308 $this->getAndCheck($params, $relationship['id'], 'relationship');
313 * Check relationship creation.
314 * @param int $version
315 * @dataProvider versionThreeAndFour
317 public function testRelationshipCreate($version) {
318 $this->_apiversion
= $version;
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',
329 $result = $this->callAPIAndDocument('relationship', 'create', $params, __FUNCTION__
, __FILE__
);
330 $this->assertNotNull($result['id']);
332 'id' => $result['id'],
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') {
343 $this->assertEquals($value, $values[$key], $key . " doesn't match " . print_r($values, TRUE));
345 $params['id'] = $result['id'];
346 $this->callAPISuccess('relationship', 'delete', $params);
350 * Ensure disabling works.
351 * @param int $version
352 * @dataProvider versionThreeAndFour
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']);
361 $this->assertEquals('blah', $result['values'][$result['id']]['description']);
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']);
373 * Check relationship creation.
374 * @param int $version
375 * @dataProvider versionThreeAndFour
377 public function testRelationshipCreateEmptyEndDate($version) {
378 $this->_apiversion
= $version;
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',
389 $result = $this->callAPISuccess('relationship', 'create', $params);
390 $this->assertNotNull($result['id']);
392 'id' => $result['id'],
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') {
403 if ($key == 'end_date') {
404 $this->assertTrue(empty($values[$key]));
407 $this->assertEquals($value, $values[$key], $key . " doesn't match " . print_r($values, TRUE) . 'in line' . __LINE__
);
409 $params['id'] = $result['id'];
410 $this->callAPISuccess('relationship', 'delete', $params);
414 * Check relationship creation with custom data.
417 public function testRelationshipCreateEditWithCustomData() {
418 $this->createCustomGroupWithFieldsOfAllTypes();
419 //few custom Values for comparing
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',
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',
434 $params = array_merge($params, $custom_params);
435 $result = $this->callAPISuccess('relationship', 'create', $params);
437 $relationParams = ['id' => $result['id']];
438 $this->assertDBState('CRM_Contact_DAO_Relationship', $result['id'], $relationParams);
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
,
447 $reln = new CRM_Contact_Form_Relationship();
448 $reln->_action
= CRM_Core_Action
::UPDATE
;
449 $reln->_relationshipId
= $result['id'];
450 $reln->submit($updateParams);
452 $check = $this->callAPISuccess('relationship', 'get', $getParams);
453 $this->assertEquals("Edited Text Value", $check['values'][$check['id']][$this->getCustomFieldName('text')]);
455 $params['id'] = $result['id'];
456 $this->callAPISuccess('relationship', 'delete', $params);
457 $this->relationshipTypeDelete($this->_relTypeID
);
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
467 public function testGetWithCustom() {
468 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__
, __FILE__
);
470 $params = $this->_params
;
471 $params['custom_' . $ids['custom_field_id']] = "custom string";
473 $result = $this->callAPISuccess($this->entity
, 'create', $params);
474 $this->assertEquals($result['id'], $result['values'][$result['id']]['id']);
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__
);
480 $this->customFieldDelete($ids['custom_field_id']);
481 $this->customGroupDelete($ids['custom_group_id']);
485 * Check if required fields are not passed.
486 * @param int $version
487 * @dataProvider versionThreeAndFour
489 public function testRelationshipDeleteWithoutRequired($version) {
490 $this->_apiversion
= $version;
492 'start_date' => '2008-12-20',
493 'end_date' => '2009-12-20',
497 $this->callAPIFailure('relationship', 'delete', $params);
501 * Check with incorrect required fields.
503 public function testRelationshipDeleteWithIncorrectData() {
505 'contact_id_a' => $this->_cId_a
,
506 'contact_id_b' => $this->_cId_b
,
507 'relationship_type_id' => 'Breaking Relationship',
510 $this->callAPIFailure('relationship', 'delete', $params, 'Mandatory key(s) missing from params array: id');
512 $params['id'] = "Invalid";
513 $this->callAPIFailure('relationship', 'delete', $params, 'id is not a valid integer');
517 * Check relationship creation.
518 * @param int $version
519 * @dataProvider versionThreeAndFour
521 public function testRelationshipDelete($version) {
522 $this->_apiversion
= $version;
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',
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
);
537 ///////////////// civicrm_relationship_update methods
540 * Check with empty array.
541 * @param int $version
542 * @dataProvider versionThreeAndFour
544 public function testRelationshipUpdateEmpty($version) {
545 $this->_apiversion
= $version;
546 $this->callAPIFailure('relationship', 'create', [],
547 'contact_id_a, contact_id_b, relationship_type_id');
551 * Check if required fields are not passed.
555 * Check relationship update.
556 * @param int $version
557 * @dataProvider versionThreeAndFour
559 public function testRelationshipCreateDuplicate($version) {
560 $this->_apiversion
= $version;
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',
570 $result = $this->callAPISuccess('relationship', 'create', $relParams);
572 $this->assertNotNull($result['id']);
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',
583 $this->callAPIFailure('relationship', 'create', $params, 'Duplicate Relationship');
585 $this->callAPISuccess('relationship', 'delete', ['id' => $result['id']]);
586 $this->relationshipTypeDelete($this->_relTypeID
);
590 * CRM-13725 - Two relationships of same type with same start and end date
591 * should be OK if the custom field values differ.
594 public function testRelationshipCreateDuplicateWithCustomFields() {
595 $this->createCustomGroupWithFieldsOfAllTypes();
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',
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',
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',
619 $params_1 = array_merge($params, $custom_params_1);
620 $params_2 = array_merge($params, $custom_params_2);
622 $result_1 = $this->callAPISuccess('relationship', 'create', $params_1);
623 $result_2 = $this->callAPISuccess('relationship', 'create', $params_2);
625 $this->assertNotNull($result_2['id']);
626 $this->assertEquals(0, $result_2['is_error']);
628 $this->relationshipTypeDelete($this->_relTypeID
);
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
638 public function testRelationshipCreateDuplicateWithCustomFields2() {
639 $this->createCustomGroupWithFieldsOfAllTypes();
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',
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',
656 $params_2 = array_merge($params_1, $custom_params_2);
658 $this->callAPISuccess('relationship', 'create', $params_1);
659 $result_2 = $this->callAPISuccess('relationship', 'create', $params_2);
661 $this->assertNotNull($result_2['id']);
662 $this->assertEquals(0, $result_2['is_error']);
664 $this->relationshipTypeDelete($this->_relTypeID
);
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
674 public function testRelationshipCreateDuplicateWithCustomFields3() {
675 $this->createCustomGroupWithFieldsOfAllTypes();
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',
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',
692 $params_1 = array_merge($params_2, $custom_params_1);
694 $this->callAPISuccess('relationship', 'create', $params_1);
695 $result_2 = $this->callAPISuccess('relationship', 'create', $params_2);
697 $this->assertNotNull($result_2['id']);
698 $this->assertEquals(0, $result_2['is_error']);
700 $this->relationshipTypeDelete($this->_relTypeID
);
704 * Check with valid params array.
706 public function testRelationshipsGet() {
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',
716 $this->callAPISuccess('relationship', 'create', $relParams);
720 'contact_id' => $this->_cId_b
,
722 $result = $this->callAPISuccess('relationship', 'get', $params);
723 $this->assertEquals($result['count'], 1);
725 'contact_id_a' => $this->_cId_a
,
727 $result = $this->callAPISuccess('relationship', 'get', $params);
728 $this->assertEquals($result['count'], 1);
729 // contact_id_a is wrong so should be no matches
731 'contact_id_a' => $this->_cId_b
,
733 $result = $this->callAPISuccess('relationship', 'get', $params);
734 $this->assertEquals($result['count'], 0);
738 * Chain Relationship.get and to Contact.get.
739 * @param int $version
740 * @dataProvider versionThreeAndFour
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'];
748 // Try to retrieve it using chaining.
750 'relationship_type_id' => $this->_relTypeID
,
752 'api.Contact.get' => [
753 'id' => '$value.contact_id_b',
757 $result = $this->callAPISuccess('relationship', 'get', $params);
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']);
767 * Chain Contact.get to Relationship.get and again to Contact.get.
768 * @param int $version
769 * @dataProvider versionThreeAndFour
771 public function testRelationshipGetInChainedCall($version) {
772 $this->_apiversion
= $version;
773 // Create a relationship.
774 $this->callAPISuccess('relationship', 'create', $this->_params
);
776 // Try to retrieve it using chaining.
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',
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']);
799 * Check with valid params array.
800 * (The get function will behave differently without 'contact_id' passed
801 * @param int $version
802 * @dataProvider versionThreeAndFour
804 public function testRelationshipsGetGeneric($version) {
805 $this->_apiversion
= $version;
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',
815 $this->callAPISuccess('relationship', 'create', $relParams);
819 'contact_id_b' => $this->_cId_b
,
821 $this->callAPISuccess('relationship', 'get', $params);
825 * Test retrieving only current relationships.
826 * @param int $version
827 * @dataProvider versionThreeAndFour
829 public function testGetIsCurrent($version) {
830 $this->_apiversion
= $version;
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',
838 $rel0 = $this->callAPISuccess('relationship', 'create', $rel2Params);
839 $rel1 = $this->callAPISuccess('relationship', 'create', $this->_params
);
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']);
848 // now try not started
849 $rel2Params['is_active'] = 1;
850 $rel2Params['start_date'] = 'tomorrow';
851 $rel2 = $this->callAPISuccess('relationship', 'create', $rel2Params);
854 $rel2Params['start_date'] = 'last week';
855 $rel2Params['end_date'] = 'yesterday';
856 $rel3 = $this->callAPISuccess('relationship', 'create', $rel2Params);
858 $result = $this->callAPISuccess('relationship', 'get', $getParams);
859 $this->assertEquals($result['count'], 1);
860 $this->AssertEquals($rel1['id'], $result['id']);
862 foreach ([$rel0, $rel1, $rel2, $rel3] as $rel) {
863 $this->callAPISuccess('Relationship', 'delete', $rel);
868 * Test using various operators.
869 * @param int $version
870 * @dataProvider versionThreeAndFour
872 public function testGetTypeOperators($version) {
873 $this->_apiversion
= $version;
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',
883 $relationType2 = $this->relationshipTypeCreate($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',
893 $relationType3 = $this->relationshipTypeCreate($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',
904 $relationType4 = $this->relationshipTypeCreate($relTypeParams);
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]));
915 'relationship_type_id' => ['IN' => [$relationType2, $relationType3]],
918 $description = "Demonstrates use of IN filter.";
919 $subfile = 'INRelationshipType';
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']));
925 $description = "Demonstrates use of NOT IN filter.";
926 $subfile = 'NotInRelationshipType';
928 'relationship_type_id' => ['NOT IN' => [$relationType2, $relationType3]],
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']));
934 $description = "Demonstrates use of BETWEEN filter.";
935 $subfile = 'BetweenRelationshipType';
937 'relationship_type_id' => ['BETWEEN' => [$relationType2, $relationType4]],
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']));
943 $description = "Demonstrates use of Not BETWEEN filter.";
944 $subfile = 'NotBetweenRelationshipType';
946 'relationship_type_id' => ['NOT BETWEEN' => [$relationType2, $relationType4]],
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']));
952 foreach ([$relationType2, $relationType3, $relationType4] as $id) {
953 $this->callAPISuccess('RelationshipType', 'delete', ['id' => $id]);
958 * Check with invalid relationshipType Id.
960 public function testRelationshipTypeAddInvalidId() {
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',
968 $this->callAPIFailure('relationship_type', 'create', $relTypeParams,
969 'id is not a valid integer');
973 * Check with valid data with contact_b.
975 public function testGetRelationshipWithContactB() {
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',
985 $relationship = $this->callAPISuccess('relationship', 'create', $relParams);
988 'contact_id' => $this->_cId_a
,
991 $result = $this->callAPISuccess('relationship', 'get', $contacts);
992 $this->assertGreaterThan(0, $result['count']);
994 'id' => $relationship['id'],
996 $this->callAPISuccess('relationship', 'delete', $params);
997 $this->relationshipTypeDelete($this->_relTypeID
);
1001 * Check with valid data with relationshipTypes.
1003 public function testGetRelationshipWithRelTypes() {
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',
1013 $relationship = $this->callAPISuccess('relationship', 'create', $relParams);
1016 'contact_id' => $this->_cId_a
,
1018 $this->callAPISuccess('relationship', 'get', $contact_a);
1021 'id' => $relationship['id'],
1023 $this->callAPISuccess('relationship', 'delete', $params);
1024 $this->relationshipTypeDelete($this->_relTypeID
);
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
1032 * We should get 1 result without or with correct relationship type id & 0 with
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
,
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,
1046 $this->assertEquals(0, $result['count']);
1047 $this->callAPISuccess($this->entity
, 'delete', ['id' => $created['id']]);
1051 * Checks that passing in 'contact_id_b' + a relationship type
1052 * will filter by relationship type for contact b
1054 * We should get 1 result without or with correct relationship type id & 0 with
1056 * @param int $version
1057 * @dataProvider versionThreeAndFour
1059 public function testGetRelationshipByTypeDAO($version) {
1060 $this->_apiversion
= $version;
1061 $this->_ids
['relationship'] = $this->callAPISuccess($this->entity
, 'create', ['format.only_id' => TRUE] +
1063 $this->callAPISuccess($this->entity
, 'getcount', [
1064 'contact_id_a' => $this->_cId_a
,
1066 $result = $this->callAPISuccess($this->entity
, 'get', [
1067 'contact_id_a' => $this->_cId_a
,
1068 'relationship_type_id' => $this->_relTypeID
,
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,
1075 $this->assertEquals(0, $result['count']);
1079 * Checks that passing in 'contact_id_b' + a relationship type
1080 * will filter by relationship type for contact b
1082 * We should get 1 result without or with correct relationship type id & 0 with
1084 * @param int $version
1085 * @dataProvider versionThreeAndFour
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!
1093 // lets just assume built in ones aren't being messed with!
1097 $this->callAPISuccess($this->entity
, 'create',
1098 array_merge($this->_params
, [
1099 'relationship_type_id' => $relType2,
1100 'contact_id_b' => $this->_cId_b2
,
1105 $this->callAPISuccess($this->entity
, 'create',
1106 array_merge($this->_params
, [
1107 'relationship_type_id' => $relType3,
1108 'contact_id_b' => $org3,
1112 $result = $this->callAPISuccess($this->entity
, 'get', [
1113 'contact_id_a' => $this->_cId_a
,
1114 'relationship_type_id' => ['IN' => [$this->_relTypeID
, $relType3]],
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]));
1124 * Checks that passing in 'contact_id_b' + a relationship type
1125 * will filter by relationship type for contact b
1127 * We should get 1 result without or with correct relationship type id & 0 with
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!
1138 $this->callAPISuccess($this->entity
, 'create',
1139 array_merge($this->_params
, [
1140 'relationship_type_id' => $relType2,
1141 'contact_id_b' => $this->_cId_b2
,
1146 $this->callAPISuccess($this->entity
, 'create',
1147 array_merge($this->_params
, [
1148 'relationship_type_id' => $relType3,
1149 'contact_id_b' => $org3,
1153 $result = $this->callAPISuccess($this->entity
, 'get', [
1154 'contact_id' => $this->_cId_a
,
1155 'relationship_type_id' => ['IN' => [$this->_relTypeID
, $relType3]],
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]));
1165 * Test relationship get by membership type.
1167 * Checks that passing in 'contact_id_b' + a relationship type
1168 * will filter by relationship type for contact b
1170 * We should get 1 result without or with correct relationship type id & 0 with
1172 * @param int $version
1173 * @dataProvider versionThreeAndFour
1175 public function testGetRelationshipByMembershipTypeDAO($version) {
1176 $this->_apiversion
= $version;
1177 $this->callAPISuccess($this->entity
, 'create', $this->_params
);
1178 $org3 = $this->organizationCreate();
1180 // lets just assume built in ones aren't being messed with!
1182 // lets just assume built in ones aren't being messed with!
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
,
1191 $this->callAPISuccess($this->entity
, 'create',
1192 array_merge($this->_params
, [
1193 'relationship_type_id' => $relType2,
1194 'contact_id_b' => $this->_cId_b2
,
1199 $this->callAPISuccess($this->entity
, 'create',
1200 array_merge($this->_params
, [
1201 'relationship_type_id' => $relType3,
1202 'contact_id_b' => $org3,
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
,
1215 $result = $this->callAPISuccess($this->entity
, 'get', [
1216 'contact_id_a' => $this->_cId_a
,
1217 'membership_type_id' => $memberType,
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]));
1227 * Checks that passing in 'contact_id_b' + a relationship type
1228 * will filter by relationship type for contact b
1230 * We should get 1 result without or with correct relationship type id & 0 with
1232 * @param int $version
1233 * @dataProvider versionThreeAndFour
1235 public function testGetRelationshipByMembershipTypeReciprocal($version) {
1236 $this->_apiversion
= $version;
1237 $this->callAPISuccess($this->entity
, 'create', $this->_params
);
1238 $org3 = $this->organizationCreate();
1240 // Let's just assume built in ones aren't being messed with!
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
,
1250 $this->callAPISuccess($this->entity
, 'create',
1251 array_merge($this->_params
, [
1252 'relationship_type_id' => $relType2,
1253 'contact_id_b' => $this->_cId_b2
,
1258 $this->callAPISuccess($this->entity
, 'create',
1259 array_merge($this->_params
, [
1260 'relationship_type_id' => $relType3,
1261 'contact_id_b' => $org3,
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
,
1274 $result = $this->callAPISuccess($this->entity
, 'get', [
1275 'contact_id' => $this->_cId_a
,
1276 'membership_type_id' => $memberType,
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']);
1281 foreach ($result['values'] as $key => $value) {
1282 $this->assertTrue(in_array($value['relationship_type_id'], [$relType1, $relType3]));
1287 * Check for e-notices on enable & disable as reported in CRM-14350
1289 * @param int $version
1291 * @dataProvider versionThreeAndFour
1293 * @throws \CRM_Core_Exception
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]);
1303 * Test creating related memberships.
1305 * @param int $version
1307 * @dataProvider versionThreeAndFour
1309 * @throws \CRM_Core_Exception
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',
1326 'domain_id' => CRM_Core_Config
::domainID(),
1328 $originalMembership = $this->callAPISuccess('Membership', 'create', [
1329 'membership_type_id' => $relatedMembershipType['id'],
1330 'contact_id' => $this->_cId_b
,
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
,
1337 $contactAMembership = $this->callAPISuccessGetSingle('membership', ['contact_id' => $this->_cId_a
]);
1338 $this->assertEquals($originalMembership['id'], $contactAMembership['owner_membership_id']);
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',
1347 $this->callAPISuccessGetCount('membership', ['contact_id' => $this->_cId_a_2
], 0);
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);
1355 * Test api respects is_current_employer.
1357 * @throws \CRM_Core_Exception
1359 public function testRelationshipCreateWithEmployerData() {
1360 // CASE A: Create a current employee relationship without setting end date, ensure that employer field is set
1362 'relationship_type_id' => '5_a_b',
1363 'related_contact_id' => $this->_cId_b
,
1364 'start_date' => '2008-12-20',
1367 'is_current_employer' => 1,
1368 'is_permission_a_b' => 0,
1369 'is_permission_b_a' => 0,
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(
1377 $this->callAPISuccess('Contact', 'getvalue', [
1378 'id' => $this->_cId_a
,
1379 'return' => 'current_employer_id',
1381 // CASE B: Create a past employee relationship by setting end date of past, ensure that employer field is cleared
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',
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',
1395 $this->callAPISuccess('relationship', 'delete', ['id' => $relationshipIds[0]]);
1399 * Test disabling an expired relationship does not incorrectly clear employer_id.
1401 * See https://lab.civicrm.org/dev/core/issues/470
1403 * @throws \CRM_Core_Exception
1404 * @throws \CiviCRM_API3_Exception
1406 public function testDisableExpiredRelationships() {
1407 // Step 1: Create a current employer relationship with Org A
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',
1415 'is_current_employer' => 1,
1416 'is_permission_a_b' => 0,
1417 'is_permission_b_a' => 0,
1419 $this->callAPISuccess('Relationship', 'create', $params);
1421 // ensure that the employer_id field is sucessfully set
1422 $this->assertEquals(
1424 $this->callAPISuccess('Contact', 'getvalue', [
1425 'id' => $this->_cId_a
,
1426 'return' => 'current_employer_id',
1428 // Step 2: Create a PAST employer relationship with Org B, and setting is_current_employer = FALSE
1429 $orgID2 = $this->organizationCreate();
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',
1437 'is_current_employer' => 0,
1438 'is_permission_a_b' => 0,
1439 'is_permission_b_a' => 0,
1442 $relationshipB = $this->callAPISuccess('Relationship', 'create', $params);
1443 // ensure that the employer_id field is still set to contact b
1444 $this->assertEquals(
1446 $this->callAPISuccess('Contact', 'getvalue', [
1447 'id' => $this->_cId_a
,
1448 'return' => 'current_employer_id',
1451 // Step 3: Call schedule job disable_expired_relationships
1452 CRM_Contact_BAO_Relationship
::disableExpiredRelationships();
1454 // Result A: Ensure that employer field is not cleared
1455 $this->assertEquals(
1457 $this->callAPISuccess('Contact', 'getvalue', [
1458 'id' => $this->_cId_a
,
1459 'return' => 'current_employer_id',
1461 // Result B: Ensure that the previous employer relationship with Org B is successfully disabled
1462 $this->assertEquals(
1464 (bool) $this->callAPISuccess('Relationship', 'getvalue', [
1465 'id' => $relationshipB['id'],
1466 'return' => 'is_active',