3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
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.
41 class CRM_Member_Form_MembershipTest
extends CiviUnitTestCase
{
44 * Assume empty database with just civicrm_data.
46 protected $_individualId;
47 protected $_contribution;
48 protected $_financialTypeId = 1;
49 protected $_apiversion;
50 protected $_entity = 'Membership';
52 protected $_ids = array();
53 protected $_paymentProcessorID;
56 * Membership type ID for annual fixed membership.
60 protected $membershipTypeAnnualFixedID;
63 * Parameters to create payment processor.
67 protected $_processorParams = array();
70 * ID of created membership.
74 protected $_membershipID;
77 * Payment instrument mapping.
81 protected $paymentInstruments = array();
84 * Test setup for every test.
86 * Connect to the database, truncate the tables that will be used
87 * and redirect stdin to a temporary file.
89 public function setUp() {
90 $this->_apiversion
= 3;
93 $this->_individualId
= $this->individualCreate();
94 $this->_paymentProcessorID
= $this->processorCreate();
96 $op = new PHPUnit_Extensions_Database_Operation_Insert();
97 $op->execute($this->_dbconn
,
98 $this->createFlatXMLDataSet(
99 dirname(__FILE__
) . '/dataset/data.xml'
102 $membershipTypeAnnualFixed = $this->callAPISuccess('membership_type', 'create', array(
104 'name' => "AnnualFixed",
105 'member_of_contact_id' => 23,
106 'duration_unit' => "year",
107 'duration_interval' => 1,
108 'period_type' => "fixed",
109 'fixed_period_start_day' => "101",
110 'fixed_period_rollover_day' => "1231",
111 'relationship_type_id' => 20,
112 'financial_type_id' => 2,
114 $this->membershipTypeAnnualFixedID
= $membershipTypeAnnualFixed['id'];
116 $instruments = $this->callAPISuccess('contribution', 'getoptions', array('field' => 'payment_instrument_id'));
117 $this->paymentInstruments
= $instruments['values'];
121 * Clean up after each test.
123 public function tearDown() {
124 $this->quickCleanUpFinancialEntities();
127 'civicrm_relationship',
128 'civicrm_membership_type',
129 'civicrm_membership',
133 $this->callAPISuccess('contact', 'delete', array('id' => 17, 'skip_undelete' => TRUE));
134 $this->callAPISuccess('contact', 'delete', array('id' => 23, 'skip_undelete' => TRUE));
135 $this->callAPISuccess('relationship_type', 'delete', array('id' => 20));
139 * Test CRM_Member_Form_Membership::buildQuickForm()
141 //function testCRMMemberFormMembershipBuildQuickForm()
143 // throw new PHPUnit_Framework_IncompleteTestError( "not implemented" );
147 * Test CRM_Member_Form_Membership::formRule() with a parameter
148 * that has an empty contact_select_id value
150 public function testFormRuleEmptyContact() {
152 'contact_select_id' => 0,
153 'membership_type_id' => array(1 => NULL),
156 $obj = new CRM_Member_Form_Membership();
157 $rc = $obj->formRule($params, $files, $obj);
158 $this->assertType('array', $rc);
159 $this->assertTrue(array_key_exists('membership_type_id', $rc));
161 $params['membership_type_id'] = array(1 => 3);
162 $rc = $obj->formRule($params, $files, $obj);
163 $this->assertType('array', $rc);
164 $this->assertTrue(array_key_exists('join_date', $rc));
168 * Test that form rule fails if start date is before join date.
170 * Test CRM_Member_Form_Membership::formRule() with a parameter
171 * that has an start date before the join date and a rolling
174 public function testFormRuleRollingEarlyStart() {
176 $ymdNow = date('m/d/Y', $unixNow);
177 $unixYesterday = $unixNow - (24 * 60 * 60);
178 $ymdYesterday = date('m/d/Y', $unixYesterday);
180 'join_date' => $ymdNow,
181 'start_date' => $ymdYesterday,
183 'membership_type_id' => array('23', '15'),
186 $obj = new CRM_Member_Form_Membership();
187 $rc = call_user_func(array('CRM_Member_Form_Membership', 'formRule'),
188 $params, $files, $obj
190 $this->assertType('array', $rc);
191 $this->assertTrue(array_key_exists('start_date', $rc));
195 * Test CRM_Member_Form_Membership::formRule() with a parameter
196 * that has an end date before the start date and a rolling
199 public function testFormRuleRollingEarlyEnd() {
201 $ymdNow = date('m/d/Y', $unixNow);
202 $unixYesterday = $unixNow - (24 * 60 * 60);
203 $ymdYesterday = date('m/d/Y', $unixYesterday);
205 'join_date' => $ymdNow,
206 'start_date' => $ymdNow,
207 'end_date' => $ymdYesterday,
208 'membership_type_id' => array('23', '15'),
211 $obj = new CRM_Member_Form_Membership();
212 $rc = $obj->formRule($params, $files, $obj);
213 $this->assertType('array', $rc);
214 $this->assertTrue(array_key_exists('end_date', $rc));
218 * Test CRM_Member_Form_Membership::formRule() with end date but no start date and a rolling membership type.
220 public function testFormRuleRollingEndNoStart() {
222 $ymdNow = date('m/d/Y', $unixNow);
223 $unixYearFromNow = $unixNow +
(365 * 24 * 60 * 60);
224 $ymdYearFromNow = date('m/d/Y', $unixYearFromNow);
226 'join_date' => $ymdNow,
228 'end_date' => $ymdYearFromNow,
229 'membership_type_id' => array('23', '15'),
232 $obj = new CRM_Member_Form_Membership();
233 $rc = $obj->formRule($params, $files, $obj);
234 $this->assertType('array', $rc);
235 $this->assertTrue(array_key_exists('start_date', $rc));
239 * Test CRM_Member_Form_Membership::formRule() with a parameter
240 * that has an end date and a lifetime membership type
242 public function testFormRuleRollingLifetimeEnd() {
244 $unixYearFromNow = $unixNow +
(365 * 24 * 60 * 60);
246 'join_date' => date('m/d/Y', $unixNow),
247 'start_date' => date('m/d/Y', $unixNow),
248 'end_date' => date('m/d/Y',
251 'membership_type_id' => array('23', '25'),
254 $obj = new CRM_Member_Form_Membership();
255 $rc = $obj->formRule($params, $files, $obj);
256 $this->assertType('array', $rc);
257 $this->assertTrue(array_key_exists('status_id', $rc));
261 * Test CRM_Member_Form_Membership::formRule() with a parameter
262 * that has an override and no status
264 public function testFormRuleOverrideNoStatus() {
267 'join_date' => date('m/d/Y', $unixNow),
268 'membership_type_id' => array('23', '25'),
269 'is_override' => TRUE,
272 $obj = new CRM_Member_Form_Membership();
273 $rc = $obj->formRule($params, $files, $obj);
274 $this->assertType('array', $rc);
275 $this->assertTrue(array_key_exists('status_id', $rc));
279 * Test CRM_Member_Form_Membership::formRule() with a join date
280 * of one month from now and a rolling membership type
282 public function testFormRuleRollingJoin1MonthFromNow() {
284 $unix1MFmNow = $unixNow +
(31 * 24 * 60 * 60);
286 'join_date' => date('m/d/Y', $unix1MFmNow),
289 'membership_type_id' => array('23', '15'),
292 $obj = new CRM_Member_Form_Membership();
293 $rc = $obj->formRule($params, $files, $obj);
295 // Should have found no valid membership status.
296 $this->assertType('array', $rc);
297 $this->assertTrue(array_key_exists('_qf_default', $rc));
301 * Test CRM_Member_Form_Membership::formRule() with a join date of today and a rolling membership type.
303 public function testFormRuleRollingJoinToday() {
306 'join_date' => date('m/d/Y', $unixNow),
309 'membership_type_id' => array('23', '15'),
312 $obj = new CRM_Member_Form_Membership();
313 $rc = $obj->formRule($params, $files, $obj);
315 // Should have found New membership status
316 $this->assertTrue($rc);
320 * Test CRM_Member_Form_Membership::formRule() with a join date
321 * of one month ago and a rolling membership type
323 public function testFormRuleRollingJoin1MonthAgo() {
325 $unix1MAgo = $unixNow - (31 * 24 * 60 * 60);
327 'join_date' => date('m/d/Y', $unix1MAgo),
330 'membership_type_id' => array('23', '15'),
333 $obj = new CRM_Member_Form_Membership();
334 $rc = $obj->formRule($params, $files, $obj);
336 // Should have found New membership status.
337 $this->assertTrue($rc);
341 * Test CRM_Member_Form_Membership::formRule() with a join date of six months ago and a rolling membership type.
343 public function testFormRuleRollingJoin6MonthsAgo() {
345 $unix6MAgo = $unixNow - (180 * 24 * 60 * 60);
347 'join_date' => date('m/d/Y', $unix6MAgo),
350 'membership_type_id' => array('23', '15'),
353 $obj = new CRM_Member_Form_Membership();
354 $rc = $obj->formRule($params, $files, $obj);
356 // Should have found Current membership status.
357 $this->assertTrue($rc);
361 * Test CRM_Member_Form_Membership::formRule() with a join date
362 * of one year+ ago and a rolling membership type
364 public function testFormRuleRollingJoin1YearAgo() {
366 $unix1YAgo = $unixNow - (370 * 24 * 60 * 60);
368 'join_date' => date('m/d/Y', $unix1YAgo),
371 'membership_type_id' => array('23', '15'),
374 $obj = new CRM_Member_Form_Membership();
375 $rc = $obj->formRule($params, $files, $obj);
377 // Should have found Grace membership status
378 $this->assertTrue($rc);
382 * Test CRM_Member_Form_Membership::formRule() with a join date
383 * of two years ago and a rolling membership type
385 public function testFormRuleRollingJoin2YearsAgo() {
387 $unix2YAgo = $unixNow - (2 * 365 * 24 * 60 * 60);
389 'join_date' => date('m/d/Y', $unix2YAgo),
392 'membership_type_id' => array('23', '15'),
395 $obj = new CRM_Member_Form_Membership();
396 $rc = $obj->formRule($params, $files, $obj);
398 // Should have found Expired membership status
399 $this->assertTrue($rc);
403 * Test CRM_Member_Form_Membership::formRule() with a join date
404 * of six months ago and a fixed membership type
406 public function testFormRuleFixedJoin6MonthsAgo() {
408 $unix6MAgo = $unixNow - (180 * 24 * 60 * 60);
410 'join_date' => date('m/d/Y', $unix6MAgo),
413 'membership_type_id' => array('23', '7'),
416 $obj = new CRM_Member_Form_Membership();
417 $rc = $obj->formRule($params, $files, $obj);
419 // Should have found Current membership status
420 $this->assertTrue($rc);
424 * Test the submit function of the membership form.
426 public function testSubmit() {
427 $form = $this->getForm();
428 $form->_mode
= 'test';
429 $this->createLoggedInUser();
431 'cid' => $this->_individualId
,
432 'join_date' => date('m/d/Y', time()),
435 // This format reflects the 23 being the organisation & the 25 being the type.
436 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID
),
441 'total_amount' => '50.00',
442 'financial_type_id' => '2', //Member dues, see data.xml
443 'soft_credit_type_id' => '',
444 'soft_credit_contact_id' => '',
445 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
446 'receipt_text_signup' => 'Thank you text',
447 'payment_processor_id' => $this->_paymentProcessorID
,
448 'credit_card_number' => '4111111111111111',
450 'credit_card_exp_date' => array(
452 'Y' => '2024', // TODO: Future proof
454 'credit_card_type' => 'Visa',
455 'billing_first_name' => 'Test',
456 'billing_middlename' => 'Last',
457 'billing_street_address-5' => '10 Test St',
458 'billing_city-5' => 'Test',
459 'billing_state_province_id-5' => '1003',
460 'billing_postal_code-5' => '90210',
461 'billing_country_id-5' => '1228',
463 $form->_contactID
= $this->_individualId
;
464 $form->testSubmit($params);
465 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
466 $this->callAPISuccessGetCount('ContributionRecur', array('contact_id' => $this->_individualId
), 0);
467 $contribution = $this->callAPISuccess('Contribution', 'get', array(
468 'contact_id' => $this->_individualId
,
472 $this->callAPISuccessGetCount('LineItem', array(
473 'entity_id' => $membership['id'],
474 'entity_table' => 'civicrm_membership',
475 'contribution_id' => $contribution['id'],
480 * Test the submit function of the membership form.
482 public function testSubmitRecur() {
483 $form = $this->getForm();
485 $this->callAPISuccess('MembershipType', 'create', array(
486 'id' => $this->membershipTypeAnnualFixedID
,
487 'duration_unit' => 'month',
488 'duration_interval' => 1,
489 'auto_renew' => TRUE,
492 $this->createLoggedInUser();
493 $params = $this->getBaseSubmitParams();
494 $form->_mode
= 'test';
495 $form->_contactID
= $this->_individualId
;
496 $form->testSubmit($params);
497 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
498 $this->callAPISuccessGetCount('ContributionRecur', array('contact_id' => $this->_individualId
), 1);
500 $contribution = $this->callAPISuccess('Contribution', 'get', array(
501 'contact_id' => $this->_individualId
,
506 $this->callAPISuccessGetCount('LineItem', array(
507 'entity_id' => $membership['id'],
508 'entity_table' => 'civicrm_membership',
509 'contribution_id' => $contribution['id'],
514 * Test the submit function of the membership form.
516 public function testSubmitPayLaterWithBilling() {
517 $form = $this->getForm(NULL);
518 $this->createLoggedInUser();
520 'cid' => $this->_individualId
,
521 'join_date' => date('m/d/Y', time()),
524 // This format reflects the 23 being the organisation & the 25 being the type.
525 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID
),
530 'total_amount' => '50.00',
531 //Member dues, see data.xml
532 'financial_type_id' => '2',
533 'soft_credit_type_id' => '',
534 'soft_credit_contact_id' => '',
535 'payment_instrument_id' => 4,
536 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
537 'receipt_text_signup' => 'Thank you text',
538 'payment_processor_id' => $this->_paymentProcessorID
,
539 'record_contribution' => TRUE,
541 'contribution_status_id' => 2,
542 'billing_first_name' => 'Test',
543 'billing_middlename' => 'Last',
544 'billing_street_address-5' => '10 Test St',
545 'billing_city-5' => 'Test',
546 'billing_state_province_id-5' => '1003',
547 'billing_postal_code-5' => '90210',
548 'billing_country_id-5' => '1228',
550 $form->_contactID
= $this->_individualId
;
552 $form->testSubmit($params);
553 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
554 $contribution = $this->callAPISuccessGetSingle('Contribution', array(
555 'contact_id' => $this->_individualId
,
556 'contribution_status_id' => 2,
558 $this->assertEquals($contribution['trxn_id'], 777);
560 $this->callAPISuccessGetCount('LineItem', array(
561 'entity_id' => $membership['id'],
562 'entity_table' => 'civicrm_membership',
563 'contribution_id' => $contribution['id'],
565 $this->callAPISuccessGetSingle('address', array(
566 'contact_id' => $this->_individualId
,
567 'street_address' => '10 Test St',
568 'postal_code' => 90210,
573 * Test the submit function of the membership form.
575 public function testSubmitRecurCompleteInstant() {
576 $form = $this->getForm();
577 $mut = new CiviMailUtils($this, TRUE);
578 $processor = Civi\Payment\System
::singleton()->getById($this->_paymentProcessorID
);
579 $processor->setDoDirectPaymentResult(array(
580 'payment_status_id' => 1,
581 'trxn_id' => 'kettles boil water',
584 $this->callAPISuccess('MembershipType', 'create', array(
585 'id' => $this->membershipTypeAnnualFixedID
,
586 'duration_unit' => 'month',
587 'duration_interval' => 1,
588 'auto_renew' => TRUE,
591 $this->createLoggedInUser();
592 $params = $this->getBaseSubmitParams();
593 $form->_mode
= 'test';
594 $form->_contactID
= $this->_individualId
;
595 $form->testSubmit($params);
596 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
597 $this->callAPISuccessGetCount('ContributionRecur', array('contact_id' => $this->_individualId
), 1);
599 $contribution = $this->callAPISuccess('Contribution', 'getsingle', array(
600 'contact_id' => $this->_individualId
,
604 $this->assertEquals(.14, $contribution['fee_amount']);
605 $this->assertEquals('kettles boil water', $contribution['trxn_id']);
607 $this->callAPISuccessGetCount('LineItem', array(
608 'entity_id' => $membership['id'],
609 'entity_table' => 'civicrm_membership',
610 'contribution_id' => $contribution['id'],
612 $mut->checkMailLog(array(
613 '===========================================================
614 Billing Name and Address
615 ===========================================================
620 '===========================================================
621 Membership Information
622 ===========================================================
623 Membership Type: AnnualFixed
624 Membership Start Date: ',
625 '===========================================================
626 Credit Card Information
627 ===========================================================
638 * Get a membership form object.
640 * We need to instantiate the form to run preprocess, which means we have to trick it about the request method.
642 * @return \CRM_Member_Form_Membership
644 protected function getForm() {
645 $form = new CRM_Member_Form_Membership();
646 $_SERVER['REQUEST_METHOD'] = 'GET';
647 $form->controller
= new CRM_Core_Controller();
655 protected function getBaseSubmitParams() {
657 'cid' => $this->_individualId
,
659 'join_date' => date('m/d/Y', time()),
663 // This format reflects the 23 being the organisation & the 25 being the type.
664 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID
),
670 'total_amount' => '77.00',
671 'financial_type_id' => '2', //Member dues, see data.xml
672 'soft_credit_type_id' => 11,
673 'soft_credit_contact_id' => '',
674 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
675 'receipt_text' => 'Thank you text',
676 'payment_processor_id' => $this->_paymentProcessorID
,
677 'credit_card_number' => '4111111111111111',
679 'credit_card_exp_date' => array(
681 'Y' => '2019', // TODO: Future proof
683 'credit_card_type' => 'Visa',
684 'billing_first_name' => 'Test',
685 'billing_middlename' => 'Last',
686 'billing_street_address-5' => '10 Test St',
687 'billing_city-5' => 'Test',
688 'billing_state_province_id-5' => '1003',
689 'billing_postal_code-5' => '90210',
690 'billing_country_id-5' => '1228',