2019-10-20 17:36:09 +02:00
|
|
|
'use strict'
|
|
|
|
/* eslint-disable handle-callback-err */
|
|
|
|
process.env.NODE_ENV = 'production'
|
|
|
|
|
|
|
|
const sinon = require('sinon')
|
|
|
|
const should = require('chai').should()
|
|
|
|
const nock = require('nock')
|
|
|
|
const Outgoing = require('./../lib/outgoing')
|
|
|
|
|
|
|
|
describe('Outgoing webhook component', () => {
|
2019-11-23 19:37:28 +01:00
|
|
|
let logger, config, xmppSendStub, xmpp, scope, scopeUnauthorized, scopeWithError, scopeWithTimeout, reqSpy
|
2019-10-20 17:36:09 +02:00
|
|
|
|
|
|
|
before('Setup', () => {
|
|
|
|
// create default logger
|
|
|
|
logger = require('./../lib/logger')()
|
|
|
|
|
|
|
|
// get configuration
|
|
|
|
config = require('./../lib/config')(logger, './test/config.json')
|
|
|
|
|
|
|
|
// update logger with configuration
|
|
|
|
logger.updateConfig(config.logger)
|
|
|
|
|
|
|
|
// mock xmpp component
|
|
|
|
xmppSendStub = sinon.stub()
|
|
|
|
xmpp = {
|
|
|
|
send: xmppSendStub
|
|
|
|
}
|
|
|
|
|
|
|
|
// spy nock requests
|
|
|
|
reqSpy = sinon.spy()
|
|
|
|
})
|
|
|
|
|
|
|
|
beforeEach('Reset XMPP stub history', function (done) {
|
|
|
|
xmppSendStub.resetHistory()
|
|
|
|
reqSpy.resetHistory()
|
|
|
|
|
|
|
|
// mock remote server
|
|
|
|
scope = nock('https://domain.ltd:port')
|
|
|
|
.post('/path/resource')
|
|
|
|
.reply(200, { reply: 'This is a reply' })
|
|
|
|
scope.on('request', reqSpy)
|
2019-11-23 19:18:35 +01:00
|
|
|
|
2019-10-20 17:36:09 +02:00
|
|
|
scopeUnauthorized = nock('https://domain.ltd:port')
|
|
|
|
.post('/path/protectedresource')
|
|
|
|
.reply(401, {})
|
|
|
|
scopeUnauthorized.on('request', reqSpy)
|
2019-11-23 19:18:35 +01:00
|
|
|
|
2019-10-20 17:36:09 +02:00
|
|
|
scopeWithError = nock('https://domain.ltd:port')
|
2019-11-23 19:18:35 +01:00
|
|
|
.post('/path/request-error')
|
|
|
|
.replyWithError('error in request')
|
2019-10-20 17:36:09 +02:00
|
|
|
scopeWithError.on('request', reqSpy)
|
|
|
|
|
2019-11-23 19:37:28 +01:00
|
|
|
scopeWithTimeout = nock('https://domain.ltd:port')
|
|
|
|
.post('/path/timeout-error')
|
|
|
|
.delay(1000)
|
|
|
|
.reply(200, { reply: 'This is a reply' })
|
|
|
|
scopeWithTimeout.on('request', reqSpy)
|
|
|
|
|
2019-10-20 17:36:09 +02:00
|
|
|
done()
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('Unkwnow outgoing webhook', () => {
|
2019-11-23 19:18:35 +01:00
|
|
|
it('Should throw an exception and not execute request', async () => {
|
|
|
|
try {
|
|
|
|
await Outgoing(logger, config, xmpp, 'user', 'destination', 'message', 'type', 'unknownCode')
|
|
|
|
should.fail(0, 1, 'Exception not thrown')
|
|
|
|
} catch (error) {
|
|
|
|
error.message.should.equal('There is no webhook with code "unknownCode"')
|
|
|
|
}
|
|
|
|
sinon.assert.notCalled(reqSpy)
|
2019-10-20 17:36:09 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('POST with basic authorization and JSON content-type and reply message to XMPP', () => {
|
2019-11-23 19:18:35 +01:00
|
|
|
it('Should send basic authentication and JSON content-type in header and send an XMPP message', async () => {
|
|
|
|
let result
|
|
|
|
try {
|
|
|
|
result = await Outgoing(logger, config, xmpp, 'user', 'destination', 'This a first message', 'type', 'basic-json-reply')
|
|
|
|
} catch (error) {
|
|
|
|
should.fail(0, 1, 'Exception is thrown')
|
|
|
|
}
|
|
|
|
result.should.equal('Message sent. There is a reply to send back in chat destination: This is a reply')
|
|
|
|
sinon.assert.calledOnce(reqSpy)
|
|
|
|
const req = reqSpy.args[0][0]
|
|
|
|
const bodyReq = JSON.parse(reqSpy.args[0][2])
|
|
|
|
req.headers.authorization.should.equal('Basic dXNlcjM6M3Bhc3M=')
|
|
|
|
req.headers['content-type'].should.equal('application/json')
|
|
|
|
bodyReq.from.should.equal('user')
|
|
|
|
bodyReq.channel.should.equal('destination')
|
|
|
|
bodyReq.message.should.equal('This a first message')
|
|
|
|
sinon.assert.calledOnce(xmppSendStub)
|
|
|
|
const xmppSendArgs = xmppSendStub.args[0]
|
|
|
|
xmppSendArgs[0].should.equal('destination')
|
|
|
|
xmppSendArgs[1].should.equal('This is a reply')
|
|
|
|
xmppSendArgs[2].should.equal('type')
|
2019-10-20 17:36:09 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-11-23 19:18:35 +01:00
|
|
|
describe('POST with bearer authorization and form-urlencoded content-type', () => {
|
|
|
|
it('Should send bearer authentication and form-urlencoded content-type in header', async () => {
|
|
|
|
let result
|
|
|
|
try {
|
|
|
|
result = await Outgoing(logger, config, xmpp, 'user', 'destination', 'This a second message', 'type', 'bearer-form')
|
|
|
|
} catch (error) {
|
|
|
|
should.fail(0, 1, 'Exception is thrown')
|
|
|
|
}
|
|
|
|
result.should.equal('Message sent')
|
|
|
|
sinon.assert.calledOnce(reqSpy)
|
|
|
|
const req = reqSpy.args[0][0]
|
|
|
|
const bodyReq = decodeURIComponent(reqSpy.args[0][2])
|
|
|
|
req.headers.authorization.should.equal('Bearer abcdefgh')
|
|
|
|
req.headers['content-type'].should.equal('application/x-www-form-urlencoded')
|
|
|
|
bodyReq.should.equal('from=user&message=This a second message&channel=destination')
|
2019-10-20 17:36:09 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('POST without authorization', () => {
|
2019-11-23 19:18:35 +01:00
|
|
|
it('Should not send authorization in header, handle 401 and throw an exception', async () => {
|
|
|
|
try {
|
|
|
|
await Outgoing(logger, config, xmpp, 'user', 'destination', 'message', 'type', 'protected')
|
|
|
|
should.fail(0, 1, 'Exception not thrown')
|
|
|
|
} catch (error) {
|
|
|
|
error.message.should.equal('HTTP error: 401')
|
|
|
|
}
|
|
|
|
sinon.assert.calledOnce(reqSpy)
|
2019-10-20 17:36:09 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('POST with HTTP error', () => {
|
2019-11-23 19:18:35 +01:00
|
|
|
it('Should handle error and throw an exception', async () => {
|
|
|
|
try {
|
|
|
|
await Outgoing(logger, config, xmpp, 'user', 'destination', 'This a second message', 'type', 'request-error')
|
|
|
|
should.fail(0, 1, 'Exception not thrown')
|
|
|
|
} catch (error) {
|
|
|
|
error.message.should.equal('error in request')
|
|
|
|
}
|
|
|
|
sinon.assert.calledOnce(reqSpy)
|
2019-10-20 17:36:09 +02:00
|
|
|
})
|
|
|
|
})
|
2019-11-23 19:37:28 +01:00
|
|
|
|
|
|
|
describe('POST with timeout', () => {
|
|
|
|
it('Should handle error and throw an exception', async () => {
|
|
|
|
try {
|
|
|
|
await Outgoing(logger, config, xmpp, 'user', 'destination', 'This a second message', 'type', 'timeout-error')
|
|
|
|
should.fail(0, 1, 'Exception not thrown')
|
|
|
|
} catch (error) {
|
|
|
|
error.message.should.equal('ESOCKETTIMEDOUT')
|
|
|
|
}
|
|
|
|
sinon.assert.calledOnce(reqSpy)
|
|
|
|
})
|
|
|
|
})
|
2019-10-20 17:36:09 +02:00
|
|
|
})
|