Skip to content

Commit 3e41368

Browse files
flovilmartTylerBrock
authored andcommitted
Makes HTTPResponse serializable (#2143)
* Use the callback body instead of response.body that may not be set * Adds test to handle undefined responses * Adds toJSON method to properly serialize HTTPResponse * Use ES5 defineProperty to make keys enumerable * removes body key from serialization * Indent nits
1 parent 35b4c06 commit 3e41368

File tree

3 files changed

+122
-16
lines changed

3 files changed

+122
-16
lines changed

spec/HTTPRequest.spec.js

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
var httpRequest = require("../src/cloud-code/httpRequest"),
4+
HTTPResponse = require('../src/cloud-code/HTTPResponse').default,
45
bodyParser = require('body-parser'),
56
express = require("express");
67

@@ -245,4 +246,81 @@ describe("httpRequest", () => {
245246
})
246247
});
247248

249+
it('should not crash with undefined body', () => {
250+
let httpResponse = new HTTPResponse({});
251+
expect(httpResponse.body).toBeUndefined();
252+
expect(httpResponse.data).toBeUndefined();
253+
expect(httpResponse.text).toBeUndefined();
254+
expect(httpResponse.buffer).toBeUndefined();
255+
});
256+
257+
it('serialized httpResponse correctly with body string', () => {
258+
let httpResponse = new HTTPResponse({}, 'hello');
259+
expect(httpResponse.text).toBe('hello');
260+
expect(httpResponse.data).toBe(undefined);
261+
expect(httpResponse.body).toBe('hello');
262+
263+
let serialized = JSON.stringify(httpResponse);
264+
let result = JSON.parse(serialized);
265+
expect(result.text).toBe('hello');
266+
expect(result.data).toBe(undefined);
267+
expect(result.body).toBe(undefined);
268+
});
269+
270+
it('serialized httpResponse correctly with body object', () => {
271+
let httpResponse = new HTTPResponse({}, {foo: "bar"});
272+
let encodedResponse = Parse._encode(httpResponse);
273+
let serialized = JSON.stringify(httpResponse);
274+
let result = JSON.parse(serialized);
275+
276+
expect(httpResponse.text).toEqual('{"foo":"bar"}');
277+
expect(httpResponse.data).toEqual({foo: 'bar'});
278+
expect(httpResponse.body).toEqual({foo: 'bar'});
279+
280+
expect(result.text).toEqual('{"foo":"bar"}');
281+
expect(result.data).toEqual({foo: 'bar'});
282+
expect(result.body).toEqual(undefined);
283+
});
284+
285+
it('serialized httpResponse correctly with body buffer string', () => {
286+
let httpResponse = new HTTPResponse({}, new Buffer('hello'));
287+
expect(httpResponse.text).toBe('hello');
288+
expect(httpResponse.data).toBe(undefined);
289+
290+
let serialized = JSON.stringify(httpResponse);
291+
let result = JSON.parse(serialized);
292+
expect(result.text).toBe('hello');
293+
expect(result.data).toBe(undefined);
294+
});
295+
296+
it('serialized httpResponse correctly with body buffer JSON Object', () => {
297+
let json = '{"foo":"bar"}';
298+
let httpResponse = new HTTPResponse({}, new Buffer(json));
299+
let serialized = JSON.stringify(httpResponse);
300+
let result = JSON.parse(serialized);
301+
expect(result.text).toEqual('{"foo":"bar"}');
302+
expect(result.data).toEqual({foo: 'bar'});
303+
});
304+
305+
it('serialized httpResponse with Parse._encode should be allright', () => {
306+
let json = '{"foo":"bar"}';
307+
let httpResponse = new HTTPResponse({}, new Buffer(json));
308+
let encoded = Parse._encode(httpResponse);
309+
let foundData, foundText, foundBody = false;
310+
for(var key in encoded) {
311+
if (key == 'data') {
312+
foundData = true;
313+
}
314+
if (key == 'text') {
315+
foundText = true;
316+
}
317+
if (key == 'body') {
318+
foundBody = true;
319+
}
320+
}
321+
expect(foundData).toBe(true);
322+
expect(foundText).toBe(true);
323+
expect(foundBody).toBe(false);
324+
});
325+
248326
});

src/cloud-code/HTTPResponse.js

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,49 @@
11

22
export default class HTTPResponse {
3-
constructor(response) {
3+
constructor(response, body) {
4+
let _text, _data;
45
this.status = response.statusCode;
5-
this.headers = response.headers;
6-
this.buffer = response.body;
7-
this.cookies = response.headers["set-cookie"];
8-
}
9-
10-
get text() {
11-
return this.buffer.toString('utf-8');
12-
}
13-
get data() {
14-
if (!this._data) {
15-
try {
16-
this._data = JSON.parse(this.text);
17-
} catch (e) {}
6+
this.headers = response.headers || {};
7+
this.cookies = this.headers["set-cookie"];
8+
9+
if (typeof body == 'string') {
10+
_text = body;
11+
} else if (Buffer.isBuffer(body)) {
12+
this.buffer = body;
13+
} else if (typeof body == 'object') {
14+
_data = body;
15+
}
16+
17+
let getText = () => {
18+
if (!_text && this.buffer) {
19+
_text = this.buffer.toString('utf-8');
20+
} else if (!_text && _data) {
21+
_text = JSON.stringify(_data);
22+
}
23+
return _text;
1824
}
19-
return this._data;
25+
26+
let getData = () => {
27+
if (!_data) {
28+
try {
29+
_data = JSON.parse(getText());
30+
} catch (e) {}
31+
}
32+
return _data;
33+
}
34+
35+
Object.defineProperty(this, 'body', {
36+
get: () => { return body }
37+
});
38+
39+
Object.defineProperty(this, 'text', {
40+
enumerable: true,
41+
get: getText
42+
});
43+
44+
Object.defineProperty(this, 'data', {
45+
enumerable: true,
46+
get: getData
47+
});
2048
}
2149
}

src/cloud-code/httpRequest.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ module.exports = function(options) {
6262
}
6363
return promise.reject(error);
6464
}
65-
let httpResponse = new HTTPResponse(response);
65+
let httpResponse = new HTTPResponse(response, body);
6666

6767
// Consider <200 && >= 400 as errors
6868
if (httpResponse.status < 200 || httpResponse.status >= 400) {

0 commit comments

Comments
 (0)