meshblu-http
Version:
Meshblu HTTP API
720 lines (546 loc) • 25.5 kB
text/coffeescript
MeshbluHttp = require '../src/meshblu-http'
describe 'MeshbluHttp', ->
describe '->constructor', ->
describe 'default', ->
beforeEach ->
= new MeshbluHttp
it 'should set urlBase', ->
expect(.urlBase).to.equal 'https://meshblu.octoblu.com:443'
describe 'with options', ->
beforeEach ->
= new MeshbluHttp
uuid: '1234'
token: 'tok3n'
server: 'google.co'
port: 555
protocol: 'ldap'
it 'should set urlBase', ->
expect(.urlBase).to.equal 'ldap://google.co:555'
it 'should set the protocol', ->
expect(.protocol).to.equal 'ldap'
it 'should set uuid', ->
expect(.uuid).to.equal '1234'
it 'should set token', ->
expect(.token).to.equal 'tok3n'
it 'should set server', ->
expect(.server).to.equal 'google.co'
it 'should set port', ->
expect(.port).to.equal 555
describe 'with other options', ->
beforeEach ->
= new MeshbluHttp
protocol: 'ftp'
server: 'halo'
port: 400
it 'should set urlBase', ->
expect(.urlBase).to.equal 'ftp://halo:400'
describe 'with websocket protocol options', ->
beforeEach ->
= new MeshbluHttp
protocol: 'websocket'
server: 'halo'
port: 400
it 'should set urlBase', ->
expect(.urlBase).to.equal 'http://halo:400'
describe 'without a protocol on a specific port', ->
beforeEach ->
= new MeshbluHttp
server: 'localhost'
port: 3000
it 'should set urlBase', ->
expect(.urlBase).to.equal 'http://localhost:3000'
describe '->device', ->
beforeEach ->
= get: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'when given a valid uuid', ->
beforeEach (done) ->
.get.yields null, {statusCode: 200}, foo: 'bar'
.device 'the-uuuuid', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/v2/devices/the-uuuuid'
it 'should call callback', ->
expect().to.deep.equal foo: 'bar'
describe 'when an error happens', ->
beforeEach (done) ->
.get.yields new Error
= request:
.device 'invalid-uuid', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/v2/devices/invalid-uuid'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe 'when a meshblu error body is returned', ->
beforeEach (done) ->
.get.yields null, null, error: 'something wrong'
.device 'invalid-uuid', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/v2/devices/invalid-uuid'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe '->devices', ->
beforeEach ->
= get: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'with a valid query', ->
beforeEach (done) ->
.get.yields null, null, foo: 'bar'
.devices type: 'octoblu:test', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices',
qs:
type: 'octoblu:test'
json: true
it 'should call callback', ->
expect().to.deep.equal foo: 'bar'
describe 'when an error happens', ->
beforeEach (done) ->
.get.yields new Error
.devices 'invalid-uuid', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe 'when a meshblu error body is returned', ->
beforeEach (done) ->
.get.yields null, null, error: 'something wrong'
.devices 'invalid-uuid', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe '->generateAndStoreToken', ->
beforeEach ->
= post: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'with a valid uuid', ->
beforeEach (done) ->
.post.yields null, null, foo: 'bar'
.generateAndStoreToken 'uuid', (, ) => done()
it 'should call get', ->
expect(.post).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/uuid/tokens'
it 'should call callback', ->
expect().to.deep.equal foo: 'bar'
describe 'when an error happens', ->
beforeEach (done) ->
.post.yields new Error
.generateAndStoreToken 'invalid-uuid', (, ) => done()
it 'should call get', ->
expect(.post).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/invalid-uuid/tokens'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe 'when a meshblu error body is returned', ->
beforeEach (done) ->
.post.yields null, null, error: 'something wrong'
.generateAndStoreToken 'invalid-uuid', (, ) => done()
it 'should call get', ->
expect(.post).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/invalid-uuid/tokens'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe '->mydevices', ->
beforeEach ->
= get: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'with a valid query', ->
beforeEach (done) ->
.get.yields null, null, foo: 'bar'
.mydevices type: 'octoblu:test', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/mydevices',
qs:
type: 'octoblu:test'
json: true
it 'should call callback', ->
expect().to.deep.equal foo: 'bar'
describe 'when an error happens', ->
beforeEach (done) ->
.get.yields new Error
.mydevices 'invalid-uuid', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/mydevices'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe 'when a meshblu error body is returned', ->
beforeEach (done) ->
.get.yields null, null, error: 'something wrong'
.mydevices 'invalid-uuid', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/mydevices'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe '->message', ->
beforeEach ->
= post: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'with a message', ->
beforeEach (done) ->
.post.yields null, null, foo: 'bar'
.message devices: 'uuid', (, ) => done()
it 'should call get', ->
expect(.post).to.have.been.calledWith 'https://meshblu.octoblu.com:443/messages',
json:
devices: 'uuid'
it 'should call callback', ->
expect().to.deep.equal foo: 'bar'
describe 'when an error happens', ->
beforeEach (done) ->
.post.yields new Error
.message test: 'invalid-uuid', (, ) => done()
it 'should call get', ->
expect(.post).to.have.been.calledWith 'https://meshblu.octoblu.com:443/messages'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe 'when a meshblu error body is returned', ->
beforeEach (done) ->
.post.yields null, null, error: 'something wrong'
.message test: 'invalid-uuid', (, ) => done()
it 'should call get', ->
expect(.post).to.have.been.calledWith 'https://meshblu.octoblu.com:443/messages'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe '->register', ->
beforeEach ->
= post: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'with a device', ->
beforeEach (done) ->
.post = sinon.stub().yields null, null, null
.register {uuid: 'howdy', token: 'sweet'}, () => done()
it 'should not have an error', ->
expect().to.not.exist
it 'should call request.post on the device', ->
expect(.post).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices'
describe 'with an invalid device', ->
beforeEach (done) ->
.post = sinon.stub().yields new Error('unable to register device'), null, null
.register {uuid: 'NOPE', token: 'NO'}, () => done()
it 'should have an error', ->
expect(.message).to.equal 'unable to register device'
describe 'when request returns an error in the body', ->
beforeEach (done) ->
.post = sinon.stub().yields null, null, error: new Error('body error')
.register {uuid: 'NOPE', token: 'NO'}, () => done()
it 'should have an error', ->
expect(.message).to.equal 'body error'
describe '->resetToken', ->
beforeEach ->
= post: sinon.stub()
= new MeshbluHttp {}, request:
describe 'when called with a uuid', ->
beforeEach ->
.resetToken 'some-uuid'
it 'should call post on request', ->
expect(.post).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/some-uuid/token'
describe 'when called with a different-uuid', ->
beforeEach ->
.resetToken 'some-other-uuid'
it 'should call post on request', ->
expect(.post).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/some-other-uuid/token'
describe 'when request yields a new token', ->
beforeEach (done) ->
.post.yields null, {statusCode: 201}, uuid: 'the-uuid', token: 'my-new-token'
.resetToken 'the-uuid', (error, ) => done()
it 'should call the callback with the uuid and new token', ->
expect().to.deep.equal uuid: 'the-uuid', token: 'my-new-token'
describe 'when request yields a different new token', ->
beforeEach (done) ->
.post.yields null, {statusCode: 201}, uuid: 'the-other-uuid', token: 'my-other-new-token'
.resetToken 'the-other-uuid', (error, ) => done()
it 'should call the callback with the uuid and new token', ->
expect().to.deep.equal uuid: 'the-other-uuid', token: 'my-other-new-token'
describe 'when request yields a 401 response code', ->
beforeEach (done) ->
.post.yields null, {statusCode: 401}, error: 'unauthorized'
.resetToken 'uuid', () => done()
it 'should call the callback with the error', ->
expect().to.deep.equal new Error('unauthorized')
describe 'when request yields an error', ->
beforeEach (done) ->
.post.yields new Error('oh snap'), null
.resetToken 'the-other-uuid', () => done()
it 'should call the callback with the error', ->
expect().to.deep.equal new Error('oh snap')
describe '->revokeToken', ->
beforeEach ->
= del: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'with a valid uuid', ->
beforeEach (done) ->
.del.yields null, null, null
.revokeToken 'uuid', 'taken', (, ) => done()
it 'should call del', ->
expect(.del).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/uuid/tokens/taken'
it 'should not have an error', ->
expect().to.not.exist
describe 'when an error happens', ->
beforeEach (done) ->
.del.yields new Error
.revokeToken 'invalid-uuid', 'tekken', (, ) => done()
it 'should call del', ->
expect(.del).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/invalid-uuid/tokens/tekken'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe 'when a meshblu error body is returned', ->
beforeEach (done) ->
.del.yields null, null, error: 'something wrong'
.revokeToken 'invalid-uuid', 'tkoen', (, ) => done()
it 'should call del', ->
expect(.del).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/invalid-uuid/tokens/tkoen'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe '->setPrivateKey', ->
beforeEach ->
= {}
= sinon.spy =>
= new MeshbluHttp {}, NodeRSA:
.setPrivateKey 'data'
it 'should new NodeRSA', ->
expect().to.have.been.calledWithNew
it 'should set', ->
expect(.privateKey).to.exist
describe '->generateKeyPair', ->
beforeEach ->
=
exportKey: sinon.stub().returns ''
generateKeyPair: sinon.spy()
= sinon.spy =>
= new MeshbluHttp {}, NodeRSA:
= .generateKeyPair()
it 'should new NodeRSA', ->
expect().to.have.been.calledWithNew
it 'should get a privateKey', ->
expect(.privateKey).to.exist
it 'should get a publicKey', ->
expect(.publicKey).to.exist
describe '->sign', ->
beforeEach ->
= new MeshbluHttp {}
.privateKey = sign: sinon.stub().returns 'abcd'
it 'should sign', ->
expect(.sign('1234')).to.equal 'abcd'
describe '->unregister', ->
beforeEach ->
= del: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'with a device', ->
beforeEach (done) ->
.del = sinon.stub().yields null, null, null
.unregister {uuid: 'howdy', token: 'sweet'}, () => done()
it 'should not have an error', ->
expect().to.not.exist
it 'should call request.del on the device', ->
expect(.del).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/howdy'
describe 'with an invalid device', ->
beforeEach (done) ->
.del = sinon.stub().yields new Error('unable to delete device'), null, null
.unregister {uuid: 'NOPE', token: 'NO'}, () => done()
it 'should have an error', ->
expect(.message).to.equal 'unable to delete device'
describe 'when request returns an error in the body', ->
beforeEach (done) ->
.del = sinon.stub().yields null, null, error: new Error('body error')
.unregister {uuid: 'NOPE', token: 'NO'}, () => done()
it 'should have an error', ->
expect(.message).to.equal 'body error'
describe '->update', ->
beforeEach ->
= {}
= request:
= new MeshbluHttp {uuid: 'uuid', token: 'token'},
describe 'with a uuid and params', ->
beforeEach (done) ->
.patch = sinon.stub().yields null, statusCode: 204, uuid: 'howdy'
.update 'howdy', {sam: 'I am'}, () => done()
it 'should not have an error', ->
expect().to.not.exist
it 'should call request.patch on the device', ->
expect(.patch).to.have.been.calledWith 'https://meshblu.octoblu.com:443/v2/devices/howdy'
describe 'with an invalid device', ->
beforeEach (done) ->
.patch = sinon.stub().yields new Error('unable to update device'), null, null
.update 'NOPE', {}, () => done()
it 'should have an error', ->
expect(.message).to.equal 'unable to update device'
describe 'when request returns an error in the body with a statusCode', ->
beforeEach (done) ->
.patch = sinon.stub().yields null, {statusCode: 422}, error: 'body error'
.update 'NOPE', {}, () => done()
it 'should have an error', ->
expect().to.be.an.instanceOf Error
expect(.message).to.equal 'body error'
describe '->updateDangerously', ->
beforeEach ->
= put: sinon.stub()
= request:
= new MeshbluHttp {uuid: 'uuid', token: 'token'},
describe 'with a uuid and params', ->
beforeEach (done) ->
.put = sinon.stub().yields null, statusCode: 204, uuid: 'howdy'
.updateDangerously 'howdy', {sam: 'I am'}, () => done()
it 'should not have an error', ->
expect().to.not.exist
it 'should call request.put on the device', ->
expect(.put).to.have.been.calledWith 'https://meshblu.octoblu.com:443/v2/devices/howdy'
describe 'with an invalid device', ->
beforeEach (done) ->
.put = sinon.stub().yields new Error('unable to update device'), null, null
.updateDangerously 'NOPE', {}, () => done()
it 'should have an error', ->
expect(.message).to.equal 'unable to update device'
describe 'when request returns an error in the body with a statusCode', ->
beforeEach (done) ->
.put = sinon.stub().yields null, {statusCode: 422}, error: 'body error'
.updateDangerously 'NOPE', {}, () => done()
it 'should have an error', ->
expect().to.be.an.instanceOf Error
expect(.message).to.equal 'body error'
describe '->verify', ->
beforeEach ->
= new MeshbluHttp {}
.privateKey = verify: sinon.stub().returns true
it 'should sign', ->
expect(.verify('1234', 'bbb')).to.be.true
describe '->whoami', ->
beforeEach ->
= get: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'when given a valid uuid', ->
beforeEach (done) ->
.get.yields null, {statusCode: 200}, foo: 'bar'
.whoami (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/v2/whoami'
it 'should call callback', ->
expect().to.deep.equal foo: 'bar'
describe 'when an error happens', ->
beforeEach (done) ->
.get.yields new Error
= request:
.whoami (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/v2/whoami'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe 'when a meshblu error body is returned', ->
beforeEach (done) ->
.get.yields null, null, error: 'something wrong'
.whoami (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/v2/whoami'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe '->publicKey', ->
beforeEach ->
= get: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'when given a valid uuid', ->
beforeEach (done) ->
.get.yields null, {statusCode: 200}, foo: 'bar'
.publicKey 'my-uuid', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/my-uuid/publickey'
it 'should call callback', ->
expect().to.deep.equal foo: 'bar'
describe 'when an error happens', ->
beforeEach (done) ->
.get.yields new Error
= request:
.publicKey 'my-uuid', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/my-uuid/publickey'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe 'when a meshblu error body is returned', ->
beforeEach (done) ->
.get.yields null, null, error: 'something wrong'
.publicKey 'my-uuid', (, ) => done()
it 'should call get', ->
expect(.get).to.have.been.calledWith 'https://meshblu.octoblu.com:443/devices/my-uuid/publickey'
it 'should callback with an error', ->
expect().to.deep.equal new Error
describe '->createSubscription', ->
beforeEach ->
= post: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'when given a valid uuid', ->
beforeEach (done) ->
.post.yields null, {statusCode: 201}, {}
options =
subscriberId: 'my-uuid'
emitterId: 'device-uuid'
type: 'broadcast'
.createSubscription options, (, ) => done()
it 'should call post', ->
url = 'https://meshblu.octoblu.com:443/devices/my-uuid/subscriptions/device-uuid/broadcast'
expect(.post).to.have.been.calledWith url
describe 'when given an invalid uuid', ->
beforeEach (done) ->
.post.yields null, {statusCode: 201}, {}
options =
subscriberId: 'my-invalid-uuid'
emitterId: 'device-uuid'
type: 'received'
.createSubscription options, (, ) => done()
it 'should call post', ->
url = 'https://meshblu.octoblu.com:443/devices/my-invalid-uuid/subscriptions/device-uuid/received'
expect(.post).to.have.been.calledWith url
describe 'when given an valid uuid that meshblu thinks is invalid', ->
beforeEach (done) ->
.post.yields null, {statusCode: 422}, {error: 'message'}
options =
subscriberId: 'my-other-uuid'
emitterId: 'device-uuid'
type: 'nvm'
.createSubscription options, (, ) => done()
it 'should yield an error', ->
expect(=> throw ).to.throw 'message'
describe '->deleteSubscription', ->
beforeEach ->
= delete: sinon.stub()
= request:
= new MeshbluHttp {},
describe 'when given a valid uuid', ->
beforeEach (done) ->
.delete.yields null, {statusCode: 204}, {}
options =
subscriberId: 'my-uuid'
emitterId: 'device-uuid'
type: 'facebook'
.deleteSubscription options, (, ) => done()
it 'should call post', ->
url = 'https://meshblu.octoblu.com:443/devices/my-uuid/subscriptions/device-uuid/facebook'
expect(.delete).to.have.been.calledWith url
describe 'when given an invalid uuid', ->
beforeEach (done) ->
.delete.yields null, {statusCode: 204}, {}
options =
subscriberId: 'my-invalid-uuid'
emitterId: 'device-uuid'
type: 'twitter'
.deleteSubscription options, (, ) => done()
it 'should call post', ->
url = 'https://meshblu.octoblu.com:443/devices/my-invalid-uuid/subscriptions/device-uuid/twitter'
expect(.delete).to.have.been.calledWith url
it 'should not yield an error', ->
expect().to.not.exist
describe 'when given an valid uuid that meshblu thinks is invalid', ->
beforeEach (done) ->
.delete.yields null, {statusCode: 422}, {error: 'message'}
options =
subscriberId: 'my-other-uuid'
emitterId: 'device-uuid'
type: 'knull'
.deleteSubscription options, (, ) => done()
it 'should yield an error', ->
expect(=> throw ).to.throw 'message'