From 90219044fee02f97eca73b9e254119197d382090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Weber?= Date: Tue, 18 Apr 2017 18:24:23 -0400 Subject: [PATCH 1/8] Remove unit id from constructor --- example/index.js | 9 +++++++-- src/index.js | 7 +++---- tests/index_test.js | 15 +++++---------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/example/index.js b/example/index.js index f853c7f..10115c1 100644 --- a/example/index.js +++ b/example/index.js @@ -24,6 +24,12 @@ if (!barracksApiKey) { } var unitId = 'SDK-example-unit'; +var customClientData = { + type: 'alpha', + extra: { + app2: true + } +}; var packages = [ { @@ -43,7 +49,6 @@ var packages = [ var barracks = new Barracks({ baseURL: barracksBaseUrl, apiKey: barracksApiKey, - unitId: unitId, allowSelfSigned: (isSelfSigned ? (isSelfSigned === '1') : false) }); @@ -91,7 +96,7 @@ function handleUnavailablePackages(packages) { function waitAndDisplayUpdate() { setTimeout(function () { - barracks.checkUpdate(packages, { test: 'coucou' }).then(function (response) { + barracks.checkUpdate(unitId, packages, customClientData).then(function (response) { handleAvailablePackages(response.available); handleChangedPackages(response.changed); handleUnchangedPackages(response.unchanged); diff --git a/src/index.js b/src/index.js index 99bb2df..115062e 100644 --- a/src/index.js +++ b/src/index.js @@ -16,8 +16,7 @@ var fileHelper = require('./fileHelper'); function Barracks(options) { this.options = { baseURL: options.baseURL || DEFAULT_BARRACKS_BASE_URL, - apiKey: options.apiKey, - unitId: options.unitId + apiKey: options.apiKey }; if (options.allowSelfSigned && options.allowSelfSigned === true) { @@ -25,7 +24,7 @@ function Barracks(options) { } } -Barracks.prototype.checkUpdate = function (packages, customClientData) { +Barracks.prototype.checkUpdate = function (unitId, packages, customClientData) { var that = this; return new Promise(function (resolve, reject) { var requestOptions = { @@ -36,7 +35,7 @@ Barracks.prototype.checkUpdate = function (packages, customClientData) { 'Content-type': 'application/json' }, body: JSON.stringify({ - unitId: that.options.unitId, + unitId: unitId, customClientData: customClientData, components: packages }) diff --git a/tests/index_test.js b/tests/index_test.js index e8bc554..05d726a 100644 --- a/tests/index_test.js +++ b/tests/index_test.js @@ -36,7 +36,6 @@ describe('Constructor : ', function () { expect(barracks.checkUpdate).to.be.a('function'); expect(barracks.options).to.deep.equals({ apiKey: API_KEY, - unitId: UNIT_ID, baseURL: expectedBaseUrl }); } @@ -44,8 +43,7 @@ describe('Constructor : ', function () { it('Should return the Barracks object with default values when minimums options given', function () { // Given var options = { - apiKey: API_KEY, - unitId: UNIT_ID + apiKey: API_KEY }; // When @@ -60,7 +58,6 @@ describe('Constructor : ', function () { var url = 'not.barracks.io'; var options = { apiKey: API_KEY, - unitId: UNIT_ID, baseURL: url }; @@ -75,7 +72,6 @@ describe('Constructor : ', function () { // Given var options = { apiKey: API_KEY, - unitId: UNIT_ID, allowSelfSigned: 'plop' }; @@ -91,7 +87,6 @@ describe('Constructor : ', function () { // Given var options = { apiKey: API_KEY, - unitId: UNIT_ID, allowSelfSigned: true }; @@ -159,7 +154,7 @@ describe('checkUpdate(components, customClientData) ', function () { }; // When / Then - barracks.checkUpdate(components).then(function () { + barracks.checkUpdate(UNIT_ID, components).then(function () { done('should have failed'); }).catch(function (err) { expect(err).to.deep.equals({ @@ -187,7 +182,7 @@ describe('checkUpdate(components, customClientData) ', function () { }; // When / Then - barracks.checkUpdate(components).then(function () { + barracks.checkUpdate(UNIT_ID, components).then(function () { done('should have failed'); }).catch(function (err) { expect(err).to.deep.equals({ @@ -228,7 +223,7 @@ describe('checkUpdate(components, customClientData) ', function () { }; // When / Then - barracks.checkUpdate(components).then(function (result) { + barracks.checkUpdate(UNIT_ID, components).then(function (result) { expect(result).to.deep.equals(componentInfo); expect(requestSpy).to.have.been.calledOnce; expect(requestSpy).to.have.been.calledWithExactly( @@ -271,7 +266,7 @@ describe('checkUpdate(components, customClientData) ', function () { }; // When / Then - barracks.checkUpdate(components).then(function (result) { + barracks.checkUpdate(UNIT_ID, components).then(function (result) { expect(result).to.deep.equals(componentInfo); expect(requestSpy).to.have.been.calledOnce; expect(requestSpy).to.have.been.calledWithExactly( From d004f6b027ed0d6a5ef9b864c79e57f2ff27fb7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Weber?= Date: Tue, 18 Apr 2017 18:28:58 -0400 Subject: [PATCH 2/8] Add test with custom client data in check update --- tests/index_test.js | 53 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/tests/index_test.js b/tests/index_test.js index 05d726a..0aae50b 100644 --- a/tests/index_test.js +++ b/tests/index_test.js @@ -12,6 +12,10 @@ chai.use(sinonChai); var UNIT_ID = 'unit1'; var API_KEY = 'validKey'; +var CUSTOM_CLIENT_DATA = { + aKey: 'aValue', + anotherKey: true +}; var component1 = { reference: 'component.1.ref', @@ -99,14 +103,14 @@ describe('Constructor : ', function () { }); }); -describe('checkUpdate(components, customClientData) ', function () { +describe('checkUpdate(unitId, components, customClientData) ', function () { var barracks; var checkUpdateComponentsUrl = '/api/device/resolve'; var requestMock = function () {}; var buildResponseMock = function () {}; - function getRequestPayloadForComponents(components) { + function getRequestPayloadForComponents(components, customClientData) { return { url: 'https://app.barracks.io' + checkUpdateComponentsUrl, method: 'POST', @@ -116,7 +120,7 @@ describe('checkUpdate(components, customClientData) ', function () { }, body: JSON.stringify({ unitId: UNIT_ID, - customClientData: undefined, + customClientData: customClientData, components: components }) }; @@ -241,6 +245,49 @@ describe('checkUpdate(components, customClientData) ', function () { }); }); + it('Should send customClientData and return server response when server return 200 OK', function (done) { + // Given + var componentInfo = { + available:[], + changed:[], + unchanged:[], + unavailable:[] + }; + var response = { + body: JSON.stringify(componentInfo), + statusCode: 200 + }; + var components = [ component1, component2 ]; + var requestSpy = sinon.spy(); + requestMock = function (options, callback) { + requestSpy(options, callback); + callback(undefined, response, response.body); + }; + var buildResponseSpy = sinon.spy(); + buildResponseMock = function (body, downloadFunction) { + buildResponseSpy(body, downloadFunction); + return componentInfo; + }; + + // When / Then + barracks.checkUpdate(UNIT_ID, components, CUSTOM_CLIENT_DATA).then(function (result) { + expect(result).to.deep.equals(componentInfo); + expect(requestSpy).to.have.been.calledOnce; + expect(requestSpy).to.have.been.calledWithExactly( + getRequestPayloadForComponents(components, CUSTOM_CLIENT_DATA), + sinon.match.func + ); + expect(buildResponseSpy).to.have.been.calledOnce; + expect(buildResponseSpy).to.have.been.calledWithExactly( + componentInfo, + sinon.match.func + ); + done(); + }).catch(function (err) { + done(err); + }); + }); + it('Should return server response when server return 200 OK', function (done) { // Given var componentInfo = { From a61bbeaf6902c80fb46744d4ae045622aa88a527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Weber?= Date: Tue, 18 Apr 2017 18:35:00 -0400 Subject: [PATCH 3/8] Rename checkUpdate to getDevicePackages and update documentation --- README.md | 20 ++++++++++---------- example/index.js | 1 + src/index.js | 6 +++--- tests/index_test.js | 18 +++++++++--------- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 24fb1f9..100f903 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ var customClientData = { } }; -barracks.checkUpdate(packages, customClientData).then(function (packagesInfo) { +barracks.getDevicePackages(packages, customClientData).then(function (packagesInfo) { packagesInfo.available.forEach(function (packageInfo) { // Do something with the newly available packages }); @@ -84,7 +84,7 @@ barracks.checkUpdate(packages, customClientData).then(function (packagesInfo) { }); ``` -The ```checkUpdate``` response is always as follow : +The ```getDevicePackages``` response is always as follow : ```js { @@ -128,7 +128,7 @@ The ```checkUpdate``` response is always as follow : ### Download a package -Once you have the response from checkUpdate, you'll be able to download file for all packages that are available for the device (packages that are in the ```available```, and ```changed``` lists of the response). +Once you have the response from getDevicePackages, you'll be able to download file for all packages that are available for the device (packages that are in the ```available```, and ```changed``` lists of the response). ```js var packages = [ @@ -142,7 +142,7 @@ var packages = [ } ]; -barracks.checkUpdate(packages, customClientData).then(function (packagesInfo) { +barracks.getDevicePackages(packages, customClientData).then(function (packagesInfo) { var downloadAvailablePackagesPromise = Promise.all( packagesInfo.available.map(function (packageInfo) { return packageInfo.download('/tmp/' + package.filename); // Return a Promise @@ -180,12 +180,12 @@ All errors returned by the SDK follow the same object format: Error type can be one of the the following: -* `REQUEST_FAILED`, is returned by both `Barracks.checkUpdate()` and `Barracks.checkUpdateAndDownload()` methods if the check update request fails. The error object also contains one additional property `requestError` that is the `Error` object returned by the [request](https://www.npmjs.com/package/request) library. -* `UNEXPECTED_SERVER_RESPONSE`, is returned by both `Barracks.checkUpdate()` and `Barracks.checkUpdateAndDownload()` methods if the HTTP response code is not `200` (a new update is available) or `204` (no update available). -* `DOWNLOAD_FAILED`, is returned by both `Update.download()` and `Barracks.checkUpdateAndDownload()` methods if the download of an update package fails. -* `DELETE_FILE_FAILED`, is returned by both `Update.download()` and `Barracks.checkUpdateAndDownload()` methods if the SDK fail to delete an update package that did not pass the MD5 checksum verification. -* `CHECKSUM_VERIFICATION_FAILED`, is returned by both `Update.download()` and `Barracks.checkUpdateAndDownload()` methods if the MD5 checksum verification of the update package downloaded fails. -* `MD5_HASH_CREATION_FAILED`, is returned by both `Update.download()` and `Barracks.checkUpdateAndDownload()` methods if the SDK is not able to generate the MD5 checksum of the update package downloaded. +* `REQUEST_FAILED`, is returned by `Barracks.getDevicePackages()` method if the getDevicePackage request fails. The error object also contains one additional property `requestError` that is the `Error` object returned by the [request](https://www.npmjs.com/package/request) library. +* `UNEXPECTED_SERVER_RESPONSE`, is returned by `Barracks.getDevicePackages()` method if the HTTP response code is not `200`. +* `DOWNLOAD_FAILED`, is returned by `Package.download()` method if the download of a package fails. +* `DELETE_FILE_FAILED`, is returned by `Package.download()` method if the SDK fail to delete a package that did not pass the MD5 checksum verification. +* `CHECKSUM_VERIFICATION_FAILED`, is returned by `Package.download()` method if the MD5 checksum verification of the package downloaded fails. +* `MD5_HASH_CREATION_FAILED`, is returned by `Package.download()` method if the SDK is not able to generate the MD5 checksum of the package downloaded. ## Docs & Community diff --git a/example/index.js b/example/index.js index 10115c1..6de6191 100644 --- a/example/index.js +++ b/example/index.js @@ -97,6 +97,7 @@ function handleUnavailablePackages(packages) { function waitAndDisplayUpdate() { setTimeout(function () { barracks.checkUpdate(unitId, packages, customClientData).then(function (response) { + barracks.getDevicePackages(unitId, packages, customClientData).then(function (response) { handleAvailablePackages(response.available); handleChangedPackages(response.changed); handleUnchangedPackages(response.unchanged); diff --git a/src/index.js b/src/index.js index 115062e..ccfd3e1 100644 --- a/src/index.js +++ b/src/index.js @@ -5,7 +5,7 @@ var ERROR_DOWNLOAD_FAILED = 'DOWNLOAD_FAILED'; var ERROR_UNEXPECTED_SERVER_RESPONSE = 'UNEXPECTED_SERVER_RESPONSE'; var DEFAULT_BARRACKS_BASE_URL = 'https://app.barracks.io'; -var CHECK_UPDATE_ENDPOINT = '/api/device/resolve'; +var GET_DEVICE_PACKAGES_ENDPOINT = '/api/device/resolve'; require('es6-promise').polyfill(); var responseBuilder = require('./responseBuilder'); @@ -24,11 +24,11 @@ function Barracks(options) { } } -Barracks.prototype.checkUpdate = function (unitId, packages, customClientData) { +Barracks.prototype.getDevicePackages = function (unitId, packages, customClientData) { var that = this; return new Promise(function (resolve, reject) { var requestOptions = { - url: that.options.baseURL + CHECK_UPDATE_ENDPOINT, + url: that.options.baseURL + GET_DEVICE_PACKAGES_ENDPOINT, method: 'POST', headers: { 'Authorization': that.options.apiKey, diff --git a/tests/index_test.js b/tests/index_test.js index 0aae50b..0ee322c 100644 --- a/tests/index_test.js +++ b/tests/index_test.js @@ -37,7 +37,7 @@ describe('Constructor : ', function () { function validateBarracksObject(barracks, expectedBaseUrl) { expect(barracks).to.be.an('object'); expect(barracks.options).to.be.an('object'); - expect(barracks.checkUpdate).to.be.a('function'); + expect(barracks.getDevicePackages).to.be.a('function'); expect(barracks.options).to.deep.equals({ apiKey: API_KEY, baseURL: expectedBaseUrl @@ -103,16 +103,16 @@ describe('Constructor : ', function () { }); }); -describe('checkUpdate(unitId, components, customClientData) ', function () { +describe('getDevicePackages(unitId, components, customClientData) ', function () { var barracks; - var checkUpdateComponentsUrl = '/api/device/resolve'; + var getDevicePackagesComponentsUrl = '/api/device/resolve'; var requestMock = function () {}; var buildResponseMock = function () {}; function getRequestPayloadForComponents(components, customClientData) { return { - url: 'https://app.barracks.io' + checkUpdateComponentsUrl, + url: 'https://app.barracks.io' + getDevicePackagesComponentsUrl, method: 'POST', headers: { 'Authorization': API_KEY, @@ -158,7 +158,7 @@ describe('checkUpdate(unitId, components, customClientData) ', function () { }; // When / Then - barracks.checkUpdate(UNIT_ID, components).then(function () { + barracks.getDevicePackages(UNIT_ID, components).then(function () { done('should have failed'); }).catch(function (err) { expect(err).to.deep.equals({ @@ -186,7 +186,7 @@ describe('checkUpdate(unitId, components, customClientData) ', function () { }; // When / Then - barracks.checkUpdate(UNIT_ID, components).then(function () { + barracks.getDevicePackages(UNIT_ID, components).then(function () { done('should have failed'); }).catch(function (err) { expect(err).to.deep.equals({ @@ -227,7 +227,7 @@ describe('checkUpdate(unitId, components, customClientData) ', function () { }; // When / Then - barracks.checkUpdate(UNIT_ID, components).then(function (result) { + barracks.getDevicePackages(UNIT_ID, components).then(function (result) { expect(result).to.deep.equals(componentInfo); expect(requestSpy).to.have.been.calledOnce; expect(requestSpy).to.have.been.calledWithExactly( @@ -270,7 +270,7 @@ describe('checkUpdate(unitId, components, customClientData) ', function () { }; // When / Then - barracks.checkUpdate(UNIT_ID, components, CUSTOM_CLIENT_DATA).then(function (result) { + barracks.getDevicePackages(UNIT_ID, components, CUSTOM_CLIENT_DATA).then(function (result) { expect(result).to.deep.equals(componentInfo); expect(requestSpy).to.have.been.calledOnce; expect(requestSpy).to.have.been.calledWithExactly( @@ -313,7 +313,7 @@ describe('checkUpdate(unitId, components, customClientData) ', function () { }; // When / Then - barracks.checkUpdate(UNIT_ID, components).then(function (result) { + barracks.getDevicePackages(UNIT_ID, components).then(function (result) { expect(result).to.deep.equals(componentInfo); expect(requestSpy).to.have.been.calledOnce; expect(requestSpy).to.have.been.calledWithExactly( From 4859879cb33f762836b7868756655a74753b3b26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Weber?= Date: Tue, 18 Apr 2017 18:41:09 -0400 Subject: [PATCH 4/8] Fix example --- example/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/example/index.js b/example/index.js index 6de6191..4a9f413 100644 --- a/example/index.js +++ b/example/index.js @@ -96,7 +96,6 @@ function handleUnavailablePackages(packages) { function waitAndDisplayUpdate() { setTimeout(function () { - barracks.checkUpdate(unitId, packages, customClientData).then(function (response) { barracks.getDevicePackages(unitId, packages, customClientData).then(function (response) { handleAvailablePackages(response.available); handleChangedPackages(response.changed); From 2c381cf867bb44addd76880ea6927f83bfc49e6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Weber?= Date: Tue, 18 Apr 2017 19:06:44 -0400 Subject: [PATCH 5/8] Add parameter validation --- src/index.js | 19 ++++++++-- tests/index_test.js | 84 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index ccfd3e1..d4dc4de 100644 --- a/src/index.js +++ b/src/index.js @@ -3,9 +3,10 @@ var ERROR_REQUEST_FAILED = 'REQUEST_FAILED'; var ERROR_DOWNLOAD_FAILED = 'DOWNLOAD_FAILED'; var ERROR_UNEXPECTED_SERVER_RESPONSE = 'UNEXPECTED_SERVER_RESPONSE'; +var ERROR_MISSING_MANDATORY_ARGUMENT = 'MISSING_MANDATORY_ARGUMENT'; -var DEFAULT_BARRACKS_BASE_URL = 'https://app.barracks.io'; -var GET_DEVICE_PACKAGES_ENDPOINT = '/api/device/resolve'; +var DEFAULT_BARRACKS_BASE_URL = 'https://app.barracks.io'; +var GET_DEVICE_PACKAGES_ENDPOINT = '/api/device/resolve'; require('es6-promise').polyfill(); var responseBuilder = require('./responseBuilder'); @@ -27,6 +28,13 @@ function Barracks(options) { Barracks.prototype.getDevicePackages = function (unitId, packages, customClientData) { var that = this; return new Promise(function (resolve, reject) { + if (!unitId || !packages) { + reject({ + type: ERROR_MISSING_MANDATORY_ARGUMENT, + message: 'missing or empty unitId or packages arguments' + }); + } + var requestOptions = { url: that.options.baseURL + GET_DEVICE_PACKAGES_ENDPOINT, method: 'POST', @@ -63,6 +71,13 @@ Barracks.prototype.getDevicePackages = function (unitId, packages, customClientD Barracks.prototype.downloadPackage = function (packageInfo, filePath) { var that = this; return new Promise(function (resolve, reject) { + if (!packageInfo) { + reject({ + type: ERROR_MISSING_MANDATORY_ARGUMENT, + message: 'missing or empty packageInfo argument' + }); + } + var downloadParams = { url: packageInfo.url, method: 'GET', diff --git a/tests/index_test.js b/tests/index_test.js index 0ee322c..62cb8b2 100644 --- a/tests/index_test.js +++ b/tests/index_test.js @@ -147,6 +147,64 @@ describe('getDevicePackages(unitId, components, customClientData) ', function () }); }); + it('Should reject MISSING_MANDATORY_ARGUMENT error when no unitId given', function (done) { + // Given + var components = [ component1, component2 ]; + + // When / Then + barracks.getDevicePackages(undefined, components).then(function () { + done('should have failed'); + }).catch(function (err) { + expect(err).to.deep.equals({ + type: 'MISSING_MANDATORY_ARGUMENT', + message: 'missing or empty unitId or packages arguments' + }); + done(); + }); + }); + + it('Should reject MISSING_MANDATORY_ARGUMENT error when empty unitId given', function (done) { + // Given + var components = [ component1, component2 ]; + + // When / Then + barracks.getDevicePackages('', components).then(function () { + done('should have failed'); + }).catch(function (err) { + expect(err).to.deep.equals({ + type: 'MISSING_MANDATORY_ARGUMENT', + message: 'missing or empty unitId or packages arguments' + }); + done(); + }); + }); + + it('Should reject MISSING_MANDATORY_ARGUMENT error when no packages given', function (done) { + // When / Then + barracks.getDevicePackages(UNIT_ID).then(function () { + done('should have failed'); + }).catch(function (err) { + expect(err).to.deep.equals({ + type: 'MISSING_MANDATORY_ARGUMENT', + message: 'missing or empty unitId or packages arguments' + }); + done(); + }); + }); + + it('Should reject MISSING_MANDATORY_ARGUMENT error when empty packages given', function (done) { + // When / Then + barracks.getDevicePackages(UNIT_ID, '').then(function () { + done('should have failed'); + }).catch(function (err) { + expect(err).to.deep.equals({ + type: 'MISSING_MANDATORY_ARGUMENT', + message: 'missing or empty unitId or packages arguments' + }); + done(); + }); + }); + it('Should return request failed error when request failed', function (done) { // Given var error = { message: 'Error occured' }; @@ -366,6 +424,32 @@ describe('downloadPackage(packageInfo, filePath) ', function () { }); }); + it('Should reject MISSING_MANDATORY_ARGUMENT error when no packageInfo given', function (done) { + // When / Then + barracks.downloadPackage().then(function () { + done('Should have failed'); + }).catch(function (err) { + expect(err).to.deep.equals({ + type: 'MISSING_MANDATORY_ARGUMENT', + message: 'missing or empty packageInfo argument' + }); + done(); + }); + }); + + it('Should reject MISSING_MANDATORY_ARGUMENT error when empty packageInfo given', function (done) { + // When / Then + barracks.downloadPackage('').then(function () { + done('Should have failed'); + }).catch(function (err) { + expect(err).to.deep.equals({ + type: 'MISSING_MANDATORY_ARGUMENT', + message: 'missing or empty packageInfo argument' + }); + done(); + }); + }); + it('Should return ERROR_DOWNLOAD_FAILED when server return http code other than 200 OK', function (done) { // Given var response = { statusCode: 500 }; From 59cfc76593fb3beb09f09280f6a5dc1e824f9a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Weber?= Date: Wed, 19 Apr 2017 16:33:32 -0400 Subject: [PATCH 6/8] Add build notifications --- .travis.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 038890a..1fdaa22 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,11 @@ deploy: secure: VTrqcB3d0y7jQWb3JuLO2TZTczArGnkOzJsik0vBVv17VB/nZyNkPlGfv1zdIIe5x3hMRwP2V/ual+MMEldLhMnGPI8359XYx6D/NAv+P8MmjwbsVbwo8hRG0ctXlDzHI9ni07zh6UaGsh/XiMEtm1sp1ZSzv8LMjNRetOEvP67SicqGvxD2mZHur30s8Fn0qTleamJddYVluJpvsCLYetobeGEghq+aS3l5A1zbnNDHsV54doyfBRjxMO05Awc8md84i4pZTbAGYFpGRxxkmCW6cyUzgWQnIlKUWSypDslwNRJOCzVIZwaXj8uyrnXCk/Bp0eZiooU5CiMjbLMoF2QMxd94vDyIxju/pYnq+yhMsTTdEHm2ZPZCJxdyMbqc0HscvouPi2va6MYXq3XRtR80kDvlAIWYWMJ8pPuSnlSRFUrk5AtQ6MygJeJxyANc+b45uyHQ1PtfBZd3TLm+PNhEZVFEoe2CAvK6IVaNoac7rMLurM/g/vtjrwbCDFBXvMMEUKuhpiVTyuig0V8lRN8IyEhytFnbMmsdFj0D+/B479fpZYOUAq2lXoJ9CxVn/qaZDYTx8DD7e/mP1xm9xJRcwCPB+RuQqDPkqGdRjXcVhkxzVSCQUHR9fOg2LyI1WHOVoc1gfaYt2kSJZ5seKmvATrp5u++yKPIdvkAR1AU= on: tags: true - repo: barracksiot/javascript-client \ No newline at end of file + repo: barracksiot/javascript-client + +notifications: + slack: + rooms: + secure: "ctLNliKum/SL5FhQ5PvrNkf67/fq6f6ud0V7XyZLBw5JHhn+ro8FoTY+IhZz3qh6F0AqcO0xItzBFEsY66D6gd3x+1QzYgdPvBkB42MDmE6abFrLy8LBrRpin1UEm1rtw9gQenwm+xMi8eGzytX8cSoZWR689h5mcYoN6tpWh8rxYny2XuY8BOHbLuTOJbbHpvDkAJqaZTgfhxlwhfIMKrCVvmenrvBRXuNP/mq/xxYo2Go2+H72d2IKOd1gOv7GsALhLOd3UAbhXeoK3pOUxw4jQCMYR7PjlT+LXjt4MVqElce998tbf+FAPTw9QVJc6y9jLXcto5jRBpeEdx/Wey457lBemaga375rzz3EM0gvSjwB+EhHZlq9nlhXB4iUVrZ3TiMRX6ZG6o3JoZXh7CTq2z8Mc9e0GqQ7/V21jHIuMxeUtCCTAjlRH+/5tlkwPGpEQ73UYDGdK2qjc9AWgkZZ08/ur5oEY4Mw6p5B2GcxPobgfVH/bp8ldhBrBJM0A4er7hIXimckRORvFZNg+jRTCNQYPLpyRSaIiJWGfGXaiitcaYO8z9lv835QpDbSxM3rEbGZOh+cDOHaoK7TUnw9kvai3mkgT6xkyKfj4ewC/3r0TpMvHlYpI3eRr0vkVkTLLGZedB7jOuYve31cHFDrlNSEDSw+Xwkcj1ukS8w=" + on_success: change + on_failure: always \ No newline at end of file From 4e1aef905c7471429e0091ced9e857054917c577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Weber?= Date: Wed, 19 Apr 2017 16:54:46 -0400 Subject: [PATCH 7/8] Add default value for file path when download a package, and update Doc --- README.md | 10 ++++-- package.json | 3 +- src/index.js | 3 ++ tests/index_test.js | 78 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 100f903..69fcdee 100644 --- a/README.md +++ b/README.md @@ -94,8 +94,9 @@ The ```getDevicePackages``` response is always as follow : reference: "abc.edf", version: "0.0.1", url: "https://app.barracks.io/path/to/package/version/", - size: 42, md5: "deadbeefbadc0ffee", + size: 42, + filename: 'aFile.sh', download: function (filePath) {} // Function to download package } ], @@ -105,8 +106,9 @@ The ```getDevicePackages``` response is always as follow : reference: "abc.edf", version: "0.0.1", url: "https://app.barracks.io/path/to/package/version/", - size: 42, md5: "deadbeefbadc0ffee", + size: 42, + filename: 'aFile.sh', download: function (filePath) {} // Function to download package } ], @@ -130,6 +132,9 @@ The ```getDevicePackages``` response is always as follow : Once you have the response from getDevicePackages, you'll be able to download file for all packages that are available for the device (packages that are in the ```available```, and ```changed``` lists of the response). +The ```filePath``` argument of the download function is optionnal. The default value will be as follow: +```_``` + ```js var packages = [ { @@ -180,6 +185,7 @@ All errors returned by the SDK follow the same object format: Error type can be one of the the following: +* `MISSING_MANDATORY_ARGUMENT`, is returned by both `Barracks.getDevicePackages()` and `Package.download()`. It indicate that one or more of the mandatory arguments are missing. * `REQUEST_FAILED`, is returned by `Barracks.getDevicePackages()` method if the getDevicePackage request fails. The error object also contains one additional property `requestError` that is the `Error` object returned by the [request](https://www.npmjs.com/package/request) library. * `UNEXPECTED_SERVER_RESPONSE`, is returned by `Barracks.getDevicePackages()` method if the HTTP response code is not `200`. * `DOWNLOAD_FAILED`, is returned by `Package.download()` method if the download of a package fails. diff --git a/package.json b/package.json index a718087..54bad49 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,8 @@ "dependencies": { "es6-promise": "4.0.5", "md5-file": "3.1.1", - "request": "2.74.0" + "request": "2.74.0", + "uuid": "^3.0.1" }, "engines": { "node": ">=0.10 <7.0" diff --git a/src/index.js b/src/index.js index d4dc4de..ea586b8 100644 --- a/src/index.js +++ b/src/index.js @@ -13,6 +13,7 @@ var responseBuilder = require('./responseBuilder'); var fs = require('fs'); var request = require('request'); var fileHelper = require('./fileHelper'); +var uuid = require('uuid/v1'); function Barracks(options) { this.options = { @@ -78,6 +79,8 @@ Barracks.prototype.downloadPackage = function (packageInfo, filePath) { }); } + filePath = filePath || uuid() + '_' + packageInfo.filename; + var downloadParams = { url: packageInfo.url, method: 'GET', diff --git a/tests/index_test.js b/tests/index_test.js index 62cb8b2..8e7a049 100644 --- a/tests/index_test.js +++ b/tests/index_test.js @@ -397,6 +397,7 @@ describe('downloadPackage(packageInfo, filePath) ', function () { var checkMd5Mock = function () {}; var deleteFileMock = function () {}; var requestMock = function () {}; + var uuidMock = function() {}; beforeEach(function () { var Barracks = proxyquire('../src/index.js', { @@ -415,6 +416,9 @@ describe('downloadPackage(packageInfo, filePath) ', function () { }, 'request': function (params) { return requestMock(params); + }, + 'uuid/v1': function () { + return uuidMock(); } }); @@ -648,4 +652,78 @@ describe('downloadPackage(packageInfo, filePath) ', function () { done(err); }); }); + + it('Should generate random path for the file to download when no filePath given', function (done) { + // Given + var response = { statusCode: 200 }; + var packageInfo = { + package: 'abc.edf', + version: '0.0.1', + url: 'https://not.barracks.io/path/to/file', + filename: 'myFile.sh', + size: 42, + md5: 'deadbeefbadc0ffee' + }; + + var fileStream = new Stream(); + var createWriteStreamSpy = sinon.spy(); + createWriteStreamMock = function (path) { + createWriteStreamSpy(path); + return fileStream; + }; + + var requestStream = new Stream(); + var requestSpy = sinon.spy(); + requestMock = function (params) { + requestSpy(params); + return requestStream; + }; + + var checkMd5Spy = sinon.spy(); + checkMd5Mock = function (path, checksum) { + checkMd5Spy(path, checksum); + return Promise.resolve(); + }; + + var uuidSpy = sinon.spy(); + var randomUuid = 'qaserdxcftygvghujhnbnjkmklknbhgfcxdesazw'; + uuidMock = function () { + uuidSpy(); + return randomUuid; + }; + + var expectedFilePath = randomUuid + '_' + packageInfo.filename; + + setTimeout(function () { + requestStream.emit('response', response); + }, 75); + setTimeout(function () { + fileStream.emit('close'); + }, 95); + + // When / Then + barracks.downloadPackage(packageInfo).then(function (result) { + expect(result).to.be.equals(expectedFilePath); + expect(uuidSpy).to.have.been.calledOnce; + expect(uuidSpy).to.have.been.calledWithExactly(); + expect(createWriteStreamSpy).to.have.been.calledOnce; + expect(createWriteStreamSpy).to.have.been.calledWithExactly(expectedFilePath); + expect(requestSpy).to.have.been.calledOnce; + expect(requestSpy).to.have.been.calledWithExactly({ + url: packageInfo.url, + method: 'GET', + headers: { + Authorization: API_KEY + } + }); + expect(checkMd5Spy).to.have.been.calledOnce; + expect(checkMd5Spy).to.have.been.calledWithExactly( + expectedFilePath, + packageInfo.md5 + ); + done(); + }).catch(function (err) { + done(err); + }); + }); }); From 3d5ae375df551369fa394c24888d19edc3d18c8b Mon Sep 17 00:00:00 2001 From: Simon Guerout Date: Fri, 21 Apr 2017 15:15:34 -0400 Subject: [PATCH 8/8] Updated SDK to match definitive APIs. --- src/index.js | 36 ++--- tests/index_test.js | 319 +++++++++++++++++++++++--------------------- 2 files changed, 184 insertions(+), 171 deletions(-) diff --git a/src/index.js b/src/index.js index ea586b8..d251480 100644 --- a/src/index.js +++ b/src/index.js @@ -1,12 +1,12 @@ 'use strict'; -var ERROR_REQUEST_FAILED = 'REQUEST_FAILED'; -var ERROR_DOWNLOAD_FAILED = 'DOWNLOAD_FAILED'; -var ERROR_UNEXPECTED_SERVER_RESPONSE = 'UNEXPECTED_SERVER_RESPONSE'; -var ERROR_MISSING_MANDATORY_ARGUMENT = 'MISSING_MANDATORY_ARGUMENT'; +var ERROR_REQUEST_FAILED = 'REQUEST_FAILED'; +var ERROR_DOWNLOAD_FAILED = 'DOWNLOAD_FAILED'; +var ERROR_UNEXPECTED_SERVER_RESPONSE = 'UNEXPECTED_SERVER_RESPONSE'; +var ERROR_MISSING_MANDATORY_ARGUMENT = 'MISSING_MANDATORY_ARGUMENT'; -var DEFAULT_BARRACKS_BASE_URL = 'https://app.barracks.io'; -var GET_DEVICE_PACKAGES_ENDPOINT = '/api/device/resolve'; +var DEFAULT_BARRACKS_BASE_URL = 'https://app.barracks.io'; +var GET_DEVICE_PACKAGES_ENDPOINT = '/api/device/resolve'; require('es6-promise').polyfill(); var responseBuilder = require('./responseBuilder'); @@ -26,9 +26,9 @@ function Barracks(options) { } } -Barracks.prototype.getDevicePackages = function (unitId, packages, customClientData) { +Barracks.prototype.getDevicePackages = function(unitId, packages, customClientData) { var that = this; - return new Promise(function (resolve, reject) { + return new Promise(function(resolve, reject) { if (!unitId || !packages) { reject({ type: ERROR_MISSING_MANDATORY_ARGUMENT, @@ -46,11 +46,11 @@ Barracks.prototype.getDevicePackages = function (unitId, packages, customClientD body: JSON.stringify({ unitId: unitId, customClientData: customClientData, - components: packages + packages: packages }) }; - request(requestOptions, function (error, response, body) { + request(requestOptions, function(error, response, body) { if (error) { reject({ type: ERROR_REQUEST_FAILED, @@ -69,9 +69,9 @@ Barracks.prototype.getDevicePackages = function (unitId, packages, customClientD }); }; -Barracks.prototype.downloadPackage = function (packageInfo, filePath) { +Barracks.prototype.downloadPackage = function(packageInfo, filePath) { var that = this; - return new Promise(function (resolve, reject) { + return new Promise(function(resolve, reject) { if (!packageInfo) { reject({ type: ERROR_MISSING_MANDATORY_ARGUMENT, @@ -90,25 +90,25 @@ Barracks.prototype.downloadPackage = function (packageInfo, filePath) { }; var fileStream = fs.createWriteStream(filePath); - request(downloadParams).on('response', function (response) { + request(downloadParams).on('response', function(response) { if (response.statusCode != 200) { fileStream.emit('error', { type: ERROR_DOWNLOAD_FAILED, message: 'Server replied with HTTP ' + response.statusCode }); } - }).pipe(fileStream).on('close', function () { - fileHelper.checkMd5(filePath, packageInfo.md5).then(function () { + }).pipe(fileStream).on('close', function() { + fileHelper.checkMd5(filePath, packageInfo.md5).then(function() { resolve(filePath); - }).catch(function (err) { + }).catch(function(err) { fileHelper.deleteFile(filePath, reject); reject(err); }); - }).on('error', function (err) { + }).on('error', function(err) { fileHelper.deleteFile(filePath, reject); reject(err); }); }); }; -module.exports = Barracks; \ No newline at end of file +module.exports = Barracks; diff --git a/tests/index_test.js b/tests/index_test.js index 8e7a049..8b135c6 100644 --- a/tests/index_test.js +++ b/tests/index_test.js @@ -5,7 +5,7 @@ var sinon = require('sinon'); var sinonChai = require('sinon-chai'); var chai = require('chai'); var expect = chai.expect; -var proxyquire = require('proxyquire'); +var proxyquire = require('proxyquire'); var Stream = require('stream'); chai.use(sinonChai); @@ -17,20 +17,20 @@ var CUSTOM_CLIENT_DATA = { anotherKey: true }; -var component1 = { - reference: 'component.1.ref', +var package1 = { + reference: 'package.1.ref', version: '1.2.3' }; -var component2 = { - reference: 'component.2.ref', +var package2 = { + reference: 'package.2.ref', version: '4.5.6' }; -describe('Constructor : ', function () { +describe('Constructor : ', function() { var Barracks; - beforeEach(function () { + beforeEach(function() { Barracks = require('../src/index.js'); }); @@ -44,7 +44,7 @@ describe('Constructor : ', function () { }); } - it('Should return the Barracks object with default values when minimums options given', function () { + it('Should return the Barracks object with default values when minimums options given', function() { // Given var options = { apiKey: API_KEY @@ -57,7 +57,7 @@ describe('Constructor : ', function () { validateBarracksObject(barracks, 'https://app.barracks.io'); }); - it('Should return the Barracks object with baseUrl overriden when url option given', function () { + it('Should return the Barracks object with baseUrl overriden when url option given', function() { // Given var url = 'not.barracks.io'; var options = { @@ -72,7 +72,7 @@ describe('Constructor : ', function () { validateBarracksObject(barracks, url); }); - it('Should return the Barracks object that do not accept self signed cert when option given with invalid value', function () { + it('Should return the Barracks object that do not accept self signed cert when option given with invalid value', function() { // Given var options = { apiKey: API_KEY, @@ -87,7 +87,7 @@ describe('Constructor : ', function () { expect(process.env.NODE_TLS_REJECT_UNAUTHORIZED).to.be.equals(undefined); }); - it('Should return the Barracks object thta accept self signed cert when option given', function () { + it('Should return the Barracks object thta accept self signed cert when option given', function() { // Given var options = { apiKey: API_KEY, @@ -103,16 +103,16 @@ describe('Constructor : ', function () { }); }); -describe('getDevicePackages(unitId, components, customClientData) ', function () { +describe('getDevicePackages(unitId, packages, customClientData) ', function() { var barracks; - var getDevicePackagesComponentsUrl = '/api/device/resolve'; - var requestMock = function () {}; - var buildResponseMock = function () {}; + var getDevicePackagesUrl = '/api/device/resolve'; + var requestMock = function() {}; + var buildResponseMock = function() {}; - function getRequestPayloadForComponents(components, customClientData) { + function getRequestPayloadForPackages(packages, customClientData) { return { - url: 'https://app.barracks.io' + getDevicePackagesComponentsUrl, + url: 'https://app.barracks.io' + getDevicePackagesUrl, method: 'POST', headers: { 'Authorization': API_KEY, @@ -121,21 +121,21 @@ describe('getDevicePackages(unitId, components, customClientData) ', function () body: JSON.stringify({ unitId: UNIT_ID, customClientData: customClientData, - components: components + packages: packages }) }; } - beforeEach(function () { - requestMock = function () {}; - buildResponseMock = function () {}; + beforeEach(function() { + requestMock = function() {}; + buildResponseMock = function() {}; var Barracks = proxyquire('../src/index.js', { - 'request': function (options, callback) { + 'request': function(options, callback) { return requestMock(options, callback); }, './responseBuilder': { - buildResponse: function (body, downloadFunction) { + buildResponse: function(body, downloadFunction) { return buildResponseMock(body, downloadFunction); } } @@ -147,14 +147,14 @@ describe('getDevicePackages(unitId, components, customClientData) ', function () }); }); - it('Should reject MISSING_MANDATORY_ARGUMENT error when no unitId given', function (done) { + it('Should reject MISSING_MANDATORY_ARGUMENT error when no unitId given', function(done) { // Given - var components = [ component1, component2 ]; + var packages = [package1, package2]; // When / Then - barracks.getDevicePackages(undefined, components).then(function () { + barracks.getDevicePackages(undefined, packages).then(function() { done('should have failed'); - }).catch(function (err) { + }).catch(function(err) { expect(err).to.deep.equals({ type: 'MISSING_MANDATORY_ARGUMENT', message: 'missing or empty unitId or packages arguments' @@ -163,14 +163,14 @@ describe('getDevicePackages(unitId, components, customClientData) ', function () }); }); - it('Should reject MISSING_MANDATORY_ARGUMENT error when empty unitId given', function (done) { + it('Should reject MISSING_MANDATORY_ARGUMENT error when empty unitId given', function(done) { // Given - var components = [ component1, component2 ]; + var packages = [package1, package2]; // When / Then - barracks.getDevicePackages('', components).then(function () { + barracks.getDevicePackages('', packages).then(function() { done('should have failed'); - }).catch(function (err) { + }).catch(function(err) { expect(err).to.deep.equals({ type: 'MISSING_MANDATORY_ARGUMENT', message: 'missing or empty unitId or packages arguments' @@ -179,11 +179,11 @@ describe('getDevicePackages(unitId, components, customClientData) ', function () }); }); - it('Should reject MISSING_MANDATORY_ARGUMENT error when no packages given', function (done) { + it('Should reject MISSING_MANDATORY_ARGUMENT error when no packages given', function(done) { // When / Then - barracks.getDevicePackages(UNIT_ID).then(function () { + barracks.getDevicePackages(UNIT_ID).then(function() { done('should have failed'); - }).catch(function (err) { + }).catch(function(err) { expect(err).to.deep.equals({ type: 'MISSING_MANDATORY_ARGUMENT', message: 'missing or empty unitId or packages arguments' @@ -192,11 +192,11 @@ describe('getDevicePackages(unitId, components, customClientData) ', function () }); }); - it('Should reject MISSING_MANDATORY_ARGUMENT error when empty packages given', function (done) { + it('Should reject MISSING_MANDATORY_ARGUMENT error when empty packages given', function(done) { // When / Then - barracks.getDevicePackages(UNIT_ID, '').then(function () { + barracks.getDevicePackages(UNIT_ID, '').then(function() { done('should have failed'); - }).catch(function (err) { + }).catch(function(err) { expect(err).to.deep.equals({ type: 'MISSING_MANDATORY_ARGUMENT', message: 'missing or empty unitId or packages arguments' @@ -205,20 +205,22 @@ describe('getDevicePackages(unitId, components, customClientData) ', function () }); }); - it('Should return request failed error when request failed', function (done) { + it('Should return request failed error when request failed', function(done) { // Given - var error = { message: 'Error occured' }; - var components = [ component1, component2 ]; + var error = { + message: 'Error occured' + }; + var packages = [package1, package2]; var requestSpy = sinon.spy(); - requestMock = function (options, callback) { + requestMock = function(options, callback) { requestSpy(options, callback); callback(error); }; // When / Then - barracks.getDevicePackages(UNIT_ID, components).then(function () { + barracks.getDevicePackages(UNIT_ID, packages).then(function() { done('should have failed'); - }).catch(function (err) { + }).catch(function(err) { expect(err).to.deep.equals({ type: 'REQUEST_FAILED', requestError: error, @@ -226,198 +228,201 @@ describe('getDevicePackages(unitId, components, customClientData) ', function () }); expect(requestSpy).to.have.been.calledOnce; expect(requestSpy).to.have.been.calledWithExactly( - getRequestPayloadForComponents(components), + getRequestPayloadForPackages(packages), sinon.match.func ); done(); }); }); - it('Should return unexpected server response error when server do not return 200 OK', function (done) { + it('Should return unexpected server response error when server do not return 200 OK', function(done) { // Given - var response = { body: 'Internal error', statusCode: 500 }; - var components = [ component1, component2 ]; + var response = { + body: 'Internal error', + statusCode: 500 + }; + var packages = [package1, package2]; var requestSpy = sinon.spy(); - requestMock = function (options, callback) { + requestMock = function(options, callback) { requestSpy(options, callback); callback(undefined, response, response.body); }; // When / Then - barracks.getDevicePackages(UNIT_ID, components).then(function () { + barracks.getDevicePackages(UNIT_ID, packages).then(function() { done('should have failed'); - }).catch(function (err) { + }).catch(function(err) { expect(err).to.deep.equals({ type: 'UNEXPECTED_SERVER_RESPONSE', message: response.body }); expect(requestSpy).to.have.been.calledOnce; expect(requestSpy).to.have.been.calledWithExactly( - getRequestPayloadForComponents(components), + getRequestPayloadForPackages(packages), sinon.match.func ); done(); }); }); - it('Should return server response when server return 200 OK', function (done) { + it('Should return server response when server return 200 OK', function(done) { // Given - var componentInfo = { - available:[], - changed:[], - unchanged:[], - unavailable:[] + var packageInfo = { + available: [], + changed: [], + unchanged: [], + unavailable: [] }; var response = { - body: JSON.stringify(componentInfo), + body: JSON.stringify(packageInfo), statusCode: 200 }; - var components = [ component1, component2 ]; + var packages = [package1, package2]; var requestSpy = sinon.spy(); - requestMock = function (options, callback) { + requestMock = function(options, callback) { requestSpy(options, callback); callback(undefined, response, response.body); }; var buildResponseSpy = sinon.spy(); - buildResponseMock = function (body, downloadFunction) { + buildResponseMock = function(body, downloadFunction) { buildResponseSpy(body, downloadFunction); - return componentInfo; + return packageInfo; }; // When / Then - barracks.getDevicePackages(UNIT_ID, components).then(function (result) { - expect(result).to.deep.equals(componentInfo); + barracks.getDevicePackages(UNIT_ID, packages).then(function(result) { + expect(result).to.deep.equals(packageInfo); expect(requestSpy).to.have.been.calledOnce; expect(requestSpy).to.have.been.calledWithExactly( - getRequestPayloadForComponents(components), + getRequestPayloadForPackages(packages), sinon.match.func ); expect(buildResponseSpy).to.have.been.calledOnce; expect(buildResponseSpy).to.have.been.calledWithExactly( - componentInfo, + packageInfo, sinon.match.func ); done(); - }).catch(function (err) { + }).catch(function(err) { done(err); }); }); - it('Should send customClientData and return server response when server return 200 OK', function (done) { + it('Should send customClientData and return server response when server return 200 OK', function(done) { // Given - var componentInfo = { - available:[], - changed:[], - unchanged:[], - unavailable:[] + var packageInfo = { + available: [], + changed: [], + unchanged: [], + unavailable: [] }; var response = { - body: JSON.stringify(componentInfo), + body: JSON.stringify(packageInfo), statusCode: 200 }; - var components = [ component1, component2 ]; + var packages = [package1, package2]; var requestSpy = sinon.spy(); - requestMock = function (options, callback) { + requestMock = function(options, callback) { requestSpy(options, callback); callback(undefined, response, response.body); }; var buildResponseSpy = sinon.spy(); - buildResponseMock = function (body, downloadFunction) { + buildResponseMock = function(body, downloadFunction) { buildResponseSpy(body, downloadFunction); - return componentInfo; + return packageInfo; }; // When / Then - barracks.getDevicePackages(UNIT_ID, components, CUSTOM_CLIENT_DATA).then(function (result) { - expect(result).to.deep.equals(componentInfo); + barracks.getDevicePackages(UNIT_ID, packages, CUSTOM_CLIENT_DATA).then(function(result) { + expect(result).to.deep.equals(packageInfo); expect(requestSpy).to.have.been.calledOnce; expect(requestSpy).to.have.been.calledWithExactly( - getRequestPayloadForComponents(components, CUSTOM_CLIENT_DATA), + getRequestPayloadForPackages(packages, CUSTOM_CLIENT_DATA), sinon.match.func ); expect(buildResponseSpy).to.have.been.calledOnce; expect(buildResponseSpy).to.have.been.calledWithExactly( - componentInfo, + packageInfo, sinon.match.func ); done(); - }).catch(function (err) { + }).catch(function(err) { done(err); }); }); - it('Should return server response when server return 200 OK', function (done) { + it('Should return server response when server return 200 OK', function(done) { // Given - var componentInfo = { - available:[], - changed:[], - unchanged:[], - unavailable:[] + var packageInfo = { + available: [], + changed: [], + unchanged: [], + unavailable: [] }; var response = { - body: JSON.stringify(componentInfo), + body: JSON.stringify(packageInfo), statusCode: 200 }; - var components = [ component1, component2 ]; + var packages = [package1, package2]; var requestSpy = sinon.spy(); - requestMock = function (options, callback) { + requestMock = function(options, callback) { requestSpy(options, callback); callback(undefined, response, response.body); }; var buildResponseSpy = sinon.spy(); - buildResponseMock = function (body, downloadFunction) { + buildResponseMock = function(body, downloadFunction) { buildResponseSpy(body, downloadFunction); - return componentInfo; + return packageInfo; }; // When / Then - barracks.getDevicePackages(UNIT_ID, components).then(function (result) { - expect(result).to.deep.equals(componentInfo); + barracks.getDevicePackages(UNIT_ID, packages).then(function(result) { + expect(result).to.deep.equals(packageInfo); expect(requestSpy).to.have.been.calledOnce; expect(requestSpy).to.have.been.calledWithExactly( - getRequestPayloadForComponents(components), + getRequestPayloadForPackages(packages), sinon.match.func ); expect(buildResponseSpy).to.have.been.calledOnce; expect(buildResponseSpy).to.have.been.calledWithExactly( - componentInfo, + packageInfo, sinon.match.func ); done(); - }).catch(function (err) { + }).catch(function(err) { done(err); }); }); }); -describe('downloadPackage(packageInfo, filePath) ', function () { +describe('downloadPackage(packageInfo, filePath) ', function() { var barracks; - var createWriteStreamMock = function () {}; - var checkMd5Mock = function () {}; - var deleteFileMock = function () {}; - var requestMock = function () {}; + var createWriteStreamMock = function() {}; + var checkMd5Mock = function() {}; + var deleteFileMock = function() {}; + var requestMock = function() {}; var uuidMock = function() {}; - beforeEach(function () { + beforeEach(function() { var Barracks = proxyquire('../src/index.js', { 'fs': { - createWriteStream: function (path) { + createWriteStream: function(path) { return createWriteStreamMock(path); } }, './fileHelper': { - checkMd5: function (file, checksum) { + checkMd5: function(file, checksum) { return checkMd5Mock(file, checksum); }, - deleteFile: function (file, reject) { + deleteFile: function(file, reject) { return deleteFileMock(file, reject); } }, - 'request': function (params) { + 'request': function(params) { return requestMock(params); }, - 'uuid/v1': function () { + 'uuid/v1': function() { return uuidMock(); } }); @@ -428,11 +433,11 @@ describe('downloadPackage(packageInfo, filePath) ', function () { }); }); - it('Should reject MISSING_MANDATORY_ARGUMENT error when no packageInfo given', function (done) { + it('Should reject MISSING_MANDATORY_ARGUMENT error when no packageInfo given', function(done) { // When / Then - barracks.downloadPackage().then(function () { + barracks.downloadPackage().then(function() { done('Should have failed'); - }).catch(function (err) { + }).catch(function(err) { expect(err).to.deep.equals({ type: 'MISSING_MANDATORY_ARGUMENT', message: 'missing or empty packageInfo argument' @@ -441,11 +446,11 @@ describe('downloadPackage(packageInfo, filePath) ', function () { }); }); - it('Should reject MISSING_MANDATORY_ARGUMENT error when empty packageInfo given', function (done) { + it('Should reject MISSING_MANDATORY_ARGUMENT error when empty packageInfo given', function(done) { // When / Then - barracks.downloadPackage('').then(function () { + barracks.downloadPackage('').then(function() { done('Should have failed'); - }).catch(function (err) { + }).catch(function(err) { expect(err).to.deep.equals({ type: 'MISSING_MANDATORY_ARGUMENT', message: 'missing or empty packageInfo argument' @@ -454,9 +459,11 @@ describe('downloadPackage(packageInfo, filePath) ', function () { }); }); - it('Should return ERROR_DOWNLOAD_FAILED when server return http code other than 200 OK', function (done) { + it('Should return ERROR_DOWNLOAD_FAILED when server return http code other than 200 OK', function(done) { // Given - var response = { statusCode: 500 }; + var response = { + statusCode: 500 + }; var packageInfo = { package: 'abc.edf', version: '0.0.1', @@ -468,31 +475,31 @@ describe('downloadPackage(packageInfo, filePath) ', function () { var fileStream = new Stream(); var createWriteStreamSpy = sinon.spy(); - createWriteStreamMock = function (path) { + createWriteStreamMock = function(path) { createWriteStreamSpy(path); return fileStream; }; var requestStream = new Stream(); var requestSpy = sinon.spy(); - requestMock = function (params) { + requestMock = function(params) { requestSpy(params); return requestStream; }; var deleteFileSpy = sinon.spy(); - deleteFileMock = function (file, reject) { + deleteFileMock = function(file, reject) { deleteFileSpy(file, reject); }; - setTimeout(function () { + setTimeout(function() { requestStream.emit('response', response); }, 75); // When / Then - barracks.downloadPackage(packageInfo, filePath).then(function () { + barracks.downloadPackage(packageInfo, filePath).then(function() { done('Should have failed'); - }).catch(function (err) { + }).catch(function(err) { expect(err).to.deep.equals({ type: 'DOWNLOAD_FAILED', message: 'Server replied with HTTP ' + response.statusCode @@ -516,9 +523,11 @@ describe('downloadPackage(packageInfo, filePath) ', function () { }); }); - it('Should return an error when md5 check fail', function (done) { + it('Should return an error when md5 check fail', function(done) { // Given - var response = { statusCode: 200 }; + var response = { + statusCode: 200 + }; var md5Error = 'MD5 do not match !!'; var packageInfo = { package: 'abc.edf', @@ -531,40 +540,40 @@ describe('downloadPackage(packageInfo, filePath) ', function () { var fileStream = new Stream(); var createWriteStreamSpy = sinon.spy(); - createWriteStreamMock = function (path) { + createWriteStreamMock = function(path) { createWriteStreamSpy(path); return fileStream; }; var requestStream = new Stream(); var requestSpy = sinon.spy(); - requestMock = function (params) { + requestMock = function(params) { requestSpy(params); return requestStream; }; var checkMd5Spy = sinon.spy(); - checkMd5Mock = function (path, checksum) { + checkMd5Mock = function(path, checksum) { checkMd5Spy(path, checksum); return Promise.reject(md5Error); }; var deleteFileSpy = sinon.spy(); - deleteFileMock = function (file, reject) { + deleteFileMock = function(file, reject) { deleteFileSpy(file, reject); }; - setTimeout(function () { + setTimeout(function() { requestStream.emit('response', response); }, 75); - setTimeout(function () { + setTimeout(function() { fileStream.emit('close'); }, 95); // When / Then - barracks.downloadPackage(packageInfo, filePath).then(function () { + barracks.downloadPackage(packageInfo, filePath).then(function() { done('Should have failed'); - }).catch(function (err) { + }).catch(function(err) { expect(err).to.be.equals(md5Error); expect(createWriteStreamSpy).to.have.been.calledOnce; expect(createWriteStreamSpy).to.have.been.calledWithExactly(filePath); @@ -590,9 +599,11 @@ describe('downloadPackage(packageInfo, filePath) ', function () { }); }); - it('Should return the path to downloaded file when request successful', function (done) { + it('Should return the path to downloaded file when request successful', function(done) { // Given - var response = { statusCode: 200 }; + var response = { + statusCode: 200 + }; var packageInfo = { package: 'abc.edf', version: '0.0.1', @@ -604,33 +615,33 @@ describe('downloadPackage(packageInfo, filePath) ', function () { var fileStream = new Stream(); var createWriteStreamSpy = sinon.spy(); - createWriteStreamMock = function (path) { + createWriteStreamMock = function(path) { createWriteStreamSpy(path); return fileStream; }; var requestStream = new Stream(); var requestSpy = sinon.spy(); - requestMock = function (params) { + requestMock = function(params) { requestSpy(params); return requestStream; }; var checkMd5Spy = sinon.spy(); - checkMd5Mock = function (path, checksum) { + checkMd5Mock = function(path, checksum) { checkMd5Spy(path, checksum); return Promise.resolve(); }; - setTimeout(function () { + setTimeout(function() { requestStream.emit('response', response); }, 75); - setTimeout(function () { + setTimeout(function() { fileStream.emit('close'); }, 95); // When / Then - barracks.downloadPackage(packageInfo, filePath).then(function (result) { + barracks.downloadPackage(packageInfo, filePath).then(function(result) { expect(result).to.be.equals(filePath); expect(createWriteStreamSpy).to.have.been.calledOnce; expect(createWriteStreamSpy).to.have.been.calledWithExactly(filePath); @@ -648,14 +659,16 @@ describe('downloadPackage(packageInfo, filePath) ', function () { packageInfo.md5 ); done(); - }).catch(function (err) { + }).catch(function(err) { done(err); }); }); - it('Should generate random path for the file to download when no filePath given', function (done) { + it('Should generate random path for the file to download when no filePath given', function(done) { // Given - var response = { statusCode: 200 }; + var response = { + statusCode: 200 + }; var packageInfo = { package: 'abc.edf', version: '0.0.1', @@ -667,42 +680,42 @@ describe('downloadPackage(packageInfo, filePath) ', function () { var fileStream = new Stream(); var createWriteStreamSpy = sinon.spy(); - createWriteStreamMock = function (path) { + createWriteStreamMock = function(path) { createWriteStreamSpy(path); return fileStream; }; var requestStream = new Stream(); var requestSpy = sinon.spy(); - requestMock = function (params) { + requestMock = function(params) { requestSpy(params); return requestStream; }; var checkMd5Spy = sinon.spy(); - checkMd5Mock = function (path, checksum) { + checkMd5Mock = function(path, checksum) { checkMd5Spy(path, checksum); return Promise.resolve(); }; var uuidSpy = sinon.spy(); var randomUuid = 'qaserdxcftygvghujhnbnjkmklknbhgfcxdesazw'; - uuidMock = function () { + uuidMock = function() { uuidSpy(); return randomUuid; }; var expectedFilePath = randomUuid + '_' + packageInfo.filename; - setTimeout(function () { + setTimeout(function() { requestStream.emit('response', response); }, 75); - setTimeout(function () { + setTimeout(function() { fileStream.emit('close'); }, 95); // When / Then - barracks.downloadPackage(packageInfo).then(function (result) { + barracks.downloadPackage(packageInfo).then(function(result) { expect(result).to.be.equals(expectedFilePath); expect(uuidSpy).to.have.been.calledOnce; expect(uuidSpy).to.have.been.calledWithExactly(); @@ -722,7 +735,7 @@ describe('downloadPackage(packageInfo, filePath) ', function () { packageInfo.md5 ); done(); - }).catch(function (err) { + }).catch(function(err) { done(err); }); });