3 +--------------------------------------------------------------------+
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
29 * Test class for CRM_Contact_BAO_Relationship
34 class CRM_Contact_BAO_RelationshipTest
extends CiviUnitTestCase
{
37 * Sets up the fixture, for example, opens a network connection.
39 * This method is called before a test is executed.
41 protected function setUp() {
46 * Tears down the fixture, for example, closes a network connection.
48 * This method is called after a test is executed.
50 protected function tearDown() {
52 'civicrm_relationship_type',
53 'civicrm_relationship',
60 public function testRelationshipTypeOptionsWillReturnSpecifiedType() {
61 $orgToOrgType = 'A_B_relationship';
62 $orgToOrgReverseType = 'B_A_relationship';
63 civicrm_api3('RelationshipType', 'create', [
64 'name_a_b' => $orgToOrgType,
65 'name_b_a' => $orgToOrgReverseType,
66 'contact_type_a' => 'Organization',
67 'contact_type_b' => 'Organization',
70 $result = CRM_Contact_BAO_Relationship
::buildRelationshipTypeOptions(
71 ['contact_type' => 'Organization']
73 $this->assertContains($orgToOrgType, $result);
74 $this->assertContains($orgToOrgReverseType, $result);
76 $result = CRM_Contact_BAO_Relationship
::buildRelationshipTypeOptions(
77 ['contact_type' => 'Individual']
80 $this->assertNotContains($orgToOrgType, $result);
81 $this->assertNotContains($orgToOrgReverseType, $result);
84 public function testContactIdAndRelationshipIdWillBeUsedInFilter() {
85 $individual = civicrm_api3('Contact', 'create', [
86 'display_name' => 'Individual A',
87 'contact_type' => 'Individual',
89 $organization = civicrm_api3('Contact', 'create', [
90 'organization_name' => 'Organization B',
91 'contact_type' => 'Organization',
94 $personToOrgType = 'A_B_relationship';
95 $orgToPersonType = 'B_A_relationship';
97 $orgToPersonTypeId = civicrm_api3('RelationshipType', 'create', [
98 'name_a_b' => $personToOrgType,
99 'name_b_a' => $orgToPersonType,
100 'contact_type_a' => 'Individual',
101 'contact_type_b' => 'Organization',
104 $personToPersonType = 'A_B_alt_relationship';
105 $personToPersonReverseType = 'B_A_alt_relationship';
107 civicrm_api3('RelationshipType', 'create', [
108 'name_a_b' => $personToPersonType,
109 'name_b_a' => $personToPersonReverseType,
110 'contact_type_a' => 'Individual',
111 'contact_type_b' => 'Individual',
114 // create a relationship individual => organization
115 $relationship = civicrm_api3('Relationship', 'create', [
116 'contact_id_a' => $individual['id'],
117 'contact_id_b' => $organization['id'],
118 'relationship_type_id' => $orgToPersonTypeId,
121 $options = CRM_Contact_BAO_Relationship
::buildRelationshipTypeOptions([
122 'relationship_id' => (string) $relationship['id'],
123 'contact_id' => $individual['id'],
126 // for this relationship only individual=>organization is possible
127 $this->assertContains($personToOrgType, $options);
128 $this->assertNotContains($orgToPersonType, $options);
130 // by passing relationship ID we know that the "B" side is an organization
131 $this->assertNotContains($personToPersonType, $options);
132 $this->assertNotContains($personToPersonReverseType, $options);
134 $options = CRM_Contact_BAO_Relationship
::buildRelationshipTypeOptions([
135 'contact_id' => $individual['id'],
138 // for this result we only know that "A" must be an individual
139 $this->assertContains($personToOrgType, $options);
140 $this->assertNotContains($orgToPersonType, $options);
142 // unlike when we pass relationship type ID there is no filter by "B" type
143 $this->assertContains($personToPersonType, $options);
144 $this->assertContains($personToPersonReverseType, $options);
148 * Test removeRelationshipTypeDuplicates method.
150 * @dataProvider getRelationshipTypeDuplicates
152 public function testRemoveRelationshipTypeDuplicates($relationshipTypeList, $suffix = NULL, $expected, $description) {
153 $result = CRM_Contact_BAO_Relationship
::removeRelationshipTypeDuplicates($relationshipTypeList, $suffix);
154 $this->assertEquals($expected, $result, "Failure on set '$description'");
157 public function getRelationshipTypeDuplicates() {
158 $relationshipTypeList = [
159 '1_a_b' => 'duplicate one',
160 '1_b_a' => 'duplicate one',
166 $relationshipTypeList,
169 '1_a_b' => 'duplicate one',
176 $relationshipTypeList,
179 '1_b_a' => 'duplicate one',
186 $relationshipTypeList,
189 '1_a_b' => 'duplicate one',
196 $relationshipTypeList,
199 '1_a_b' => 'duplicate one',
203 'With suffix "" (empty string)',
210 * Test that two similar memberships are not created for two relationships
212 * @throws \CRM_Core_Exception
214 public function testSingleMembershipForTwoRelationships() {
215 $individualID = $this->individualCreate(['display_name' => 'Individual A']);
216 $organisationID = $this->organizationCreate(['organization_name' => 'Organization B']);
217 $membershipOrganisationID = $this->organizationCreate(['organization_name' => 'Membership Organization']);
218 $orgToPersonTypeId1 = $this->relationshipTypeCreate(['name_a_b' => 'Inherited_Relationship_1_A_B', 'name_b_a' => 'Inherited_Relationship_1_B_A']);
219 $orgToPersonTypeId2 = $this->relationshipTypeCreate(['name_a_b' => 'Inherited_Relationship_2_A_B', 'name_b_a' => 'Inherited_Relationship_2_B_A']);
221 $membershipType = $this->callAPISuccess('MembershipType', 'create', [
222 'member_of_contact_id' => $membershipOrganisationID,
223 'financial_type_id' => 'Member Dues',
224 'duration_unit' => 'year',
225 'duration_interval' => 1,
226 'period_type' => 'rolling',
227 'name' => 'Inherited Membership',
228 'relationship_type_id' => [$orgToPersonTypeId1, $orgToPersonTypeId2],
229 'relationship_direction' => ['b_a', 'a_b'],
231 $membershipType = $this->callAPISuccessGetSingle('MembershipType', ['id' => $membershipType['id']]);
232 // Check the metadata worked....
233 $this->assertEquals([$orgToPersonTypeId1, $orgToPersonTypeId2], $membershipType['relationship_type_id']);
234 $this->assertEquals(['b_a', 'a_b'], $membershipType['relationship_direction']);
236 $this->callAPISuccess('Membership', 'create', [
237 'membership_type_id' => $membershipType['id'],
238 'contact_id' => $organisationID,
241 $relationshipOne = $this->callAPISuccess('Relationship', 'create', [
242 'contact_id_a' => $individualID,
243 'contact_id_b' => $organisationID,
244 'relationship_type_id' => $orgToPersonTypeId1,
246 $relationshipTwo = $this->callAPISuccess('Relationship', 'create', [
247 'contact_id_a' => $individualID,
248 'contact_id_b' => $organisationID,
249 'relationship_type_id' => $orgToPersonTypeId2,
252 $this->callAPISuccessGetCount('Membership', ['contact_id' => $individualID], 1);
254 // Disable the relationship & check the membership is removed.
255 $relationshipOne['is_active'] = 0;
256 $this->callAPISuccess('Relationship', 'create', array_merge($relationshipOne, ['is_active' => 0]));
257 $this->callAPISuccessGetCount('Membership', ['contact_id' => $individualID], 0);
259 * @todo this section not yet working due to bug in would-be-tested code.
260 $relationshipTwo['is_active'] = 0;
261 $this->callAPISuccess('Relationship', 'create', $relationshipTwo);
262 $this->callAPISuccessGetCount('Membership', ['contact_id' => $individualID], 1);
264 $relationshipOne['is_active'] = 1;
265 $this->callAPISuccess('Relationship', 'create', $relationshipOne);
266 $this->callAPISuccessGetCount('Membership', ['contact_id' => $individualID], 1);
267 $relationshipTwo['is_active'] = 1;
268 $this->callAPISuccess('Relationship', 'create', $relationshipTwo);
269 $this->callAPISuccessGetCount('Membership', ['contact_id' => $individualID], 1);
270 $this->callAPISuccess('Relationship', 'delete', ['id' => $relationshipTwo['id']]);
271 $this->callAPISuccessGetCount('Membership', ['contact_id' => $individualID], 1);
272 $this->callAPISuccess('Relationship', 'delete', ['id' => $relationshipOne['id']]);
273 $this->callAPISuccessGetCount('Membership', ['contact_id' => $individualID], 0);