slapp
Version:
A module for Slack App integrations
1,366 lines (1,134 loc) • 28.5 kB
JavaScript
'use strict'
const test = require('ava').test
const sinon = require('sinon')
const Slapp = require('../src/slapp')
const Message = require('../src/message')
const fixtures = require('./fixtures/')
const meta = {
app_token: 'app_token',
team_id: 'team_id',
channel_id: 'channel_id',
user_id: 'user_id',
app_bot_id: 'app_bot_id'
}
test('Slapp()', t => {
let options = {
log: true,
colors: true,
verify_token: 'verify_token',
convo_store: () => {},
context
}
let app = new Slapp(options)
t.is(app.log, options.log)
t.is(app.convoStore, options.convo_store)
t.is(app.verify_token, options.verify_token)
t.is(typeof app.client, 'object')
t.is(typeof app.receiver, 'object')
t.true(Array.isArray(app._middleware))
t.is(app._middleware.length, 0)
t.is(typeof app.emit, 'function')
})
test('Slapp() w/o context', t => {
t.throws(() => {
let app = new Slapp()
t.is(null, app)
t.fail()
})
})
test('Slapp.use()', t => {
let mw = () => {}
let app = new Slapp({ context })
t.is(app._middleware.length, 0)
app.use(mw)
t.is(app._middleware.length, 1)
t.deepEqual(app._middleware, [mw])
})
test('Slapp() convo_store string', t => {
let app = new Slapp({
context,
convo_store: 'memory'
})
t.is(typeof app.convoStore, 'object')
})
test('Slapp.init()', t => {
let app = new Slapp({ context })
app.init()
t.is(app._middleware.length, 2)
})
test('Slapp.init() w/ ignoreSelf false', t => {
let app = new Slapp({ context, ignoreSelf: false })
app.init()
t.is(app._middleware.length, 1)
})
test('Slapp.init() w/ ignoreBots true', t => {
let app = new Slapp({ context, ignoreBots: true })
app.init()
t.is(app._middleware.length, 3)
})
test('Slapp.attachToExpress()', t => {
let app = new Slapp({ context })
let stub = sinon.stub(app.receiver, 'attachToExpress')
app.attachToExpress({})
t.true(stub.calledOnce)
})
test('Slapp.route()', t => {
let app = new Slapp({ context })
let key = 'routeKey'
let fn = () => {}
app.route(key, fn)
t.deepEqual(app._registry[key], fn)
})
test('Slapp.getRoute()', t => {
let app = new Slapp({ context })
let key = 'routeKey'
let fn = () => {}
app.route(key, fn)
t.deepEqual(app.getRoute(key), fn)
})
test('Slapp.match()', t => {
let app = new Slapp({ context })
let fn = () => {}
t.is(app._matchers.length, 0)
app.match(fn)
t.is(app._matchers.length, 1)
t.deepEqual(app._matchers, [fn])
})
test.cb('Slapp._handle() w/ a bad message', t => {
t.plan(2)
let app = new Slapp({ context })
let message = new Message('event', {}, {})
let emitSpy = sinon.stub(app, 'emit')
app._handle(message, (err) => {
t.is(err, null)
t.true(emitSpy.calledWith('error'))
t.end()
})
})
test.cb('Slapp._handle() 1 mw, no override, no matchers', t => {
t.plan(4)
let app = new Slapp({ context })
let message = new Message('event', {}, meta)
let attachSlappStub = sinon.stub(message, 'attachSlapp')
app.use((msg, next) => {
t.deepEqual(msg, message)
next()
})
app._handle(message, (err, handled) => {
t.true(attachSlappStub.calledOnce)
t.is(err, null)
t.false(handled)
t.end()
})
})
test('Slapp._handle() no callback provided', t => {
let app = new Slapp({ context })
let message = new Message('event', {}, meta)
let attachSlappStub = sinon.stub(message, 'attachSlapp')
app._handle(message)
t.true(attachSlappStub.calledOnce)
})
test.cb('Slapp._handle() 1 mw, no override, 1 matchers', t => {
t.plan(4)
let app = new Slapp({ context })
let message = new Message('event', {}, meta)
let attachSlappStub = sinon.stub(message, 'attachSlapp')
app
.use((msg, next) => {
t.deepEqual(msg, message)
next()
})
.match((msg) => {
return true
})
app._handle(message, (err, handled) => {
t.true(attachSlappStub.calledOnce)
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp._handle() no mw, with override, no matchers', t => {
t.plan(5)
let app = new Slapp({ context })
let message = new Message('event', {}, meta)
message.override = (msg) => {
t.deepEqual(msg, message)
}
let attachSlappStub = sinon.stub(message, 'attachSlapp')
let delSpy = sinon.spy(app.convoStore, 'del')
app._handle(message, (err, handled) => {
t.true(attachSlappStub.calledOnce)
t.is(err, null)
t.true(handled)
t.true(delSpy.calledWith(message.conversation_id))
t.end()
})
})
test.cb('Slapp._handle() with override and del error', t => {
t.plan(6)
let app = new Slapp({ context })
let message = new Message('event', {}, meta)
message.conversation_id = 'asdf'
message.override = (msg) => {
t.deepEqual(msg, message)
}
let attachSlappStub = sinon.stub(message, 'attachSlapp')
let emitSpy = sinon.stub(app, 'emit')
let delStub = sinon.stub(app.convoStore, 'del', (id, cb) => {
cb(new Error('kaboom'))
})
app._handle(message, (err, handled) => {
t.true(attachSlappStub.calledOnce)
t.is(err.message, 'kaboom')
t.true(handled)
t.true(delStub.calledWith(message.conversation_id))
t.true(emitSpy.calledWith('error'))
t.end()
})
})
test.cb('Slapp._handle() w/ attached response', t => {
t.plan(2)
let app = new Slapp({ context })
let message = new Message('event', {}, meta)
let res = fixtures.getMockRes()
message.attachResponse(res, 100)
let clearResponseStub = sinon.stub(message, 'clearResponse')
app._handle(message, (err) => {
t.is(err, null)
t.true(clearResponseStub.calledOnce)
t.end()
})
})
test.cb('Slapp.command() w/o criteria', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('command', {
command: 'test'
}, meta)
app
.command(message.body.command, (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.command() w/ command regex', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('command', {
command: '/test',
text: 'hello'
}, meta)
app
.command(/\/tes.*/, /llo$/, (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.command() w/ command string regex', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('command', {
command: '/test',
text: 'hello'
}, meta)
app
.command('/tes.*', /llo$/, (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.command() w/ command string regex and redundant ^$', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('command', {
command: '/test',
text: 'hello'
}, meta)
app
.command('^^/test$$', /llo$/, (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.command() w/ criteria string', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('command', {
command: 'test',
text: 'hello'
}, meta)
app
.command(message.body.command, 'hel', (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.command() w/ criteria regex', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('command', {
command: 'test',
text: 'hello'
}, meta)
app
.command(message.body.command, /llo$/, (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.command() w/ criteria matcher', t => {
t.plan(6)
let app = new Slapp({ context })
let message = new Message('command', {
command: 'test',
text: 'one two'
}, meta)
app
.command(message.body.command, '([oO]ne) ([tT]wo)', (msg, text, match1, match2) => {
t.deepEqual(msg, message)
t.is(text, message.body.text)
t.is(match1, 'one')
t.is(match2, 'two')
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.command() w/ non-matching string criteria', t => {
t.plan(2)
let app = new Slapp({ context })
let message = new Message('command', {
command: 'test',
text: 'hello'
}, meta)
app
.command(message.body.command, 'derp', () => {})
._handle(message, (err, handled) => {
t.is(err, null)
t.false(handled)
t.end()
})
})
test.cb('Slapp.command() w/ non-matching regex criteria', t => {
t.plan(2)
let app = new Slapp({ context })
let message = new Message('command', {
command: 'test',
text: 'hello'
}, meta)
app
.command(message.body.command, /^derp$/, () => {})
._handle(message, (err, handled) => {
t.is(err, null)
t.false(handled)
t.end()
})
})
test.cb('Slapp.action() non-matching no actions', t => {
t.plan(2)
let app = new Slapp({ context })
let message = new Message('action', {
callback_id: 'my_callback',
command: 'test'
}, meta)
app
.action(message.body.callback_id, (msg) => {})
._handle(message, (err, handled) => {
t.is(err, null)
t.false(handled)
t.end()
})
})
test.cb('Slapp.action() non-matching criteria', t => {
t.plan(2)
let app = new Slapp({ context })
let message = new Message('action', {
actions: [
{ name: 'beep' }
],
callback_id: 'my_callback',
command: 'test'
}, meta)
app
.action('mismatch', (msg) => { })
._handle(message, (err, handled) => {
t.is(err, null)
t.false(handled)
t.end()
})
})
test.cb('Slapp.action() w/o criteria', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('action', {
actions: [
{ name: 'beep' }
],
callback_id: 'my_callback',
command: 'test'
}, meta)
app
.action(message.body.callback_id, (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.action() w/ name criteria string', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('action', {
actions: [
{ name: 'beep' }
],
callback_id: 'my_callback',
command: 'test'
}, meta)
app
.action(message.body.callback_id, 'beep', (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.action() w/ name and value criteria string', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('action', {
actions: [
{ name: 'beep', value: 'boop' }
],
callback_id: 'my_callback',
command: 'test'
}, meta)
app
.action(message.body.callback_id, 'beep', 'boop', (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.action() w/ name and value criteria regex', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('action', {
actions: [
{ name: 'beep', value: 'Boop' }
],
callback_id: 'my_callback',
command: 'test'
}, meta)
app
.action(message.body.callback_id, /^beep.*/, /B[o]{2}p/, (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.action() w/ non-matching criteria', t => {
t.plan(2)
let app = new Slapp({ context })
let message = new Message('action', {
actions: [
{ name: 'beep' }
],
callback_id: 'my_callback',
command: 'test'
}, meta)
app
.action(message.body.callback_id, 'boop', () => {})
._handle(message, (err, handled) => {
t.is(err, null)
t.false(handled)
t.end()
})
})
test.cb('Slapp.action() w/ selected_options', t => {
t.plan(5)
let app = new Slapp({ context })
let message = new Message('action', {
actions: [
{ name: 'beep', selected_options: [{ value: 'no match' }, { value: 'Boop' }] }
],
callback_id: 'my_callback'
}, meta)
app
.action(message.body.callback_id, /^beep.*/, /B[o]{2}p/, (msg, val) => {
t.deepEqual(msg, message)
t.true(Array.isArray(val))
t.deepEqual(val, ['no match', 'Boop'])
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.action() w/ selected_options no matches', t => {
t.plan(2)
let app = new Slapp({ context })
let message = new Message('action', {
actions: [
{ name: 'beep', selected_options: [{ value: 'no match' }] }
],
callback_id: 'my_callback'
}, meta)
app
.action(message.body.callback_id, /^beep.*/, /B[o]{2}p/, (msg, val) => {})
._handle(message, (err, handled) => {
t.is(err, null)
t.false(handled)
t.end()
})
})
test.cb('Slapp.action() w/ callback URL', t => {
t.plan(5)
let app = new Slapp({ context })
let callbackIdCriteria = '/account/:one/:two'
let message = new Message('action', {
actions: [
{ name: 'beep', value: 'boop' }
],
callback_id: '/account/foo/bar',
command: 'test'
}, meta)
app
.action(callbackIdCriteria, (msg) => {
t.deepEqual(msg, message)
t.is(msg.meta.params.one, 'foo')
t.is(msg.meta.params.two, 'bar')
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.action() w/ callback URL with large encoded value', t => {
t.plan(5)
let app = new Slapp({ context })
let longValue = 'long with spaces ?/:¡™£¢∞§¶•ªº–:{"x:":"y"}'
let longValueEncoded = encodeURIComponent(longValue)
let callbackIdCriteria = '/account/:one/:two'
let message = new Message('action', {
actions: [
{ name: 'beep', value: 'boop' }
],
callback_id: `/account/foo/${longValueEncoded}`,
command: 'test'
}, meta)
app
.action(callbackIdCriteria, (msg) => {
t.deepEqual(msg, message)
t.is(msg.meta.params.one, 'foo')
t.is(msg.meta.params.two, longValueEncoded)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.messageAction() w/ no match not message_action', t => {
t.plan(2)
let app = new Slapp({ context })
let message = new Message('action', {
type: 'not_message_action',
callback_id: 'my_callback'
}, meta)
app
.messageAction(message.body.callback_id, (msg, messageParsed) => { })
._handle(message, (err, handled) => {
t.is(err, null)
t.false(handled)
t.end()
})
})
test.cb('Slapp.messageAction() w/ no match on callback_id', t => {
t.plan(2)
let app = new Slapp({ context })
let message = new Message('action', {
type: 'message_action',
callback_id: 'my_callback'
}, meta)
app
.messageAction('no_match', (msg, messageParsed) => {
t.fail('messageAction should not be called when no match')
})
._handle(message, (err, handled) => {
t.is(err, null)
t.false(handled)
t.end()
})
})
test.cb('Slapp.messageAction() w/ match', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('action', {
type: 'message_action',
callback_id: 'my_callback',
message: {
ts: 'ts'
}
}, meta)
app
.messageAction(message.body.callback_id, (msg, messageParsed) => {
t.deepEqual(message.body.message, messageParsed)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.message() w/o filter', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('event', {
event: {
type: 'message',
text: 'beep boop'
}
}, meta)
app
.message('beep', (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.message() w/ matchers', t => {
t.plan(6)
let app = new Slapp({ context })
let message = new Message('event', {
event: {
type: 'message',
text: 'beep one Two'
}
}, meta)
app
.message('beep ([oO]ne) ([tT]wo)', (msg, text, match1, match2) => {
t.deepEqual(msg, message)
t.is(text, 'beep one Two')
t.is(match1, 'one')
t.is(match2, 'Two')
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.message() w/ filter', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('event', {
event: {
type: 'message',
text: 'beep boop'
}
}, meta)
app
.message('beep', 'ambient', (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.event() w/ string criteria', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('event', {
event: {
type: 'message',
text: 'beep boop'
}
}, meta)
app
.event('message', (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.event() w/ regex criteria', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('event', {
event: {
type: 'message',
text: 'beep boop'
}
}, meta)
app
.event(/^mess/, (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp._handle() w/ init()', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('event', {
event: {
type: 'message',
text: 'beep boop'
}
}, meta)
app
.init()
.event('message', (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.ignoreBotsMiddleware() with bot_message and bot_id', t => {
let app = new Slapp({ context })
let mw = app.ignoreBotsMiddleware()
let message = new Message('event', {
event: {
type: 'message',
subtype: 'bot_message'
}
}, {
bot_id: 'asdf'
})
// this callback is synchronous
mw(message, () => {
t.fail()
})
t.pass()
t.end()
})
test.cb('Slapp.ignoreBotsMiddleware() with bot_message no bot_id', t => {
let app = new Slapp({ context })
let mw = app.ignoreBotsMiddleware()
let message = new Message('event', {
event: {
type: 'message',
subtype: 'bot_message'
}
}, {})
// this callback is synchronous
mw(message, () => {
t.pass()
t.end()
})
})
test.cb('Slapp.ignoreBotsMiddleware() w/o bot message', t => {
let app = new Slapp({ context })
let mw = app.ignoreBotsMiddleware()
let message = new Message('event', {}, meta)
// this callback is synchronous
mw(message, () => {
t.pass()
t.end()
})
})
test.cb('Slapp.ignoreSelfMiddleware() with bot_message and matching bot_id', t => {
let app = new Slapp({ context })
let mw = app.ignoreSelfMiddleware()
let message = new Message('event', {
event: {
type: 'message',
subtype: 'bot_message'
}
}, {
bot_id: 'app_bot_id',
app_bot_id: 'app_bot_id'
})
// this callback is synchronous
mw(message, () => {
t.fail()
})
t.pass()
t.end()
})
test.cb('Slapp.ignoreSelfMiddleware() with bot_message and non-matching bot_id', t => {
let app = new Slapp({ context })
let mw = app.ignoreSelfMiddleware()
let message = new Message('event', {
event: {
type: 'message',
subtype: 'bot_message'
}
}, {
bot_id: 'other_bot_id',
app_bot_id: 'app_bot_id'
})
// this callback is synchronous
mw(message, () => {
t.pass()
t.end()
})
})
test.cb('Slapp.ignoreSelfMiddleware() without bot_message', t => {
let app = new Slapp({ context })
let mw = app.ignoreSelfMiddleware()
let message = new Message('event', {
event: {
type: 'message'
}
}, {
app_bot_id: 'app_bot_id'
})
// this callback is synchronous
mw(message, () => {
t.pass()
t.end()
})
})
test.cb('Slapp.ignoreSelfMiddleware() both ids falsey', t => {
let app = new Slapp({ context })
let mw = app.ignoreSelfMiddleware()
let message = new Message('event', {
event: {
type: 'message',
subtype: 'bot_message'
}
}, {
bot_id: null,
app_bot_id: null
})
// this callback is synchronous
mw(message, () => {
t.pass()
t.end()
})
})
test.cb('Slapp.ignoreSelfMiddleware() one id falsey', t => {
let app = new Slapp({ context })
let mw = app.ignoreSelfMiddleware()
let message = new Message('event', {
event: {
type: 'message',
subtype: 'bot_message'
}
}, {
bot_id: 'bot_id',
app_bot_id: null
})
// this callback is synchronous
mw(message, () => {
t.pass()
t.end()
})
})
test.cb('Slapp.preprocessConversationMiddleware() w/ conversation', t => {
t.plan(3)
let app = new Slapp({ context })
let mw = app.preprocessConversationMiddleware()
let message = new Message('event', {}, meta)
message.conversation_id = 'convo_id'
let convo = {
fnKey: 'next-route',
state: {
beep: 'boop'
}
}
let overrideStub = sinon.stub(message, 'attachOverrideRoute')
let getStub = sinon.stub(app.convoStore, 'get', (id, cb) => {
t.is(id, message.conversation_id)
cb(null, convo)
})
mw(message, () => {
t.true(overrideStub.calledWith(convo.fnKey, convo.state))
t.true(getStub.calledOnce)
t.end()
})
})
test.cb('Slapp.preprocessConversationMiddleware() w/o conversation', t => {
t.plan(3)
let app = new Slapp({ context })
let mw = app.preprocessConversationMiddleware()
let message = new Message('event', {}, meta)
message.conversation_id = 'convo_id'
let overrideStub = sinon.stub(message, 'attachOverrideRoute')
let getStub = sinon.stub(app.convoStore, 'get', (id, cb) => {
t.is(id, message.conversation_id)
cb(null, null)
})
mw(message, () => {
t.false(overrideStub.called)
t.true(getStub.calledOnce)
t.end()
})
})
test.cb('Slapp.preprocessConversationMiddleware() w/ error', t => {
t.plan(4)
let app = new Slapp({ context })
let mw = app.preprocessConversationMiddleware()
let message = new Message('event', {}, meta)
message.conversation_id = 'convo_id'
let emitSpy = sinon.stub(app, 'emit')
let overrideStub = sinon.stub(message, 'attachOverrideRoute')
let getStub = sinon.stub(app.convoStore, 'get', (id, cb) => {
t.is(id, message.conversation_id)
cb(new Error('kaboom'))
})
mw(message, () => t.fail())
t.false(overrideStub.called)
t.true(getStub.calledOnce)
t.true(emitSpy.calledWith('error'))
t.end()
})
test.cb('Slapp.options() w/ callback_id only', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('options', {
callback_id: 'my_callback'
}, meta)
app
.options('my_callback', (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.options() w/ string criteria', t => {
t.plan(4)
let app = new Slapp({ context })
let message = new Message('options', {
name: 'my_name',
value: 'my_value',
callback_id: 'my_callback'
}, meta)
app
.options('my_callback', 'my_name', (msg, val) => {
t.deepEqual(msg, message)
t.is(val, 'my_value')
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.options() w/ regex criteria', t => {
t.plan(3)
let app = new Slapp({ context })
let message = new Message('options', {
name: 'my_name',
callback_id: 'my_callback'
}, meta)
app
.options('my_callback', /^my_n.*/, (msg) => {
t.deepEqual(msg, message)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.options() w/ url style callback criteria', t => {
t.plan(4)
let app = new Slapp({ context })
let message = new Message('options', {
callback_id: '/my_callback/1234'
}, meta)
app
.options('/my_callback/:id', (msg, val) => {
t.deepEqual(msg, message)
t.is(msg.meta.params.id, '1234')
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.options() non matching criteria', t => {
t.plan(4)
let app = new Slapp({ context })
let message = new Message('options', {
callback_id: '/my_callback'
}, meta)
app
.options('/your_callback', (msg, val) => {})
._handle(message, (err, handled) => {
t.is(err, null)
t.false(handled)
})
._handle(new Message('', {}, meta), (err, handled) => {
t.is(err, null)
t.false(handled)
t.end()
})
})
test.cb('Slapp.dialog()', t => {
t.plan(5)
let app = new Slapp({ context })
let submission = {
question: 'answer',
another: 'another'
}
let message = new Message('action', {
type: 'dialog_submission',
submission: submission,
callback_id: '/dialog/12345'
}, meta)
app
.dialog('/dialog/:id', (msg, theSubmission) => {
t.deepEqual(msg, message)
t.deepEqual(submission, theSubmission)
t.is('12345', msg.meta.params.id)
})
._handle(message, (err, handled) => {
t.is(err, null)
t.true(handled)
t.end()
})
})
test.cb('Slapp.dialog() no match', t => {
t.plan(2)
let app = new Slapp({ context })
let message = new Message('action', {
type: 'dialog_submission',
submission: {},
callback_id: '/xxxx/xxxx'
}, meta)
app
.dialog('/dialog/:id', (msg, theSubmission) => {})
._handle(message, (err, handled) => {
t.is(err, null)
t.false(handled)
t.end()
})
})
test.cb('Slapp.dialog() not action, not dialog_submission', t => {
t.plan(4)
let app = new Slapp({ context })
app
.dialog('/dialog/:id', (msg, theSubmission) => { })
._handle(new Message('', {}, meta), (err, handled) => {
t.is(err, null)
t.false(handled)
})
._handle(new Message('action', {}, meta), (err, handled) => {
t.is(err, null)
t.false(handled)
t.end()
})
})
test('Slapp default logger', t => {
let app = new Slapp({ context })
app.init()
t.is(app.listenerCount('info'), 1)
t.is(app.listenerCount('error'), 1)
})
test('Slapp custom logger', t => {
const logger = (app) => {
app
.on('info', () => {})
.on('error', () => {})
}
let app = new Slapp({
logger,
context
})
app.init()
t.is(app.listenerCount('info'), 1)
t.is(app.listenerCount('error'), 1)
})
test.cb('Slapp custom logger w/ a message', t => {
t.plan(1)
let app = new Slapp({
logger: (app) => {
app
.on('info', (msg) => {
t.true(true)
t.end()
})
},
context
})
app.init()
let message = new Message('event', {
event: {
type: 'message',
text: 'beep boop'
}
}, meta)
app
._handle(message)
})
test.cb('Slapp custom logger w/ a bad message', t => {
t.plan(1)
let app = new Slapp({
logger: (app) => {
app
.on('error', () => {
t.true(true)
t.end()
})
},
context
})
app.init()
let message = new Message('event', {}, {})
app._handle(message)
})
// Test context fn
function context (req, res, next) {
next()
}