Skip to content

Commit

Permalink
Merge pull request #112 from particle-iot/downloadBinaryFix
Browse files Browse the repository at this point in the history
fixes #110
  • Loading branch information
busticated authored Feb 4, 2020
2 parents bde184c + 2dd6a63 commit 11c288d
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 31 deletions.
26 changes: 20 additions & 6 deletions src/Agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,19 @@ export default class Agent {
* @parma {Object} context the invocation context, describing the tool and project.
* @return {Promise} A promise. fulfilled with {body, statusCode}, rejected with { statusCode, errorDescription, error, body }
*/
request({ uri, method, data = undefined, auth, query = undefined, form = undefined, files = undefined, context = undefined }) {
request({
uri,
method,
data = undefined,
auth,
query = undefined,
form = undefined,
files = undefined,
context = undefined,
raw = false
}) {
const requestFiles = this._sanitizeFiles(files);
return this._request({ uri, method, data, auth, query, form, context, files: requestFiles });
return this._request({ uri, method, data, auth, query, form, context, files: requestFiles, raw });
}

/**
Expand All @@ -76,8 +86,12 @@ export default class Agent {
* @param {Object} context the invocation context
* @return {Promise} A promise. fulfilled with {body, statusCode}, rejected with { statusCode, errorDescription, error, body }
*/
_request({ uri, method, data, auth, query, form, files, context }) {
_request({ uri, method, data, auth, query, form, files, context, raw }) {
const req = this._buildRequest({ uri, method, data, auth, query, form, context, files });

if (raw){
return req;
}
return this._promiseResponse(req);
}

Expand Down Expand Up @@ -123,7 +137,7 @@ export default class Agent {
});
}

_buildRequest({ uri, method, data, auth, query, form, files, context, makerequest=request }) {
_buildRequest({ uri, method, data, auth, query, form, files, context, makerequest = request }) {
const req = makerequest(method, uri);
if (this.prefix) {
req.use(this.prefix);
Expand All @@ -141,7 +155,7 @@ export default class Agent {
let options = {
filepath: file.path
};
if (this._inBrowser(makerequest)) {
if (this.isForBrowser(makerequest)) {
options = file.path;
}
req.attach(name, file.data, options);
Expand All @@ -160,7 +174,7 @@ export default class Agent {
return req;
}

_inBrowser(makerequest) {
isForBrowser(makerequest = request) {
// superagent only has the getXHR method in the browser version
return !!makerequest.getXHR;
}
Expand Down
52 changes: 30 additions & 22 deletions src/Particle.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import request from 'superagent';
import binaryParser from './superagent-binary-parser';
import Defaults from './Defaults';
import EventStream from './EventStream';
Expand Down Expand Up @@ -588,11 +587,14 @@ class Particle {
* @returns {Request} A promise
*/
downloadFirmwareBinary({ binaryId, auth }){
const uri = `/v1/binaries/${binaryId}`;
const req = request('get', uri);
req.use(this.prefix);
this.headers(req, auth);
return req;
let req = this.request({
uri: `/v1/binaries/${binaryId}`,
method: 'get',
raw: true,
auth
});

return this._provideFileData(req);
}

/**
Expand Down Expand Up @@ -1131,17 +1133,8 @@ class Particle {
* @returns {Promise} Resolves to a buffer with the file data
*/
downloadFile({ url }){
let req = request.get(url);
// Different API in Node and browser
if (!request.getXHR){
req = req.buffer(true).parse(binaryParser);
} else if (req.responseType){
req = req.responseType('arraybuffer').then(res => {
res.body = res.xhr.response;
return res;
});
}
return req.then(res => res.body);
let req = this.request({ uri: url, method: 'get', raw: true });
return this._provideFileData(req);
}

/**
Expand Down Expand Up @@ -1299,11 +1292,26 @@ class Particle {
* @returns {Request} A promise
*/
downloadProductFirmware({ version, product, auth }){
const uri = `/v1/products/${product}/firmware/${version}/binary`;
const req = request('get', uri);
req.use(this.prefix);
this.headers(req, auth);
return req;
let req = this.request({
uri: `/v1/products/${product}/firmware/${version}/binary`,
method: 'get',
raw: true,
auth
});

return this._provideFileData(req);
}

_provideFileData(req){
if (this.agent.isForBrowser()){
req = req.responseType('arraybuffer').then(res => {
res.body = res.xhr.response;
return res;
});
} else {
req = req.buffer(true).parse(binaryParser);
}
return req.then(res => res.body);
}

/**
Expand Down
6 changes: 4 additions & 2 deletions test/Agent.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,8 @@ describe('Agent', () => {
query: 'all',
form:form,
files: sanitizedFiles,
context: undefined
context: undefined,
raw: false
});
});

Expand All @@ -323,7 +324,8 @@ describe('Agent', () => {
files: undefined,
form: undefined,
query: undefined,
context: undefined
context: undefined,
raw: false
});
});

Expand Down
44 changes: 43 additions & 1 deletion test/Particle.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const props = {
files: {
'app.ino': new Buffer('void(){}\nsetup(){}\n')
},
binaryId: '123456',
targetVersion: '0.4.7',
requestType: 'GET',
headers: {
Expand Down Expand Up @@ -712,6 +713,21 @@ describe('ParticleAPI', () => {
});
});
});
describe('.downloadFirmwareBinary', () => {
it('generates request', () => {
sinon.stub(api, '_provideFileData').callsFake(x => Promise.resolve(x));
const req = api.downloadFirmwareBinary(propsWithProduct);
api._provideFileData.callCount.should.equal(1);
return req.then((results) => {
results.should.match({
uri: `/v1/binaries/${props.binaryId}`,
method: 'get',
auth: props.auth,
raw: true
});
});
});
});
describe('.sendPublicKey', () => {
it('generates request', () => {
return api.sendPublicKey(props).then(Common.expectDeviceUrlAndToken);
Expand Down Expand Up @@ -1574,7 +1590,17 @@ describe('ParticleAPI', () => {
});
});
});

describe('.downloadFile', () => {
it('generates request', () => {
sinon.stub(api, '_provideFileData').callsFake(x => Promise.resolve(x));
const uri = 'http://example.com/path/to/file.png';
const req = api.downloadFile({ url: uri });
api._provideFileData.callCount.should.equal(1);
return req.then((results) => {
results.should.match({ uri, method: 'get', raw: true });
});
});
});
describe('.listOAuthClients', () => {
describe('user scope', () => {
it('generates request', () => {
Expand Down Expand Up @@ -1751,6 +1777,22 @@ describe('ParticleAPI', () => {
});
});

describe('.downloadProductFirmware', () => {
it('generates request', () => {
sinon.stub(api, '_provideFileData').callsFake(x => Promise.resolve(x));
const req = api.downloadProductFirmware(propsWithProduct);
api._provideFileData.callCount.should.equal(1);
return req.then((results) => {
results.should.match({
uri: `/v1/products/${product}/firmware/${props.version}/binary`,
method: 'get',
auth: props.auth,
raw: true
});
});
});
});

describe('.getProductFirmware', () => {
it('generates request', () => {
return api.getProductFirmware(propsWithProduct).then((results) => {
Expand Down

0 comments on commit 11c288d

Please sign in to comment.