-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
118 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,16 +2,16 @@ | |
process.env.NODE_ENV = 'production' | ||
|
||
const sinon = require('sinon') | ||
require('chai').should() | ||
const EventEmitter = require('events').EventEmitter | ||
const mock = require('mock-require') | ||
const xml = require('@xmpp/xml') | ||
const jid = require('@xmpp/jid') | ||
|
||
describe('XMPP component', () => { | ||
const simpleXmppEvents = new EventEmitter() | ||
let logger, config, outgoingStub, xmppSendStub, xmppCloseStub | ||
let logger, config, outgoingStub, outgoingStubRejected, xmppSendStub, xmppCloseStub, simpleXmppEvents, xmpp | ||
|
||
before('Setup', (done) => { | ||
before('Setup logger and config', (done) => { | ||
// create default logger | ||
logger = require('./../lib/logger')() | ||
|
||
|
@@ -21,6 +21,25 @@ describe('XMPP component', () => { | |
// update logger with configuration | ||
logger.updateConfig(config.logger) | ||
|
||
// mock logger trace | ||
sinon.stub(logger, 'trace') | ||
|
||
done() | ||
}) | ||
|
||
after('Remove mocks', (done) => { | ||
mock.stopAll() | ||
logger.trace.restore() | ||
done() | ||
}) | ||
|
||
beforeEach('Setup XMPP client with stub', function () { | ||
simpleXmppEvents = new EventEmitter() | ||
|
||
// mock outgoing module | ||
outgoingStub = sinon.stub().resolves() | ||
mock('./../lib/outgoing', outgoingStub) | ||
|
||
// mock @xmpp/client module | ||
xmppSendStub = sinon.stub().resolves() | ||
xmppCloseStub = sinon.stub().resolves() | ||
|
@@ -38,32 +57,21 @@ describe('XMPP component', () => { | |
jid: require('@xmpp/jid') | ||
}) | ||
|
||
// mock outgoing | ||
outgoingStub = sinon.stub() | ||
mock('./../lib/outgoing', outgoingStub) | ||
|
||
// mock logger trace | ||
sinon.stub(logger, 'trace') | ||
|
||
done() | ||
}) | ||
|
||
after('Remove mocks', (done) => { | ||
mock.stopAll() | ||
logger.trace.restore() | ||
done() | ||
}) | ||
|
||
beforeEach('Reset outgoing and xmpp stub history', function () { | ||
// reset stubs history | ||
outgoingStub.resetHistory() | ||
xmppSendStub.resetHistory() | ||
xmppCloseStub.resetHistory() | ||
|
||
// call module and emit online event | ||
xmpp = require('./../lib/xmpp')(logger, config) | ||
simpleXmppEvents.emit('online', jid('[email protected]/resource')) | ||
}) | ||
|
||
describe('Connect to XMPP server', () => { | ||
beforeEach(async () => { | ||
await simpleXmppEvents.emit('status', 'connecting') | ||
}) | ||
it('Should connect to XMPP server and join rooms when application start', (done) => { | ||
require('./../lib/xmpp')(logger, config) | ||
simpleXmppEvents.emit('online', jid('[email protected]/resource')) | ||
sinon.assert.called(xmppSendStub) | ||
// 1 "send" call for presence and n "send" calls for joining rooms | ||
let roomsLength = config.xmpp.rooms.length | ||
|
@@ -87,42 +95,46 @@ describe('XMPP component', () => { | |
done() | ||
}) | ||
it('Should trace connection status', (done) => { | ||
simpleXmppEvents.emit('status', 'connecting') | ||
sinon.assert.calledWith(logger.trace, 'Status changed to connecting') | ||
done() | ||
}) | ||
}) | ||
|
||
describe('Bot receive a presence stanza from someone', () => { | ||
it('Should not trigger outgoing webhook', (done) => { | ||
simpleXmppEvents.emit('stanza', xml( | ||
beforeEach(async () => { | ||
await simpleXmppEvents.emit('stanza', xml( | ||
'presence', { | ||
from: '[email protected]', | ||
to: '[email protected]' | ||
} | ||
)) | ||
}) | ||
it('Should not trigger outgoing webhook', (done) => { | ||
sinon.assert.notCalled(outgoingStub) | ||
done() | ||
}) | ||
}) | ||
|
||
describe('Bot receive an empty message from someone', () => { | ||
it('Should not trigger outgoing webhook', (done) => { | ||
simpleXmppEvents.emit('stanza', xml( | ||
beforeEach(async () => { | ||
await simpleXmppEvents.emit('stanza', xml( | ||
'message', { | ||
from: '[email protected]', | ||
to: '[email protected]', | ||
type: 'chat' | ||
} | ||
)) | ||
}) | ||
it('Should not trigger outgoing webhook', (done) => { | ||
sinon.assert.notCalled(outgoingStub) | ||
done() | ||
}) | ||
}) | ||
|
||
describe('Bot receive a message from someone', () => { | ||
it('Should trigger outgoing webhook with valid arguments and send a message delivery receipt', (done) => { | ||
simpleXmppEvents.emit('stanza', xml( | ||
beforeEach(async () => { | ||
xmppSendStub.resetHistory() | ||
await simpleXmppEvents.emit('stanza', xml( | ||
'message', { | ||
from: '[email protected]', | ||
to: '[email protected]', | ||
|
@@ -138,6 +150,8 @@ describe('XMPP component', () => { | |
xmlns: 'urn:xmpp:receipts' | ||
}) | ||
)) | ||
}) | ||
it('Should trigger outgoing webhook with valid arguments and send a message delivery receipt', (done) => { | ||
sinon.assert.calledOnce(outgoingStub) | ||
const args = outgoingStub.args[0] | ||
args.should.have.length(8) | ||
|
@@ -163,9 +177,55 @@ describe('XMPP component', () => { | |
}) | ||
}) | ||
|
||
describe('Bot receive a message from someone but webhook call failed', () => { | ||
beforeEach(async () => { | ||
simpleXmppEvents = new EventEmitter() | ||
outgoingStubRejected = sinon.stub().rejects() | ||
mock('./../lib/outgoing', outgoingStubRejected) | ||
require('./../lib/xmpp')(logger, config) | ||
simpleXmppEvents.emit('online', jid('[email protected]/resource')) | ||
xmppSendStub.resetHistory() | ||
await simpleXmppEvents.emit('stanza', xml( | ||
'message', { | ||
from: '[email protected]', | ||
to: '[email protected]', | ||
type: 'chat', | ||
id: 'fcdd3d8c' | ||
}, | ||
xml( | ||
'body', { | ||
}, | ||
'Is it working?') | ||
)) | ||
}) | ||
it('Should send a XMPP reply if webhook failed', () => { | ||
sinon.assert.calledOnce(outgoingStubRejected) | ||
const args = outgoingStubRejected.args[0] | ||
args.should.have.length(8) | ||
args[3].should.equal('someone') | ||
args[4].should.equal('[email protected]') | ||
args[5].should.equal('Is it working?') | ||
args[6].should.equal('chat') | ||
args[7].should.equal('w1') | ||
sinon.assert.calledOnce(xmppSendStub) | ||
const receiptStanza = xml( | ||
'message', { | ||
to: '[email protected]', | ||
type: 'chat' | ||
}, | ||
xml( | ||
'body', { | ||
}, | ||
'Oops, something went wrong :(' | ||
) | ||
) | ||
xmppSendStub.args[0][0].should.deep.equal(receiptStanza) | ||
}) | ||
}) | ||
|
||
describe('Bot receive a message from himself in a room', () => { | ||
it('Should not trigger outgoing webhook', (done) => { | ||
simpleXmppEvents.emit('stanza', xml( | ||
beforeEach(async () => { | ||
await simpleXmppEvents.emit('stanza', xml( | ||
'message', { | ||
from: '[email protected]/bot', | ||
to: '[email protected]', | ||
|
@@ -176,14 +236,16 @@ describe('XMPP component', () => { | |
}, | ||
'This is the message text') | ||
)) | ||
}) | ||
it('Should not trigger outgoing webhook', (done) => { | ||
sinon.assert.notCalled(outgoingStub) | ||
done() | ||
}) | ||
}) | ||
|
||
describe('Bot receive a message in an unknown room', () => { | ||
it('Should not trigger outgoing webhook', (done) => { | ||
simpleXmppEvents.emit('stanza', xml( | ||
beforeEach(async () => { | ||
await simpleXmppEvents.emit('stanza', xml( | ||
'message', { | ||
from: '[email protected]/someone', | ||
to: '[email protected]', | ||
|
@@ -194,15 +256,16 @@ describe('XMPP component', () => { | |
}, | ||
'This is the message text') | ||
)) | ||
}) | ||
it('Should not trigger outgoing webhook', (done) => { | ||
sinon.assert.notCalled(outgoingStub) | ||
done() | ||
}) | ||
}) | ||
|
||
describe('Bot receive an old message in a room', () => { | ||
it('Should not trigger outgoing webhook', (done) => { | ||
simpleXmppEvents.emit('groupchat', '[email protected]', 'someone', 'This is the message text', 'stamp') | ||
simpleXmppEvents.emit('stanza', xml( | ||
beforeEach(async () => { | ||
await simpleXmppEvents.emit('stanza', xml( | ||
'message', { | ||
from: '[email protected]/someone', | ||
to: '[email protected]', | ||
|
@@ -219,14 +282,16 @@ describe('XMPP component', () => { | |
}, | ||
'This is the message text') | ||
)) | ||
}) | ||
it('Should not trigger outgoing webhook', (done) => { | ||
sinon.assert.notCalled(outgoingStub) | ||
done() | ||
}) | ||
}) | ||
|
||
describe('Bot receive a message in a room', () => { | ||
it('Should trigger outgoing webhook with valid arguments', (done) => { | ||
simpleXmppEvents.emit('stanza', xml( | ||
beforeEach(async () => { | ||
await simpleXmppEvents.emit('stanza', xml( | ||
'message', { | ||
from: '[email protected]/someone', | ||
to: '[email protected]', | ||
|
@@ -237,6 +302,8 @@ describe('XMPP component', () => { | |
}, | ||
'This is the message text') | ||
)) | ||
}) | ||
it('Should trigger outgoing webhook with valid arguments', (done) => { | ||
sinon.assert.calledOnce(outgoingStub) | ||
const args = outgoingStub.args[0] | ||
args.should.have.length(8) | ||
|
@@ -250,9 +317,11 @@ describe('XMPP component', () => { | |
}) | ||
|
||
describe('Send a message', () => { | ||
beforeEach(async () => { | ||
xmppSendStub.resetHistory() | ||
await xmpp.send('[email protected]', 'This is the message text sent by bot', 'chat') | ||
}) | ||
it('Should call xmpp/client.send() with valid stanza', (done) => { | ||
const xmpp = require('./../lib/xmpp')(logger, config) | ||
xmpp.send('[email protected]', 'This is the message text sent by bot', 'chat') | ||
sinon.assert.calledOnce(xmppSendStub) | ||
let stanza = xml( | ||
'message', { | ||
|
@@ -272,29 +341,31 @@ describe('XMPP component', () => { | |
}) | ||
|
||
describe('Close connection', () => { | ||
beforeEach(async () => { | ||
await xmpp.close() | ||
}) | ||
it('Should call xmpp/client.stop()', (done) => { | ||
const xmpp = require('./../lib/xmpp')(logger, config) | ||
xmpp.close() | ||
sinon.assert.calledOnce(xmppCloseStub) | ||
done() | ||
}) | ||
}) | ||
|
||
describe('XMPP server send an error', () => { | ||
before(() => { | ||
let errorText | ||
beforeEach(async () => { | ||
sinon.stub(process, 'exit') | ||
errorText = 'This the error text' | ||
await simpleXmppEvents.emit('error', new Error(errorText)) | ||
}) | ||
after(() => { | ||
afterEach(() => { | ||
process.exit.restore() | ||
}) | ||
it('Should log error and exit with 99 code', (done) => { | ||
let error = 'This the error text' | ||
simpleXmppEvents.emit('error', new Error(error)) | ||
require('fs').readFile(config.logger.file.path + config.logger.file.filename, 'utf8', (err, data) => { | ||
if (err) { | ||
throw err | ||
} | ||
data.should.match(new RegExp('XMPP client encountered following error: ' + error + '\n$')) | ||
data.should.match(new RegExp('XMPP client encountered following error: ' + errorText + '\n$')) | ||
sinon.assert.calledWith(process.exit, 99) | ||
done() | ||
}) | ||
|