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