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