camper_van 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,433 @@
1
+ require "spec_helper"
2
+
3
+ describe CamperVan::Channel do
4
+
5
+ class TestClient
6
+ attr_reader :sent, :nick, :user, :host
7
+ include CamperVan::ServerReply
8
+ def initialize
9
+ @nick, @user, @host = "nathan", "nathan", "localhost"
10
+ @sent = []
11
+ end
12
+ def send_line(line)
13
+ @sent << line
14
+ end
15
+ def subdomain
16
+ "subdomain"
17
+ end
18
+ end
19
+
20
+ class TestRoom
21
+ attr_reader :locked, :full, :topic, :membership_limit
22
+ attr_reader :sent
23
+
24
+ attr_writer :users, :topic, :locked, :full, :open_to_guests
25
+ attr_writer :stream
26
+
27
+ def initialize
28
+ @users = []
29
+ @sent = []
30
+ @membership_limit = 12
31
+ end
32
+
33
+ def id
34
+ 10
35
+ end
36
+
37
+ def locked?
38
+ @locked
39
+ end
40
+ def full?
41
+ @full
42
+ end
43
+ def open_to_guests?
44
+ @open_to_guests
45
+ end
46
+ def join
47
+ yield
48
+ end
49
+
50
+ def users
51
+ yield @users if block_given?
52
+ @users
53
+ end
54
+
55
+ def text(line)
56
+ @sent << line
57
+ end
58
+
59
+ def tweet(line)
60
+ @sent << [:tweet, line]
61
+ end
62
+
63
+ def stream
64
+ if @messages
65
+ @messages.each { |m| yield m }
66
+ end
67
+ return @stream
68
+ end
69
+ end
70
+
71
+ before :each do
72
+ @client = TestClient.new
73
+ @room = TestRoom.new
74
+ @room.topic = "the topic"
75
+ @channel = CamperVan::Channel.new("#test", @client, @room)
76
+ end
77
+
78
+ describe "#join" do
79
+ it "sends a user join as the command" do
80
+ @channel.join
81
+ @client.sent.first.must_equal ":nathan!nathan@localhost JOIN :#test"
82
+ end
83
+
84
+ it "sends the topic as a command" do
85
+ @channel.join
86
+ @client.sent[1].must_equal ":camper_van 332 nathan #test :the topic"
87
+ end
88
+
89
+ it "sends the list of users" do
90
+ @room.users = [
91
+ OpenStruct.new(:id => 10, :name => "Nathan", :email_address => "x@y.com"),
92
+ OpenStruct.new(:id => 11, :name => "Bob", :email_address => "x@y.com"),
93
+ OpenStruct.new(:id => 12, :name => "Joe", :email_address => "x@y.com")
94
+ ]
95
+ @channel.join
96
+ @client.sent[2].must_equal ":camper_van 353 nathan = #test :nathan bob joe"
97
+ @client.sent[3].must_equal ":camper_van 366 nathan #test :End of /NAMES list."
98
+ end
99
+
100
+ it "sends the list of users including myself, even if the server doesn't say i'm there" do
101
+ @room.users = [
102
+ OpenStruct.new(:id => 11, :name => "Bob", :email_address => "x@y.com"),
103
+ OpenStruct.new(:id => 12, :name => "Joe", :email_address => "x@y.com")
104
+ ]
105
+ @channel.join
106
+ @client.sent[2].must_equal ":camper_van 353 nathan = #test :nathan bob joe"
107
+ end
108
+ end
109
+
110
+ describe "#part" do
111
+ it "sends a part command to the client" do
112
+ @channel.part
113
+ @client.sent.last.must_match /PART #test/
114
+ end
115
+
116
+ it "closes the connection on the stream" do
117
+ @room.stream = MiniTest::Mock.new
118
+ @room.stream.expect(:close_connection, nil)
119
+ @channel.stream_campfire_to_channel # sets up stream
120
+ @channel.part
121
+
122
+ @room.stream.verify
123
+ end
124
+ end
125
+
126
+ describe "#list_users" do
127
+ before :each do
128
+ @room.users = [OpenStruct.new(:id => 10, :name => "Joe", :email_address => "user@example.com")]
129
+ @channel.join
130
+ @client.sent.clear
131
+ end
132
+ it "retrieves a list of users and sends them to the client" do
133
+ @channel.list_users
134
+ @client.sent.first.must_equal(
135
+ ":camper_van 352 nathan #test user example.com camper_van joe H :0 Joe"
136
+ )
137
+ @client.sent.last.must_match /:camper_van 315 nathan #test :End/
138
+ end
139
+
140
+ it "issues JOIN irc commands for users who have joined but aren't yet tracked" do
141
+ @channel.list_users
142
+ @room.users << OpenStruct.new(:id => 11, :name => "Bob", :email_address => "bob@example.com")
143
+ @client.sent.clear
144
+ @channel.list_users
145
+ @client.sent.first.must_match /bob.*JOIN #test/
146
+ end
147
+
148
+ it "issues PART commands for users who have left but are still tracked" do
149
+ @room.users = []
150
+ @channel.list_users
151
+ @client.sent.first.must_match /joe.*PART #test/
152
+ end
153
+
154
+ it "shows a user as away if they are idle" do
155
+ @channel.users[10].idle = true
156
+ @channel.list_users
157
+ @client.sent.first.must_match /joe G :0 Joe/
158
+ end
159
+
160
+ it "shows admin users as having +o" do
161
+ @channel.users[10].admin = true
162
+ @channel.list_users
163
+ @client.sent.first.must_match /joe H@ :0 Joe/
164
+ end
165
+ end
166
+
167
+ describe "#privmsg" do
168
+ it "sends the message as text to the room" do
169
+ @channel.privmsg "hello world"
170
+ @room.sent.first.must_equal "hello world"
171
+ end
172
+
173
+ it "converts ACTION messages to campfire-appropriate messages" do
174
+ @channel.privmsg "\01ACTION runs away\01"
175
+ @room.sent.first.must_equal "*runs away*"
176
+ end
177
+
178
+ it "converts twitter urls to tweet messages" do
179
+ url = "https://twitter.com/aniero/status/12345"
180
+ @channel.privmsg url
181
+ @room.sent.first.must_equal [:tweet, url]
182
+ end
183
+
184
+ it "converts leading nicknames into campfire names" do
185
+ # get the users into the room
186
+ @room.users = [
187
+ OpenStruct.new(:id => 11, :name => "Bob Fred", :email_address => "x@y.com"),
188
+ OpenStruct.new(:id => 12, :name => "Joe", :email_address => "x@y.com")
189
+ ]
190
+ @channel.list_users
191
+
192
+ @channel.privmsg "bob_fred: sup dude"
193
+ @room.sent.last.must_match /Bob Fred: sup dude/
194
+ end
195
+ end
196
+
197
+ describe "#current_mode" do
198
+ it "sends the current mode to the client" do
199
+ @channel.current_mode
200
+ @client.sent.last.must_match ":camper_van 324 nathan #test +ls 12"
201
+ end
202
+
203
+ context "and a locked room" do
204
+ it "includes +i mode" do
205
+ @room.locked = true
206
+ @channel.current_mode
207
+ @client.sent.last.must_match ":camper_van 324 nathan #test +ils 12"
208
+ end
209
+ end
210
+
211
+ context "and a room that allows guests" do
212
+ it "drops the +s from the mode" do
213
+ @room.open_to_guests = true
214
+ @channel.current_mode
215
+ @client.sent.last.must_match ":camper_van 324 nathan #test +l 12"
216
+ end
217
+ end
218
+ end
219
+
220
+ describe "#set_mode" do
221
+ before :each do
222
+ @room = OpenStruct.new :membership_limit => 10
223
+ class << @room
224
+ def locked?
225
+ self.locked
226
+ end
227
+ def lock
228
+ self.lock_called = true
229
+ end
230
+ def unlock
231
+ self.unlock_called = true
232
+ end
233
+ end
234
+ @channel = CamperVan::Channel.new("#test", @client, @room)
235
+ end
236
+
237
+ context "with a +i" do
238
+ it "locks the room" do
239
+ @channel.set_mode "+i"
240
+ @room.lock_called.must_equal true
241
+ @room.locked.must_equal true
242
+ end
243
+
244
+ it "tells the client that the channel mode has changed" do
245
+ @channel.set_mode "+i"
246
+ @client.sent.last.must_match /MODE #test \+ils 10/
247
+ end
248
+ end
249
+
250
+ context "with a -i" do
251
+ it "unlocks the room" do
252
+ @channel.set_mode "-i"
253
+ @room.unlock_called.must_equal true
254
+ @room.locked.must_equal false
255
+ end
256
+
257
+ it "tells the client the channel mode has changed" do
258
+ @channel.set_mode "-i"
259
+ @client.sent.last.must_match /MODE #test \+ls 10/
260
+ end
261
+ end
262
+
263
+ context "with an unknown mode" do
264
+ it "replies with an irc error" do
265
+ @channel.set_mode "+m"
266
+ @client.sent.last.must_match /472 nathan :.*unknown mode/
267
+ end
268
+ end
269
+ end
270
+
271
+ describe "#map_message_to_irc when streaming" do
272
+ class TestMessage < OpenStruct
273
+ def user
274
+ yield OpenStruct.new :name => "Joe", :id => 10, :email_address => "joe@example.com"
275
+ end
276
+ end
277
+
278
+ def msg(type, attributes={})
279
+ TestMessage.new(
280
+ attributes.merge :type => "#{type}Message", :id => 1234
281
+ )
282
+ end
283
+
284
+ it "sends a privmsg with the message when a user says something" do
285
+ @channel.map_message_to_irc msg("Text", :body => "hello")
286
+ @client.sent.last.must_match ":joe!joe@campfire PRIVMSG #test hello"
287
+ end
288
+
289
+ it "sends a privmsg with the pasted url and the first line when a user pastes something" do
290
+ @channel.map_message_to_irc msg("Paste", :body => "foo\nbar\nbaz\nbleh")
291
+ @client.sent.last.must_match %r(:joe\S+ PRIVMSG #test .*room/10/paste/1234)
292
+ end
293
+
294
+ it "sends a privmsg with an action when a user message is wrapped in *'s" do
295
+ @channel.map_message_to_irc msg("Text", :body => "*did a thing*")
296
+ @client.sent.last.must_match /PRIVMSG #test :\x01ACTION did a thing\x01/
297
+ end
298
+
299
+ it "converts leading name matches to irc nicks" do
300
+ # get the users into the room
301
+ @room.users = [
302
+ OpenStruct.new(:id => 11, :name => "Bob Fred", :email_address => "x@y.com"),
303
+ OpenStruct.new(:id => 12, :name => "Joe", :email_address => "x@y.com")
304
+ ]
305
+ @channel.list_users
306
+ @client.sent.clear
307
+
308
+ # now check the mapping
309
+ @channel.map_message_to_irc msg("Text", :body => "Bob Fred: hello")
310
+ @client.sent.last.must_match %r(PRIVMSG #test :bob_fred: hello)
311
+ end
312
+
313
+ it "sends an action when a user plays the crickets sound" do
314
+ @channel.map_message_to_irc msg("Sound", :body => "crickets")
315
+ @client.sent.last.must_match /\x01ACTION hears crickets chirping\x01/
316
+ end
317
+
318
+ it "sends an action when a user plays the rimshot sound" do
319
+ @channel.map_message_to_irc msg("Sound", :body => "rimshot")
320
+ @client.sent.last.must_match /\x01ACTION plays a rimshot\x01/
321
+ end
322
+
323
+ it "sends an action when a user plays the trombone sound" do
324
+ @channel.map_message_to_irc msg("Sound", :body => "trombone")
325
+ @client.sent.last.must_match /\x01ACTION plays a sad trombone\x01/
326
+ end
327
+
328
+ it "sends an action when a user plays the vuvuzela sound" do
329
+ @channel.map_message_to_irc msg("Sound", :body => "vuvuzela")
330
+ @client.sent.last.must_match /ACTION ======<\(\)/
331
+ end
332
+
333
+ it "sends an action when a user plays an unknown sound" do
334
+ @channel.map_message_to_irc msg("Sound", :body => "boing")
335
+ @client.sent.last.must_match /\x01ACTION played a boing sound\x01/
336
+ end
337
+
338
+ it "sends a mode change when the room is locked" do
339
+ @channel.map_message_to_irc msg("Lock")
340
+ @client.sent.last.must_match %r/:joe\S+ MODE #test \+i/
341
+ end
342
+
343
+ it "sends a mode change when the room is unlocked" do
344
+ @channel.map_message_to_irc msg("Unlock")
345
+ @client.sent.last.must_match %r/:joe\S+ MODE #test -i/
346
+ end
347
+
348
+ it "sends a mode change when the room disallows guests" do
349
+ @channel.map_message_to_irc msg("DisallowGuests")
350
+ @client.sent.last.must_match %r/:joe\S+ MODE #test \+s/
351
+ end
352
+
353
+ it "sends a mode change when the room allows guests" do
354
+ @channel.map_message_to_irc msg("AllowGuests")
355
+ @client.sent.last.must_match %r/:joe\S+ MODE #test -s/
356
+ end
357
+
358
+ it "sends a join command when a user enters the room" do
359
+ @channel.map_message_to_irc msg("Enter")
360
+ @client.sent.last.must_match %r/:joe\S+ JOIN #test/
361
+ end
362
+
363
+ it "adds the user to the internal tracking list when a user joins" do
364
+ @channel.map_message_to_irc msg("Enter")
365
+ @client.sent.last.must_match %r/:joe\S+ JOIN #test/
366
+ @channel.users[10].wont_equal nil
367
+ end
368
+
369
+ it "sends a part command when a user leaves the room" do
370
+ @channel.map_message_to_irc msg("Leave")
371
+ @client.sent.last.must_match %r/:joe\S+ PART #test/
372
+ end
373
+
374
+ it "removes the user from the tracking list when they depart" do
375
+ @channel.map_message_to_irc msg("Enter")
376
+ @channel.map_message_to_irc msg("Leave")
377
+ @channel.users.size.must_equal 0
378
+ end
379
+
380
+ it "sends a part command when a user is kicked from the room" do
381
+ @channel.map_message_to_irc msg("Kick")
382
+ @client.sent.last.must_match %r/:joe\S+ PART #test/
383
+ end
384
+
385
+ it "sends a topic command when a user changes the topic" do
386
+ @channel.map_message_to_irc msg("TopicChange", :body => "new topic")
387
+ @client.sent.last.must_match ":joe!joe@campfire TOPIC #test :new topic"
388
+ end
389
+
390
+ it "sends a message containing the upload link when a user uploads a file" do
391
+ @channel.map_message_to_irc msg("Upload", :body => "filename")
392
+ @client.sent.last.must_match %r(:joe\S+ PRIVMSG #test .*uploads/1234/filename)
393
+ end
394
+
395
+ it "sends a message containing the tweet url when a user posts a tweet" do
396
+ body = {
397
+ "id" => 12345,
398
+ "author_username" => "aniero",
399
+ "message" => "hello, twitter",
400
+ "author_avatar_url" => "http://example.com/url.img"
401
+ }
402
+ @channel.map_message_to_irc msg("Tweet", :body => body.to_yaml)
403
+ @client.sent.last.must_match %r(:joe\S+ PRIVMSG #test .*twitter.com/aniero/status/12345.*)
404
+ end
405
+
406
+ it "sends a message containing the tweet url when a user posts a tweet with symbols" do
407
+ body = {
408
+ :id => 12345,
409
+ :author_username => "aniero",
410
+ :message => "hello, twitter",
411
+ :author_avatar_url => "http://example.com/url.img"
412
+ }
413
+ @channel.map_message_to_irc msg("Tweet", :body => body.to_yaml)
414
+ @client.sent.last.must_match %r(:joe\S+ PRIVMSG #test .*twitter.com/aniero/status/12345.*)
415
+ end
416
+
417
+ # it "sends a notice with the message when the system sends a message"
418
+
419
+ it "marks the user as away when a user goes idle" do
420
+ @channel.map_message_to_irc msg("Enter")
421
+ @channel.map_message_to_irc msg("Idle")
422
+ @channel.users[10].idle?.must_equal true
423
+ end
424
+
425
+ it "marks the user as back when a user becomes active" do
426
+ @channel.map_message_to_irc msg("Enter")
427
+ @channel.map_message_to_irc msg("Idle")
428
+ @channel.map_message_to_irc msg("Unidle")
429
+ @channel.users[10].idle?.must_equal false
430
+ end
431
+ end
432
+ end
433
+
@@ -0,0 +1,54 @@
1
+ require "spec_helper"
2
+
3
+ describe CamperVan::CommandDefinition do
4
+ before :each do
5
+ @test_commands = Class.new do
6
+ include CamperVan::CommandDefinition
7
+ attr_accessor :nick
8
+
9
+ handle :nick do |args|
10
+ @nick = args.first
11
+ args
12
+ end
13
+
14
+ end
15
+ end
16
+
17
+ it "defines a handle class method on a class" do
18
+ @test_commands.must_respond_to :handle
19
+ end
20
+
21
+ it "defines a handle instance method on a class" do
22
+ @test_commands.new.must_respond_to :handle
23
+ end
24
+
25
+ describe "#handle" do
26
+ before :each do
27
+ @cmd = @test_commands.new
28
+ end
29
+
30
+ it "raises an exception when no handler is available" do
31
+ lambda { @cmd.handle(:foo => []) }.must_raise(CamperVan::HandlerMissing)
32
+ end
33
+
34
+ it "passes the arguments to the block" do
35
+ @cmd.handle(:nick => %w(lol what)).must_equal %w(lol what)
36
+ end
37
+
38
+ it "evaluates the block in the instance context" do
39
+ @cmd.nick.must_equal nil
40
+ @cmd.handle(:nick => ["bob"])
41
+ @cmd.nick.must_equal "bob"
42
+ end
43
+ end
44
+
45
+ describe ".handle" do
46
+ it "defines a handler for the given command" do
47
+ @test_commands.handle :foo do
48
+ "success"
49
+ end
50
+ @test_commands.new.handle(:foo => []).must_equal "success"
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ describe CamperVan::CommandParser do
4
+ class TestParser
5
+ include CamperVan::CommandParser
6
+ end
7
+
8
+ it "defines a parse method on a class that includes it" do
9
+ TestParser.new.must_respond_to :parse
10
+ end
11
+
12
+ describe "#parse" do
13
+ before :each do
14
+ @parser = TestParser.new
15
+ end
16
+
17
+ it "returns nil for a malformed command" do
18
+ @parser.parse("lolwhat").must_equal nil
19
+ end
20
+
21
+ it "parses a LIST command" do
22
+ @parser.parse("LIST").must_equal :list => []
23
+ end
24
+
25
+ it "parses a NICK command" do
26
+ @parser.parse("NICK nathan").must_equal :nick => ["nathan"]
27
+ end
28
+
29
+ it "parses a PRIVMSG command" do
30
+ @parser.parse("PRIVMSG #chan :hello there").must_equal(
31
+ :privmsg => ["#chan", "hello there"]
32
+ )
33
+ end
34
+
35
+ it "parses a MODE command" do
36
+ @parser.parse("MODE +i").must_equal :mode => ["+i"]
37
+ end
38
+ end
39
+
40
+ end