/* global it:false */ /* global describe:false */ /* global before:false */ /* global after:false */ 'use strict'; const apps = require('../apps.js'), BoxError = require('../boxerror.js'), common = require('./common.js'), constants = require('../constants.js'), expect = require('expect.js'), nock = require('nock'), paths = require('../paths.js'), safe = require('safetydance'), semver = require('semver'), updater = require('../updater.js'); const UPDATE_VERSION = semver.inc(constants.VERSION, 'major'); describe('updater', function () { const { setup, cleanup, app, appstoreToken, mockApiServerOrigin } = common; describe('settings', function () { before(setup); after(cleanup); it('can get default autoupdate_pattern', async function () { const pattern = await updater.getAutoupdatePattern(); expect(pattern).to.be('00 00 1,3,5,23 * * *'); }); it('cannot set invalid autoupdate_pattern', async function () { const [error] = await safe(updater.setAutoupdatePattern('02 * 1 *')); expect(error.reason).to.be(BoxError.BAD_FIELD); }); it('can set default autoupdate_pattern', async function () { await updater.setAutoupdatePattern('02 * 1-5 * * *'); }); }); describe('checker', function () { before(setup); before(() => { if (!nock.isActive()) nock.activate(); }); after(cleanup); describe('box updates', function () { before(async function () { safe.fs.unlinkSync(paths.BOX_UPDATE_FILE); await updater.setAutoupdatePattern(constants.CRON_PATTERN_NEVER); }); it('no updates', async function () { nock.cleanAll(); const scope = nock(mockApiServerOrigin) .get('/api/v1/boxupdate') .query({ boxVersion: constants.VERSION, accessToken: appstoreToken, stableOnly: false }) .reply(204, { } ); await updater.checkBoxUpdate({ stableOnly: false }); const boxUpdateInfo = await updater.getBoxUpdate(); expect(boxUpdateInfo).to.be(null); expect(scope.isDone()).to.be.ok(); }); it('new version', async function () { nock.cleanAll(); const scope = nock(mockApiServerOrigin) .get('/api/v1/boxupdate') .query({ boxVersion: constants.VERSION, accessToken: appstoreToken, stableOnly: false }) .reply(200, { version: UPDATE_VERSION, changelog: [''], sourceTarballUrl: 'box.tar.gz', sourceTarballSigUrl: 'box.tar.gz.sig', boxVersionsUrl: 'box.versions', boxVersionsSigUrl: 'box.versions.sig', unstable: false } ); await updater.checkBoxUpdate({ stableOnly: false }); const boxUpdateInfo = await updater.getBoxUpdate(); expect(boxUpdateInfo).to.be.ok(); expect(boxUpdateInfo.version).to.be(UPDATE_VERSION); expect(boxUpdateInfo.sourceTarballUrl).to.be('box.tar.gz'); expect(scope.isDone()).to.be.ok(); }); it('bad response offers whatever was last valid', async function () { nock.cleanAll(); const scope = nock(mockApiServerOrigin) .get('/api/v1/boxupdate') .query({ boxVersion: constants.VERSION, accessToken: appstoreToken, stableOnly: false }) .reply(404, { version: '2.0.0-pre.0', changelog: [''], sourceTarballUrl: 'box-pre.tar.gz' } ); await safe(updater.checkBoxUpdate({ stableOnly: false })); // ignore error const boxUpdateInfo = await updater.getBoxUpdate(); expect(boxUpdateInfo.version).to.be(UPDATE_VERSION); expect(boxUpdateInfo.sourceTarballUrl).to.be('box.tar.gz'); expect(scope.isDone()).to.be.ok(); }); }); describe('app updates', function () { before(async function () { await updater.setAutoupdatePattern(constants.CRON_PATTERN_NEVER); }); it('no updates', async function () { nock.cleanAll(); const scope = nock(mockApiServerOrigin) .get('/api/v1/appupdate') .query({ boxVersion: constants.VERSION, accessToken: appstoreToken, appId: app.appStoreId, appVersion: app.manifest.version, stableOnly: false }) .reply(204, { } ); const appUpdateInfo = await updater.checkAppUpdate(app, { stableOnly: false }); expect(appUpdateInfo).to.eql(null); expect(scope.isDone()).to.be.ok(); const tmp = await apps.get(app.id); expect(tmp.updateInfo).to.be(null); }); it('bad response', async function () { nock.cleanAll(); const scope = nock(mockApiServerOrigin) .get('/api/v1/appupdate') .query({ boxVersion: constants.VERSION, accessToken: appstoreToken, appId: app.appStoreId, appVersion: app.manifest.version, stableOnly: false }) .reply(500, { update: { manifest: { version: '1.0.0', changelog: '* some changes' } } } ); const [error] = await safe(updater.checkAppUpdate(app, { stableOnly: false })); expect(error).to.be.ok(); expect(scope.isDone()).to.be.ok(); }); it('offers new version', async function () { nock.cleanAll(); const scope = nock(mockApiServerOrigin) .get('/api/v1/appupdate') .query({ boxVersion: constants.VERSION, accessToken: appstoreToken, appId: app.appStoreId, appVersion: app.manifest.version, stableOnly: false }) .reply(200, { manifest: { version: '2.0.0', changelog: '* some changes' } } ); const expectedUpdateInfo = { manifest: { version: '2.0.0', changelog: '* some changes' }, unstable: false, isAutoUpdatable: false, manualUpdateReason: 'Invalid or Expired subscription' }; const appUpdateInfo = await updater.checkAppUpdate(app, { stableOnly: false }); expect(appUpdateInfo.manifest).to.eql(expectedUpdateInfo.manifest); expect(scope.isDone()).to.be.ok(); const tmp = await apps.get(app.id); expect(tmp.updateInfo).to.eql(expectedUpdateInfo); }); it('does not offer old version', async function () { nock.cleanAll(); const expectedUpdateInfo = { manifest: { version: '2.0.0', changelog: '* some changes' }, unstable: false, isAutoUpdatable: false, manualUpdateReason: 'Invalid or Expired subscription' }; const [error] = await safe(updater.checkAppUpdate(app, { stableOnly: false })); expect(error).to.be.ok(); const tmp = await apps.get(app.id); expect(tmp.updateInfo).to.eql(expectedUpdateInfo); }); }); }); });