Merge pull request #9595 from totten/master-extbatch-env
[civicrm-core.git] / tests / phpunit / api / v3 / MembershipTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
81621fee 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
15a4309a 6 | Copyright CiviCRM LLC (c) 2004-2017 |
6a488035
TO
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 * Test APIv3 civicrm_membership functions
30 *
6c6e6187
TO
31 * @package CiviCRM_APIv3
32 * @subpackage API_Member
6a488035
TO
33 */
34
4cbe18b8
EM
35/**
36 * Class api_v3_MembershipTest
acb109b7 37 * @group headless
4cbe18b8 38 */
6a488035
TO
39class api_v3_MembershipTest extends CiviUnitTestCase {
40 protected $_apiversion;
41 protected $_contactID;
d54576ed
EM
42 protected $_membershipID;
43 protected $_membershipID2;
44 protected $_membershipID3;
6a488035 45 protected $_membershipTypeID;
8c33a68c 46 protected $_membershipTypeID2;
6a488035 47 protected $_membershipStatusID;
6a488035
TO
48 protected $_entity;
49 protected $_params;
b7c9bc4c 50
80d714d2 51 /**
52 * Set up for tests.
53 */
6a488035 54 public function setUp() {
6a488035
TO
55 parent::setUp();
56 $this->_apiversion = 3;
57 $this->_contactID = $this->individualCreate();
75638074 58 $this->_membershipTypeID = $this->membershipTypeCreate(array('member_of_contact_id' => $this->_contactID));
5896d037
TO
59 $this->_membershipTypeID2 = $this->membershipTypeCreate(array(
60 'period_type' => 'fixed',
2ea0abec 61 // Ie. 1 March.
5896d037 62 'fixed_period_start_day' => '301',
2ea0abec 63 // Ie. 11 Nov.
21dfd5f5 64 'fixed_period_rollover_day' => '1111',
5d8b37be 65 'name' => 'Another one',
5896d037 66 ));
6a488035
TO
67 $this->_membershipStatusID = $this->membershipStatusCreate('test status');
68
6a488035
TO
69 CRM_Member_PseudoConstant::membershipType(NULL, TRUE);
70 CRM_Member_PseudoConstant::membershipStatus(NULL, NULL, 'name', TRUE);
71 CRM_Core_PseudoConstant::activityType(TRUE, TRUE, TRUE, 'name');
72
73 $this->_entity = 'Membership';
74 $this->_params = array(
75 'contact_id' => $this->_contactID,
76 'membership_type_id' => $this->_membershipTypeID,
77 'join_date' => '2009-01-21',
78 'start_date' => '2009-01-21',
79 'end_date' => '2009-12-21',
80 'source' => 'Payment',
81 'is_override' => 1,
82 'status_id' => $this->_membershipStatusID,
6a488035
TO
83 );
84 }
85
80d714d2 86 /**
87 * Clean up after tests.
88 *
89 * @throws \Exception
90 */
00be9182 91 public function tearDown() {
6a488035 92 $this->quickCleanup(array(
5896d037
TO
93 'civicrm_membership',
94 'civicrm_membership_payment',
95 'civicrm_membership_log',
771f3245 96 ),
97 TRUE
6a488035
TO
98 );
99 $this->membershipStatusDelete($this->_membershipStatusID);
8c33a68c 100 $this->membershipTypeDelete(array('id' => $this->_membershipTypeID2));
6a488035
TO
101 $this->membershipTypeDelete(array('id' => $this->_membershipTypeID));
102 $this->contactDelete($this->_contactID);
103
104 }
105
106 /**
2ea0abec 107 * Test membership deletion.
6a488035 108 */
00be9182 109 public function testMembershipDelete() {
6a488035 110 $membershipID = $this->contactMembershipCreate($this->_params);
3506b6cd 111 $this->assertDBRowExist('CRM_Member_DAO_Membership', $membershipID);
6a488035 112 $params = array(
21dfd5f5 113 'id' => $membershipID,
6a488035 114 );
d54576ed 115 $this->callAPIAndDocument('membership', 'delete', $params, __FUNCTION__, __FILE__);
3506b6cd 116 $this->assertDBRowNotExist('CRM_Member_DAO_Membership', $membershipID);
6a488035
TO
117 }
118
00be9182 119 public function testMembershipDeleteEmpty() {
d54576ed 120 $this->callAPIFailure('membership', 'delete', array());
6a488035
TO
121 }
122
00be9182 123 public function testMembershipDeleteInvalidID() {
d54576ed 124 $this->callAPIFailure('membership', 'delete', array('id' => 'blah'));
6a488035
TO
125 }
126
127 /**
2ea0abec 128 * Test civicrm_membership_delete() with invalid Membership Id.
6a488035 129 */
00be9182 130 public function testMembershipDeleteWithInvalidMembershipId() {
6a488035 131 $membershipId = 'membership';
d54576ed 132 $this->callAPIFailure('membership', 'delete', $membershipId);
6a488035
TO
133 }
134
ed4cc29d
JT
135 /**
136 * Test membership deletion and with the preserve contribution param.
137 */
138 public function testMembershipDeletePreserveContribution() {
139 $membershipID = $this->contactMembershipCreate($this->_params); //DELETE
140 $this->assertDBRowExist('CRM_Member_DAO_Membership', $membershipID); //DELETE
141 $ContributionCreate = $this->callAPISuccess('Contribution', 'create', array(
142 'sequential' => 1,
143 'financial_type_id' => "Member Dues",
144 'total_amount' => 100,
145 'contact_id' => $this->_params['contact_id'],
146 ));
147 $membershipPaymentCreate = $this->callAPISuccess('MembershipPayment', 'create', array(
148 'sequential' => 1,
149 'contribution_id' => $ContributionCreate['values'][0]['id'],
150 'membership_id' => $membershipID,
151 ));
152 $memParams = array(
153 'id' => $membershipID,
154 'preserve_contribution' => 1,
155 );
156 $contribParams = array(
157 'id' => $ContributionCreate['values'][0]['id'],
158 );
159 $this->callAPIAndDocument('membership', 'delete', $memParams, __FUNCTION__, __FILE__);
160 $this->assertDBRowNotExist('CRM_Member_DAO_Membership', $membershipID);
161 $this->assertDBRowExist('CRM_Contribute_DAO_Contribution', $ContributionCreate['values'][0]['id']);
162 $this->callAPISuccess('Contribution', 'delete', $contribParams);
163 $this->assertDBRowNotExist('CRM_Contribute_DAO_Contribution', $ContributionCreate['values'][0]['id']);
164 }
165
6a488035 166 /**
2ea0abec 167 * Test membership get.
6a488035 168 */
00be9182 169 public function testContactMembershipsGet() {
6a488035 170 $this->_membershipID = $this->contactMembershipCreate($this->_params);
2ea0abec 171 $this->callAPISuccess('membership', 'get', array());
6c6e6187 172 $this->callAPISuccess('Membership', 'Delete', array('id' => $this->_membershipID));
6a488035
TO
173 }
174
175 /**
176 * Test civicrm_membership_get with params not array.
2ea0abec 177 *
6a488035
TO
178 * Gets treated as contact_id, memberships expected.
179 */
00be9182 180 public function testGetWithParamsContactId() {
6a488035
TO
181 $this->_membershipID = $this->contactMembershipCreate($this->_params);
182 $params = array(
183 'contact_id' => $this->_contactID,
6a488035 184 );
771f3245 185 $membership = $this->callAPISuccess('membership', 'get', $params);
6a488035
TO
186
187 $result = $membership['values'][$this->_membershipID];
771f3245 188 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 189 'id' => $this->_membershipID,
5896d037 190 ));
6a488035
TO
191 $this->assertEquals($result['contact_id'], $this->_contactID, "In line " . __LINE__);
192 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID, "In line " . __LINE__);
193 $this->assertEquals($result['status_id'], $this->_membershipStatusID, "In line " . __LINE__);
194 $this->assertEquals($result['join_date'], '2009-01-21', "In line " . __LINE__);
195 $this->assertEquals($result['start_date'], '2009-01-21', "In line " . __LINE__);
196 $this->assertEquals($result['end_date'], '2009-12-21', "In line " . __LINE__);
197 $this->assertEquals($result['source'], 'Payment', "In line " . __LINE__);
198 $this->assertEquals($result['is_override'], 1, "In line " . __LINE__);
199 }
200
b4529041 201 /**
202 * Test civicrm_membership_get with params not array.
2ea0abec 203 *
b4529041 204 * Gets treated as contact_id, memberships expected.
205 */
00be9182 206 public function testGetInSyntax() {
b4529041 207 $this->_membershipID = $this->contactMembershipCreate($this->_params);
208 $this->_membershipID2 = $this->contactMembershipCreate($this->_params);
209 $this->_membershipID3 = $this->contactMembershipCreate($this->_params);
210 $params = array(
211 'id' => array('IN' => array($this->_membershipID, $this->_membershipID3)),
212 );
213 $membership = $this->callAPISuccess('membership', 'get', $params);
214 $this->assertEquals(2, $membership['count']);
215 $this->assertEquals(array($this->_membershipID, $this->_membershipID3), array_keys($membership['values']));
216 $params = array(
217 'id' => array('NOT IN' => array($this->_membershipID, $this->_membershipID3)),
218 );
219 $membership = $this->callAPISuccess('membership', 'get', $params);
220 $this->assertEquals(1, $membership['count']);
221 $this->assertEquals(array($this->_membershipID2), array_keys($membership['values']));
b4529041 222 }
223
caca32ba 224 /**
225 * Test civicrm_membership_get with params not array.
226 * Gets treated as contact_id, memberships expected.
227 */
00be9182 228 public function testGetInSyntaxOnContactID() {
caca32ba 229 $this->_membershipID = $this->contactMembershipCreate($this->_params);
230 $contact2 = $this->individualCreate();
231 $contact3 = $this->individualCreate(array('first_name' => 'Scout', 'last_name' => 'Canine'));
232 $this->_membershipID2 = $this->contactMembershipCreate(array_merge($this->_params, array('contact_id' => $contact2)));
233 $this->_membershipID3 = $this->contactMembershipCreate(array_merge($this->_params, array('contact_id' => $contact3)));
234 $params = array(
235 'contact_id' => array('IN' => array($this->_contactID, $contact3)),
236 );
237 $membership = $this->callAPISuccess('membership', 'get', $params);
238 $this->assertEquals(2, $membership['count']);
239 $this->assertEquals(array($this->_membershipID, $this->_membershipID3), array_keys($membership['values']));
240 $params = array(
241 'contact_id' => array('NOT IN' => array($this->_contactID, $contact3)),
242 );
243 $membership = $this->callAPISuccess('membership', 'get', $params);
244 $this->assertEquals(1, $membership['count']);
245 $this->assertEquals(array($this->_membershipID2), array_keys($membership['values']));
246 }
5896d037 247
caca32ba 248 /**
249 * Test civicrm_membership_get with params not array.
80d714d2 250 *
caca32ba 251 * Gets treated as contact_id, memberships expected.
252 */
00be9182 253 public function testGetWithParamsMemberShipTypeId() {
d54576ed 254 $this->callAPISuccess($this->_entity, 'create', $this->_params);
6a488035
TO
255 $params = array(
256 'membership_type_id' => $this->_membershipTypeID,
6a488035 257 );
771f3245 258 $membership = $this->callAPISuccess('membership', 'get', $params);
d54576ed 259 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 260 'id' => $membership['id'],
771f3245 261 ));
6a488035 262 $result = $membership['values'][$membership['id']];
80d714d2 263 $this->assertEquals($result['contact_id'], $this->_contactID);
264 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID);
265 $this->assertEquals($result['status_id'], $this->_membershipStatusID);
266 $this->assertEquals($result['join_date'], '2009-01-21');
267 $this->assertEquals($result['start_date'], '2009-01-21');
268 $this->assertEquals($result['end_date'], '2009-12-21');
269 $this->assertEquals($result['source'], 'Payment');
270 $this->assertEquals($result['is_override'], 1);
6a488035
TO
271 $this->assertEquals($result['id'], $membership['id']);
272 }
5896d037 273
a73daeff
E
274 /**
275 * Test civicrm_membership_get with params not array.
276 * Gets treated as contact_id, memberships expected.
277 */
00be9182 278 public function testGetWithParamsMemberShipTypeIdContactID() {
a73daeff
E
279 $params = $this->_params;
280 $this->callAPISuccess($this->_entity, 'create', $params);
281 $params['membership_type_id'] = $this->_membershipTypeID2;
282 $this->callAPISuccess($this->_entity, 'create', $params);
283 $this->callAPISuccessGetCount('membership', array('contact_id' => $this->_contactID), 2);
284 $params = array(
285 'membership_type_id' => $this->_membershipTypeID,
286 'contact_id' => $this->_contactID,
287 );
288 $result = $this->callAPISuccess('membership', 'getsingle', $params);
289 $this->assertEquals($result['contact_id'], $this->_contactID);
290 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID);
6a488035 291
a73daeff
E
292 $params = array(
293 'membership_type_id' => $this->_membershipTypeID2,
294 'contact_id' => $this->_contactID,
295 );
296 $result = $this->callAPISuccess('membership', 'getsingle', $params);
297 $this->assertEquals($result['contact_id'], $this->_contactID);
298 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID2);
299 }
5896d037 300
6a488035 301 /**
80d714d2 302 * Check with complete array + custom field.
303 *
6a488035
TO
304 * Note that the test is written on purpose without any
305 * variables specific to participant so it can be replicated into other entities
306 * and / or moved to the automated test suite
307 */
00be9182 308 public function testGetWithParamsMemberShipIdAndCustom() {
6a488035
TO
309 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
310
311 $params = $this->_params;
312 $params['custom_' . $ids['custom_field_id']] = "custom string";
313
771f3245 314 $result = $this->callAPISuccess($this->_entity, 'create', $params);
6a488035 315
771f3245 316 $getParams = array('membership_type_id' => $params['membership_type_id']);
317 $check = $this->callAPIAndDocument($this->_entity, 'get', $getParams, __FUNCTION__, __FILE__);
6a488035
TO
318 $this->assertEquals("custom string", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
319
d54576ed 320 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 321 'id' => $result['id'],
771f3245 322 ));
6a488035
TO
323 }
324
325 /**
326 * Test civicrm_membership_get with proper params.
327 * Memberships expected.
328 */
00be9182 329 public function testGet() {
6a488035
TO
330 $membershipID = $this->contactMembershipCreate($this->_params);
331 $params = array(
332 'contact_id' => $this->_contactID,
6a488035
TO
333 );
334
771f3245 335 $membership = $this->callAPISuccess('membership', 'get', $params);
6a488035 336 $result = $membership['values'][$membershipID];
771f3245 337 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 338 'id' => $membership['id'],
771f3245 339 ));
80d714d2 340 $this->assertEquals($result['join_date'], '2009-01-21');
341 $this->assertEquals($result['contact_id'], $this->_contactID);
342 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID);
343 $this->assertEquals($result['status_id'], $this->_membershipStatusID);
6a488035 344
80d714d2 345 $this->assertEquals($result['start_date'], '2009-01-21');
346 $this->assertEquals($result['end_date'], '2009-12-21');
347 $this->assertEquals($result['source'], 'Payment');
348 $this->assertEquals($result['is_override'], 1);
6a488035
TO
349 }
350
351
352 /**
353 * Test civicrm_membership_get with proper params.
354 * Memberships expected.
355 */
00be9182 356 public function testGetWithId() {
6a488035
TO
357 $membershipID = $this->contactMembershipCreate($this->_params);
358 $params = array(
359 'contact_id' => $this->_contactID,
d54576ed 360 'id' => $this->_membershipID,
6a488035
TO
361 'return' => 'id',
362 );
771f3245 363 $result = $this->callAPISuccess('membership', 'get', $params);
6a488035
TO
364 $this->assertEquals($membershipID, $result['id']);
365 $params = array(
366 'contact_id' => $this->_contactID,
d54576ed 367 'membership_id' => $this->_membershipID,
6a488035
TO
368 'return' => 'membership_id',
369 );
771f3245 370 $result = $this->callAPISuccess('membership', 'get', $params);
6a488035 371 $this->assertEquals($membershipID, $result['id']);
6a488035
TO
372 }
373
374 /**
375 * Test civicrm_membership_get for only active.
376 * Memberships expected.
377 */
00be9182 378 public function testGetOnlyActive() {
5c49fee0 379 $description = "Demonstrates use of 'filter' active_only' param.";
6a488035 380 $this->_membershipID = $this->contactMembershipCreate($this->_params);
5896d037 381 $params = array(
6a488035
TO
382 'contact_id' => $this->_contactID,
383 'active_only' => 1,
6a488035
TO
384 );
385
771f3245 386 $membership = $this->callAPISuccess('membership', 'get', $params);
a73daeff
E
387 $this->assertEquals($membership['values'][$this->_membershipID]['status_id'], $this->_membershipStatusID);
388 $this->assertEquals($membership['values'][$this->_membershipID]['contact_id'], $this->_contactID);
6a488035
TO
389 $params = array(
390 'contact_id' => $this->_contactID,
391 'filters' => array(
392 'is_current' => 1,
393 ),
6a488035
TO
394 );
395
a828d7b8 396 $membership = $this->callAPIAndDocument('membership', 'get', $params, __FUNCTION__, __FILE__, $description, 'FilterIsCurrent');
a73daeff
E
397 $this->assertEquals($membership['values'][$this->_membershipID]['status_id'], $this->_membershipStatusID);
398 $this->assertEquals($membership['values'][$this->_membershipID]['contact_id'], $this->_contactID);
6a488035 399
6c6e6187 400 $this->callAPISuccess('Membership', 'Delete', array('id' => $this->_membershipID));
6a488035
TO
401 }
402
403 /**
404 * Test civicrm_membership_get for non exist contact.
405 * empty Memberships.
406 */
00be9182 407 public function testGetNoContactExists() {
6a488035
TO
408 $params = array(
409 'contact_id' => 55555,
6a488035
TO
410 );
411
771f3245 412 $membership = $this->callAPISuccess('membership', 'get', $params);
80d714d2 413 $this->assertEquals($membership['count'], 0);
6a488035
TO
414 }
415
416 /**
417 * Test civicrm_membership_get with relationship.
418 * get Memberships.
419 */
00be9182 420 public function testGetWithRelationship() {
6a488035 421 $membershipOrgId = $this->organizationCreate(NULL);
e4d5f1e2 422 $memberContactId = $this->individualCreate();
6a488035
TO
423
424 $relTypeParams = array(
425 'name_a_b' => 'Relation 1',
426 'name_b_a' => 'Relation 2',
427 'description' => 'Testing relationship type',
428 'contact_type_a' => 'Organization',
429 'contact_type_b' => 'Individual',
430 'is_reserved' => 1,
431 'is_active' => 1,
6a488035
TO
432 );
433 $relTypeID = $this->relationshipTypeCreate($relTypeParams);
434
435 $params = array(
436 'name' => 'test General',
437 'duration_unit' => 'year',
438 'duration_interval' => 1,
439 'period_type' => 'rolling',
440 'member_of_contact_id' => $membershipOrgId,
441 'domain_id' => 1,
5896d037 442 'financial_type_id' => 1,
6a488035
TO
443 'relationship_type_id' => $relTypeID,
444 'relationship_direction' => 'b_a',
445 'is_active' => 1,
6a488035 446 );
771f3245 447 $memType = $this->callAPISuccess('membership_type', 'create', $params);
6a488035
TO
448
449 $params = array(
450 'contact_id' => $memberContactId,
451 'membership_type_id' => $memType['id'],
452 'join_date' => '2009-01-21',
453 'start_date' => '2009-01-21',
454 'end_date' => '2009-12-21',
455 'source' => 'Payment',
456 'is_override' => 1,
457 'status_id' => $this->_membershipStatusID,
6a488035
TO
458 );
459 $membershipID = $this->contactMembershipCreate($params);
460
461 $params = array(
462 'contact_id' => $memberContactId,
463 'membership_type_id' => $memType['id'],
6a488035
TO
464 );
465
771f3245 466 $result = $this->callAPISuccess('membership', 'get', $params);
6a488035
TO
467
468 $membership = $result['values'][$membershipID];
771f3245 469 $this->assertEquals($this->_membershipStatusID, $membership['status_id']);
d54576ed 470 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 471 'id' => $membership['id'],
5896d037 472 ));
6a488035
TO
473 $this->membershipTypeDelete(array('id' => $memType['id']));
474 $this->relationshipTypeDelete($relTypeID);
475 $this->contactDelete($membershipOrgId);
476 $this->contactDelete($memberContactId);
477 }
478
4cc99d00 479 /**
480 * Test civicrm_membership_create with relationships.
481 * create/get Memberships.
482 *
483 * Test suite for CRM-14758: API ( contact, create ) does not always create related membership
484 * and max_related property for Membership_Type and Membership entities
485 */
00be9182 486 public function testCreateWithRelationship() {
4cc99d00 487 // Create membership type: inherited through employment, max_related = 2
488 $params = array(
489 'name_a_b' => 'Employee of',
490 );
491 $result = $this->callAPISuccess('relationship_type', 'get', $params);
492 $relationshipTypeId = $result['id'];
493 $membershipOrgId = $this->organizationCreate();
494 $params = array(
495 'name' => 'Corporate Membership',
496 'duration_unit' => 'year',
497 'duration_interval' => 1,
498 'period_type' => 'rolling',
499 'member_of_contact_id' => $membershipOrgId,
500 'domain_id' => 1,
501 'financial_type_id' => 1,
502 'relationship_type_id' => $relationshipTypeId,
503 'relationship_direction' => 'b_a',
504 'max_related' => 2,
505 'is_active' => 1,
506 );
507 $result = $this->callAPISuccess('membership_type', 'create', $params);
508 $membershipTypeId = $result['id'];
509
510 // Create employer and first employee
511 $employerId[0] = $this->organizationCreate(array(), 1);
512 $memberContactId[0] = $this->individualCreate(array('employer_id' => $employerId[0]), 0);
513
514 // Create organization's membership
515 $params = array(
516 'contact_id' => $employerId[0],
517 'membership_type_id' => $membershipTypeId,
518 'source' => 'Test suite',
519 'start_date' => date('Y-m-d'),
520 'end_date' => "+1 year",
521 );
522 $OrganizationMembershipID = $this->contactMembershipCreate($params);
523
524 // Check that the employee inherited the membership
525 $params = array(
526 'contact_id' => $memberContactId[0],
527 'membership_type_id' => $membershipTypeId,
528 );
529
530 $result = $this->callAPISuccess('membership', 'get', $params);
531
532 $this->assertEquals(1, $result['count']);
533 $result = $result['values'][$result['id']];
534 $this->assertEquals($OrganizationMembershipID, $result['owner_membership_id']);
535
536 // Create second employee
537 $memberContactId[1] = $this->individualCreate(array('employer_id' => $employerId[0]), 1);
538
539 // Check that the employee inherited the membership
540 $params = array(
541 'contact_id' => $memberContactId[1],
542 'membership_type_id' => $membershipTypeId,
543 );
544 $result = $this->callAPISuccess('membership', 'get', $params);
4cc99d00 545 // If it fails here CRM-14758 is not fixed
546 $this->assertEquals(1, $result['count']);
547 $result = $result['values'][$result['id']];
548 $this->assertEquals($OrganizationMembershipID, $result['owner_membership_id']);
549
550 // Create third employee
932a6904 551 $memberContactId[2] = $this->individualCreate(array('employer_id' => $employerId[0]), 2);
4cc99d00 552
553 // Check that employee does NOT inherit the membership (max_related = 2)
554 $params = array(
555 'contact_id' => $memberContactId[2],
556 'membership_type_id' => $membershipTypeId,
557 );
558 $result = $this->callAPISuccess('membership', 'get', $params);
559 $this->assertEquals(0, $result['count']);
560
561 // Increase max_related for the employer's membership
562 $params = array(
563 'id' => $OrganizationMembershipID,
564 'max_related' => 3,
565 );
5d8b37be 566 $this->callAPISuccess('Membership', 'create', $params);
4cc99d00 567
568 // Check that the employee inherited the membership
569 $params = array(
570 'contact_id' => $memberContactId[2],
571 'membership_type_id' => $membershipTypeId,
572 );
573 $result = $this->callAPISuccess('membership', 'get', $params);
574 $this->assertEquals(1, $result['count']);
575 $result = $result['values'][$result['id']];
576 $this->assertEquals($OrganizationMembershipID, $result['owner_membership_id']);
577
578 // First employee moves to a new job
579 $employerId[1] = $this->organizationCreate(array(), 2);
580 $params = array(
581 'id' => $memberContactId[0],
582 'employer_id' => $employerId[1],
583 );
584 $this->callAPISuccess('contact', 'create', $params);
585
586 // Check that employee does NO LONGER inherit the membership
587 $params = array(
588 'contact_id' => $memberContactId[0],
589 'membership_type_id' => $membershipTypeId,
590 );
591 $result = $this->callAPISuccess('membership', 'get', $params);
592 $this->assertEquals(0, $result['count']);
593
4a009ccf
CW
594 // Set up params for enable/disable checks
595 $relationship1 = $this->callAPISuccess('relationship', 'get', array('contact_id_a' => $memberContactId[1]));
596 $params = array(
597 'contact_id' => $memberContactId[1],
598 'membership_type_id' => $membershipTypeId,
599 );
600
601 // Deactivate relationship using create and assert membership is not inherited
602 $this->callAPISuccess('relationship', 'create', array('id' => $relationship1['id'], 'is_active' => 0));
603 $result = $this->callAPISuccess('membership', 'get', $params);
604 $this->assertEquals(0, $result['count']);
605
606 // Re-enable relationship using create and assert membership is inherited
607 $this->callAPISuccess('relationship', 'create', array('id' => $relationship1['id'], 'is_active' => 1));
608 $result = $this->callAPISuccess('membership', 'get', $params);
609 $this->assertEquals(1, $result['count']);
610
611 // Deactivate relationship using setvalue and assert membership is not inherited
612 $this->callAPISuccess('relationship', 'setvalue', array('id' => $relationship1['id'], 'field' => 'is_active', 'value' => 0));
613 $result = $this->callAPISuccess('membership', 'get', $params);
614 $this->assertEquals(0, $result['count']);
615
616 // Re-enable relationship using setvalue and assert membership is inherited
617 $this->callAPISuccess('relationship', 'setvalue', array('id' => $relationship1['id'], 'field' => 'is_active', 'value' => 1));
618 $result = $this->callAPISuccess('membership', 'get', $params);
619 $this->assertEquals(1, $result['count']);
620
1b5fad8a
CW
621 // Delete relationship and assert membership is not inherited
622 $this->callAPISuccess('relationship', 'delete', array('id' => $relationship1['id']));
623 $result = $this->callAPISuccess('membership', 'get', $params);
624 $this->assertEquals(0, $result['count']);
625
4cc99d00 626 // Tear down - reverse of creation to be safe
627 $this->contactDelete($memberContactId[2]);
628 $this->contactDelete($memberContactId[1]);
629 $this->contactDelete($memberContactId[0]);
630 $this->contactDelete($employerId[1]);
631 $this->contactDelete($employerId[0]);
632 $this->membershipTypeDelete(array('id' => $membershipTypeId));
633 $this->contactDelete($membershipOrgId);
634 }
635
37eda84b 636 /**
0298287b 637 * We are checking for no e-notices + only id & end_date returned
37eda84b 638 */
00be9182 639 public function testMembershipGetWithReturn() {
d54576ed 640 $this->contactMembershipCreate($this->_params);
37eda84b 641 $result = $this->callAPISuccess('membership', 'get', array('return' => 'end_date'));
6c6e6187 642 foreach ($result['values'] as $membership) {
0248c335 643 $this->assertEquals(array('id', 'end_date'), array_keys($membership));
37eda84b 644 }
645 }
6a488035
TO
646 ///////////////// civicrm_membership_create methods
647
648 /**
649 * Test civicrm_contact_memberships_create with empty params.
650 * Error expected.
651 */
00be9182 652 public function testCreateWithEmptyParams() {
6a488035 653 $params = array();
d54576ed 654 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
655 }
656
657 /**
fe482240 658 * If is_overide is passed in status must also be passed in.
6a488035 659 */
00be9182 660 public function testCreateOverrideNoStatus() {
6a488035
TO
661 $params = $this->_params;
662 unset($params['status_id']);
d54576ed 663 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
664 }
665
00be9182 666 public function testMembershipCreateMissingRequired() {
6a488035
TO
667 $params = array(
668 'membership_type_id' => '1',
669 'join_date' => '2006-01-21',
670 'start_date' => '2006-01-21',
671 'end_date' => '2006-12-21',
672 'source' => 'Payment',
673 'status_id' => '2',
6a488035
TO
674 );
675
d54576ed 676 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
677 }
678
00be9182 679 public function testMembershipCreate() {
6a488035
TO
680 $params = array(
681 'contact_id' => $this->_contactID,
682 'membership_type_id' => $this->_membershipTypeID,
683 'join_date' => '2006-01-21',
684 'start_date' => '2006-01-21',
685 'end_date' => '2006-12-21',
686 'source' => 'Payment',
687 'is_override' => 1,
688 'status_id' => $this->_membershipStatusID,
6a488035
TO
689 );
690
771f3245 691 $result = $this->callAPIAndDocument('membership', 'create', $params, __FUNCTION__, __FILE__);
6a488035 692 $this->getAndCheck($params, $result['id'], $this->_entity);
6a488035
TO
693 $this->assertNotNull($result['id']);
694 $this->assertEquals($this->_contactID, $result['values'][$result['id']]['contact_id'], " in line " . __LINE__);
695 $this->assertEquals($result['id'], $result['values'][$result['id']]['id'], " in line " . __LINE__);
696 }
5896d037 697
28a04ea9 698 /**
699 * Check for useful message if contact doesn't exist
700 */
00be9182 701 public function testMembershipCreateWithInvalidContact() {
6a488035
TO
702 $params = array(
703 'contact_id' => 999,
704 'membership_type_id' => $this->_membershipTypeID,
705 'join_date' => '2006-01-21',
706 'start_date' => '2006-01-21',
707 'end_date' => '2006-12-21',
708 'source' => 'Payment',
709 'is_override' => 1,
710 'status_id' => $this->_membershipStatusID,
6a488035
TO
711 );
712
d54576ed 713 $this->callAPIFailure('membership', 'create', $params,
771f3245 714 'contact_id is not valid : 999'
715 );
6a488035 716 }
5896d037 717
00be9182 718 public function testMembershipCreateWithInvalidStatus() {
6a488035
TO
719 $params = $this->_params;
720 $params['status_id'] = 999;
d54576ed 721 $this->callAPIFailure('membership', 'create', $params,
771f3245 722 "'999' is not a valid option for field status_id"
723 );
6a488035
TO
724 }
725
00be9182 726 public function testMembershipCreateWithInvalidType() {
6a488035
TO
727 $params = $this->_params;
728 $params['membership_type_id'] = 999;
729
d54576ed 730 $this->callAPIFailure('membership', 'create', $params,
771f3245 731 "'999' is not a valid option for field membership_type_id"
732 );
6a488035
TO
733 }
734
735 /**
100fef9d 736 * Check with complete array + custom field
6a488035
TO
737 * Note that the test is written on purpose without any
738 * variables specific to participant so it can be replicated into other entities
739 * and / or moved to the automated test suite
740 */
00be9182 741 public function testCreateWithCustom() {
6a488035
TO
742 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
743
744 $params = $this->_params;
745 $params['custom_' . $ids['custom_field_id']] = "custom string";
746
a828d7b8 747 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, NULL, 'CreateWithCustomData');
5896d037
TO
748 $check = $this->callAPISuccess($this->_entity, 'get', array(
749 'id' => $result['id'],
21dfd5f5 750 'contact_id' => $this->_contactID,
5896d037 751 ));
6a488035 752 $this->assertEquals("custom string", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
6a488035
TO
753 }
754
22e97101
JV
755 /**
756 * Search on custom field value.
757 */
758 public function testSearchWithCustomDataCRM16036() {
759 // Create a custom field on membership
760 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
761
762 // Create a new membership, but don't assign anything to the custom field.
763 $params = $this->_params;
764 $result = $this->callAPIAndDocument(
765 $this->_entity,
766 'create',
767 $params,
768 __FUNCTION__,
769 __FILE__,
770 NULL,
771 'SearchWithCustomData');
772
773 // search memberships with CRM-16036 as custom field value.
774 // Since we did not touch the custom field of any membership,
775 // this should not return any results.
776 $check = $this->callAPISuccess($this->_entity, 'get', array(
777 'custom_' . $ids['custom_field_id'] => "CRM-16036",
778 ));
779
780 // Cleanup.
781 $this->callAPISuccess($this->_entity, 'delete', array(
782 'id' => $result['id'],
783 ));
784
785 // Assert.
786 $this->assertEquals(0, $check['count']);
787 }
788
6a488035
TO
789 /**
790 * Test civicrm_contact_memberships_create with membership id (edit
791 * membership).
792 * success expected.
793 */
00be9182 794 public function testMembershipCreateWithId() {
6a488035
TO
795 $membershipID = $this->contactMembershipCreate($this->_params);
796 $params = array(
797 'id' => $membershipID,
798 'contact_id' => $this->_contactID,
799 'membership_type_id' => $this->_membershipTypeID,
800 'join_date' => '2006-01-21',
801 'start_date' => '2006-01-21',
802 'end_date' => '2006-12-21',
803 'source' => 'Payment',
804 'is_override' => 1,
805 'status_id' => $this->_membershipStatusID,
6a488035
TO
806 );
807
771f3245 808 $result = $this->callAPISuccess('membership', 'create', $params);
809 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 810 'id' => $result['id'],
771f3245 811 ));
6a488035
TO
812 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
813 }
814
815 /**
816 * Test civicrm_contact_memberships_create with membership id (edit
817 * membership).
818 * success expected.
819 */
00be9182 820 public function testMembershipCreateUpdateWithIdNoContact() {
6a488035
TO
821 $membershipID = $this->contactMembershipCreate($this->_params);
822 $params = array(
823 'id' => $membershipID,
824 'membership_type_id' => $this->_membershipTypeID,
825 'contact_id' => $this->_contactID,
826 'join_date' => '2006-01-21',
827 'start_date' => '2006-01-21',
828 'end_date' => '2006-12-21',
829 'source' => 'Payment',
830 'is_override' => 1,
831 'status_id' => $this->_membershipStatusID,
6a488035
TO
832 );
833
771f3245 834 $result = $this->callAPISuccess('membership', 'create', $params);
835 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 836 'id' => $result['id'],
5896d037 837 ));
771f3245 838
6a488035
TO
839 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
840 }
841
842 /**
843 * Test civicrm_contact_memberships_create with membership id (edit
844 * membership).
845 * success expected.
846 */
00be9182 847 public function testMembershipCreateUpdateWithIdNoDates() {
6a488035
TO
848 $membershipID = $this->contactMembershipCreate($this->_params);
849 $params = array(
850 'id' => $membershipID,
851 'contact_id' => $this->_contactID,
852 'membership_type_id' => $this->_membershipTypeID,
853 'source' => 'Payment',
854 'is_override' => 1,
855 'status_id' => $this->_membershipStatusID,
6a488035
TO
856 );
857
771f3245 858 $result = $this->callAPISuccess('membership', 'create', $params);
859 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 860 'id' => $result['id'],
5896d037 861 ));
6a488035
TO
862 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
863 }
864
865 /**
866 * Test civicrm_contact_memberships_create with membership id (edit
867 * membership).
868 * success expected.
869 */
00be9182 870 public function testMembershipCreateUpdateWithIdNoDatesNoType() {
6a488035
TO
871 $membershipID = $this->contactMembershipCreate($this->_params);
872 $params = array(
873 'id' => $membershipID,
874 'source' => 'not much here',
875 'contact_id' => $this->_contactID,
876 'is_override' => 1,
877 'status_id' => $this->_membershipStatusID,
6a488035
TO
878 );
879
771f3245 880 $result = $this->callAPISuccess('membership', 'create', $params);
881 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 882 'id' => $result['id'],
771f3245 883 ));
6a488035
TO
884 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
885 }
886
887 /**
888 * Test civicrm_contact_memberships_create with membership id (edit
889 * membership).
890 * success expected.
891 */
00be9182 892 public function testMembershipCreateUpdateWithIDAndSource() {
6a488035
TO
893 $membershipID = $this->contactMembershipCreate($this->_params);
894 $params = array(
895 'id' => $membershipID,
896 'source' => 'changed',
897 'contact_id' => $this->_contactID,
6c6e6187 898 'status_id' => $this->_membershipStatusID,
5896d037 899 'membership_type_id' => $this->_membershipTypeID,
6a488035
TO
900 'skipStatusCal' => 1,
901 );
771f3245 902 $result = $this->callAPISuccess('membership', 'create', $params);
6a488035 903 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
771f3245 904 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 905 'id' => $result['id'],
5896d037 906 ));
6a488035
TO
907 }
908
909 /**
eceb18cc 910 * Change custom field using update.
6a488035 911 */
00be9182 912 public function testUpdateWithCustom() {
6a488035
TO
913 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
914
915 $params = $this->_params;
916 $params['custom_' . $ids['custom_field_id']] = "custom string";
a828d7b8 917 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, NULL, 'UpdateCustomData');
5896d037
TO
918 $result = $this->callAPISuccess($this->_entity, 'create', array(
919 'id' => $result['id'],
21dfd5f5 920 'custom_' . $ids['custom_field_id'] => "new custom",
5896d037
TO
921 ));
922 $check = $this->callAPISuccess($this->_entity, 'get', array(
923 'id' => $result['id'],
21dfd5f5 924 'contact_id' => $this->_contactID,
5896d037 925 ));
6a488035
TO
926
927 $this->assertEquals("new custom", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
d54576ed 928 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 929 'id' => $check['id'],
5896d037 930 ));
6a488035
TO
931
932 $this->customFieldDelete($ids['custom_field_id']);
933 $this->customGroupDelete($ids['custom_group_id']);
934 }
935
93c482a4
EM
936 /**
937 * per CRM-15746 check that the id can be altered in an update hook
938 */
28a04ea9 939 public function testMembershipUpdateCreateHookCRM15746() {
93c482a4
EM
940 $this->hookClass->setHook('civicrm_pre', array($this, 'hook_civicrm_pre_update_create_membership'));
941 $result = $this->callAPISuccess('membership', 'create', $this->_params);
942 $this->callAPISuccess('membership', 'create', array('id' => $result['id'], 'end_date' => '1 year ago'));
943 $this->callAPISuccessGetCount('membership', array(), 2);
944 $this->hookClass->reset();
945 $this->callAPISuccess('membership', 'create', array('id' => $result['id'], 'end_date' => '1 year ago'));
946 $this->callAPISuccessGetCount('membership', array(), 2);
947 }
948
2ea0abec
EM
949 /**
950 * Custom hook for update membership.
951 *
952 * @param string $op
953 * @param object $objectName
954 * @param int $id
955 * @param array $params
956 *
957 * @throws \Exception
958 */
28a04ea9 959 public function hook_civicrm_pre_update_create_membership($op, $objectName, $id, &$params) {
93c482a4
EM
960 if ($objectName == 'Membership' && $op == 'edit') {
961 $existingMembership = $this->callAPISuccessGetSingle('membership', array('id' => $params['id']));
962 unset($params['id'], $params['membership_id']);
6c6e6187 963 $params['join_date'] = $params['membership_start_date'] = $params['start_date'] = date('Ymd000000', strtotime($existingMembership['start_date']));
93c482a4
EM
964 $params = array_merge($existingMembership, $params);
965 $params['id'] = NULL;
966 }
967 }
968
6a488035 969 /**
fe482240 970 * Test civicrm_contact_memberships_create Invalid membership data.
6a488035
TO
971 * Error expected.
972 */
00be9182 973 public function testMembershipCreateInvalidMemData() {
6a488035
TO
974 //membership_contact_id as string
975 $params = array(
976 'membership_contact_id' => 'Invalid',
977 'membership_type_id' => $this->_membershipTypeID,
978 'join_date' => '2011-01-21',
979 'start_date' => '2010-01-21',
980 'end_date' => '2008-12-21',
981 'source' => 'Payment',
982 'is_override' => 1,
5896d037
TO
983 'status_id' => $this->_membershipStatusID,
984 );
6a488035 985
d54576ed 986 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
987
988 //membership_contact_id which is no in contact table
989 $params['membership_contact_id'] = 999;
d54576ed 990 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
991
992 //invalid join date
993 unset($params['membership_contact_id']);
994 $params['join_date'] = "invalid";
d54576ed 995 $this->callAPIFailure('Membership', 'Create', $params);
6a488035
TO
996 }
997
998 /**
999 * Test civicrm_contact_memberships_create with membership_contact_id
1000 * membership).
1001 * Success expected.
1002 */
00be9182 1003 public function testMembershipCreateWithMemContact() {
6a488035
TO
1004 $params = array(
1005 'membership_contact_id' => $this->_contactID,
1006 'membership_type_id' => $this->_membershipTypeID,
1007 'join_date' => '2011-01-21',
1008 'start_date' => '2010-01-21',
1009 'end_date' => '2008-12-21',
1010 'source' => 'Payment',
1011 'is_override' => 1,
1012 'status_id' => $this->_membershipStatusID,
6a488035
TO
1013 );
1014
771f3245 1015 $result = $this->callAPISuccess('membership', 'create', $params);
6a488035 1016
d54576ed 1017 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 1018 'id' => $result['id'],
771f3245 1019 ));
6a488035 1020 }
5896d037 1021
cc73900e 1022 /**
1023 * Test civicrm_contact_memberships_create with membership_contact_id
1024 * membership).
1025 * Success expected.
1026 */
00be9182 1027 public function testMembershipCreateValidMembershipTypeString() {
cc73900e 1028 $params = array(
1029 'membership_contact_id' => $this->_contactID,
1030 'membership_type_id' => 'General',
1031 'join_date' => '2011-01-21',
1032 'start_date' => '2010-01-21',
1033 'end_date' => '2008-12-21',
1034 'source' => 'Payment',
1035 'is_override' => 1,
1036 'status_id' => $this->_membershipStatusID,
1037 );
1038
1039 $result = $this->callAPISuccess('membership', 'create', $params);
1040 $this->assertEquals($this->_membershipTypeID, $result['values'][$result['id']]['membership_type_id']);
d54576ed 1041 $this->callAPISuccess('Membership', 'Delete', array(
cc73900e 1042 'id' => $result['id'],
1043 ));
1044 }
1045
1046 /**
1047 * Test civicrm_contact_memberships_create with membership_contact_id
1048 * membership).
1049 * Success expected.
1050 */
00be9182 1051 public function testMembershipCreateInValidMembershipTypeString() {
cc73900e 1052 $params = array(
1053 'membership_contact_id' => $this->_contactID,
1054 'membership_type_id' => 'invalid',
1055 'join_date' => '2011-01-21',
1056 'start_date' => '2010-01-21',
1057 'end_date' => '2008-12-21',
1058 'source' => 'Payment',
1059 'is_override' => 1,
1060 'status_id' => $this->_membershipStatusID,
1061 );
1062
d54576ed 1063 $this->callAPIFailure('membership', 'create', $params);
cc73900e 1064 }
6a488035 1065
cc73900e 1066 /**
eceb18cc 1067 * Test that if membership join date is not set it defaults to today.
cc73900e 1068 */
00be9182 1069 public function testEmptyJoinDate() {
8c33a68c 1070 unset($this->_params['join_date'], $this->_params['is_override']);
1071 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1072 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1073 $this->assertEquals(date('Y-m-d', strtotime('now')), $result['join_date']);
1074 $this->assertEquals('2009-01-21', $result['start_date']);
1075 $this->assertEquals('2009-12-21', $result['end_date']);
cc73900e 1076 }
5896d037 1077
cc73900e 1078 /**
fe482240 1079 * Test that if membership start date is not set it defaults to correct end date.
8c33a68c 1080 * - fixed
cc73900e 1081 */
00be9182 1082 public function testEmptyStartDateFixed() {
8c33a68c 1083 unset($this->_params['start_date'], $this->_params['is_override']);
1084 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1085 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1086 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1087 $this->assertEquals('2009-01-21', $result['join_date']);
1088 $this->assertEquals('2008-03-01', $result['start_date']);
1089 $this->assertEquals('2009-12-21', $result['end_date']);
1090 }
cc73900e 1091
8c33a68c 1092 /**
1093 * Test that if membership start date is not set it defaults to correct end date
1094 * - fixed
1095 */
2ea0abec
EM
1096 public function testEmptyStartEndDateFixedOneYear() {
1097 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1098 $this->callAPISuccess('membership_type', 'create', array('id' => $this->_membershipTypeID2, 'duration_interval' => 1));
1099 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1100 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1101 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1102 $this->assertEquals('2009-01-21', $result['join_date']);
1103 $this->assertEquals('2008-03-01', $result['start_date']);
1104 $this->assertEquals('2010-02-28', $result['end_date']);
1105 }
1106
1107 /**
9398f167
EM
1108 * Test that if membership start date is not set it defaults to correct end date for fixed multi year memberships.
1109 */
1110 public function testEmptyStartEndDateFixedMultiYear() {
1111 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1112 $this->callAPISuccess('membership_type', 'create', array('id' => $this->_membershipTypeID2, 'duration_interval' => 5));
1113 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1114 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1115 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1116 $this->assertEquals('2009-01-21', $result['join_date']);
1117 $this->assertEquals('2008-03-01', $result['start_date']);
1118 $this->assertEquals('2014-02-28', $result['end_date']);
1119 }
1120
41dcb974 1121 /**
1122 * CRM-18503 - Test membership join date is correctly set for fixed memberships.
1123 */
1124 public function testMembershipJoinDateFixed() {
1125 $memStatus = CRM_Member_PseudoConstant::membershipStatus();
1126 // Update the fixed membership type to 1 year duration.
1127 $this->callAPISuccess('membership_type', 'create', array('id' => $this->_membershipTypeID2, 'duration_interval' => 1));
1128 $contactId = $this->createLoggedInUser();
1129 // Create membership with 'Pending' status.
1130 $params = array(
1131 'contact_id' => $contactId,
1132 'membership_type_id' => $this->_membershipTypeID2,
1133 'source' => 'test membership',
1134 'is_pay_later' => 0,
1135 'status_id' => array_search('Pending', $memStatus),
1136 'skipStatusCal' => 1,
1137 'is_for_organization' => 1,
1138 );
1139 $ids = array();
1140 $membership = CRM_Member_BAO_Membership::create($params, $ids);
1141
1142 // Update membership to 'Completed' and check the dates.
1143 $memParams = array(
1144 'id' => $membership->id,
1145 'contact_id' => $contactId,
1146 'is_test' => 0,
1147 'membership_type_id' => $this->_membershipTypeID2,
1148 'num_terms' => 1,
1149 'status_id' => array_search('New', $memStatus),
1150 );
1151 $result = $this->callAPISuccess('Membership', 'create', $memParams);
1152
70a87708 1153 // Extend duration interval if join_date exceeds the rollover period.
1154 $joinDate = date('Y-m-d');
1155 $year = date('Y');
1156 $startDate = date('Y-m-d', strtotime(date('Y-03-01')));
581eb285 1157 $rollOver = TRUE;
1158 if (strtotime($startDate) > time()) {
1159 $rollOver = FALSE;
1160 $startDate = date('Y-m-d', strtotime(date('Y-03-01') . '- 1 year'));
1161 }
70a87708 1162 $membershipTypeDetails = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($this->_membershipTypeID2);
1163 $fixedPeriodRollover = CRM_Member_BAO_MembershipType::isDuringFixedAnnualRolloverPeriod($joinDate, $membershipTypeDetails, $year, $startDate);
1164 $y = 1;
581eb285 1165 if ($fixedPeriodRollover && $rollOver) {
70a87708 1166 $y += 1;
1167 }
1168
41dcb974 1169 $expectedDates = array(
1170 'join_date' => date('Ymd'),
70a87708 1171 'start_date' => str_replace('-', '', $startDate),
1172 'end_date' => date('Ymd', strtotime(date('Y-03-01') . "+ {$y} year - 1 day")),
41dcb974 1173 );
1174 foreach ($result['values'] as $values) {
1175 foreach ($expectedDates as $date => $val) {
70a87708 1176 $this->assertEquals($val, $values[$date], "Failed asserting {$date} values");
41dcb974 1177 }
1178 }
1179 }
1180
b1fc74f0 1181 /**
964a9e96
EM
1182 * Test correct end and start dates are calculated for fixed multi year memberships.
1183 *
1184 * The empty start date is calculated to be the start_date (1 Jan prior to the join_date - so 1 Jan 15)
1185 *
1186 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1187 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1188 * and we add on 4 years rather than 5 because we are not after the rollover day - so we calculate 31 Dec 2019
1189 */
1190 public function testFixedMultiYearDateSetTwoEmptyStartEndDate() {
1191 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1192
1193 $this->callAPISuccess('membership_type', 'create', array(
1194 'id' => $this->_membershipTypeID2,
1195 'duration_interval' => 5,
1196 // Ie 1 Jan.
1197 'fixed_period_start_day' => '101',
1198 // Ie. 1 Nov.
1199 'fixed_period_rollover_day' => '1101',
1200 ));
1201 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1202 $dates = array(
1203 'join_date' => '28-Jan 2015',
1204 );
1205 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1206 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1207 $this->assertEquals('2015-01-28', $result['join_date']);
1208 $this->assertEquals('2015-01-01', $result['start_date']);
1209 $this->assertEquals('2019-12-31', $result['end_date']);
1210 }
1211
1212 /**
1213 * Test that correct end date is calculated for fixed multi year memberships and start date is not changed.
b1fc74f0
EM
1214 *
1215 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1216 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1217 * and we add on 4 years rather than 5 because we are not after the rollover day - so we calculate 31 Dec 2019
1218 */
964a9e96 1219 public function testFixedMultiYearDateSetTwoEmptyEndDate() {
b1fc74f0
EM
1220 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1221
1222 $this->callAPISuccess('membership_type', 'create', array(
1223 'id' => $this->_membershipTypeID2,
1224 'duration_interval' => 5,
1225 // Ie 1 Jan.
1226 'fixed_period_start_day' => '101',
1227 // Ie. 1 Nov.
1228 'fixed_period_rollover_day' => '1101',
1229 ));
1230 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1231 $dates = array(
1232 'start_date' => '28-Jan 2015',
1233 'join_date' => '28-Jan 2015',
1234 );
1235 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1236 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1237 $this->assertEquals('2015-01-28', $result['join_date']);
1238 $this->assertEquals('2015-01-28', $result['start_date']);
1239 $this->assertEquals('2019-12-31', $result['end_date']);
1240 }
1241
1242 /**
964a9e96
EM
1243 * Test correct end and start dates are calculated for fixed multi year memberships.
1244 *
1245 * The empty start date is calculated to be the start_date (1 Jan prior to the join_date - so 1 Jan 15)
1246 *
1247 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1248 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1249 * and we add on <1 years rather than > 1 because we are not after the rollover day - so we calculate 31 Dec 2015
1250 */
1251 public function testFixedSingleYearDateSetTwoEmptyStartEndDate() {
1252 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1253
1254 $this->callAPISuccess('membership_type', 'create', array(
1255 'id' => $this->_membershipTypeID2,
1256 'duration_interval' => 1,
1257 // Ie 1 Jan.
1258 'fixed_period_start_day' => '101',
1259 // Ie. 1 Nov.
1260 'fixed_period_rollover_day' => '1101',
1261 ));
1262 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1263 $dates = array(
1264 'join_date' => '28-Jan 2015',
1265 );
1266 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1267 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1268 $this->assertEquals('2015-01-28', $result['join_date']);
1269 $this->assertEquals('2015-01-01', $result['start_date']);
1270 $this->assertEquals('2015-12-31', $result['end_date']);
1271 }
1272
1273 /**
1274 * Test correct end date for fixed single year memberships is calculated and start_date is not changed.
b1fc74f0
EM
1275 *
1276 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1277 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1278 * and we add on <1 years rather than > 1 because we are not after the rollover day - so we calculate 31 Dec 2015
1279 */
964a9e96 1280 public function testFixedSingleYearDateSetTwoEmptyEndDate() {
b1fc74f0
EM
1281 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1282
1283 $this->callAPISuccess('membership_type', 'create', array(
1284 'id' => $this->_membershipTypeID2,
1285 'duration_interval' => 1,
1286 // Ie 1 Jan.
1287 'fixed_period_start_day' => '101',
1288 // Ie. 1 Nov.
1289 'fixed_period_rollover_day' => '1101',
1290 ));
1291 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1292 $dates = array(
1293 'start_date' => '28-Jan 2015',
1294 'join_date' => '28-Jan 2015',
1295 );
1296 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1297 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1298 $this->assertEquals('2015-01-28', $result['join_date']);
1299 $this->assertEquals('2015-01-28', $result['start_date']);
1300 $this->assertEquals('2015-12-31', $result['end_date']);
1301 }
1302
1303 /**
964a9e96 1304 * Test that correct end date is calculated for fixed multi year memberships and start date is not changed.
b1fc74f0
EM
1305 *
1306 * In this set our start date is after the start day and after the rollover day so we do get an extra year
1307 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
964a9e96 1308 * and we add on 1 year we are after the rollover day - so we calculate 31 Oct 2016
b1fc74f0 1309 */
964a9e96 1310 public function testFixedSingleYearDateSetThreeEmptyEndDate() {
b1fc74f0
EM
1311 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1312
1313 $this->callAPISuccess('membership_type', 'create', array(
1314 'id' => $this->_membershipTypeID2,
1315 'duration_interval' => 1,
1316 // Ie. 1 Nov.
1317 'fixed_period_start_day' => '1101',
1318 // Ie 1 Jan.
1319 'fixed_period_rollover_day' => '101',
1320 ));
1321 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1322 $dates = array(
1323 'start_date' => '28-Jan 2015',
1324 'join_date' => '28-Jan 2015',
1325 );
1326 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1327 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1328 $this->assertEquals('2015-01-28', $result['join_date']);
1329 $this->assertEquals('2015-01-28', $result['start_date']);
1330 $this->assertEquals('2016-10-31', $result['end_date']);
1331 }
1332
964a9e96
EM
1333 /**
1334 * Test correct end and start dates are calculated for fixed multi year memberships.
1335 *
d177a2a6 1336 * The empty start date is calculated to be the start_date (1 Nov prior to the join_date - so 1 Nov 14)
964a9e96
EM
1337 *
1338 * In this set our start date is after the start day and after the rollover day so we do get an extra year
1339 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
1340 * and we add on 1 year we are after the rollover day - so we calculate 31 Oct 2016
1341 */
1342 public function testFixedSingleYearDateSetThreeEmptyStartEndDate() {
1343 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1344
1345 $this->callAPISuccess('membership_type', 'create', array(
1346 'id' => $this->_membershipTypeID2,
1347 'duration_interval' => 1,
1348 // Ie. 1 Nov.
1349 'fixed_period_start_day' => '1101',
1350 // Ie 1 Jan.
1351 'fixed_period_rollover_day' => '101',
1352 ));
1353 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1354 $dates = array(
1355 'join_date' => '28-Jan 2015',
1356 );
1357 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1358 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1359 $this->assertEquals('2015-01-28', $result['join_date']);
1360 $this->assertEquals('2014-11-01', $result['start_date']);
1361 $this->assertEquals('2016-10-31', $result['end_date']);
1362 }
b1fc74f0
EM
1363
1364 /**
964a9e96 1365 * Test that correct end date is calculated for fixed multi year memberships and start date is not changed.
b1fc74f0
EM
1366 *
1367 * In this set our start date is after the start day and after the rollover day so we do get an extra year
1368 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
1369 * and we add on 5 years we are after the rollover day - so we calculate 31 Oct 2020
1370 */
964a9e96 1371 public function testFixedMultiYearDateSetThreeEmptyEndDate() {
b1fc74f0
EM
1372 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1373
1374 $this->callAPISuccess('membership_type', 'create', array(
1375 'id' => $this->_membershipTypeID2,
1376 'duration_interval' => 5,
1377 // Ie. 1 Nov.
1378 'fixed_period_start_day' => '1101',
1379 // Ie 1 Jan.
1380 'fixed_period_rollover_day' => '101',
1381 ));
1382 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1383 $dates = array(
1384 'start_date' => '28-Jan 2015',
1385 'join_date' => '28-Jan 2015',
1386 );
1387 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1388 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1389 $this->assertEquals('2015-01-28', $result['join_date']);
1390 $this->assertEquals('2015-01-28', $result['start_date']);
1391 $this->assertEquals('2020-10-31', $result['end_date']);
1392 }
9398f167 1393
964a9e96
EM
1394 /**
1395 * Test correct end and start dates are calculated for fixed multi year memberships.
1396 *
d177a2a6 1397 * The empty start date is calculated to be the start_date (1 Nov prior to the join_date - so 1 Nov 14)
964a9e96
EM
1398 *
1399 * The empty start date is calculated to be the start_date (1 Nov prior to the join_date - so 1 Nov 14)
1400 * In this set our join date is after the start day and after the rollover day so we do get an extra year
1401 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
1402 * and we add on 5 years we are after the rollover day - so we calculate 31 Oct 2020
1403 */
1404 public function testFixedMultiYearDateSetThreeEmptyStartEndDate() {
1405 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1406
1407 $this->callAPISuccess('membership_type', 'create', array(
1408 'id' => $this->_membershipTypeID2,
1409 'duration_interval' => 5,
1410 // Ie. 1 Nov.
1411 'fixed_period_start_day' => '1101',
1412 // Ie 1 Jan.
1413 'fixed_period_rollover_day' => '101',
1414 ));
1415 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1416 $dates = array(
1417 'join_date' => '28-Jan 2015',
1418 );
1419 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1420 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1421 $this->assertEquals('2015-01-28', $result['join_date']);
1422 $this->assertEquals('2014-11-01', $result['start_date']);
1423 $this->assertEquals('2020-10-31', $result['end_date']);
1424 }
1425
9398f167
EM
1426 /**
1427 * Test that if membership start date is not set it defaults to correct end date for fixed single year memberships.
2ea0abec 1428 */
00be9182 1429 public function testEmptyStartDateRolling() {
8c33a68c 1430 unset($this->_params['start_date'], $this->_params['is_override']);
1431 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1432 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1433 $this->assertEquals('2009-01-21', $result['join_date']);
1434 $this->assertEquals('2009-01-21', $result['start_date']);
1435 $this->assertEquals('2009-12-21', $result['end_date']);
cc73900e 1436 }
5896d037 1437
8c33a68c 1438 /**
eceb18cc 1439 * Test that if membership end date is not set it defaults to correct end date.
8c33a68c 1440 * - rolling
1441 */
00be9182 1442 public function testEmptyEndDateFixed() {
8c33a68c 1443 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1444 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1445 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1446 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1447 $this->assertEquals('2009-01-21', $result['join_date']);
1448 $this->assertEquals('2008-03-01', $result['start_date']);
1449 $this->assertEquals('2010-02-28', $result['end_date']);
1450 }
5896d037 1451
8c33a68c 1452 /**
eceb18cc 1453 * Test that if membership end date is not set it defaults to correct end date.
8c33a68c 1454 * - rolling
1455 */
00be9182 1456 public function testEmptyEndDateRolling() {
8c33a68c 1457 unset($this->_params['is_override'], $this->_params['end_date']);
1458 $this->_params['membership_type_id'] = $this->_membershipTypeID;
1459 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1460 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1461 $this->assertEquals('2009-01-21', $result['join_date']);
1462 $this->assertEquals('2009-01-21', $result['start_date']);
1463 $this->assertEquals('2010-01-20', $result['end_date']);
1464 }
1465
1466
1467 /**
452b9e04 1468 * Test that if dates are set they not over-ridden if id is passed in
8c33a68c 1469 */
6c6e6187 1470 public function testMembershipDatesNotOverridden() {
8c33a68c 1471 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1472 unset($this->_params['end_date'], $this->_params['start_date']);
1473 $this->_params['id'] = $result['id'];
1474 $this->callAPISuccess($this->_entity, 'create', $this->_params);
1475 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1476 $this->assertEquals('2009-01-21', $result['join_date']);
1477 $this->assertEquals('2009-01-21', $result['start_date']);
1478 $this->assertEquals('2009-12-21', $result['end_date']);
1479
6c6e6187 1480 }
96025800 1481
8b3df6dc 1482 /**
1483 * Test that all membership types are returned when getoptions is called.
1484 *
1485 * This test locks in current behaviour where types for all domains are returned. It should possibly be domain
1486 * specific but that should only be done in conjunction with adding a hook to allow that to be altered as the
1487 * multisite use case expects the master domain to be able to see all sites.
1488 *
1489 * See CRM-17075.
1490 */
1491 public function testGetOptionsMembershipTypeID() {
1492 $options = $this->callAPISuccess('Membership', 'getoptions', array('field' => 'membership_type_id'));
5d8b37be 1493 $this->assertEquals('Another one', array_pop($options['values']));
8b3df6dc 1494 $this->assertEquals('General', array_pop($options['values']));
1495 $this->assertEquals(NULL, array_pop($options['values']));
1496 }
1497
6a488035 1498}