Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
46 changes: 39 additions & 7 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,11 +314,16 @@ const DefaultController = {
},

download: function(uri) {
if (XHR) {
return this.downloadAjax(uri);
}
if (process.env.PARSE_BUILD === 'browser') {
return Promise.reject('Cannot make a request: No definition of XMLHttpRequest was found.');
}
return new Promise((resolve, reject) => {
let client = http;
if (uri.indexOf('https') === 0) {
client = https;
}
const client = uri.indexOf('https') === 0
? require('https')
: require('http');
client.get(uri, (resp) => {
resp.setEncoding('base64');
let base64 = '';
Expand All @@ -328,6 +336,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
57 changes: 57 additions & 0 deletions src/__tests__/ParseFile-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ describe('ParseFile', () => {
});
});

afterEach(() => {
process.env.PARSE_BUILD = 'node';
});

it('can create files with base64 encoding', () => {
const file = new ParseFile('parse.txt', { base64: 'ParseA==' });
expect(file._source.base64).toBe('ParseA==');
Expand Down Expand Up @@ -303,6 +307,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 +333,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 +357,55 @@ 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.');
}
});
});