From b896d022a2c679d987f6046cbc46ed7305c0d746 Mon Sep 17 00:00:00 2001 From: Austin Burdine Date: Sun, 18 Mar 2018 08:00:46 -0400 Subject: [PATCH] feat(process): allow process.isEnabled to return a promise refs #672 - support isEnabled returning a promise --- lib/commands/start.js | 15 ++-- lib/commands/stop.js | 18 ++-- test/unit/commands/start-spec.js | 39 +++++++-- test/unit/commands/stop-spec.js | 136 +++++++++++++++++++++++++------ 4 files changed, 163 insertions(+), 45 deletions(-) diff --git a/lib/commands/start.js b/lib/commands/start.js index b2a9e220e..540d6a1d6 100644 --- a/lib/commands/start.js +++ b/lib/commands/start.js @@ -45,16 +45,17 @@ class StartCommand extends Command { }; return this.ui.run(start, 'Starting Ghost', runOptions).then(() => { - // If process manager doesn't support enable behavior OR it's already enabled, don't try to enable - if (!ProcessManager.supportsEnableBehavior(processInstance) || processInstance.isEnabled()) { - argv.enable = false; - } - - if (!argv.enable) { + if (!argv.enable || !ProcessManager.supportsEnableBehavior(processInstance)) { return Promise.resolve(); } - return this.ui.run(processInstance.enable(), 'Enabling Ghost instance startup on server boot', runOptions); + return Promise.resolve(processInstance.isEnabled()).then((isEnabled) => { + if (isEnabled) { + return Promise.resolve(); + } + + return this.ui.run(() => processInstance.enable(), 'Enabling Ghost instance startup on server boot', runOptions); + }); }).then(() => { if (!argv.quiet) { this.ui.log(`You can access your blog at ${instance.config.get('url')}`, 'cyan'); diff --git a/lib/commands/stop.js b/lib/commands/stop.js index 10ef0f77f..4b7b5bd4e 100644 --- a/lib/commands/stop.js +++ b/lib/commands/stop.js @@ -53,17 +53,21 @@ class StopCommand extends Command { return this.ui.run(stop, 'Stopping Ghost', runOptions); }).then(() => { - if ( - argv.disable && - ProcessManager.supportsEnableBehavior(instance.process) && - instance.process.isEnabled() - ) { + if (!argv.disable || !ProcessManager.supportsEnableBehavior(instance.process)) { + return Promise.resolve(); + } + + return Promise.resolve(instance.process.isEnabled()).then((isEnabled) => { + if (!isEnabled) { + return Promise.resolve(); + } + return this.ui.run( - instance.process.disable(), + () => instance.process.disable(), 'Disabling Ghost instance startup on server boot', runOptions ); - } + }); }); } diff --git a/test/unit/commands/start-spec.js b/test/unit/commands/start-spec.js index 123723864..69b70f30e 100644 --- a/test/unit/commands/start-spec.js +++ b/test/unit/commands/start-spec.js @@ -94,16 +94,19 @@ describe('Unit: Commands > Start', function () { describe('enables instance if needed', function () { it('normal conditions', function () { const ui = { - run: sinon.stub().resolves(), + run: sinon.stub(), listr: () => Promise.resolve() }; + ui.run.onFirstCall().resolves(); + ui.run.onSecondCall().callsFake((fn) => Promise.resolve(fn())); myInstance.process = { - isEnabled: sinon.stub().returns(false), - enable: sinon.stub(), + isEnabled: sinon.stub().resolves(false), + enable: sinon.stub().resolves(), disable: 'yes' }; const start = new StartCommand(ui, mySystem); const runCommandStub = sinon.stub(start, 'runCommand').resolves(); + return start.run({quiet: true, enable: true}).then(() => { const ie = myInstance.process.isEnabled; const enable = myInstance.process.enable; @@ -120,8 +123,8 @@ describe('Unit: Commands > Start', function () { listr: () => Promise.resolve() }; myInstance.process = { - isEnabled: sinon.stub().returns(true), - enable: sinon.stub(), + isEnabled: sinon.stub().resolves(true), + enable: sinon.stub().resolves(), disable: 'yes' }; const start = new StartCommand(ui, mySystem); @@ -142,16 +145,38 @@ describe('Unit: Commands > Start', function () { listr: () => Promise.resolve() }; myInstance.process = { - isEnabled: sinon.stub().returns(true), - enable: sinon.stub() + isEnabled: sinon.stub().resolves(true), + enable: sinon.stub().resolves() }; const start = new StartCommand(ui, mySystem); const runCommandStub = sinon.stub(start, 'runCommand').resolves(); return start.run({quiet: true, enable: true}).then(() => { const ie = myInstance.process.isEnabled; const enable = myInstance.process.enable; + expect(runCommandStub.calledOnce).to.be.true; expect(ie.called).to.be.false; + expect(enable.called).to.be.false; + expect(ui.run.calledOnce).to.be.true; + }); + }); + + it('not when enabled flag is false', function () { + const ui = { + run: sinon.stub().resolves(), + listr: () => Promise.resolve() + }; + myInstance.process = { + isEnabled: sinon.stub().resolves(true), + enable: sinon.stub().resolves(), + disable: sinon.stub().resolves() + }; + const start = new StartCommand(ui, mySystem); + const runCommandStub = sinon.stub(start, 'runCommand').resolves(); + return start.run({quiet: true, enable: false}).then(() => { + const ie = myInstance.process.isEnabled; + const enable = myInstance.process.enable; expect(runCommandStub.calledOnce).to.be.true; + expect(ie.called).to.be.false; expect(enable.called).to.be.false; expect(ui.run.calledOnce).to.be.true; }); diff --git a/test/unit/commands/stop-spec.js b/test/unit/commands/stop-spec.js index 7fcaea3de..261a453f7 100644 --- a/test/unit/commands/stop-spec.js +++ b/test/unit/commands/stop-spec.js @@ -100,33 +100,121 @@ describe('Unit: Commands > Stop', function () { return stop.run.call(context, {}); }); - it('disables extensions if it needs to', function () { - class ProcessManager {} - const sEBstub = sinon.stub().returns(true); - const disableStub = sinon.stub().resolves(); - const gIstub = sinon.stub().returns({ - running: () => Promise.resolve(true), - process: { - disable: disableStub, - stop: () => true, - isEnabled: () => true - }, - loadRunningEnvironment: () => true + describe('handles disabling', function () { + it('skips disabling if disable flag is not set', function () { + const instance = { + running: () => Promise.resolve(true), + process: { + enable: () => Promise.resolve(), + disable: sinon.stub().resolves(), + stop: sinon.stub().resolves(), + isEnabled: sinon.stub().resolves(true) + }, + loadRunningEnvironment: () => true + }; + const system = { + getInstance: () => instance + }; + const ui = { + run: sinon.stub().resolves() + }; + + const StopCommand = proxyquire(modulePath, { + '../utils/check-valid-install': () => true + }); + const stop = new StopCommand(ui, system); + + return stop.run({disable: false}).then(() => { + expect(instance.process.isEnabled.called).to.be.false; + expect(ui.run.calledOnce).to.be.true; + }); }); - const context = { - system: {getInstance: gIstub}, - ui: {run: () => Promise.resolve()} - }; - ProcessManager.supportsEnableBehavior = sEBstub; - const StopCommand = proxyquire(modulePath, { - '../utils/check-valid-install': () => true, - '../process-manager': ProcessManager + + it('skips disabling if process manager doesn\'t support enable behavior', function () { + const instance = { + running: () => Promise.resolve(true), + process: { + stop: sinon.stub().resolves(), + isEnabled: sinon.stub().resolves(false) + }, + loadRunningEnvironment: () => true + }; + const system = { + getInstance: () => instance + }; + const ui = { + run: sinon.stub().resolves() + }; + + const StopCommand = proxyquire(modulePath, { + '../utils/check-valid-install': () => true + }); + const stop = new StopCommand(ui, system); + + return stop.run({disable: true}).then(() => { + expect(ui.run.calledOnce).to.be.true; + expect(instance.process.isEnabled.called).to.be.false; + }); }); - const stop = new StopCommand(); - return stop.run.call(context, {disable: true}).then(() => { - expect(sEBstub.calledOnce).to.be.true; - expect(disableStub.calledOnce).to.be.true; + it('skips disabling if isEnabled returns false', function () { + const instance = { + running: () => Promise.resolve(true), + process: { + enable: () => Promise.resolve(), + disable: sinon.stub().resolves(), + stop: sinon.stub().resolves(), + isEnabled: sinon.stub().resolves(false) + }, + loadRunningEnvironment: () => true + }; + const system = { + getInstance: () => instance + }; + const ui = { + run: sinon.stub().resolves() + }; + + const StopCommand = proxyquire(modulePath, { + '../utils/check-valid-install': () => true + }); + const stop = new StopCommand(ui, system); + + return stop.run({disable: true}).then(() => { + expect(instance.process.isEnabled.calledOnce).to.be.true; + expect(instance.process.disable.called).to.be.false; + expect(ui.run.calledOnce).to.be.true; + }); + }); + + it('disables if necessary', function () { + const instance = { + running: () => Promise.resolve(true), + process: { + enable: () => Promise.resolve(), + disable: sinon.stub().resolves(), + stop: sinon.stub().resolves(), + isEnabled: sinon.stub().resolves(true) + }, + loadRunningEnvironment: () => true + }; + const system = { + getInstance: () => instance + }; + const ui = { + run: sinon.stub().callsFake(fn => Promise.resolve(fn())) + }; + + const StopCommand = proxyquire(modulePath, { + '../utils/check-valid-install': () => true + }); + const stop = new StopCommand(ui, system); + + return stop.run({disable: true}).then(() => { + expect(instance.process.isEnabled.calledOnce).to.be.true; + expect(instance.process.disable.calledOnce).to.be.true; + expect(ui.run.calledTwice).to.be.true; + }); }); }); });