nodeunit-api-client 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +284 -0
- package/package.json +48 -0
- package/src/httpclient.js +207 -0
package/README.md
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# nodeunit-api-client
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/nodeunit-api-client)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
Lightweight HTTP/HTTPS client with built-in testing assertions for Nodeunit.
|
|
7
|
+
|
|
8
|
+
## ✨ Features
|
|
9
|
+
|
|
10
|
+
- ✅ Simple API for HTTP/HTTPS requests
|
|
11
|
+
- ✅ Built-in assertions for Nodeunit tests
|
|
12
|
+
- ✅ Support for GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT
|
|
13
|
+
- ✅ Automatic JSON parsing
|
|
14
|
+
- ✅ Configurable timeouts
|
|
15
|
+
- ✅ Basic authentication support
|
|
16
|
+
- ✅ Query string handling
|
|
17
|
+
- ✅ No external dependencies (uses native Node.js modules)
|
|
18
|
+
|
|
19
|
+
## 📦 Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install nodeunit-api-client
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 🚀 Quick Start
|
|
26
|
+
|
|
27
|
+
### Basic Usage
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
const HttpClient = require('nodeunit-api-client');
|
|
31
|
+
|
|
32
|
+
const api = new HttpClient({
|
|
33
|
+
protocol: 'https',
|
|
34
|
+
host: 'api.example.com',
|
|
35
|
+
port: 443,
|
|
36
|
+
path: '/v1'
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Simple GET request
|
|
40
|
+
api.get(null, '/users', function(response) {
|
|
41
|
+
console.log(response.statusCode); // 200
|
|
42
|
+
console.log(response.data); // Parsed JSON
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### With Nodeunit Tests
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
const HttpClient = require('nodeunit-api-client');
|
|
50
|
+
|
|
51
|
+
const api = new HttpClient({
|
|
52
|
+
protocol: 'https',
|
|
53
|
+
host: 'api.example.com'
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
exports.testAPI = {
|
|
57
|
+
'should return user data': function(test) {
|
|
58
|
+
api.get(test, '/user/123', {}, {
|
|
59
|
+
status: 200,
|
|
60
|
+
headers: { 'content-type': 'application/json' }
|
|
61
|
+
}, function(response) {
|
|
62
|
+
test.deepEqual(response.data, { id: 123, name: 'John' });
|
|
63
|
+
test.done();
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### POST with JSON Data
|
|
70
|
+
|
|
71
|
+
```javascript
|
|
72
|
+
api.post(null, '/users', {
|
|
73
|
+
data: { name: 'Alice', email: 'alice@example.com' }
|
|
74
|
+
}, {}, function(response) {
|
|
75
|
+
console.log(response.statusCode); // 201
|
|
76
|
+
console.log(response.data);
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### GET with Query Parameters
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
api.get(null, '/search', {
|
|
84
|
+
data: { q: 'nodejs', limit: 10 }
|
|
85
|
+
}, {}, function(response) {
|
|
86
|
+
// Request: GET /search?q=nodejs&limit=10
|
|
87
|
+
console.log(response.data);
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 📖 API Documentation
|
|
92
|
+
|
|
93
|
+
### Constructor Options
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
new HttpClient({
|
|
97
|
+
protocol: 'http', // 'http' or 'https' (default: 'http')
|
|
98
|
+
host: 'localhost', // Server hostname
|
|
99
|
+
port: 80, // Server port (default: 80 for http, 443 for https)
|
|
100
|
+
path: '', // Base path (e.g. '/api/v1')
|
|
101
|
+
auth: 'user:pass', // Basic authentication
|
|
102
|
+
reqHeaders: {}, // Default request headers
|
|
103
|
+
headers: {}, // Default expected response headers (for assertions)
|
|
104
|
+
status: 200, // Default expected status code (for assertions)
|
|
105
|
+
timeout: 30000, // Request timeout in ms (default: 30000)
|
|
106
|
+
debug: false // Enable debug logs (default: false)
|
|
107
|
+
})
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Methods
|
|
111
|
+
|
|
112
|
+
All methods support multiple signatures:
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
// (assert, path, callback)
|
|
116
|
+
api.get(test, '/users', function(response) { ... });
|
|
117
|
+
|
|
118
|
+
// (assert, path, res)
|
|
119
|
+
api.get(test, '/users', { status: 200 });
|
|
120
|
+
|
|
121
|
+
// (assert, path, req, callback)
|
|
122
|
+
api.get(test, '/users', { headers: { 'x-api-key': 'secret' } }, function(response) { ... });
|
|
123
|
+
|
|
124
|
+
// (assert, path, req, res)
|
|
125
|
+
api.get(test, '/users', {}, { status: 200 });
|
|
126
|
+
|
|
127
|
+
// (assert, path, req, res, callback)
|
|
128
|
+
api.get(test, '/users', {}, { status: 200 }, function(response) { ... });
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Available methods:**
|
|
132
|
+
- `get(assert, path, req, res, cb)`
|
|
133
|
+
- `post(assert, path, req, res, cb)`
|
|
134
|
+
- `put(assert, path, req, res, cb)`
|
|
135
|
+
- `del(assert, path, req, res, cb)` (DELETE)
|
|
136
|
+
- `head(assert, path, req, res, cb)`
|
|
137
|
+
- `options(assert, path, req, res, cb)`
|
|
138
|
+
- `trace(assert, path, req, res, cb)`
|
|
139
|
+
- `connect(assert, path, req, res, cb)`
|
|
140
|
+
|
|
141
|
+
### Request Object (`req`)
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
{
|
|
145
|
+
headers: {}, // Request headers
|
|
146
|
+
data: {}, // Query params (GET) or body data (POST/PUT)
|
|
147
|
+
body: '', // Raw body (alternative to data)
|
|
148
|
+
auth: 'user:pass' // Override default auth
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Response Assertions (`res`)
|
|
153
|
+
|
|
154
|
+
```javascript
|
|
155
|
+
{
|
|
156
|
+
status: 200, // Expected status code
|
|
157
|
+
headers: {}, // Expected response headers
|
|
158
|
+
body: '', // Expected raw body
|
|
159
|
+
data: {} // Expected parsed JSON data
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Response Object (in callback)
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
{
|
|
167
|
+
statusCode: 200, // HTTP status code
|
|
168
|
+
headers: {}, // Response headers
|
|
169
|
+
body: '', // Raw response body
|
|
170
|
+
data: {} // Parsed JSON (if content-type is application/json)
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## 🧪 Testing
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
npm test
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## 📝 Examples
|
|
181
|
+
|
|
182
|
+
### Basic Authentication
|
|
183
|
+
|
|
184
|
+
```javascript
|
|
185
|
+
const api = new HttpClient({
|
|
186
|
+
protocol: 'https',
|
|
187
|
+
host: 'api.example.com',
|
|
188
|
+
auth: 'username:password'
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
api.get(null, '/protected', function(response) {
|
|
192
|
+
console.log(response.statusCode);
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Custom Headers
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
const api = new HttpClient({
|
|
200
|
+
protocol: 'https',
|
|
201
|
+
host: 'api.example.com',
|
|
202
|
+
reqHeaders: {
|
|
203
|
+
'X-API-Key': 'your-api-key',
|
|
204
|
+
'User-Agent': 'MyApp/1.0'
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
api.get(null, '/data', function(response) {
|
|
209
|
+
console.log(response.data);
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Error Handling
|
|
214
|
+
|
|
215
|
+
```javascript
|
|
216
|
+
api.get(null, '/endpoint', function(response) {
|
|
217
|
+
if (response instanceof Error) {
|
|
218
|
+
console.error('Request failed:', response.message);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
console.log('Success:', response.data);
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Complete Test Example
|
|
227
|
+
|
|
228
|
+
```javascript
|
|
229
|
+
const HttpClient = require('nodeunit-api-client');
|
|
230
|
+
|
|
231
|
+
const api = new HttpClient({
|
|
232
|
+
protocol: 'https',
|
|
233
|
+
host: 'jsonplaceholder.typicode.com'
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
exports.apiTests = {
|
|
237
|
+
'GET /posts/1': function(test) {
|
|
238
|
+
api.get(test, '/posts/1', {}, {
|
|
239
|
+
status: 200,
|
|
240
|
+
headers: { 'content-type': 'application/json; charset=utf-8' }
|
|
241
|
+
}, function(response) {
|
|
242
|
+
test.equal(response.data.id, 1);
|
|
243
|
+
test.ok(response.data.title);
|
|
244
|
+
test.done();
|
|
245
|
+
});
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
'POST /posts': function(test) {
|
|
249
|
+
api.post(test, '/posts', {
|
|
250
|
+
data: {
|
|
251
|
+
title: 'foo',
|
|
252
|
+
body: 'bar',
|
|
253
|
+
userId: 1
|
|
254
|
+
}
|
|
255
|
+
}, {
|
|
256
|
+
status: 201
|
|
257
|
+
}, function(response) {
|
|
258
|
+
test.equal(response.data.title, 'foo');
|
|
259
|
+
test.done();
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
```
|
|
264
|
+
```bash
|
|
265
|
+
Copyright (c) 2024 Sabri
|
|
266
|
+
|
|
267
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
268
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
269
|
+
in the Software without restriction, including without limitation the rights
|
|
270
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
271
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
272
|
+
furnished to do so, subject to the following conditions:
|
|
273
|
+
|
|
274
|
+
The above copyright notice and this permission notice shall be included in all
|
|
275
|
+
copies or substantial portions of the Software.
|
|
276
|
+
|
|
277
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
278
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
279
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
280
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
281
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
282
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
283
|
+
SOFTWARE.
|
|
284
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nodeunit-api-client",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "Lightweight HTTP/HTTPS client with built-in testing assertions for Nodeunit",
|
|
5
|
+
"main": "src/httpclient.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./src/httpclient.js"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"http",
|
|
11
|
+
"https",
|
|
12
|
+
"client",
|
|
13
|
+
"testing",
|
|
14
|
+
"nodeunit",
|
|
15
|
+
"test",
|
|
16
|
+
"assertions",
|
|
17
|
+
"api",
|
|
18
|
+
"rest"
|
|
19
|
+
],
|
|
20
|
+
"author": "Sabri <ssabri1996@gmail.com>",
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/ssabri1996/nodeunit-httpclient.git"
|
|
25
|
+
},
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/ssabri1996/nodeunit-httpclient/issues"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/ssabri1996/nodeunit-httpclient#readme",
|
|
30
|
+
"scripts": {
|
|
31
|
+
"test": "npx nodeunit test/httpclient.test.js",
|
|
32
|
+
"prepublishOnly": "npm test"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=14"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"src/httpclient.js",
|
|
39
|
+
"README.md",
|
|
40
|
+
"LICENSE"
|
|
41
|
+
],
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"nodeunit": "^0.11.3"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"underscore": "^1.13.7"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
var querystring = require('querystring'),
|
|
3
|
+
underscore = require('underscore'),
|
|
4
|
+
debug;
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {object} Options:
|
|
9
|
+
* auth ('username:password')
|
|
10
|
+
* host ('localhost')
|
|
11
|
+
* port (80)
|
|
12
|
+
* path ('') - Base path URL e.g. '/api'
|
|
13
|
+
* headers ({}) - Test that these headers are present on every response (unless overridden)
|
|
14
|
+
* status (null) - Test that every response has this status (unless overridden)
|
|
15
|
+
* https (false) - https/http
|
|
16
|
+
* @param options
|
|
17
|
+
*/
|
|
18
|
+
var HttpClient = module.exports = function(options) {
|
|
19
|
+
options = options || {};
|
|
20
|
+
|
|
21
|
+
this.auth = options.auth || undefined;
|
|
22
|
+
this.host = options.host || 'localhost';
|
|
23
|
+
this.port = options.port || 80;
|
|
24
|
+
this.path = options.path || '';
|
|
25
|
+
this.headers = options.headers || {};
|
|
26
|
+
this.status = options.status;
|
|
27
|
+
this.http = require(options.https ? 'https' : 'http');
|
|
28
|
+
debug = options.debug ? true : false;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
HttpClient.create = function(options) {
|
|
32
|
+
return new HttpClient(options);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
var methods = ['get', 'post', 'head', 'put', 'del', 'trace', 'options', 'connect'];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Performs a testable http request
|
|
39
|
+
*
|
|
40
|
+
* @param {Assert}
|
|
41
|
+
* Nodeunit assert object
|
|
42
|
+
* @param {string} [route=undefined]
|
|
43
|
+
* http uri to test
|
|
44
|
+
* @param {object} [req=undefined]
|
|
45
|
+
* Object containing request related attributes like headers or body.
|
|
46
|
+
* @param {object} [res=undefined]
|
|
47
|
+
* Object to compare with the response of the http call
|
|
48
|
+
* @param {Function} [cb=undefined]
|
|
49
|
+
* Callback that will be called after the http call. Receives the http response object.
|
|
50
|
+
*/
|
|
51
|
+
methods.forEach(function(method) {
|
|
52
|
+
HttpClient.prototype[method] = function(assert, path, req, res, cb) {
|
|
53
|
+
var self = this;
|
|
54
|
+
|
|
55
|
+
//Handle different signatures
|
|
56
|
+
if (arguments.length == 3) {
|
|
57
|
+
//(assert, path, cb)
|
|
58
|
+
if (typeof req === 'function') {
|
|
59
|
+
cb = req;
|
|
60
|
+
req = {};
|
|
61
|
+
res = {};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//(assert, path, res)
|
|
65
|
+
else {
|
|
66
|
+
cb = null;
|
|
67
|
+
res = req;
|
|
68
|
+
req = {};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//(assert, path, req, cb)
|
|
73
|
+
if (arguments.length == 4) {
|
|
74
|
+
if (typeof res == 'function') {
|
|
75
|
+
cb = res;
|
|
76
|
+
res = {};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
//Also accepted:
|
|
81
|
+
//(assert, path, req, res)
|
|
82
|
+
//(assert, path, req, res, cb)
|
|
83
|
+
|
|
84
|
+
//Generate path based on base path, route path and querystring params
|
|
85
|
+
var fullPath = this.path + path;
|
|
86
|
+
|
|
87
|
+
//Don't add to querystring if POST or PUT
|
|
88
|
+
if (['post', 'put'].indexOf(method) === -1) {
|
|
89
|
+
var data = req.data;
|
|
90
|
+
|
|
91
|
+
if (data) {fullPath += '?' + querystring.stringify(data);}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var options = {
|
|
95
|
+
host: this.host,
|
|
96
|
+
port: this.port,
|
|
97
|
+
path: fullPath,
|
|
98
|
+
method: method == 'del' ? 'DELETE' : method.toUpperCase(),
|
|
99
|
+
headers: underscore.extend({}, this.headers, req.headers)
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
if (req.auth) {
|
|
103
|
+
options.auth = req.auth;
|
|
104
|
+
} else if (this.auth) {
|
|
105
|
+
options.auth = this.auth;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
var request = this.http.request(options);
|
|
109
|
+
|
|
110
|
+
//Write POST & PUTdata
|
|
111
|
+
if (['post', 'put'].indexOf(method) != -1) {
|
|
112
|
+
var data = req.data || req.body;
|
|
113
|
+
|
|
114
|
+
if (data) {
|
|
115
|
+
if (typeof data == 'object') {
|
|
116
|
+
request.setHeader('content-type', 'application/json');
|
|
117
|
+
request.write(JSON.stringify(data));
|
|
118
|
+
} else {
|
|
119
|
+
request.write(data);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (debug) {httpClientLogger.log('REQUEST', request);}
|
|
125
|
+
//Send
|
|
126
|
+
request.end();
|
|
127
|
+
|
|
128
|
+
request.on('response', function(response) {
|
|
129
|
+
if (debug) {httpClientLogger.log('RESPONSE', response);}
|
|
130
|
+
|
|
131
|
+
response.setEncoding('utf8');
|
|
132
|
+
|
|
133
|
+
response.on('data', function(chunk) {
|
|
134
|
+
if (response.body) {response.body += chunk;} else {response.body = chunk;}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
//Handle the response; run response tests and hand back control to test
|
|
138
|
+
response.on('end', function() {
|
|
139
|
+
//Add parsed JSON
|
|
140
|
+
var contentType = response.headers['content-type'];
|
|
141
|
+
if (contentType && contentType.indexOf('application/json') != -1) {
|
|
142
|
+
if (typeof response.body != 'undefined') {
|
|
143
|
+
//Catch errors on JSON.parse and attempt to handle cases where the response.body contains html
|
|
144
|
+
try {
|
|
145
|
+
response.data = JSON.parse(response.body);
|
|
146
|
+
} catch (err) {
|
|
147
|
+
console.log('JSON.parse response.body error:');
|
|
148
|
+
console.log(err);
|
|
149
|
+
if (debug) {httpClientLogger.log('RESPONSE.BODY', response.body);}
|
|
150
|
+
var responseTest = response.body.split('{');
|
|
151
|
+
if (responseTest.length > 1) {
|
|
152
|
+
var actualResponse = '{' + responseTest[1];
|
|
153
|
+
try {
|
|
154
|
+
response.data = JSON.parse(actualResponse);
|
|
155
|
+
console.log('JSON.parse second attempt success.');
|
|
156
|
+
} catch (err) {
|
|
157
|
+
console.log('JSON.parse error on second parse attempt.');
|
|
158
|
+
console.log(err);
|
|
159
|
+
if (debug) {httpClientLogger.log('FILTERED RESPONSE.BODY', actualResponse);}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
//Run tests on the response
|
|
167
|
+
(function testResponse() {
|
|
168
|
+
//Can pass in falsy value to prevent running tests
|
|
169
|
+
if (!assert) {return;}
|
|
170
|
+
|
|
171
|
+
//Status code
|
|
172
|
+
var status = res.status || self.status;
|
|
173
|
+
if (status) {
|
|
174
|
+
assert.equal(response.statusCode, status);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
//Headers
|
|
178
|
+
var headers = underscore.extend({}, self.headers, res.headers);
|
|
179
|
+
for (var key in headers) {
|
|
180
|
+
assert.equal(response.headers[key], headers[key]);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
//Body
|
|
184
|
+
if (res.body) {
|
|
185
|
+
assert.equal(response.body, res.body);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
//JSON data
|
|
189
|
+
if (res.data) {
|
|
190
|
+
assert.deepEqual(response.data, res.data);
|
|
191
|
+
}
|
|
192
|
+
})();
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
//Done, return control to test
|
|
196
|
+
if (cb) {return cb(response);} else {return assert.done();}
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
var httpClientLogger = {
|
|
203
|
+
log: function(header, data) {
|
|
204
|
+
console.log(header);
|
|
205
|
+
console.log(data);
|
|
206
|
+
}
|
|
207
|
+
};
|