diff --git a/lib/gui/components/update-notifier/services/update-notifier-s3.js b/lib/gui/components/update-notifier/services/update-notifier-s3.js deleted file mode 100644 index dc62dbfa..00000000 --- a/lib/gui/components/update-notifier/services/update-notifier-s3.js +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2016 Resin.io - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -'use strict'; - -const _ = require('lodash'); -const semver = require('semver'); -const xml = require('xml2js'); - -module.exports = function($q, $http, UPDATE_NOTIFIER_URL) { - - /** - * @summary Get the latest published Etcher version - * @function - * @public - * - * @description - * This function performs its job by querying the publicily accessible - * S3 bucket where we store the builds and uses the `node-semver` module - * to determine which is the latest one. - * - * @fulfil {String} - latest version - * @returns {Promise} - * - * @example - * UpdateNotifierS3Service.getLatestVersion().then((latestVersion) => { - * console.log('The latest version is: ' + latestVersion); - * }); - */ - this.getLatestVersion = () => { - return $http.get(UPDATE_NOTIFIER_URL).then((response) => { - return $q((resolve, reject) => { - xml.parseString(response.data, (error, result) => { - if (error) { - return reject(error); - } - - const bucketEntries = result.ListBucketResult.Contents; - return resolve(_.reduce(bucketEntries, (latest, entry) => { - const version = _.chain(entry.Key) - .first() - .split('/') - .nth(1) - .value(); - - return semver.gt(version, latest) ? version : latest; - - // This is a good accumulator default value since - // every version is semantically greater than this. - }, '0.0.0')); - - }); - }); - }); - }; - -}; diff --git a/lib/gui/components/update-notifier/services/update-notifier.js b/lib/gui/components/update-notifier/services/update-notifier.js index 1ed87a42..a71f2af7 100644 --- a/lib/gui/components/update-notifier/services/update-notifier.js +++ b/lib/gui/components/update-notifier/services/update-notifier.js @@ -17,8 +17,40 @@ 'use strict'; const semver = require('semver'); +const etcherLatestVersion = require('etcher-latest-version'); -module.exports = function($uibModal, UPDATE_NOTIFIER_SLEEP_TIME, ManifestBindService, UpdateNotifierS3Service, SettingsModel) { +module.exports = function($uibModal, $http, $q, UPDATE_NOTIFIER_SLEEP_TIME, ManifestBindService, SettingsModel) { + + /** + * @summary Get the latest available Etcher version + * @function + * @private + * + * @fulfil {String} - latest version + * @returns {Promise} + * + * @example + * UpdateNotifierService.getLatestVersion().then((latestVersion) => { + * console.log(`The latest version is: ${latestVersion}`); + * }); + */ + this.getLatestVersion = () => { + return $q((resolve, reject) => { + return etcherLatestVersion((url, callback) => { + return $http.get(url).then((response) => { + return callback(null, response.data); + }).catch((error) => { + return callback(error); + }); + }, (error, latestVersion) => { + if (error) { + return reject(error); + } + + return resolve(latestVersion); + }); + }); + }; /** * @summary Check if the current version is the latest version @@ -36,7 +68,7 @@ module.exports = function($uibModal, UPDATE_NOTIFIER_SLEEP_TIME, ManifestBindSer * }); */ this.isLatestVersion = () => { - return UpdateNotifierS3Service.getLatestVersion().then((version) => { + return this.getLatestVersion().then((version) => { return semver.gte(ManifestBindService.get('version'), version); }); }; diff --git a/lib/gui/components/update-notifier/update-notifier.js b/lib/gui/components/update-notifier/update-notifier.js index 94ec5fa1..4a7c5f2c 100644 --- a/lib/gui/components/update-notifier/update-notifier.js +++ b/lib/gui/components/update-notifier/update-notifier.js @@ -29,10 +29,8 @@ const UpdateNotifier = angular.module(MODULE_NAME, [ require('../../os/open-external/open-external') ]); -UpdateNotifier.constant('UPDATE_NOTIFIER_URL', 'https://resin-production-downloads.s3.amazonaws.com'); UpdateNotifier.constant('UPDATE_NOTIFIER_SLEEP_TIME', 7 * 24 * 60 * 60 * 100); UpdateNotifier.controller('UpdateNotifierController', require('./controllers/update-notifier')); UpdateNotifier.service('UpdateNotifierService', require('./services/update-notifier')); -UpdateNotifier.service('UpdateNotifierS3Service', require('./services/update-notifier-s3')); module.exports = MODULE_NAME; diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 60003166..7d064cd7 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1551,6 +1551,18 @@ "from": "etcher-image-write@>=5.0.2 <6.0.0", "resolved": "https://registry.npmjs.org/etcher-image-write/-/etcher-image-write-5.0.2.tgz" }, + "etcher-latest-version": { + "version": "1.0.0", + "from": "etcher-latest-version@latest", + "resolved": "https://registry.npmjs.org/etcher-latest-version/-/etcher-latest-version-1.0.0.tgz", + "dependencies": { + "semver": { + "version": "5.2.0", + "from": "semver@>=5.2.0 <6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.2.0.tgz" + } + } + }, "event-emitter": { "version": "0.3.4", "from": "event-emitter@>=0.3.4 <0.4.0", diff --git a/package.json b/package.json index 9af58d91..5a165ed0 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "electron-is-running-in-asar": "^1.0.0", "etcher-image-stream": "^2.2.0", "etcher-image-write": "^5.0.2", + "etcher-latest-version": "^1.0.0", "file-tail": "^0.3.0", "flexboxgrid": "^6.3.0", "immutable": "^3.8.1", @@ -87,7 +88,6 @@ "trackjs": "^2.1.16", "umount": "^1.1.3", "username": "^2.1.0", - "xml2js": "^0.4.16", "yargs": "^4.6.0" }, "devDependencies": { diff --git a/tests/gui/components/update-notifier.spec.js b/tests/gui/components/update-notifier.spec.js index 4eadde40..692d9e17 100644 --- a/tests/gui/components/update-notifier.spec.js +++ b/tests/gui/components/update-notifier.spec.js @@ -101,16 +101,6 @@ describe('Browser: UpdateNotifier', function() { let UpdateNotifierService; let ManifestBindService; - beforeEach(function() { - angular.mock.module(function($provide) { - $provide.value('UpdateNotifierS3Service', { - getLatestVersion: function() { - return $q.resolve(ManifestBindService.get('version')); - } - }); - }); - }); - beforeEach(angular.mock.inject(function(_$q_, _$rootScope_, _UpdateNotifierService_, _ManifestBindService_) { $q = _$q_; $rootScope = _$rootScope_; @@ -118,6 +108,15 @@ describe('Browser: UpdateNotifier', function() { ManifestBindService = _ManifestBindService_; })); + beforeEach(function() { + this.getLatestVersionStub = m.sinon.stub(UpdateNotifierService, 'getLatestVersion'); + this.getLatestVersionStub.returns($q.resolve(ManifestBindService.get('version'))); + }); + + afterEach(function() { + this.getLatestVersionStub.restore(); + }); + it('should resolve true', function() { let result = null; @@ -137,22 +136,21 @@ describe('Browser: UpdateNotifier', function() { let $rootScope; let UpdateNotifierService; - beforeEach(function() { - angular.mock.module(function($provide) { - $provide.value('UpdateNotifierS3Service', { - getLatestVersion: function() { - return $q.resolve('99999.9.9'); - } - }); - }); - }); - beforeEach(angular.mock.inject(function(_$q_, _$rootScope_, _UpdateNotifierService_) { $q = _$q_; $rootScope = _$rootScope_; UpdateNotifierService = _UpdateNotifierService_; })); + beforeEach(function() { + this.getLatestVersionStub = m.sinon.stub(UpdateNotifierService, 'getLatestVersion'); + this.getLatestVersionStub.returns($q.resolve('99999.9.9')); + }); + + afterEach(function() { + this.getLatestVersionStub.restore(); + }); + it('should resolve false', function() { let result = null; @@ -172,22 +170,21 @@ describe('Browser: UpdateNotifier', function() { let $rootScope; let UpdateNotifierService; - beforeEach(function() { - angular.mock.module(function($provide) { - $provide.value('UpdateNotifierS3Service', { - getLatestVersion: function() { - return $q.resolve('0.0.0'); - } - }); - }); - }); - beforeEach(angular.mock.inject(function(_$q_, _$rootScope_, _UpdateNotifierService_) { $q = _$q_; $rootScope = _$rootScope_; UpdateNotifierService = _UpdateNotifierService_; })); + beforeEach(function() { + this.getLatestVersionStub = m.sinon.stub(UpdateNotifierService, 'getLatestVersion'); + this.getLatestVersionStub.returns($q.resolve('0.0.0')); + }); + + afterEach(function() { + this.getLatestVersionStub.restore(); + }); + it('should resolve true', function() { let result = null; @@ -205,120 +202,4 @@ describe('Browser: UpdateNotifier', function() { }); - describe('UpdateNotifierS3Service', function() { - - let UpdateNotifierS3Service; - let $rootScope; - - beforeEach(angular.mock.inject(function(_$rootScope_, _UpdateNotifierS3Service_) { - $rootScope = _$rootScope_; - UpdateNotifierS3Service = _UpdateNotifierS3Service_; - })); - - describe('given a mocked S3 XML response', function() { - - let $httpBackend; - let UPDATE_NOTIFIER_URL; - - beforeEach(angular.mock.inject(function($injector) { - $httpBackend = $injector.get('$httpBackend'); - UPDATE_NOTIFIER_URL = $injector.get('UPDATE_NOTIFIER_URL'); - - $httpBackend.whenGET(UPDATE_NOTIFIER_URL).respond(` - - resin-production-downloads - - - 1000 - false - - etcher/1.0.0-beta.0/Etcher-darwin-x64.dmg - 2016-03-10T17:34:21.000Z - "5a715255aa25686688bf1e23bc1d3fc6" - 46109720 - STANDARD - - - etcher/1.0.0-beta.1/Etcher-darwin-x64.dmg - 2016-04-08T20:12:03.000Z - "cc1d6d9d53385e3edd099416fcd894c1" - 47071474 - STANDARD - - - etcher/1.0.0-beta.2/Etcher-darwin-x64.dmg - 2016-04-08T19:03:18.000Z - "5f1849f7781197ce2ee6129c16bcd498" - 48650090 - STANDARD - - - etcher/1.0.0-beta.3/Etcher-darwin-x64.dmg - 2016-04-18T01:32:09.000Z - "c173895886f44d115c66e7206ce3dff8" - 50585335 - STANDARD - - - etcher/1.0.0-beta.3/Etcher-darwin-x64.zip - 2016-04-18T01:42:37.000Z - "e9f6e957e65373b232530215d98df141" - 129327442 - STANDARD - - - etcher/1.0.0-beta.4/Etcher-darwin-x64.dmg - 2016-04-22T17:29:49.000Z - "bccb0024c58747a9b7516cbdfc5a7ecb" - 55240852 - STANDARD - - - etcher/1.0.0-beta.4/Etcher-darwin-x64.zip - 2016-04-22T17:43:27.000Z - "c93e26e68b3c4f2b7e8e88e6befc8e64" - 135443284 - STANDARD - - - etcher/1.0.0-beta.5/Etcher-darwin-x64.dmg - 2016-05-04T08:27:11.000Z - "fb596bfdb8bbaf09807b5fc4a940ce14" - 77757305 - STANDARD - - - etcher/1.0.0-beta.5/Etcher-darwin-x64.zip - 2016-05-04T08:39:56.000Z - "3f11c1b6f06644f9ceb2aea4b1947fdf" - 157933876 - STANDARD - - - `); - })); - - afterEach(function() { - $httpBackend.verifyNoOutstandingExpectation(); - $httpBackend.verifyNoOutstandingRequest(); - }); - - it('should resolve the latest version', function() { - $httpBackend.expectGET(UPDATE_NOTIFIER_URL); - - let latestVersion = null; - UpdateNotifierS3Service.getLatestVersion().then(function(result) { - latestVersion = result; - }); - - $rootScope.$apply(); - $httpBackend.flush(); - - m.chai.expect(latestVersion).to.equal('1.0.0-beta.5'); - }); - - }); - - }); - });