Skip to content

Commit

Permalink
Merge pull request #317 from recurly/api_version_2_6
Browse files Browse the repository at this point in the history
API Version 2.6
  • Loading branch information
drewish authored Jun 2, 2017
2 parents 0570c62 + c891693 commit 5bb1785
Show file tree
Hide file tree
Showing 43 changed files with 532 additions and 95 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ php:
- 5.6
- 5.5
- 5.4
- 5.3
- hhvm
sudo: false
dist: trusty
install:
- composer install --dev
script: vendor/phpunit/phpunit/phpunit Tests
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Recurly PHP Client Library CHANGELOG

## Version 2.8.0.rc1 (June 2nd, 2017)

* Remove 5.3 Support and upgrade Travis to support HHVM [#316](https://github.com/recurly/recurly-client-php/pull/316)
* Purchases endpoint [#315](https://github.com/recurly/recurly-client-php/pull/315)
* Remove X-Records header [#314](https://github.com/recurly/recurly-client-php/pull/314)
* Add trial requires billing info field and no billing info reason field [#312](https://github.com/recurly/recurly-client-php/pull/312)

### Upgrade Notes

There are a few breaking changes this release.

1. PHP 5.3 is no longer officially supported and we no longer run tests against it.
2. To speed up your listing requests we're no longer automatically computing the record counts for each request's `X-Records` header. For our larger sites this could halve the response time. If you still need a count it will be computed with a separate request.
From now on, when you call `Recurly_Pager::count()`, it will send a HEAD request to the server. Ensure you aren't calling that method in places where you expect the value
to be cached for you. For more information on how this may affect you, see PR [#314](https://github.com/recurly/recurly-client-php/pull/314)
3. For `POST /v2/subscriptions` Sending `null` for `total_billing_cycles` attribute will now override plan `total_billing_cycles` setting and will make subscription renew forever.
Omitting the attribute will cause the setting to default to the value of plan `total_billing_cycles`.

## Version 2.7.2 (March 21st, 2017)

* Require export files [#296](https://github.com/recurly/recurly-client-php/pull/296)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ be careful when upgrading.

## Requirements

###cURL and OpenSSL
### cURL and OpenSSL

The PHP library depends on PHP 5.3.0 (or higher) and libcurl compiled with
The PHP library depends on PHP 5.4.0 (or higher) and libcurl compiled with
OpenSSL support. Open up a `phpinfo();` page and verify that under the curl
section, there's a line that says something like:

Expand Down
1 change: 0 additions & 1 deletion Tests/Recurly/Account_List_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public function testLoad() {

$this->assertInstanceOf('Recurly_AccountList', $accounts);
$this->assertEquals('/accounts', $accounts->getHref());
$this->assertEquals(42, $accounts->count());
}

public function testGetActive() {
Expand Down
2 changes: 1 addition & 1 deletion Tests/Recurly/Client_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public function testDeprecationError() {
$this->client->addResponse('GET', '/accounts', 'client/deprecated-200.xml');

// This should print an error but not raise.
$accounts = Recurly_AccountList::get(null, $this->client)->count();
$accounts = Recurly_AccountList::get(null, $this->client)->get();
}

public function testUnauthorizedError() {
Expand Down
2 changes: 1 addition & 1 deletion Tests/Recurly/Coupon_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function testGetCouponRedemptions() {
$redemptions = $coupon->redemptions->get();

$this->assertInstanceOf('Recurly_CouponRedemptionList', $redemptions);
$this->assertEquals(2, $redemptions->count());
$this->assertEquals('https://api.recurly.com/v2/coupons/special/redemptions', $redemptions->getHref());
}

public function testRedeemCouponExpired() {
Expand Down
1 change: 0 additions & 1 deletion Tests/Recurly/GiftCard_List_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,5 @@ public function testLoad() {

$this->assertInstanceOf('Recurly_GiftCardList', $gift_cards);
$this->assertEquals('/gift_cards', $gift_cards->getHref());
$this->assertEquals(42, $gift_cards->count());
}
}
2 changes: 1 addition & 1 deletion Tests/Recurly/MeasuredUnit_List_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public function testGetMeasuredUnits() {
$measured_units = Recurly_MeasuredUnitList::get(null, $this->client);

$this->assertInstanceOf('Recurly_MeasuredUnitList', $measured_units);
$this->assertEquals(2, $measured_units->count());
$this->assertEquals('/measured_units', $measured_units->getHref());
}
}
3 changes: 1 addition & 2 deletions Tests/Recurly/Note_List_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ public function testGetNotes() {

$notes = Recurly_NoteList::get('abcdef1234567890', array(), $this->client);
$this->assertInstanceOf('Recurly_NoteList', $notes);
$this->assertEquals($notes->count(), 2);
$this->assertEquals('/accounts/abcdef1234567890/notes?', $notes->getHref());

$note = $notes->current();

$this->assertInstanceOf('Recurly_Note', $note);
$this->assertEquals($note->message, 'this account needs an account manager');
$this->assertEquals($note->created_at->format(DateTime::ISO8601), '2013-03-12T18:35:00+0000');
Expand Down
62 changes: 39 additions & 23 deletions Tests/Recurly/Pager_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,6 @@ protected function getWriteableAttributes() { return array(); }

class Recurly_PagerTest extends Recurly_TestCase
{
function defaultResponses() {
return array(
array('GET', '/mocks', 'pager/index-1-200.xml'),
array('GET', 'http://example.com/mocks?cursor=1', 'pager/index-1-200.xml'),
array('GET', 'http://example.com/mocks?cursor=2', 'pager/index-2-200.xml'),
array('GET', 'http://example.com/mocks?cursor=3', 'pager/index-3-200.xml'),
);
}

private function assertIteratesCorrectly($pager, $count) {
// Initialization and enumeration
$pager->rewind();
Expand Down Expand Up @@ -64,26 +55,51 @@ private function assertIteratesCorrectly($pager, $count) {
}

public function testFromHref() {
$url = '/mocks';
$pager = new Mock_Pager($url, $this->client);
$pager->_loadFrom($url);
$relative_url = '/mocks';
$this->client->addResponse('GET', $relative_url, 'pager/index-1-200.xml');

$pager = new Mock_Pager($relative_url, $this->client);
$pager->_loadFrom($relative_url);

// Until we've fetched a second page with a next link we'll keep using the
// initial relative URL.
$this->assertEquals($relative_url, $pager->getHref());
$this->client->addResponse('HEAD', $relative_url, 'pager/head-200.xml');
$this->assertEquals(count($pager), 6);

$this->assertEquals($url, $pager->getHref());
$this->assertEquals(6, $pager->count(), 'Returns correct count');
$this->assertEquals(6, count($pager), 'Returns correct count');
$this->client->addResponse('GET', 'http://example.com/mocks?cursor=1', 'pager/index-1-200.xml');
$this->client->addResponse('GET', 'http://example.com/mocks?cursor=2', 'pager/index-2-200.xml');
$this->client->addResponse('GET', 'http://example.com/mocks?cursor=3', 'pager/index-3-200.xml');
$this->assertIteratesCorrectly($pager, 6);

// After rewinding we'll be using the start link
$this->assertEquals('http://example.com/mocks?cursor=1', $pager->getHref());
$this->client->addResponse('HEAD', 'http://example.com/mocks?cursor=1', 'pager/head-200.xml');
$this->assertEquals(count($pager), 6);
}

public function testFromStub() {
$url = '/mocks';
$stub = new Recurly_Stub('mocks', $url, $this->client);
$pager = $stub->get();
$relative_url = '/mocks';
$this->client->addResponse('GET', $relative_url, 'pager/index-1-200.xml');

$pager = (new Recurly_Stub('mocks', $relative_url, $this->client))->get();
$this->assertInstanceOf('Mock_Pager', $pager);

$this->assertEquals($url, $pager->getHref());
$this->assertEquals($pager->count(), 6, 'Returns correct count');
$this->assertEquals(count($pager), 6, 'Returns correct count');
// Until we've fetched a second page with a next link we'll keep using the
// initial relative URL.
$this->assertEquals($relative_url, $pager->getHref());
$this->client->addResponse('HEAD', $relative_url, 'pager/head-200.xml');
$this->assertEquals(count($pager), 6);

$this->client->addResponse('GET', 'http://example.com/mocks?cursor=1', 'pager/index-1-200.xml');
$this->client->addResponse('GET', 'http://example.com/mocks?cursor=2', 'pager/index-2-200.xml');
$this->client->addResponse('GET', 'http://example.com/mocks?cursor=3', 'pager/index-3-200.xml');
$this->assertIteratesCorrectly($pager, 6);

// After rewinding we'll be using the start link
$this->assertEquals('http://example.com/mocks?cursor=1', $pager->getHref());
$this->client->addResponse('HEAD', 'http://example.com/mocks?cursor=1', 'pager/head-200.xml');
$this->assertEquals(count($pager), 6, 'Count works after iterating');
}

public function testFromNested() {
Expand All @@ -95,8 +111,8 @@ public function testFromNested() {
$this->assertInstanceOf('Mock_Pager', $pager);

$this->assertNull($pager->getHref(), "Nested records shouldn't have a URL");
$this->assertEquals(4, $pager->count(), 'Returns correct count');
$this->assertEquals(4, count($pager), 'Returns correct count');
$this->assertEquals(4, count($pager));
$this->assertIteratesCorrectly($pager, 4);
$this->assertEquals(4, count($pager), 'Count is unchanged after iterating');
}
}
7 changes: 5 additions & 2 deletions Tests/Recurly/Plan_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function testGetPlan() {
$this->assertEquals('days', $plan->trial_interval_unit);
$this->assertEquals(6, $plan->total_billing_cycles);
$this->assertEquals("Setup Fee AC", $plan->setup_fee_accounting_code);
$this->assertEquals(false, $plan->trial_requires_billing_info);

$this->assertInstanceOf('Recurly_CurrencyList', $plan->unit_amount_in_cents);
$this->assertEquals(1000, $plan->unit_amount_in_cents['USD']->amount_in_cents);
Expand All @@ -46,10 +47,11 @@ public function testCreateXml() {
$plan->unit_amount_in_cents->addCurrency('USD', 1500);
$plan->unit_amount_in_cents->addCurrency('EUR', 1200);
$plan->setup_fee_in_cents->addCurrency('EUR', 500);
$plan->trial_requires_billing_info = false;
$plan->total_billing_cycles = 6;

$this->assertEquals(
"<?xml version=\"1.0\"?>\n<plan><plan_code>platinum</plan_code><name>Platinum &amp; Gold Plan</name><unit_amount_in_cents><USD>1500</USD><EUR>1200</EUR></unit_amount_in_cents><setup_fee_in_cents><EUR>500</EUR></setup_fee_in_cents><total_billing_cycles>6</total_billing_cycles></plan>\n",
"<?xml version=\"1.0\"?>\n<plan><plan_code>platinum</plan_code><name>Platinum &amp; Gold Plan</name><unit_amount_in_cents><USD>1500</USD><EUR>1200</EUR></unit_amount_in_cents><setup_fee_in_cents><EUR>500</EUR></setup_fee_in_cents><total_billing_cycles>6</total_billing_cycles><trial_requires_billing_info>false</trial_requires_billing_info></plan>\n",
$plan->xml()
);
}
Expand All @@ -63,10 +65,11 @@ public function testUpdateXml() {
$plan->setup_fee_in_cents->addCurrency('EUR', 500);
$plan->total_billing_cycles = NULL;
$plan->tax_exempt = false;
$plan->trial_requires_billing_info = false;
$plan->tax_code = 'fake-tax-code';

$this->assertEquals(
"<?xml version=\"1.0\"?>\n<plan><plan_code>platinum</plan_code><name>Platinum Plan</name><unit_amount_in_cents><USD>1500</USD><EUR>1200</EUR></unit_amount_in_cents><setup_fee_in_cents><USD>500</USD><EUR>500</EUR></setup_fee_in_cents><total_billing_cycles nil=\"nil\"></total_billing_cycles><tax_exempt>false</tax_exempt><tax_code>fake-tax-code</tax_code></plan>\n",
"<?xml version=\"1.0\"?>\n<plan><plan_code>platinum</plan_code><name>Platinum Plan</name><unit_amount_in_cents><USD>1500</USD><EUR>1200</EUR></unit_amount_in_cents><setup_fee_in_cents><USD>500</USD><EUR>500</EUR></setup_fee_in_cents><total_billing_cycles nil=\"nil\"></total_billing_cycles><tax_exempt>false</tax_exempt><tax_code>fake-tax-code</tax_code><trial_requires_billing_info>false</trial_requires_billing_info></plan>\n",
$plan->xml()
);
}
Expand Down
80 changes: 80 additions & 0 deletions Tests/Recurly/Purchase_Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

class Recurly_PurchaseTest extends Recurly_TestCase
{
function defaultResponses() {
return array(
array('POST', '/purchases', 'purchases/create-201.xml'),
array('POST', '/purchases/preview', 'purchases/preview-200.xml'),
);
}

public function mockPurchase() {
$purchase = new Recurly_Purchase();
$purchase->currency = 'USD';
$purchase->collection_method = 'automatic';
$purchase->account = new Recurly_Account();
$purchase->account->account_code = 'aba9209a-aa61-4790-8e61-0a2692435fee';
$purchase->account->address->phone = "555-555-5555";
$purchase->account->address->email = "[email protected]";
$purchase->account->address->address1 = "123 Main St.";
$purchase->account->address->city = "San Francisco";
$purchase->account->address->state = "CA";
$purchase->account->address->zip = "94110";
$purchase->account->address->country = "US";

$adjustment = new Recurly_Adjustment();
$adjustment->product_code = "abcd123";
$adjustment->unit_amount_in_cents = 1000;
$adjustment->currency = 'USD';
$adjustment->quantity = 1;
$adjustment->revenue_schedule_type = 'at_invoice';

$purchase->adjustments[] = $adjustment;

return $purchase;
}

public function testXml() {
$purchase = $this->mockPurchase();

$this->assertEquals(
"<?xml version=\"1.0\"?>\n<purchase><account><account_code>aba9209a-aa61-4790-8e61-0a2692435fee</account_code><address><address1>123 Main St.</address1><city>San Francisco</city><state>CA</state><zip>94110</zip><country>US</country><phone>555-555-5555</phone></address></account><adjustments><adjustment><currency>USD</currency><unit_amount_in_cents>1000</unit_amount_in_cents><quantity>1</quantity><revenue_schedule_type>at_invoice</revenue_schedule_type><product_code>abcd123</product_code></adjustment></adjustments><collection_method>automatic</collection_method><currency>USD</currency></purchase>\n",
$purchase->xml()
);
}

public function testInvoicePurchase() {
$purchase = $this->mockPurchase();
$invoice = Recurly_Purchase::invoice($purchase, $this->client);

$this->assertInstanceOf('Recurly_Invoice', $invoice);
$this->assertEquals('3d8648fcf2be67ed304ff242d6bbb9d4', $invoice->uuid);
}

public function testPreviewPurchase() {
$purchase = $this->mockPurchase();
$invoice = Recurly_Purchase::preview($purchase, $this->client);

$this->assertInstanceOf('Recurly_Invoice', $invoice);
$this->assertNull($invoice->uuid);
}

public function testTransactionError() {
$this->client->addResponse('POST', '/purchases', 'purchases/create-422.xml');
$purchase = $this->mockPurchase();

try {
$invoice = Recurly_Purchase::invoice($purchase, $this->client);
$this->fail('Purchase should throw transaction exception but it threw no exception');
} catch (Recurly_ValidationError $e) {
$this->assertEquals($e->getMessage(), 'Credit card number is not valid.');
$this->assertInstanceOf('Recurly_TransactionError', $e->errors->transaction_error);
$this->assertInstanceOf('Recurly_Transaction', $e->errors->transaction);
} catch (Exception $e) {
print $e->getMessage();
$this->fail('Purchase should have thrown transaction exception');
}
}
}

27 changes: 21 additions & 6 deletions Tests/Recurly/ShippingAddress_Test.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?php


class Recurly_ShippingAddressTest extends Recurly_TestCase
{
function defaultResponses() {
Expand All @@ -9,12 +8,9 @@ function defaultResponses() {
);
}

public function testCreateShippingAddressOnExistingAccount() {
$account = Recurly_Account::get('abcdef1234567890', $this->client);
$this->client->addResponse('POST', 'https://api.recurly.com/v2/accounts/abcdef1234567890/shipping_addresses', 'shipping_addresses/create-201.xml');

protected function mockShippingAddress() {
$shad = new Recurly_ShippingAddress();
$shad->nickname = "Home";
$shad->nickname = "Work";
$shad->first_name = "Verena";
$shad->last_name = "Example";
$shad->phone = "555-555-5555";
Expand All @@ -24,6 +20,25 @@ public function testCreateShippingAddressOnExistingAccount() {
$shad->state = "CA";
$shad->zip = "94110";
$shad->country = "US";
$shad->company = "Recurly Inc.";

return $shad;
}

public function testXml() {
$shad = $this->mockShippingAddress();

$this->assertEquals(
"<?xml version=\"1.0\"?>\n<shipping_address><address1>123 Dolores St.</address1><city>San Francisco</city><state>CA</state><zip>94110</zip><country>US</country><phone>555-555-5555</phone><email>[email protected]</email><nickname>Work</nickname><first_name>Verena</first_name><last_name>Example</last_name><company>Recurly Inc.</company></shipping_address>\n",
$shad->xml()
);
}

public function testCreateShippingAddressOnExistingAccount() {
$account = Recurly_Account::get('abcdef1234567890', $this->client);
$this->client->addResponse('POST', 'https://api.recurly.com/v2/accounts/abcdef1234567890/shipping_addresses', 'shipping_addresses/create-201.xml');

$shad = $this->mockShippingAddress();

$account->createShippingAddress($shad, $this->client);

Expand Down
4 changes: 2 additions & 2 deletions Tests/Recurly/Subscription_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public function testGetSubscription() {
$this->assertEquals('Some Terms and Conditions', $subscription->terms_and_conditions);
$this->assertEquals('Some Customer Notes', $subscription->customer_notes);
$this->assertEquals('Some VAT Notes', $subscription->vat_reverse_charge_notes);
$this->assertEquals('plan_free_trial', $subscription->no_billing_info_reason);

# TODO: Should test the rest of the parsing.
}
Expand Down Expand Up @@ -238,8 +239,7 @@ public function testGetSubscriptionRedemptions() {
$subscription = Recurly_Subscription::get('012345678901234567890123456789ab', $this->client);

$redemptions = $subscription->redemptions->get();

$this->assertEquals(2, $redemptions->count());
$this->assertEquals('https://api.recurly.com/v2/subscriptions/012345678901234567890123456789ab/redemptions', $redemptions->getHref());

foreach($redemptions as $r) {
$this->assertInstanceOf('Recurly_CouponRedemption', $r);
Expand Down
1 change: 0 additions & 1 deletion Tests/fixtures/accounts/index-200.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
X-Records: 42
Link: <https://api.recurly.com/v2/accounts?cursor=1234567890&per_page=20>; rel="start", <https://api.recurly.com/v2/accounts?cursor=1234566890&per_page=20>; rel="next"

<?xml version="1.0" encoding="UTF-8"?>
Expand Down
1 change: 0 additions & 1 deletion Tests/fixtures/export_dates/index-200.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
X-Api-Version: 2.4
X-Records: 1

<export_dates type="array">
<export_date>
Expand Down
1 change: 0 additions & 1 deletion Tests/fixtures/export_files/index-200.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
HTTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
X-Api-Version: 2.4
X-Records: 1

<export_files href="https://api.recurly.com/v2/export_dates/2016-08-01/export_files">
<export_file href="https://api.recurly.com/v2/export_dates/2016-08-01/export_files/revenue_schedules_full.csv">
Expand Down
Loading

0 comments on commit 5bb1785

Please sign in to comment.