Skip to content

Commit

Permalink
Make sure frequency unit matches for recur/membership in IPN tests an…
Browse files Browse the repository at this point in the history
…d allow for specifying that frequency
  • Loading branch information
mattwire committed Mar 21, 2018
1 parent 61c6fbc commit b3c283b
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 9 deletions.
2 changes: 1 addition & 1 deletion tests/phpunit/CRM/Core/Payment/PayPalProIPNTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public function testIPNPaymentRecurSuccess() {
* Test IPN response updates contribution_recur & contribution for first & second contribution.
*/
public function testIPNPaymentMembershipRecurSuccess() {
$this->setupMembershipRecurringPaymentProcessorTransaction();
$this->setupMembershipRecurringPaymentProcessorTransaction(array('duration_unit' => 'year', 'frequency_unit' => 'year'));
$this->callAPISuccessGetSingle('membership_payment', array());
$paypalIPN = new CRM_Core_Payment_PayPalProIPN($this->getPaypalProRecurTransaction());
$paypalIPN->main();
Expand Down
16 changes: 13 additions & 3 deletions tests/phpunit/CiviTest/CiviUnitTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3202,9 +3202,19 @@ public function setupRecurringPaymentProcessorTransaction($params = array()) {

/**
* We don't have a good way to set up a recurring contribution with a membership so let's just do one then alter it
*
* @param array $params Optionally modify params for membership/recur (duration_unit/frequency_unit)
*/
public function setupMembershipRecurringPaymentProcessorTransaction() {
$this->ids['membership_type'] = $this->membershipTypeCreate();
public function setupMembershipRecurringPaymentProcessorTransaction($params = array()) {
$membershipParams = $recurParams = array();
if (!empty($params['duration_unit'])) {
$membershipParams['duration_unit'] = $params['duration_unit'];
}
if (!empty($params['frequency_unit'])) {
$recurParams['frequency_unit'] = $params['frequency_unit'];
}

$this->ids['membership_type'] = $this->membershipTypeCreate($membershipParams);
//create a contribution so our membership & contribution don't both have id = 1
if ($this->callAPISuccess('Contribution', 'getcount', array()) == 0) {
$this->contributionCreate(array(
Expand All @@ -3215,7 +3225,7 @@ public function setupMembershipRecurringPaymentProcessorTransaction() {
'trxn_id' => 345,
));
}
$this->setupRecurringPaymentProcessorTransaction();
$this->setupRecurringPaymentProcessorTransaction($recurParams);

$this->ids['membership'] = $this->callAPISuccess('membership', 'create', array(
'contact_id' => $this->_contactID,
Expand Down
58 changes: 53 additions & 5 deletions tests/phpunit/api/v3/ContributionPageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ public function testSubmitPaymentProcessorFailure() {
}

/**
* Test submit recurring membership with immediate confirmation (IATS style).
* Test submit recurring (yearly) membership with immediate confirmation (IATS style).
*
* - we process 2 membership transactions against with a recurring contribution against a contribution page with an immediate
* processor (IATS style - denoted by returning trxn_id)
Expand All @@ -818,27 +818,58 @@ public function testSubmitMembershipPriceSetPaymentPaymentProcessorRecurInstantP
$this->doSubmitMembershipPriceSetPaymentPaymentProcessorRecurInstantPayment(array('duration_unit' => 'year', 'recur_frequency_unit' => 'year'));
}

/**
* Test submit recurring (monthly) membership with immediate confirmation (IATS style).
*
* - we process 2 membership transactions against with a recurring contribution against a contribution page with an immediate
* processor (IATS style - denoted by returning trxn_id)
* - the first creates a new membership, completed contribution, in progress recurring. Check these
* - create another - end date should be extended
*/
public function testSubmitMembershipPriceSetPaymentPaymentProcessorRecurInstantPaymentMonth() {
$this->doSubmitMembershipPriceSetPaymentPaymentProcessorRecurInstantPayment(array('duration_unit' => 'month', 'recur_frequency_unit' => 'month'));
}

public function testSubmitMembershipPriceSetPaymentPaymentProcessorRecurInstantPaymentDifferentFrequency() {
$this->doSubmitMembershipPriceSetPaymentPaymentProcessorRecurInstantPayment(array('duration_unit' => 'year', 'recur_frequency_unit' => 'month'));
}
/**
* Test submit recurring (mismatched frequency unit) membership with immediate confirmation (IATS style).
*
* - we process 2 membership transactions against with a recurring contribution against a contribution page with an immediate
* processor (IATS style - denoted by returning trxn_id)
* - the first creates a new membership, completed contribution, in progress recurring. Check these
* - create another - end date should be extended
*/
//public function testSubmitMembershipPriceSetPaymentPaymentProcessorRecurInstantPaymentDifferentFrequency() {
// $this->doSubmitMembershipPriceSetPaymentPaymentProcessorRecurInstantPayment(array('duration_unit' => 'year', 'recur_frequency_unit' => 'month'));
//}

/**
* Helper function for testSubmitMembershipPriceSetPaymentProcessorRecurInstantPayment*
* @param array $params
*
* @throws \CRM_Core_Exception
* @throws \Exception
*/
public function doSubmitMembershipPriceSetPaymentPaymentProcessorRecurInstantPayment($params = array()) {
$this->params['is_recur'] = 1;
$this->params['recur_frequency_unit'] = $params['recur_frequency_unit'];
$membershipTypeParams['duration_unit'] = $params['duration_unit'];
if ($params['recur_frequency_unit'] === $params['duration_unit']) {
$durationUnit = $params['duration_unit'];
}
else {
$durationUnit = NULL;
}
$this->setUpMembershipContributionPage(FALSE, FALSE, $membershipTypeParams);
$dummyPP = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
$dummyPP->setDoDirectPaymentResult(array('payment_status_id' => 1, 'trxn_id' => 'create_first_success'));
$processor = $dummyPP->getPaymentProcessor();

if ($params['recur_frequency_unit'] === $params['duration_unit']) {
// Membership will be in "New" state because it will get confirmed as payment matches
$expectedMembershipStatus = 1;
}
else {
// Membership will still be in "Pending" state as it won't get confirmed as payment doesn't match
$expectedMembershipStatus = 5;
}

Expand Down Expand Up @@ -887,7 +918,24 @@ public function doSubmitMembershipPriceSetPaymentPaymentProcessorRecurInstantPay
'contribution_status_id' => 1,
));
$renewedMembership = $this->callAPISuccessGetSingle('membership', array('id' => $membershipPayment['membership_id']));
$this->assertEquals(date('Y-m-d', strtotime('+ 1 ' . $this->params['recur_frequency_unit'], strtotime($membership['end_date']))), $renewedMembership['end_date']);
if ($durationUnit) {
// We only have an end_date if frequency units match, otherwise membership won't be autorenewed and dates won't be calculated.
$renewedMembershipEndDate = new DateTime($membership['end_date']);
switch ($durationUnit) {
case 'year':
$renewedMembershipEndDate->add(new DateInterval('P1Y'));
break;

case 'month':
// We have to add 1 day first in case it's the end of the month, then subtract afterwards
// eg. 2018-02-28 should renew to 2018-03-31, if we just added 1 month we'd get 2018-03-28
$renewedMembershipEndDate->add(new DateInterval('P1D'));
$renewedMembershipEndDate->add(new DateInterval('P1M'));
$renewedMembershipEndDate->sub(new DateInterval('P1D'));
break;
}
$this->assertEquals($renewedMembershipEndDate->format('Y-m-d'), $renewedMembership['end_date']);
}
$recurringContribution = $this->callAPISuccess('contribution_recur', 'getsingle', array('id' => $contribution['contribution_recur_id']));
$this->assertEquals($processor['payment_instrument_id'], $recurringContribution['payment_instrument_id']);
$this->assertEquals(5, $recurringContribution['contribution_status_id']);
Expand Down

0 comments on commit b3c283b

Please sign in to comment.