em-campfire 0.0.1

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 ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,51 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ em-campfire (0.0.1)
5
+ em-http-request (~> 1.0.0.beta.4)
6
+ eventmachine (~> 1.0.0.beta.4)
7
+ yajl-ruby (~> 0.8.3)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ addressable (2.2.6)
13
+ cookiejar (0.3.0)
14
+ crack (0.3.1)
15
+ diff-lcs (1.1.3)
16
+ em-http-request (1.0.1)
17
+ addressable (>= 2.2.3)
18
+ cookiejar
19
+ em-socksify
20
+ eventmachine (>= 1.0.0.beta.4)
21
+ http_parser.rb (>= 0.5.3)
22
+ em-socksify (0.1.0)
23
+ eventmachine
24
+ eventmachine (1.0.0.beta.4)
25
+ http_parser.rb (0.5.3)
26
+ metaclass (0.0.1)
27
+ mocha (0.10.0)
28
+ metaclass (~> 0.0.1)
29
+ rake (0.9.2.2)
30
+ rspec (2.6.0)
31
+ rspec-core (~> 2.6.0)
32
+ rspec-expectations (~> 2.6.0)
33
+ rspec-mocks (~> 2.6.0)
34
+ rspec-core (2.6.4)
35
+ rspec-expectations (2.6.0)
36
+ diff-lcs (~> 1.1.2)
37
+ rspec-mocks (2.6.0)
38
+ webmock (1.7.10)
39
+ addressable (~> 2.2, > 2.2.5)
40
+ crack (>= 0.1.7)
41
+ yajl-ruby (0.8.3)
42
+
43
+ PLATFORMS
44
+ ruby
45
+
46
+ DEPENDENCIES
47
+ em-campfire!
48
+ mocha (~> 0.10.0)
49
+ rake (~> 0.9.2)
50
+ rspec (~> 2.6.0)
51
+ webmock (~> 1.7.6)
data/LICENSE.md ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 by Will Jessop
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,6 @@
1
+
2
+ This isn't ready for production use yet, so don't use it!
3
+
4
+ ## Example
5
+
6
+ See examples/simple.rb
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ rescue LoadError => e
7
+ task "spec" do
8
+ puts "RSpec not loaded - make sure it's installed and you're using bundle exec"
9
+ exit 1
10
+ end
11
+ end
12
+
13
+ task :default => :spec
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "em-campfire/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "em-campfire"
7
+ s.version = EventMachine::Campfire::VERSION
8
+ s.authors = ["Will Jessop"]
9
+ s.email = ["will@willj.net"]
10
+ s.homepage = "https://github.com/wjessop/em-campfire"
11
+ s.summary = %q{Eventmachine campfire API lib}
12
+ s.description = %q{Eventmachine campfire API lib}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_dependency('eventmachine', '~> 1.0.0.beta.4')
20
+ s.add_dependency('yajl-ruby', '~> 0.8.3')
21
+ s.add_dependency('em-http-request', '~> 1.0.0.beta.4')
22
+
23
+ s.add_development_dependency "rake", "~> 0.9.2"
24
+ s.add_development_dependency "rspec", "~> 2.6.0"
25
+ s.add_development_dependency "mocha", "~> 0.10.0"
26
+ s.add_development_dependency "webmock", "~> 1.7.6"
27
+ end
@@ -0,0 +1,19 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), '../lib')
2
+
3
+ require 'em-campfire'
4
+
5
+ EM.run {
6
+ connection = EM::Campfire.new(:subdomain => "foo", :api_key => "foo")
7
+ connection.join 293788 # Robot Army
8
+ connection.join 401839 # Monitoring
9
+
10
+ connection.on_message do |msg|
11
+ puts msg.inspect
12
+ end
13
+
14
+ # Give lib a chance to connect
15
+ EM::Timer.new(10) do
16
+ # Say something on a specific channel
17
+ connection.say "foofoofoo", "Robot Army"
18
+ end
19
+ }
@@ -0,0 +1,28 @@
1
+ module EventMachine
2
+ class Campfire
3
+ module Connection
4
+
5
+ attr_accessor :ignore_self
6
+
7
+ def on_message &blk
8
+ @on_message_block = blk
9
+ end
10
+
11
+ private
12
+
13
+ attr_accessor :on_message_block
14
+
15
+ def process_message(msg)
16
+ logger.debug "Received message #{msg.inspect}"
17
+ return false if ignore_self && is_me?(msg[:user_id])
18
+ if on_message_block
19
+ logger.debug "on_message callback exists, calling it #{msg.inspect}"
20
+ on_message_block.call(msg)
21
+ else
22
+ logger.debug "on_message callback does not exist"
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,39 @@
1
+ module EventMachine
2
+ class Campfire
3
+ module Messages
4
+ def say(message, room_id_or_name)
5
+ send_message(room_id_or_name, message, "Textmessage")
6
+ end
7
+
8
+ def paste(message, room_id_or_name)
9
+ send_message(room_id_or_name, message, "PasteMessage")
10
+ end
11
+
12
+ def play(sound, room_id_or_name)
13
+ send_message(room_id_or_name, sound, "SoundMessage")
14
+ end
15
+
16
+ private
17
+
18
+ # curl -vvv -H 'Content-Type: application/json' -d '{"message":{"body":"Yeeeeeaaaaaahh", "type":"Textmessage"}}' -u API_KEY:X https://something.campfirenow.com/room/2345678/speak.json
19
+ def send_message(room_id_or_name, payload, type)
20
+ if room_cache.size < 1
21
+ logger.error "Couldn't post message \"#{payload}\" to room #{room_id_or_name} as no rooms have been joined"
22
+ return
23
+ end
24
+
25
+ room_id = room_id(room_id_or_name)
26
+ url = "https://#{subdomain}.campfirenow.com/room/#{room_id}/speak.json"
27
+ http = EventMachine::HttpRequest.new(url).post :head => {'Content-Type' => 'application/json', 'authorization' => [api_key, 'X']}, :body => Yajl::Encoder.encode({:message => {:body => payload, :type => type}})
28
+ http.errback { logger.error "Couldn't connect to #{url} to post message \"#{payload}\" to room #{room_id}" }
29
+ http.callback {
30
+ if [200,201].include? http.response_header.status
31
+ logger.debug "Posted #{type} \"#{payload}\" to room #{room_id}"
32
+ else
33
+ logger.error "Couldn't post message \"#{payload}\" to room #{room_id} using url #{url}, http response from the API was #{http.response_header.status}"
34
+ end
35
+ }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,122 @@
1
+ module EventMachine
2
+ class Campfire
3
+ module Rooms
4
+
5
+ # attr_accessor :rooms
6
+ attr_accessor :room_cache
7
+
8
+ def join(room, &blk)
9
+ id = room_id(room)
10
+ # logger.info "Joining room #{id}"
11
+ if id
12
+ url = "https://#{subdomain}.campfirenow.com/room/#{id}/join.json"
13
+ http = EventMachine::HttpRequest.new(url).post :head => {'Content-Type' => 'application/json', 'authorization' => [api_key, 'X']}
14
+ http.errback { logger.error "Error joining room: #{id}" }
15
+ http.callback {
16
+ if http.response_header.status == 200
17
+ logger.info "Joined room #{id} successfully"
18
+ # fetch_room_data(id)
19
+ stream(id)
20
+ else
21
+ logger.error "Error joining room: #{id}"
22
+ end
23
+ }
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ attr_accessor :populating_room_list
30
+
31
+ def stream(room_id)
32
+ json_parser = Yajl::Parser.new :symbolize_keys => true
33
+ json_parser.on_parse_complete = method(:process_message)
34
+
35
+ url = "https://streaming.campfirenow.com/room/#{room_id}/live.json"
36
+ # Timeout per https://github.com/igrigorik/em-http-request/wiki/Redirects-and-Timeouts
37
+ http = EventMachine::HttpRequest.new(url, :connect_timeout => 20, :inactivity_timeout => 0).get :head => {'authorization' => [api_key, 'X']}
38
+ http.errback { logger.error "Couldn't stream room #{room_id} at url #{url}" }
39
+ http.callback { logger.info "Disconnected from #{url}"; join(room_id) if rooms[room_id] }
40
+ http.stream {|chunk| json_parser << chunk }
41
+ end
42
+
43
+
44
+ def room_id(room_id_or_name)
45
+ if room_id_or_name.is_a? Integer
46
+ return room_id_or_name
47
+ else
48
+ return room_id_from_room_name(room_id_or_name)
49
+ end
50
+ end
51
+
52
+ def room_id_from_room_name(room_name)
53
+ logger.debug "Looking for room id for #{room_name}"
54
+
55
+ if room_cache.has_key? room_name
56
+ return room_cache[room_name]["id"]
57
+ else
58
+ logger.warn "Attempted to join #{room_name} but could not find an ID for it"
59
+ return false
60
+ end
61
+ end
62
+
63
+ # curl -vvv -H 'Content-Type: application/json' -u API_KEY:X https://something.campfirenow.com/rooms.json
64
+ def populate_room_list
65
+ url = "https://#{subdomain}.campfirenow.com/rooms.json"
66
+ http = EventMachine::HttpRequest.new(url).get :head => {'authorization' => [api_key, 'X']}
67
+ http.errback { logger.error "Couldn't connect to url #{url} to fetch room list"; puts http.inspect }
68
+ http.callback {
69
+ if http.response_header.status == 200
70
+ logger.debug "Fetched room list"
71
+ new_rooms = {}
72
+ Yajl::Parser.parse(http.response)['rooms'].each do |c|
73
+ new_rooms[c["name"]] = c
74
+ end
75
+ @room_cache = new_rooms # replace existing room list
76
+ else
77
+ logger.error "Couldn't fetch room list with url #{url}, http response from API was #{http.response_header.status}"
78
+ end
79
+ }
80
+ end
81
+
82
+ # def fetch_room_data(room_id)
83
+ # url = "https://#{subdomain}.campfirenow.com/room/#{room_id}.json"
84
+ # http = EventMachine::HttpRequest.new(url).get :head => {'authorization' => [api_key, 'X']}
85
+ # http.errback { logger.error "Couldn't connect to #{url} to fetch room data for room #{room_id}" }
86
+ # http.callback {
87
+ # if http.response_header.status == 200
88
+ # logger.debug "Fetched room data for #{room_id}"
89
+ # room = Yajl::Parser.parse(http.response)['room']
90
+ # room_cache[room["id"]] = room
91
+ #
92
+ # room['users'].each do |u|
93
+ # update_user_cache_with(u["id"], u)
94
+ # end
95
+ # else
96
+ # logger.error "Couldn't fetch room data for room #{room_id} with url #{url}, http response from API was #{http.response_header.status}"
97
+ # end
98
+ # }
99
+ # end
100
+
101
+ def fetch_room_data(room_id)
102
+ url = "https://#{subdomain}.campfirenow.com/room/#{room_id}.json"
103
+ http = EventMachine::HttpRequest.new(url).get :head => {'authorization' => [api_key, 'X']}
104
+ http.errback { logger.error "Couldn't connect to #{url} to fetch room data for room #{room_id}" }
105
+ http.callback {
106
+ if http.response_header.status == 200
107
+ logger.debug "Fetched room data for #{room_id}"
108
+ room = Yajl::Parser.parse(http.response)['room']
109
+ room_cache[room["id"]] = room
110
+
111
+ room['users'].each do |u|
112
+ update_user_cache_with(u["id"], u)
113
+ end
114
+ else
115
+ logger.error "Couldn't fetch room data for room #{room_id} with url #{url}, http response from API was #{http.response_header.status}"
116
+ end
117
+ }
118
+ end
119
+
120
+ end # Rooms
121
+ end # Campfire
122
+ end # EventMachine
@@ -0,0 +1,56 @@
1
+ module EventMachine
2
+ class Campfire
3
+ module Users
4
+
5
+ # attr_accessor :user_cache
6
+
7
+ private
8
+
9
+ # Return the user_id if we haven't got the real name and
10
+ # kick off a user data fetch
11
+ def username_for(user_id)
12
+ # if cached_user?(user_id)
13
+ # user_cache[user_id]["name"]
14
+ # else
15
+ fetch_data_for(user_id)
16
+ # user_id.to_s
17
+ # end
18
+ end
19
+
20
+ # def is_me?(user_id)
21
+ # if user_cache['me']
22
+ # user_cache['me']['id'] == user_id
23
+ # else
24
+ # fetch_data_for('me')
25
+ # false
26
+ # end
27
+ # end
28
+ #
29
+ # def cached_user? user_id
30
+ # user_cache[user_id] != nil
31
+ # end
32
+
33
+ def fetch_data_for(user_id)
34
+ return unless user_id
35
+ url = "https://#{subdomain}.campfirenow.com/users/#{user_id}.json"
36
+ http = EventMachine::HttpRequest.new(url).get(:head => {'authorization' => [api_key, 'X'], "Content-Type" => "application/json"})
37
+ http.callback do
38
+ if http.response_header.status == 200
39
+ logger.debug "Got the data for #{user_id}"
40
+ update_user_cache_with(user_id, Yajl::Parser.parse(http.response)['user'])
41
+ else
42
+ logger.error "Couldn't fetch user data for user #{user_id} with url #{url}, http response from API was #{http.response_header.status}"
43
+ end
44
+ end
45
+ http.errback do
46
+ logger.error "Couldn't connect to #{url} to fetch user data for user #{user_id}"
47
+ end
48
+ end
49
+
50
+ # def update_user_cache_with(user_id, data)
51
+ # logger.debug "Updated user cache for #{data['name']}"
52
+ # user_cache[user_id] = data
53
+ # end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,5 @@
1
+ module EventMachine
2
+ class Campfire
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,57 @@
1
+ require 'eventmachine'
2
+ require 'em-http-request'
3
+ require 'yajl'
4
+ require "logger"
5
+
6
+ require "em-campfire/version"
7
+ require "em-campfire/connection"
8
+ require "em-campfire/rooms"
9
+ require "em-campfire/users"
10
+ require "em-campfire/messages"
11
+
12
+ module EventMachine
13
+ class Campfire
14
+ attr_accessor :logger, :verbose, :subdomain, :api_key
15
+
16
+ include Connection
17
+ include Rooms
18
+ include Users
19
+ include Messages
20
+
21
+ def initialize(options = {})
22
+ raise ArgumentError, "You must pass an API key" unless options[:api_key]
23
+ raise ArgumentError, "You must pass a subdomain" unless options[:subdomain]
24
+
25
+ options.each do |k,v|
26
+ s = "#{k}="
27
+ if respond_to?(s)
28
+ send(s, v)
29
+ else
30
+ logger.warn "em-campfire initialized with #{k.inspect} => #{v.inspect} but NO UNDERSTAND!"
31
+ end
32
+ end
33
+
34
+ # @rooms = {}
35
+ # @user_cache = {}
36
+ @room_cache = {}
37
+
38
+ populate_room_list
39
+
40
+ # # populate bot data separately, in case we are ignoring ourselves
41
+ # fetch_data_for('me')
42
+ end
43
+
44
+ def logger
45
+ unless @logger
46
+ @logger = Logger.new(STDOUT)
47
+ @logger.level = (verbose ? Logger::DEBUG : Logger::INFO)
48
+ end
49
+ @logger
50
+ end
51
+
52
+ def verbose=(is_verbose)
53
+ @verbose = is_verbose
54
+ logger.level = Logger::DEBUG if is_verbose
55
+ end
56
+ end # Campfire
57
+ end # EventMachine
@@ -0,0 +1,12 @@
1
+ require "spec_helper"
2
+
3
+ describe EventMachine::Campfire::Connection do
4
+
5
+ context "#on_message" do
6
+ before :each do
7
+ EM.run_block { @adaptor = a EM::Campfire }
8
+ end
9
+
10
+ it "run a block when it receives a message"
11
+ end
12
+ end
@@ -0,0 +1,253 @@
1
+ require "spec_helper"
2
+
3
+ describe EventMachine::Campfire do
4
+
5
+ before :each do
6
+ stub_rooms_data_request
7
+ end
8
+
9
+ describe "#initialize" do
10
+ it "should work with valid params" do
11
+ EM.run_block { a(EM::Campfire).should be_a(EM::Campfire) }
12
+ end
13
+
14
+ it "should warn if given an option it doesn't know" do
15
+ mock_logger
16
+ EM.run_block { a(EM::Campfire, :fred => "estaire").should be_a(EM::Campfire) }
17
+ logger_output.should =~ /WARN.*em-campfire initialized with :fred => "estaire" but NO UNDERSTAND!/
18
+ end
19
+
20
+ it "should require essential parameters" do
21
+ lambda { EM::Campfire.new }.should raise_error(ArgumentError, "You must pass an API key")
22
+ lambda { EM::Campfire.new(:api_key => "foo") }.should raise_error(ArgumentError, "You must pass a subdomain")
23
+ end
24
+ end
25
+
26
+ describe "#verbose" do
27
+ it "should default to false" do
28
+ EM.run_block { a(EM::Campfire).verbose.should be_false }
29
+ end
30
+
31
+ it "should be overridable at initialization" do
32
+ EM.run_block { a(EM::Campfire, :verbose => true).verbose.should be_true }
33
+ end
34
+ end
35
+
36
+ describe "#logger" do
37
+ context "default logger" do
38
+ before { EM.run_block { @adaptor = a EM::Campfire } }
39
+
40
+ it { @adaptor.logger.should be_a(Logger) }
41
+ it { @adaptor.logger.level.should be == Logger::INFO }
42
+ end
43
+
44
+ context "default logger in verbose mode" do
45
+ before { EM.run_block { @adaptor = a EM::Campfire, :verbose => true } }
46
+
47
+ it { @adaptor.logger.level.should be == Logger::DEBUG }
48
+ end
49
+
50
+ context "overriding default" do
51
+ before do
52
+ @custom_logger = Logger.new("/dev/null")
53
+ EM.run_block { @adaptor = a EM::Campfire, :logger => @custom_logger }
54
+ end
55
+
56
+ it { @adaptor.logger.should be == @custom_logger }
57
+ end
58
+
59
+
60
+
61
+ #
62
+ # it "should handle HTTP errors fetching individual room data" do
63
+ # mock_logger
64
+ # bot = a Scamp
65
+ #
66
+ # EM.run_block {
67
+ # stub_request(:post, @message_post_url).
68
+ # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X'], 'Content-Type' => 'application/json'}).
69
+ # to_return(:status => 502, :body => "", :headers => {'Content-Type'=>'text/html'})
70
+ # lambda {bot.send(:send_message, 123, "Hi", "Textmessage")}.should_not raise_error
71
+ # }
72
+ # logger_output.should =~ /ERROR.*Couldn't post message "Hi" to room 123 using url #{@message_post_url}, http response from the API was 502/
73
+ # end
74
+ #
75
+ # it "should handle network errors fetching individual room data" do
76
+ # mock_logger
77
+ # bot = a Scamp
78
+ #
79
+ # EM.run_block {
80
+ # stub_request(:post, @message_post_url).
81
+ # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X'], 'Content-Type' => 'application/json'}).to_timeout
82
+ # lambda {bot.send(:send_message, 123, "Hi", "Textmessage")}.should_not raise_error
83
+ # }
84
+ # logger_output.should =~ /ERROR.*Couldn't connect to #{@message_post_url} to post message "Hi" to room 123/
85
+ # end
86
+ #
87
+
88
+
89
+
90
+ # context "user operations" do
91
+ # it "should fetch user data" do
92
+ # adaptor = a EM::Campfire
93
+ #
94
+ # EM.run_block {
95
+ # stub_request(:get, "https://#{valid_params[:subdomain]}.campfirenow.com/users/123.json").
96
+ # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X'], 'Content-Type'=>'application/json'}).
97
+ # to_return(:status => 200, :body => Yajl::Encoder.encode(:user => valid_user_cache_data[123]), :headers => {})
98
+ # adaptor.send(:username_for, 123)
99
+ # stub.should have_been_requested
100
+ # }
101
+ # end
102
+
103
+ # it "should handle HTTP errors fetching user data" do
104
+ # mock_logger
105
+ # bot = a EM::Campfire
106
+ #
107
+ # url = "https://#{valid_params[:subdomain]}.campfirenow.com/users/123.json"
108
+ # EM.run_block {
109
+ # stub_request(:get, url).
110
+ # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X'], 'Content-Type'=>'application/json'}).
111
+ # to_return(:status => 502, :body => "", :headers => {'Content-Type'=>'text/html'})
112
+ # lambda {bot.username_for(123)}.should_not raise_error
113
+ # }
114
+ # logger_output.should =~ /ERROR.*Couldn't fetch user data for user 123 with url #{url}, http response from API was 502/
115
+ # end
116
+ #
117
+ # it "should handle network errors fetching user data" do
118
+ # mock_logger
119
+ # bot = a EM::Campfire
120
+ #
121
+ # url = "https://#{valid_params[:subdomain]}.campfirenow.com/users/123.json"
122
+ # EM.run_block {
123
+ # stub_request(:get, url).
124
+ # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X'], 'Content-Type'=>'application/json'}).to_timeout
125
+ # lambda {bot.username_for(123)}.should_not raise_error
126
+ # }
127
+ # logger_output.should =~ /ERROR.*Couldn't connect to #{url} to fetch user data for user 123/
128
+ # end
129
+ end
130
+
131
+ context "room operations" do
132
+ before do
133
+ @room_list_url = "https://#{valid_params[:subdomain]}.campfirenow.com/rooms.json"
134
+ @me_list_url = "https://#{valid_params[:subdomain]}.campfirenow.com/users/me.json"
135
+ @room_url = "https://#{valid_params[:subdomain]}.campfirenow.com/room/123.json"
136
+ @stream_url = "https://streaming.campfirenow.com/room/123/live.json"
137
+ end
138
+
139
+ # it "should fetch a room list" do
140
+ # mock_logger
141
+ # bot = a EM::Campfire
142
+ #
143
+ # EM.run_block {
144
+ # stub_request(:get, @room_list_url).
145
+ # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X']}).
146
+ # to_return(:status => 200, :body => Yajl::Encoder.encode(:rooms => valid_room_cache_data.values), :headers => {})
147
+ # bot.send(:populate_room_list)
148
+ # stub.should have_been_requested
149
+ # }
150
+ # logger_output.should =~ /DEBUG.*Fetched room list/
151
+ # end
152
+
153
+ # it "should invoke the post connection callback" do
154
+ # mock_logger
155
+ # bot = a EM::Campfire
156
+ #
157
+ # invoked_cb = false
158
+ #
159
+ # EM.run_block {
160
+ # stub_request(:get, @room_list_url).
161
+ # with(:headers => {
162
+ # 'Authorization'=>[valid_params[:api_key], 'X'],
163
+ # 'Content-Type' => 'application/json'
164
+ # }).
165
+ # to_return(:status => 200, :body => Yajl::Encoder.encode(:rooms => valid_room_cache_data.values), :headers => {})
166
+ #
167
+ # stub_request(:get, @room_list_url).
168
+ # with(:headers => {
169
+ # 'Authorization'=>[valid_params[:api_key], 'X']
170
+ # }).
171
+ # to_return(:status => 200, :body => Yajl::Encoder.encode(:rooms => valid_room_cache_data.values), :headers => {})
172
+ #
173
+ # # Disable fetch_data_for, not important to this test.
174
+ # EM::Campfire.any_instance.expects(:fetch_data_for).returns(nil)
175
+ #
176
+ # bot.send(:connect!, [valid_room_cache_data.keys.first]) do
177
+ # invoked_cb = true
178
+ # end
179
+ # }
180
+ # invoked_cb.should be_true
181
+ # end
182
+ #
183
+ # it "should handle HTTP errors fetching the room list" do
184
+ # mock_logger
185
+ # bot = a EM::Campfire
186
+ #
187
+ # EM.run_block {
188
+ # # stub_request(:get, url).
189
+ # # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X'], 'Content-Type'=>'application/json'}).
190
+ # # to_return(:status => 502, :body => "", :headers => {'Content-Type'=>'text/html'})
191
+ # stub_request(:get, @room_list_url).
192
+ # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X']}).
193
+ # to_return(:status => 502, :body => "", :headers => {'Content-Type'=>'text/html'})
194
+ # lambda {bot.send(:populate_room_list)}.should_not raise_error
195
+ # }
196
+ # logger_output.should =~ /ERROR.*Couldn't fetch room list with url #{@room_list_url}, http response from API was 502/
197
+ # end
198
+ #
199
+ # it "should handle network errors fetching the room list" do
200
+ # mock_logger
201
+ # bot = a EM::Campfire
202
+ # EM.run_block {
203
+ # stub_request(:get, @room_list_url).
204
+ # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X']}).to_timeout
205
+ # lambda {bot.send(:populate_room_list)}.should_not raise_error
206
+ # }
207
+ # logger_output.should =~ /ERROR.*Couldn't connect to url #{@room_list_url} to fetch room list/
208
+ # end
209
+ #
210
+ # it "should fetch individual room data" do
211
+ # mock_logger
212
+ # bot = a EM::Campfire
213
+ #
214
+ # EM.run_block {
215
+ # stub_request(:get, @room_url).
216
+ # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X']}).
217
+ # to_return(:status => 200, :body => Yajl::Encoder.encode(:room => valid_room_cache_data[123]), :headers => {})
218
+ # bot.room_name_for(123)
219
+ # }
220
+ # logger_output.should =~ /DEBUG.*Fetched room data for 123/
221
+ # end
222
+ #
223
+ # it "should handle HTTP errors fetching individual room data" do
224
+ # mock_logger
225
+ # bot = a EM::Campfire
226
+ #
227
+ # EM.run_block {
228
+ # stub_request(:get, @room_url).
229
+ # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X']}).
230
+ # to_return(:status => 502, :body => "", :headers => {'Content-Type'=>'text/html'})
231
+ # lambda {bot.room_name_for(123)}.should_not raise_error
232
+ # }
233
+ # logger_output.should =~ /ERROR.*Couldn't fetch room data for room 123 with url #{@room_url}, http response from API was 502/
234
+ # end
235
+ #
236
+ # it "should handle network errors fetching individual room data" do
237
+ # mock_logger
238
+ # bot = a EM::Campfire
239
+ #
240
+ # EM.run_block {
241
+ # stub_request(:get, @room_url).
242
+ # with(:headers => {'Authorization'=>[valid_params[:api_key], 'X']}).to_timeout
243
+ # lambda {bot.room_name_for(123)}.should_not raise_error
244
+ # }
245
+ # logger_output.should =~ /ERROR.*Couldn't connect to #{@room_url} to fetch room data for room 123/
246
+ # end
247
+ #
248
+ # it "should stream a room"
249
+ # it "should handle HTTP errors streaming a room"
250
+ # it "should handle network errors streaming a room"
251
+ end
252
+ end
253
+
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ describe EventMachine::Campfire::Messages do
4
+
5
+ before :each do
6
+ stub_rooms_data_request
7
+ stub_join_room_request(123)
8
+ stub_stream_room_request(123)
9
+ EM.run_block { @adaptor = a(EM::Campfire) }
10
+ end
11
+
12
+ it "should say a message" do
13
+ mock_logger
14
+ stub = stub_message_post_request
15
+
16
+ EM.run_block {
17
+ @adaptor.join 123
18
+ @adaptor.say "Hi", 123
19
+ }
20
+ stub.should have_been_requested
21
+ logger_output.should =~ /DEBUG.*Posted Textmessage "Hi" to room 123/
22
+ end
23
+
24
+ it "should paste a message" do
25
+ mock_logger
26
+ stub = stub_message_post_request
27
+
28
+ EM.run_block {
29
+ @adaptor.join 123
30
+ @adaptor.paste "Hi", 123
31
+ }
32
+ stub.should have_been_requested
33
+ logger_output.should =~ /DEBUG.*Posted PasteMessage "Hi" to room 123/
34
+ end
35
+
36
+ it "should play a sound" do
37
+ mock_logger
38
+ stub = stub_message_post_request
39
+
40
+ EM.run_block {
41
+ @adaptor.join 123
42
+ @adaptor.play "nyan", 123
43
+ }
44
+ stub.should have_been_requested
45
+ logger_output.should =~ /DEBUG.*Posted SoundMessage "nyan" to room 123/
46
+ end
47
+ end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ describe EventMachine::Campfire::Rooms do
4
+
5
+ before :each do
6
+ @message_post_url = "https://#{valid_params[:subdomain]}.campfirenow.com/room/123/speak.json"
7
+ stub_rooms_data_request
8
+ EM.run_block { @adaptor = a(EM::Campfire) }
9
+ end
10
+
11
+ context "#join" do
12
+ before :each do
13
+ EM.run_block { @adaptor = a EM::Campfire }
14
+ end
15
+
16
+ it "should allow joining by id" do
17
+ mock_logger
18
+
19
+ join_stub = stub_join_room_request(123)
20
+ stream_stub = stub_stream_room_request(123)
21
+ EM.run_block { @adaptor.join(123) }
22
+ logger_output.should =~ /INFO.*Joined room 123 successfully/
23
+ join_stub.should have_been_requested
24
+ end
25
+
26
+ it "should allow joining by name" do
27
+ join_stub = stub_join_room_request(123)
28
+ stream_stub = stub_stream_room_request(123)
29
+ EM.run_block { @adaptor.join("foo") }
30
+ join_stub.should have_been_requested
31
+ end
32
+
33
+ it "should not be able to join an invalid room" do
34
+ mock_logger
35
+ stream_stub = stub_stream_room_request(9999999999999999)
36
+ url = "https://#{valid_params[:subdomain]}.campfirenow.com/room/9999999999999999/join.json"
37
+ join_stub = stub_request(:post, url).
38
+ with(:headers => {'Authorization'=>[valid_params[:api_key], 'X'], 'Content-Type'=>'application/json'}).
39
+ to_return(:status => 302, :body => "", :headers => {})
40
+
41
+ EM.run_block { @adaptor.join(9999999999999999) }
42
+ logger_output.should =~ /Error joining room: 9999999999999999/
43
+ join_stub.should have_been_requested
44
+ stream_stub.should_not have_been_requested
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,78 @@
1
+ require File.expand_path("../lib/em-campfire", File.dirname(__FILE__))
2
+
3
+ require 'mocha'
4
+ require 'webmock/rspec'
5
+
6
+ RSpec.configure do |config|
7
+ config.color_enabled = true
8
+ config.mock_framework = :mocha
9
+ end
10
+
11
+ def a klass, params={}
12
+ params ||= {}
13
+ params = valid_params.merge(params) if klass == EM::Campfire
14
+ klass.new(params)
15
+ end
16
+
17
+ # Urg
18
+ def mock_logger
19
+ @logger_string = StringIO.new
20
+ @fake_logger = Logger.new(@logger_string)
21
+ EM::Campfire.any_instance.expects(:logger).at_least(1).returns(@fake_logger)
22
+ end
23
+
24
+ # Bleurgh
25
+ def logger_output
26
+ str = @logger_string.dup
27
+ str.rewind
28
+ str.read
29
+ end
30
+
31
+ def valid_user_cache_data
32
+ {123 => {"name" => "foo"}, 456 => {"name" => "bar"}, 'me' => {"name" => "bot", "id" => 123}}
33
+ end
34
+
35
+ def valid_room_cache_data
36
+ {
37
+ 123 => {
38
+ "id" => 123,
39
+ "name" => "foo",
40
+ "users" => []
41
+ },
42
+ 456 => {
43
+ "id" => 456,
44
+ "name" => "bar",
45
+ "users" => []
46
+ }
47
+ }
48
+ end
49
+
50
+ def valid_params
51
+ {:api_key => "6124d98749365e3db2c9e5b27ca04db6", :subdomain => "oxygen"}
52
+ end
53
+
54
+ def stub_join_room_request(room)
55
+ url = "https://#{valid_params[:subdomain]}.campfirenow.com/room/#{room}/join.json"
56
+ stub_request(:post, url).
57
+ with(:headers => {'Authorization'=>[valid_params[:api_key], 'X'], 'Content-Type'=>'application/json'}).
58
+ to_return(:status => 200, :body => "", :headers => {})
59
+ end
60
+
61
+ def stub_rooms_data_request
62
+ stub_request(:get, "https://#{valid_params[:subdomain]}.campfirenow.com/rooms.json").
63
+ with(:headers => {'Authorization'=>['6124d98749365e3db2c9e5b27ca04db6', 'X']}).
64
+ to_return(:status => 200, :body => Yajl::Encoder.encode(:rooms => valid_room_cache_data.values), :headers => {})
65
+ end
66
+
67
+ def stub_message_post_request
68
+ message_post_url = "https://#{valid_params[:subdomain]}.campfirenow.com/room/123/speak.json"
69
+ stub_request(:post, message_post_url).
70
+ with(:headers => {'Authorization'=>[valid_params[:api_key], 'X'], 'Content-Type' => 'application/json'}).
71
+ to_return(:status => 201, :body => "", :headers => {})
72
+ end
73
+
74
+ def stub_stream_room_request(room)
75
+ stub_request(:get, "https://streaming.campfirenow.com/room/#{room}/live.json").
76
+ with(:headers => {'Authorization'=>[valid_params[:api_key], 'X']}).
77
+ to_return(:status => 200, :body => "", :headers => {})
78
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: em-campfire
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Will Jessop
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: eventmachine
16
+ requirement: &70274674754820 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.0.beta.4
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70274674754820
25
+ - !ruby/object:Gem::Dependency
26
+ name: yajl-ruby
27
+ requirement: &70274674754280 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.8.3
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70274674754280
36
+ - !ruby/object:Gem::Dependency
37
+ name: em-http-request
38
+ requirement: &70274674753780 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.0.0.beta.4
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70274674753780
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &70274674753320 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.2
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70274674753320
58
+ - !ruby/object:Gem::Dependency
59
+ name: rspec
60
+ requirement: &70274674752720 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 2.6.0
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70274674752720
69
+ - !ruby/object:Gem::Dependency
70
+ name: mocha
71
+ requirement: &70274674751940 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 0.10.0
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70274674751940
80
+ - !ruby/object:Gem::Dependency
81
+ name: webmock
82
+ requirement: &70274674751460 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ version: 1.7.6
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70274674751460
91
+ description: Eventmachine campfire API lib
92
+ email:
93
+ - will@willj.net
94
+ executables: []
95
+ extensions: []
96
+ extra_rdoc_files: []
97
+ files:
98
+ - Gemfile
99
+ - Gemfile.lock
100
+ - LICENSE.md
101
+ - README.md
102
+ - Rakefile
103
+ - em-campfire.gemspec
104
+ - examples/simple.rb
105
+ - lib/em-campfire.rb
106
+ - lib/em-campfire/connection.rb
107
+ - lib/em-campfire/messages.rb
108
+ - lib/em-campfire/rooms.rb
109
+ - lib/em-campfire/users.rb
110
+ - lib/em-campfire/version.rb
111
+ - spec/lib/connection_spec.rb
112
+ - spec/lib/em-campfire_spec.rb
113
+ - spec/lib/messages_spec.rb
114
+ - spec/lib/rooms_spec.rb
115
+ - spec/spec_helper.rb
116
+ homepage: https://github.com/wjessop/em-campfire
117
+ licenses: []
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 1.8.10
137
+ signing_key:
138
+ specification_version: 3
139
+ summary: Eventmachine campfire API lib
140
+ test_files:
141
+ - spec/lib/connection_spec.rb
142
+ - spec/lib/em-campfire_spec.rb
143
+ - spec/lib/messages_spec.rb
144
+ - spec/lib/rooms_spec.rb
145
+ - spec/spec_helper.rb