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.
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();
85 * Test setup for every test.
87 * Connect to the database, truncate the tables that will be used
88 * and redirect stdin to a temporary file.
90 public function setUp() {
91 $this->_apiversion
= 3;
94 $this->_individualId
= $this->individualCreate();
95 $this->_paymentProcessorID
= $this->processorCreate();
97 $op = new PHPUnit_Extensions_Database_Operation_Insert();
98 $op->execute($this->_dbconn
,
99 $this->createFlatXMLDataSet(
100 dirname(__FILE__
) . '/dataset/data.xml'
103 $membershipTypeAnnualFixed = $this->callAPISuccess('membership_type', 'create', array(
105 'name' => "AnnualFixed",
106 'member_of_contact_id' => 23,
107 'duration_unit' => "year",
108 'duration_interval' => 1,
109 'period_type' => "fixed",
110 'fixed_period_start_day' => "101",
111 'fixed_period_rollover_day' => "1231",
112 'relationship_type_id' => 20,
113 'financial_type_id' => 2,
115 $this->membershipTypeAnnualFixedID
= $membershipTypeAnnualFixed['id'];
117 $instruments = $this->callAPISuccess('contribution', 'getoptions', array('field' => 'payment_instrument_id'));
118 $this->paymentInstruments
= $instruments['values'];
122 * Clean up after each test.
124 public function tearDown() {
125 $this->quickCleanUpFinancialEntities();
128 'civicrm_relationship',
129 'civicrm_membership_type',
130 'civicrm_membership',
134 $this->callAPISuccess('contact', 'delete', array('id' => 17, 'skip_undelete' => TRUE));
135 $this->callAPISuccess('contact', 'delete', array('id' => 23, 'skip_undelete' => TRUE));
136 $this->callAPISuccess('relationship_type', 'delete', array('id' => 20));
140 * Test CRM_Member_Form_Membership::buildQuickForm()
142 //function testCRMMemberFormMembershipBuildQuickForm()
144 // throw new PHPUnit_Framework_IncompleteTestError( "not implemented" );
148 * Test CRM_Member_Form_Membership::formRule() with a parameter
149 * that has an empty contact_select_id value
151 public function testFormRuleEmptyContact() {
153 'contact_select_id' => 0,
154 'membership_type_id' => array(1 => NULL),
157 $obj = new CRM_Member_Form_Membership();
158 $rc = $obj->formRule($params, $files, $obj);
159 $this->assertType('array', $rc);
160 $this->assertTrue(array_key_exists('membership_type_id', $rc));
162 $params['membership_type_id'] = array(1 => 3);
163 $rc = $obj->formRule($params, $files, $obj);
164 $this->assertType('array', $rc);
165 $this->assertTrue(array_key_exists('join_date', $rc));
169 * Test that form rule fails if start date is before join date.
171 * Test CRM_Member_Form_Membership::formRule() with a parameter
172 * that has an start date before the join date and a rolling
175 public function testFormRuleRollingEarlyStart() {
177 $ymdNow = date('m/d/Y', $unixNow);
178 $unixYesterday = $unixNow - (24 * 60 * 60);
179 $ymdYesterday = date('m/d/Y', $unixYesterday);
181 'join_date' => $ymdNow,
182 'start_date' => $ymdYesterday,
184 'membership_type_id' => array('23', '15'),
187 $obj = new CRM_Member_Form_Membership();
188 $rc = call_user_func(array('CRM_Member_Form_Membership', 'formRule'),
189 $params, $files, $obj
191 $this->assertType('array', $rc);
192 $this->assertTrue(array_key_exists('start_date', $rc));
196 * Test CRM_Member_Form_Membership::formRule() with a parameter
197 * that has an end date before the start date and a rolling
200 public function testFormRuleRollingEarlyEnd() {
202 $ymdNow = date('m/d/Y', $unixNow);
203 $unixYesterday = $unixNow - (24 * 60 * 60);
204 $ymdYesterday = date('m/d/Y', $unixYesterday);
206 'join_date' => $ymdNow,
207 'start_date' => $ymdNow,
208 'end_date' => $ymdYesterday,
209 'membership_type_id' => array('23', '15'),
212 $obj = new CRM_Member_Form_Membership();
213 $rc = $obj->formRule($params, $files, $obj);
214 $this->assertType('array', $rc);
215 $this->assertTrue(array_key_exists('end_date', $rc));
219 * Test CRM_Member_Form_Membership::formRule() with end date but no start date and a rolling membership type.
221 public function testFormRuleRollingEndNoStart() {
223 $ymdNow = date('m/d/Y', $unixNow);
224 $unixYearFromNow = $unixNow +
(365 * 24 * 60 * 60);
225 $ymdYearFromNow = date('m/d/Y', $unixYearFromNow);
227 'join_date' => $ymdNow,
229 'end_date' => $ymdYearFromNow,
230 'membership_type_id' => array('23', '15'),
233 $obj = new CRM_Member_Form_Membership();
234 $rc = $obj->formRule($params, $files, $obj);
235 $this->assertType('array', $rc);
236 $this->assertTrue(array_key_exists('start_date', $rc));
240 * Test CRM_Member_Form_Membership::formRule() with a parameter
241 * that has an end date and a lifetime membership type
243 public function testFormRuleRollingLifetimeEnd() {
245 $unixYearFromNow = $unixNow +
(365 * 24 * 60 * 60);
247 'join_date' => date('m/d/Y', $unixNow),
248 'start_date' => date('m/d/Y', $unixNow),
249 'end_date' => date('m/d/Y',
252 'membership_type_id' => array('23', '25'),
255 $obj = new CRM_Member_Form_Membership();
256 $rc = $obj->formRule($params, $files, $obj);
257 $this->assertType('array', $rc);
258 $this->assertTrue(array_key_exists('status_id', $rc));
262 * Test CRM_Member_Form_Membership::formRule() with a parameter
263 * that has an override and no status
265 public function testFormRuleOverrideNoStatus() {
268 'join_date' => date('m/d/Y', $unixNow),
269 'membership_type_id' => array('23', '25'),
270 'is_override' => TRUE,
273 $obj = new CRM_Member_Form_Membership();
274 $rc = $obj->formRule($params, $files, $obj);
275 $this->assertType('array', $rc);
276 $this->assertTrue(array_key_exists('status_id', $rc));
280 * Test CRM_Member_Form_Membership::formRule() with a join date
281 * of one month from now and a rolling membership type
283 public function testFormRuleRollingJoin1MonthFromNow() {
285 $unix1MFmNow = $unixNow +
(31 * 24 * 60 * 60);
287 'join_date' => date('m/d/Y', $unix1MFmNow),
290 'membership_type_id' => array('23', '15'),
293 $obj = new CRM_Member_Form_Membership();
294 $rc = $obj->formRule($params, $files, $obj);
296 // Should have found no valid membership status.
297 $this->assertType('array', $rc);
298 $this->assertTrue(array_key_exists('_qf_default', $rc));
302 * Test CRM_Member_Form_Membership::formRule() with a join date of today and a rolling membership type.
304 public function testFormRuleRollingJoinToday() {
307 'join_date' => date('m/d/Y', $unixNow),
310 'membership_type_id' => array('23', '15'),
313 $obj = new CRM_Member_Form_Membership();
314 $rc = $obj->formRule($params, $files, $obj);
316 // Should have found New membership status
317 $this->assertTrue($rc);
321 * Test CRM_Member_Form_Membership::formRule() with a join date
322 * of one month ago and a rolling membership type
324 public function testFormRuleRollingJoin1MonthAgo() {
326 $unix1MAgo = $unixNow - (31 * 24 * 60 * 60);
328 'join_date' => date('m/d/Y', $unix1MAgo),
331 'membership_type_id' => array('23', '15'),
334 $obj = new CRM_Member_Form_Membership();
335 $rc = $obj->formRule($params, $files, $obj);
337 // Should have found New membership status.
338 $this->assertTrue($rc);
342 * Test CRM_Member_Form_Membership::formRule() with a join date of six months ago and a rolling membership type.
344 public function testFormRuleRollingJoin6MonthsAgo() {
346 $unix6MAgo = $unixNow - (180 * 24 * 60 * 60);
348 'join_date' => date('m/d/Y', $unix6MAgo),
351 'membership_type_id' => array('23', '15'),
354 $obj = new CRM_Member_Form_Membership();
355 $rc = $obj->formRule($params, $files, $obj);
357 // Should have found Current membership status.
358 $this->assertTrue($rc);
362 * Test CRM_Member_Form_Membership::formRule() with a join date
363 * of one year+ ago and a rolling membership type
365 public function testFormRuleRollingJoin1YearAgo() {
367 $unix1YAgo = $unixNow - (370 * 24 * 60 * 60);
369 'join_date' => date('m/d/Y', $unix1YAgo),
372 'membership_type_id' => array('23', '15'),
375 $obj = new CRM_Member_Form_Membership();
376 $rc = $obj->formRule($params, $files, $obj);
378 // Should have found Grace membership status
379 $this->assertTrue($rc);
383 * Test CRM_Member_Form_Membership::formRule() with a join date
384 * of two years ago and a rolling membership type
386 public function testFormRuleRollingJoin2YearsAgo() {
388 $unix2YAgo = $unixNow - (2 * 365 * 24 * 60 * 60);
390 'join_date' => date('m/d/Y', $unix2YAgo),
393 'membership_type_id' => array('23', '15'),
396 $obj = new CRM_Member_Form_Membership();
397 $rc = $obj->formRule($params, $files, $obj);
399 // Should have found Expired membership status
400 $this->assertTrue($rc);
404 * Test CRM_Member_Form_Membership::formRule() with a join date
405 * of six months ago and a fixed membership type
407 public function testFormRuleFixedJoin6MonthsAgo() {
409 $unix6MAgo = $unixNow - (180 * 24 * 60 * 60);
411 'join_date' => date('m/d/Y', $unix6MAgo),
414 'membership_type_id' => array('23', '7'),
417 $obj = new CRM_Member_Form_Membership();
418 $rc = $obj->formRule($params, $files, $obj);
420 // Should have found Current membership status
421 $this->assertTrue($rc);
425 * Test the submit function of the membership form.
427 public function testSubmit() {
428 $form = $this->getForm();
429 $form->_mode
= 'test';
430 $this->createLoggedInUser();
432 'cid' => $this->_individualId
,
433 'join_date' => date('m/d/Y', time()),
436 // This format reflects the 23 being the organisation & the 25 being the type.
437 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID
),
442 'total_amount' => '50.00',
443 'financial_type_id' => '2', //Member dues, see data.xml
444 'soft_credit_type_id' => '',
445 'soft_credit_contact_id' => '',
446 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
447 'receipt_text_signup' => 'Thank you text',
448 'payment_processor_id' => $this->_paymentProcessorID
,
449 'credit_card_number' => '4111111111111111',
451 'credit_card_exp_date' => array(
453 'Y' => '2024', // TODO: Future proof
455 'credit_card_type' => 'Visa',
456 'billing_first_name' => 'Test',
457 'billing_middlename' => 'Last',
458 'billing_street_address-5' => '10 Test St',
459 'billing_city-5' => 'Test',
460 'billing_state_province_id-5' => '1003',
461 'billing_postal_code-5' => '90210',
462 'billing_country_id-5' => '1228',
464 $form->_contactID
= $this->_individualId
;
465 $form->testSubmit($params);
466 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
467 $this->callAPISuccessGetCount('ContributionRecur', array('contact_id' => $this->_individualId
), 0);
468 $contribution = $this->callAPISuccess('Contribution', 'get', array(
469 'contact_id' => $this->_individualId
,
473 $this->callAPISuccessGetCount('LineItem', array(
474 'entity_id' => $membership['id'],
475 'entity_table' => 'civicrm_membership',
476 'contribution_id' => $contribution['id'],
481 * Test the submit function of the membership form.
483 public function testSubmitRecur() {
484 $form = $this->getForm();
486 $this->callAPISuccess('MembershipType', 'create', array(
487 'id' => $this->membershipTypeAnnualFixedID
,
488 'duration_unit' => 'month',
489 'duration_interval' => 1,
490 'auto_renew' => TRUE,
493 $this->createLoggedInUser();
494 $params = $this->getBaseSubmitParams();
495 $form->_mode
= 'test';
496 $form->_contactID
= $this->_individualId
;
497 $form->testSubmit($params);
498 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
499 $this->callAPISuccessGetCount('ContributionRecur', array('contact_id' => $this->_individualId
), 1);
501 $contribution = $this->callAPISuccess('Contribution', 'get', array(
502 'contact_id' => $this->_individualId
,
507 $this->callAPISuccessGetCount('LineItem', array(
508 'entity_id' => $membership['id'],
509 'entity_table' => 'civicrm_membership',
510 'contribution_id' => $contribution['id'],
515 * Test the submit function of the membership form.
517 public function testSubmitPayLaterWithBilling() {
518 $form = $this->getForm(NULL);
519 $this->createLoggedInUser();
521 'cid' => $this->_individualId
,
522 'join_date' => date('m/d/Y', time()),
525 // This format reflects the 23 being the organisation & the 25 being the type.
526 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID
),
531 'total_amount' => '50.00',
532 //Member dues, see data.xml
533 'financial_type_id' => '2',
534 'soft_credit_type_id' => '',
535 'soft_credit_contact_id' => '',
536 'payment_instrument_id' => 4,
537 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
538 'receipt_text_signup' => 'Thank you text',
539 'payment_processor_id' => $this->_paymentProcessorID
,
540 'record_contribution' => TRUE,
542 'contribution_status_id' => 2,
543 'billing_first_name' => 'Test',
544 'billing_middlename' => 'Last',
545 'billing_street_address-5' => '10 Test St',
546 'billing_city-5' => 'Test',
547 'billing_state_province_id-5' => '1003',
548 'billing_postal_code-5' => '90210',
549 'billing_country_id-5' => '1228',
551 $form->_contactID
= $this->_individualId
;
553 $form->testSubmit($params);
554 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
555 $contribution = $this->callAPISuccessGetSingle('Contribution', array(
556 'contact_id' => $this->_individualId
,
557 'contribution_status_id' => 2,
559 $this->assertEquals($contribution['trxn_id'], 777);
561 $this->callAPISuccessGetCount('LineItem', array(
562 'entity_id' => $membership['id'],
563 'entity_table' => 'civicrm_membership',
564 'contribution_id' => $contribution['id'],
566 $this->callAPISuccessGetSingle('address', array(
567 'contact_id' => $this->_individualId
,
568 'street_address' => '10 Test St',
569 'postal_code' => 90210,
574 * Test the submit function of the membership form.
576 public function testSubmitRecurCompleteInstant() {
577 $form = $this->getForm();
578 $mut = new CiviMailUtils($this, TRUE);
579 $processor = Civi\Payment\System
::singleton()->getById($this->_paymentProcessorID
);
580 $processor->setDoDirectPaymentResult(array(
581 'payment_status_id' => 1,
582 'trxn_id' => 'kettles boil water',
585 $this->callAPISuccess('MembershipType', 'create', array(
586 'id' => $this->membershipTypeAnnualFixedID
,
587 'duration_unit' => 'month',
588 'duration_interval' => 1,
589 'auto_renew' => TRUE,
592 $this->createLoggedInUser();
593 $params = $this->getBaseSubmitParams();
594 $form->_mode
= 'test';
595 $form->_contactID
= $this->_individualId
;
596 $form->testSubmit($params);
597 $membership = $this->callAPISuccessGetSingle('Membership', array('contact_id' => $this->_individualId
));
598 $this->callAPISuccessGetCount('ContributionRecur', array('contact_id' => $this->_individualId
), 1);
600 $contribution = $this->callAPISuccess('Contribution', 'getsingle', array(
601 'contact_id' => $this->_individualId
,
605 $this->assertEquals(.14, $contribution['fee_amount']);
606 $this->assertEquals('kettles boil water', $contribution['trxn_id']);
608 $this->callAPISuccessGetCount('LineItem', array(
609 'entity_id' => $membership['id'],
610 'entity_table' => 'civicrm_membership',
611 'contribution_id' => $contribution['id'],
613 $mut->checkMailLog(array(
614 '===========================================================
615 Billing Name and Address
616 ===========================================================
621 '===========================================================
622 Membership Information
623 ===========================================================
624 Membership Type: AnnualFixed
625 Membership Start Date: ',
626 '===========================================================
627 Credit Card Information
628 ===========================================================
639 * Get a membership form object.
641 * We need to instantiate the form to run preprocess, which means we have to trick it about the request method.
643 * @return \CRM_Member_Form_Membership
645 protected function getForm() {
646 $form = new CRM_Member_Form_Membership();
647 $_SERVER['REQUEST_METHOD'] = 'GET';
648 $form->controller
= new CRM_Core_Controller();
656 protected function getBaseSubmitParams() {
658 'cid' => $this->_individualId
,
660 'join_date' => date('m/d/Y', time()),
664 // This format reflects the 23 being the organisation & the 25 being the type.
665 'membership_type_id' => array(23, $this->membershipTypeAnnualFixedID
),
671 'total_amount' => '77.00',
672 'financial_type_id' => '2', //Member dues, see data.xml
673 'soft_credit_type_id' => 11,
674 'soft_credit_contact_id' => '',
675 'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
676 'receipt_text' => 'Thank you text',
677 'payment_processor_id' => $this->_paymentProcessorID
,
678 'credit_card_number' => '4111111111111111',
680 'credit_card_exp_date' => array(
682 'Y' => '2019', // TODO: Future proof
684 'credit_card_type' => 'Visa',
685 'billing_first_name' => 'Test',
686 'billing_middlename' => 'Last',
687 'billing_street_address-5' => '10 Test St',
688 'billing_city-5' => 'Test',
689 'billing_state_province_id-5' => '1003',
690 'billing_postal_code-5' => '90210',
691 'billing_country_id-5' => '1228',