flamethrower 0.3.0 → 0.3.2
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.
- 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
|