UNPKG

nanocyte-deployer

Version:
468 lines (390 loc) 16.7 kB
_ = require 'lodash' FlowDeployer = require '../src/flow-deployer' describe 'FlowDeployer', -> describe 'when constructed with a flow', -> beforeEach -> @request = get: sinon.stub() @configuration = erik_is_happy: true options = flowUuid: 'the-flow-uuid' flowToken: 'the-flow-token' forwardUrl: 'http://www.zombo.com' instanceId: 'an-instance-id' userUuid: 'some-user-uuid' userToken: 'some-user-token' octobluUrl: 'https://api.octoblu.com' deploymentUuid: 'the-deployment-uuid' flowLoggerUuid: 'flow-logger-uuid' @configurationGenerator = configure: sinon.stub() @configurationSaver = save: sinon.stub() stop: sinon.stub() @meshbluHttp = message: sinon.stub() updateDangerously: sinon.stub() createSubscription: sinon.stub() whoami: sinon.stub() MeshbluHttp = sinon.spy => @meshbluHttp @sut = new FlowDeployer options, configurationGenerator: @configurationGenerator configurationSaver: @configurationSaver MeshbluHttp: MeshbluHttp request: @request @request.get.withArgs('https://api.octoblu.com/api/flows/the-flow-uuid').yields null, {}, {a: 1, b: 5} @request.get.withArgs('https://api.octoblu.com/api/user').yields null, {}, {api: {}} describe 'when deploy is called', -> beforeEach (done)-> flowConfig = 'some': 'thing' 'subscribe-devices': config: 'broadcast.sent': ['subscribe-to-this-uuid'] @configurationGenerator.configure.yields null, flowConfig, {stop: 'config'} @configurationSaver.stop.yields null @configurationSaver.save.yields null @sut.setupDevice = sinon.stub().yields null @sut.deploy => done() it 'should message the FLOW_LOGGER_UUID', -> expect(@meshbluHttp.message).to.have.been.called firstArg = @meshbluHttp.message.firstCall.args[0] delete firstArg.payload.date expect(firstArg).to.deep.equal devices: ['flow-logger-uuid'] payload: application: 'flow-deploy-service' deploymentUuid: 'the-deployment-uuid' flowUuid: 'the-flow-uuid' userUuid: 'some-user-uuid' workflow: 'flow-start' state: 'begin' message: undefined it 'should call configuration generator with the flow', -> expect(@configurationGenerator.configure).to.have.been.calledWith flowData: { a: 1, b: 5 } userData: {api: {}} deploymentUuid: 'the-deployment-uuid' flowToken: 'the-flow-token' it 'should call configuration saver with the flow', -> expect(@configurationSaver.save).to.have.been.calledWith( flowId: 'the-flow-uuid' instanceId: 'an-instance-id' flowData: 'some': 'thing' 'subscribe-devices': config: 'broadcast.sent': ['subscribe-to-this-uuid'] ) expect(@configurationSaver.save).to.have.been.calledWith( flowId: 'the-flow-uuid-stop' instanceId: 'an-instance-id' flowData: stop: 'config' ) it 'should call request.get', -> options = json: true auth : user: 'some-user-uuid' pass: 'some-user-token' expect(@request.get).to.have.been.calledWith 'https://api.octoblu.com/api/flows/the-flow-uuid', options expect(@request.get).to.have.been.calledWith 'https://api.octoblu.com/api/user', options it 'should message the FLOW_LOGGER_UUID', -> expect(@meshbluHttp.message).to.have.been.called firstArg = @meshbluHttp.message.secondCall.args[0] delete firstArg.payload.date expect(firstArg).to.deep.equal devices: ['flow-logger-uuid'] payload: application: 'flow-deploy-service' deploymentUuid: 'the-deployment-uuid' flowUuid: 'the-flow-uuid' userUuid: 'some-user-uuid' workflow: 'flow-start' state: 'end' message: undefined describe 'when deploy is called and user GET errored', -> beforeEach (done) -> userUrl = 'https://api.octoblu.com/api/user' @request.get.withArgs(userUrl).yields new Error 'whoa, thats not a user', null @sut.deploy (@error, @result) => done() it 'should call request.get', -> expect(@request.get).to.have.been.called it 'should yield and error', -> expect(@error).to.exist it 'should not give us a result', -> expect(@result).to.not.exist it 'should message the FLOW_LOGGER_UUID', -> expect(@meshbluHttp.message).to.have.been.calledTwice firstArg = @meshbluHttp.message.secondCall.args[0] delete firstArg.payload.date expect(firstArg).to.deep.equal devices: ['flow-logger-uuid'] payload: application: 'flow-deploy-service' deploymentUuid: 'the-deployment-uuid' flowUuid: 'the-flow-uuid' userUuid: 'some-user-uuid' workflow: 'flow-start' state: 'error' message: 'whoa, thats not a user' describe 'when deploy is called and flow get errored', -> beforeEach (done) -> userUrl = 'https://api.octoblu.com/api/user' @request.get.withArgs(userUrl).yields null flowUrl = 'https://api.octoblu.com/api/flows/the-flow-uuid' @request.get.withArgs(flowUrl).yields new Error 'whoa, shoots bad', null @sut.deploy (@error, @result) => done() it 'should call request.get', -> expect(@request.get).to.have.been.called it 'should yield and error', -> expect(@error).to.exist it 'should not give us a result', -> expect(@result).to.not.exist it 'should message the FLOW_LOGGER_UUID', -> expect(@meshbluHttp.message).to.have.been.calledTwice firstArg = @meshbluHttp.message.secondCall.args[0] delete firstArg.payload.date expect(firstArg).to.deep.equal devices: ['flow-logger-uuid'] payload: application: 'flow-deploy-service' deploymentUuid: 'the-deployment-uuid' flowUuid: 'the-flow-uuid' userUuid: 'some-user-uuid' workflow: 'flow-start' state: 'error' message: 'whoa, shoots bad' describe 'when deploy is called and the configuration generator returns an error', -> beforeEach (done)-> @configurationGenerator.configure.yields new Error 'Oh noes' @sut.deploy (@error, @result)=> done() it 'should return an error with an error', -> expect(@error).to.exist it 'should not give us a result', -> expect(@result).to.not.exist it 'should message the FLOW_LOGGER_UUID', -> expect(@meshbluHttp.message).to.have.been.calledTwice firstArg = @meshbluHttp.message.secondCall.args[0] delete firstArg.payload.date expect(firstArg).to.deep.equal devices: ['flow-logger-uuid'] payload: application: 'flow-deploy-service' deploymentUuid: 'the-deployment-uuid' flowUuid: 'the-flow-uuid' userUuid: 'some-user-uuid' workflow: 'flow-start' state: 'error' message: 'Oh noes' describe 'when deploy is called and the configuration stop returns an error', -> beforeEach (done)-> @configurationGenerator.configure.yields null, { erik_likes_me: true} @configurationSaver.stop.yields new Error 'Erik can never like me enough' @sut.deploy (@error, @result)=> done() it 'should yield and error', -> expect(@error).to.exist it 'should not give us a result', -> expect(@result).to.not.exist it 'should not call save', -> expect(@configurationSaver.save).to.not.have.been.called it 'should message the FLOW_LOGGER_UUID', -> expect(@meshbluHttp.message).to.have.been.calledTwice firstArg = @meshbluHttp.message.secondCall.args[0] delete firstArg.payload.date expect(firstArg).to.deep.equal devices: ['flow-logger-uuid'] payload: application: 'flow-deploy-service' deploymentUuid: 'the-deployment-uuid' flowUuid: 'the-flow-uuid' userUuid: 'some-user-uuid' workflow: 'flow-start' state: 'error' message: 'Erik can never like me enough' describe 'when deploy is called and the configuration save returns an error', -> beforeEach (done)-> @configurationGenerator.configure.yields null, { erik_likes_me: true} @configurationSaver.stop.yields null @configurationSaver.save.yields new Error 'Erik can never like me enough' @sut.deploy (@error, @result)=> done() it 'should yield and error', -> expect(@error).to.exist it 'should not give us a result', -> expect(@result).to.not.exist it 'should message the FLOW_LOGGER_UUID', -> expect(@meshbluHttp.message).to.have.been.calledTwice firstArg = @meshbluHttp.message.secondCall.args[0] delete firstArg.payload.date expect(firstArg).to.deep.equal devices: ['flow-logger-uuid'] payload: application: 'flow-deploy-service' deploymentUuid: 'the-deployment-uuid' flowUuid: 'the-flow-uuid' userUuid: 'some-user-uuid' workflow: 'flow-start' state: 'error' message: 'Erik can never like me enough' describe 'when deploy is called and the generator and saver actually worked', -> beforeEach (done) -> @configurationGenerator.configure.yields null, { erik_likes_me: 'more than you know'} @configurationSaver.stop.yields null @configurationSaver.save.yields null, {finally_i_am_happy: true} @sut.setupDevice = sinon.stub().yields null @sut.deploy (@error, @result) => done() it 'should call setupDeviceForwarding', -> expect(@sut.setupDevice).to.have.been.called describe 'createSubscriptions', -> beforeEach (done) -> @meshbluHttp.createSubscription.yields null flowConfig = 'subscribe-devices': config: 'broadcast.sent': ['subscribe-to-this-uuid'] @sut.createSubscriptions flowConfig, done it "should create the subscription to the device's", -> subscriberUuid = 'the-flow-uuid' emitterUuid = 'subscribe-to-this-uuid' type = 'broadcast.sent' expect(@meshbluHttp.createSubscription).to.have.been.calledWith {subscriberUuid, emitterUuid, type} describe 'setupDeviceForwarding', -> beforeEach (done) -> @updateMessageHooks = $addToSet: 'meshblu.forwarders.broadcast.received': signRequest: true url: 'http://www.zombo.com' method: 'POST' name: 'nanocyte-flow-deploy' type: 'webhook' 'meshblu.forwarders.message.received': signRequest: true url: 'http://www.zombo.com' method: 'POST' name: 'nanocyte-flow-deploy' type: 'webhook' @pullMessageHooks = $pull: 'meshblu.forwarders.received': name: 'nanocyte-flow-deploy' 'meshblu.messageHooks': name: 'nanocyte-flow-deploy' 'meshblu.forwarders.broadcast.received': name: 'nanocyte-flow-deploy' 'meshblu.forwarders.message.received': name: 'nanocyte-flow-deploy' @removeOldMessageHooks = $unset: 'meshblu.forwarders.broadcast': '' @device = uuid: 1 flow: {a: 1, b: 5} meshblu: messageHooks: [ generateAndForwardMeshbluCredentials: true url: 'http://www.neopets.com' method: 'DELETE' name: 'nanocyte-flow-deploy' ] @meshbluHttp.whoami.yields null, meshblu: forwarders: broadcast: [] @meshbluHttp.updateDangerously.yields null, null @sut.setupDeviceForwarding (@error, @result) => done() it "should update a meshblu device with the webhook to wherever it's going", -> expect(@meshbluHttp.updateDangerously).to.have.been.calledWith 'the-flow-uuid', @removeOldMessageHooks expect(@meshbluHttp.updateDangerously).to.have.been.calledWith 'the-flow-uuid', @pullMessageHooks expect(@meshbluHttp.updateDangerously).to.have.been.calledWith 'the-flow-uuid', @updateMessageHooks describe 'setupMessageSchema', -> beforeEach (done) -> @updateDevice = $set: messageSchema: type: "object" properties: from: type: "string" title: 'Trigger' required: true enum: [ 'a', 'c' ] messageFormSchema: [ key: "from" titleMap: { 'a' : 'multiply (a)' 'c' : 'rabbits (c)' } ] nodes = [ { class: 'trigger' id: 'a' name: 'multiply' }, { class: 'not-a-trigger' id: 'b' name: 'like' }, { class: 'trigger' id: 'c' name: 'rabbits' } ] @sut.meshbluHttp.updateDangerously.yields null, null @sut.setupMessageSchema nodes, (@error, @result) => done() it "should update a meshblu device with message schema for triggers", -> expect(@sut.meshbluHttp.updateDangerously).to.have.been.calledWith 'the-flow-uuid', @updateDevice describe 'startFlow', -> describe 'when called and there is no errors', -> beforeEach (done) -> @meshbluHttp.updateDangerously.yields null @meshbluHttp.message.yields null, null @sut.startFlow (@error, @result) => done() it 'should update meshblu device status', -> expect(@meshbluHttp.updateDangerously).to.have.been.calledWith 'the-flow-uuid', $set: online: true deploying: false stopping: false it 'should message meshblu with the a flow start message', -> expect(@meshbluHttp.message).to.have.been.calledWith devices: ['the-flow-uuid'] payload: from: "engine-start" it 'should message meshblu with a subscribe:pulse message', -> expect(@meshbluHttp.message).to.have.been.calledWith devices: ['the-flow-uuid'] topic: 'subscribe:pulse' describe 'when called and meshblu returns an error', -> beforeEach (done) -> @message = payload: from: "engine-start" @meshbluHttp.updateDangerously.yields null @meshbluHttp.message.yields new Error 'duck army', null @sut.startFlow (@error, @result) => done() it 'should call the callback with the error', -> expect(@error).to.exist describe 'stopFlow', -> describe 'when called and there is no error', -> beforeEach (done) -> @meshbluHttp.updateDangerously.yields null @meshbluHttp.message.yields null, null @sut.stopFlow (@error, @result) => done() it 'should update the meshblu device with as offline', -> expect(@meshbluHttp.updateDangerously).to.have.been.calledWith 'the-flow-uuid', $set: online: false deploying: false stopping: false it 'should message meshblu with the a flow stop message', -> expect(@sut.meshbluHttp.message).to.have.been.calledWith devices: ['the-flow-uuid'] payload: from: "engine-stop" describe 'when called and meshblu returns an error', -> beforeEach (done) -> @meshbluHttp.updateDangerously.yields null @meshbluHttp.message.yields new Error 'look at meeeeee', null @sut.stopFlow (@error, @result) => done() it 'should call the callback with the error', -> expect(@error).to.exist