Merge pull request #9490 from eileenmcnaughton/report
[civicrm-core.git] / tests / phpunit / CRM / Member / BAO / 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 * Class CRM_Member_BAO_MembershipTest
30 * @group headless
31 */
32 class CRM_Member_BAO_MembershipTest extends CiviUnitTestCase {
33
34 public function setUp() {
35 parent::setUp();
36 // FIXME: something NULLs $GLOBALS['_HTML_QuickForm_registered_rules'] when the tests are ran all together
37 $GLOBALS['_HTML_QuickForm_registered_rules'] = array(
38 'required' => array('html_quickform_rule_required', 'HTML/QuickForm/Rule/Required.php'),
39 'maxlength' => array('html_quickform_rule_range', 'HTML/QuickForm/Rule/Range.php'),
40 'minlength' => array('html_quickform_rule_range', 'HTML/QuickForm/Rule/Range.php'),
41 'rangelength' => array('html_quickform_rule_range', 'HTML/QuickForm/Rule/Range.php'),
42 'email' => array('html_quickform_rule_email', 'HTML/QuickForm/Rule/Email.php'),
43 'regex' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
44 'lettersonly' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
45 'alphanumeric' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
46 'numeric' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
47 'nopunctuation' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
48 'nonzero' => array('html_quickform_rule_regex', 'HTML/QuickForm/Rule/Regex.php'),
49 'callback' => array('html_quickform_rule_callback', 'HTML/QuickForm/Rule/Callback.php'),
50 'compare' => array('html_quickform_rule_compare', 'HTML/QuickForm/Rule/Compare.php'),
51 );
52
53 $this->_contactID = $this->organizationCreate();
54 $this->_membershipTypeID = $this->membershipTypeCreate(array('member_of_contact_id' => $this->_contactID));
55 // add a random number to avoid silly conflicts with old data
56 $this->_membershipStatusID = $this->membershipStatusCreate('test status' . rand(1, 1000));
57 }
58
59 /**
60 * Tears down the fixture, for example, closes a network connection.
61 * This method is called after a test is executed.
62 */
63 public function tearDown() {
64 $this->membershipTypeDelete(array('id' => $this->_membershipTypeID));
65 $this->membershipStatusDelete($this->_membershipStatusID);
66 $this->contactDelete($this->_contactID);
67
68 $this->_contactID = $this->_membershipStatusID = $this->_membershipTypeID = NULL;
69 }
70
71 public function testCreate() {
72
73 $contactId = $this->individualCreate();
74
75 $params = array(
76 'contact_id' => $contactId,
77 'membership_type_id' => $this->_membershipTypeID,
78 'join_date' => date('Ymd', strtotime('2006-01-21')),
79 'start_date' => date('Ymd', strtotime('2006-01-21')),
80 'end_date' => date('Ymd', strtotime('2006-12-21')),
81 'source' => 'Payment',
82 'is_override' => 1,
83 'status_id' => $this->_membershipStatusID,
84 );
85 $ids = array();
86 CRM_Member_BAO_Membership::create($params, $ids);
87
88 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
89 'contact_id', 'Database check for created membership.'
90 );
91
92 // Now call create() to modify an existing Membership
93
94 $params = array();
95 $params = array(
96 'contact_id' => $contactId,
97 'membership_type_id' => $this->_membershipTypeID,
98 'join_date' => date('Ymd', strtotime('2006-01-21')),
99 'start_date' => date('Ymd', strtotime('2006-01-21')),
100 'end_date' => date('Ymd', strtotime('2006-12-21')),
101 'source' => 'Payment',
102 'is_override' => 1,
103 'status_id' => $this->_membershipStatusID,
104 );
105 $ids = array(
106 'membership' => $membershipId,
107 );
108 CRM_Member_BAO_Membership::create($params, $ids);
109
110 $membershipTypeId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId,
111 'membership_type_id', 'contact_id',
112 'Database check on updated membership record.'
113 );
114 $this->assertEquals($membershipTypeId, $this->_membershipTypeID, 'Verify membership type id is fetched.');
115
116 $this->membershipDelete($membershipId);
117 $this->contactDelete($contactId);
118 }
119
120 public function testGetValues() {
121 // $this->markTestSkipped( 'causes mysterious exit, needs fixing!' );
122 // Calculate membership dates based on the current date
123 $now = time();
124 $year_from_now = $now + (365 * 24 * 60 * 60);
125 $last_month = $now - (30 * 24 * 60 * 60);
126 $year_from_last_month = $last_month + (365 * 24 * 60 * 60);
127
128 $contactId = $this->individualCreate();
129
130 $params = array(
131 'contact_id' => $contactId,
132 'membership_type_id' => $this->_membershipTypeID,
133 'join_date' => date('Ymd'),
134 'start_date' => date('Ymd'),
135 'end_date' => date('Ymd', $year_from_now),
136 'source' => 'Payment',
137 'is_override' => 1,
138 'status_id' => $this->_membershipStatusID,
139 );
140
141 $ids = array();
142 CRM_Member_BAO_Membership::create($params, $ids);
143
144 $membershipId1 = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
145 'contact_id', 'Database check for created membership.'
146 );
147
148 $params = array(
149 'contact_id' => $contactId,
150 'membership_type_id' => $this->_membershipTypeID,
151 'join_date' => date('Ymd', $last_month),
152 'start_date' => date('Ymd', $last_month),
153 'end_date' => date('Ymd', $year_from_last_month),
154 'source' => 'Source123',
155 'is_override' => 0,
156 'status_id' => $this->_membershipStatusID,
157 );
158 $ids = array();
159 CRM_Member_BAO_Membership::create($params, $ids);
160
161 $membershipId2 = $this->assertDBNotNull('CRM_Member_BAO_Membership', 'source123', 'id',
162 'source', 'Database check for created membership.'
163 );
164
165 $membership = array('contact_id' => $contactId);
166 $membershipValues = array();
167 CRM_Member_BAO_Membership::getValues($membership, $membershipValues, TRUE);
168
169 $this->assertEquals($membershipValues[$membershipId1]['membership_id'], $membershipId1, 'Verify membership record 1 is fetched.');
170
171 $this->assertEquals($membershipValues[$membershipId2]['membership_id'], $membershipId2, 'Verify membership record 2 is fetched.');
172
173 $this->membershipDelete($membershipId1);
174 $this->membershipDelete($membershipId2);
175 $this->contactDelete($contactId);
176 }
177
178 public function testRetrieve() {
179 $contactId = $this->individualCreate();
180
181 $params = array(
182 'contact_id' => $contactId,
183 'membership_type_id' => $this->_membershipTypeID,
184 'join_date' => date('Ymd', strtotime('2006-01-21')),
185 'start_date' => date('Ymd', strtotime('2006-01-21')),
186 'end_date' => date('Ymd', strtotime('2006-12-21')),
187 'source' => 'Payment',
188 'is_override' => 1,
189 'status_id' => $this->_membershipStatusID,
190 );
191 $ids = array();
192 CRM_Member_BAO_Membership::create($params, $ids);
193
194 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
195 'contact_id', 'Database check for created membership.'
196 );
197 $params = array('id' => $membershipId);
198 $values = array();
199 CRM_Member_BAO_Membership::retrieve($params, $values);
200 $this->assertEquals($values['id'], $membershipId, 'Verify membership record is retrieved.');
201
202 $this->membershipDelete($membershipId);
203 $this->contactDelete($contactId);
204 }
205
206 public function testActiveMembers() {
207 $contactId = $this->individualCreate();
208
209 $params = array(
210 'contact_id' => $contactId,
211 'membership_type_id' => $this->_membershipTypeID,
212 'join_date' => date('Ymd', strtotime('2006-01-21')),
213 'start_date' => date('Ymd', strtotime('2006-01-21')),
214 'end_date' => date('Ymd', strtotime('2006-12-21')),
215 'source' => 'Payment',
216 'is_override' => 1,
217 'status_id' => $this->_membershipStatusID,
218 );
219 $ids = array();
220 CRM_Member_BAO_Membership::create($params, $ids);
221
222 $membershipId1 = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
223 'contact_id', 'Database check for created membership.'
224 );
225
226 $params = array('id' => $membershipId1);
227 $values1 = array();
228 CRM_Member_BAO_Membership::retrieve($params, $values1);
229 $membership = array($membershipId1 => $values1);
230
231 $params = array(
232 'contact_id' => $contactId,
233 'membership_type_id' => $this->_membershipTypeID,
234 'join_date' => date('Ymd', strtotime('2006-01-21')),
235 'start_date' => date('Ymd', strtotime('2006-01-21')),
236 'end_date' => date('Ymd', strtotime('2006-12-21')),
237 'source' => 'PaySource',
238 'is_override' => 1,
239 'status_id' => $this->_membershipStatusID,
240 );
241 $ids = array();
242 CRM_Member_BAO_Membership::create($params, $ids);
243
244 $membershipId2 = $this->assertDBNotNull('CRM_Member_BAO_Membership', 'PaySource', 'id',
245 'source', 'Database check for created membership.'
246 );
247
248 $params = array('id' => $membershipId2);
249 $values2 = array();
250 CRM_Member_BAO_Membership::retrieve($params, $values2);
251 $membership[$membershipId2] = $values2;
252
253 $activeMembers = CRM_Member_BAO_Membership::activeMembers($membership);
254 $inActiveMembers = CRM_Member_BAO_Membership::activeMembers($membership, 'inactive');
255
256 $this->assertEquals($activeMembers[$membershipId1]['id'], $membership[$membershipId1]['id'], 'Verify active membership record is retrieved.');
257 $this->assertEquals($activeMembers[$membershipId2]['id'], $membership[$membershipId2]['id'], 'Verify active membership record is retrieved.');
258
259 $this->assertEquals(0, count($inActiveMembers), 'Verify No inactive membership record is retrieved.');
260
261 $this->membershipDelete($membershipId1);
262 $this->membershipDelete($membershipId2);
263 $this->contactDelete($contactId);
264 }
265
266 public function testDeleteMembership() {
267 $contactId = $this->individualCreate();
268
269 $params = array(
270 'contact_id' => $contactId,
271 'membership_type_id' => $this->_membershipTypeID,
272 'join_date' => date('Ymd', strtotime('2006-01-21')),
273 'start_date' => date('Ymd', strtotime('2006-01-21')),
274 'end_date' => date('Ymd', strtotime('2006-12-21')),
275 'source' => 'Payment',
276 'is_override' => 1,
277 'status_id' => $this->_membershipStatusID,
278 );
279 $ids = array();
280 CRM_Member_BAO_Membership::create($params, $ids);
281
282 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
283 'contact_id', 'Database check for created membership.'
284 );
285 CRM_Member_BAO_Membership::del($membershipId);
286
287 $this->assertDBNull('CRM_Member_BAO_Membership', $contactId, 'id',
288 'contact_id', 'Database check for deleted membership.'
289 );
290 $this->contactDelete($contactId);
291 }
292
293 public function testGetContactMembership() {
294 $contactId = $this->individualCreate();
295
296 $params = array(
297 'contact_id' => $contactId,
298 'membership_type_id' => $this->_membershipTypeID,
299 'join_date' => date('Ymd', strtotime('2006-01-21')),
300 'start_date' => date('Ymd', strtotime('2006-01-21')),
301 'end_date' => date('Ymd', strtotime('2006-12-21')),
302 'source' => 'Payment',
303 'is_override' => 1,
304 'status_id' => $this->_membershipStatusID,
305 );
306 $ids = array();
307 CRM_Member_BAO_Membership::create($params, $ids);
308
309 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
310 'contact_id', 'Database check for created membership.'
311 );
312
313 $membership = CRM_Member_BAO_Membership::getContactMembership($contactId, $this->_membershipTypeID, FALSE);
314
315 $this->assertEquals($membership['id'], $membershipId, 'Verify membership record is retrieved.');
316
317 $this->membershipDelete($membershipId);
318 $this->contactDelete($contactId);
319 }
320
321
322 /**
323 * Get the contribution.
324 * page id from the membership record
325 */
326 public function testgetContributionPageId() {
327 $contactId = $this->individualCreate();
328
329 $params = array(
330 'contact_id' => $contactId,
331 'membership_type_id' => $this->_membershipTypeID,
332 'join_date' => date('Ymd', strtotime('2006-01-21')),
333 'start_date' => date('Ymd', strtotime('2006-01-21')),
334 'end_date' => date('Ymd', strtotime('2006-12-21')),
335 'source' => 'Payment',
336 'is_override' => 1,
337 'status_id' => $this->_membershipStatusID,
338 );
339 $ids = array();
340 CRM_Member_BAO_Membership::create($params, $ids);
341
342 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
343 'contact_id', 'Database check for created membership.'
344 );
345 $membership[$membershipId]['renewPageId'] = CRM_Member_BAO_Membership::getContributionPageId($membershipId);
346
347 $this->membershipDelete($membershipId);
348 $this->contactDelete($contactId);
349 }
350
351 /**
352 * Get membership joins/renewals
353 * for a specified membership
354 * type.
355 */
356 public function testgetMembershipStarts() {
357 $contactId = $this->individualCreate();
358
359 $params = array(
360 'contact_id' => $contactId,
361 'membership_type_id' => $this->_membershipTypeID,
362 'join_date' => date('Ymd', strtotime('2006-01-21')),
363 'start_date' => date('Ymd', strtotime('2006-01-21')),
364 'end_date' => date('Ymd', strtotime('2006-12-21')),
365 'source' => 'Payment',
366 'is_override' => 1,
367 'status_id' => $this->_membershipStatusID,
368 );
369 $ids = array();
370 CRM_Member_BAO_Membership::create($params, $ids);
371
372 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
373 'contact_id', 'Database check for created membership.'
374 );
375 $yearStart = date('Y') . '0101';
376 $currentDate = date('Ymd');
377 CRM_Member_BAO_Membership::getMembershipStarts($this->_membershipTypeID, $yearStart, $currentDate);
378
379 $this->membershipDelete($membershipId);
380 $this->contactDelete($contactId);
381 }
382
383 /**
384 * Get a count of membership for a specified membership type,
385 * optionally for a specified date.
386 */
387 public function testGetMembershipCount() {
388 $contactId = $this->individualCreate();
389
390 $params = array(
391 'contact_id' => $contactId,
392 'membership_type_id' => $this->_membershipTypeID,
393 'join_date' => date('Ymd', strtotime('2006-01-21')),
394 'start_date' => date('Ymd', strtotime('2006-01-21')),
395 'end_date' => date('Ymd', strtotime('2006-12-21')),
396 'source' => 'Payment',
397 'is_override' => 1,
398 'status_id' => $this->_membershipStatusID,
399 );
400 $ids = array();
401 CRM_Member_BAO_Membership::create($params, $ids);
402
403 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
404 'contact_id', 'Database check for created membership.'
405 );
406 $currentDate = date('Ymd');
407 $test = 0;
408 CRM_Member_BAO_Membership::getMembershipCount($this->_membershipTypeID, $currentDate, $test);
409
410 $this->membershipDelete($membershipId);
411 $this->contactDelete($contactId);
412 }
413
414
415 /**
416 * Checkup sort name function.
417 */
418 public function testSortName() {
419 $contactId = $this->individualCreate();
420
421 $params = array(
422 'contact_id' => $contactId,
423 'membership_type_id' => $this->_membershipTypeID,
424 'join_date' => '2006-01-21',
425 'start_date' => '2006-01-21',
426 'end_date' => '2006-12-21',
427 'source' => 'Payment',
428 'is_override' => 1,
429 'status_id' => $this->_membershipStatusID,
430 );
431
432 $membership = $this->callAPISuccess('Membership', 'create', $params);
433
434 $this->assertEquals('Anderson, Anthony', CRM_Member_BAO_Membership::sortName($membership['id']));
435
436 $this->membershipDelete($membership['id']);
437 $this->contactDelete($contactId);
438 }
439
440 /**
441 * Delete related memberships.
442 */
443 public function testdeleteRelatedMemberships() {
444 $contactId = $this->individualCreate();
445
446 $params = array(
447 'contact_id' => $contactId,
448 'membership_type_id' => $this->_membershipTypeID,
449 'join_date' => date('Ymd', strtotime('2006-01-21')),
450 'start_date' => date('Ymd', strtotime('2006-01-21')),
451 'end_date' => date('Ymd', strtotime('2006-12-21')),
452 'source' => 'Payment',
453 'is_override' => 1,
454 'status_id' => $this->_membershipStatusID,
455 );
456 $ids = array();
457
458 CRM_Member_BAO_Membership::create($params, $ids);
459
460 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
461 'contact_id', 'Database check for created membership.'
462 );
463
464 CRM_Member_BAO_Membership::deleteRelatedMemberships($membershipId);
465
466 $this->membershipDelete($membershipId);
467 $this->contactDelete($contactId);
468 }
469
470 /**
471 * Renew membership with change in membership type.
472 */
473 public function testRenewMembership() {
474 $contactId = $this->individualCreate();
475 $joinDate = $startDate = date("Ymd", strtotime(date("Ymd") . " -6 month"));
476 $endDate = date("Ymd", strtotime($joinDate . " +1 year -1 day"));
477 $params = array(
478 'contact_id' => $contactId,
479 'membership_type_id' => $this->_membershipTypeID,
480 'join_date' => $joinDate,
481 'start_date' => $startDate,
482 'end_date' => $endDate,
483 'source' => 'Payment',
484 'is_override' => 1,
485 'status_id' => $this->_membershipStatusID,
486 );
487 $ids = array();
488 $membership = CRM_Member_BAO_Membership::create($params, $ids);
489 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
490 'contact_id', 'Database check for created membership.'
491 );
492
493 $this->assertDBNotNull('CRM_Member_BAO_MembershipLog',
494 $membership->id,
495 'id',
496 'membership_id',
497 'Database checked on membershiplog record.'
498 );
499
500 // this is a test and we dont want qfKey generation / validation
501 // easier to suppress it, than change core code
502 $config = CRM_Core_Config::singleton();
503 $config->keyDisable = TRUE;
504
505 $isTestMembership = 0;
506 list($MembershipRenew) = CRM_Member_BAO_Membership::processMembership(
507 $contactId,
508 $this->_membershipTypeID,
509 $isTestMembership,
510 NULL,
511 NULL,
512 NULL,
513 1,
514 FALSE,
515 NULL,
516 NULL,
517 FALSE,
518 NULL,
519 NULL
520 );
521 $endDate = date("Y-m-d", strtotime($membership->end_date . " +1 year"));
522
523 $this->assertDBNotNull('CRM_Member_BAO_MembershipLog',
524 $MembershipRenew->id,
525 'id',
526 'membership_id',
527 'Database checked on membershiplog record.'
528 );
529 $this->assertEquals($this->_membershipTypeID, $MembershipRenew->membership_type_id, 'Verify membership type is changed during renewal.');
530 $this->assertEquals($endDate, $MembershipRenew->end_date, 'Verify correct end date is calculated after membership renewal');
531
532 $this->membershipDelete($membershipId);
533 $this->contactDelete($contactId);
534 }
535
536 /**
537 * Renew stale membership.
538 */
539 public function testStaleMembership() {
540 $statusId = 3;
541 $contactId = $this->individualCreate();
542 $joinDate = $startDate = date("Ymd", strtotime(date("Ymd") . " -1 year -15 days"));
543 $endDate = date("Ymd", strtotime($joinDate . " +1 year -1 day"));
544 $params = array(
545 'contact_id' => $contactId,
546 'membership_type_id' => $this->_membershipTypeID,
547 'join_date' => $joinDate,
548 'start_date' => $startDate,
549 'end_date' => $endDate,
550 'source' => 'Payment',
551 'status_id' => $statusId,
552 );
553
554 $ids = array();
555 $membership = CRM_Member_BAO_Membership::create($params, $ids);
556
557 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
558 'contact_id', 'Database check for created membership.'
559 );
560
561 $this->assertEquals($membership->status_id, $statusId, 'Verify correct status id is calculated.');
562 $this->assertEquals($membership->membership_type_id, $this->_membershipTypeID,
563 'Verify correct membership type id.'
564 );
565
566 //verify all dates.
567 $dates = array(
568 'startDate' => 'start_date',
569 'joinDate' => 'join_date',
570 'endDate' => 'end_date',
571 );
572
573 foreach ($dates as $date => $dbDate) {
574 $this->assertEquals($membership->$dbDate, $$date,
575 "Verify correct {$date} is present."
576 );
577 }
578
579 $this->assertDBNotNull('CRM_Member_BAO_MembershipLog',
580 $membership->id,
581 'id',
582 'membership_id',
583 'Database checked on membershiplog record.'
584 );
585
586 // this is a test and we dont want qfKey generation / validation
587 // easier to suppress it, than change core code
588 $config = CRM_Core_Config::singleton();
589 $config->keyDisable = TRUE;
590
591 $membershipRenewal = new CRM_Core_Form();
592 $membershipRenewal->controller = new CRM_Core_Controller();
593 list($MembershipRenew) = CRM_Member_BAO_Membership::processMembership(
594 $contactId,
595 $this->_membershipTypeID,
596 FALSE,
597 $membershipRenewal,
598 NULL,
599 NULL,
600 NULL,
601 1,
602 NULL,
603 NULL,
604 NULL,
605 FALSE,
606 NULL
607 );
608
609 $this->assertDBNotNull('CRM_Member_BAO_MembershipLog',
610 $MembershipRenew->id,
611 'id',
612 'membership_id',
613 'Database checked on membershiplog record.'
614 );
615
616 $this->membershipDelete($membershipId);
617 $this->contactDelete($contactId);
618 }
619
620 }