3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2016 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
29 * File for the MembershipTest class
33 * @author Walt Haas <walt@dharmatech.org> (801) 534-1262
37 * Test CRM_Member_Form_Membership functions.
42 class CRM_Member_Form_MembershipTest
extends CiviUnitTestCase
{
45 * Assume empty database with just civicrm_data.
47 protected $_individualId;
48 protected $_contribution;
49 protected $_financialTypeId = 1;
50 protected $_apiversion;
51 protected $_entity = 'Membership';
53 protected $_ids = array();
54 protected $_paymentProcessorID;
57 * Membership type ID for annual fixed membership.
61 protected $membershipTypeAnnualFixedID;
64 * Parameters to create payment processor.
68 protected $_processorParams = array();
71 * ID of created membership.
75 protected $_membershipID;
78 * Payment instrument mapping.
82 protected $paymentInstruments = array();
90 * Test setup for every test.
92 * Connect to the database, truncate the tables that will be used
93 * and redirect stdin to a temporary file.
95 public function setUp() {
96 $this->_apiversion
= 3;
99 $this->_individualId
= $this->individualCreate();
100 $this->_paymentProcessorID
= $this->processorCreate();
102 $op = new PHPUnit_Extensions_Database_Operation_Insert();
103 $op->execute($this->_dbconn
,
104 $this->createFlatXMLDataSet(
105 dirname(__FILE__
) . '/dataset/data.xml'
108 $membershipTypeAnnualFixed = $this->callAPISuccess('membership_type', 'create', array(
110 'name' => "AnnualFixed",
111 'member_of_contact_id' => 23,
112 'duration_unit' => "year",
113 'duration_interval' => 1,
114 'period_type' => "fixed",
115 'fixed_period_start_day' => "101",
116 'fixed_period_rollover_day' => "1231",
117 'relationship_type_id' => 20,
118 'financial_type_id' => 2,
120 $this->membershipTypeAnnualFixedID
= $membershipTypeAnnualFixed['id'];
122 $instruments = $this->callAPISuccess('contribution', 'getoptions', array('field' => 'payment_instrument_id'));
123 $this->paymentInstruments
= $instruments['values'];
127 * Clean up after each test.
129 public function tearDown() {
130 $this->quickCleanUpFinancialEntities();
133 'civicrm_relationship',
134 'civicrm_membership_type',
135 'civicrm_membership',
139 $this->callAPISuccess('contact', 'delete', array('id' => 17, 'skip_undelete' => TRUE));
140 $this->callAPISuccess('contact', 'delete', array('id' => 23, 'skip_undelete' => TRUE));
141 $this->callAPISuccess('relationship_type', 'delete', array('id' => 20));
145 * Test CRM_Member_Form_Membership::buildQuickForm()
147 //function testCRMMemberFormMembershipBuildQuickForm()
149 // throw new PHPUnit_Framework_IncompleteTestError( "not implemented" );
153 * Test CRM_Member_Form_Membership::formRule() with a parameter
154 * that has an empty contact_select_id value
156 public function testFormRuleEmptyContact() {
158 'contact_select_id' => 0,
159 'membership_type_id' => array(1 => NULL),
162 $obj = new CRM_Member_Form_Membership();
163 $rc = $obj->formRule($params, $files, $obj);
164 $this->assertType('array', $rc);
165 $this->assertTrue(array_key_exists('membership_type_id', $rc));
167 $params['membership_type_id'] = array(1 => 3);
168 $rc = $obj->formRule($params, $files, $obj);
169 $this->assertType('array', $rc);
170 $this->assertTrue(array_key_exists('join_date', $rc));
174 * Test that form rule fails if start date is before join date.
176 * Test CRM_Member_Form_Membership::formRule() with a parameter
177 * that has an start date before the join date and a rolling
180 public function testFormRuleRollingEarlyStart() {
182 $ymdNow = date('m/d/Y', $unixNow);
183 $unixYesterday = $unixNow - (24 * 60 * 60);
184 $ymdYesterday = date('m/d/Y', $unixYesterday);
186 'join_date' => $ymdNow,
187 'start_date' => $ymdYesterday,
189 'membership_type_id' => array('23', '15'),
192 $obj = new CRM_Member_Form_Membership();
193 $rc = call_user_func(array('CRM_Member_Form_Membership', 'formRule'),
194 $params, $files, $obj
196 $this->assertType('array', $rc);
197 $this->assertTrue(array_key_exists('start_date', $rc));
201 * Test CRM_Member_Form_Membership::formRule() with a parameter
202 * that has an end date before the start date and a rolling
205 public function testFormRuleRollingEarlyEnd() {
207 $ymdNow = date('m/d/Y', $unixNow);
208 $unixYesterday = $unixNow - (24 * 60 * 60);
209 $ymdYesterday = date('m/d/Y', $unixYesterday);
211 'join_date' => $ymdNow,
212 'start_date' => $ymdNow,
213 'end_date' => $ymdYesterday,
214 'membership_type_id' => array('23', '15'),
217 $obj = new CRM_Member_Form_Membership();
218 $rc = $obj->formRule($params, $files, $obj);
219 $this->assertType('array', $rc);
220 $this->assertTrue(array_key_exists('end_date', $rc));
224 * Test CRM_Member_Form_Membership::formRule() with end date but no start date and a rolling membership type.
226 public function testFormRuleRollingEndNoStart() {
228 $ymdNow = date('m/d/Y', $unixNow);
229 $unixYearFromNow = $unixNow +
(365 * 24 * 60 * 60);
230 $ymdYearFromNow = date('m/d/Y', $unixYearFromNow);
232 'join_date' => $ymdNow,
234 'end_date' => $ymdYearFromNow,
235 'membership_type_id' => array('23', '15'),
238 $obj = new CRM_Member_Form_Membership();
239 $rc = $obj->formRule($params, $files, $obj);
240 $this->assertType('array', $rc);
241 $this->assertTrue(array_key_exists('start_date', $rc));
245 * Test CRM_Member_Form_Membership::formRule() with a parameter
246 * that has an end date and a lifetime membership type
248 public function testFormRuleRollingLifetimeEnd() {
250 $unixYearFromNow = $unixNow +
(365 * 24 * 60 * 60);
252 'join_date' => date('m/d/Y', $unixNow),
253 'start_date' => date('m/d/Y', $unixNow),
254 'end_date' => date('m/d/Y',
257 'membership_type_id' => array('23', '25'),
260 $obj = new CRM_Member_Form_Membership();
261 $rc = $obj->formRule($params, $files, $obj);
262 $this->assertType('array', $rc);
263 $this->assertTrue(array_key_exists('status_id', $rc));
267 * Test CRM_Member_Form_Membership::formRule() with a parameter
268 * that has an override and no status
270 public function testFormRuleOverrideNoStatus() {
273 'join_date' => date('m/d/Y', $unixNow),
274 'membership_type_id' => array('23', '25'),
275 'is_override' => TRUE,
278 $obj = new CRM_Member_Form_Membership();
279 $rc = $obj->formRule($params, $files, $obj);
280 $this->assertType('array', $rc);
281 $this->assertTrue(array_key_exists('status_id', $rc));
285 * Test CRM_Member_Form_Membership::formRule() with a join date
286 * of one month from now and a rolling membership type
288 public function testFormRuleRollingJoin1MonthFromNow() {
290 $unix1MFmNow = $unixNow +
(31 * 24 * 60 * 60);
292 'join_date' => date('m/d/Y', $unix1MFmNow),
295 'membership_type_id' => array('23', '15'),
298 $obj = new CRM_Member_Form_Membership();
299 $rc = $obj->formRule($params, $files, $obj);
301 // Should have found no valid membership status.
302 $this->assertType('array', $rc);
303 $this->assertTrue(array_key_exists('_qf_default', $rc));
307 * Test CRM_Member_Form_Membership::formRule() with a join date of today and a rolling membership type.
309 public function testFormRuleRollingJoinToday() {
312 'join_date' => date('m/d/Y', $unixNow),
315 'membership_type_id' => array('23', '15'),
318 $obj = new CRM_Member_Form_Membership();
319 $rc = $obj->formRule($params, $files, $obj);
321 // Should have found New membership status
322 $this->assertTrue($rc);
326 * Test CRM_Member_Form_Membership::formRule() with a join date
327 * of one month ago and a rolling membership type
329 public function testFormRuleRollingJoin1MonthAgo() {
331 $unix1MAgo = $unixNow - (31 * 24 * 60 * 60);
333 'join_date' => date('m/d/Y', $unix1MAgo),
336 'membership_type_id' => array('23', '15'),
339 $obj = new CRM_Member_Form_Membership();
340 $rc = $obj->formRule($params, $files, $obj);
342 // Should have found New membership status.
343 $this->assertTrue($rc);
347 * Test CRM_Member_Form_Membership::formRule() with a join date of six months ago and a rolling membership type.
349 public function testFormRuleRollingJoin6MonthsAgo() {
351 $unix6MAgo = $unixNow - (180 * 24 * 60 * 60);
353 'join_date' => date('m/d/Y', $unix6MAgo),
356 'membership_type_id' => array('23', '15'),
359 $obj = new CRM_Member_Form_Membership();
360 $rc = $obj->formRule($params, $files, $obj);
362 // Should have found Current membership status.
363 $this->assertTrue($rc);
367 * Test CRM_Member_Form_Membership::formRule() with a join date
368 * of one year+ ago and a rolling membership type
370 public function testFormRuleRollingJoin1YearAgo() {
372 $unix1YAgo = $unixNow - (370 * 24 * 60 * 60);
374 'join_date' => date('m/d/Y', $unix1YAgo),
377 'membership_type_id' => array('23', '15'),
380 $obj = new CRM_Member_Form_Membership();
381 $rc = $obj->formRule($params, $files, $obj);
383 // Should have found Grace membership status
384 $this->assertTrue($rc);
388 * Test CRM_Member_Form_Membership::formRule() with a join date
389 * of two years ago and a rolling membership type
391 public function testFormRuleRollingJoin2YearsAgo() {
393 $unix2YAgo = $unixNow - (2 * 365 * 24 * 60 * 60);
395 'join_date' => date('m/d/Y', $unix2YAgo),
398 'membership_type_id' => array('23', '15'),
401 $obj = new CRM_Member_Form_Membership();
402 $rc = $obj->formRule($params, $files, $obj);
404 // Should have found Expired membership status
405 $this->assertTrue($rc);
409 * Test CRM_Member_Form_Membership::formRule() with a join date
410 * of six months ago and a fixed membership type
412 public function testFormRuleFixedJoin6MonthsAgo() {
414 $unix6MAgo = $unixNow - (180 * 24 * 60 * 60);
416 'join_date' => date('m/d/Y', $unix6MAgo),
419 'membership_type_id' => array('23', '7'),
422 $obj = new CRM_Member_Form_Membership();
423 $rc = $obj->formRule($params, $files, $obj);
425 // Should have found Current membership status
426 $this->assertTrue($rc);
430 * Test the submit function of the membership form.
432 public function testSubmit() {
433 $form = $this->getForm();
434 $this->mut
= new CiviMailUtils($this, TRUE);
435 $form->_mode
= 'test';
436 $this->createLoggedInUser();
438 'cid' => $this->_individualId
,
439 'join_date' => date('m/d/Y', time()),
442 // This format reflects the 23 being the organisation & the 25 being the type.
443 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID
),
448 'total_amount' => '50.00',
449 'financial_type_id' => '2', //Member dues, see data.xml
450 'soft_credit_type_id' => '',
451 'soft_credit_contact_id' => '',
452 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
453 'payment_processor_id' => $this->_paymentProcessorID
,
454 'credit_card_number' => '4111111111111111',
456 'credit_card_exp_date' => array(
458 'Y' => '2024', // TODO: Future proof
460 'credit_card_type' => 'Visa',
461 'billing_first_name' => 'Test',
462 'billing_middlename' => 'Last',
463 'billing_street_address-5' => '10 Test St',
464 'billing_city-5' => 'Test',
465 'billing_state_province_id-5' => '1003',
466 'billing_postal_code-5' => '90210',
467 'billing_country_id-5' => '1228',
468 'send_receipt' => TRUE,
469 'receipt_text' => 'Receipt text',
471 $form->_contactID
= $this->_individualId
;
472 $form->testSubmit($params);
473 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
474 $this->callAPISuccessGetCount('ContributionRecur', array('contact_id' => $this->_individualId
), 0);
475 $contribution = $this->callAPISuccess('Contribution', 'get', array(
476 'contact_id' => $this->_individualId
,
480 $this->callAPISuccessGetCount('LineItem', array(
481 'entity_id' => $membership['id'],
482 'entity_table' => 'civicrm_membership',
483 'contribution_id' => $contribution['id'],
485 $this->mut
->checkMailLog(array(
493 * Test the submit function of the membership form.
495 public function testSubmitRecur() {
496 $form = $this->getForm();
498 $this->callAPISuccess('MembershipType', 'create', array(
499 'id' => $this->membershipTypeAnnualFixedID
,
500 'duration_unit' => 'month',
501 'duration_interval' => 1,
502 'auto_renew' => TRUE,
505 $this->createLoggedInUser();
506 $params = $this->getBaseSubmitParams();
507 $form->_mode
= 'test';
508 $form->_contactID
= $this->_individualId
;
509 $form->testSubmit($params);
510 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
511 $this->callAPISuccessGetCount('ContributionRecur', array('contact_id' => $this->_individualId
), 1);
513 $contribution = $this->callAPISuccess('Contribution', 'get', array(
514 'contact_id' => $this->_individualId
,
519 $this->callAPISuccessGetCount('LineItem', array(
520 'entity_id' => $membership['id'],
521 'entity_table' => 'civicrm_membership',
522 'contribution_id' => $contribution['id'],
527 * Test the submit function of the membership form.
529 public function testSubmitPayLaterWithBilling() {
530 $form = $this->getForm(NULL);
531 $this->createLoggedInUser();
533 'cid' => $this->_individualId
,
534 'join_date' => date('m/d/Y', time()),
537 // This format reflects the 23 being the organisation & the 25 being the type.
538 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID
),
543 'total_amount' => '50.00',
544 //Member dues, see data.xml
545 'financial_type_id' => '2',
546 'soft_credit_type_id' => '',
547 'soft_credit_contact_id' => '',
548 'payment_instrument_id' => 4,
549 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
550 'receipt_text_signup' => 'Thank you text',
551 'payment_processor_id' => $this->_paymentProcessorID
,
552 'record_contribution' => TRUE,
554 'contribution_status_id' => 2,
555 'billing_first_name' => 'Test',
556 'billing_middlename' => 'Last',
557 'billing_street_address-5' => '10 Test St',
558 'billing_city-5' => 'Test',
559 'billing_state_province_id-5' => '1003',
560 'billing_postal_code-5' => '90210',
561 'billing_country_id-5' => '1228',
563 $form->_contactID
= $this->_individualId
;
565 $form->testSubmit($params);
566 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
567 $contribution = $this->callAPISuccessGetSingle('Contribution', array(
568 'contact_id' => $this->_individualId
,
569 'contribution_status_id' => 2,
571 $this->assertEquals($contribution['trxn_id'], 777);
573 $this->callAPISuccessGetCount('LineItem', array(
574 'entity_id' => $membership['id'],
575 'entity_table' => 'civicrm_membership',
576 'contribution_id' => $contribution['id'],
578 $this->callAPISuccessGetSingle('address', array(
579 'contact_id' => $this->_individualId
,
580 'street_address' => '10 Test St',
581 'postal_code' => 90210,
586 * Test the submit function of the membership form.
588 public function testSubmitRecurCompleteInstant() {
589 $form = $this->getForm();
590 $mut = new CiviMailUtils($this, TRUE);
591 $processor = Civi\Payment\System
::singleton()->getById($this->_paymentProcessorID
);
592 $processor->setDoDirectPaymentResult(array(
593 'payment_status_id' => 1,
594 'trxn_id' => 'kettles boil water',
597 $this->callAPISuccess('MembershipType', 'create', array(
598 'id' => $this->membershipTypeAnnualFixedID
,
599 'duration_unit' => 'month',
600 'duration_interval' => 1,
601 'auto_renew' => TRUE,
604 $this->createLoggedInUser();
605 $params = $this->getBaseSubmitParams();
606 $form->_mode
= 'test';
607 $form->_contactID
= $this->_individualId
;
608 $form->testSubmit($params);
609 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
610 $this->callAPISuccessGetCount('ContributionRecur', array('contact_id' => $this->_individualId
), 1);
612 $contribution = $this->callAPISuccess('Contribution', 'getsingle', array(
613 'contact_id' => $this->_individualId
,
617 $this->assertEquals(.14, $contribution['fee_amount']);
618 $this->assertEquals('kettles boil water', $contribution['trxn_id']);
620 $this->callAPISuccessGetCount('LineItem', array(
621 'entity_id' => $membership['id'],
622 'entity_table' => 'civicrm_membership',
623 'contribution_id' => $contribution['id'],
625 $mut->checkMailLog(array(
626 '===========================================================
627 Billing Name and Address
628 ===========================================================
633 '===========================================================
634 Membership Information
635 ===========================================================
636 Membership Type: AnnualFixed
637 Membership Start Date: ',
638 '===========================================================
639 Credit Card Information
640 ===========================================================
651 * Get a membership form object.
653 * We need to instantiate the form to run preprocess, which means we have to trick it about the request method.
655 * @return \CRM_Member_Form_Membership
657 protected function getForm() {
658 $form = new CRM_Member_Form_Membership();
659 $_SERVER['REQUEST_METHOD'] = 'GET';
660 $form->controller
= new CRM_Core_Controller();
668 protected function getBaseSubmitParams() {
670 'cid' => $this->_individualId
,
672 'join_date' => date('m/d/Y', time()),
676 // This format reflects the 23 being the organisation & the 25 being the type.
677 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID
),
683 'total_amount' => '77.00',
684 'financial_type_id' => '2', //Member dues, see data.xml
685 'soft_credit_type_id' => 11,
686 'soft_credit_contact_id' => '',
687 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
688 'receipt_text' => 'Thank you text',
689 'payment_processor_id' => $this->_paymentProcessorID
,
690 'credit_card_number' => '4111111111111111',
692 'credit_card_exp_date' => array(
694 'Y' => '2019', // TODO: Future proof
696 'credit_card_type' => 'Visa',
697 'billing_first_name' => 'Test',
698 'billing_middlename' => 'Last',
699 'billing_street_address-5' => '10 Test St',
700 'billing_city-5' => 'Test',
701 'billing_state_province_id-5' => '1003',
702 'billing_postal_code-5' => '90210',
703 'billing_country_id-5' => '1228',