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.
Files changed (45) hide show
  1. package/package.json +1 -1
  2. package/src/robot.js +0 -11
  3. package/.editorconfig +0 -14
  4. package/.github/stale.yml +0 -23
  5. package/.github/workflows/nodejs-macos.yml +0 -26
  6. package/.github/workflows/nodejs-ubuntu.yml +0 -28
  7. package/.github/workflows/nodejs-windows.yml +0 -26
  8. package/.github/workflows/release.yml +0 -37
  9. package/bin/e2e-test.sh +0 -47
  10. package/docs/adapters/campfire.md +0 -79
  11. package/docs/adapters/development.md +0 -125
  12. package/docs/adapters/shell.md +0 -24
  13. package/docs/adapters.md +0 -27
  14. package/docs/deploying/azure.md +0 -97
  15. package/docs/deploying/bluemix.md +0 -111
  16. package/docs/deploying/heroku.md +0 -66
  17. package/docs/deploying/unix.md +0 -72
  18. package/docs/deploying/windows.md +0 -66
  19. package/docs/deploying.md +0 -11
  20. package/docs/implementation.md +0 -55
  21. package/docs/index.md +0 -125
  22. package/docs/patterns.md +0 -265
  23. package/docs/scripting.md +0 -1051
  24. package/examples/hubot-start.ps1 +0 -12
  25. package/examples/hubot.service +0 -27
  26. package/script/bootstrap +0 -3
  27. package/script/release +0 -44
  28. package/script/server +0 -3
  29. package/script/smoke-test +0 -3
  30. package/script/test +0 -3
  31. package/test/adapter_test.js +0 -97
  32. package/test/brain_test.js +0 -336
  33. package/test/datastore_test.js +0 -154
  34. package/test/es2015_test.js +0 -199
  35. package/test/fixtures/MockAdapter.coffee +0 -10
  36. package/test/fixtures/MockAdapter.mjs +0 -43
  37. package/test/fixtures/TestScript.coffee +0 -9
  38. package/test/fixtures/TestScript.js +0 -13
  39. package/test/fixtures/mock-adapter.js +0 -35
  40. package/test/listener_test.js +0 -379
  41. package/test/message_test.js +0 -46
  42. package/test/middleware_test.js +0 -507
  43. package/test/robot_test.js +0 -1153
  44. package/test/shell_test.js +0 -73
  45. package/test/user_test.js +0 -29
@@ -1,12 +0,0 @@
1
- #Hubot PowerShell Start Script
2
- #Invoke from the PowerShell prompt or start via automated tools
3
-
4
- $HubotPath = "drive:\path\to\hubot"
5
- $HubotAdapter = "Hubot adapter"
6
-
7
- Write-Host "Starting Hubot Watcher"
8
- While (1)
9
- {
10
- Write-Host "Starting Hubot"
11
- Start-Process powershell -ArgumentList "$HubotPath\bin\hubot –adapter $HubotAdapter" -wait
12
- }
@@ -1,27 +0,0 @@
1
- ; Hubot systemd service unit file
2
- ; Place in e.g. `/etc/systemd/system/hubot.service`, then `systemctl daemon-reload` and `service hubot start`.
3
-
4
- [Unit]
5
- Description=Hubot
6
- Requires=network.target
7
- After=network.target
8
-
9
- [Service]
10
- Type=simple
11
- WorkingDirectory=/path/to/hubot
12
- User=change-to-hubot-user
13
-
14
- Restart=always
15
- RestartSec=10
16
-
17
- ; Configure Hubot environment variables, use quotes around vars with whitespace as shown below.
18
- Environment="HUBOT_aaa=xxx"
19
- Environment="HUBOT_bbb='yyy yyy'"
20
-
21
- ; Alternatively multiple environment variables can loaded from an external file
22
- ;EnvironmentFile=/etc/hubot-environment
23
-
24
- ExecStart=/path/to/hubot/bin/hubot --adapter zzz
25
-
26
- [Install]
27
- WantedBy=multi-user.target
package/script/bootstrap DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- npm install
package/script/release DELETED
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Tag and push a release.
3
-
4
- set -e
5
-
6
- # Make sure we're in the project root.
7
-
8
- cd $(dirname "$0")/..
9
-
10
- # Make sure the darn thing works
11
-
12
- npm update && script/smoke-test
13
-
14
- # Make sure we're on the main branch.
15
-
16
- (git branch | grep -q '* main') || {
17
- echo "Only release from the main branch."
18
- exit 1
19
- }
20
-
21
- # Figure out what version we're releasing.
22
-
23
- tag=v`node -e 'console.log(require("./package.json").version)'`
24
-
25
- # Ensure there's a line in the CHANGELOG
26
-
27
- grep "$tag" CHANGELOG.md || {
28
- echo "No entry for '$tag' found in the CHANGELOG."
29
- exit 1
30
- }
31
-
32
- # Make sure we haven't released this version before.
33
-
34
- git fetch -t origin
35
-
36
- (git tag -l | grep -q "$tag") && {
37
- echo "Whoops, there's already a '${tag}' tag."
38
- exit 1
39
- }
40
-
41
- # Tag it and bag it.
42
-
43
- npm publish && git tag "$tag" &&
44
- git push origin main --tags
package/script/server DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- npm start -- "$@"
package/script/smoke-test DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- npm run test:smoke
package/script/test DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- npm test -- "$@"
@@ -1,97 +0,0 @@
1
- 'use strict'
2
-
3
- /* global describe, beforeEach, it */
4
-
5
- const chai = require('chai')
6
- const sinon = require('sinon')
7
- chai.use(require('sinon-chai'))
8
-
9
- const expect = chai.expect
10
-
11
- const Adapter = require('../src/adapter')
12
-
13
- describe('Adapter', function () {
14
- beforeEach(function () {
15
- this.robot = { receive: sinon.spy() }
16
- })
17
-
18
- describe('Public API', function () {
19
- beforeEach(function () {
20
- this.adapter = new Adapter(this.robot)
21
- })
22
-
23
- it('assigns robot', function () {
24
- expect(this.adapter.robot).to.equal(this.robot)
25
- })
26
-
27
- describe('send', function () {
28
- it('is a function', function () {
29
- expect(this.adapter.send).to.be.a('function')
30
- })
31
-
32
- it('does nothing', function () {
33
- this.adapter.send({}, 'nothing')
34
- })
35
- })
36
-
37
- describe('reply', function () {
38
- it('is a function', function () {
39
- expect(this.adapter.reply).to.be.a('function')
40
- })
41
-
42
- it('does nothing', function () {
43
- this.adapter.reply({}, 'nothing')
44
- })
45
- })
46
-
47
- describe('topic', function () {
48
- it('is a function', function () {
49
- expect(this.adapter.topic).to.be.a('function')
50
- })
51
-
52
- it('does nothing', function () {
53
- this.adapter.topic({}, 'nothing')
54
- })
55
- })
56
-
57
- describe('play', function () {
58
- it('is a function', function () {
59
- expect(this.adapter.play).to.be.a('function')
60
- })
61
-
62
- it('does nothing', function () {
63
- this.adapter.play({}, 'nothing')
64
- })
65
- })
66
-
67
- describe('run', function () {
68
- it('is a function', function () {
69
- expect(this.adapter.run).to.be.a('function')
70
- })
71
-
72
- it('does nothing', function () {
73
- this.adapter.run()
74
- })
75
- })
76
-
77
- describe('close', function () {
78
- it('is a function', function () {
79
- expect(this.adapter.close).to.be.a('function')
80
- })
81
-
82
- it('does nothing', function () {
83
- this.adapter.close()
84
- })
85
- })
86
- })
87
-
88
- it('dispatches received messages to the robot', function () {
89
- this.robot.receive = sinon.spy()
90
- this.adapter = new Adapter(this.robot)
91
- this.message = sinon.spy()
92
-
93
- this.adapter.receive(this.message)
94
-
95
- expect(this.robot.receive).to.have.been.calledWith(this.message)
96
- })
97
- })
@@ -1,336 +0,0 @@
1
- 'use strict'
2
-
3
- /* global describe, beforeEach, afterEach, it */
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
- const isCircular = require('is-circular')
14
-
15
- // Hubot classes
16
- const Brain = require('../src/brain')
17
- const User = require('../src/user')
18
-
19
- describe('Brain', function () {
20
- beforeEach(function () {
21
- this.clock = sinon.useFakeTimers()
22
- this.mockRobot = {
23
- emit () {},
24
- on () {}
25
- }
26
-
27
- // This *should* be callsArgAsync to match the 'on' API, but that makes
28
- // the tests more complicated and seems irrelevant.
29
- sinon.stub(this.mockRobot, 'on').withArgs('running').callsArg(1)
30
-
31
- this.brain = new Brain(this.mockRobot)
32
-
33
- this.user1 = this.brain.userForId('1', { name: 'Guy One' })
34
- this.user2 = this.brain.userForId('2', { name: 'Guy One Two' })
35
- this.user3 = this.brain.userForId('3', { name: 'Girl Three' })
36
- })
37
-
38
- afterEach(function () {
39
- this.clock.restore()
40
- })
41
-
42
- describe('Unit Tests', function () {
43
- describe('#mergeData', function () {
44
- it('performs a proper merge with the new data taking precedent', function () {
45
- this.brain.data = {
46
- 1: 'old',
47
- 2: 'old'
48
- }
49
-
50
- this.brain.mergeData({ 2: 'new' })
51
-
52
- expect(this.brain.data).to.deep.equal({
53
- 1: 'old',
54
- 2: 'new'
55
- })
56
- })
57
-
58
- it('emits a loaded event with the new data', function () {
59
- sinon.spy(this.brain, 'emit')
60
- this.brain.mergeData({})
61
- expect(this.brain.emit).to.have.been.calledWith('loaded', this.brain.data)
62
- })
63
-
64
- it('coerces loaded data into User objects', function () {
65
- this.brain.mergeData({ users: { 4: { name: 'new', id: '4' } } })
66
- const user = this.brain.userForId('4')
67
- expect(user.constructor.name).to.equal('User')
68
- expect(user.id).to.equal('4')
69
- expect(user.name).to.equal('new')
70
- expect(isCircular(this.brain)).to.be.false
71
- })
72
- })
73
-
74
- describe('#save', () => it('emits a save event', function () {
75
- sinon.spy(this.brain, 'emit')
76
- this.brain.save()
77
- expect(this.brain.emit).to.have.been.calledWith('save', this.brain.data)
78
- }))
79
-
80
- describe('#resetSaveInterval', () => it('updates the auto-save interval', function () {
81
- sinon.spy(this.brain, 'save')
82
- // default is 5s
83
- this.brain.resetSaveInterval(10)
84
- // make sure autosave is on
85
- this.brain.setAutoSave(true)
86
-
87
- this.clock.tick(5000)
88
- // old interval has passed
89
- expect(this.brain.save).to.not.have.been.called
90
- this.clock.tick(5000)
91
- // new interval has passed
92
- expect(this.brain.save).to.have.been.calledOnce
93
- }))
94
-
95
- describe('#close', function () {
96
- it('saves', function () {
97
- sinon.spy(this.brain, 'save')
98
- this.brain.close()
99
- expect(this.brain.save).to.have.been.calledOnce
100
- })
101
-
102
- it('emits a close event', function () {
103
- sinon.spy(this.brain, 'emit')
104
- this.brain.close()
105
- expect(this.brain.emit).to.have.been.calledWith('close')
106
- })
107
-
108
- it('saves before emitting the close event', function () {
109
- sinon.spy(this.brain, 'save')
110
- sinon.spy(this.brain, 'emit').withArgs('close')
111
- this.brain.close()
112
- expect(this.brain.save).to.have.been.calledBefore(this.brain.emit)
113
- })
114
-
115
- it('stops auto-saving', function () {
116
- // make sure autosave is on
117
- this.brain.setAutoSave(true)
118
- this.brain.close()
119
-
120
- // set up the spy after because 'close' calls 'save'
121
- sinon.spy(this.brain, 'save')
122
-
123
- this.clock.tick(2 * 5000)
124
- expect(this.brain.save).to.not.have.been.called
125
- })
126
- })
127
-
128
- describe('#get', function () {
129
- it('returns the saved value', function () {
130
- this.brain.data._private['test-key'] = 'value'
131
- expect(this.brain.get('test-key')).to.equal('value')
132
- })
133
-
134
- it('returns null if object is not found', function () {
135
- expect(this.brain.get('not a real key')).to.be.null
136
- })
137
- })
138
-
139
- describe('#set', function () {
140
- it('saves the value', function () {
141
- this.brain.set('test-key', 'value')
142
- expect(this.brain.data._private['test-key']).to.equal('value')
143
- })
144
-
145
- it('sets multiple keys at once if an object is provided', function () {
146
- this.brain.data._private = {
147
- key1: 'val1',
148
- key2: 'val1'
149
- }
150
-
151
- this.brain.set({
152
- key2: 'val2',
153
- key3: 'val2'
154
- })
155
-
156
- expect(this.brain.data._private).to.deep.equal({
157
- key1: 'val1',
158
- key2: 'val2',
159
- key3: 'val2'
160
- })
161
- })
162
-
163
- // Unable to understand why this behavior is needed, but adding a test
164
- // case to protect it
165
- it('emits loaded', function () {
166
- sinon.spy(this.brain, 'emit')
167
- this.brain.set('test-key', 'value')
168
- expect(this.brain.emit).to.have.been.calledWith('loaded', this.brain.data)
169
- })
170
-
171
- it('returns the brain', function () {
172
- expect(this.brain.set('test-key', 'value')).to.equal(this.brain)
173
- })
174
- })
175
-
176
- describe('#remove', () => it('removes the specified key', function () {
177
- this.brain.data._private['test-key'] = 'value'
178
- this.brain.remove('test-key')
179
- expect(this.brain.data._private).to.not.include.keys('test-key')
180
- }))
181
-
182
- describe('#userForId', function () {
183
- it('returns the user object', function () {
184
- expect(this.brain.userForId(1)).to.equal(this.user1)
185
- })
186
-
187
- it('does an exact match', function () {
188
- const user4 = this.brain.userForId('FOUR')
189
- expect(this.brain.userForId('four')).to.not.equal(user4)
190
- })
191
-
192
- // Cannot understand why this behavior is needed, but adding a test case
193
- // to protect it
194
- it('recreates the user if the room option differs from the user object', function () {
195
- expect(this.brain.userForId(1).room).to.be.undefined
196
-
197
- // undefined -> having a room
198
- const newUser1 = this.brain.userForId(1, { room: 'room1' })
199
- expect(newUser1).to.not.equal(this.user1)
200
-
201
- // changing the room
202
- const newUser2 = this.brain.userForId(1, { room: 'room2' })
203
- expect(newUser2).to.not.equal(newUser1)
204
- })
205
-
206
- describe('when there is no matching user ID', function () {
207
- it('creates a new User', function () {
208
- expect(this.brain.data.users).to.not.include.key('all-new-user')
209
- const newUser = this.brain.userForId('all-new-user')
210
- expect(newUser).to.be.instanceof(User)
211
- expect(newUser.id).to.equal('all-new-user')
212
- expect(this.brain.data.users).to.include.key('all-new-user')
213
- })
214
-
215
- it('passes the provided options to the new User', function () {
216
- const newUser = this.brain.userForId('all-new-user', { name: 'All New User', prop: 'mine' })
217
- expect(newUser.name).to.equal('All New User')
218
- expect(newUser.prop).to.equal('mine')
219
- })
220
- })
221
- })
222
-
223
- describe('#userForName', function () {
224
- it('returns the user with a matching name', function () {
225
- expect(this.brain.userForName('Guy One')).to.equal(this.user1)
226
- })
227
-
228
- it('does a case-insensitive match', function () {
229
- expect(this.brain.userForName('guy one')).to.equal(this.user1)
230
- })
231
-
232
- it('returns null if no user matches', function () {
233
- expect(this.brain.userForName('not a real user')).to.be.null
234
- })
235
- })
236
-
237
- describe('#usersForRawFuzzyName', function () {
238
- it('does a case-insensitive match', function () {
239
- expect(this.brain.usersForRawFuzzyName('guy')).to.have.members([this.user1, this.user2])
240
- })
241
-
242
- it('returns all matching users (prefix match) when there is not an exact match (case-insensitive)', function () {
243
- expect(this.brain.usersForRawFuzzyName('Guy')).to.have.members([this.user1, this.user2])
244
- })
245
-
246
- it('returns all matching users (prefix match) when there is an exact match (case-insensitive)', function () {
247
- // Matched case
248
- expect(this.brain.usersForRawFuzzyName('Guy One')).to.deep.equal([this.user1, this.user2])
249
- // Mismatched case
250
- expect(this.brain.usersForRawFuzzyName('guy one')).to.deep.equal([this.user1, this.user2])
251
- })
252
-
253
- it('returns an empty array if no users match', function () {
254
- const result = this.brain.usersForRawFuzzyName('not a real user')
255
- expect(result).to.be.an('array')
256
- expect(result).to.be.empty
257
- })
258
- })
259
-
260
- describe('#usersForFuzzyName', function () {
261
- it('does a case-insensitive match', function () {
262
- expect(this.brain.usersForFuzzyName('guy')).to.have.members([this.user1, this.user2])
263
- })
264
-
265
- it('returns all matching users (prefix match) when there is not an exact match', function () {
266
- expect(this.brain.usersForFuzzyName('Guy')).to.have.members([this.user1, this.user2])
267
- })
268
-
269
- it('returns just the user when there is an exact match (case-insensitive)', function () {
270
- // Matched case
271
- expect(this.brain.usersForFuzzyName('Guy One')).to.deep.equal([this.user1])
272
- // Mismatched case
273
- expect(this.brain.usersForFuzzyName('guy one')).to.deep.equal([this.user1])
274
- })
275
-
276
- it('returns an empty array if no users match', function () {
277
- const result = this.brain.usersForFuzzyName('not a real user')
278
- expect(result).to.be.an('array')
279
- expect(result).to.be.empty
280
- })
281
- })
282
- })
283
-
284
- describe('Auto-Save', function () {
285
- it('is on by default', function () {
286
- expect(this.brain.autoSave).to.equal(true)
287
- })
288
-
289
- it('automatically saves every 5 seconds when turned on', function () {
290
- sinon.spy(this.brain, 'save')
291
-
292
- this.brain.setAutoSave(true)
293
-
294
- this.clock.tick(5000)
295
- expect(this.brain.save).to.have.been.called
296
- })
297
-
298
- it('does not auto-save when turned off', function () {
299
- sinon.spy(this.brain, 'save')
300
-
301
- this.brain.setAutoSave(false)
302
-
303
- this.clock.tick(2 * 5000)
304
- expect(this.brain.save).to.not.have.been.called
305
- })
306
- })
307
-
308
- describe('User Searching', function () {
309
- it('finds users by ID', function () {
310
- expect(this.brain.userForId('1')).to.equal(this.user1)
311
- })
312
-
313
- it('finds users by exact name', function () {
314
- expect(this.brain.userForName('Guy One')).to.equal(this.user1)
315
- })
316
-
317
- it('finds users by fuzzy name (prefix match)', function () {
318
- const result = this.brain.usersForFuzzyName('Guy')
319
- expect(result).to.have.members([this.user1, this.user2])
320
- expect(result).to.not.have.members([this.user3])
321
- })
322
-
323
- it('returns User objects, not POJOs', function () {
324
- expect(this.brain.userForId('1').constructor.name).to.equal('User')
325
- for (const user of this.brain.usersForFuzzyName('Guy')) {
326
- expect(user.constructor.name).to.equal('User')
327
- }
328
-
329
- for (const user of this.brain.usersForRawFuzzyName('Guy One')) {
330
- expect(user.constructor.name).to.equal('User')
331
- }
332
-
333
- expect(isCircular(this.brain)).to.be.false
334
- })
335
- })
336
- })
@@ -1,154 +0,0 @@
1
- 'use strict'
2
-
3
- /* global describe, beforeEach, it */
4
-
5
- const chai = require('chai')
6
- const sinon = require('sinon')
7
- chai.use(require('sinon-chai'))
8
-
9
- const expect = chai.expect
10
-
11
- const Brain = require('../src/brain')
12
- const InMemoryDataStore = require('../src/datastores/memory')
13
-
14
- describe('Datastore', function () {
15
- beforeEach(function () {
16
- this.clock = sinon.useFakeTimers()
17
- this.robot = {
18
- emit () {},
19
- on () {},
20
- receive: sinon.spy()
21
- }
22
-
23
- // This *should* be callsArgAsync to match the 'on' API, but that makes
24
- // the tests more complicated and seems irrelevant.
25
- sinon.stub(this.robot, 'on').withArgs('running').callsArg(1)
26
-
27
- this.robot.brain = new Brain(this.robot)
28
- this.robot.datastore = new InMemoryDataStore(this.robot)
29
- this.robot.brain.userForId('1', { name: 'User One' })
30
- this.robot.brain.userForId('2', { name: 'User Two' })
31
- })
32
-
33
- this.afterEach(function () {
34
- this.clock.restore()
35
- })
36
-
37
- describe('global scope', function () {
38
- it('returns undefined for values not in the datastore', function () {
39
- return this.robot.datastore.get('blah').then(function (value) {
40
- expect(value).to.be.an('undefined')
41
- })
42
- })
43
-
44
- it('can store simple values', function () {
45
- return this.robot.datastore.set('key', 'value').then(() => {
46
- return this.robot.datastore.get('key').then((value) => {
47
- expect(value).to.equal('value')
48
- })
49
- })
50
- })
51
-
52
- it('can store arbitrary JavaScript values', function () {
53
- const object = {
54
- name: 'test',
55
- data: [1, 2, 3]
56
- }
57
- return this.robot.datastore.set('key', object).then(() => {
58
- return this.robot.datastore.get('key').then((value) => {
59
- expect(value.name).to.equal('test')
60
- expect(value.data).to.deep.equal([1, 2, 3])
61
- })
62
- })
63
- })
64
-
65
- it('can dig inside objects for values', function () {
66
- const object = {
67
- a: 'one',
68
- b: 'two'
69
- }
70
- return this.robot.datastore.set('key', object).then(() => {
71
- return this.robot.datastore.getObject('key', 'a').then((value) => {
72
- expect(value).to.equal('one')
73
- })
74
- })
75
- })
76
-
77
- it('can set individual keys inside objects', function () {
78
- const object = {
79
- a: 'one',
80
- b: 'two'
81
- }
82
- return this.robot.datastore.set('object', object).then(() => {
83
- return this.robot.datastore.setObject('object', 'c', 'three').then(() => {
84
- return this.robot.datastore.get('object').then((value) => {
85
- expect(value.a).to.equal('one')
86
- expect(value.b).to.equal('two')
87
- expect(value.c).to.equal('three')
88
- })
89
- })
90
- })
91
- })
92
-
93
- it('creates an object from scratch when none exists', function () {
94
- return this.robot.datastore.setObject('object', 'key', 'value').then(() => {
95
- return this.robot.datastore.get('object').then((value) => {
96
- const expected = { key: 'value' }
97
- expect(value).to.deep.equal(expected)
98
- })
99
- })
100
- })
101
-
102
- it('can append to an existing array', function () {
103
- return this.robot.datastore.set('array', [1, 2, 3]).then(() => {
104
- return this.robot.datastore.setArray('array', 4).then(() => {
105
- return this.robot.datastore.get('array').then((value) => {
106
- expect(value).to.deep.equal([1, 2, 3, 4])
107
- })
108
- })
109
- })
110
- })
111
-
112
- it('creates an array from scratch when none exists', function () {
113
- return this.robot.datastore.setArray('array', 4).then(() => {
114
- return this.robot.datastore.get('array').then((value) => {
115
- expect(value).to.deep.equal([4])
116
- })
117
- })
118
- })
119
- })
120
-
121
- describe('User scope', function () {
122
- it('has access to the robot object', function () {
123
- const user = this.robot.brain.userForId('1')
124
- expect(user._getRobot()).to.equal(this.robot)
125
- })
126
-
127
- it('can store user data which is separate from global data', function () {
128
- const user = this.robot.brain.userForId('1')
129
- return user.set('blah', 'blah').then(() => {
130
- return user.get('blah').then((userBlah) => {
131
- return this.robot.datastore.get('blah').then((datastoreBlah) => {
132
- expect(userBlah).to.not.equal(datastoreBlah)
133
- expect(userBlah).to.equal('blah')
134
- expect(datastoreBlah).to.be.an('undefined')
135
- })
136
- })
137
- })
138
- })
139
-
140
- it('stores user data separate per-user', function () {
141
- const userOne = this.robot.brain.userForId('1')
142
- const userTwo = this.robot.brain.userForId('2')
143
- return userOne.set('blah', 'blah').then(() => {
144
- return userOne.get('blah').then((valueOne) => {
145
- return userTwo.get('blah').then((valueTwo) => {
146
- expect(valueOne).to.not.equal(valueTwo)
147
- expect(valueOne).to.equal('blah')
148
- expect(valueTwo).to.be.an('undefined')
149
- })
150
- })
151
- })
152
- })
153
- })
154
- })