View source
<?php
require_once realpath(dirname(__FILE__)) . '/../TestHelper.php';
require_once realpath(dirname(__FILE__)) . '/SubscriptionTestHelper.php';
class Braintree_SubscriptionTest extends PHPUnit_Framework_TestCase {
function testCreate_doesNotAcceptBadAttributes() {
$this
->setExpectedException('InvalidArgumentException', 'invalid keys: bad');
$result = Braintree_Subscription::create(array(
'bad' => 'value',
));
}
function testCreate_whenSuccessful() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
Braintree_TestHelper::assertPrintable($result);
$this
->assertTrue($result->success);
$subscription = $result->subscription;
$this
->assertEquals($creditCard->token, $subscription->paymentMethodToken);
$this
->assertEquals(0, $subscription->failureCount);
$this
->assertEquals($plan['id'], $subscription->planId);
$this
->assertEquals(Braintree_TestHelper::defaultMerchantAccountId(), $subscription->merchantAccountId);
$this
->assertEquals(Braintree_Subscription::ACTIVE, $subscription->status);
$this
->assertEquals('12.34', $subscription->nextBillAmount);
$this
->assertEquals('12.34', $subscription->nextBillingPeriodAmount);
$this
->assertEquals('0.00', $subscription->balance);
$this
->assertEquals(1, $subscription->currentBillingCycle);
$this
->assertType('DateTime', $subscription->firstBillingDate);
$this
->assertType('DateTime', $subscription->nextBillingDate);
$this
->assertType('DateTime', $subscription->billingPeriodStartDate);
$this
->assertType('DateTime', $subscription->billingPeriodEndDate);
$this
->assertType('DateTime', $subscription->paidThroughDate);
}
function testCreate_returnsTransactionWhenTransactionFails() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'price' => Braintree_Test_TransactionAmounts::$decline,
));
Braintree_TestHelper::assertPrintable($result);
$this
->assertFalse($result->success);
$this
->assertEquals(Braintree_Transaction::PROCESSOR_DECLINED, $result->transaction->status);
}
function testCreate_canSetTheId() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$newId = strval(rand());
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'id' => $newId,
));
$this
->assertTrue($result->success);
$subscription = $result->subscription;
$this
->assertEquals($newId, $subscription->id);
}
function testCreate_canSetTheMerchantAccountId() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'merchantAccountId' => Braintree_TestHelper::nonDefaultMerchantAccountId(),
));
$this
->assertTrue($result->success);
$subscription = $result->subscription;
$this
->assertEquals(Braintree_TestHelper::nonDefaultMerchantAccountId(), $subscription->merchantAccountId);
}
function testCreate_trialPeriodDefaultsToPlanWithoutTrial() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$subscription = $result->subscription;
$this
->assertFalse($subscription->trialPeriod);
$this
->assertNull($subscription->trialDuration);
$this
->assertNull($subscription->trialDurationUnit);
}
function testCreate_trialPeriondDefaultsToPlanWithTrial() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::trialPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$subscription = $result->subscription;
$this
->assertTrue($subscription->trialPeriod);
$this
->assertEquals(2, $subscription->trialDuration);
$this
->assertEquals('day', $subscription->trialDurationUnit);
}
function testCreate_alterPlanTrialPeriod() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::trialPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'trialDuration' => 5,
'trialDurationUnit' => 'month',
));
$subscription = $result->subscription;
$this
->assertTrue($subscription->trialPeriod);
$this
->assertEquals(5, $subscription->trialDuration);
$this
->assertEquals('month', $subscription->trialDurationUnit);
}
function testCreate_removePlanTrialPeriod() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::trialPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'trialPeriod' => false,
));
$subscription = $result->subscription;
$this
->assertFalse($subscription->trialPeriod);
}
function testCreate_createsATransactionIfNoTrialPeriod() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$subscription = $result->subscription;
$this
->assertEquals(1, sizeof($subscription->transactions));
$transaction = $subscription->transactions[0];
$this
->assertType('Braintree_Transaction', $transaction);
$this
->assertEquals($plan['price'], $transaction->amount);
$this
->assertEquals(Braintree_Transaction::SALE, $transaction->type);
$this
->assertEquals($subscription->id, $transaction->subscriptionId);
}
function testCreate_doesNotCreateTransactionIfTrialPeriod() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::trialPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$subscription = $result->subscription;
$this
->assertEquals(0, sizeof($subscription->transactions));
}
function testCreate_returnsATransactionWithSubscriptionBillingPeriod() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$subscription = $result->subscription;
$transaction = $subscription->transactions[0];
$this
->assertEquals($subscription->billingPeriodStartDate, $transaction->subscriptionDetails->billingPeriodStartDate);
$this
->assertEquals($subscription->billingPeriodEndDate, $transaction->subscriptionDetails->billingPeriodEndDate);
}
function testCreate_priceCanBeOverriden() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::trialPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'price' => '2.00',
));
$subscription = $result->subscription;
$this
->assertEquals('2.00', $subscription->price);
}
function testCreate_billingDayOfMonthIsInheritedFromPlan() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::billingDayOfMonthPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$subscription = $result->subscription;
$this
->assertEquals(5, $subscription->billingDayOfMonth);
}
function testCreate_billingDayOfMonthCanBeOverriden() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::billingDayOfMonthPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'billingDayOfMonth' => 14,
));
$subscription = $result->subscription;
$this
->assertEquals(14, $subscription->billingDayOfMonth);
}
function testCreate_billingDayOfMonthCanBeOverridenWithStartImmediately() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::billingDayOfMonthPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'options' => array(
'startImmediately' => true,
),
));
$subscription = $result->subscription;
$this
->assertEquals(1, sizeof($subscription->transactions));
}
function testCreate_firstBillingDateCanBeSet() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::billingDayOfMonthPlan();
$tomorrow = new DateTime("now + 1 day");
$tomorrow
->setTime(0, 0, 0);
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'firstBillingDate' => $tomorrow,
));
$subscription = $result->subscription;
$this
->assertEquals($tomorrow, $subscription->firstBillingDate);
$this
->assertEquals(Braintree_Subscription::PENDING, $result->subscription->status);
}
function testCreate_firstBillingDateInThePast() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::billingDayOfMonthPlan();
$past = new DateTime("now - 3 days");
$past
->setTime(0, 0, 0);
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'firstBillingDate' => $past,
));
$this
->assertFalse($result->success);
$errors = $result->errors
->forKey('subscription')
->onAttribute('firstBillingDate');
$this
->assertEquals(Braintree_Error_Codes::SUBSCRIPTION_FIRST_BILLING_DATE_CANNOT_BE_IN_THE_PAST, $errors[0]->code);
}
function testCreate_numberOfBillingCyclesCanBeOverridden() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::trialPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$subscription = $result->subscription;
$this
->assertEquals($plan['numberOfBillingCycles'], $subscription->numberOfBillingCycles);
$result = Braintree_Subscription::create(array(
'numberOfBillingCycles' => '10',
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$subscription = $result->subscription;
$this
->assertEquals(10, $subscription->numberOfBillingCycles);
$this
->assertFalse($subscription->neverExpires);
}
function testCreate_numberOfBillingCyclesCanBeOverriddenToNeverExpire() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::trialPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$subscription = $result->subscription;
$this
->assertEquals($plan['numberOfBillingCycles'], $subscription->numberOfBillingCycles);
$result = Braintree_Subscription::create(array(
'neverExpires' => true,
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$subscription = $result->subscription;
$this
->assertNull($subscription->numberOfBillingCycles);
$this
->assertTrue($subscription->neverExpires);
}
function testCreate_doesNotInheritAddOnsAndDiscountsWhenDoNotInheritAddOnsOrDiscountsIsSet() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::addOnDiscountPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'options' => array(
'doNotInheritAddOnsOrDiscounts' => true,
),
));
$subscription = $result->subscription;
$this
->assertEquals(0, sizeof($subscription->addOns));
$this
->assertEquals(0, sizeof($subscription->discounts));
}
function testCreate_inheritsAddOnsAndDiscountsFromPlanByDefault() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::addOnDiscountPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$subscription = $result->subscription;
$this
->assertEquals(2, sizeof($subscription->addOns));
$addOns = $subscription->addOns;
Braintree_SubscriptionTestHelper::sortModificationsById($addOns);
$this
->assertEquals($addOns[0]->amount, "10.00");
$this
->assertEquals($addOns[0]->quantity, 1);
$this
->assertEquals($addOns[0]->numberOfBillingCycles, null);
$this
->assertEquals($addOns[0]->neverExpires, true);
$this
->assertEquals($addOns[1]->amount, "20.00");
$this
->assertEquals($addOns[1]->quantity, 1);
$this
->assertEquals($addOns[1]->numberOfBillingCycles, null);
$this
->assertEquals($addOns[1]->neverExpires, true);
$this
->assertEquals(2, sizeof($subscription->discounts));
$discounts = $subscription->discounts;
Braintree_SubscriptionTestHelper::sortModificationsById($discounts);
$this
->assertEquals($discounts[0]->amount, "11.00");
$this
->assertEquals($discounts[0]->quantity, 1);
$this
->assertEquals($discounts[0]->numberOfBillingCycles, null);
$this
->assertEquals($discounts[0]->neverExpires, true);
$this
->assertEquals($discounts[1]->amount, "7.00");
$this
->assertEquals($discounts[1]->quantity, 1);
$this
->assertEquals($discounts[1]->numberOfBillingCycles, null);
$this
->assertEquals($discounts[1]->neverExpires, true);
}
function testCreate_allowsOverridingInheritedAddOnsAndDiscounts() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::addOnDiscountPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'addOns' => array(
'update' => array(
array(
'amount' => '50.00',
'existingId' => 'increase_10',
'quantity' => 2,
'numberOfBillingCycles' => 5,
),
array(
'amount' => '60.00',
'existingId' => 'increase_20',
'quantity' => 4,
'numberOfBillingCycles' => 9,
),
),
),
'discounts' => array(
'update' => array(
array(
'amount' => '15.00',
'existingId' => 'discount_7',
'quantity' => 2,
'neverExpires' => true,
),
),
),
));
$subscription = $result->subscription;
$this
->assertEquals(2, sizeof($subscription->addOns));
$addOns = $subscription->addOns;
Braintree_SubscriptionTestHelper::sortModificationsById($addOns);
$this
->assertEquals($addOns[0]->amount, "50.00");
$this
->assertEquals($addOns[0]->quantity, 2);
$this
->assertEquals($addOns[0]->numberOfBillingCycles, 5);
$this
->assertEquals($addOns[0]->neverExpires, false);
$this
->assertEquals($addOns[1]->amount, "60.00");
$this
->assertEquals($addOns[1]->quantity, 4);
$this
->assertEquals($addOns[1]->numberOfBillingCycles, 9);
$this
->assertEquals($addOns[1]->neverExpires, false);
$this
->assertEquals(2, sizeof($subscription->discounts));
$discounts = $subscription->discounts;
Braintree_SubscriptionTestHelper::sortModificationsById($discounts);
$this
->assertEquals($discounts[0]->amount, "11.00");
$this
->assertEquals($discounts[0]->quantity, 1);
$this
->assertEquals($discounts[0]->numberOfBillingCycles, null);
$this
->assertEquals($discounts[0]->neverExpires, true);
$this
->assertEquals($discounts[1]->amount, "15.00");
$this
->assertEquals($discounts[1]->quantity, 2);
$this
->assertEquals($discounts[1]->numberOfBillingCycles, null);
$this
->assertEquals($discounts[1]->neverExpires, true);
}
function testCreate_allowsRemovalOfInheritedAddOnsAndDiscounts() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::addOnDiscountPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'addOns' => array(
'remove' => array(
'increase_10',
'increase_20',
),
),
'discounts' => array(
'remove' => array(
'discount_7',
),
),
));
$subscription = $result->subscription;
$this
->assertEquals(0, sizeof($subscription->addOns));
$this
->assertEquals(1, sizeof($subscription->discounts));
$this
->assertEquals($subscription->discounts[0]->amount, "11.00");
$this
->assertEquals($subscription->discounts[0]->quantity, 1);
$this
->assertEquals($subscription->discounts[0]->numberOfBillingCycles, null);
$this
->assertEquals($subscription->discounts[0]->neverExpires, true);
}
function testCreate_allowsAddingNewAddOnsAndDiscounts() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::addOnDiscountPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'addOns' => array(
'add' => array(
array(
'inheritedFromId' => 'increase_30',
'amount' => '35.00',
'neverExpires' => true,
'quantity' => 2,
),
),
),
'discounts' => array(
'add' => array(
array(
'inheritedFromId' => 'discount_15',
'amount' => '15.50',
'numberOfBillingCycles' => 10,
'quantity' => 3,
),
),
),
));
$subscription = $result->subscription;
$this
->assertEquals(3, sizeof($subscription->addOns));
$addOns = $subscription->addOns;
Braintree_SubscriptionTestHelper::sortModificationsById($addOns);
$this
->assertEquals($addOns[0]->amount, "10.00");
$this
->assertEquals($addOns[1]->amount, "20.00");
$this
->assertEquals($addOns[2]->id, "increase_30");
$this
->assertEquals($addOns[2]->amount, "35.00");
$this
->assertEquals($addOns[2]->neverExpires, true);
$this
->assertEquals($addOns[2]->numberOfBillingCycles, null);
$this
->assertEquals($addOns[2]->quantity, 2);
$this
->assertEquals(3, sizeof($subscription->discounts));
$discounts = $subscription->discounts;
Braintree_SubscriptionTestHelper::sortModificationsById($discounts);
$this
->assertEquals($discounts[0]->amount, "11.00");
$this
->assertEquals($discounts[1]->amount, "15.50");
$this
->assertEquals($discounts[1]->id, "discount_15");
$this
->assertEquals($discounts[1]->neverExpires, false);
$this
->assertEquals($discounts[1]->numberOfBillingCycles, 10);
$this
->assertEquals($discounts[1]->quantity, 3);
$this
->assertEquals($discounts[2]->amount, "7.00");
}
function testCreate_properlyParsesValidationErrorsForArrays() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::addOnDiscountPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'addOns' => array(
'update' => array(
array(
'existingId' => 'increase_10',
'amount' => 'invalid',
),
array(
'existingId' => 'increase_20',
'quantity' => -10,
),
),
),
));
$this
->assertFalse($result->success);
$errors = $result->errors
->forKey('subscription')
->forKey('addOns')
->forKey('update')
->forIndex(0)
->onAttribute('amount');
$this
->assertEquals(Braintree_Error_Codes::SUBSCRIPTION_MODIFICATION_AMOUNT_IS_INVALID, $errors[0]->code);
$errors = $result->errors
->forKey('subscription')
->forKey('addOns')
->forKey('update')
->forIndex(1)
->onAttribute('quantity');
$this
->assertEquals(Braintree_Error_Codes::SUBSCRIPTION_MODIFICATION_QUANTITY_IS_INVALID, $errors[0]->code);
}
function testCreate_withDescriptor() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'descriptor' => array(
'name' => '123*123456789012345678',
'phone' => '3334445555',
),
));
$this
->assertTrue($result->success);
$subscription = $result->subscription;
$this
->assertEquals('123*123456789012345678', $subscription->descriptor->name);
$this
->assertEquals('3334445555', $subscription->descriptor->phone);
$transaction = $subscription->transactions[0];
$this
->assertEquals('123*123456789012345678', $transaction->descriptor->name);
$this
->assertEquals('3334445555', $transaction->descriptor->phone);
}
function testCreate_withDescriptorValidation() {
$result = Braintree_Subscription::create(array(
'descriptor' => array(
'name' => 'xxxxxx',
'phone' => 'xxxx',
),
));
$this
->assertFalse($result->success);
$subscription = $result->subscription;
$errors = $result->errors
->forKey('subscription')
->forKey('descriptor')
->onAttribute('name');
$this
->assertEquals(Braintree_Error_Codes::DESCRIPTOR_NAME_FORMAT_IS_INVALID, $errors[0]->code);
$errors = $result->errors
->forKey('subscription')
->forKey('descriptor')
->onAttribute('phone');
$this
->assertEquals(Braintree_Error_Codes::DESCRIPTOR_PHONE_FORMAT_IS_INVALID, $errors[0]->code);
}
function testValidationErrors_hasValidationErrorsOnId() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'id' => 'invalid token',
));
$this
->assertFalse($result->success);
$errors = $result->errors
->forKey('subscription')
->onAttribute('id');
$this
->assertEquals(Braintree_Error_Codes::SUBSCRIPTION_TOKEN_FORMAT_IS_INVALID, $errors[0]->code);
}
function testFind() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$result = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
));
$this
->assertTrue($result->success);
$subscription = Braintree_Subscription::find($result->subscription->id);
$this
->assertEquals($result->subscription->id, $subscription->id);
$this
->assertEquals($plan['id'], $subscription->planId);
}
function testFind_throwsIfNotFound() {
$this
->setExpectedException('Braintree_Exception_NotFound', 'subscription with id does-not-exist not found');
Braintree_Subscription::find('does-not-exist');
}
function testUpdate_whenSuccessful() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
$newId = strval(rand());
$newPlan = Braintree_SubscriptionTestHelper::trialPlan();
$result = Braintree_Subscription::update($subscription->id, array(
'id' => $newId,
'price' => '999.99',
'planId' => $newPlan['id'],
));
$this
->assertTrue($result->success);
$this
->assertEquals($newId, $result->subscription->id);
$this
->assertEquals($newPlan['id'], $result->subscription->planId);
$this
->assertEquals('999.99', $result->subscription->price);
}
function testUpdate_doesNotAcceptBadAttributes() {
$this
->setExpectedException('InvalidArgumentException', 'invalid keys: bad');
$result = Braintree_Subscription::update('id', array(
'bad' => 'value',
));
}
function testUpdate_canUpdateNumberOfBillingCycles() {
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
$this
->assertEquals($plan['numberOfBillingCycles'], $subscription->numberOfBillingCycles);
$updatedSubscription = Braintree_Subscription::update($subscription->id, array(
'numberOfBillingCycles' => 15,
))->subscription;
$this
->assertEquals(15, $updatedSubscription->numberOfBillingCycles);
}
function testUpdate_canUpdateNumberOfBillingCyclesToNeverExpire() {
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
$this
->assertEquals($plan['numberOfBillingCycles'], $subscription->numberOfBillingCycles);
$updatedSubscription = Braintree_Subscription::update($subscription->id, array(
'neverExpires' => true,
))->subscription;
$this
->assertNull($updatedSubscription->numberOfBillingCycles);
}
function testUpdate_createsTransactionOnProration() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
$result = Braintree_Subscription::update($subscription->id, array(
'price' => $subscription->price + 1,
));
$this
->assertTrue($result->success);
$this
->assertEquals(sizeof($subscription->transactions) + 1, sizeof($result->subscription->transactions));
}
function testUpdate_createsProratedTransactionWhenFlagIsPassedTrue() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
$result = Braintree_Subscription::update($subscription->id, array(
'price' => $subscription->price + 1,
'options' => array(
'prorateCharges' => true,
),
));
$this
->assertTrue($result->success);
$this
->assertEquals(sizeof($subscription->transactions) + 1, sizeof($result->subscription->transactions));
}
function testUpdate_createsProratedTransactionWhenFlagIsPassedFalse() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
$result = Braintree_Subscription::update($subscription->id, array(
'price' => $subscription->price + 1,
'options' => array(
'prorateCharges' => false,
),
));
$this
->assertTrue($result->success);
$this
->assertEquals(sizeof($subscription->transactions), sizeof($result->subscription->transactions));
}
function testUpdate_DoesNotUpdateSubscriptionWhenProrationTransactionFailsAndRevertIsTrue() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
$result = Braintree_Subscription::update($subscription->id, array(
'price' => $subscription->price + 2100,
'options' => array(
'prorateCharges' => true,
'revertSubscriptionOnProrationFailure' => true,
),
));
$this
->assertFalse($result->success);
$this
->assertEquals(sizeof($subscription->transactions) + 1, sizeof($result->subscription->transactions));
$this
->assertEquals(Braintree_Transaction::PROCESSOR_DECLINED, $result->subscription->transactions[0]->status);
$this
->assertEquals("0.00", $result->subscription->balance);
$this
->assertEquals($subscription->price, $result->subscription->price);
}
function testUpdate_UpdatesSubscriptionWhenProrationTransactionFailsAndRevertIsFalse() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
$result = Braintree_Subscription::update($subscription->id, array(
'price' => $subscription->price + 2100,
'options' => array(
'prorateCharges' => true,
'revertSubscriptionOnProrationFailure' => false,
),
));
$this
->assertTrue($result->success);
$this
->assertEquals(sizeof($subscription->transactions) + 1, sizeof($result->subscription->transactions));
$this
->assertEquals(Braintree_Transaction::PROCESSOR_DECLINED, $result->subscription->transactions[0]->status);
$this
->assertEquals($result->subscription->transactions[0]->amount, $result->subscription->balance);
$this
->assertEquals($subscription->price + 2100, $result->subscription->price);
}
function testUpdate_invalidSubscriptionId() {
$this
->setExpectedException('Braintree_Exception_NotFound');
Braintree_Subscription::update('does-not-exist', array());
}
function testUpdate_validationErrors() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
$result = Braintree_Subscription::update($subscription->id, array(
'price' => '',
));
$this
->assertFalse($result->success);
$errors = $result->errors
->forKey('subscription')
->onAttribute('price');
$this
->assertEquals(Braintree_Error_Codes::SUBSCRIPTION_PRICE_CANNOT_BE_BLANK, $errors[0]->code);
}
function testUpdate_cannotUpdateCanceledSubscription() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
Braintree_Subscription::cancel($subscription->id);
$result = Braintree_Subscription::update($subscription->id, array(
'price' => '1.00',
));
$this
->assertFalse($result->success);
$errors = $result->errors
->forKey('subscription')
->onAttribute('base');
$this
->assertEquals(Braintree_Error_Codes::SUBSCRIPTION_CANNOT_EDIT_CANCELED_SUBSCRIPTION, $errors[0]->code);
}
function testUpdate_canUpdatePaymentMethodToken() {
$oldCreditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$subscription = Braintree_Subscription::create(array(
'paymentMethodToken' => $oldCreditCard->token,
'price' => '54.99',
'planId' => $plan['id'],
))->subscription;
$newCreditCard = Braintree_CreditCard::createNoValidate(array(
'number' => '5105105105105100',
'expirationDate' => '05/2010',
'customerId' => $oldCreditCard->customerId,
));
$result = Braintree_Subscription::update($subscription->id, array(
'paymentMethodToken' => $newCreditCard->token,
));
$this
->assertTrue($result->success);
$this
->assertEquals($newCreditCard->token, $result->subscription->paymentMethodToken);
}
function testUpdate_canUpdateAddOnsAndDiscounts() {
$oldCreditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::addOnDiscountPlan();
$subscription = Braintree_Subscription::create(array(
'paymentMethodToken' => $oldCreditCard->token,
'price' => '54.99',
'planId' => $plan['id'],
))->subscription;
$result = Braintree_Subscription::update($subscription->id, array(
'addOns' => array(
'update' => array(
array(
'amount' => '99.99',
'existingId' => 'increase_10',
'quantity' => 99,
'numberOfBillingCycles' => 99,
),
array(
'amount' => '22.22',
'existingId' => 'increase_20',
'quantity' => 22,
'neverExpires' => true,
),
),
),
'discounts' => array(
'update' => array(
array(
'amount' => '33.33',
'existingId' => 'discount_11',
'quantity' => 33,
'numberOfBillingCycles' => 33,
),
),
),
));
$this
->assertTrue($result->success);
$subscription = $result->subscription;
$this
->assertEquals(2, sizeof($subscription->addOns));
$addOns = $subscription->addOns;
Braintree_SubscriptionTestHelper::sortModificationsById($addOns);
$this
->assertEquals($addOns[0]->id, "increase_10");
$this
->assertEquals($addOns[0]->amount, "99.99");
$this
->assertEquals($addOns[0]->neverExpires, false);
$this
->assertEquals($addOns[0]->numberOfBillingCycles, 99);
$this
->assertEquals($addOns[0]->quantity, 99);
$this
->assertEquals($addOns[1]->id, "increase_20");
$this
->assertEquals($addOns[1]->amount, "22.22");
$this
->assertEquals($addOns[1]->neverExpires, true);
$this
->assertEquals($addOns[1]->numberOfBillingCycles, null);
$this
->assertEquals($addOns[1]->quantity, 22);
$this
->assertEquals(2, sizeof($subscription->discounts));
$discounts = $subscription->discounts;
Braintree_SubscriptionTestHelper::sortModificationsById($discounts);
$this
->assertEquals($discounts[0]->id, "discount_11");
$this
->assertEquals($discounts[0]->amount, "33.33");
$this
->assertEquals($discounts[0]->neverExpires, false);
$this
->assertEquals($discounts[0]->numberOfBillingCycles, 33);
$this
->assertEquals($discounts[0]->quantity, 33);
}
function testUpdate_canAddAndRemoveAddOnsAndDiscounts() {
$oldCreditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::addOnDiscountPlan();
$subscription = Braintree_Subscription::create(array(
'paymentMethodToken' => $oldCreditCard->token,
'price' => '54.99',
'planId' => $plan['id'],
))->subscription;
$result = Braintree_Subscription::update($subscription->id, array(
'addOns' => array(
'add' => array(
array(
'amount' => '33.33',
'inheritedFromId' => 'increase_30',
'quantity' => 33,
'numberOfBillingCycles' => 33,
),
),
'remove' => array(
'increase_10',
'increase_20',
),
),
'discounts' => array(
'add' => array(
array(
'inheritedFromId' => 'discount_15',
),
),
'remove' => array(
'discount_7',
),
),
));
$this
->assertTrue($result->success);
$subscription = $result->subscription;
$this
->assertEquals(1, sizeof($subscription->addOns));
$addOns = $subscription->addOns;
Braintree_SubscriptionTestHelper::sortModificationsById($addOns);
$this
->assertEquals($addOns[0]->id, "increase_30");
$this
->assertEquals($addOns[0]->amount, "33.33");
$this
->assertEquals($addOns[0]->neverExpires, false);
$this
->assertEquals($addOns[0]->numberOfBillingCycles, 33);
$this
->assertEquals($addOns[0]->quantity, 33);
$this
->assertEquals(2, sizeof($subscription->discounts));
$discounts = $subscription->discounts;
Braintree_SubscriptionTestHelper::sortModificationsById($discounts);
$this
->assertEquals($discounts[0]->id, "discount_11");
$this
->assertEquals($discounts[1]->id, "discount_15");
$this
->assertEquals($discounts[1]->amount, "15.00");
$this
->assertEquals($discounts[1]->neverExpires, true);
$this
->assertNull($discounts[1]->numberOfBillingCycles);
$this
->assertEquals($discounts[1]->quantity, 1);
}
function testUpdate_canReplaceEntireSetOfAddonsAndDiscounts() {
$oldCreditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::addOnDiscountPlan();
$subscription = Braintree_Subscription::create(array(
'paymentMethodToken' => $oldCreditCard->token,
'price' => '54.99',
'planId' => $plan['id'],
))->subscription;
$result = Braintree_Subscription::update($subscription->id, array(
'addOns' => array(
'add' => array(
array(
'inheritedFromId' => 'increase_30',
),
array(
'inheritedFromId' => 'increase_20',
),
),
),
'discounts' => array(
'add' => array(
array(
'inheritedFromId' => 'discount_15',
),
),
),
'options' => array(
'replaceAllAddOnsAndDiscounts' => true,
),
));
$this
->assertTrue($result->success);
$subscription = $result->subscription;
$this
->assertEquals(2, sizeof($subscription->addOns));
$addOns = $subscription->addOns;
Braintree_SubscriptionTestHelper::sortModificationsById($addOns);
$this
->assertEquals($addOns[0]->id, "increase_20");
$this
->assertEquals($addOns[1]->id, "increase_30");
$this
->assertEquals(1, sizeof($subscription->discounts));
$discounts = $subscription->discounts;
$this
->assertEquals($discounts[0]->id, "discount_15");
}
function testUpdate_withDescriptor() {
$creditCard = Braintree_SubscriptionTestHelper::createCreditCard();
$plan = Braintree_SubscriptionTestHelper::triallessPlan();
$subscription = Braintree_Subscription::create(array(
'paymentMethodToken' => $creditCard->token,
'planId' => $plan['id'],
'descriptor' => array(
'name' => '123*123456789012345678',
'phone' => '3334445555',
),
))->subscription;
$result = Braintree_Subscription::update($subscription->id, array(
'descriptor' => array(
'name' => '999*9999999',
'phone' => '8887776666',
),
));
$updatedSubscription = $result->subscription;
$this
->assertEquals('999*9999999', $updatedSubscription->descriptor->name);
$this
->assertEquals('8887776666', $updatedSubscription->descriptor->phone);
}
function testCancel_returnsSuccessIfCanceled() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
$result = Braintree_Subscription::cancel($subscription->id);
$this
->assertTrue($result->success);
$this
->assertEquals(Braintree_Subscription::CANCELED, $result->subscription->status);
}
function testCancel_throwsErrorIfRecordNotFound() {
$this
->setExpectedException('Braintree_Exception_NotFound');
Braintree_Subscription::cancel('non-existing-id');
}
function testCancel_returnsErrorIfCancelingCanceledSubscription() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
Braintree_Subscription::cancel($subscription->id);
$result = Braintree_Subscription::cancel($subscription->id);
$this
->assertFalse($result->success);
$errors = $result->errors
->forKey('subscription')
->onAttribute('status');
$this
->assertEquals(Braintree_Error_Codes::SUBSCRIPTION_STATUS_IS_CANCELED, $errors[0]->code);
}
function testRetryCharge_WithoutAmount() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
Braintree_Http::put('/subscriptions/' . $subscription->id . '/make_past_due');
$result = Braintree_Subscription::retryCharge($subscription->id);
$this
->assertTrue($result->success);
$transaction = $result->transaction;
$this
->assertEquals($subscription->price, $transaction->amount);
$this
->assertNotNull($transaction->processorAuthorizationCode);
$this
->assertEquals(Braintree_Transaction::SALE, $transaction->type);
$this
->assertEquals(Braintree_Transaction::AUTHORIZED, $transaction->status);
}
function testRetryCharge_WithAmount() {
$subscription = Braintree_SubscriptionTestHelper::createSubscription();
Braintree_Http::put('/subscriptions/' . $subscription->id . '/make_past_due');
$result = Braintree_Subscription::retryCharge($subscription->id, 1000);
$this
->assertTrue($result->success);
$transaction = $result->transaction;
$this
->assertEquals(1000, $transaction->amount);
$this
->assertNotNull($transaction->processorAuthorizationCode);
$this
->assertEquals(Braintree_Transaction::SALE, $transaction->type);
$this
->assertEquals(Braintree_Transaction::AUTHORIZED, $transaction->status);
}
}