hubot 5.0.4 → 5.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/robot.js +0 -11
- package/.editorconfig +0 -14
- package/.github/stale.yml +0 -23
- package/.github/workflows/nodejs-macos.yml +0 -26
- package/.github/workflows/nodejs-ubuntu.yml +0 -28
- package/.github/workflows/nodejs-windows.yml +0 -26
- package/.github/workflows/release.yml +0 -37
- package/bin/e2e-test.sh +0 -47
- package/docs/adapters/campfire.md +0 -79
- package/docs/adapters/development.md +0 -125
- package/docs/adapters/shell.md +0 -24
- package/docs/adapters.md +0 -27
- package/docs/deploying/azure.md +0 -97
- package/docs/deploying/bluemix.md +0 -111
- package/docs/deploying/heroku.md +0 -66
- package/docs/deploying/unix.md +0 -72
- package/docs/deploying/windows.md +0 -66
- package/docs/deploying.md +0 -11
- package/docs/implementation.md +0 -55
- package/docs/index.md +0 -125
- package/docs/patterns.md +0 -265
- package/docs/scripting.md +0 -1051
- package/examples/hubot-start.ps1 +0 -12
- package/examples/hubot.service +0 -27
- package/script/bootstrap +0 -3
- package/script/release +0 -44
- package/script/server +0 -3
- package/script/smoke-test +0 -3
- package/script/test +0 -3
- package/test/adapter_test.js +0 -97
- package/test/brain_test.js +0 -336
- package/test/datastore_test.js +0 -154
- package/test/es2015_test.js +0 -199
- package/test/fixtures/MockAdapter.coffee +0 -10
- package/test/fixtures/MockAdapter.mjs +0 -43
- package/test/fixtures/TestScript.coffee +0 -9
- package/test/fixtures/TestScript.js +0 -13
- package/test/fixtures/mock-adapter.js +0 -35
- package/test/listener_test.js +0 -379
- package/test/message_test.js +0 -46
- package/test/middleware_test.js +0 -507
- package/test/robot_test.js +0 -1153
- package/test/shell_test.js +0 -73
- package/test/user_test.js +0 -29
package/test/robot_test.js
DELETED
|
@@ -1,1153 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/* global describe, beforeEach, it, afterEach */
|
|
4
|
-
/* eslint-disable no-unused-expressions */
|
|
5
|
-
|
|
6
|
-
// Assertions and Stubbing
|
|
7
|
-
const chai = require('chai')
|
|
8
|
-
const sinon = require('sinon')
|
|
9
|
-
chai.use(require('sinon-chai'))
|
|
10
|
-
|
|
11
|
-
const expect = chai.expect
|
|
12
|
-
|
|
13
|
-
// Hubot classes
|
|
14
|
-
const Robot = require('../src/robot')
|
|
15
|
-
const CatchAllMessage = require('../src/message').CatchAllMessage
|
|
16
|
-
const EnterMessage = require('../src/message').EnterMessage
|
|
17
|
-
const LeaveMessage = require('../src/message').LeaveMessage
|
|
18
|
-
const TextMessage = require('../src/message').TextMessage
|
|
19
|
-
const TopicMessage = require('../src/message').TopicMessage
|
|
20
|
-
|
|
21
|
-
// mock `hubot-mock-adapter` module from fixture
|
|
22
|
-
const mockery = require('mockery')
|
|
23
|
-
const path = require('path')
|
|
24
|
-
|
|
25
|
-
describe('Robot', function () {
|
|
26
|
-
beforeEach(async function () {
|
|
27
|
-
mockery.enable({
|
|
28
|
-
warnOnReplace: false,
|
|
29
|
-
warnOnUnregistered: false
|
|
30
|
-
})
|
|
31
|
-
mockery.registerMock('hubot-mock-adapter', require('./fixtures/mock-adapter.js'))
|
|
32
|
-
process.env.EXPRESS_PORT = 0
|
|
33
|
-
this.robot = new Robot('mock-adapter', true, 'TestHubot')
|
|
34
|
-
this.robot.alias = 'Hubot'
|
|
35
|
-
await this.robot.loadAdapter()
|
|
36
|
-
this.robot.run()
|
|
37
|
-
|
|
38
|
-
// Re-throw AssertionErrors for clearer test failures
|
|
39
|
-
this.robot.on('error', function (name, err, response) {
|
|
40
|
-
if (err?.constructor.name === 'AssertionError' || name instanceof chai.AssertionError) {
|
|
41
|
-
process.nextTick(function () {
|
|
42
|
-
throw err
|
|
43
|
-
})
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
this.user = this.robot.brain.userForId('1', {
|
|
48
|
-
name: 'hubottester',
|
|
49
|
-
room: '#mocha'
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
afterEach(function () {
|
|
54
|
-
mockery.disable()
|
|
55
|
-
this.robot.shutdown()
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
describe('Unit Tests', function () {
|
|
59
|
-
describe('#http', function () {
|
|
60
|
-
beforeEach(function () {
|
|
61
|
-
const url = 'http://localhost'
|
|
62
|
-
this.httpClient = this.robot.http(url)
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('creates a new ScopedHttpClient', function () {
|
|
66
|
-
// 'instanceOf' check doesn't work here due to the design of
|
|
67
|
-
// ScopedHttpClient
|
|
68
|
-
expect(this.httpClient).to.have.property('get')
|
|
69
|
-
expect(this.httpClient).to.have.property('post')
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('passes options through to the ScopedHttpClient', function () {
|
|
73
|
-
const agent = {}
|
|
74
|
-
const httpClient = this.robot.http('http://localhost', { agent })
|
|
75
|
-
expect(httpClient.options.agent).to.equal(agent)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
it('sets a sane user agent', function () {
|
|
79
|
-
expect(this.httpClient.options.headers['User-Agent']).to.contain('Hubot')
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it('merges in any global http options', function () {
|
|
83
|
-
const agent = {}
|
|
84
|
-
this.robot.globalHttpOptions = { agent }
|
|
85
|
-
const httpClient = this.robot.http('http://localhost')
|
|
86
|
-
expect(httpClient.options.agent).to.equal(agent)
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
it('local options override global http options', function () {
|
|
90
|
-
const agentA = {}
|
|
91
|
-
const agentB = {}
|
|
92
|
-
this.robot.globalHttpOptions = { agent: agentA }
|
|
93
|
-
const httpClient = this.robot.http('http://localhost', { agent: agentB })
|
|
94
|
-
expect(httpClient.options.agent).to.equal(agentB)
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
it('builds the url correctly from a string', function () {
|
|
98
|
-
const options = this.httpClient.buildOptions('http://localhost:3001')
|
|
99
|
-
expect(options.host).to.equal('localhost:3001')
|
|
100
|
-
expect(options.pathname).to.equal('/')
|
|
101
|
-
expect(options.protocol).to.equal('http:')
|
|
102
|
-
expect(options.port).to.equal('3001')
|
|
103
|
-
})
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
describe('#respondPattern', function () {
|
|
107
|
-
it('matches messages starting with robot\'s name', function () {
|
|
108
|
-
const testMessage = this.robot.name + 'message123'
|
|
109
|
-
const testRegex = /(.*)/
|
|
110
|
-
|
|
111
|
-
const pattern = this.robot.respondPattern(testRegex)
|
|
112
|
-
expect(testMessage).to.match(pattern)
|
|
113
|
-
const match = testMessage.match(pattern)[1]
|
|
114
|
-
expect(match).to.equal('message123')
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
it('matches messages starting with robot\'s alias', function () {
|
|
118
|
-
const testMessage = this.robot.alias + 'message123'
|
|
119
|
-
const testRegex = /(.*)/
|
|
120
|
-
|
|
121
|
-
const pattern = this.robot.respondPattern(testRegex)
|
|
122
|
-
expect(testMessage).to.match(pattern)
|
|
123
|
-
const match = testMessage.match(pattern)[1]
|
|
124
|
-
expect(match).to.equal('message123')
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('does not match unaddressed messages', function () {
|
|
128
|
-
const testMessage = 'message123'
|
|
129
|
-
const testRegex = /(.*)/
|
|
130
|
-
|
|
131
|
-
const pattern = this.robot.respondPattern(testRegex)
|
|
132
|
-
expect(testMessage).to.not.match(pattern)
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
it('matches properly when name is substring of alias', function () {
|
|
136
|
-
this.robot.name = 'Meg'
|
|
137
|
-
this.robot.alias = 'Megan'
|
|
138
|
-
const testMessage1 = this.robot.name + ' message123'
|
|
139
|
-
const testMessage2 = this.robot.alias + ' message123'
|
|
140
|
-
const testRegex = /(.*)/
|
|
141
|
-
|
|
142
|
-
const pattern = this.robot.respondPattern(testRegex)
|
|
143
|
-
|
|
144
|
-
expect(testMessage1).to.match(pattern)
|
|
145
|
-
const match1 = testMessage1.match(pattern)[1]
|
|
146
|
-
expect(match1).to.equal('message123')
|
|
147
|
-
|
|
148
|
-
expect(testMessage2).to.match(pattern)
|
|
149
|
-
const match2 = testMessage2.match(pattern)[1]
|
|
150
|
-
expect(match2).to.equal('message123')
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
it('matches properly when alias is substring of name', function () {
|
|
154
|
-
this.robot.name = 'Megan'
|
|
155
|
-
this.robot.alias = 'Meg'
|
|
156
|
-
const testMessage1 = this.robot.name + ' message123'
|
|
157
|
-
const testMessage2 = this.robot.alias + ' message123'
|
|
158
|
-
const testRegex = /(.*)/
|
|
159
|
-
|
|
160
|
-
const pattern = this.robot.respondPattern(testRegex)
|
|
161
|
-
|
|
162
|
-
expect(testMessage1).to.match(pattern)
|
|
163
|
-
const match1 = testMessage1.match(pattern)[1]
|
|
164
|
-
expect(match1).to.equal('message123')
|
|
165
|
-
|
|
166
|
-
expect(testMessage2).to.match(pattern)
|
|
167
|
-
const match2 = testMessage2.match(pattern)[1]
|
|
168
|
-
expect(match2).to.equal('message123')
|
|
169
|
-
})
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
describe('#listen', () =>
|
|
173
|
-
it('registers a new listener directly', function () {
|
|
174
|
-
expect(this.robot.listeners).to.have.length(0)
|
|
175
|
-
this.robot.listen(function () {}, function () {})
|
|
176
|
-
expect(this.robot.listeners).to.have.length(1)
|
|
177
|
-
})
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
describe('#hear', () =>
|
|
181
|
-
it('registers a new listener directly', function () {
|
|
182
|
-
expect(this.robot.listeners).to.have.length(0)
|
|
183
|
-
this.robot.hear(/.*/, function () {})
|
|
184
|
-
expect(this.robot.listeners).to.have.length(1)
|
|
185
|
-
})
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
describe('#respond', () =>
|
|
189
|
-
it('registers a new listener using hear', function () {
|
|
190
|
-
sinon.spy(this.robot, 'hear')
|
|
191
|
-
this.robot.respond(/.*/, function () {})
|
|
192
|
-
expect(this.robot.hear).to.have.been.called
|
|
193
|
-
})
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
describe('#enter', () =>
|
|
197
|
-
it('registers a new listener using listen', function () {
|
|
198
|
-
sinon.spy(this.robot, 'listen')
|
|
199
|
-
this.robot.enter(function () {})
|
|
200
|
-
expect(this.robot.listen).to.have.been.called
|
|
201
|
-
})
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
describe('#leave', () =>
|
|
205
|
-
it('registers a new listener using listen', function () {
|
|
206
|
-
sinon.spy(this.robot, 'listen')
|
|
207
|
-
this.robot.leave(function () {})
|
|
208
|
-
expect(this.robot.listen).to.have.been.called
|
|
209
|
-
})
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
describe('#topic', () =>
|
|
213
|
-
it('registers a new listener using listen', function () {
|
|
214
|
-
sinon.spy(this.robot, 'listen')
|
|
215
|
-
this.robot.topic(function () {})
|
|
216
|
-
expect(this.robot.listen).to.have.been.called
|
|
217
|
-
})
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
describe('#catchAll', () =>
|
|
221
|
-
it('registers a new listener using listen', function () {
|
|
222
|
-
sinon.spy(this.robot, 'listen')
|
|
223
|
-
this.robot.catchAll(function () {})
|
|
224
|
-
expect(this.robot.listen).to.have.been.called
|
|
225
|
-
})
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
describe('#receive', function () {
|
|
229
|
-
it('calls all registered listeners', function (done) {
|
|
230
|
-
// Need to use a real Message so that the CatchAllMessage constructor works
|
|
231
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
232
|
-
|
|
233
|
-
const listener = {
|
|
234
|
-
call (response, middleware, cb) {
|
|
235
|
-
cb()
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
sinon.spy(listener, 'call')
|
|
239
|
-
|
|
240
|
-
this.robot.listeners = [
|
|
241
|
-
listener,
|
|
242
|
-
listener,
|
|
243
|
-
listener,
|
|
244
|
-
listener
|
|
245
|
-
]
|
|
246
|
-
|
|
247
|
-
this.robot.receive(testMessage, function () {
|
|
248
|
-
// When no listeners match, each listener is called twice: once with
|
|
249
|
-
// the original message and once with a CatchAll message
|
|
250
|
-
expect(listener.call).to.have.callCount(8)
|
|
251
|
-
done()
|
|
252
|
-
})
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
it('sends a CatchAllMessage if no listener matches', function (done) {
|
|
256
|
-
// Testing for recursion with a new CatchAllMessage that wraps the
|
|
257
|
-
// original message
|
|
258
|
-
|
|
259
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
260
|
-
this.robot.listeners = []
|
|
261
|
-
|
|
262
|
-
// Replace @robot.receive so we can catch when the functions recurses
|
|
263
|
-
const oldReceive = this.robot.receive
|
|
264
|
-
this.robot.receive = function (message, cb) {
|
|
265
|
-
expect(message).to.be.instanceof(CatchAllMessage)
|
|
266
|
-
expect(message.message).to.be.equal(testMessage)
|
|
267
|
-
cb()
|
|
268
|
-
}
|
|
269
|
-
sinon.spy(this.robot, 'receive')
|
|
270
|
-
|
|
271
|
-
// Call the original receive method that we want to test
|
|
272
|
-
oldReceive.call(this.robot, testMessage, () => {
|
|
273
|
-
expect(this.robot.receive).to.have.been.called
|
|
274
|
-
done()
|
|
275
|
-
})
|
|
276
|
-
})
|
|
277
|
-
|
|
278
|
-
it('does not trigger a CatchAllMessage if a listener matches', function (done) {
|
|
279
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
280
|
-
|
|
281
|
-
const matchingListener = {
|
|
282
|
-
call (message, middleware, doesMatch) {
|
|
283
|
-
// indicate that the message matched the listener
|
|
284
|
-
doesMatch(true)
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// Replace @robot.receive so we can catch if the functions recurses
|
|
289
|
-
const oldReceive = this.robot.receive
|
|
290
|
-
this.robot.receive = sinon.spy()
|
|
291
|
-
|
|
292
|
-
this.robot.listeners = [
|
|
293
|
-
matchingListener
|
|
294
|
-
]
|
|
295
|
-
|
|
296
|
-
// Call the original receive method that we want to test
|
|
297
|
-
oldReceive.call(this.robot, testMessage, done)
|
|
298
|
-
|
|
299
|
-
// Ensure the function did not recurse
|
|
300
|
-
expect(this.robot.receive).to.not.have.been.called
|
|
301
|
-
})
|
|
302
|
-
|
|
303
|
-
it('stops processing if a listener marks the message as done', function (done) {
|
|
304
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
305
|
-
|
|
306
|
-
const matchingListener = {
|
|
307
|
-
call (message, middleware, doesMatch) {
|
|
308
|
-
message.done = true
|
|
309
|
-
// Listener must have matched
|
|
310
|
-
doesMatch(true)
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
const listenerSpy =
|
|
315
|
-
{ call: sinon.spy() }
|
|
316
|
-
|
|
317
|
-
this.robot.listeners = [
|
|
318
|
-
matchingListener,
|
|
319
|
-
listenerSpy
|
|
320
|
-
]
|
|
321
|
-
|
|
322
|
-
this.robot.receive(testMessage, function () {
|
|
323
|
-
expect(listenerSpy.call).to.not.have.been.called
|
|
324
|
-
done()
|
|
325
|
-
})
|
|
326
|
-
})
|
|
327
|
-
|
|
328
|
-
it('gracefully handles listener uncaughtExceptions (move on to next listener)', function (done) {
|
|
329
|
-
const testMessage = {}
|
|
330
|
-
const theError = new Error()
|
|
331
|
-
|
|
332
|
-
const badListener = {
|
|
333
|
-
call () {
|
|
334
|
-
throw theError
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
let goodListenerCalled = false
|
|
339
|
-
const goodListener = {
|
|
340
|
-
call (_, middleware, doesMatch) {
|
|
341
|
-
goodListenerCalled = true
|
|
342
|
-
doesMatch(true)
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
this.robot.listeners = [
|
|
347
|
-
badListener,
|
|
348
|
-
goodListener
|
|
349
|
-
]
|
|
350
|
-
|
|
351
|
-
this.robot.emit = function (name, err, response) {
|
|
352
|
-
expect(name).to.equal('error')
|
|
353
|
-
expect(err).to.equal(theError)
|
|
354
|
-
expect(response.message).to.equal(testMessage)
|
|
355
|
-
}
|
|
356
|
-
sinon.spy(this.robot, 'emit')
|
|
357
|
-
|
|
358
|
-
this.robot.receive(testMessage, () => {
|
|
359
|
-
expect(this.robot.emit).to.have.been.called
|
|
360
|
-
expect(goodListenerCalled).to.be.ok
|
|
361
|
-
done()
|
|
362
|
-
})
|
|
363
|
-
})
|
|
364
|
-
|
|
365
|
-
it('executes the callback after the function returns when there are no listeners', function (done) {
|
|
366
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
367
|
-
let finished = false
|
|
368
|
-
this.robot.receive(testMessage, function () {
|
|
369
|
-
expect(finished).to.be.ok
|
|
370
|
-
done()
|
|
371
|
-
})
|
|
372
|
-
finished = true
|
|
373
|
-
})
|
|
374
|
-
})
|
|
375
|
-
|
|
376
|
-
describe('#loadFile', function () {
|
|
377
|
-
beforeEach(function () {
|
|
378
|
-
this.sandbox = sinon.createSandbox()
|
|
379
|
-
})
|
|
380
|
-
|
|
381
|
-
afterEach(function () {
|
|
382
|
-
this.sandbox.restore()
|
|
383
|
-
})
|
|
384
|
-
|
|
385
|
-
it('should require the specified file', function () {
|
|
386
|
-
const module = require('module')
|
|
387
|
-
|
|
388
|
-
const script = sinon.spy(function (robot) {})
|
|
389
|
-
this.sandbox.stub(module, '_load').returns(script)
|
|
390
|
-
this.sandbox.stub(this.robot, 'parseHelp')
|
|
391
|
-
|
|
392
|
-
this.robot.loadFile('./scripts', 'TestScript.js')
|
|
393
|
-
expect(module._load).to.have.been.calledWith(path.join('scripts', 'TestScript'))
|
|
394
|
-
})
|
|
395
|
-
|
|
396
|
-
describe('proper script', function () {
|
|
397
|
-
beforeEach(function () {
|
|
398
|
-
const module = require('module')
|
|
399
|
-
|
|
400
|
-
this.script = sinon.spy(function (robot) {})
|
|
401
|
-
this.sandbox.stub(module, '_load').returns(this.script)
|
|
402
|
-
this.sandbox.stub(this.robot, 'parseHelp')
|
|
403
|
-
})
|
|
404
|
-
|
|
405
|
-
it('should call the script with the Robot', function () {
|
|
406
|
-
this.robot.loadFile('./scripts', 'TestScript.js')
|
|
407
|
-
expect(this.script).to.have.been.calledWith(this.robot)
|
|
408
|
-
})
|
|
409
|
-
|
|
410
|
-
it('should parse the script documentation', function () {
|
|
411
|
-
this.robot.loadFile('./scripts', 'TestScript.js')
|
|
412
|
-
expect(this.robot.parseHelp).to.have.been.calledWith(path.join('scripts', 'TestScript.js'))
|
|
413
|
-
})
|
|
414
|
-
})
|
|
415
|
-
|
|
416
|
-
describe('non-Function script', function () {
|
|
417
|
-
beforeEach(function () {
|
|
418
|
-
const module = require('module')
|
|
419
|
-
|
|
420
|
-
this.script = {}
|
|
421
|
-
this.sandbox.stub(module, '_load').returns(this.script)
|
|
422
|
-
this.sandbox.stub(this.robot, 'parseHelp')
|
|
423
|
-
})
|
|
424
|
-
|
|
425
|
-
it('logs a warning for a .js file', function () {
|
|
426
|
-
sinon.stub(this.robot.logger, 'warning')
|
|
427
|
-
this.robot.loadFile('./scripts', 'TestScript.js')
|
|
428
|
-
expect(this.robot.logger.warning).to.have.been.called
|
|
429
|
-
})
|
|
430
|
-
|
|
431
|
-
it('logs a warning for a .mjs file', function () {
|
|
432
|
-
sinon.stub(this.robot.logger, 'warning')
|
|
433
|
-
this.robot.loadFile('./scripts', 'TestScript.mjs')
|
|
434
|
-
expect(this.robot.logger.warning).to.have.been.called
|
|
435
|
-
})
|
|
436
|
-
})
|
|
437
|
-
|
|
438
|
-
describe('unsupported file extension', function () {
|
|
439
|
-
beforeEach(function () {
|
|
440
|
-
const module = require('module')
|
|
441
|
-
|
|
442
|
-
this.script = sinon.spy(function (robot) {})
|
|
443
|
-
this.sandbox.stub(module, '_load').returns(this.script)
|
|
444
|
-
this.sandbox.stub(this.robot, 'parseHelp')
|
|
445
|
-
})
|
|
446
|
-
|
|
447
|
-
it('should not be loaded by the Robot', function () {
|
|
448
|
-
this.robot.loadFile('./scripts', 'unsupported.yml')
|
|
449
|
-
expect(this.script).to.not.have.been.calledWith(this.robot)
|
|
450
|
-
})
|
|
451
|
-
})
|
|
452
|
-
})
|
|
453
|
-
|
|
454
|
-
describe('#send', function () {
|
|
455
|
-
beforeEach(function () {
|
|
456
|
-
sinon.spy(this.robot.adapter, 'send')
|
|
457
|
-
})
|
|
458
|
-
|
|
459
|
-
it('delegates to adapter "send" with proper context', function () {
|
|
460
|
-
this.robot.send({}, 'test message')
|
|
461
|
-
expect(this.robot.adapter.send).to.have.been.calledOn(this.robot.adapter)
|
|
462
|
-
})
|
|
463
|
-
})
|
|
464
|
-
|
|
465
|
-
describe('#reply', function () {
|
|
466
|
-
beforeEach(function () {
|
|
467
|
-
sinon.spy(this.robot.adapter, 'reply')
|
|
468
|
-
})
|
|
469
|
-
|
|
470
|
-
it('delegates to adapter "reply" with proper context', function () {
|
|
471
|
-
this.robot.reply({}, 'test message')
|
|
472
|
-
expect(this.robot.adapter.reply).to.have.been.calledOn(this.robot.adapter)
|
|
473
|
-
})
|
|
474
|
-
})
|
|
475
|
-
|
|
476
|
-
describe('#messageRoom', function () {
|
|
477
|
-
beforeEach(function () {
|
|
478
|
-
sinon.spy(this.robot.adapter, 'send')
|
|
479
|
-
})
|
|
480
|
-
|
|
481
|
-
it('delegates to adapter "send" with proper context', function () {
|
|
482
|
-
this.robot.messageRoom('testRoom', 'messageRoom test')
|
|
483
|
-
expect(this.robot.adapter.send).to.have.been.calledOn(this.robot.adapter)
|
|
484
|
-
})
|
|
485
|
-
})
|
|
486
|
-
|
|
487
|
-
describe('#on', function () {
|
|
488
|
-
beforeEach(function () {
|
|
489
|
-
sinon.spy(this.robot.events, 'on')
|
|
490
|
-
})
|
|
491
|
-
|
|
492
|
-
it('delegates to events "on" with proper context', function () {
|
|
493
|
-
this.robot.on('event', function () {})
|
|
494
|
-
expect(this.robot.events.on).to.have.been.calledOn(this.robot.events)
|
|
495
|
-
})
|
|
496
|
-
})
|
|
497
|
-
|
|
498
|
-
describe('#emit', function () {
|
|
499
|
-
beforeEach(function () {
|
|
500
|
-
sinon.spy(this.robot.events, 'emit')
|
|
501
|
-
})
|
|
502
|
-
|
|
503
|
-
it('delegates to events "emit" with proper context', function () {
|
|
504
|
-
this.robot.emit('event', function () {})
|
|
505
|
-
expect(this.robot.events.emit).to.have.been.calledOn(this.robot.events)
|
|
506
|
-
})
|
|
507
|
-
})
|
|
508
|
-
})
|
|
509
|
-
|
|
510
|
-
describe('Listener Registration', function () {
|
|
511
|
-
describe('#listen', () =>
|
|
512
|
-
it('forwards the matcher, options, and callback to Listener', function () {
|
|
513
|
-
const callback = sinon.spy()
|
|
514
|
-
const matcher = sinon.spy()
|
|
515
|
-
const options = {}
|
|
516
|
-
|
|
517
|
-
this.robot.listen(matcher, options, callback)
|
|
518
|
-
const testListener = this.robot.listeners[0]
|
|
519
|
-
|
|
520
|
-
expect(testListener.matcher).to.equal(matcher)
|
|
521
|
-
expect(testListener.callback).to.equal(callback)
|
|
522
|
-
expect(testListener.options).to.equal(options)
|
|
523
|
-
})
|
|
524
|
-
)
|
|
525
|
-
|
|
526
|
-
describe('#hear', function () {
|
|
527
|
-
it('matches TextMessages', function () {
|
|
528
|
-
const callback = sinon.spy()
|
|
529
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
530
|
-
const testRegex = /^message123$/
|
|
531
|
-
|
|
532
|
-
this.robot.hear(testRegex, callback)
|
|
533
|
-
const testListener = this.robot.listeners[0]
|
|
534
|
-
const result = testListener.matcher(testMessage)
|
|
535
|
-
|
|
536
|
-
expect(result).to.be.ok
|
|
537
|
-
})
|
|
538
|
-
|
|
539
|
-
it('does not match EnterMessages', function () {
|
|
540
|
-
const callback = sinon.spy()
|
|
541
|
-
const testMessage = new EnterMessage(this.user)
|
|
542
|
-
const testRegex = /.*/
|
|
543
|
-
|
|
544
|
-
this.robot.hear(testRegex, callback)
|
|
545
|
-
const testListener = this.robot.listeners[0]
|
|
546
|
-
const result = testListener.matcher(testMessage)
|
|
547
|
-
|
|
548
|
-
expect(result).to.not.be.ok
|
|
549
|
-
})
|
|
550
|
-
})
|
|
551
|
-
|
|
552
|
-
describe('#respond', function () {
|
|
553
|
-
it('matches TextMessages addressed to the robot', function () {
|
|
554
|
-
const callback = sinon.spy()
|
|
555
|
-
const testMessage = new TextMessage(this.user, 'TestHubot message123')
|
|
556
|
-
const testRegex = /message123$/
|
|
557
|
-
|
|
558
|
-
this.robot.respond(testRegex, callback)
|
|
559
|
-
const testListener = this.robot.listeners[0]
|
|
560
|
-
const result = testListener.matcher(testMessage)
|
|
561
|
-
|
|
562
|
-
expect(result).to.be.ok
|
|
563
|
-
})
|
|
564
|
-
|
|
565
|
-
it('does not match EnterMessages', function () {
|
|
566
|
-
const callback = sinon.spy()
|
|
567
|
-
const testMessage = new EnterMessage(this.user)
|
|
568
|
-
const testRegex = /.*/
|
|
569
|
-
|
|
570
|
-
this.robot.respond(testRegex, callback)
|
|
571
|
-
const testListener = this.robot.listeners[0]
|
|
572
|
-
const result = testListener.matcher(testMessage)
|
|
573
|
-
|
|
574
|
-
expect(result).to.not.be.ok
|
|
575
|
-
})
|
|
576
|
-
})
|
|
577
|
-
|
|
578
|
-
describe('#enter', function () {
|
|
579
|
-
it('matches EnterMessages', function () {
|
|
580
|
-
const callback = sinon.spy()
|
|
581
|
-
const testMessage = new EnterMessage(this.user)
|
|
582
|
-
|
|
583
|
-
this.robot.enter(callback)
|
|
584
|
-
const testListener = this.robot.listeners[0]
|
|
585
|
-
const result = testListener.matcher(testMessage)
|
|
586
|
-
|
|
587
|
-
expect(result).to.be.ok
|
|
588
|
-
})
|
|
589
|
-
|
|
590
|
-
it('does not match TextMessages', function () {
|
|
591
|
-
const callback = sinon.spy()
|
|
592
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
593
|
-
|
|
594
|
-
this.robot.enter(callback)
|
|
595
|
-
const testListener = this.robot.listeners[0]
|
|
596
|
-
const result = testListener.matcher(testMessage)
|
|
597
|
-
|
|
598
|
-
expect(result).to.not.be.ok
|
|
599
|
-
})
|
|
600
|
-
})
|
|
601
|
-
|
|
602
|
-
describe('#leave', function () {
|
|
603
|
-
it('matches LeaveMessages', function () {
|
|
604
|
-
const callback = sinon.spy()
|
|
605
|
-
const testMessage = new LeaveMessage(this.user)
|
|
606
|
-
|
|
607
|
-
this.robot.leave(callback)
|
|
608
|
-
const testListener = this.robot.listeners[0]
|
|
609
|
-
const result = testListener.matcher(testMessage)
|
|
610
|
-
|
|
611
|
-
expect(result).to.be.ok
|
|
612
|
-
})
|
|
613
|
-
|
|
614
|
-
it('does not match TextMessages', function () {
|
|
615
|
-
const callback = sinon.spy()
|
|
616
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
617
|
-
|
|
618
|
-
this.robot.leave(callback)
|
|
619
|
-
const testListener = this.robot.listeners[0]
|
|
620
|
-
const result = testListener.matcher(testMessage)
|
|
621
|
-
|
|
622
|
-
expect(result).to.not.be.ok
|
|
623
|
-
})
|
|
624
|
-
})
|
|
625
|
-
|
|
626
|
-
describe('#topic', function () {
|
|
627
|
-
it('matches TopicMessages', function () {
|
|
628
|
-
const callback = sinon.spy()
|
|
629
|
-
const testMessage = new TopicMessage(this.user)
|
|
630
|
-
|
|
631
|
-
this.robot.topic(callback)
|
|
632
|
-
const testListener = this.robot.listeners[0]
|
|
633
|
-
const result = testListener.matcher(testMessage)
|
|
634
|
-
|
|
635
|
-
expect(result).to.be.ok
|
|
636
|
-
})
|
|
637
|
-
|
|
638
|
-
it('does not match TextMessages', function () {
|
|
639
|
-
const callback = sinon.spy()
|
|
640
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
641
|
-
|
|
642
|
-
this.robot.topic(callback)
|
|
643
|
-
const testListener = this.robot.listeners[0]
|
|
644
|
-
const result = testListener.matcher(testMessage)
|
|
645
|
-
|
|
646
|
-
expect(result).to.not.be.ok
|
|
647
|
-
})
|
|
648
|
-
})
|
|
649
|
-
|
|
650
|
-
describe('#catchAll', function () {
|
|
651
|
-
it('matches CatchAllMessages', function () {
|
|
652
|
-
const callback = sinon.spy()
|
|
653
|
-
const testMessage = new CatchAllMessage(new TextMessage(this.user, 'message123'))
|
|
654
|
-
|
|
655
|
-
this.robot.catchAll(callback)
|
|
656
|
-
const testListener = this.robot.listeners[0]
|
|
657
|
-
const result = testListener.matcher(testMessage)
|
|
658
|
-
|
|
659
|
-
expect(result).to.be.ok
|
|
660
|
-
})
|
|
661
|
-
|
|
662
|
-
it('does not match TextMessages', function () {
|
|
663
|
-
const callback = sinon.spy()
|
|
664
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
665
|
-
|
|
666
|
-
this.robot.catchAll(callback)
|
|
667
|
-
const testListener = this.robot.listeners[0]
|
|
668
|
-
const result = testListener.matcher(testMessage)
|
|
669
|
-
|
|
670
|
-
expect(result).to.not.be.ok
|
|
671
|
-
})
|
|
672
|
-
})
|
|
673
|
-
})
|
|
674
|
-
|
|
675
|
-
describe('Message Processing', function () {
|
|
676
|
-
it('calls a matching listener', function (done) {
|
|
677
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
678
|
-
this.robot.hear(/^message123$/, function (response) {
|
|
679
|
-
expect(response.message).to.equal(testMessage)
|
|
680
|
-
done()
|
|
681
|
-
})
|
|
682
|
-
this.robot.receive(testMessage)
|
|
683
|
-
})
|
|
684
|
-
|
|
685
|
-
it('calls multiple matching listeners', function (done) {
|
|
686
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
687
|
-
|
|
688
|
-
let listenersCalled = 0
|
|
689
|
-
const listenerCallback = function (response) {
|
|
690
|
-
expect(response.message).to.equal(testMessage)
|
|
691
|
-
listenersCalled++
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
this.robot.hear(/^message123$/, listenerCallback)
|
|
695
|
-
this.robot.hear(/^message123$/, listenerCallback)
|
|
696
|
-
|
|
697
|
-
this.robot.receive(testMessage, function () {
|
|
698
|
-
expect(listenersCalled).to.equal(2)
|
|
699
|
-
done()
|
|
700
|
-
})
|
|
701
|
-
})
|
|
702
|
-
|
|
703
|
-
it('calls the catch-all listener if no listeners match', function (done) {
|
|
704
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
705
|
-
|
|
706
|
-
const listenerCallback = sinon.spy()
|
|
707
|
-
this.robot.hear(/^no-matches$/, listenerCallback)
|
|
708
|
-
|
|
709
|
-
this.robot.catchAll(function (response) {
|
|
710
|
-
expect(listenerCallback).to.not.have.been.called
|
|
711
|
-
expect(response.message).to.equal(testMessage)
|
|
712
|
-
done()
|
|
713
|
-
})
|
|
714
|
-
|
|
715
|
-
this.robot.receive(testMessage)
|
|
716
|
-
})
|
|
717
|
-
|
|
718
|
-
it('does not call the catch-all listener if any listener matched', function (done) {
|
|
719
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
720
|
-
|
|
721
|
-
const listenerCallback = sinon.spy()
|
|
722
|
-
this.robot.hear(/^message123$/, listenerCallback)
|
|
723
|
-
|
|
724
|
-
const catchAllCallback = sinon.spy()
|
|
725
|
-
this.robot.catchAll(catchAllCallback)
|
|
726
|
-
|
|
727
|
-
this.robot.receive(testMessage, function () {
|
|
728
|
-
expect(listenerCallback).to.have.been.calledOnce
|
|
729
|
-
expect(catchAllCallback).to.not.have.been.called
|
|
730
|
-
done()
|
|
731
|
-
})
|
|
732
|
-
})
|
|
733
|
-
|
|
734
|
-
it('stops processing if message.finish() is called synchronously', function (done) {
|
|
735
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
736
|
-
|
|
737
|
-
this.robot.hear(/^message123$/, response => response.message.finish())
|
|
738
|
-
|
|
739
|
-
const listenerCallback = sinon.spy()
|
|
740
|
-
this.robot.hear(/^message123$/, listenerCallback)
|
|
741
|
-
|
|
742
|
-
this.robot.receive(testMessage, function () {
|
|
743
|
-
expect(listenerCallback).to.not.have.been.called
|
|
744
|
-
done()
|
|
745
|
-
})
|
|
746
|
-
})
|
|
747
|
-
|
|
748
|
-
it('calls non-TextListener objects', function (done) {
|
|
749
|
-
const testMessage = new EnterMessage(this.user)
|
|
750
|
-
|
|
751
|
-
this.robot.enter(function (response) {
|
|
752
|
-
expect(response.message).to.equal(testMessage)
|
|
753
|
-
done()
|
|
754
|
-
})
|
|
755
|
-
|
|
756
|
-
this.robot.receive(testMessage)
|
|
757
|
-
})
|
|
758
|
-
|
|
759
|
-
it('gracefully handles listener uncaughtExceptions (move on to next listener)', function (done) {
|
|
760
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
761
|
-
const theError = new Error()
|
|
762
|
-
|
|
763
|
-
this.robot.hear(/^message123$/, function () {
|
|
764
|
-
throw theError
|
|
765
|
-
})
|
|
766
|
-
|
|
767
|
-
let goodListenerCalled = false
|
|
768
|
-
this.robot.hear(/^message123$/, () => {
|
|
769
|
-
goodListenerCalled = true
|
|
770
|
-
})
|
|
771
|
-
|
|
772
|
-
this.robot.emit = function (name, err, response) {
|
|
773
|
-
expect(name).to.equal('error')
|
|
774
|
-
expect(err).to.equal(theError)
|
|
775
|
-
expect(response.message).to.equal(testMessage)
|
|
776
|
-
}
|
|
777
|
-
sinon.spy(this.robot, 'emit')
|
|
778
|
-
|
|
779
|
-
this.robot.receive(testMessage, () => {
|
|
780
|
-
expect(this.robot.emit).to.have.been.called
|
|
781
|
-
expect(goodListenerCalled).to.be.ok
|
|
782
|
-
done()
|
|
783
|
-
})
|
|
784
|
-
})
|
|
785
|
-
|
|
786
|
-
describe('Listener Middleware', function () {
|
|
787
|
-
it('allows listener callback execution', function (testDone) {
|
|
788
|
-
const listenerCallback = sinon.spy()
|
|
789
|
-
this.robot.hear(/^message123$/, listenerCallback)
|
|
790
|
-
this.robot.listenerMiddleware((context, next, done) =>
|
|
791
|
-
// Allow Listener callback execution
|
|
792
|
-
next(done)
|
|
793
|
-
)
|
|
794
|
-
|
|
795
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
796
|
-
this.robot.receive(testMessage, function () {
|
|
797
|
-
expect(listenerCallback).to.have.been.called
|
|
798
|
-
testDone()
|
|
799
|
-
})
|
|
800
|
-
})
|
|
801
|
-
|
|
802
|
-
it('can block listener callback execution', function (testDone) {
|
|
803
|
-
const listenerCallback = sinon.spy()
|
|
804
|
-
this.robot.hear(/^message123$/, listenerCallback)
|
|
805
|
-
this.robot.listenerMiddleware((context, next, done) =>
|
|
806
|
-
// Block Listener callback execution
|
|
807
|
-
done()
|
|
808
|
-
)
|
|
809
|
-
|
|
810
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
811
|
-
this.robot.receive(testMessage, function () {
|
|
812
|
-
expect(listenerCallback).to.not.have.been.called
|
|
813
|
-
testDone()
|
|
814
|
-
})
|
|
815
|
-
})
|
|
816
|
-
|
|
817
|
-
it('receives the correct arguments', function (testDone) {
|
|
818
|
-
this.robot.hear(/^message123$/, function () {})
|
|
819
|
-
const testListener = this.robot.listeners[0]
|
|
820
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
821
|
-
|
|
822
|
-
this.robot.listenerMiddleware((context, next, done) => {
|
|
823
|
-
// Escape middleware error handling for clearer test failures
|
|
824
|
-
process.nextTick(() => {
|
|
825
|
-
expect(context.listener).to.equal(testListener)
|
|
826
|
-
expect(context.response.message).to.equal(testMessage)
|
|
827
|
-
expect(next).to.be.a('function')
|
|
828
|
-
expect(done).to.be.a('function')
|
|
829
|
-
testDone()
|
|
830
|
-
})
|
|
831
|
-
})
|
|
832
|
-
|
|
833
|
-
this.robot.receive(testMessage)
|
|
834
|
-
})
|
|
835
|
-
|
|
836
|
-
it('executes middleware in order of definition', function (testDone) {
|
|
837
|
-
const execution = []
|
|
838
|
-
|
|
839
|
-
const testMiddlewareA = function (context, next, done) {
|
|
840
|
-
execution.push('middlewareA')
|
|
841
|
-
next(function () {
|
|
842
|
-
execution.push('doneA')
|
|
843
|
-
done()
|
|
844
|
-
})
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
const testMiddlewareB = function (context, next, done) {
|
|
848
|
-
execution.push('middlewareB')
|
|
849
|
-
next(function () {
|
|
850
|
-
execution.push('doneB')
|
|
851
|
-
done()
|
|
852
|
-
})
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
this.robot.listenerMiddleware(testMiddlewareA)
|
|
856
|
-
this.robot.listenerMiddleware(testMiddlewareB)
|
|
857
|
-
|
|
858
|
-
this.robot.hear(/^message123$/, () => execution.push('listener'))
|
|
859
|
-
|
|
860
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
861
|
-
this.robot.receive(testMessage, function () {
|
|
862
|
-
expect(execution).to.deep.equal([
|
|
863
|
-
'middlewareA',
|
|
864
|
-
'middlewareB',
|
|
865
|
-
'listener',
|
|
866
|
-
'doneB',
|
|
867
|
-
'doneA'
|
|
868
|
-
])
|
|
869
|
-
testDone()
|
|
870
|
-
})
|
|
871
|
-
})
|
|
872
|
-
})
|
|
873
|
-
|
|
874
|
-
describe('Receive Middleware', function () {
|
|
875
|
-
it('fires for all messages, including non-matching ones', function (testDone) {
|
|
876
|
-
const middlewareSpy = sinon.spy()
|
|
877
|
-
const listenerCallback = sinon.spy()
|
|
878
|
-
this.robot.hear(/^message123$/, listenerCallback)
|
|
879
|
-
this.robot.receiveMiddleware(function (context, next, done) {
|
|
880
|
-
middlewareSpy()
|
|
881
|
-
next(done)
|
|
882
|
-
})
|
|
883
|
-
|
|
884
|
-
const testMessage = new TextMessage(this.user, 'not message 123')
|
|
885
|
-
|
|
886
|
-
this.robot.receive(testMessage, function () {
|
|
887
|
-
expect(listenerCallback).to.not.have.been.called
|
|
888
|
-
expect(middlewareSpy).to.have.been.called
|
|
889
|
-
testDone()
|
|
890
|
-
})
|
|
891
|
-
})
|
|
892
|
-
|
|
893
|
-
it('can block listener execution', function (testDone) {
|
|
894
|
-
const middlewareSpy = sinon.spy()
|
|
895
|
-
const listenerCallback = sinon.spy()
|
|
896
|
-
this.robot.hear(/^message123$/, listenerCallback)
|
|
897
|
-
this.robot.receiveMiddleware(function (context, next, done) {
|
|
898
|
-
// Block Listener callback execution
|
|
899
|
-
middlewareSpy()
|
|
900
|
-
done()
|
|
901
|
-
})
|
|
902
|
-
|
|
903
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
904
|
-
this.robot.receive(testMessage, function () {
|
|
905
|
-
expect(listenerCallback).to.not.have.been.called
|
|
906
|
-
expect(middlewareSpy).to.have.been.called
|
|
907
|
-
testDone()
|
|
908
|
-
})
|
|
909
|
-
})
|
|
910
|
-
|
|
911
|
-
it('receives the correct arguments', function (testDone) {
|
|
912
|
-
this.robot.hear(/^message123$/, function () {})
|
|
913
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
914
|
-
|
|
915
|
-
this.robot.receiveMiddleware(function (context, next, done) {
|
|
916
|
-
// Escape middleware error handling for clearer test failures
|
|
917
|
-
expect(context.response.message).to.equal(testMessage)
|
|
918
|
-
expect(next).to.be.a('function')
|
|
919
|
-
expect(done).to.be.a('function')
|
|
920
|
-
testDone()
|
|
921
|
-
next(done)
|
|
922
|
-
})
|
|
923
|
-
|
|
924
|
-
this.robot.receive(testMessage)
|
|
925
|
-
})
|
|
926
|
-
|
|
927
|
-
it('executes receive middleware in order of definition', function (testDone) {
|
|
928
|
-
const execution = []
|
|
929
|
-
|
|
930
|
-
const testMiddlewareA = function (context, next, done) {
|
|
931
|
-
execution.push('middlewareA')
|
|
932
|
-
next(function () {
|
|
933
|
-
execution.push('doneA')
|
|
934
|
-
done()
|
|
935
|
-
})
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
const testMiddlewareB = function (context, next, done) {
|
|
939
|
-
execution.push('middlewareB')
|
|
940
|
-
next(function () {
|
|
941
|
-
execution.push('doneB')
|
|
942
|
-
done()
|
|
943
|
-
})
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
this.robot.receiveMiddleware(testMiddlewareA)
|
|
947
|
-
this.robot.receiveMiddleware(testMiddlewareB)
|
|
948
|
-
|
|
949
|
-
this.robot.hear(/^message123$/, () => execution.push('listener'))
|
|
950
|
-
|
|
951
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
952
|
-
this.robot.receive(testMessage, function () {
|
|
953
|
-
expect(execution).to.deep.equal([
|
|
954
|
-
'middlewareA',
|
|
955
|
-
'middlewareB',
|
|
956
|
-
'listener',
|
|
957
|
-
'doneB',
|
|
958
|
-
'doneA'
|
|
959
|
-
])
|
|
960
|
-
testDone()
|
|
961
|
-
})
|
|
962
|
-
})
|
|
963
|
-
|
|
964
|
-
it('allows editing the message portion of the given response', function (testDone) {
|
|
965
|
-
const testMiddlewareA = function (context, next, done) {
|
|
966
|
-
context.response.message.text = 'foobar'
|
|
967
|
-
next()
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
const testMiddlewareB = function (context, next, done) {
|
|
971
|
-
// Subsequent middleware should see the modified message
|
|
972
|
-
expect(context.response.message.text).to.equal('foobar')
|
|
973
|
-
next()
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
this.robot.receiveMiddleware(testMiddlewareA)
|
|
977
|
-
this.robot.receiveMiddleware(testMiddlewareB)
|
|
978
|
-
|
|
979
|
-
const testCallback = sinon.spy()
|
|
980
|
-
// We'll never get to this if testMiddlewareA has not modified the message.
|
|
981
|
-
this.robot.hear(/^foobar$/, testCallback)
|
|
982
|
-
|
|
983
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
984
|
-
this.robot.receive(testMessage, function () {
|
|
985
|
-
expect(testCallback).to.have.been.called
|
|
986
|
-
testDone()
|
|
987
|
-
})
|
|
988
|
-
})
|
|
989
|
-
})
|
|
990
|
-
|
|
991
|
-
describe('Response Middleware', function () {
|
|
992
|
-
it('executes response middleware in order', function (testDone) {
|
|
993
|
-
let sendSpy
|
|
994
|
-
this.robot.adapter.send = (sendSpy = sinon.spy())
|
|
995
|
-
this.robot.hear(/^message123$/, response => response.send('foobar, sir, foobar.'))
|
|
996
|
-
|
|
997
|
-
this.robot.responseMiddleware(function (context, next, done) {
|
|
998
|
-
context.strings[0] = context.strings[0].replace(/foobar/g, 'barfoo')
|
|
999
|
-
next()
|
|
1000
|
-
})
|
|
1001
|
-
|
|
1002
|
-
this.robot.responseMiddleware(function (context, next, done) {
|
|
1003
|
-
context.strings[0] = context.strings[0].replace(/barfoo/g, 'replaced bar-foo')
|
|
1004
|
-
next()
|
|
1005
|
-
})
|
|
1006
|
-
|
|
1007
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
1008
|
-
this.robot.receive(testMessage, function () {
|
|
1009
|
-
expect(sendSpy.getCall(0).args[1]).to.equal('replaced bar-foo, sir, replaced bar-foo.')
|
|
1010
|
-
testDone()
|
|
1011
|
-
})
|
|
1012
|
-
})
|
|
1013
|
-
|
|
1014
|
-
it('allows replacing outgoing strings', function (testDone) {
|
|
1015
|
-
let sendSpy
|
|
1016
|
-
this.robot.adapter.send = (sendSpy = sinon.spy())
|
|
1017
|
-
this.robot.hear(/^message123$/, response => response.send('foobar, sir, foobar.'))
|
|
1018
|
-
|
|
1019
|
-
this.robot.responseMiddleware(function (context, next, done) {
|
|
1020
|
-
context.strings = ['whatever I want.']
|
|
1021
|
-
next()
|
|
1022
|
-
})
|
|
1023
|
-
|
|
1024
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
1025
|
-
this.robot.receive(testMessage, function () {
|
|
1026
|
-
expect(sendSpy.getCall(0).args[1]).to.deep.equal('whatever I want.')
|
|
1027
|
-
testDone()
|
|
1028
|
-
})
|
|
1029
|
-
})
|
|
1030
|
-
|
|
1031
|
-
it('marks plaintext as plaintext', function (testDone) {
|
|
1032
|
-
const sendSpy = sinon.spy()
|
|
1033
|
-
this.robot.adapter.send = sendSpy
|
|
1034
|
-
this.robot.hear(/^message123$/, response => response.send('foobar, sir, foobar.'))
|
|
1035
|
-
this.robot.hear(/^message456$/, response => response.play('good luck with that'))
|
|
1036
|
-
|
|
1037
|
-
let method
|
|
1038
|
-
let plaintext
|
|
1039
|
-
this.robot.responseMiddleware(function (context, next, done) {
|
|
1040
|
-
method = context.method
|
|
1041
|
-
plaintext = context.plaintext
|
|
1042
|
-
next(done)
|
|
1043
|
-
})
|
|
1044
|
-
|
|
1045
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
1046
|
-
|
|
1047
|
-
this.robot.receive(testMessage, () => {
|
|
1048
|
-
expect(plaintext).to.equal(true)
|
|
1049
|
-
expect(method).to.equal('send')
|
|
1050
|
-
const testMessage2 = new TextMessage(this.user, 'message456')
|
|
1051
|
-
this.robot.receive(testMessage2, function () {
|
|
1052
|
-
expect(plaintext).to.equal(undefined)
|
|
1053
|
-
expect(method).to.equal('play')
|
|
1054
|
-
testDone()
|
|
1055
|
-
})
|
|
1056
|
-
})
|
|
1057
|
-
})
|
|
1058
|
-
|
|
1059
|
-
it('does not send trailing functions to middleware', function (testDone) {
|
|
1060
|
-
let sendSpy
|
|
1061
|
-
this.robot.adapter.send = (sendSpy = sinon.spy())
|
|
1062
|
-
let asserted = false
|
|
1063
|
-
const postSendCallback = function () {}
|
|
1064
|
-
this.robot.hear(/^message123$/, response => response.send('foobar, sir, foobar.', postSendCallback))
|
|
1065
|
-
|
|
1066
|
-
this.robot.responseMiddleware(function (context, next, done) {
|
|
1067
|
-
// We don't send the callback function to middleware, so it's not here.
|
|
1068
|
-
expect(context.strings).to.deep.equal(['foobar, sir, foobar.'])
|
|
1069
|
-
expect(context.method).to.equal('send')
|
|
1070
|
-
asserted = true
|
|
1071
|
-
next()
|
|
1072
|
-
})
|
|
1073
|
-
|
|
1074
|
-
const testMessage = new TextMessage(this.user, 'message123')
|
|
1075
|
-
this.robot.receive(testMessage, function () {
|
|
1076
|
-
expect(asserted).to.equal(true)
|
|
1077
|
-
expect(sendSpy.getCall(0).args[1]).to.equal('foobar, sir, foobar.')
|
|
1078
|
-
expect(sendSpy.getCall(0).args[2]).to.equal(postSendCallback)
|
|
1079
|
-
testDone()
|
|
1080
|
-
})
|
|
1081
|
-
})
|
|
1082
|
-
})
|
|
1083
|
-
})
|
|
1084
|
-
})
|
|
1085
|
-
|
|
1086
|
-
describe('Robot Defaults', () => {
|
|
1087
|
-
let robot = null
|
|
1088
|
-
beforeEach(async () => {
|
|
1089
|
-
process.env.EXPRESS_PORT = 0
|
|
1090
|
-
robot = new Robot(null, true, 'TestHubot')
|
|
1091
|
-
robot.alias = 'Hubot'
|
|
1092
|
-
await robot.loadAdapter()
|
|
1093
|
-
robot.run()
|
|
1094
|
-
})
|
|
1095
|
-
afterEach(() => {
|
|
1096
|
-
robot.shutdown()
|
|
1097
|
-
})
|
|
1098
|
-
it('should load the builtin shell adapter by default', async () => {
|
|
1099
|
-
expect(robot.adapter.name).to.equal('Shell')
|
|
1100
|
-
})
|
|
1101
|
-
})
|
|
1102
|
-
|
|
1103
|
-
describe('Robot ES6', () => {
|
|
1104
|
-
let robot = null
|
|
1105
|
-
beforeEach(async () => {
|
|
1106
|
-
process.env.EXPRESS_PORT = 0
|
|
1107
|
-
robot = new Robot('MockAdapter', true, 'TestHubot')
|
|
1108
|
-
robot.alias = 'Hubot'
|
|
1109
|
-
await robot.loadAdapter('./test/fixtures/MockAdapter.mjs')
|
|
1110
|
-
robot.loadFile(path.resolve('./test/fixtures/'), 'TestScript.js')
|
|
1111
|
-
robot.run()
|
|
1112
|
-
})
|
|
1113
|
-
afterEach(() => {
|
|
1114
|
-
robot.shutdown()
|
|
1115
|
-
})
|
|
1116
|
-
it('should load an ES6 module adapter from a file', async () => {
|
|
1117
|
-
const { MockAdapter } = await import('./fixtures/MockAdapter.mjs')
|
|
1118
|
-
expect(robot.adapter).to.be.an.instanceOf(MockAdapter)
|
|
1119
|
-
expect(robot.adapter.name).to.equal('MockAdapter')
|
|
1120
|
-
})
|
|
1121
|
-
it('should respond to a message', async () => {
|
|
1122
|
-
const sent = (envelop, strings) => {
|
|
1123
|
-
expect(strings).to.deep.equal(['test response'])
|
|
1124
|
-
}
|
|
1125
|
-
robot.adapter.on('send', sent)
|
|
1126
|
-
await robot.adapter.receive(new TextMessage('tester', 'hubot test'))
|
|
1127
|
-
})
|
|
1128
|
-
})
|
|
1129
|
-
|
|
1130
|
-
describe('Robot Coffeescript', () => {
|
|
1131
|
-
let robot = null
|
|
1132
|
-
beforeEach(async () => {
|
|
1133
|
-
process.env.EXPRESS_PORT = 0
|
|
1134
|
-
robot = new Robot('MockAdapter', true, 'TestHubot')
|
|
1135
|
-
robot.alias = 'Hubot'
|
|
1136
|
-
await robot.loadAdapter('./test/fixtures/MockAdapter.coffee')
|
|
1137
|
-
robot.loadFile(path.resolve('./test/fixtures/'), 'TestScript.coffee')
|
|
1138
|
-
robot.run()
|
|
1139
|
-
})
|
|
1140
|
-
afterEach(() => {
|
|
1141
|
-
robot.shutdown()
|
|
1142
|
-
})
|
|
1143
|
-
it('should load a CoffeeScript adapter from a file', async () => {
|
|
1144
|
-
expect(robot.adapter.name).to.equal('MockAdapter')
|
|
1145
|
-
})
|
|
1146
|
-
it('should load a coffeescript file and respond to a message', async () => {
|
|
1147
|
-
const sent = (envelop, strings) => {
|
|
1148
|
-
expect(strings).to.deep.equal(['test response from coffeescript'])
|
|
1149
|
-
}
|
|
1150
|
-
robot.adapter.on('send', sent)
|
|
1151
|
-
await robot.adapter.receive(new TextMessage('tester', 'hubot test'))
|
|
1152
|
-
})
|
|
1153
|
-
})
|