Merge pull request #10006 from JMAConsulting/CRM-20022
[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 'civicrm_uf_match',
97 ),
98 TRUE
99 );
100 $this->membershipStatusDelete($this->_membershipStatusID);
101 $this->membershipTypeDelete(array('id' => $this->_membershipTypeID2));
102 $this->membershipTypeDelete(array('id' => $this->_membershipTypeID));
103 $this->contactDelete($this->_contactID);
104
105 }
106
107 /**
108 * Test membership deletion.
109 */
110 public function testMembershipDelete() {
111 $membershipID = $this->contactMembershipCreate($this->_params);
112 $this->assertDBRowExist('CRM_Member_DAO_Membership', $membershipID);
113 $params = array(
114 'id' => $membershipID,
115 );
116 $this->callAPIAndDocument('membership', 'delete', $params, __FUNCTION__, __FILE__);
117 $this->assertDBRowNotExist('CRM_Member_DAO_Membership', $membershipID);
118 }
119
120 public function testMembershipDeleteEmpty() {
121 $this->callAPIFailure('membership', 'delete', array());
122 }
123
124 public function testMembershipDeleteInvalidID() {
125 $this->callAPIFailure('membership', 'delete', array('id' => 'blah'));
126 }
127
128 /**
129 * Test civicrm_membership_delete() with invalid Membership Id.
130 */
131 public function testMembershipDeleteWithInvalidMembershipId() {
132 $membershipId = 'membership';
133 $this->callAPIFailure('membership', 'delete', $membershipId);
134 }
135
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
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
208 /**
209 * Test membership get.
210 */
211 public function testContactMembershipsGet() {
212 $this->_membershipID = $this->contactMembershipCreate($this->_params);
213 $this->callAPISuccess('membership', 'get', array());
214 $this->callAPISuccess('Membership', 'Delete', array('id' => $this->_membershipID));
215 }
216
217 /**
218 * Test civicrm_membership_get with params not array.
219 *
220 * Gets treated as contact_id, memberships expected.
221 */
222 public function testGetWithParamsContactId() {
223 $this->_membershipID = $this->contactMembershipCreate($this->_params);
224 $params = array(
225 'contact_id' => $this->_contactID,
226 );
227 $membership = $this->callAPISuccess('membership', 'get', $params);
228
229 $result = $membership['values'][$this->_membershipID];
230 $this->callAPISuccess('Membership', 'Delete', array(
231 'id' => $this->_membershipID,
232 ));
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
243 /**
244 * Test civicrm_membership_get with params not array.
245 *
246 * Gets treated as contact_id, memberships expected.
247 */
248 public function testGetInSyntax() {
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']));
264 }
265
266 /**
267 * Test civicrm_membership_get with params not array.
268 * Gets treated as contact_id, memberships expected.
269 */
270 public function testGetInSyntaxOnContactID() {
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 }
289
290 /**
291 * Test civicrm_membership_get with params not array.
292 *
293 * Gets treated as contact_id, memberships expected.
294 */
295 public function testGetWithParamsMemberShipTypeId() {
296 $this->callAPISuccess($this->_entity, 'create', $this->_params);
297 $params = array(
298 'membership_type_id' => $this->_membershipTypeID,
299 );
300 $membership = $this->callAPISuccess('membership', 'get', $params);
301 $this->callAPISuccess('Membership', 'Delete', array(
302 'id' => $membership['id'],
303 ));
304 $result = $membership['values'][$membership['id']];
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);
313 $this->assertEquals($result['id'], $membership['id']);
314 }
315
316 /**
317 * Test civicrm_membership_get with params not array.
318 * Gets treated as contact_id, memberships expected.
319 */
320 public function testGetWithParamsMemberShipTypeIdContactID() {
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);
333
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 }
342
343 /**
344 * Check with complete array + custom field.
345 *
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 */
350 public function testGetWithParamsMemberShipIdAndCustom() {
351 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
352
353 $params = $this->_params;
354 $params['custom_' . $ids['custom_field_id']] = "custom string";
355
356 $result = $this->callAPISuccess($this->_entity, 'create', $params);
357
358 $getParams = array('membership_type_id' => $params['membership_type_id']);
359 $check = $this->callAPIAndDocument($this->_entity, 'get', $getParams, __FUNCTION__, __FILE__);
360 $this->assertEquals("custom string", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
361
362 $this->callAPISuccess('Membership', 'Delete', array(
363 'id' => $result['id'],
364 ));
365 }
366
367 /**
368 * Test civicrm_membership_get with proper params.
369 * Memberships expected.
370 */
371 public function testGet() {
372 $membershipID = $this->contactMembershipCreate($this->_params);
373 $params = array(
374 'contact_id' => $this->_contactID,
375 );
376
377 $membership = $this->callAPISuccess('membership', 'get', $params);
378 $result = $membership['values'][$membershipID];
379 $this->callAPISuccess('Membership', 'Delete', array(
380 'id' => $membership['id'],
381 ));
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);
386
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);
391 }
392
393
394 /**
395 * Test civicrm_membership_get with proper params.
396 * Memberships expected.
397 */
398 public function testGetWithId() {
399 $membershipID = $this->contactMembershipCreate($this->_params);
400 $params = array(
401 'contact_id' => $this->_contactID,
402 'id' => $this->_membershipID,
403 'return' => 'id',
404 );
405 $result = $this->callAPISuccess('membership', 'get', $params);
406 $this->assertEquals($membershipID, $result['id']);
407 $params = array(
408 'contact_id' => $this->_contactID,
409 'membership_id' => $this->_membershipID,
410 'return' => 'membership_id',
411 );
412 $result = $this->callAPISuccess('membership', 'get', $params);
413 $this->assertEquals($membershipID, $result['id']);
414 }
415
416 /**
417 * Test civicrm_membership_get for only active.
418 * Memberships expected.
419 */
420 public function testGetOnlyActive() {
421 $description = "Demonstrates use of 'filter' active_only' param.";
422 $this->_membershipID = $this->contactMembershipCreate($this->_params);
423 $params = array(
424 'contact_id' => $this->_contactID,
425 'active_only' => 1,
426 );
427
428 $membership = $this->callAPISuccess('membership', 'get', $params);
429 $this->assertEquals($membership['values'][$this->_membershipID]['status_id'], $this->_membershipStatusID);
430 $this->assertEquals($membership['values'][$this->_membershipID]['contact_id'], $this->_contactID);
431 $params = array(
432 'contact_id' => $this->_contactID,
433 'filters' => array(
434 'is_current' => 1,
435 ),
436 );
437
438 $membership = $this->callAPIAndDocument('membership', 'get', $params, __FUNCTION__, __FILE__, $description, 'FilterIsCurrent');
439 $this->assertEquals($membership['values'][$this->_membershipID]['status_id'], $this->_membershipStatusID);
440 $this->assertEquals($membership['values'][$this->_membershipID]['contact_id'], $this->_contactID);
441
442 $this->callAPISuccess('Membership', 'Delete', array('id' => $this->_membershipID));
443 }
444
445 /**
446 * Test civicrm_membership_get for non exist contact.
447 * empty Memberships.
448 */
449 public function testGetNoContactExists() {
450 $params = array(
451 'contact_id' => 55555,
452 );
453
454 $membership = $this->callAPISuccess('membership', 'get', $params);
455 $this->assertEquals($membership['count'], 0);
456 }
457
458 /**
459 * Test civicrm_membership_get with relationship.
460 * get Memberships.
461 */
462 public function testGetWithRelationship() {
463 $membershipOrgId = $this->organizationCreate(NULL);
464 $memberContactId = $this->individualCreate();
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,
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,
484 'financial_type_id' => 1,
485 'relationship_type_id' => $relTypeID,
486 'relationship_direction' => 'b_a',
487 'is_active' => 1,
488 );
489 $memType = $this->callAPISuccess('membership_type', 'create', $params);
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,
500 );
501 $membershipID = $this->contactMembershipCreate($params);
502
503 $params = array(
504 'contact_id' => $memberContactId,
505 'membership_type_id' => $memType['id'],
506 );
507
508 $result = $this->callAPISuccess('membership', 'get', $params);
509
510 $membership = $result['values'][$membershipID];
511 $this->assertEquals($this->_membershipStatusID, $membership['status_id']);
512 $this->callAPISuccess('Membership', 'Delete', array(
513 'id' => $membership['id'],
514 ));
515 $this->membershipTypeDelete(array('id' => $memType['id']));
516 $this->relationshipTypeDelete($relTypeID);
517 $this->contactDelete($membershipOrgId);
518 $this->contactDelete($memberContactId);
519 }
520
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 */
528 public function testCreateWithRelationship() {
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);
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
593 $memberContactId[2] = $this->individualCreate(array('employer_id' => $employerId[0]), 2);
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 );
608 $this->callAPISuccess('Membership', 'create', $params);
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
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
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
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
678 /**
679 * We are checking for no e-notices + only id & end_date returned
680 */
681 public function testMembershipGetWithReturn() {
682 $this->contactMembershipCreate($this->_params);
683 $result = $this->callAPISuccess('membership', 'get', array('return' => 'end_date'));
684 foreach ($result['values'] as $membership) {
685 $this->assertEquals(array('id', 'end_date'), array_keys($membership));
686 }
687 }
688 ///////////////// civicrm_membership_create methods
689
690 /**
691 * Test civicrm_contact_memberships_create with empty params.
692 * Error expected.
693 */
694 public function testCreateWithEmptyParams() {
695 $params = array();
696 $this->callAPIFailure('membership', 'create', $params);
697 }
698
699 /**
700 * If is_overide is passed in status must also be passed in.
701 */
702 public function testCreateOverrideNoStatus() {
703 $params = $this->_params;
704 unset($params['status_id']);
705 $this->callAPIFailure('membership', 'create', $params);
706 }
707
708 public function testMembershipCreateMissingRequired() {
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',
716 );
717
718 $this->callAPIFailure('membership', 'create', $params);
719 }
720
721 public function testMembershipCreate() {
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,
731 );
732
733 $result = $this->callAPIAndDocument('membership', 'create', $params, __FUNCTION__, __FILE__);
734 $this->getAndCheck($params, $result['id'], $this->_entity);
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 }
739
740 /**
741 * Check for useful message if contact doesn't exist
742 */
743 public function testMembershipCreateWithInvalidContact() {
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,
753 );
754
755 $this->callAPIFailure('membership', 'create', $params,
756 'contact_id is not valid : 999'
757 );
758 }
759
760 public function testMembershipCreateWithInvalidStatus() {
761 $params = $this->_params;
762 $params['status_id'] = 999;
763 $this->callAPIFailure('membership', 'create', $params,
764 "'999' is not a valid option for field status_id"
765 );
766 }
767
768 public function testMembershipCreateWithInvalidType() {
769 $params = $this->_params;
770 $params['membership_type_id'] = 999;
771
772 $this->callAPIFailure('membership', 'create', $params,
773 "'999' is not a valid option for field membership_type_id"
774 );
775 }
776
777 /**
778 * Check with complete array + custom field
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 */
783 public function testCreateWithCustom() {
784 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
785
786 $params = $this->_params;
787 $params['custom_' . $ids['custom_field_id']] = "custom string";
788
789 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, NULL, 'CreateWithCustomData');
790 $check = $this->callAPISuccess($this->_entity, 'get', array(
791 'id' => $result['id'],
792 'contact_id' => $this->_contactID,
793 ));
794 $this->assertEquals("custom string", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
795 }
796
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
831 /**
832 * Test civicrm_contact_memberships_create with membership id (edit
833 * membership).
834 * success expected.
835 */
836 public function testMembershipCreateWithId() {
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,
848 );
849
850 $result = $this->callAPISuccess('membership', 'create', $params);
851 $this->callAPISuccess('Membership', 'Delete', array(
852 'id' => $result['id'],
853 ));
854 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
855 }
856
857 /**
858 * Test civicrm_contact_memberships_create with membership id (edit
859 * membership).
860 * success expected.
861 */
862 public function testMembershipCreateUpdateWithIdNoContact() {
863 $membershipID = $this->contactMembershipCreate($this->_params);
864 $params = array(
865 'id' => $membershipID,
866 'membership_type_id' => $this->_membershipTypeID,
867 'contact_id' => $this->_contactID,
868 'join_date' => '2006-01-21',
869 'start_date' => '2006-01-21',
870 'end_date' => '2006-12-21',
871 'source' => 'Payment',
872 'is_override' => 1,
873 'status_id' => $this->_membershipStatusID,
874 );
875
876 $result = $this->callAPISuccess('membership', 'create', $params);
877 $this->callAPISuccess('Membership', 'Delete', array(
878 'id' => $result['id'],
879 ));
880
881 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
882 }
883
884 /**
885 * Test civicrm_contact_memberships_create with membership id (edit
886 * membership).
887 * success expected.
888 */
889 public function testMembershipCreateUpdateWithIdNoDates() {
890 $membershipID = $this->contactMembershipCreate($this->_params);
891 $params = array(
892 'id' => $membershipID,
893 'contact_id' => $this->_contactID,
894 'membership_type_id' => $this->_membershipTypeID,
895 'source' => 'Payment',
896 'is_override' => 1,
897 'status_id' => $this->_membershipStatusID,
898 );
899
900 $result = $this->callAPISuccess('membership', 'create', $params);
901 $this->callAPISuccess('Membership', 'Delete', array(
902 'id' => $result['id'],
903 ));
904 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
905 }
906
907 /**
908 * Test civicrm_contact_memberships_create with membership id (edit
909 * membership).
910 * success expected.
911 */
912 public function testMembershipCreateUpdateWithIdNoDatesNoType() {
913 $membershipID = $this->contactMembershipCreate($this->_params);
914 $params = array(
915 'id' => $membershipID,
916 'source' => 'not much here',
917 'contact_id' => $this->_contactID,
918 'is_override' => 1,
919 'status_id' => $this->_membershipStatusID,
920 );
921
922 $result = $this->callAPISuccess('membership', 'create', $params);
923 $this->callAPISuccess('Membership', 'Delete', array(
924 'id' => $result['id'],
925 ));
926 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
927 }
928
929 /**
930 * Test civicrm_contact_memberships_create with membership id (edit
931 * membership).
932 * success expected.
933 */
934 public function testMembershipCreateUpdateWithIDAndSource() {
935 $membershipID = $this->contactMembershipCreate($this->_params);
936 $params = array(
937 'id' => $membershipID,
938 'source' => 'changed',
939 'contact_id' => $this->_contactID,
940 'status_id' => $this->_membershipStatusID,
941 'membership_type_id' => $this->_membershipTypeID,
942 'skipStatusCal' => 1,
943 );
944 $result = $this->callAPISuccess('membership', 'create', $params);
945 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
946 $this->callAPISuccess('Membership', 'Delete', array(
947 'id' => $result['id'],
948 ));
949 }
950
951 /**
952 * Change custom field using update.
953 */
954 public function testUpdateWithCustom() {
955 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
956
957 $params = $this->_params;
958 $params['custom_' . $ids['custom_field_id']] = "custom string";
959 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, NULL, 'UpdateCustomData');
960 $result = $this->callAPISuccess($this->_entity, 'create', array(
961 'id' => $result['id'],
962 'custom_' . $ids['custom_field_id'] => "new custom",
963 ));
964 $check = $this->callAPISuccess($this->_entity, 'get', array(
965 'id' => $result['id'],
966 'contact_id' => $this->_contactID,
967 ));
968
969 $this->assertEquals("new custom", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
970 $this->callAPISuccess('Membership', 'Delete', array(
971 'id' => $check['id'],
972 ));
973
974 $this->customFieldDelete($ids['custom_field_id']);
975 $this->customGroupDelete($ids['custom_group_id']);
976 }
977
978 /**
979 * per CRM-15746 check that the id can be altered in an update hook
980 */
981 public function testMembershipUpdateCreateHookCRM15746() {
982 $this->hookClass->setHook('civicrm_pre', array($this, 'hook_civicrm_pre_update_create_membership'));
983 $result = $this->callAPISuccess('membership', 'create', $this->_params);
984 $this->callAPISuccess('membership', 'create', array('id' => $result['id'], 'end_date' => '1 year ago'));
985 $this->callAPISuccessGetCount('membership', array(), 2);
986 $this->hookClass->reset();
987 $this->callAPISuccess('membership', 'create', array('id' => $result['id'], 'end_date' => '1 year ago'));
988 $this->callAPISuccessGetCount('membership', array(), 2);
989 }
990
991 /**
992 * Custom hook for update membership.
993 *
994 * @param string $op
995 * @param object $objectName
996 * @param int $id
997 * @param array $params
998 *
999 * @throws \Exception
1000 */
1001 public function hook_civicrm_pre_update_create_membership($op, $objectName, $id, &$params) {
1002 if ($objectName == 'Membership' && $op == 'edit') {
1003 $existingMembership = $this->callAPISuccessGetSingle('membership', array('id' => $params['id']));
1004 unset($params['id'], $params['membership_id']);
1005 $params['join_date'] = $params['membership_start_date'] = $params['start_date'] = date('Ymd000000', strtotime($existingMembership['start_date']));
1006 $params = array_merge($existingMembership, $params);
1007 $params['id'] = NULL;
1008 }
1009 }
1010
1011 /**
1012 * Test civicrm_contact_memberships_create Invalid membership data.
1013 * Error expected.
1014 */
1015 public function testMembershipCreateInvalidMemData() {
1016 //membership_contact_id as string
1017 $params = array(
1018 'membership_contact_id' => 'Invalid',
1019 'membership_type_id' => $this->_membershipTypeID,
1020 'join_date' => '2011-01-21',
1021 'start_date' => '2010-01-21',
1022 'end_date' => '2008-12-21',
1023 'source' => 'Payment',
1024 'is_override' => 1,
1025 'status_id' => $this->_membershipStatusID,
1026 );
1027
1028 $this->callAPIFailure('membership', 'create', $params);
1029
1030 //membership_contact_id which is no in contact table
1031 $params['membership_contact_id'] = 999;
1032 $this->callAPIFailure('membership', 'create', $params);
1033
1034 //invalid join date
1035 unset($params['membership_contact_id']);
1036 $params['join_date'] = "invalid";
1037 $this->callAPIFailure('Membership', 'Create', $params);
1038 }
1039
1040 /**
1041 * Test civicrm_contact_memberships_create with membership_contact_id
1042 * membership).
1043 * Success expected.
1044 */
1045 public function testMembershipCreateWithMemContact() {
1046 $params = array(
1047 'membership_contact_id' => $this->_contactID,
1048 'membership_type_id' => $this->_membershipTypeID,
1049 'join_date' => '2011-01-21',
1050 'start_date' => '2010-01-21',
1051 'end_date' => '2008-12-21',
1052 'source' => 'Payment',
1053 'is_override' => 1,
1054 'status_id' => $this->_membershipStatusID,
1055 );
1056
1057 $result = $this->callAPISuccess('membership', 'create', $params);
1058
1059 $this->callAPISuccess('Membership', 'Delete', array(
1060 'id' => $result['id'],
1061 ));
1062 }
1063
1064 /**
1065 * Test civicrm_contact_memberships_create with membership_contact_id
1066 * membership).
1067 * Success expected.
1068 */
1069 public function testMembershipCreateValidMembershipTypeString() {
1070 $params = array(
1071 'membership_contact_id' => $this->_contactID,
1072 'membership_type_id' => 'General',
1073 'join_date' => '2011-01-21',
1074 'start_date' => '2010-01-21',
1075 'end_date' => '2008-12-21',
1076 'source' => 'Payment',
1077 'is_override' => 1,
1078 'status_id' => $this->_membershipStatusID,
1079 );
1080
1081 $result = $this->callAPISuccess('membership', 'create', $params);
1082 $this->assertEquals($this->_membershipTypeID, $result['values'][$result['id']]['membership_type_id']);
1083 $this->callAPISuccess('Membership', 'Delete', array(
1084 'id' => $result['id'],
1085 ));
1086 }
1087
1088 /**
1089 * Test civicrm_contact_memberships_create with membership_contact_id
1090 * membership).
1091 * Success expected.
1092 */
1093 public function testMembershipCreateInValidMembershipTypeString() {
1094 $params = array(
1095 'membership_contact_id' => $this->_contactID,
1096 'membership_type_id' => 'invalid',
1097 'join_date' => '2011-01-21',
1098 'start_date' => '2010-01-21',
1099 'end_date' => '2008-12-21',
1100 'source' => 'Payment',
1101 'is_override' => 1,
1102 'status_id' => $this->_membershipStatusID,
1103 );
1104
1105 $this->callAPIFailure('membership', 'create', $params);
1106 }
1107
1108 /**
1109 * Test that if membership join date is not set it defaults to today.
1110 */
1111 public function testEmptyJoinDate() {
1112 unset($this->_params['join_date'], $this->_params['is_override']);
1113 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1114 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1115 $this->assertEquals(date('Y-m-d', strtotime('now')), $result['join_date']);
1116 $this->assertEquals('2009-01-21', $result['start_date']);
1117 $this->assertEquals('2009-12-21', $result['end_date']);
1118 }
1119
1120 /**
1121 * Test that if membership start date is not set it defaults to correct end date.
1122 * - fixed
1123 */
1124 public function testEmptyStartDateFixed() {
1125 unset($this->_params['start_date'], $this->_params['is_override']);
1126 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1127 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1128 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1129 $this->assertEquals('2009-01-21', $result['join_date']);
1130 $this->assertEquals('2008-03-01', $result['start_date']);
1131 $this->assertEquals('2009-12-21', $result['end_date']);
1132 }
1133
1134 /**
1135 * Test that if membership start date is not set it defaults to correct end date
1136 * - fixed
1137 */
1138 public function testEmptyStartEndDateFixedOneYear() {
1139 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1140 $this->callAPISuccess('membership_type', 'create', array('id' => $this->_membershipTypeID2, 'duration_interval' => 1));
1141 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1142 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1143 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1144 $this->assertEquals('2009-01-21', $result['join_date']);
1145 $this->assertEquals('2008-03-01', $result['start_date']);
1146 $this->assertEquals('2010-02-28', $result['end_date']);
1147 }
1148
1149 /**
1150 * Test that if membership start date is not set it defaults to correct end date for fixed multi year memberships.
1151 */
1152 public function testEmptyStartEndDateFixedMultiYear() {
1153 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1154 $this->callAPISuccess('membership_type', 'create', array('id' => $this->_membershipTypeID2, 'duration_interval' => 5));
1155 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1156 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1157 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1158 $this->assertEquals('2009-01-21', $result['join_date']);
1159 $this->assertEquals('2008-03-01', $result['start_date']);
1160 $this->assertEquals('2014-02-28', $result['end_date']);
1161 }
1162
1163 /**
1164 * CRM-18503 - Test membership join date is correctly set for fixed memberships.
1165 */
1166 public function testMembershipJoinDateFixed() {
1167 $memStatus = CRM_Member_PseudoConstant::membershipStatus();
1168 // Update the fixed membership type to 1 year duration.
1169 $this->callAPISuccess('membership_type', 'create', array('id' => $this->_membershipTypeID2, 'duration_interval' => 1));
1170 $contactId = $this->createLoggedInUser();
1171 // Create membership with 'Pending' status.
1172 $params = array(
1173 'contact_id' => $contactId,
1174 'membership_type_id' => $this->_membershipTypeID2,
1175 'source' => 'test membership',
1176 'is_pay_later' => 0,
1177 'status_id' => array_search('Pending', $memStatus),
1178 'skipStatusCal' => 1,
1179 'is_for_organization' => 1,
1180 );
1181 $ids = array();
1182 $membership = CRM_Member_BAO_Membership::create($params, $ids);
1183
1184 // Update membership to 'Completed' and check the dates.
1185 $memParams = array(
1186 'id' => $membership->id,
1187 'contact_id' => $contactId,
1188 'is_test' => 0,
1189 'membership_type_id' => $this->_membershipTypeID2,
1190 'num_terms' => 1,
1191 'status_id' => array_search('New', $memStatus),
1192 );
1193 $result = $this->callAPISuccess('Membership', 'create', $memParams);
1194
1195 // Extend duration interval if join_date exceeds the rollover period.
1196 $joinDate = date('Y-m-d');
1197 $year = date('Y');
1198 $startDate = date('Y-m-d', strtotime(date('Y-03-01')));
1199 $rollOver = TRUE;
1200 if (strtotime($startDate) > time()) {
1201 $rollOver = FALSE;
1202 $startDate = date('Y-m-d', strtotime(date('Y-03-01') . '- 1 year'));
1203 }
1204 $membershipTypeDetails = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($this->_membershipTypeID2);
1205 $fixedPeriodRollover = CRM_Member_BAO_MembershipType::isDuringFixedAnnualRolloverPeriod($joinDate, $membershipTypeDetails, $year, $startDate);
1206 $y = 1;
1207 if ($fixedPeriodRollover && $rollOver) {
1208 $y += 1;
1209 }
1210
1211 $expectedDates = array(
1212 'join_date' => date('Ymd'),
1213 'start_date' => str_replace('-', '', $startDate),
1214 'end_date' => date('Ymd', strtotime(date('Y-03-01') . "+ {$y} year - 1 day")),
1215 );
1216 foreach ($result['values'] as $values) {
1217 foreach ($expectedDates as $date => $val) {
1218 $this->assertEquals($val, $values[$date], "Failed asserting {$date} values");
1219 }
1220 }
1221 }
1222
1223 /**
1224 * Test correct end and start dates are calculated for fixed multi year memberships.
1225 *
1226 * The empty start date is calculated to be the start_date (1 Jan prior to the join_date - so 1 Jan 15)
1227 *
1228 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1229 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1230 * and we add on 4 years rather than 5 because we are not after the rollover day - so we calculate 31 Dec 2019
1231 */
1232 public function testFixedMultiYearDateSetTwoEmptyStartEndDate() {
1233 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1234
1235 $this->callAPISuccess('membership_type', 'create', array(
1236 'id' => $this->_membershipTypeID2,
1237 'duration_interval' => 5,
1238 // Ie 1 Jan.
1239 'fixed_period_start_day' => '101',
1240 // Ie. 1 Nov.
1241 'fixed_period_rollover_day' => '1101',
1242 ));
1243 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1244 $dates = array(
1245 'join_date' => '28-Jan 2015',
1246 );
1247 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1248 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1249 $this->assertEquals('2015-01-28', $result['join_date']);
1250 $this->assertEquals('2015-01-01', $result['start_date']);
1251 $this->assertEquals('2019-12-31', $result['end_date']);
1252 }
1253
1254 /**
1255 * Test that correct end date is calculated for fixed multi year memberships and start date is not changed.
1256 *
1257 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1258 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1259 * and we add on 4 years rather than 5 because we are not after the rollover day - so we calculate 31 Dec 2019
1260 */
1261 public function testFixedMultiYearDateSetTwoEmptyEndDate() {
1262 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1263
1264 $this->callAPISuccess('membership_type', 'create', array(
1265 'id' => $this->_membershipTypeID2,
1266 'duration_interval' => 5,
1267 // Ie 1 Jan.
1268 'fixed_period_start_day' => '101',
1269 // Ie. 1 Nov.
1270 'fixed_period_rollover_day' => '1101',
1271 ));
1272 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1273 $dates = array(
1274 'start_date' => '28-Jan 2015',
1275 'join_date' => '28-Jan 2015',
1276 );
1277 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1278 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1279 $this->assertEquals('2015-01-28', $result['join_date']);
1280 $this->assertEquals('2015-01-28', $result['start_date']);
1281 $this->assertEquals('2019-12-31', $result['end_date']);
1282 }
1283
1284 /**
1285 * Test correct end and start dates are calculated for fixed multi year memberships.
1286 *
1287 * The empty start date is calculated to be the start_date (1 Jan prior to the join_date - so 1 Jan 15)
1288 *
1289 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1290 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1291 * and we add on <1 years rather than > 1 because we are not after the rollover day - so we calculate 31 Dec 2015
1292 */
1293 public function testFixedSingleYearDateSetTwoEmptyStartEndDate() {
1294 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1295
1296 $this->callAPISuccess('membership_type', 'create', array(
1297 'id' => $this->_membershipTypeID2,
1298 'duration_interval' => 1,
1299 // Ie 1 Jan.
1300 'fixed_period_start_day' => '101',
1301 // Ie. 1 Nov.
1302 'fixed_period_rollover_day' => '1101',
1303 ));
1304 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1305 $dates = array(
1306 'join_date' => '28-Jan 2015',
1307 );
1308 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1309 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1310 $this->assertEquals('2015-01-28', $result['join_date']);
1311 $this->assertEquals('2015-01-01', $result['start_date']);
1312 $this->assertEquals('2015-12-31', $result['end_date']);
1313 }
1314
1315 /**
1316 * Test correct end date for fixed single year memberships is calculated and start_date is not changed.
1317 *
1318 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1319 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1320 * and we add on <1 years rather than > 1 because we are not after the rollover day - so we calculate 31 Dec 2015
1321 */
1322 public function testFixedSingleYearDateSetTwoEmptyEndDate() {
1323 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1324
1325 $this->callAPISuccess('membership_type', 'create', array(
1326 'id' => $this->_membershipTypeID2,
1327 'duration_interval' => 1,
1328 // Ie 1 Jan.
1329 'fixed_period_start_day' => '101',
1330 // Ie. 1 Nov.
1331 'fixed_period_rollover_day' => '1101',
1332 ));
1333 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1334 $dates = array(
1335 'start_date' => '28-Jan 2015',
1336 'join_date' => '28-Jan 2015',
1337 );
1338 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1339 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1340 $this->assertEquals('2015-01-28', $result['join_date']);
1341 $this->assertEquals('2015-01-28', $result['start_date']);
1342 $this->assertEquals('2015-12-31', $result['end_date']);
1343 }
1344
1345 /**
1346 * Test that correct end date is calculated for fixed multi year memberships and start date is not changed.
1347 *
1348 * In this set our start date is after the start day and after the rollover day so we do get an extra year
1349 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
1350 * and we add on 1 year we are after the rollover day - so we calculate 31 Oct 2016
1351 */
1352 public function testFixedSingleYearDateSetThreeEmptyEndDate() {
1353 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1354
1355 $this->callAPISuccess('membership_type', 'create', array(
1356 'id' => $this->_membershipTypeID2,
1357 'duration_interval' => 1,
1358 // Ie. 1 Nov.
1359 'fixed_period_start_day' => '1101',
1360 // Ie 1 Jan.
1361 'fixed_period_rollover_day' => '101',
1362 ));
1363 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1364 $dates = array(
1365 'start_date' => '28-Jan 2015',
1366 'join_date' => '28-Jan 2015',
1367 );
1368 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1369 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1370 $this->assertEquals('2015-01-28', $result['join_date']);
1371 $this->assertEquals('2015-01-28', $result['start_date']);
1372 $this->assertEquals('2016-10-31', $result['end_date']);
1373 }
1374
1375 /**
1376 * Test correct end and start dates are calculated for fixed multi year memberships.
1377 *
1378 * The empty start date is calculated to be the start_date (1 Nov prior to the join_date - so 1 Nov 14)
1379 *
1380 * In this set our start date is after the start day and after the rollover day so we do get an extra year
1381 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
1382 * and we add on 1 year we are after the rollover day - so we calculate 31 Oct 2016
1383 */
1384 public function testFixedSingleYearDateSetThreeEmptyStartEndDate() {
1385 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1386
1387 $this->callAPISuccess('membership_type', 'create', array(
1388 'id' => $this->_membershipTypeID2,
1389 'duration_interval' => 1,
1390 // Ie. 1 Nov.
1391 'fixed_period_start_day' => '1101',
1392 // Ie 1 Jan.
1393 'fixed_period_rollover_day' => '101',
1394 ));
1395 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1396 $dates = array(
1397 'join_date' => '28-Jan 2015',
1398 );
1399 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1400 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1401 $this->assertEquals('2015-01-28', $result['join_date']);
1402 $this->assertEquals('2014-11-01', $result['start_date']);
1403 $this->assertEquals('2016-10-31', $result['end_date']);
1404 }
1405
1406 /**
1407 * Test that correct end date is calculated for fixed multi year memberships and start date is not changed.
1408 *
1409 * In this set our start date is after the start day and after the rollover day so we do get an extra year
1410 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
1411 * and we add on 5 years we are after the rollover day - so we calculate 31 Oct 2020
1412 */
1413 public function testFixedMultiYearDateSetThreeEmptyEndDate() {
1414 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1415
1416 $this->callAPISuccess('membership_type', 'create', array(
1417 'id' => $this->_membershipTypeID2,
1418 'duration_interval' => 5,
1419 // Ie. 1 Nov.
1420 'fixed_period_start_day' => '1101',
1421 // Ie 1 Jan.
1422 'fixed_period_rollover_day' => '101',
1423 ));
1424 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1425 $dates = array(
1426 'start_date' => '28-Jan 2015',
1427 'join_date' => '28-Jan 2015',
1428 );
1429 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1430 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1431 $this->assertEquals('2015-01-28', $result['join_date']);
1432 $this->assertEquals('2015-01-28', $result['start_date']);
1433 $this->assertEquals('2020-10-31', $result['end_date']);
1434 }
1435
1436 /**
1437 * Test correct end and start dates are calculated for fixed multi year memberships.
1438 *
1439 * The empty start date is calculated to be the start_date (1 Nov prior to the join_date - so 1 Nov 14)
1440 *
1441 * The empty start date is calculated to be the start_date (1 Nov prior to the join_date - so 1 Nov 14)
1442 * In this set our join date is after the start day and after the rollover day so we do get an extra year
1443 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
1444 * and we add on 5 years we are after the rollover day - so we calculate 31 Oct 2020
1445 */
1446 public function testFixedMultiYearDateSetThreeEmptyStartEndDate() {
1447 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1448
1449 $this->callAPISuccess('membership_type', 'create', array(
1450 'id' => $this->_membershipTypeID2,
1451 'duration_interval' => 5,
1452 // Ie. 1 Nov.
1453 'fixed_period_start_day' => '1101',
1454 // Ie 1 Jan.
1455 'fixed_period_rollover_day' => '101',
1456 ));
1457 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1458 $dates = array(
1459 'join_date' => '28-Jan 2015',
1460 );
1461 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1462 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1463 $this->assertEquals('2015-01-28', $result['join_date']);
1464 $this->assertEquals('2014-11-01', $result['start_date']);
1465 $this->assertEquals('2020-10-31', $result['end_date']);
1466 }
1467
1468 /**
1469 * Test that if membership start date is not set it defaults to correct end date for fixed single year memberships.
1470 */
1471 public function testEmptyStartDateRolling() {
1472 unset($this->_params['start_date'], $this->_params['is_override']);
1473 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1474 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1475 $this->assertEquals('2009-01-21', $result['join_date']);
1476 $this->assertEquals('2009-01-21', $result['start_date']);
1477 $this->assertEquals('2009-12-21', $result['end_date']);
1478 }
1479
1480 /**
1481 * Test that if membership end date is not set it defaults to correct end date.
1482 * - rolling
1483 */
1484 public function testEmptyEndDateFixed() {
1485 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1486 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1487 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1488 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1489 $this->assertEquals('2009-01-21', $result['join_date']);
1490 $this->assertEquals('2008-03-01', $result['start_date']);
1491 $this->assertEquals('2010-02-28', $result['end_date']);
1492 }
1493
1494 /**
1495 * Test that if membership end date is not set it defaults to correct end date.
1496 * - rolling
1497 */
1498 public function testEmptyEndDateRolling() {
1499 unset($this->_params['is_override'], $this->_params['end_date']);
1500 $this->_params['membership_type_id'] = $this->_membershipTypeID;
1501 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1502 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1503 $this->assertEquals('2009-01-21', $result['join_date']);
1504 $this->assertEquals('2009-01-21', $result['start_date']);
1505 $this->assertEquals('2010-01-20', $result['end_date']);
1506 }
1507
1508
1509 /**
1510 * Test that if dates are set they not over-ridden if id is passed in
1511 */
1512 public function testMembershipDatesNotOverridden() {
1513 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1514 unset($this->_params['end_date'], $this->_params['start_date']);
1515 $this->_params['id'] = $result['id'];
1516 $this->callAPISuccess($this->_entity, 'create', $this->_params);
1517 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1518 $this->assertEquals('2009-01-21', $result['join_date']);
1519 $this->assertEquals('2009-01-21', $result['start_date']);
1520 $this->assertEquals('2009-12-21', $result['end_date']);
1521
1522 }
1523
1524 /**
1525 * Test that all membership types are returned when getoptions is called.
1526 *
1527 * This test locks in current behaviour where types for all domains are returned. It should possibly be domain
1528 * specific but that should only be done in conjunction with adding a hook to allow that to be altered as the
1529 * multisite use case expects the master domain to be able to see all sites.
1530 *
1531 * See CRM-17075.
1532 */
1533 public function testGetOptionsMembershipTypeID() {
1534 $options = $this->callAPISuccess('Membership', 'getoptions', array('field' => 'membership_type_id'));
1535 $this->assertEquals('Another one', array_pop($options['values']));
1536 $this->assertEquals('General', array_pop($options['values']));
1537 $this->assertEquals(NULL, array_pop($options['values']));
1538 }
1539
1540 }