Merge pull request #9579 from omarabuhussein/CRM-19801-fix-relationship-saving
[civicrm-core.git] / tests / phpunit / api / v3 / MembershipTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2017 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 * Test APIv3 civicrm_membership functions
30 *
31 * @package CiviCRM_APIv3
32 * @subpackage API_Member
33 */
34
35 /**
36 * Class api_v3_MembershipTest
37 * @group headless
38 */
39 class api_v3_MembershipTest extends CiviUnitTestCase {
40 protected $_apiversion;
41 protected $_contactID;
42 protected $_membershipID;
43 protected $_membershipID2;
44 protected $_membershipID3;
45 protected $_membershipTypeID;
46 protected $_membershipTypeID2;
47 protected $_membershipStatusID;
48 protected $_entity;
49 protected $_params;
50
51 /**
52 * Set up for tests.
53 */
54 public function setUp() {
55 parent::setUp();
56 $this->_apiversion = 3;
57 $this->_contactID = $this->individualCreate();
58 $this->_membershipTypeID = $this->membershipTypeCreate(array('member_of_contact_id' => $this->_contactID));
59 $this->_membershipTypeID2 = $this->membershipTypeCreate(array(
60 'period_type' => 'fixed',
61 // Ie. 1 March.
62 'fixed_period_start_day' => '301',
63 // Ie. 11 Nov.
64 'fixed_period_rollover_day' => '1111',
65 'name' => 'Another one',
66 ));
67 $this->_membershipStatusID = $this->membershipStatusCreate('test status');
68
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,
83 );
84 }
85
86 /**
87 * Clean up after tests.
88 *
89 * @throws \Exception
90 */
91 public function tearDown() {
92 $this->quickCleanup(array(
93 'civicrm_membership',
94 'civicrm_membership_payment',
95 'civicrm_membership_log',
96 ),
97 TRUE
98 );
99 $this->membershipStatusDelete($this->_membershipStatusID);
100 $this->membershipTypeDelete(array('id' => $this->_membershipTypeID2));
101 $this->membershipTypeDelete(array('id' => $this->_membershipTypeID));
102 $this->contactDelete($this->_contactID);
103
104 }
105
106 /**
107 * Test membership deletion.
108 */
109 public function testMembershipDelete() {
110 $membershipID = $this->contactMembershipCreate($this->_params);
111 $this->assertDBRowExist('CRM_Member_DAO_Membership', $membershipID);
112 $params = array(
113 'id' => $membershipID,
114 );
115 $this->callAPIAndDocument('membership', 'delete', $params, __FUNCTION__, __FILE__);
116 $this->assertDBRowNotExist('CRM_Member_DAO_Membership', $membershipID);
117 }
118
119 public function testMembershipDeleteEmpty() {
120 $this->callAPIFailure('membership', 'delete', array());
121 }
122
123 public function testMembershipDeleteInvalidID() {
124 $this->callAPIFailure('membership', 'delete', array('id' => 'blah'));
125 }
126
127 /**
128 * Test civicrm_membership_delete() with invalid Membership Id.
129 */
130 public function testMembershipDeleteWithInvalidMembershipId() {
131 $membershipId = 'membership';
132 $this->callAPIFailure('membership', 'delete', $membershipId);
133 }
134
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
166 /**
167 * Test membership get.
168 */
169 public function testContactMembershipsGet() {
170 $this->_membershipID = $this->contactMembershipCreate($this->_params);
171 $this->callAPISuccess('membership', 'get', array());
172 $this->callAPISuccess('Membership', 'Delete', array('id' => $this->_membershipID));
173 }
174
175 /**
176 * Test civicrm_membership_get with params not array.
177 *
178 * Gets treated as contact_id, memberships expected.
179 */
180 public function testGetWithParamsContactId() {
181 $this->_membershipID = $this->contactMembershipCreate($this->_params);
182 $params = array(
183 'contact_id' => $this->_contactID,
184 );
185 $membership = $this->callAPISuccess('membership', 'get', $params);
186
187 $result = $membership['values'][$this->_membershipID];
188 $this->callAPISuccess('Membership', 'Delete', array(
189 'id' => $this->_membershipID,
190 ));
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
201 /**
202 * Test civicrm_membership_get with params not array.
203 *
204 * Gets treated as contact_id, memberships expected.
205 */
206 public function testGetInSyntax() {
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']));
222 }
223
224 /**
225 * Test civicrm_membership_get with params not array.
226 * Gets treated as contact_id, memberships expected.
227 */
228 public function testGetInSyntaxOnContactID() {
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 }
247
248 /**
249 * Test civicrm_membership_get with params not array.
250 *
251 * Gets treated as contact_id, memberships expected.
252 */
253 public function testGetWithParamsMemberShipTypeId() {
254 $this->callAPISuccess($this->_entity, 'create', $this->_params);
255 $params = array(
256 'membership_type_id' => $this->_membershipTypeID,
257 );
258 $membership = $this->callAPISuccess('membership', 'get', $params);
259 $this->callAPISuccess('Membership', 'Delete', array(
260 'id' => $membership['id'],
261 ));
262 $result = $membership['values'][$membership['id']];
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);
271 $this->assertEquals($result['id'], $membership['id']);
272 }
273
274 /**
275 * Test civicrm_membership_get with params not array.
276 * Gets treated as contact_id, memberships expected.
277 */
278 public function testGetWithParamsMemberShipTypeIdContactID() {
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);
291
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 }
300
301 /**
302 * Check with complete array + custom field.
303 *
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 */
308 public function testGetWithParamsMemberShipIdAndCustom() {
309 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
310
311 $params = $this->_params;
312 $params['custom_' . $ids['custom_field_id']] = "custom string";
313
314 $result = $this->callAPISuccess($this->_entity, 'create', $params);
315
316 $getParams = array('membership_type_id' => $params['membership_type_id']);
317 $check = $this->callAPIAndDocument($this->_entity, 'get', $getParams, __FUNCTION__, __FILE__);
318 $this->assertEquals("custom string", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
319
320 $this->callAPISuccess('Membership', 'Delete', array(
321 'id' => $result['id'],
322 ));
323 }
324
325 /**
326 * Test civicrm_membership_get with proper params.
327 * Memberships expected.
328 */
329 public function testGet() {
330 $membershipID = $this->contactMembershipCreate($this->_params);
331 $params = array(
332 'contact_id' => $this->_contactID,
333 );
334
335 $membership = $this->callAPISuccess('membership', 'get', $params);
336 $result = $membership['values'][$membershipID];
337 $this->callAPISuccess('Membership', 'Delete', array(
338 'id' => $membership['id'],
339 ));
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);
344
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);
349 }
350
351
352 /**
353 * Test civicrm_membership_get with proper params.
354 * Memberships expected.
355 */
356 public function testGetWithId() {
357 $membershipID = $this->contactMembershipCreate($this->_params);
358 $params = array(
359 'contact_id' => $this->_contactID,
360 'id' => $this->_membershipID,
361 'return' => 'id',
362 );
363 $result = $this->callAPISuccess('membership', 'get', $params);
364 $this->assertEquals($membershipID, $result['id']);
365 $params = array(
366 'contact_id' => $this->_contactID,
367 'membership_id' => $this->_membershipID,
368 'return' => 'membership_id',
369 );
370 $result = $this->callAPISuccess('membership', 'get', $params);
371 $this->assertEquals($membershipID, $result['id']);
372 }
373
374 /**
375 * Test civicrm_membership_get for only active.
376 * Memberships expected.
377 */
378 public function testGetOnlyActive() {
379 $description = "Demonstrates use of 'filter' active_only' param.";
380 $this->_membershipID = $this->contactMembershipCreate($this->_params);
381 $params = array(
382 'contact_id' => $this->_contactID,
383 'active_only' => 1,
384 );
385
386 $membership = $this->callAPISuccess('membership', 'get', $params);
387 $this->assertEquals($membership['values'][$this->_membershipID]['status_id'], $this->_membershipStatusID);
388 $this->assertEquals($membership['values'][$this->_membershipID]['contact_id'], $this->_contactID);
389 $params = array(
390 'contact_id' => $this->_contactID,
391 'filters' => array(
392 'is_current' => 1,
393 ),
394 );
395
396 $membership = $this->callAPIAndDocument('membership', 'get', $params, __FUNCTION__, __FILE__, $description, 'FilterIsCurrent');
397 $this->assertEquals($membership['values'][$this->_membershipID]['status_id'], $this->_membershipStatusID);
398 $this->assertEquals($membership['values'][$this->_membershipID]['contact_id'], $this->_contactID);
399
400 $this->callAPISuccess('Membership', 'Delete', array('id' => $this->_membershipID));
401 }
402
403 /**
404 * Test civicrm_membership_get for non exist contact.
405 * empty Memberships.
406 */
407 public function testGetNoContactExists() {
408 $params = array(
409 'contact_id' => 55555,
410 );
411
412 $membership = $this->callAPISuccess('membership', 'get', $params);
413 $this->assertEquals($membership['count'], 0);
414 }
415
416 /**
417 * Test civicrm_membership_get with relationship.
418 * get Memberships.
419 */
420 public function testGetWithRelationship() {
421 $membershipOrgId = $this->organizationCreate(NULL);
422 $memberContactId = $this->individualCreate();
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,
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,
442 'financial_type_id' => 1,
443 'relationship_type_id' => $relTypeID,
444 'relationship_direction' => 'b_a',
445 'is_active' => 1,
446 );
447 $memType = $this->callAPISuccess('membership_type', 'create', $params);
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,
458 );
459 $membershipID = $this->contactMembershipCreate($params);
460
461 $params = array(
462 'contact_id' => $memberContactId,
463 'membership_type_id' => $memType['id'],
464 );
465
466 $result = $this->callAPISuccess('membership', 'get', $params);
467
468 $membership = $result['values'][$membershipID];
469 $this->assertEquals($this->_membershipStatusID, $membership['status_id']);
470 $this->callAPISuccess('Membership', 'Delete', array(
471 'id' => $membership['id'],
472 ));
473 $this->membershipTypeDelete(array('id' => $memType['id']));
474 $this->relationshipTypeDelete($relTypeID);
475 $this->contactDelete($membershipOrgId);
476 $this->contactDelete($memberContactId);
477 }
478
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 */
486 public function testCreateWithRelationship() {
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);
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
551 $memberContactId[2] = $this->individualCreate(array('employer_id' => $employerId[0]), 2);
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 );
566 $this->callAPISuccess('Membership', 'create', $params);
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
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
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
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
636 /**
637 * We are checking for no e-notices + only id & end_date returned
638 */
639 public function testMembershipGetWithReturn() {
640 $this->contactMembershipCreate($this->_params);
641 $result = $this->callAPISuccess('membership', 'get', array('return' => 'end_date'));
642 foreach ($result['values'] as $membership) {
643 $this->assertEquals(array('id', 'end_date'), array_keys($membership));
644 }
645 }
646 ///////////////// civicrm_membership_create methods
647
648 /**
649 * Test civicrm_contact_memberships_create with empty params.
650 * Error expected.
651 */
652 public function testCreateWithEmptyParams() {
653 $params = array();
654 $this->callAPIFailure('membership', 'create', $params);
655 }
656
657 /**
658 * If is_overide is passed in status must also be passed in.
659 */
660 public function testCreateOverrideNoStatus() {
661 $params = $this->_params;
662 unset($params['status_id']);
663 $this->callAPIFailure('membership', 'create', $params);
664 }
665
666 public function testMembershipCreateMissingRequired() {
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',
674 );
675
676 $this->callAPIFailure('membership', 'create', $params);
677 }
678
679 public function testMembershipCreate() {
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,
689 );
690
691 $result = $this->callAPIAndDocument('membership', 'create', $params, __FUNCTION__, __FILE__);
692 $this->getAndCheck($params, $result['id'], $this->_entity);
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 }
697
698 /**
699 * Check for useful message if contact doesn't exist
700 */
701 public function testMembershipCreateWithInvalidContact() {
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,
711 );
712
713 $this->callAPIFailure('membership', 'create', $params,
714 'contact_id is not valid : 999'
715 );
716 }
717
718 public function testMembershipCreateWithInvalidStatus() {
719 $params = $this->_params;
720 $params['status_id'] = 999;
721 $this->callAPIFailure('membership', 'create', $params,
722 "'999' is not a valid option for field status_id"
723 );
724 }
725
726 public function testMembershipCreateWithInvalidType() {
727 $params = $this->_params;
728 $params['membership_type_id'] = 999;
729
730 $this->callAPIFailure('membership', 'create', $params,
731 "'999' is not a valid option for field membership_type_id"
732 );
733 }
734
735 /**
736 * Check with complete array + custom field
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 */
741 public function testCreateWithCustom() {
742 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
743
744 $params = $this->_params;
745 $params['custom_' . $ids['custom_field_id']] = "custom string";
746
747 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, NULL, 'CreateWithCustomData');
748 $check = $this->callAPISuccess($this->_entity, 'get', array(
749 'id' => $result['id'],
750 'contact_id' => $this->_contactID,
751 ));
752 $this->assertEquals("custom string", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
753 }
754
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
789 /**
790 * Test civicrm_contact_memberships_create with membership id (edit
791 * membership).
792 * success expected.
793 */
794 public function testMembershipCreateWithId() {
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,
806 );
807
808 $result = $this->callAPISuccess('membership', 'create', $params);
809 $this->callAPISuccess('Membership', 'Delete', array(
810 'id' => $result['id'],
811 ));
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 */
820 public function testMembershipCreateUpdateWithIdNoContact() {
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,
832 );
833
834 $result = $this->callAPISuccess('membership', 'create', $params);
835 $this->callAPISuccess('Membership', 'Delete', array(
836 'id' => $result['id'],
837 ));
838
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 */
847 public function testMembershipCreateUpdateWithIdNoDates() {
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,
856 );
857
858 $result = $this->callAPISuccess('membership', 'create', $params);
859 $this->callAPISuccess('Membership', 'Delete', array(
860 'id' => $result['id'],
861 ));
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 */
870 public function testMembershipCreateUpdateWithIdNoDatesNoType() {
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,
878 );
879
880 $result = $this->callAPISuccess('membership', 'create', $params);
881 $this->callAPISuccess('Membership', 'Delete', array(
882 'id' => $result['id'],
883 ));
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 */
892 public function testMembershipCreateUpdateWithIDAndSource() {
893 $membershipID = $this->contactMembershipCreate($this->_params);
894 $params = array(
895 'id' => $membershipID,
896 'source' => 'changed',
897 'contact_id' => $this->_contactID,
898 'status_id' => $this->_membershipStatusID,
899 'membership_type_id' => $this->_membershipTypeID,
900 'skipStatusCal' => 1,
901 );
902 $result = $this->callAPISuccess('membership', 'create', $params);
903 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
904 $this->callAPISuccess('Membership', 'Delete', array(
905 'id' => $result['id'],
906 ));
907 }
908
909 /**
910 * Change custom field using update.
911 */
912 public function testUpdateWithCustom() {
913 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
914
915 $params = $this->_params;
916 $params['custom_' . $ids['custom_field_id']] = "custom string";
917 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, NULL, 'UpdateCustomData');
918 $result = $this->callAPISuccess($this->_entity, 'create', array(
919 'id' => $result['id'],
920 'custom_' . $ids['custom_field_id'] => "new custom",
921 ));
922 $check = $this->callAPISuccess($this->_entity, 'get', array(
923 'id' => $result['id'],
924 'contact_id' => $this->_contactID,
925 ));
926
927 $this->assertEquals("new custom", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
928 $this->callAPISuccess('Membership', 'Delete', array(
929 'id' => $check['id'],
930 ));
931
932 $this->customFieldDelete($ids['custom_field_id']);
933 $this->customGroupDelete($ids['custom_group_id']);
934 }
935
936 /**
937 * per CRM-15746 check that the id can be altered in an update hook
938 */
939 public function testMembershipUpdateCreateHookCRM15746() {
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
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 */
959 public function hook_civicrm_pre_update_create_membership($op, $objectName, $id, &$params) {
960 if ($objectName == 'Membership' && $op == 'edit') {
961 $existingMembership = $this->callAPISuccessGetSingle('membership', array('id' => $params['id']));
962 unset($params['id'], $params['membership_id']);
963 $params['join_date'] = $params['membership_start_date'] = $params['start_date'] = date('Ymd000000', strtotime($existingMembership['start_date']));
964 $params = array_merge($existingMembership, $params);
965 $params['id'] = NULL;
966 }
967 }
968
969 /**
970 * Test civicrm_contact_memberships_create Invalid membership data.
971 * Error expected.
972 */
973 public function testMembershipCreateInvalidMemData() {
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,
983 'status_id' => $this->_membershipStatusID,
984 );
985
986 $this->callAPIFailure('membership', 'create', $params);
987
988 //membership_contact_id which is no in contact table
989 $params['membership_contact_id'] = 999;
990 $this->callAPIFailure('membership', 'create', $params);
991
992 //invalid join date
993 unset($params['membership_contact_id']);
994 $params['join_date'] = "invalid";
995 $this->callAPIFailure('Membership', 'Create', $params);
996 }
997
998 /**
999 * Test civicrm_contact_memberships_create with membership_contact_id
1000 * membership).
1001 * Success expected.
1002 */
1003 public function testMembershipCreateWithMemContact() {
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,
1013 );
1014
1015 $result = $this->callAPISuccess('membership', 'create', $params);
1016
1017 $this->callAPISuccess('Membership', 'Delete', array(
1018 'id' => $result['id'],
1019 ));
1020 }
1021
1022 /**
1023 * Test civicrm_contact_memberships_create with membership_contact_id
1024 * membership).
1025 * Success expected.
1026 */
1027 public function testMembershipCreateValidMembershipTypeString() {
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']);
1041 $this->callAPISuccess('Membership', 'Delete', array(
1042 'id' => $result['id'],
1043 ));
1044 }
1045
1046 /**
1047 * Test civicrm_contact_memberships_create with membership_contact_id
1048 * membership).
1049 * Success expected.
1050 */
1051 public function testMembershipCreateInValidMembershipTypeString() {
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
1063 $this->callAPIFailure('membership', 'create', $params);
1064 }
1065
1066 /**
1067 * Test that if membership join date is not set it defaults to today.
1068 */
1069 public function testEmptyJoinDate() {
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']);
1076 }
1077
1078 /**
1079 * Test that if membership start date is not set it defaults to correct end date.
1080 * - fixed
1081 */
1082 public function testEmptyStartDateFixed() {
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 }
1091
1092 /**
1093 * Test that if membership start date is not set it defaults to correct end date
1094 * - fixed
1095 */
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 /**
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
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
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')));
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 }
1162 $membershipTypeDetails = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($this->_membershipTypeID2);
1163 $fixedPeriodRollover = CRM_Member_BAO_MembershipType::isDuringFixedAnnualRolloverPeriod($joinDate, $membershipTypeDetails, $year, $startDate);
1164 $y = 1;
1165 if ($fixedPeriodRollover && $rollOver) {
1166 $y += 1;
1167 }
1168
1169 $expectedDates = array(
1170 'join_date' => date('Ymd'),
1171 'start_date' => str_replace('-', '', $startDate),
1172 'end_date' => date('Ymd', strtotime(date('Y-03-01') . "+ {$y} year - 1 day")),
1173 );
1174 foreach ($result['values'] as $values) {
1175 foreach ($expectedDates as $date => $val) {
1176 $this->assertEquals($val, $values[$date], "Failed asserting {$date} values");
1177 }
1178 }
1179 }
1180
1181 /**
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.
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 */
1219 public function testFixedMultiYearDateSetTwoEmptyEndDate() {
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 /**
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.
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 */
1280 public function testFixedSingleYearDateSetTwoEmptyEndDate() {
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 /**
1304 * Test that correct end date is calculated for fixed multi year memberships and start date is not changed.
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
1308 * and we add on 1 year we are after the rollover day - so we calculate 31 Oct 2016
1309 */
1310 public function testFixedSingleYearDateSetThreeEmptyEndDate() {
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
1333 /**
1334 * Test correct end and start dates are calculated for fixed multi year memberships.
1335 *
1336 * The empty start date is calculated to be the start_date (1 Nov prior to the join_date - so 1 Nov 14)
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 }
1363
1364 /**
1365 * Test that correct end date is calculated for fixed multi year memberships and start date is not changed.
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 */
1371 public function testFixedMultiYearDateSetThreeEmptyEndDate() {
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 }
1393
1394 /**
1395 * Test correct end and start dates are calculated for fixed multi year memberships.
1396 *
1397 * The empty start date is calculated to be the start_date (1 Nov prior to the join_date - so 1 Nov 14)
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
1426 /**
1427 * Test that if membership start date is not set it defaults to correct end date for fixed single year memberships.
1428 */
1429 public function testEmptyStartDateRolling() {
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']);
1436 }
1437
1438 /**
1439 * Test that if membership end date is not set it defaults to correct end date.
1440 * - rolling
1441 */
1442 public function testEmptyEndDateFixed() {
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 }
1451
1452 /**
1453 * Test that if membership end date is not set it defaults to correct end date.
1454 * - rolling
1455 */
1456 public function testEmptyEndDateRolling() {
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 /**
1468 * Test that if dates are set they not over-ridden if id is passed in
1469 */
1470 public function testMembershipDatesNotOverridden() {
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
1480 }
1481
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'));
1493 $this->assertEquals('Another one', array_pop($options['values']));
1494 $this->assertEquals('General', array_pop($options['values']));
1495 $this->assertEquals(NULL, array_pop($options['values']));
1496 }
1497
1498 }