Skip to content

Commit 646111c

Browse files
authored
Merge pull request #15 from cyon/mock-tests
Mock tests
2 parents 672563e + b47c220 commit 646111c

195 files changed

Lines changed: 328 additions & 22 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.travis.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
language: php
22
php:
3-
- 5.3
4-
- 5.4
5-
3+
- 5.5
4+
- 5.6
5+
- 7.0
6+
- 7.1
67
notifications:
78
email:
89
- kill-bill-commits@googlegroups.com

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ If you want to use the client but are not using [Composer](https://getcomposer.o
6666
- You can now use the client like above described.
6767
- If you don't want to have an additional build step, just check the `vendor/` folder into your repository.
6868

69+
Testing
70+
-------
71+
72+
The Killbill PHP client uses [phpunit](https://phpunit.de/) as testing framework. Tests can either be run locally using `composer test` or against
73+
a live Killbill instance that is running on `127.0.0.1:8080` using `composer test-integration`.
74+
6975
Requirements
7076
------------
7177

composer.json

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@
33
"description": "Official PHP client to the Killbill HTTP API",
44
"type": "library",
55
"autoload": {
6-
"psr-4": {
7-
"Killbill\\Client\\": "src/"
8-
}
6+
"psr-4": {
7+
"Killbill\\Client\\": "src/"
8+
}
99
},
1010
"autoload-dev": {
11-
"psr-4": {
12-
"Killbill\\Client\\": "test/"
13-
}
11+
"psr-4": {
12+
"Killbill\\Client\\": "test/"
13+
}
1414
},
1515
"scripts": {
16-
"test": "phpunit"
16+
"test": "ENV=local phpunit",
17+
"test-integration": "phpunit",
18+
"record-mocks": "composer run test-integration && RECORD_REQUESTS=1 phpunit"
1719
},
1820
"license": "Apache",
1921
"require": {},

src/Client.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
namespace Killbill\Client;
1919

2020
class Client {
21+
public static $mockManager = null;
22+
public static $useMockData = false;
23+
public static $recordMocks = false;
2124

2225
public static $serverUrl = 'http://127.0.0.1:8080';
2326
public static $apiVersion = '1.0';
@@ -51,16 +54,21 @@ public function request($method, $uri, $data = null, $user = null, $reason = nul
5154

5255
private function _sendRequest($method, $uri, $data = null, $user = null, $reason = null, $comment = null, $additional_headers = null) {
5356

57+
if (self::$useMockData && isset(self::$mockManager)) {
58+
return $this->getMockResponse($method . ' ' . $uri . ' ' . $data);
59+
}
60+
5461
if (function_exists('mb_internal_encoding')) {
5562
mb_internal_encoding(self::DEFAULT_ENCODING);
5663
}
5764

65+
$effectiveUri = $uri;
5866
if (substr($uri, 0, 4) != 'http') {
59-
$uri = self::__apiUrl() . $uri;
67+
$effectiveUri = self::__apiUrl() . $uri;
6068
}
6169

6270
$ch = curl_init();
63-
curl_setopt($ch, CURLOPT_URL, $uri);
71+
curl_setopt($ch, CURLOPT_URL, $effectiveUri);
6472
// Don't follow the Location header
6573
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
6674
// Include the header in the output
@@ -128,12 +136,29 @@ private function _sendRequest($method, $uri, $data = null, $user = null, $reason
128136
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
129137
curl_close($ch);
130138

139+
131140
$header = substr($response, 0, $header_size);
132141
$headers = $this->_getHeaders($header);
133142

134143
$body = substr($response, $header_size);
135144

136-
return new Response($statusCode, $headers, $body);
145+
$response = new Response($statusCode, $headers, $body);
146+
if (self::$recordMocks && isset(self::$mockManager)) {
147+
$this->saveResponseMock($method . ' ' . $uri . ' ' . $data, $response);
148+
}
149+
150+
return $response;
151+
}
152+
153+
private function getMockResponse($mockName) {
154+
$rawMockFileContents = self::$mockManager->getMock($mockName);
155+
$mockData = json_decode($rawMockFileContents, true);
156+
return new Response($mockData['statusCode'], $mockData['headers'], $mockData['body']);
157+
}
158+
159+
private function saveResponseMock($mockName, $response) {
160+
$mockContents = json_encode($response);
161+
self::$mockManager->saveMock($mockName, $mockContents);
137162
}
138163

139164
private static function __apiUrl() {

src/Resource.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,11 +195,7 @@ private function fromJsonObject($class, $json) {
195195
* @return json encoded resource
196196
*/
197197
public function jsonSerialize() {
198-
199-
$keys = get_object_vars($this);
200-
201198
$x = $this->prepareForSerialization();
202-
203199
return json_encode($x);
204200
}
205201

@@ -220,10 +216,16 @@ public function prepareForSerialization() {
220216
}
221217
}
222218
}
223-
return $keys;
224-
}
219+
$sortedArray = array();
220+
$arrayKeys = array_keys($keys);
221+
asort($arrayKeys, SORT_STRING | SORT_NATURAL);
225222

223+
foreach ($arrayKeys as $arrayKey) {
224+
$sortedArray[$arrayKey] = $keys[$arrayKey];
225+
}
226226

227+
return $sortedArray;
228+
}
227229

228230
private function initClientIfNeeded() {
229231
if (is_null($this->_client)) {

test/KillbillTest.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,21 @@ class KillbillTest extends \PHPUnit_Framework_TestCase
3232

3333
public function setUp()
3434
{
35+
$externalKey = uniqid();
36+
if (getenv('ENV') === 'local' || getenv('RECORD_REQUESTS') == '1') {
37+
Client::$mockManager = new MockManager();
38+
$externalKey = md5(static::class . ':' . $this->getName());
39+
40+
if (getenv('RECORD_REQUESTS') == '1') {
41+
Client::$recordMocks = true;
42+
} else {
43+
Client::$useMockData = true;
44+
}
45+
}
46+
47+
3548
$tenant = new Tenant();
36-
$tenant->setExternalKey(uniqid());
49+
$tenant->setExternalKey($externalKey);
3750
$tenant->setApiKey('test-php-api-key-' . $tenant->getExternalKey());
3851
$tenant->setApiSecret('test-php-api-secret-' . $tenant->getExternalKey());
3952
$this->tenant = $tenant->create($this->user, $this->reason, $this->comment);
@@ -52,6 +65,9 @@ public function setUp()
5265
$this->clock->setClock(null, $this->tenant->getTenantHeaders());
5366

5467
$this->externalAccountId = uniqid();
68+
if (getenv('ENV') === 'local' || getenv('RECORD_REQUESTS') == '1') {
69+
$this->externalAccountId = md5('externalAccount' . static::class . ':' . $this->getName());
70+
}
5571
$this->accountData = new Account();
5672
$this->accountData->setName("Killbill php test");
5773
$this->accountData->setExternalKey($this->externalAccountId);

test/MockManager.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
/*
3+
* Copyright 2011-2017 Ning, Inc.
4+
*
5+
* Ning licenses this file to you under the Apache License, version 2.0
6+
* (the "License"); you may not use this file except in compliance with the
7+
* License. You may obtain a copy of the License at:
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
* License for the specific language governing permissions and limitations
15+
* under the License.
16+
*/
17+
18+
namespace Killbill\Client;
19+
20+
class MockManager
21+
{
22+
protected $stubs = null;
23+
24+
public function __construct() {
25+
$this->stubs = array();
26+
}
27+
28+
public function saveMock($identifier, $response) {
29+
$filename = $this->getIteratedIdentifier($identifier);
30+
file_put_contents(__DIR__ . '/resources/mocks/' . $filename, $response);
31+
}
32+
33+
public function getMock($identifier) {
34+
$filename = $this->getIteratedIdentifier($identifier);
35+
return file_get_contents(__DIR__ . '/resources/mocks/' . $filename);
36+
}
37+
38+
private function getIteratedIdentifier($identifier) {
39+
$iteration = 0;
40+
$identifier = md5($identifier);
41+
if (in_array($identifier, array_keys($this->stubs))) {
42+
$iteration = $this->stubs[$identifier];
43+
$this->stubs[$identifier] = ++$iteration;
44+
} else {
45+
$this->stubs[$identifier] = 0;
46+
}
47+
48+
return md5($identifier . '_' . $iteration);
49+
}
50+
}

test/ServerAccountTest.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,18 @@ function testTags()
8181
*/
8282
$tag1 = new TagDefinition();
8383
$tag1->setName(uniqid());
84-
$tag1->setDescription("This is tag1");
84+
if (getenv('ENV') === 'local' || getenv('RECORD_REQUESTS') == '1') {
85+
$tag1->setName(md5('tag1' . static::class . ':' . $this->getName()));
86+
}
87+
$tag1->setDescription('This is tag1');
8588
$tag1 = $tag1->create($this->user, $this->reason, $this->comment, $this->tenant->getTenantHeaders());
8689

8790
$tag2 = new TagDefinition();
8891
$tag2->setName(uniqid());
89-
$tag2->setDescription("This is tag2");
92+
if (getenv('ENV') === 'local' || getenv('RECORD_REQUESTS') == '1') {
93+
$tag2->setName(md5('tag2' . static::class . ':' . $this->getName()));
94+
}
95+
$tag2->setDescription('This is tag2');
9096
$tag2 = $tag2->create($this->user, $this->reason, $this->comment, $this->tenant->getTenantHeaders());
9197

9298
/*

test/ServerInvoiceTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ function setUp()
2929
{
3030
parent::setUp();
3131
$this->externalBundleId = uniqid();
32+
if (getenv('ENV') === 'local' || getenv('RECORD_REQUESTS') == '1') {
33+
$this->externalBundleId = md5('serverInvoiceTest' . static::class . ':' . $this->getName());
34+
}
3235
$this->account = $this->accountData->create($this->user, $this->reason, $this->comment, $this->tenant->getTenantHeaders());
3336

3437
$paymentMethod = new PaymentMethod();

test/ServerPaymentMethodsTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ function setUp()
2828
{
2929
parent::setUp();
3030
$this->externalBundleId = uniqid();
31+
if (getenv('ENV') === 'local' || getenv('RECORD_REQUESTS') == '1') {
32+
$this->externalBundleId = md5('serverPaymentMethodTest' . static::class . ':' . $this->getName());
33+
}
3134
$this->account = $this->accountData->create($this->user, $this->reason, $this->comment, $this->tenant->getTenantHeaders());
3235
}
3336

0 commit comments

Comments
 (0)