flamethrower 0.3.0 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -0
- data/README.rdoc +11 -5
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/bin/flamethrower +1 -1
- data/bin/flamethrowerd +20 -0
- data/flamethrower.gemspec +18 -10
- data/flamethrower.yml.example +6 -0
- data/lib/flamethrower.rb +3 -1
- data/lib/flamethrower/ascii_imager.rb +16 -0
- data/lib/flamethrower/campfire/connection.rb +8 -11
- data/lib/flamethrower/campfire/message.rb +58 -2
- data/lib/flamethrower/campfire/rest_api.rb +15 -8
- data/lib/flamethrower/campfire/room.rb +106 -23
- data/lib/flamethrower/{server.rb → connection.rb} +5 -4
- data/lib/flamethrower/dispatcher.rb +29 -28
- data/lib/flamethrower/irc/codes.rb +1 -0
- data/lib/flamethrower/irc/commands.rb +8 -1
- data/lib/flamethrower/server/event_server.rb +13 -7
- data/lib/flamethrower/server/{mock_server.rb → mock_connection.rb} +6 -2
- data/spec/fixtures/recent_messages.json +1 -0
- data/spec/fixtures/streaming_image_message.json +1 -0
- data/spec/fixtures/tweet_message.json +1 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/campfire/connection_spec.rb +20 -17
- data/spec/unit/campfire/message_spec.rb +66 -0
- data/spec/unit/campfire/room_spec.rb +221 -14
- data/spec/unit/{server_spec.rb → connection_spec.rb} +51 -41
- data/spec/unit/dispatcher_spec.rb +63 -45
- data/spec/unit/irc/channel_spec.rb +3 -3
- data/spec/unit/irc/message_spec.rb +2 -2
- data/spec/unit/server/event_server_spec.rb +20 -1
- metadata +30 -9
@@ -1,5 +1,5 @@
|
|
1
1
|
module Flamethrower
|
2
|
-
module
|
2
|
+
module Connection
|
3
3
|
include Flamethrower::Irc::Commands
|
4
4
|
|
5
5
|
attr_accessor :campfire_connection, :current_user, :dispatcher, :irc_channels
|
@@ -11,6 +11,7 @@ module Flamethrower
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def after_connect
|
14
|
+
send_welcome
|
14
15
|
send_motd
|
15
16
|
populate_irc_channels
|
16
17
|
populate_my_user
|
@@ -23,10 +24,10 @@ module Flamethrower
|
|
23
24
|
end
|
24
25
|
|
25
26
|
def receive_data(msg)
|
26
|
-
|
27
|
-
|
28
|
-
dispatcher.handle_message(Flamethrower::Irc::Message.new(message))
|
27
|
+
@data ||= ::BufferedTokenizer.new("\r\n")
|
28
|
+
@data.extract(msg).each do |message|
|
29
29
|
::FLAMETHROWER_LOGGER.debug "<< #{message}"
|
30
|
+
dispatcher.handle_message(Flamethrower::Irc::Message.new(message))
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module Flamethrower
|
2
2
|
class Dispatcher
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :connection
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize(connection)
|
6
|
+
@connection = connection
|
7
7
|
end
|
8
8
|
|
9
9
|
def handle_message(message)
|
@@ -14,11 +14,11 @@ module Flamethrower
|
|
14
14
|
private
|
15
15
|
|
16
16
|
def find_channel_or_error(name, error=Flamethrower::Irc::Codes::ERR_BADCHANNELKEY)
|
17
|
-
channel =
|
17
|
+
channel = connection.irc_channels.detect {|channel| channel.name == name}
|
18
18
|
if channel && block_given?
|
19
19
|
yield(channel)
|
20
20
|
else
|
21
|
-
|
21
|
+
connection.send_message(connection.error(error))
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -33,44 +33,44 @@ module Flamethrower
|
|
33
33
|
|
34
34
|
def handle_ping(message)
|
35
35
|
hostname = message.parameters.first
|
36
|
-
|
36
|
+
connection.send_pong(hostname)
|
37
37
|
end
|
38
38
|
|
39
39
|
def handle_user(message)
|
40
40
|
username, hostname, servername, realname = message.parameters
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
if
|
46
|
-
|
41
|
+
connection.current_user.username ||= username
|
42
|
+
connection.current_user.hostname ||= hostname
|
43
|
+
connection.current_user.servername ||= servername
|
44
|
+
connection.current_user.realname ||= realname
|
45
|
+
if connection.current_user.nick_set? && connection.current_user.user_set?
|
46
|
+
connection.after_connect
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
50
|
def handle_nick(message)
|
51
51
|
nickname = message.parameters.first
|
52
|
-
|
53
|
-
if
|
54
|
-
|
52
|
+
connection.current_user.nickname = nickname
|
53
|
+
if connection.current_user.nick_set? && connection.current_user.user_set?
|
54
|
+
connection.after_connect
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
58
|
def handle_topic(message)
|
59
59
|
find_channel_or_error(message.parameters.first) do |channel|
|
60
60
|
channel.to_campfire.send_topic(message.parameters.last) if message.parameters.size > 1
|
61
|
-
|
61
|
+
connection.send_topic(channel)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
def handle_mode(message)
|
66
66
|
first_param = message.parameters.first
|
67
67
|
error = Flamethrower::Irc::Codes::ERR_UNKNOWNCOMMAND
|
68
|
-
if first_param ==
|
69
|
-
|
68
|
+
if first_param == connection.current_user.nickname
|
69
|
+
connection.send_user_mode
|
70
70
|
return
|
71
71
|
else
|
72
72
|
find_channel_or_error(first_param, error) do |channel|
|
73
|
-
|
73
|
+
connection.send_channel_mode(channel)
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
@@ -78,26 +78,27 @@ module Flamethrower
|
|
78
78
|
def handle_join(message)
|
79
79
|
find_channel_or_error(message.parameters.first) do |channel|
|
80
80
|
room = channel.to_campfire
|
81
|
-
channel.users <<
|
81
|
+
channel.users << connection.current_user
|
82
82
|
room.join
|
83
83
|
room.start
|
84
|
+
connection.send_join(connection.current_user, channel)
|
84
85
|
end
|
85
86
|
end
|
86
87
|
|
87
88
|
def handle_away(message)
|
88
89
|
away_message = message.parameters.first
|
89
|
-
if away_message.empty?
|
90
|
-
|
91
|
-
|
90
|
+
if !away_message || away_message.empty?
|
91
|
+
connection.current_user.away_message = nil
|
92
|
+
connection.send_unaway
|
92
93
|
else
|
93
|
-
|
94
|
-
|
94
|
+
connection.current_user.away_message = away_message
|
95
|
+
connection.send_nowaway
|
95
96
|
end
|
96
97
|
end
|
97
98
|
|
98
99
|
def handle_who(message)
|
99
100
|
find_channel_or_error(message.parameters.first) do |channel|
|
100
|
-
|
101
|
+
connection.send_who(channel)
|
101
102
|
end
|
102
103
|
end
|
103
104
|
|
@@ -105,12 +106,12 @@ module Flamethrower
|
|
105
106
|
find_channel_or_error(message.parameters.first) do |channel|
|
106
107
|
room = channel.to_campfire
|
107
108
|
room.stop
|
108
|
-
|
109
|
+
connection.send_part(connection.current_user, channel)
|
109
110
|
end
|
110
111
|
end
|
111
112
|
|
112
113
|
def handle_quit(message)
|
113
|
-
|
114
|
+
connection.irc_channels.each {|c| c.to_campfire.stop}
|
114
115
|
end
|
115
116
|
end
|
116
117
|
end
|
@@ -3,10 +3,13 @@ module Flamethrower
|
|
3
3
|
module Commands
|
4
4
|
include Flamethrower::Irc::Codes
|
5
5
|
|
6
|
+
def send_welcome
|
7
|
+
send_message reply(RPL_WLCM, ":Welcome to Flamethrower")
|
8
|
+
end
|
9
|
+
|
6
10
|
def send_motd
|
7
11
|
send_messages do |messages|
|
8
12
|
messages << reply(RPL_MOTDSTART, ":MOTD")
|
9
|
-
messages << reply(RPL_MOTD, ":Welcome to Flamethrower")
|
10
13
|
messages << reply(RPL_MOTD, ":Fetching channel list from campfire...")
|
11
14
|
end
|
12
15
|
end
|
@@ -66,6 +69,10 @@ module Flamethrower
|
|
66
69
|
send_message reply(RPL_UMODEIS, @current_user.mode)
|
67
70
|
end
|
68
71
|
|
72
|
+
def send_join(user, channel)
|
73
|
+
send_message ":#{user.to_s} JOIN #{channel.name}"
|
74
|
+
end
|
75
|
+
|
69
76
|
def send_part(user, channel)
|
70
77
|
send_message ":#{user.to_s} PART #{channel.name}"
|
71
78
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Flamethrower
|
2
2
|
class EventConnection < EventMachine::Connection
|
3
|
-
include Flamethrower::
|
3
|
+
include Flamethrower::Connection
|
4
4
|
|
5
5
|
attr_accessor :server
|
6
6
|
|
@@ -22,13 +22,19 @@ module Flamethrower
|
|
22
22
|
end
|
23
23
|
|
24
24
|
class EventServer
|
25
|
-
attr_reader :host, :port, :campfire_connection, :connections
|
25
|
+
attr_reader :host, :port, :ascii_conversion, :campfire_connection, :connections
|
26
|
+
ASCII_DEFAULTS = {
|
27
|
+
'enabled' => true
|
28
|
+
}
|
26
29
|
|
27
|
-
def initialize(
|
28
|
-
@host = host || "0.0.0.0"
|
29
|
-
@port = port || 6667
|
30
|
-
@domain = domain
|
31
|
-
@token = token
|
30
|
+
def initialize(options = {})
|
31
|
+
@host = options['host'] || "0.0.0.0"
|
32
|
+
@port = options['port'] || 6667
|
33
|
+
@domain = options['domain']
|
34
|
+
@token = options['token']
|
35
|
+
@ascii_conversion = options['ascii_conversion'] ?
|
36
|
+
ASCII_DEFAULTS.merge(options['ascii_conversion']) :
|
37
|
+
ASCII_DEFAULTS
|
32
38
|
@connections = []
|
33
39
|
end
|
34
40
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Flamethrower
|
2
|
-
class
|
3
|
-
include Flamethrower::
|
2
|
+
class MockConnection
|
3
|
+
include Flamethrower::Connection
|
4
4
|
|
5
5
|
def send_data(msg)
|
6
6
|
end
|
@@ -9,5 +9,9 @@ module Flamethrower
|
|
9
9
|
Flamethrower::Campfire::Connection.new("mydomain", "mytoken", self)
|
10
10
|
end
|
11
11
|
|
12
|
+
def server
|
13
|
+
Flamethrower::EventServer.new
|
14
|
+
end
|
15
|
+
|
12
16
|
end
|
13
17
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"messages":[{"type":"KickMessage","room_id":347348,"created_at":"2011/05/02 04:30:15 +0000","id":344873939,"body":null,"user_id":899091},{"type":"TimestampMessage","room_id":347348,"created_at":"2011/05/02 17:45:00 +0000","id":345107174,"body":null,"user_id":null},{"type":"EnterMessage","room_id":347348,"created_at":"2011/05/02 17:45:17 +0000","id":345107175,"body":null,"user_id":734581},{"type":"EnterMessage","room_id":347348,"created_at":"2011/05/02 17:45:58 +0000","id":345107527,"body":null,"user_id":899091},{"type":"TextMessage","room_id":347348,"created_at":"2011/05/02 17:46:33 +0000","id":345107811,"body":"http://www.berkeleytwpschools.com/bts/Potter/Classroom%20Web%20Pages/Library/Links%20of%20the%20Month/___zumuhead.html_files/sad-eyes-dog-puppy-clip-art-thumb3033696.jpg","user_id":899091},{"type":"TimestampMessage","room_id":347348,"created_at":"2011/05/02 18:00:00 +0000","id":345116388,"body":null,"user_id":null},{"type":"KickMessage","room_id":347348,"created_at":"2011/05/02 18:00:27 +0000","id":345116389,"body":null,"user_id":734581},{"type":"KickMessage","room_id":347348,"created_at":"2011/05/02 18:00:27 +0000","id":345116395,"body":null,"user_id":899091},{"type":"TimestampMessage","room_id":347348,"created_at":"2011/05/09 04:00:00 +0000","id":347880310,"body":null,"user_id":null},{"type":"EnterMessage","room_id":347348,"created_at":"2011/05/09 04:01:34 +0000","id":347880311,"body":null,"user_id":734581}]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"room_id":73541,"created_at":"2010/12/14 20:09:23 +0000","body":"http://example.com/kitties.jpg","id":289361911,"user_id":489198,"type":"TextMessage"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"room_id":73541,"created_at":"2011/01/26 16:34:46 +0000","body":"--- \n:author_username: jeresig\n:author_avatar_url: http://a1.twimg.com/profile_images/1181631474/john_normal.jpg\n:message: \"A hilarious video pops up after you unsubscribe from Groupon emails: http://j.mp/hpes49 Punish the developer!\"\n:id: 30293022537162752\n","id":304070140,"user_id":703609,"type":"TweetMessage"}
|
data/spec/spec_helper.rb
CHANGED
@@ -2,26 +2,26 @@ require File.join(File.dirname(__FILE__), "../../spec_helper")
|
|
2
2
|
|
3
3
|
describe Flamethrower::Campfire::Connection do
|
4
4
|
before do
|
5
|
-
@
|
6
|
-
@
|
5
|
+
@connection = Flamethrower::MockConnection.new
|
6
|
+
@campfire_connection = @connection.campfire_connection
|
7
7
|
end
|
8
8
|
|
9
9
|
describe "#fetch_my_user" do
|
10
|
-
it "retrieves my user and stores it on the
|
10
|
+
it "retrieves my user and stores it on the campfire_connection" do
|
11
11
|
stub_request(:get, "https://mydomain.campfirenow.com/users/me.json").
|
12
12
|
with(:headers => {'Authorization'=>['mytoken', 'x']}).
|
13
13
|
to_return(:status => 200, :body => json_fixture("user"))
|
14
|
-
EM.run_block { @
|
15
|
-
@
|
14
|
+
EM.run_block { @campfire_connection.fetch_my_user }
|
15
|
+
@connection.current_user.nickname.should == "blake"
|
16
16
|
end
|
17
17
|
|
18
18
|
it "renames your current user to the new current user" do
|
19
|
-
@
|
19
|
+
@connection.current_user = Flamethrower::Irc::User.new(:nickname => "bob")
|
20
20
|
stub_request(:get, "https://mydomain.campfirenow.com/users/me.json").
|
21
21
|
with(:headers => {'Authorization'=>['mytoken', 'x']}).
|
22
22
|
to_return(:status => 200, :body => json_fixture("user"))
|
23
|
-
@
|
24
|
-
EM.run_block { @
|
23
|
+
@connection.should_receive(:send_message).with(":bob NICK blake")
|
24
|
+
EM.run_block { @campfire_connection.fetch_my_user }
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -30,8 +30,8 @@ describe Flamethrower::Campfire::Connection do
|
|
30
30
|
stub_request(:get, "https://mydomain.campfirenow.com/rooms.json").
|
31
31
|
with(:headers => {'Authorization'=>['mytoken', 'x']}).
|
32
32
|
to_return(:status => 200, :body => json_fixture("rooms"))
|
33
|
-
EM.run_block { @
|
34
|
-
room = @
|
33
|
+
EM.run_block { @campfire_connection.fetch_rooms }
|
34
|
+
room = @connection.irc_channels.first.to_campfire
|
35
35
|
room.number.should == 347348
|
36
36
|
room.name.should == "Room 1"
|
37
37
|
room.topic.should == "some topic"
|
@@ -41,7 +41,7 @@ describe Flamethrower::Campfire::Connection do
|
|
41
41
|
stub_request(:get, "https://mydomain.campfirenow.com/rooms.json").
|
42
42
|
with(:headers => {'Authorization'=>['mytoken', 'x']}).
|
43
43
|
to_return(:status => 200, :body => json_fixture("rooms"))
|
44
|
-
EM.run_block { @
|
44
|
+
EM.run_block { @campfire_connection.fetch_rooms }
|
45
45
|
assert_requested(:get, "https://mydomain.campfirenow.com/rooms.json") {|req| req.headers['Authorization'].should == ["mytoken", "x"]}
|
46
46
|
end
|
47
47
|
|
@@ -49,14 +49,17 @@ describe Flamethrower::Campfire::Connection do
|
|
49
49
|
stub_request(:get, "https://mydomain.campfirenow.com/rooms.json").
|
50
50
|
with(:headers => {'Authorization'=>['mytoken', 'x']}).
|
51
51
|
to_return(:status => 400)
|
52
|
-
EM.run_block { @
|
53
|
-
@
|
52
|
+
EM.run_block { @campfire_connection.fetch_rooms }
|
53
|
+
@connection.irc_channels.should == []
|
54
54
|
end
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
it "sends a motd error message if unable to fetch room list" do
|
57
|
+
stub_request(:get, "https://mydomain.campfirenow.com/rooms.json").
|
58
|
+
with(:headers => {'Authorization'=>['mytoken', 'x']}).
|
59
|
+
to_timeout
|
60
|
+
@connection.should_receive(:send_message).with(@connection.reply(Flamethrower::Irc::Codes::RPL_MOTD, ":ERROR: Unable to make API call GET /rooms.json. Check your connection?"))
|
61
|
+
EM.run_block { @campfire_connection.fetch_rooms }
|
62
|
+
@connection.irc_channels.should == []
|
60
63
|
end
|
61
64
|
end
|
62
65
|
|
@@ -75,6 +75,72 @@ describe Flamethrower::Campfire::Message do
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
describe "#image_urls" do
|
79
|
+
it "returns a standalone image url" do
|
80
|
+
@message.body = "http://example.com/kitties.jpg"
|
81
|
+
@message.image_urls.should == ["http://example.com/kitties.jpg"]
|
82
|
+
end
|
83
|
+
|
84
|
+
it "supports jpeg" do
|
85
|
+
@message.body = "http://example.com/kitties.jpeg"
|
86
|
+
@message.image_urls.should == ["http://example.com/kitties.jpeg"]
|
87
|
+
end
|
88
|
+
|
89
|
+
it "supports gif" do
|
90
|
+
@message.body = "http://example.com/kitties.gif"
|
91
|
+
@message.image_urls.should == ["http://example.com/kitties.gif"]
|
92
|
+
end
|
93
|
+
|
94
|
+
it "supports png" do
|
95
|
+
@message.body = "http://example.com/kitties.png"
|
96
|
+
@message.image_urls.should == ["http://example.com/kitties.png"]
|
97
|
+
end
|
98
|
+
|
99
|
+
it "supports multiple images" do
|
100
|
+
@message.body = "http://example.com/kitties.png http://blah.com/duppy-pogs.png"
|
101
|
+
@message.image_urls.should == ["http://example.com/kitties.png", "http://blah.com/duppy-pogs.png"]
|
102
|
+
end
|
103
|
+
|
104
|
+
it "supports interleaved urls with messages" do
|
105
|
+
@message.body = "check this out: http://example.com/kitties.png"
|
106
|
+
@message.image_urls.should == ["http://example.com/kitties.png"]
|
107
|
+
end
|
108
|
+
|
109
|
+
it "supports upcased image extensions" do
|
110
|
+
@message.body = "check this out: http://example.com/kitties.PNG"
|
111
|
+
@message.image_urls.should == ["http://example.com/kitties.PNG"]
|
112
|
+
end
|
113
|
+
|
114
|
+
it "supports https image links" do
|
115
|
+
@message.body = "check this out: https://example.com/kitties.png"
|
116
|
+
@message.image_urls.should == ["https://example.com/kitties.png"]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "#has_images?" do
|
121
|
+
it "returns true if there are images present in the body" do
|
122
|
+
@message.body = "look ma! kitties! http://example.com/kitties.jpg"
|
123
|
+
@message.should have_images
|
124
|
+
end
|
125
|
+
|
126
|
+
it "returns false if there are no images present in the body" do
|
127
|
+
@message.body = "i love lamp, i really do"
|
128
|
+
@message.should_not have_images
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#needs_conversion?" do
|
133
|
+
it "returns true if the image hasn't been converted yet" do
|
134
|
+
@message.body = "look ma! kitties! http://example.com/kitties.jpg"
|
135
|
+
@message.should be_needs_image_conversion
|
136
|
+
end
|
137
|
+
|
138
|
+
it "returns false if the image has already been converted" do
|
139
|
+
@message.set_ascii_image("LOLCATS ASCII HERE!")
|
140
|
+
@message.should_not be_needs_image_conversion
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
78
144
|
describe "#mark_delivered!" do
|
79
145
|
it "sets the status to delivered" do
|
80
146
|
@message.status.should_not == "delivered"
|
@@ -2,9 +2,9 @@ require File.join(File.dirname(__FILE__), "../../spec_helper")
|
|
2
2
|
|
3
3
|
describe Flamethrower::Campfire::Room do
|
4
4
|
before do
|
5
|
-
@
|
5
|
+
@connection = Flamethrower::MockConnection.new
|
6
6
|
@room = Flamethrower::Campfire::Room.new("mydomain", "mytoken", "id" => 347348, "topic" => "some topic", "name" => "some name")
|
7
|
-
@room.
|
7
|
+
@room.connection = @connection
|
8
8
|
@user = Flamethrower::Campfire::User.new('name' => "bob", 'id' => 489198)
|
9
9
|
@user2 = Flamethrower::Campfire::User.new('name' => "bill", 'id' => 123456)
|
10
10
|
end
|
@@ -30,6 +30,38 @@ describe Flamethrower::Campfire::Room do
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
describe "#on_reconnect" do
|
34
|
+
it "writes to the log that it reconnected" do
|
35
|
+
message = "Reconnected to some name stream"
|
36
|
+
::FLAMETHROWER_LOGGER.should_receive(:debug).with(message)
|
37
|
+
|
38
|
+
@room.on_reconnect
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#on_max_reconnects" do
|
43
|
+
before do
|
44
|
+
@room.instance_variable_set("@stream", mock(:stream))
|
45
|
+
end
|
46
|
+
|
47
|
+
it "writes to the log that it has failed to reconnect" do
|
48
|
+
@room.stub(:setup_reconnect)
|
49
|
+
message = "Failed to reconnect to some name, restarting room in 20 seconds"
|
50
|
+
::FLAMETHROWER_LOGGER.should_receive(:debug).with(message)
|
51
|
+
|
52
|
+
@room.on_max_reconnects
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#on_error" do
|
57
|
+
it "writes to the log that there was an error" do
|
58
|
+
message = "There was an error connecting to some name stream"
|
59
|
+
::FLAMETHROWER_LOGGER.should_receive(:debug).with(message)
|
60
|
+
|
61
|
+
@room.on_error
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
33
65
|
describe "#send_topic!" do
|
34
66
|
it "sets the topic when the campfire API returns 200" do
|
35
67
|
stub_request(:put, "https://mydomain.campfirenow.com/room/347348.json").
|
@@ -47,6 +79,40 @@ describe Flamethrower::Campfire::Room do
|
|
47
79
|
EM.run_block { @room.send_topic("some updated topic") }
|
48
80
|
@room.topic.should == "some old topic"
|
49
81
|
end
|
82
|
+
|
83
|
+
it "sends a motd error message if the send_topic call times out" do
|
84
|
+
stub_request(:put, "https://mydomain.campfirenow.com/room/347348.json").
|
85
|
+
with(:headers => {'Authorization'=>['mytoken', 'x'], 'Content-Type'=>'application/json'}).
|
86
|
+
to_timeout
|
87
|
+
@connection.should_receive(:send_message).with(@connection.reply(Flamethrower::Irc::Codes::RPL_MOTD, ":ERROR: Unable to make API call PUT /room/347348.json. Check your connection?"))
|
88
|
+
@room.instance_variable_set("@topic", "some old topic")
|
89
|
+
EM.run_block { @room.send_topic("some updated topic") }
|
90
|
+
@room.topic.should == "some old topic"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "#stop" do
|
95
|
+
it "should stop the stream" do
|
96
|
+
EventMachine.stub(:cancel_timer)
|
97
|
+
@room.instance_variable_set("@stream", mock(:stream, :stop => nil))
|
98
|
+
@room.stream.should_receive(:stop)
|
99
|
+
@room.stop
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should cancel the timers" do
|
103
|
+
timer = mock(:timer)
|
104
|
+
@room.instance_variable_set("@polling_timer", timer)
|
105
|
+
@room.instance_variable_set("@periodic_timer", timer)
|
106
|
+
EventMachine.should_receive(:cancel_timer).with(timer).twice
|
107
|
+
@room.stop
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should flip all the appropriate stop booleans" do
|
111
|
+
EventMachine.stub(:cancel_timer)
|
112
|
+
@room.stop
|
113
|
+
@room.should_not be_alive
|
114
|
+
@room.instance_variable_get("@room_info_set").should be_false
|
115
|
+
end
|
50
116
|
end
|
51
117
|
|
52
118
|
describe "#fetch_room_info" do
|
@@ -54,6 +120,7 @@ describe Flamethrower::Campfire::Room do
|
|
54
120
|
stub_request(:get, "https://mydomain.campfirenow.com/room/347348.json").
|
55
121
|
with(:headers => {'Authorization'=>['mytoken', 'x']}).
|
56
122
|
to_return(:status => 200, :body => json_fixture("room"))
|
123
|
+
@room.stub(:fetch_recent_messages)
|
57
124
|
end
|
58
125
|
|
59
126
|
it "retrieves a list of users and stores them as user objects" do
|
@@ -71,6 +138,31 @@ describe Flamethrower::Campfire::Room do
|
|
71
138
|
EM.run_block { @room.fetch_room_info }
|
72
139
|
assert_requested(:get, "https://mydomain.campfirenow.com/room/347348.json") {|req| req.headers['Authorization'].should == ["mytoken", "x"]}
|
73
140
|
end
|
141
|
+
|
142
|
+
it "calls fetch_recent_messages if the room_info_set is false" do
|
143
|
+
@room.instance_variable_set("@room_info_sent", false)
|
144
|
+
@room.should_receive(:fetch_recent_messages)
|
145
|
+
EM.run_block { @room.fetch_room_info }
|
146
|
+
end
|
147
|
+
|
148
|
+
it "doesn't call fetch_recent_messages if the room_info_sent = true" do
|
149
|
+
@room.instance_variable_set("@room_info_sent", true)
|
150
|
+
@room.should_not_receive(:fetch_recent_messages)
|
151
|
+
EM.run_block { @room.fetch_room_info }
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "#fetch_recent_messages" do
|
156
|
+
before do
|
157
|
+
stub_request(:get, "https://mydomain.campfirenow.com/room/347348/recent.json?limit=10").
|
158
|
+
with(:headers => {'Authorization'=>['mytoken', 'x']}).
|
159
|
+
to_return(:status => 200, :body => json_fixture("recent_messages"))
|
160
|
+
end
|
161
|
+
|
162
|
+
it "retrieves the most recent 10 messages and sends them to the inbound message queue" do
|
163
|
+
EM.run_block { @room.fetch_recent_messages }
|
164
|
+
@room.instance_variable_get("@users_to_fetch").size.should == 7
|
165
|
+
end
|
74
166
|
end
|
75
167
|
|
76
168
|
describe "#resolve renames" do
|
@@ -87,12 +179,48 @@ describe Flamethrower::Campfire::Room do
|
|
87
179
|
bob2.name = "Bob Hope"
|
88
180
|
new_users = [blake2, bob2, bill]
|
89
181
|
|
90
|
-
@room.
|
91
|
-
@room.
|
182
|
+
@room.connection.should_receive(:send_rename).with("blake", "Blake_Smith")
|
183
|
+
@room.connection.should_receive(:send_rename).with("bob", "Bob_Hope")
|
184
|
+
@room.resolve_renames(old_users, new_users)
|
185
|
+
end
|
186
|
+
|
187
|
+
it "doesn't rename if old_users has a user that new_users doesn't" do
|
188
|
+
blake = Flamethrower::Campfire::User.new('id' => 1, 'name' => 'blake')
|
189
|
+
bob = Flamethrower::Campfire::User.new('id' => 2, 'name' => 'bob')
|
190
|
+
bill = Flamethrower::Campfire::User.new('id' => 3, 'name' => 'bill')
|
191
|
+
old_users = [blake, bob, bill]
|
192
|
+
new_users = [blake, bob]
|
193
|
+
|
194
|
+
@room.connection.should_not_receive(:send_rename)
|
92
195
|
@room.resolve_renames(old_users, new_users)
|
93
196
|
end
|
94
197
|
end
|
95
198
|
|
199
|
+
describe "#fetch_images" do
|
200
|
+
it "makes a call to the image ascii service to convert the image" do
|
201
|
+
stub_request(:get, "http://skeeter.blakesmith.me/?image_url=http://example.com/kitties.jpg&width=80").
|
202
|
+
to_return(:status => 200, :body => "LOLCAT ASCII ART HERE!")
|
203
|
+
@message = Flamethrower::Campfire::Message.new(JSON.parse(json_fixture("streaming_image_message")))
|
204
|
+
@room.instance_variable_get("@images_to_fetch") << @message
|
205
|
+
EM.run_block { @room.fetch_images }
|
206
|
+
expected_body = "http://example.com/kitties.jpg\n"
|
207
|
+
expected_body << "LOLCAT ASCII ART HERE!"
|
208
|
+
@message.body.should == expected_body
|
209
|
+
end
|
210
|
+
|
211
|
+
context "when the image get call fails" do
|
212
|
+
it "marks the message as failed and puts it into the failed messages" do
|
213
|
+
stub_request(:get, "http://skeeter.blakesmith.me/?image_url=http://example.com/kitties.jpg&width=80").
|
214
|
+
to_return(:status => 400, :body => "An error has occured")
|
215
|
+
@message = Flamethrower::Campfire::Message.new(JSON.parse(json_fixture("streaming_image_message")))
|
216
|
+
@message.user = mock('user')
|
217
|
+
@room.instance_variable_get("@images_to_fetch") << @message
|
218
|
+
EM.run_block { @room.fetch_images }
|
219
|
+
@room.instance_variable_get("@failed_messages").size.should == 1
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
96
224
|
describe "#fetch_users" do
|
97
225
|
it "makes a call to the campfire api to fetch user information" do
|
98
226
|
stub_request(:get, "https://mydomain.campfirenow.com/users/734581.json").
|
@@ -104,9 +232,8 @@ describe Flamethrower::Campfire::Room do
|
|
104
232
|
end
|
105
233
|
|
106
234
|
it "fetches using the 'user_id' field if a streaming message" do
|
107
|
-
stub_request(:get, "https://mytoken:x@mydomain.campfirenow.com/users/734581.json").to_return(:body => json_fixture("user"), :status => 200)
|
108
235
|
@room.instance_variable_get("@users_to_fetch") << Flamethrower::Campfire::Message.new(JSON.parse(json_fixture("enter_message")))
|
109
|
-
@room.should_receive(:campfire_get).with("/users/734581.json").and_return(mock(:
|
236
|
+
@room.should_receive(:campfire_get).with("/users/734581.json").and_return(mock(:get, :callback => nil))
|
110
237
|
EM.run_block { @room.fetch_users }
|
111
238
|
end
|
112
239
|
|
@@ -115,7 +242,9 @@ describe Flamethrower::Campfire::Room do
|
|
115
242
|
stub_request(:get, "https://mydomain.campfirenow.com/users/734581.json").
|
116
243
|
with(:headers => {'Authorization'=>['mytoken', 'x']}).
|
117
244
|
to_return(:status => 200, :body => json_fixture("user"))
|
118
|
-
|
245
|
+
json = JSON.parse(json_fixture('enter_message'))
|
246
|
+
json['direction'] = 'inbound'
|
247
|
+
@room.instance_variable_get("@users_to_fetch") << Flamethrower::Campfire::Message.new(json)
|
119
248
|
EM.run_block { @room.fetch_users }
|
120
249
|
message = @room.inbound_messages.pop.user.number.should == 734581
|
121
250
|
end
|
@@ -130,6 +259,15 @@ describe Flamethrower::Campfire::Room do
|
|
130
259
|
EM.run_block { @room.fetch_users }
|
131
260
|
message = @room.inbound_messages.size.should == 0
|
132
261
|
end
|
262
|
+
|
263
|
+
it "marks the message as failed and puts it into failed messages" do
|
264
|
+
stub_request(:get, "https://mydomain.campfirenow.com/users/734581.json").
|
265
|
+
with(:headers => {'Authorization'=>['mytoken', 'x']}).
|
266
|
+
to_return(:status => 400, :body => json_fixture("user"))
|
267
|
+
@room.instance_variable_get("@users_to_fetch") << Flamethrower::Campfire::Message.new(JSON.parse(json_fixture("enter_message")))
|
268
|
+
EM.run_block { @room.fetch_users }
|
269
|
+
message = @room.instance_variable_get("@failed_messages").size.should == 1
|
270
|
+
end
|
133
271
|
end
|
134
272
|
end
|
135
273
|
|
@@ -149,18 +287,37 @@ describe Flamethrower::Campfire::Room do
|
|
149
287
|
EM.run_block { @room.join }
|
150
288
|
@room.joined.should be_false
|
151
289
|
end
|
290
|
+
|
291
|
+
it "sends a motd error message if the join call times out" do
|
292
|
+
stub_request(:post, "https://mydomain.campfirenow.com/room/347348/join.json").
|
293
|
+
with(:headers => {'Authorization'=>['mytoken', 'x'], 'Content-Type'=>'application/json'}).
|
294
|
+
to_timeout
|
295
|
+
@connection.should_receive(:send_message).with(@connection.reply(Flamethrower::Irc::Codes::RPL_MOTD, ":ERROR: Unable to make API call POST /room/347348/join.json. Check your connection?"))
|
296
|
+
EM.run_block { @room.join }
|
297
|
+
@room.joined.should be_false
|
298
|
+
end
|
152
299
|
end
|
153
300
|
|
154
301
|
describe "#connect" do
|
155
302
|
it "initializes the twitter jsonstream with the right options" do
|
156
|
-
|
303
|
+
stream = mock(:stream, :on_reconnect => nil, :on_error => nil, :on_max_reconnects => nil)
|
304
|
+
Twitter::JSONStream.should_receive(:connect).with(:path => "/room/347348/live.json", :host => "streaming.campfirenow.com", :auth => "mytoken:x").and_return(stream)
|
305
|
+
@room.connect
|
306
|
+
end
|
307
|
+
|
308
|
+
it "sets up the stream callbacks" do
|
309
|
+
stream = mock(:stream, :on_reconnect => nil, :on_error => nil, :on_max_reconnects => nil)
|
310
|
+
Twitter::JSONStream.should_receive(:connect).with(:path => "/room/347348/live.json", :host => "streaming.campfirenow.com", :auth => "mytoken:x").and_return(stream)
|
311
|
+
|
312
|
+
@room.should_receive(:setup_stream_callbacks)
|
157
313
|
@room.connect
|
158
314
|
end
|
159
315
|
end
|
160
316
|
|
161
317
|
describe "#fetch_messages" do
|
162
318
|
before do
|
163
|
-
|
319
|
+
stream = mock(:stream, :on_reconnect => nil, :on_error => nil, :on_max_reconnects => nil)
|
320
|
+
Twitter::JSONStream.stub(:connect).and_return(stream)
|
164
321
|
@item = json_fixture("streaming_message")
|
165
322
|
@room.users << @user
|
166
323
|
@room.connect
|
@@ -188,6 +345,11 @@ describe Flamethrower::Campfire::Room do
|
|
188
345
|
@room.inbound_messages.pop.room.should == @room
|
189
346
|
end
|
190
347
|
|
348
|
+
it "marks the message as inbound" do
|
349
|
+
@room.fetch_messages
|
350
|
+
@room.inbound_messages.pop.should be_inbound
|
351
|
+
end
|
352
|
+
|
191
353
|
it "discards timestamp messages altogether" do
|
192
354
|
item = json_fixture("timestamp_message")
|
193
355
|
@room.stream.stub(:each_item).and_yield(item)
|
@@ -202,23 +364,46 @@ describe Flamethrower::Campfire::Room do
|
|
202
364
|
@room.stream.stub(:each_item).and_yield(enter_message.to_json)
|
203
365
|
@room.fetch_messages
|
204
366
|
@room.instance_variable_get("@users_to_fetch").size.should == 1
|
367
|
+
@room.instance_variable_get("@inbound_messages").size.should == 0
|
368
|
+
end
|
369
|
+
|
370
|
+
it "puts messages that have an image url in the into the images_to_fetch queue" do
|
371
|
+
image_message = json_fixture("streaming_image_message")
|
372
|
+
@room.stream.stub(:each_item).and_yield(image_message)
|
373
|
+
@room.fetch_messages
|
374
|
+
@room.instance_variable_get("@inbound_messages").size.should == 0
|
375
|
+
@room.instance_variable_get("@images_to_fetch").size.should == 1
|
376
|
+
end
|
377
|
+
|
378
|
+
it "doesn't make the call to the image ascii service if the option is disabled" do
|
379
|
+
@room.connection.server.ascii_conversion['enabled'] = false
|
380
|
+
image_message = json_fixture("streaming_image_message")
|
381
|
+
@room.stream.stub(:each_item).and_yield(image_message)
|
382
|
+
@room.fetch_messages
|
383
|
+
@room.instance_variable_get("@users_to_fetch").size.should == 0
|
384
|
+
@room.instance_variable_get("@images_to_fetch").size.should == 0
|
385
|
+
@room.instance_variable_get("@inbound_messages").size.should == 1
|
205
386
|
end
|
206
387
|
end
|
207
388
|
|
208
389
|
describe "#say" do
|
209
390
|
it "queues a campfire message given a message body" do
|
210
|
-
message = Flamethrower::Campfire::Message.new('body' => 'Hello there', 'user' => @user, 'room' => @room)
|
211
391
|
@room.say('Hello there')
|
212
392
|
popped_message = @room.outbound_messages.pop
|
213
393
|
popped_message.body.should == 'Hello there'
|
214
394
|
end
|
215
395
|
|
216
396
|
it "takes an optional message type" do
|
217
|
-
message = Flamethrower::Campfire::Message.new('type' => 'TextMessage', 'body' => 'Hello there', 'user' => @user, 'room' => @room)
|
218
397
|
@room.say('Hello there', 'TextMessage')
|
219
398
|
popped_message = @room.outbound_messages.pop
|
220
399
|
popped_message.message_type.should == 'TextMessage'
|
221
400
|
end
|
401
|
+
|
402
|
+
it "marks the message as an outbound message" do
|
403
|
+
@room.say('Hello there', 'TextMessage')
|
404
|
+
popped_message = @room.outbound_messages.pop
|
405
|
+
popped_message.should be_outbound
|
406
|
+
end
|
222
407
|
end
|
223
408
|
|
224
409
|
describe "#translate_nicknames" do
|
@@ -240,25 +425,47 @@ describe Flamethrower::Campfire::Room do
|
|
240
425
|
end
|
241
426
|
|
242
427
|
describe "#requeue_failed_messages" do
|
243
|
-
it "queues
|
428
|
+
it "queues an outbound message whos retry_at is greater than now" do
|
244
429
|
Time.stub(:now).and_return(Time.parse("9:00AM"))
|
245
|
-
message = Flamethrower::Campfire::Message.new('type' => 'TextMessage', 'body' => 'Hello there', 'user' => @user, 'room' => @room)
|
430
|
+
message = Flamethrower::Campfire::Message.new('type' => 'TextMessage', 'body' => 'Hello there', 'user' => @user, 'room' => @room, 'direction' => 'outbound')
|
246
431
|
message.retry_at = Time.parse("9:00:01AM")
|
432
|
+
message.status = "failed"
|
247
433
|
@room.failed_messages << message
|
248
434
|
@room.requeue_failed_messages
|
249
435
|
@room.outbound_messages.size.should == 1
|
250
436
|
@room.failed_messages.size.should == 0
|
251
437
|
end
|
252
438
|
|
439
|
+
it "queues an inbound message whos retry_at is greater than now" do
|
440
|
+
Time.stub(:now).and_return(Time.parse("9:00AM"))
|
441
|
+
message = Flamethrower::Campfire::Message.new('type' => 'TextMessage', 'body' => 'Hello there', 'user' => @user, 'room' => @room, 'direction' => 'inbound')
|
442
|
+
message.retry_at = Time.parse("9:00:01AM")
|
443
|
+
message.status = "failed"
|
444
|
+
@room.failed_messages << message
|
445
|
+
@room.requeue_failed_messages
|
446
|
+
@room.inbound_messages.size.should == 1
|
447
|
+
@room.failed_messages.size.should == 0
|
448
|
+
end
|
449
|
+
|
253
450
|
it "doesn't queue a message whos retry_at is less than now" do
|
254
451
|
Time.stub(:now).and_return(Time.parse("9:00AM"))
|
255
|
-
message = Flamethrower::Campfire::Message.new('type' => 'TextMessage', 'body' => 'Hello there', 'user' => @user, 'room' => @room)
|
452
|
+
message = Flamethrower::Campfire::Message.new('type' => 'TextMessage', 'body' => 'Hello there', 'user' => @user, 'room' => @room, 'direction' => 'outbound')
|
256
453
|
message.retry_at = Time.parse("8:59AM")
|
454
|
+
message.status = "failed"
|
257
455
|
@room.failed_messages << message
|
258
456
|
@room.requeue_failed_messages
|
259
457
|
@room.outbound_messages.size.should == 0
|
260
458
|
@room.failed_messages.size.should == 1
|
261
459
|
end
|
460
|
+
|
461
|
+
it "marks the message as pending when it requeues" do
|
462
|
+
Time.stub(:now).and_return(Time.parse("9:00AM"))
|
463
|
+
message = Flamethrower::Campfire::Message.new('type' => 'TextMessage', 'body' => 'Hello there', 'user' => @user, 'room' => @room, 'direction' => 'inbound')
|
464
|
+
message.mark_failed!
|
465
|
+
@room.failed_messages << message
|
466
|
+
@room.requeue_failed_messages
|
467
|
+
message.should be_pending
|
468
|
+
end
|
262
469
|
end
|
263
470
|
|
264
471
|
describe "#post_messages" do
|