UNPKG

9.82 kBtext/coffeescriptView Raw
1# Hubot classes
2Robot = require "hubot/src/robot"
3TextMessage = require("hubot/src/message").TextMessage
4path = require 'path'
5moment = require 'moment'
6
7# Load assertion methods to this scope
8{ expect } = require 'chai'
9nock = require 'nock'
10nock.disableNetConnect()
11
12# Globals
13robot = user = {}
14
15# Test environment variables
16process.env.HUBOT_HIGHFIVE_CHAT_SERVICE = 'dummy'
17process.env.PORT = 8088
18process.env.HUBOT_HOSTNAME = 'http://localhost:8088'
19
20# Mock out the tangocard API
21process.env.HUBOT_TANGOCARD_ROOTURL = 'http://tango.example.com/'
22process.env.HUBOT_TANGOCARD_CUSTOMER = 'Foo'
23process.env.HUBOT_TANGOCARD_ACCOUNT = 'Bar'
24
25# No daily doubles or boomerangs unless we test them explicitly
26process.env.HUBOT_HIGHFIVE_DOUBLE_RATE = '0'
27process.env.HUBOT_HIGHFIVE_BOOMERANG_RATE = '0'
28
29# Create a robot, load our script
30prep = (done) ->
31 robot = new Robot path.resolve(__dirname), 'shell', yes, 'TestHubot'
32 robot.adapter.on 'connected', ->
33 # Project script
34 robot.loadFile path.resolve('.'), 'index.coffee'
35 # Some test users
36 user = robot.brain.userForId "1",
37 name: "mocha"
38 email: "mocha@example.com"
39 room: "#mocha"
40 robot.brain.userForId '2',
41 name: 'foo'
42 email: 'foo@example.com'
43 room: '#mocha'
44 done()
45 robot.run()
46
47prepNock = ->
48 nock('http://tango.example.com')
49 .filteringPath /Authorization=[^&]*/g, 'Authorization=FOOBAR'
50 .get('/accounts/Foo/Bar?Authorization=FOOBAR')
51 .reply 200,
52 success: true
53 account:
54 available_balance: 100
55 .post('/cc_fund?Authorization=FOOBAR')
56 .reply 200,
57 success: true
58 .post('/orders?Authorization=FOOBAR')
59 .reply 200,
60 success: true
61 order:
62 delivered_at: moment.utc().toISOString()
63 reward:
64 number: '123'
65 nock('http://jsonip.com')
66 .get('/')
67 .reply 200, ip: '0.0.0.0'
68
69cleanup = ->
70 robot.server.close()
71 robot.shutdown()
72 nock.cleanAll()
73
74# Message/response helper
75message_response = (msg, evt, direct_address, expecter) ->
76 # direct_address is optional, need to detect if it's missing to find the callback
77 if not expecter?
78 expecter = direct_address
79 direct_address = true
80
81 robot.adapter.on evt, expecter
82 robot.adapter.receive new TextMessage user, "#{if direct_address then 'TestHubot ' else ''}#{msg}"
83
84# Test help output
85describe 'help', ->
86 beforeEach prep
87 afterEach cleanup
88
89 it 'should have 4', (done) ->
90 expect(robot.helpCommands()).to.have.length 4
91 do done
92
93 it 'should parse help', (done) ->
94 help = robot.helpCommands()
95 expected = [
96 'hubot highfive @<user> $<amount> for <awesome thing> - makes a loud announcement and sends the user an Amazon.com giftcard',
97 'hubot highfive @<user> for <awesome thing> - makes a loud announcement in a public chatroom',
98 'hubot highfive config - show URL for configuration UI',
99 'hubot highfive stats - show stats about high-fives',
100 ]
101 expect(expected).to.contain(x) for x in help
102 do done
103
104# We handle a couple of varieties of reason: "for X", and just "X".
105# That last case still results in hubot sending the reason as "for X".
106[{
107 reason: 'for something',
108 reason_sent: 'for something'
109}, {
110 reason: 'something',
111 reason_sent: 'for something'
112}].forEach (reasonCtx) ->
113
114 # Test the command with a given reason
115 describe "highfive #{reasonCtx.reason}", ->
116 # We want to test the behavior in all four combinations of direct_address
117 # and allow_eavesdropping, but false/false is different in that the message
118 # is expected to be ignored. Thus, we test the other three cases here, and
119 # special-case the false/false "ignore the message" case separately.
120 [{
121 direct_address: true,
122 allow_eavesdropping: false,
123 }, {
124 direct_address: true
125 allow_eavesdropping: true,
126 }, {
127 direct_address: false
128 allow_eavesdropping: true,
129 }].forEach (directCtx) ->
130 describe "with allow eavesdropping #{directCtx.allow_eavesdropping} and direct address #{directCtx.direct_address}", ->
131
132 beforeEach (done) ->
133 process.env.HUBOT_HIGHFIVE_ALLOW_EAVESDROPPING = directCtx.allow_eavesdropping.toString()
134 prep done
135
136 afterEach ->
137 delete process.env.HUBOT_HIGHFIVE_ALLOW_EAVESDROPPING
138 do cleanup
139
140 it "shouldn't let you high-five yourself", (done) ->
141 message_response "highfive @mocha #{reasonCtx.reason}", 'reply', directCtx.direct_address, (e,strs) ->
142 expect(strs).to.contain 'clapping'
143 do done
144
145 it "should complain if it can't find a user", (done) ->
146 message_response "highfive @bar #{reasonCtx.reason}", 'reply', directCtx.direct_address, (e,strs) ->
147 expect(strs).to.equal "Who's @bar?"
148 do done
149
150 it 'should make some noise', (done) ->
151 message_response "highfive @foo #{reasonCtx.reason}", 'send', directCtx.direct_address, (e,strs) ->
152 expect(strs).to.match /woo/i
153 expect(strs).to.contain 'foo'
154 expect(strs).to.contain 'mocha'
155 expect(strs).to.match /\.gif/i
156 do done
157
158 it "should send #{reasonCtx.reason_sent} for #{reasonCtx.reason}", (done) ->
159 message_response "highfive @foo #{reasonCtx.reason}", 'send', directCtx.direct_address, (e,strs) ->
160 expect(strs).to.contain reasonCtx.reason_sent
161 do done
162
163
164 describe 'with allow eavesdropping false and direct address false', ->
165 beforeEach prep
166 afterEach cleanup
167
168 it "should ignore highfives that aren't directly addressed to hubot", (done) ->
169 message_response "highfive @foo #{reasonCtx.reason}", 'send', false, (e,strs) ->
170 expect(true).to.equal(false)
171 do done
172 # wait for 1 second to make sure the expecter *isn't* called
173 setTimeout done, 1000
174
175 # Test the Tango Card API implementation
176 describe 'with 1Tango Card', ->
177 # Because we need to tweak settings for many of these tests, they
178 # are individually responsible for calling `prep`!
179 beforeEach prepNock
180 afterEach cleanup
181
182 describe 'default limits', ->
183 beforeEach prep
184
185 it 'should announce the gift card', (done) ->
186 message_response "highfive @foo $25 #{reasonCtx.reason}", 'send', (e,strs) ->
187 unless strs.match /woo/i
188 expect(strs).to.match /.*\$25.*card.*/i
189 do done
190
191 it "shouldn't let you send huge gifts", (done) ->
192 message_response "highfive @foo $5000 #{reasonCtx.reason}", 'reply', (e,strs) ->
193 expect(strs).to.match /\$5000.*smaller.*150/i
194 do done
195
196 it 'should refuse to send too much money in one day', (done) ->
197 process.env.HUBOT_HIGHFIVE_DAILY_LIMIT = '30'
198 prep ->
199 message_response "highfive @foo $20 #{reasonCtx.reason}", 'send', (e,strs) ->
200 return unless strs.match /\$20/
201 message_response "highfive @foo $15 #{reasonCtx.reason}", 'reply', (e,strs) ->
202 if strs.indexOf('$15') == -1
203 expect(strs).to.match /.*sorry.*\$20.*\$30/i
204 delete process.env.HUBOT_HIGHFIVE_DAILY_LIMIT
205 do done
206
207 it 'should mention the right limit when refusing to order a card', (done) ->
208 process.env.HUBOT_HIGHFIVE_AWARD_LIMIT = '20'
209 prep ->
210 message_response "highfive @foo $30 #{reasonCtx.reason}", 'reply', (e, strs) ->
211 expect(strs).to.contain "$#{process.env.HUBOT_HIGHFIVE_AWARD_LIMIT}"
212 delete process.env.HUBOT_HIGHFIVE_AWARD_LIMIT
213 do done
214
215 it 'should refuse to send a card if awards are disabled', (done) ->
216 process.env.HUBOT_HIGHFIVE_AWARD_LIMIT = '0'
217 prep ->
218 message_response "highfive @foo $10 #{reasonCtx.reason}", 'reply', (e,strs) ->
219 expect(strs).to.contain 'disabled'
220 delete process.env.HUBOT_HIGHFIVE_AWARD_LIMIT
221 do done
222
223 it 'daily double should double the amount', (done) ->
224 process.env.HUBOT_HIGHFIVE_DOUBLE_RATE = '1'
225 prep ->
226 message_response "highfive @foo $10 #{reasonCtx.reason}", 'send', (e, strs) ->
227 return unless strs.match /gift card is on its way/
228 expect(strs).to.match /A \$20 gift card is on its way/
229 process.env.HUBOT_HIGHFIVE_DOUBLE_RATE = '0'
230 do done
231
232
233describe 'config', ->
234 beforeEach prep
235 afterEach cleanup
236
237 it "should respond", (done) ->
238 message_response 'highfive config', 'reply', (e,strs) ->
239 expect(strs).to.match /localhost:8088\/highfive\/$/
240 do done