diff --git a/.eslintrc.js b/.eslintrc.js index c9196f6..a36e2ad 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,7 +1,7 @@ module.exports = { root: true, parserOptions: { - ecmaVersion: 6, + ecmaVersion: 10, sourceType: 'module' }, extends: 'eslint:recommended', diff --git a/index.js b/index.js index e9369da..b285018 100644 --- a/index.js +++ b/index.js @@ -1,26 +1,22 @@ /* jshint node: true */ 'use strict'; -var RSVP = require('rsvp'); -var path = require('path'); -var fs = require('fs'); +let path = require('path'); +let fs = require('fs'); -var denodeify = require('rsvp').denodeify; -var readFile = denodeify(fs.readFile); - -var DeployPluginBase = require('ember-cli-deploy-plugin'); +let DeployPluginBase = require('ember-cli-deploy-plugin'); module.exports = { name: 'ember-cli-deploy-redis', - createDeployPlugin: function(options) { + createDeployPlugin(options) { var Redis = require('./lib/redis'); var DeployPlugin = DeployPluginBase.extend({ name: options.name, defaultConfig: { host: 'localhost', - port: function(context) { + port(context) { if (context.tunnel && context.tunnel.srcPort) { return context.tunnel.srcPort; } else { @@ -29,27 +25,27 @@ module.exports = { }, filePattern: 'index.html', maxRecentUploads: 10, - distDir: function(context) { + distDir(context) { return context.distDir; }, - keyPrefix: function(context){ - return context.project.name() + ':index'; + keyPrefix(context){ + return `${context.project.name()}:index`; }, activationSuffix: 'current', activeContentSuffix: 'current-content', - didDeployMessage: function(context){ + didDeployMessage(context){ var revisionKey = context.revisionData && context.revisionData.revisionKey; var activatedRevisionKey = context.revisionData && context.revisionData.activatedRevisionKey; if (revisionKey && !activatedRevisionKey) { - return "Deployed but did not activate revision " + revisionKey + ". " - + "To activate, run: " - + "ember deploy:activate " + context.deployTarget + " --revision=" + revisionKey + "\n"; + return `Deployed but did not activate revision ${revisionKey}. ` + + `To activate, run: ` + + `ember deploy:activate ${context.deployTarget} --revision=${revisionKey}` + "\n"; } }, - revisionKey: function(context) { + revisionKey(context) { return context.commandOptions.revision || (context.revisionData && context.revisionData.revisionKey); }, - redisDeployClient: function(context, pluginHelper) { + redisDeployClient(context, pluginHelper) { var redisLib = context._redisLib; var options = { url: pluginHelper.readConfig('url'), @@ -65,11 +61,11 @@ module.exports = { return new Redis(options, redisLib); }, - revisionData: function(context) { + revisionData(context) { return context.revisionData; } }, - configure: function(/* context */) { + configure(/* context */) { this.log('validating config', { verbose: true }); if (!this.pluginConfig.url) { @@ -78,7 +74,7 @@ module.exports = { var redisUrlRegexp = new RegExp('^redis://'); if (!this.pluginConfig.url.match(redisUrlRegexp)) { - throw new Error('Your Redis URL appears to be missing the "redis://" protocol. Update your URL to: redis://' + this.pluginConfig.url); + throw new Error(`Your Redis URL appears to be missing the "redis://" protocol. Update your URL to: redis://${this.pluginConfig.url}`); } } @@ -87,109 +83,110 @@ module.exports = { this.log('config ok', { verbose: true }); }, - upload: function(/* context */) { - var redisDeployClient = this.readConfig('redisDeployClient'); - var revisionKey = this.readConfig('revisionKey'); - var distDir = this.readConfig('distDir'); - var filePattern = this.readConfig('filePattern'); - var keyPrefix = this.readConfig('keyPrefix'); - var filePath = path.join(distDir, filePattern); - - this.log('Uploading `' + filePath + '`', { verbose: true }); - return this._readFileContents(filePath) - .then(redisDeployClient.upload.bind(redisDeployClient, keyPrefix, revisionKey, this.readConfig('revisionData'))) - .then(this._uploadSuccessMessage.bind(this)) - .then(function(key) { - return { redisKey: key }; - }) - .catch(this._errorMessage.bind(this)); + async upload(/* context */) { + let redisDeployClient = this.readConfig('redisDeployClient'); + let revisionKey = this.readConfig('revisionKey'); + let distDir = this.readConfig('distDir'); + let filePattern = this.readConfig('filePattern'); + let keyPrefix = this.readConfig('keyPrefix'); + let filePath = path.join(distDir, filePattern); + + this.log(`Uploading \`${filePath}\``, { verbose: true }); + try { + let fileContents = await this._readFileContents(filePath); + let key = await redisDeployClient.upload(keyPrefix, revisionKey, this.readConfig('revisionData'), fileContents); + this._logUploadSuccessMessage(key); + return { redisKey: key }; + } catch(e) { + this._logErrorMessage(e); + throw e; + } }, - willActivate: function(/* context */) { - var redisDeployClient = this.readConfig('redisDeployClient'); - var keyPrefix = this.readConfig('keyPrefix'); + async willActivate(/* context */) { + let redisDeployClient = this.readConfig('redisDeployClient'); + let keyPrefix = this.readConfig('keyPrefix'); - var revisionKey = redisDeployClient.activeRevision(keyPrefix); + let previousRevisionKey = await redisDeployClient.activeRevision(keyPrefix); + return { + revisionData: { + previousRevisionKey + } + }; + }, - return RSVP.resolve(revisionKey).then(function(previousRevisionKey) { + async activate(/* context */) { + let redisDeployClient = this.readConfig('redisDeployClient'); + let revisionKey = this.readConfig('revisionKey'); + let keyPrefix = this.readConfig('keyPrefix'); + let activationSuffix = this.readConfig('activationSuffix'); + let activeContentSuffix = this.readConfig('activeContentSuffix'); + + this.log(`Activating revision \`${revisionKey}\``, { verbose: true }); + try { + await redisDeployClient.activate(keyPrefix, revisionKey, activationSuffix, activeContentSuffix); + this.log(`✔ Activated revision \`${revisionKey}\``, {}); return { revisionData: { - previousRevisionKey: previousRevisionKey + activatedRevisionKey: revisionKey } }; - }); - }, - - activate: function(/* context */) { - var redisDeployClient = this.readConfig('redisDeployClient'); - var revisionKey = this.readConfig('revisionKey'); - var keyPrefix = this.readConfig('keyPrefix'); - var activationSuffix = this.readConfig('activationSuffix'); - var activeContentSuffix = this.readConfig('activeContentSuffix'); - - this.log('Activating revision `' + revisionKey + '`', { verbose: true }); - return RSVP.resolve(redisDeployClient.activate(keyPrefix, revisionKey, activationSuffix, activeContentSuffix)) - .then(this.log.bind(this, '✔ Activated revision `' + revisionKey + '`', {})) - .then(function(){ - return { - revisionData: { - activatedRevisionKey: revisionKey - } - }; - }) - .catch(this._errorMessage.bind(this)); + } catch(e) { + this._logErrorMessage(e); + throw e; + } }, - didDeploy: function(/* context */){ + didDeploy(/* context */){ var didDeployMessage = this.readConfig('didDeployMessage'); if (didDeployMessage) { this.log(didDeployMessage); } }, - fetchInitialRevisions: function(/* context */) { - var redisDeployClient = this.readConfig('redisDeployClient'); - var keyPrefix = this.readConfig('keyPrefix'); - - this.log('Listing initial revisions for key: `' + keyPrefix + '`', { verbose: true }); - return RSVP.resolve(redisDeployClient.fetchRevisions(keyPrefix)) - .then(function(revisions) { - return { - initialRevisions: revisions - }; - }) - .catch(this._errorMessage.bind(this)); + async fetchInitialRevisions(/* context */) { + let redisDeployClient = this.readConfig('redisDeployClient'); + let keyPrefix = this.readConfig('keyPrefix'); + + this.log(`Listing initial revisions for key: \`${keyPrefix}\``, { verbose: true }); + try { + let initialRevisions = await redisDeployClient.fetchRevisions(keyPrefix); + return { + initialRevisions + }; + } catch(e) { + this._logErrorMessage(e); + throw e; + } }, - fetchRevisions: function(/* context */) { - var redisDeployClient = this.readConfig('redisDeployClient'); - var keyPrefix = this.readConfig('keyPrefix'); - - this.log('Listing revisions for key: `' + keyPrefix + '`'); - return RSVP.resolve(redisDeployClient.fetchRevisions(keyPrefix)) - .then(function(revisions) { - return { - revisions: revisions - }; - }) - .catch(this._errorMessage.bind(this)); + async fetchRevisions(/* context */) { + let redisDeployClient = this.readConfig('redisDeployClient'); + let keyPrefix = this.readConfig('keyPrefix'); + + this.log(`Listing revisions for key: \`${keyPrefix}\``); + try { + let revisions = await redisDeployClient.fetchRevisions(keyPrefix); + return { + revisions + }; + } catch(e) { + this._logErrorMessage(e); + throw e; + } }, - _readFileContents: function(path) { - return readFile(path) - .then(function(buffer) { - return buffer.toString(); - }); + async _readFileContents(path) { + let buffer = await fs.promises.readFile(path); + return buffer.toString(); }, - _uploadSuccessMessage: function(key) { - this.log('Uploaded with key `' + key + '`', { verbose: true }); - return RSVP.resolve(key); + _logUploadSuccessMessage(key) { + this.log(`Uploaded with key \`${key}\``, { verbose: true }); }, - _errorMessage: function(error) { + _logErrorMessage(error) { this.log(error, { color: 'red' }); - return RSVP.reject(error); } }); diff --git a/lib/redis.js b/lib/redis.js index c1abe82..e3913d7 100644 --- a/lib/redis.js +++ b/lib/redis.js @@ -3,7 +3,7 @@ var RSVP = require('rsvp'); module.exports = CoreObject.extend({ - init: function(options, lib) { + init(options, lib) { this._super(); var redisOptions = {}; var RedisLib = lib; @@ -36,102 +36,86 @@ module.exports = CoreObject.extend({ this._activationSuffix = options.activationSuffix || 'current'; }, - upload: function(/*keyPrefix, revisionKey, value*/) { - var args = Array.prototype.slice.call(arguments); - - var keyPrefix = args.shift(); - var value = args.pop(); - var revisionKey = args[0] || 'default'; - var revisionData = args[1]; - var redisKey = keyPrefix + ':' + revisionKey; - var maxEntries = this._maxRecentUploads; - var _this = this; - - return RSVP.resolve() - .then(this._uploadIfKeyDoesNotExist.bind(this, redisKey, value)) - .then(function() { - if (revisionData) { - return _this._uploadRevisionData(keyPrefix, revisionKey, revisionData); - } else { - return RSVP.resolve(); - } - }) - .then(this._updateRecentUploadsList.bind(this, keyPrefix, revisionKey)) - .then(this._trimRecentUploadsList.bind(this, keyPrefix, maxEntries)) - .then(function() { - return redisKey; - }); + async upload(/*keyPrefix, revisionKey, value*/) { + let args = Array.prototype.slice.call(arguments); + + let keyPrefix = args.shift(); + let value = args.pop(); + let revisionKey = args[0] || 'default'; + let revisionData = args[1]; + let redisKey = `${keyPrefix}:${revisionKey}`; + let maxEntries = this._maxRecentUploads; + + await this._uploadIfKeyDoesNotExist(redisKey, value); + if (revisionData) { + await this._uploadRevisionData(keyPrefix, revisionKey, revisionData); + } + await this._updateRecentUploadsList(keyPrefix, revisionKey); + await this._trimRecentUploadsList(keyPrefix, maxEntries); + return redisKey; }, - activate: function(keyPrefix, revisionKey, activationSuffix, activeContentSuffix) { - return RSVP.resolve() - .then(this._listRevisions.bind(this, keyPrefix)) - .then(this._validateRevisionKey.bind(this, revisionKey)) - .then(this._activateRevision.bind(this, keyPrefix, revisionKey, activationSuffix, activeContentSuffix)); + async activate(keyPrefix, revisionKey, activationSuffix, activeContentSuffix) { + let revisions = await this._listRevisions(keyPrefix); + this._validateRevisionKey(revisionKey, revisions); + await this._activateRevision(keyPrefix, revisionKey, activationSuffix, activeContentSuffix); }, - fetchRevisions: function(keyPrefix) { - var _this = this; - return this._listRevisions(keyPrefix).then(function(revisions) { - return RSVP.hash({ - revisions: RSVP.resolve(revisions), - current: _this.activeRevision(keyPrefix), - revisionData: _this._revisionData(keyPrefix, revisions) - }); - }).then(function(results) { - return results.revisions.map(function(revision, i) { - var hash = { - revision: revision, - active: revision === results.current, - }; - if (results.revisionData) { - hash.revisionData = results.revisionData[i]; - } - return hash; - }); + async fetchRevisions(keyPrefix) { + let revisions = await this._listRevisions(keyPrefix); + let results = await RSVP.hash({ + current: this.activeRevision(keyPrefix), + revisionData: this._revisionData(keyPrefix, revisions) + }); + return revisions.map(function(revision, i) { + let hash = { + revision: revision, + active: revision === results.current, + }; + if (results.revisionData) { + hash.revisionData = results.revisionData[i]; + } + return hash; }); }, - activeRevision: function(keyPrefix) { + activeRevision(keyPrefix) { var currentKey = keyPrefix + ':' + this._activationSuffix; return this._client.get(currentKey); }, - _revisionData: function(keyPrefix, revisions) { + async _revisionData(keyPrefix, revisions) { if (revisions.length === 0) { - return RSVP.resolve(); + return; } - var dataKeys = revisions.map(function(revision) { - return keyPrefix + ':revision-data:' + revision; - }); + let dataKeys = revisions.map((rev) => `${keyPrefix}:revision-data:${rev}`); - return this._client.mget(dataKeys).then(function(data) { - if (!data) { - return RSVP.resolve(); - } - return data.map(function(d) { - return JSON.parse(d); - }); - }); + let data = this._client.mget(dataKeys); + if (!data) { + return; + } + return data.map((d) => JSON.parse(d)); }, - _listRevisions: function(keyPrefix) { - var client = this._client; - var listKey = keyPrefix + ':revisions'; + _listRevisions(keyPrefix) { + let client = this._client; + let listKey = `${keyPrefix}:revisions`; return client.zrevrange(listKey, 0, -1); }, - _validateRevisionKey: function(revisionKey, revisions) { - return revisions.indexOf(revisionKey) > -1 ? RSVP.resolve() : RSVP.reject('`' + revisionKey + '` is not a valid revision key'); + _validateRevisionKey(revisionKey, revisions) { + if (revisions.indexOf(revisionKey) === -1) { + throw new Error(`\`${revisionKey}\` is not a valid revision key`); + } + return; }, - _activateRevisionKey: function(keyPrefix, revisionKey, activationSuffix) { - var currentKey = keyPrefix + ':' + activationSuffix; - + _activateRevisionKey(keyPrefix, revisionKey, activationSuffix) { + let currentKey = `${keyPrefix}:${activationSuffix}`; return this._client.set(currentKey, revisionKey); }, - _activateRevision: function(keyPrefix, revisionKey, activationSuffix, activeContentSuffix) { + _activateRevision(keyPrefix, revisionKey, activationSuffix, activeContentSuffix) { if (activeContentSuffix) { return this._copyRevisionAndActivateRevisionKey(keyPrefix, revisionKey, activationSuffix, activeContentSuffix); } @@ -139,85 +123,65 @@ module.exports = CoreObject.extend({ return this._activateRevisionKey(keyPrefix, revisionKey, activationSuffix); }, - _copyRevisionAndActivateRevisionKey: function(keyPrefix, revisionKey, activationSuffix, activeContentSuffix) { - var client = this._client; - var _this = this; - var activeContentKey = keyPrefix + ':' + activeContentSuffix; - var revisionContentKey = keyPrefix + ':' + revisionKey; - - return new RSVP.Promise(function(resolve, reject) { - client.get(revisionContentKey).then( - function(value) { - client.set(activeContentKey, value).then(function() { - _this._activateRevisionKey(keyPrefix, revisionKey, activationSuffix).then(resolve, reject); - }); - }, - reject - ); - }); + async _copyRevisionAndActivateRevisionKey(keyPrefix, revisionKey, activationSuffix, activeContentSuffix) { + let client = this._client; + let activeContentKey = `${keyPrefix}:${activeContentSuffix}`; + let revisionContentKey = `${keyPrefix}:${revisionKey}`; + + let value = await client.get(revisionContentKey); + await client.set(activeContentKey, value); + await this._activateRevisionKey(keyPrefix, revisionKey, activationSuffix); }, - _uploadIfKeyDoesNotExist: function(redisKey, value) { - var client = this._client; - var allowOverwrite = !!this._allowOverwrite; - - return RSVP.resolve() - .then(function() { - return client.get(redisKey); - }) - .then(function(value) { - if (value && !allowOverwrite) { - return RSVP.reject('Value already exists for key: ' + redisKey); - } - }) - .then(function() { - return client.set(redisKey, value); - }); + async _uploadIfKeyDoesNotExist(redisKey, value) { + let client = this._client; + let allowOverwrite = !!this._allowOverwrite; + + let existingValue = await client.get(redisKey); + if (existingValue && !allowOverwrite) { + throw new Error(`Value already exists for key: ${redisKey}`); + } + return client.set(redisKey, value); }, - _uploadRevisionData: function(keyPrefix, revisionKey, revisionData) { - var client = this._client; - var redisKey = keyPrefix + ':revision-data:' + revisionKey; - return RSVP.resolve() - .then(function() { - return client.set(redisKey, JSON.stringify(revisionData)); - }); + async _uploadRevisionData(keyPrefix, revisionKey, revisionData) { + let client = this._client; + let redisKey = `${keyPrefix}:revision-data:${revisionKey}`; + await client.set(redisKey, JSON.stringify(revisionData)); }, - _updateRecentUploadsList: function(keyPrefix, revisionKey) { - var client = this._client; - var score = new Date().getTime(); - var listKey = keyPrefix + ':revisions'; - return client.zadd(listKey, score, revisionKey); + async _updateRecentUploadsList(keyPrefix, revisionKey) { + let client = this._client; + let score = new Date().getTime(); + let listKey = `${keyPrefix}:revisions`; + await client.zadd(listKey, score, revisionKey); }, - _trimRecentUploadsList: function(keyPrefix, maxEntries) { - var client = this._client; - var listKey = keyPrefix + ':revisions'; + async _trimRecentUploadsList(keyPrefix, maxEntries) { + let client = this._client; + let listKey = `${keyPrefix}:revisions`; - return RSVP.hash({ + let results = await RSVP.hash({ revisionsToBeRemoved: client.zrange(listKey, 0, -(maxEntries + 1)), current: this.activeRevision(keyPrefix) - }).then(function(results) { - var revisions = results.revisionsToBeRemoved; - var current = results.current; - if (!revisions) { - return; + }); + let revisions = results.revisionsToBeRemoved; + let current = results.current; + if (!revisions) { + return; + } + let promises = []; + revisions.forEach(function(revision) { + if (revision !== current) { + promises.push(client.del(`${keyPrefix}:${revision}`)); + promises.push(client.del(`${keyPrefix}:revision-data:${revision}`)); + promises.push(client.zrem(listKey, revision)); } - var promises = []; - revisions.forEach(function(revision) { - if (revision !== current) { - promises.push(client.del(keyPrefix + ":" + revision)); - promises.push(client.del(keyPrefix + ":revision-data:" + revision)); - promises.push(client.zrem(listKey, revision)); - } - }); - - return RSVP.all(promises); }); + await RSVP.all(promises); }, - _stripUsernameFromConfigUrl: function(configUrl) { + _stripUsernameFromConfigUrl(configUrl) { var regex = /redis:\/\/(\w+):(\w+)(.*)/; var matches = configUrl.match(regex); diff --git a/tests/unit/index-test.js b/tests/unit/index-test.js index fe58421..3ee864c 100644 --- a/tests/unit/index-test.js +++ b/tests/unit/index-test.js @@ -6,7 +6,7 @@ var IoRedis = require("ioredis"); var sandbox = require("sinon").createSandbox(); var stubProject = { - name: function() { + name() { return "my-project"; } }; @@ -19,8 +19,8 @@ describe("redis plugin", function() { mockUi = { verbose: true, messages: [], - write: function() {}, - writeLine: function(message) { + write() {}, + writeLine(message) { this.messages.push(message); } }; @@ -523,7 +523,7 @@ describe("redis plugin", function() { var plugin; var context; - it("uploads the index", function() { + it("uploads the index", async function() { plugin = subject.createDeployPlugin({ name: "redis" }); @@ -537,9 +537,9 @@ describe("redis plugin", function() { filePattern: "index.html", distDir: "tests", revisionKey: "123abc", - redisDeployClient: function(/* context */) { + redisDeployClient(/* context */) { return { - upload: function(keyPrefix, revisionKey) { + upload(keyPrefix, revisionKey) { return RSVP.resolve(keyPrefix + ":" + revisionKey); } }; @@ -550,14 +550,13 @@ describe("redis plugin", function() { plugin.beforeHook(context); plugin.configure(context); - return assert.isFulfilled(plugin.upload(context)).then(function(result) { - assert.deepEqual(result, { redisKey: "test-prefix:123abc" }); - }); + let result = await assert.isFulfilled(plugin.upload(context)); + assert.deepEqual(result, { redisKey: "test-prefix:123abc" }); }); }); describe("activate hook", function() { - it("activates revision", function() { + it("activates revision", async function() { var activateCalled = false; var plugin = subject.createDeployPlugin({ @@ -573,9 +572,9 @@ describe("redis plugin", function() { filePattern: "index.html", distDir: "tests", revisionKey: "123abc", - redisDeployClient: function(/* context */) { + redisDeployClient(/* context */) { return { - activate: function() { + activate() { activateCalled = true; } }; @@ -585,15 +584,12 @@ describe("redis plugin", function() { }; plugin.beforeHook(context); - return assert - .isFulfilled(plugin.activate(context)) - .then(function(result) { - assert.ok(activateCalled); - assert.equal(result.revisionData.activatedRevisionKey, "123abc"); - }); + let result = await assert.isFulfilled(plugin.activate(context)); + assert.ok(activateCalled); + assert.equal(result.revisionData.activatedRevisionKey, "123abc"); }); - it("rejects if an error is thrown when activating", function() { + it("rejects if an error is thrown when activating", async function() { var plugin = subject.createDeployPlugin({ name: "redis" }); @@ -607,9 +603,9 @@ describe("redis plugin", function() { filePattern: "index.html", distDir: "tests", revisionKey: "123abc", - redisDeployClient: function(/* context */) { + redisDeployClient(/* context */) { return { - activate: function() { + activate() { return RSVP.reject("some-error"); } }; @@ -619,9 +615,8 @@ describe("redis plugin", function() { }; plugin.beforeHook(context); - return assert.isRejected(plugin.activate(context)).then(function(error) { - assert.equal(error, "some-error"); - }); + let error = await assert.isRejected(plugin.activate(context)); + assert.equal(error, "some-error"); }); }); describe("didDeploy hook", function() { @@ -637,10 +632,10 @@ describe("redis plugin", function() { var context = { deployTarget: "qa", ui: { - write: function(message) { + write(message) { messageOutput = messageOutput + message; }, - writeLine: function(message) { + writeLine(message) { messageOutput = messageOutput + message + "\n"; } }, @@ -666,7 +661,7 @@ describe("redis plugin", function() { }); describe("fetchInitialRevisions hook", function() { - it("fills the initialRevisions variable on context", function() { + it("fills the initialRevisions variable on context", async function() { var plugin; var context; @@ -683,9 +678,9 @@ describe("redis plugin", function() { filePattern: "index.html", distDir: "tests", revisionKey: "123abc", - redisDeployClient: function(/* context */) { + redisDeployClient(/* context */) { return { - fetchRevisions: function(/* keyPrefix, revisionKey */) { + fetchRevisions(/* keyPrefix, revisionKey */) { return RSVP.resolve([ { revision: "a", @@ -701,23 +696,20 @@ describe("redis plugin", function() { plugin.beforeHook(context); plugin.configure(context); - return assert - .isFulfilled(plugin.fetchInitialRevisions(context)) - .then(function(result) { - assert.deepEqual(result, { - initialRevisions: [ - { - active: false, - revision: "a" - } - ] - }); - }); + let result = await assert.isFulfilled(plugin.fetchInitialRevisions(context)); + assert.deepEqual(result, { + initialRevisions: [ + { + active: false, + revision: "a" + } + ] + }); }); }); describe("fetchRevisions hook", function() { - it("fills the revisions variable on context", function() { + it("fills the revisions variable on context", async function() { var plugin; var context; @@ -734,9 +726,9 @@ describe("redis plugin", function() { filePattern: "index.html", distDir: "tests", revisionKey: "123abc", - redisDeployClient: function(/* context */) { + redisDeployClient(/* context */) { return { - fetchRevisions: function(/* keyPrefix, revisionKey */) { + fetchRevisions(/* keyPrefix, revisionKey */) { return RSVP.resolve([ { revision: "a", @@ -752,18 +744,15 @@ describe("redis plugin", function() { plugin.beforeHook(context); plugin.configure(context); - return assert - .isFulfilled(plugin.fetchRevisions(context)) - .then(function(result) { - assert.deepEqual(result, { - revisions: [ - { - active: false, - revision: "a" - } - ] - }); - }); + let result = await assert.isFulfilled(plugin.fetchRevisions(context)); + assert.deepEqual(result, { + revisions: [ + { + active: false, + revision: "a" + } + ] + }); }); }); }); diff --git a/tests/unit/lib/redis-test.js b/tests/unit/lib/redis-test.js index f2fe270..cc26cc6 100644 --- a/tests/unit/lib/redis-test.js +++ b/tests/unit/lib/redis-test.js @@ -18,337 +18,209 @@ describe('redis', function () { }); describe('#upload', function () { - it('rejects if the key already exists in redis', function () { + it('rejects if the key already exists in redis', async function () { var redis = new Redis({}, IoredisMock); - return redis.upload('key', 'value').then(() => { - var promise = redis.upload('key', 'value'); - assert.isRejected(promise, /^Value already exists for key: key:default$/); - }); + await redis.upload('key', 'value'); + let promise = redis.upload('key', 'value'); + assert.isRejected(promise, /^Value already exists for key: key:default$/); }); - it('uploads the contents if the key does not already exist', function () { + it('uploads the contents if the key does not already exist', async function () { var redis = new Redis({}, IoredisMock); - var promise = redis.upload('key', 'value', 'filecontents'); - return assert.isFulfilled(promise).then(() => { - return redis._client.get('key:value'); - }).then((value) => { - assert.equal(value, 'filecontents'); - }); + let promise = redis.upload('key', 'value', 'filecontents'); + await assert.isFulfilled(promise); + let value = await redis._client.get('key:value'); + assert.equal(value, 'filecontents'); }); - it('uploads the contents if the key already exists but allowOverwrite is true', function () { + it('uploads the contents if the key already exists but allowOverwrite is true', async function () { var redis = new Redis({ allowOverwrite: true }, IoredisMock); - return redis.upload('key', 'value', 'firstfilecontents').then(() => { - return redis.upload('key', 'value', 'secondfilecontents'); - }).then(() => { - return redis._client.get('key:value'); - }).then((value) => { - assert.equal(value, 'secondfilecontents'); - }); + await redis.upload('key', 'value', 'firstfilecontents'); + await redis.upload('key', 'value', 'secondfilecontents'); + let value = await redis._client.get('key:value'); + assert.equal(value, 'secondfilecontents'); }); - it('trims the list of recent uploads and removes the index key and the revisionData', function () { - var redis = new Redis({ + it('trims the list of recent uploads and removes the index key and the revisionData', async function () { + let redis = new Redis({ maxRecentUploads: 2 }, IoredisMock); - return RSVP.resolve() - .then(() => { - return redis.upload('key', 1, '1value'); - }) - .then(() => { - return redis.upload('key', 2, '2value'); - }) - .then(() => { - return redis.upload('key', 3, '3value'); - }) - .then(() => { - return redis._client.mget('key:1', 'key:revision-data:1') - }) - .then((values) => { - assert.equal(values.filter(Boolean).length, 0, 'Expected key:1 and key:revision-data:1 to be deleted.'); - return redis._client.zrange('key:revisions', 0, -1); - }) - .then((value) => { - assert.deepEqual(value, ['2', '3']); - }); + await redis.upload('key', 1, '1value'); + await redis.upload('key', 2, '2value'); + await redis.upload('key', 3, '3value'); + let values = await redis._client.mget('key:1', 'key:revision-data:1') + assert.equal(values.filter(Boolean).length, 0, 'Expected key:1 and key:revision-data:1 to be deleted.'); + let value = await redis._client.zrange('key:revisions', 0, -1); + assert.deepEqual(value, ['2', '3']); }); - it('trims the list of recent uploads but leaves the active one', function () { - var redis = new Redis({ + it('trims the list of recent uploads but leaves the active one', async function () { + let redis = new Redis({ maxRecentUploads: 2 }, IoredisMock); - return RSVP.resolve() - .then(() => { - return redis.upload('key', 1, '1value'); - }) - .then(() => { - return redis._client.set('key:current', '1'); - }) - .then(() => { - return redis.upload('key', 2, '2value'); - }) - .then(() => { - return redis.upload('key', 3, '3value'); - }) - .then(() => { - return redis.upload('key', 4, '4value'); - }) - .then(() => { - return redis._client.keys('*'); - }) - .then((values) => { - assert.deepEqual(values, [ - 'key:1', - 'key:revisions', - 'key:current', - 'key:3', // key 2 was trimmed - 'key:4' - ]); - }); + await redis.upload('key', 1, '1value'); + await redis._client.set('key:current', '1'); + await redis.upload('key', 2, '2value'); + await redis.upload('key', 3, '3value'); + await redis.upload('key', 4, '4value'); + let values = await redis._client.keys('*'); + assert.deepEqual(values, [ + 'key:1', + 'key:revisions', + 'key:current', + 'key:3', // key 2 was trimmed + 'key:4' + ]); }); describe('generating the redis key', function () { - it('will use just the default tag if the tag is not provided', function () { - var redis = new Redis({}, IoredisMock); - - return RSVP.resolve() - .then(() => { - return redis.upload('key', undefined, 'filecontents'); - }) - .then(() => { - return redis._client.get('key:default'); - }) - .then((value) => { - assert.equal(value, 'filecontents'); - }); + it('will use just the default tag if the tag is not provided', async function () { + let redis = new Redis({}, IoredisMock); + + await redis.upload('key', undefined, 'filecontents'); + let value = await redis._client.get('key:default'); + assert.equal(value, 'filecontents'); }); - it('will use the key and the tag if the tag is provided', function () { - var redis = new Redis({}, IoredisMock); - - return RSVP.resolve() - .then(() => { - return redis.upload('key', 'tag', 'filecontents'); - }) - .then(() => { - return redis._client.get('key:tag'); - }) - .then((value) => { - assert.equal(value, 'filecontents'); - }); + it('will use the key and the tag if the tag is provided', async function () { + let redis = new Redis({}, IoredisMock); + + await redis.upload('key', 'tag', 'filecontents'); + let value = await redis._client.get('key:tag'); + assert.equal(value, 'filecontents'); }); }); }); describe('#willActivate', function () { - it('sets the previous revision to the current revision', function () { - var redis = new Redis({}, IoredisMock); - - return RSVP.resolve() - .then(() => { - return redis.upload('key', '1', 'filecontents1'); - }) - .then(() => { - return redis.upload('key', '2', 'filecontents2'); - }) - .then(() => { - return redis.activate('key', '1', 'current'); - }) - .then(() => { - return redis.activeRevision('key'); - }) - .then((activeRevision) => { - assert.equal(activeRevision, '1'); - }); - }); - }), - - describe('#activate', function () { - it('rejects if the revisionKey doesn\'t exist in list of uploaded revisions', function () { - var redis = new Redis({}, IoredisMock); - - return RSVP.resolve() - .then(() => { - return redis.upload('key', '1', 'filecontents1'); - }) - .then(() => { - return redis.upload('key', '2', 'filecontents2'); - }) - .then(() => { - var promise = redis.activate('key', '3', 'current'); - return assert.isRejected(promise); - }) - }); + it('sets the previous revision to the current revision', async function () { + let redis = new Redis({}, IoredisMock); + + await redis.upload('key', '1', 'filecontents1'); + await redis.upload('key', '2', 'filecontents2'); + await redis.activate('key', '1', 'current'); + let activeRevision = await redis.activeRevision('key'); + assert.equal(activeRevision, '1'); + }); + }), - it('resolves and sets the current revision to the revision key provided', function () { - var redis = new Redis({}, IoredisMock); - - return RSVP.resolve() - .then(() => { - return redis.upload('key', '1', 'filecontents1'); - }) - .then(() => { - return redis.upload('key', '2', 'filecontents2'); - }) - .then(() => { - return redis.activate('key', '1', 'current'); - }) - .then(() => { - return redis.activeRevision('key'); - }) - .then((activeRevision) => { - assert.equal(activeRevision, '1'); - return redis._client.get('key:1'); - }).then((keyContents) => { - assert.equal(keyContents, 'filecontents1'); - }); - }); + describe('#activate', function () { + it('rejects if the revisionKey doesn\'t exist in list of uploaded revisions', async function () { + let redis = new Redis({}, IoredisMock); - it('copies revision to the activeContentSuffix', function () { - var redis = new Redis({}, IoredisMock); - - return RSVP.resolve() - .then(() => { - return redis.upload('key', '1', 'filecontents1'); - }) - .then(() => { - return redis.upload('key', '2', 'filecontents2'); - }) - .then(() => { - return redis.upload('key', '3', 'filecontents3'); - }) - .then(() => { - return redis.activate('key', '1', 'current-id', 'current-content'); - }) - .then(() => { - return redis._client.get('key:current-content'); - }) - .then((currentContent) => { - assert.equal(currentContent, 'filecontents1'); - return redis._client.get('key:current-id'); - }).then((currentId) => { - assert.equal(currentId, '1'); - }); - }); + await redis.upload('key', '1', 'filecontents1'); + await redis.upload('key', '2', 'filecontents2'); + let promise = redis.activate('key', '3', 'current'); + await assert.isRejected(promise); }); - describe('#fetchRevisions', function () { - it('lists the last existing revisions', function () { - var redis = new Redis({}, IoredisMock); + it('resolves and sets the current revision to the revision key provided', async function () { + let redis = new Redis({}, IoredisMock); - return RSVP.resolve() - .then(() => { - return redis.upload('key', '1', 'filecontents1'); - }) - .then(() => { - return redis.upload('key', '2', 'filecontents2'); - }) - .then(() => { - return redis.upload('key', '3', 'filecontents3'); - }) - .then(() => { - return redis.fetchRevisions('key'); - }) - .then((recentRevisions) => { - assert.deepEqual(recentRevisions, [{ - revision: '3', - active: false, - revisionData: null - }, - { - revision: '2', - active: false, - revisionData: null - }, - { - revision: '1', - active: false, - revisionData: null - } - ]); - }); + await redis.upload('key', '1', 'filecontents1'); + await redis.upload('key', '2', 'filecontents2'); + await redis.activate('key', '1', 'current'); + let activeRevision = await redis.activeRevision('key'); + assert.equal(activeRevision, '1'); + let keyContents = await redis._client.get('key:1'); + assert.equal(keyContents, 'filecontents1'); }); - it('lists revisions and marks the active one', function () { - var redis = new Redis({}, IoredisMock); + it('copies revision to the activeContentSuffix', async function () { + let redis = new Redis({}, IoredisMock); + + await redis.upload('key', '1', 'filecontents1'); + await redis.upload('key', '2', 'filecontents2'); + await redis.upload('key', '3', 'filecontents3'); + await redis.activate('key', '1', 'current-id', 'current-content'); + let currentContent = await redis._client.get('key:current-content'); + assert.equal(currentContent, 'filecontents1'); + let currentId = await redis._client.get('key:current-id'); + assert.equal(currentId, '1'); + }); + }); - return RSVP.resolve() - .then(() => { - return redis.upload('key', '1', 'filecontents1'); - }) - .then(() => { - return redis.activate('key', '1', 'current'); - }) - .then(() => { - return redis.upload('key', '2', 'filecontents2'); - }) - .then(() => { - return redis.upload('key', '3', 'filecontents3'); - }) - .then(() => { - return redis.fetchRevisions('key'); - }) - .then((recentRevisions) => { - assert.deepEqual(recentRevisions, [{ - revision: '3', - active: false, - revisionData: null - }, - { - revision: '2', - active: false, - revisionData: null - }, - { - revision: '1', - active: true, - revisionData: null - } - ]); - }); + describe('#fetchRevisions', function () { + it('lists the last existing revisions', async function () { + let redis = new Redis({}, IoredisMock); + + await redis.upload('key', '1', 'filecontents1'); + await redis.upload('key', '2', 'filecontents2'); + await redis.upload('key', '3', 'filecontents3'); + let recentRevisions = await redis.fetchRevisions('key'); + assert.deepEqual(recentRevisions, [{ + revision: '3', + active: false, + revisionData: null + }, + { + revision: '2', + active: false, + revisionData: null + }, + { + revision: '1', + active: false, + revisionData: null + } + ]); }); - it('retrieves revisionData', function () { - var redis = new Redis({}, IoredisMock); - var revisionData = '{"revisionKey":"a","timestamp":"2016-03-13T14:25:40.563Z","scm":{"sha":"9101968710f18a6720c48bf032fd82efd5743b7d","email":"mattia@mail.com","name":"Mattia Gheda","timestamp":"2015-12-22T12:44:48.000Z","branch":"master"}}'; - - return RSVP.resolve() - .then(() => { - return redis.upload('key', '1', revisionData, 'filecontents1'); - }) - .then(() => { - return redis.fetchRevisions('key'); - }) - .then((revisions) => { - assert.deepEqual(revisions, [{ - revision: '1', - active: false, - revisionData: revisionData - }]); - }); + it('lists revisions and marks the active one', async function () { + let redis = new Redis({}, IoredisMock); + + await redis.upload('key', '1', 'filecontents1'); + await redis.activate('key', '1', 'current'); + await redis.upload('key', '2', 'filecontents2'); + await redis.upload('key', '3', 'filecontents3'); + let recentRevisions = await redis.fetchRevisions('key'); + assert.deepEqual(recentRevisions, [{ + revision: '3', + active: false, + revisionData: null + }, + { + revision: '2', + active: false, + revisionData: null + }, + { + revision: '1', + active: true, + revisionData: null + } + ]); }); - it('uses activationSuffix in order to get the right activeRevision', function () { - var redis = new Redis({ + it('retrieves revisionData', async function () { + let redis = new Redis({}, IoredisMock); + let revisionData = '{"revisionKey":"a","timestamp":"2016-03-13T14:25:40.563Z","scm":{"sha":"9101968710f18a6720c48bf032fd82efd5743b7d","email":"mattia@mail.com","name":"Mattia Gheda","timestamp":"2015-12-22T12:44:48.000Z","branch":"master"}}'; + + await redis.upload('key', '1', revisionData, 'filecontents1'); + let revisions = await redis.fetchRevisions('key'); + assert.deepEqual(revisions, [{ + revision: '1', + active: false, + revisionData: revisionData + }]); + }); + + it('uses activationSuffix in order to get the right activeRevision', async function () { + let redis = new Redis({ activationSuffix: 'active-key' }, IoredisMock); - var redisGetStub = sandbox.stub(redis._client, 'get').returns(RSVP.Promise.resolve()); + let redisGetStub = sandbox.stub(redis._client, 'get').returns(RSVP.Promise.resolve()); - return RSVP.resolve() - .then(() => { - return redis.activeRevision('key-prefix'); - }) - .then(() => { - assert.isTrue(redisGetStub.calledWith('key-prefix:active-key')); - }); + await redis.activeRevision('key-prefix'); + assert.isTrue(redisGetStub.calledWith('key-prefix:active-key')); }); }); });