Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 38 additions & 5 deletions src/ParseFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
*
* @flow
*/
/* global File */
/* global XMLHttpRequest, File */
import CoreManager from './CoreManager';
import type { FullOptions } from './RESTController';
const http = require('http');
const https = require('https');

let XHR = null;
if (typeof XMLHttpRequest !== 'undefined') {
XHR = XMLHttpRequest;
}

type Base64 = { base64: string };
type FileData = Array<number> | Base64 | File;
Expand Down Expand Up @@ -311,10 +314,16 @@ const DefaultController = {
},

download: function(uri) {
if (XHR) {
return this.downloadAjax(uri);
}
if (process.env.PARSE_BUILD !== 'node') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe i don't understand what process.env.PARSE_BUILD is, but the way I'm reading this is:

if we're not in node, complain that we don't have XMLHttpRequest, but XMLHttpRequest is in the browser, not node. set me straight here :).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For browsers that don't support ajax.

https://www.tutorialspoint.com/ajax/ajax_browser_support.htm

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return Promise.reject('Cannot make a request: No definition of XMLHttpRequest was found.');
}
return new Promise((resolve, reject) => {
let client = http;
let client = require('http');
if (uri.indexOf('https') === 0) {
client = https;
client = require('https');
}
client.get(uri, (resp) => {
resp.setEncoding('base64');
Expand All @@ -328,6 +337,30 @@ const DefaultController = {
});
}).on('error', reject);
});
},

downloadAjax: function(uri) {
return new Promise((resolve, reject) => {
const xhr = new XHR();
xhr.open('GET', uri, true);
xhr.responseType = 'arraybuffer';
xhr.onerror = function(e) { reject(e); };
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) {
return;
}
const bytes = new Uint8Array(this.response);
resolve({
base64: ParseFile.encodeBase64(bytes),
contentType: xhr.getResponseHeader('content-type'),
});
};
xhr.send();
});
},

_setXHR(xhr: any) {
XHR = xhr;
}
};

Expand Down
54 changes: 54 additions & 0 deletions src/__tests__/ParseFile-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ describe('FileController', () => {
});

it('download with base64 http', async () => {
defaultController._setXHR(null);
const mockResponse = Object.create(EventEmitter.prototype);
EventEmitter.call(mockResponse);
mockResponse.setEncoding = function() {}
Expand All @@ -328,6 +329,7 @@ describe('FileController', () => {
});

it('download with base64 https', async () => {
defaultController._setXHR(null);
const mockResponse = Object.create(EventEmitter.prototype);
EventEmitter.call(mockResponse);
mockResponse.setEncoding = function() {}
Expand All @@ -351,4 +353,56 @@ describe('FileController', () => {
expect(mockHttps.get).toHaveBeenCalledTimes(1);
spy.mockRestore();
});

it('download with ajax', async () => {
const mockXHR = function () {
return {
open: jest.fn(),
send: jest.fn().mockImplementation(function() {
this.response = [61, 170, 236, 120];
this.readyState = 2;
this.onreadystatechange();
this.readyState = 4;
this.onreadystatechange();
}),
getResponseHeader: function() {
return 'image/png';
}
};
};
defaultController._setXHR(mockXHR);

const data = await defaultController.download('https://example.com/image.png');
expect(data.base64).toBe('ParseA==');
expect(data.contentType).toBe('image/png');
});

it('download with ajax error', async () => {
const mockXHR = function () {
return {
open: jest.fn(),
send: jest.fn().mockImplementation(function() {
this.onerror('error thrown');
})
};
};
defaultController._setXHR(mockXHR);

try {
await defaultController.download('https://example.com/image.png');
} catch (e) {
expect(e).toBe('error thrown');
}
});

it('download with xmlhttprequest unsupported', async () => {
defaultController._setXHR(null);
process.env.PARSE_BUILD = 'browser';
try {
await defaultController.download('https://example.com/image.png');
} catch (e) {
expect(e).toBe('Cannot make a request: No definition of XMLHttpRequest was found.');
}
process.env.PARSE_BUILD = 'node';
});
});