post_commit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,5 @@
1
+ = Changelog
2
+
3
+ == March 1 2010
4
+
5
+ * Released 0.1.0 version
data/README.rdoc ADDED
@@ -0,0 +1,133 @@
1
+ = Introduction
2
+
3
+ Post commit allows you to notify several services with simple and elegant DSL. It currently supports 5 services:
4
+
5
+ * Basecamp
6
+ * Campfire
7
+ * FriendFeed
8
+ * LightHouse
9
+ * Twitter
10
+
11
+ = Usage
12
+
13
+ To install Post Commit run the command
14
+
15
+ sudo gem install post_commit
16
+
17
+ and you're good to go!
18
+
19
+ == Basecamp
20
+
21
+ To send a Basecamp message you have to inform your subdomain, API token and project id.
22
+
23
+ post_commit :basecamp do
24
+ authorize :subdomain => "mycompany", :token => "492bfe53dcd3", :project => 12345, :ssl => true
25
+ post "Some title", "Some message"
26
+ end
27
+
28
+ == Campfire
29
+
30
+ To send a Campfire message you have to inform your subdomain, API token and room id.
31
+
32
+ post_commit :campfire do
33
+ authorize :subdomain => "mycompany", :token => "ec930a0f7fb1", :room => 12345
34
+ post "Some message"
35
+ end
36
+
37
+ The Campfire hook supports 3 message types: <tt>text</tt>, <tt>paste</tt> and <tt>twitter</tt>.
38
+
39
+ post "Some message"
40
+ post "Some message", :type => :text
41
+ post "Some pasted code", :type => :paste
42
+ post "http://twitter.com/johndoe/statuses/12345", :type => :twitter
43
+
44
+ == FriendFeed
45
+
46
+ To send a FriendFeed message you have to inform your username and API token.
47
+
48
+ post_commit :friendfeed do
49
+ authorize :username => "johndoe", :token => "wow39dupa"
50
+ post "Check it out this page", :url => "http://example.com"
51
+ end
52
+
53
+ == LightHouse
54
+
55
+ To send a LightHouse message you have to inform your subdomain, API token and project id.
56
+
57
+ post_commit :lighthouse do
58
+ authorize :subdomain => "mycompany", :token => "2aad05e8b", :project => 12345
59
+ post "Some title", "Some message"
60
+ end
61
+
62
+ == Twitter
63
+
64
+ To send a Twitter message you have to inform your username and password.
65
+
66
+ post_commit :twitter do
67
+ authorize :username => "johndoe", :password => "mypass"
68
+ post "Hi Twitter!"
69
+ end
70
+
71
+ The Twitter hook supports public and direct messages.
72
+
73
+ post "Hi Twitter!"
74
+ post "Hi Twitter!", :type => :status
75
+ post "Mary, check this out! http://example.com", :type => :direct_message, :screen_name => "marydoe"
76
+ post "Mary, check this out! http://example.com", :type => :direct_message, :user_id => 12345
77
+
78
+ = Creating new hooks
79
+
80
+ To create a new hook, you can extend the <tt>PostCommit::Hooks::Base</tt> class, to bootstrap your own class.
81
+
82
+ class Email < PostCommit::Hooks::Base
83
+ def post(message, to)
84
+ ActionMailer::Base.smtp_settings = credentials
85
+
86
+ # send the message
87
+ end
88
+ end
89
+
90
+ To register this new hook, you just have to call the <tt>PostCommit::Hooks.register</tt> method.
91
+
92
+ PostCommit::Hooks.register :email, Email
93
+
94
+ Then you can use it through the <tt>post_commit</tt> method.
95
+
96
+ post_commit :email do
97
+ authorize :address => "example.com", :user_name => "noreply", :password => "mypass", :authentication => :plain
98
+ post "Some message", "mary@doe.com"
99
+ end
100
+
101
+ The <tt>authorize</tt> accepts anything you want. In this case, we're providing all SMTP info we want to use.
102
+ You can use the <tt>credentials</tt> attribute to retrieve these settings.
103
+
104
+ = To-Do
105
+
106
+ * Receive post commits
107
+
108
+ = Maintainer
109
+
110
+ * Nando Vieira - http://simplesideias.com.br
111
+
112
+ = License
113
+
114
+ (The MIT License)
115
+
116
+ Permission is hereby granted, free of charge, to any person obtaining
117
+ a copy of this software and associated documentation files (the
118
+ 'Software'), to deal in the Software without restriction, including
119
+ without limitation the rights to use, copy, modify, merge, publish,
120
+ distribute, sublicense, and/or sell copies of the Software, and to
121
+ permit persons to whom the Software is furnished to do so, subject to
122
+ the following conditions:
123
+
124
+ The above copyright notice and this permission notice shall be
125
+ included in all copies or substantial portions of the Software.
126
+
127
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
128
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
129
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
130
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
131
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
132
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
133
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,37 @@
1
+ require "json"
2
+ require "net/http"
3
+ require "uri"
4
+ require "json"
5
+
6
+ require "post_commit/errors"
7
+ require "post_commit/hooks"
8
+ require "post_commit/hooks/base"
9
+ require "post_commit/hooks/basecamp"
10
+ require "post_commit/hooks/campfire"
11
+ require "post_commit/hooks/friend_feed"
12
+ require "post_commit/hooks/light_house"
13
+ require "post_commit/hooks/twitter"
14
+ require "post_commit/version"
15
+
16
+ PostCommit::Hooks.register :basecamp, PostCommit::Hooks::Basecamp
17
+ PostCommit::Hooks.register :campfire, PostCommit::Hooks::Campfire
18
+ PostCommit::Hooks.register :friendfeed, PostCommit::Hooks::FriendFeed
19
+ PostCommit::Hooks.register :lighthouse, PostCommit::Hooks::LightHouse
20
+ PostCommit::Hooks.register :twitter, PostCommit::Hooks::Twitter
21
+
22
+ # Send a notification to the specified service. This method is just
23
+ # a shorcut to the PostCommit::Hooks module.
24
+ #
25
+ # post_commit :twitter do
26
+ # authorize :username => "johndoe", :password => "test"
27
+ # post "Some message!"
28
+ # end
29
+ def post_commit(service, &block)
30
+ hook_class = PostCommit::Hooks.hooks[service.to_sym]
31
+
32
+ raise PostCommit::UnknownHookError unless hook_class
33
+
34
+ hook = hook_class.new
35
+ hook.instance_eval(&block)
36
+ hook
37
+ end
@@ -0,0 +1,5 @@
1
+ module PostCommit
2
+ class InvalidOptionError < StandardError; end
3
+ class AbstractMethodError < StandardError; end
4
+ class UnknownHookError < StandardError; end
5
+ end
@@ -0,0 +1,15 @@
1
+ module PostCommit
2
+ module Hooks
3
+ class << self
4
+ attr_accessor :hooks
5
+ end
6
+
7
+ # Register a hook.
8
+ #
9
+ # PostCommit::Hooks.register :campfire, PostCommit::Hooks::Campfire
10
+ def self.register(name, hook_class)
11
+ self.hooks ||= {}
12
+ self.hooks[name.to_sym] = hook_class
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,31 @@
1
+ module PostCommit
2
+ module Hooks
3
+ class Base
4
+ # Hold the authorization options.
5
+ attr_accessor :credentials
6
+
7
+ # Hold the latest response
8
+ attr_reader :response
9
+
10
+ # Hold the latest request object
11
+ attr_reader :request
12
+
13
+ # Hold the latest uri object
14
+ attr_reader :uri
15
+
16
+ def initialize
17
+ @credentials = {}
18
+ end
19
+
20
+ # Set up the authorization for the current notifier.
21
+ # Each notifier can have its own authorization options.
22
+ def authorize(options = {})
23
+ @credentials = options
24
+ end
25
+
26
+ def post(options = {}) # :nodoc:
27
+ raise PostCommit::AbstractMethodError
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,41 @@
1
+ module PostCommit
2
+ module Hooks
3
+ # To send a Basecamp post commit, you have to setup your subdomain, API token and project.
4
+ #
5
+ # post_commit :basecamp do
6
+ # authorize :subdomain => "mycompany", :token => "TVfD8rB0x1sze8nZ4P1vaO5wOWM", :project => 666, :ssl => true
7
+ # post "Some title", "Some message"
8
+ # end
9
+ #
10
+ class Basecamp < Base
11
+ # Post message to Basecamp.
12
+ #
13
+ # post "Some title", "Some message"
14
+ def post(title, message)
15
+ protocol = credentials[:ssl] ? "https" : "http"
16
+ @uri = URI.parse("#{protocol}://#{credentials[:subdomain]}.basecamphq.com/projects/#{credentials[:project]}/posts.xml")
17
+ http = Net::HTTP.new(uri.host, uri.port)
18
+
19
+ @request = Net::HTTP::Post.new(uri.path)
20
+ @request.basic_auth credentials[:token], "x"
21
+ @request.content_type = "application/xml"
22
+ @request.body = <<-TXT
23
+ <post>
24
+ <title><![CDATA[#{title}]]></title>
25
+ <body><![CDATA[#{message}]]></body>
26
+ </post>
27
+ TXT
28
+
29
+ @response = http.request(@request)
30
+
31
+ if @response.code == "201"
32
+ true
33
+ else
34
+ false
35
+ end
36
+ rescue Exception
37
+ false
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,54 @@
1
+ module PostCommit
2
+ module Hooks
3
+ # To send a Campifire post commit, you have to setup your subdomain, API token and room.
4
+ #
5
+ # post_commit :campfire do
6
+ # authorize :subdomain => "mycompany", :token => "TVfD8rB0x1sze8nZ4P1vaO5wOWM", :room => 666, :ssl => true
7
+ # post "Some message"
8
+ # end
9
+ #
10
+ # You can specify the message type. See PostCommit::Hooks::Campfire#post for usage.
11
+ class Campfire < Base
12
+ MESSAGE_TYPE = {
13
+ :text => "TextMessage",
14
+ :paste => "PasteMessage",
15
+ :twitter => "TwitterMessage"
16
+ }
17
+
18
+ # Post message to Campfire.
19
+ #
20
+ # post "Hi Campfire!"
21
+ # #=> send text message
22
+ #
23
+ # post "Pasted code", :type => :paste
24
+ # #=> formatted paste message with more link and scroll bar
25
+ #
26
+ # post "http://twitter.com/dhh/status/9688523285", :type => :twitter
27
+ # #=> display the specified Twitter status
28
+ def post(message, options = {})
29
+ options = {:type => :text}.merge(options)
30
+ protocol = credentials[:ssl] ? "https" : "http"
31
+ @uri = URI.parse("#{protocol}://#{credentials[:subdomain]}.campfirenow.com/room/#{credentials[:room]}/speak.json")
32
+ http = Net::HTTP.new(uri.host, uri.port)
33
+
34
+ @request = Net::HTTP::Post.new(uri.path)
35
+ @request.basic_auth credentials[:token], "x"
36
+ @request.content_type = "application/json"
37
+ @request.body = {:message => {
38
+ :type => MESSAGE_TYPE[options[:type].to_sym],
39
+ :body => message.to_s
40
+ }}.to_json
41
+
42
+ @response = http.request(@request)
43
+
44
+ if @response.code == "201"
45
+ JSON.parse response.body
46
+ else
47
+ false
48
+ end
49
+ rescue Exception
50
+ false
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,39 @@
1
+ module PostCommit
2
+ module Hooks
3
+ # To send a FriendFeed post commit, you have to setup your username and API token.
4
+ # You can retrieve your API token at https://friendfeed.com/account/api.
5
+ #
6
+ # post_commit :friendfeed do
7
+ # authorize :username => "johndoe", :token => "abc"
8
+ # post "Some message", :url => "http://example.com/"
9
+ # end
10
+ #
11
+ class FriendFeed < Base
12
+ # Post message to FriendFeed.
13
+ #
14
+ # post "We're working on it!"
15
+ # post "Google", :url => "http://google.com"
16
+ def post(message, options = {})
17
+ @uri = URI.parse("http://friendfeed-api.com/v2/entry")
18
+ http = Net::HTTP.new(uri.host, uri.port)
19
+
20
+ @request = Net::HTTP::Post.new(uri.path)
21
+ @request.basic_auth credentials[:username], credentials[:token]
22
+ @request.form_data = {
23
+ :body => message,
24
+ :link => options[:url]
25
+ }
26
+
27
+ @response = http.request(@request)
28
+
29
+ if response.code == "200"
30
+ JSON.parse response.body
31
+ else
32
+ false
33
+ end
34
+ rescue Exception
35
+ false
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ module PostCommit
2
+ module Hooks
3
+ # To send a Campifire post commit, you have to setup your subdomain, API token and room.
4
+ #
5
+ # post_commit :lighthouse do
6
+ # authorize :subdomain => "mycompany", :project => 47533, :token => "TVfD8rB0x1sze8nZ4P1vaO5wOWM"
7
+ # post "Some title", "Some message"
8
+ # end
9
+ class LightHouse < Base
10
+ # Post message to Lighthouse.
11
+ #
12
+ # post "Some nice title", "Hi Lighthouse!"
13
+ def post(title, message)
14
+ @uri = URI.parse("http://#{credentials[:subdomain]}.lighthouseapp.com/projects/#{credentials[:project]}/messages.json")
15
+ http = Net::HTTP.new(uri.host, uri.port)
16
+
17
+ @request = Net::HTTP::Post.new(uri.path)
18
+ @request.content_type = "application/json"
19
+ @request["X-LighthouseToken"] = credentials[:token]
20
+ @request.body = {:message => {
21
+ :title => title.to_s,
22
+ :body => message.to_s
23
+ }}.to_json
24
+
25
+ @response = http.request(@request)
26
+
27
+ if @response.code == "201"
28
+ JSON.parse response.body
29
+ else
30
+ false
31
+ end
32
+ rescue Exception
33
+ false
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,67 @@
1
+ module PostCommit
2
+ module Hooks
3
+ # To send a Twitter post commit, you have to setup your username and password.
4
+ #
5
+ # post_commit :twitter do
6
+ # authorize :username => "johndoe", :password => "test"
7
+ # post "Some message"
8
+ # end
9
+ #
10
+ # You can specify the message type. See PostCommit::Hooks::Twitter#post for usage.
11
+ class Twitter < Base
12
+ # Post message to Twitter.
13
+ # You can send public and direct messages.
14
+ #
15
+ # post "Hi Twitter!"
16
+ # #=> public message
17
+ #
18
+ # post "Hi john!", :type => :direct_message, :screen_name => "johndoe"
19
+ # #=> private message
20
+ #
21
+ # post "Hi john!", :type => :direct_message, :user_id => 1
22
+ # #=> private message
23
+ def post(message, options = {})
24
+ options = {:type => :status}.merge(options)
25
+
26
+ case options.delete(:type)
27
+ when :status then status(message, options)
28
+ when :direct_message then direct_message(message, options)
29
+ else
30
+ raise PostCommit::InvalidOptionError, "Twitter's message type should be either :status or :direct_message"
31
+ end
32
+ end
33
+
34
+ private
35
+ # Send a public message
36
+ def status(message, options = {})
37
+ _request "http://twitter.com/statuses/update.json", options.merge(:status => message)
38
+ end
39
+
40
+ # Send a private message.
41
+ # The user you're notifying should be following you.
42
+ def direct_message(message, options = {})
43
+ _request "http://twitter.com/direct_messages/new.json", options.merge(:text => message)
44
+ end
45
+
46
+ # Send message to the specified url
47
+ def _request(url, options = {})
48
+ @uri = URI.parse(url)
49
+ http = Net::HTTP.new(uri.host, uri.port)
50
+
51
+ @request = Net::HTTP::Post.new(uri.path)
52
+ @request.basic_auth credentials[:username], credentials[:password]
53
+ @request.form_data = options
54
+
55
+ @response = http.request(@request)
56
+
57
+ if response.code == "200"
58
+ JSON.parse response.body
59
+ else
60
+ false
61
+ end
62
+ rescue Exception
63
+ false
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,8 @@
1
+ module PostCommit
2
+ module Version
3
+ MAJOR = "0"
4
+ MINOR = "1"
5
+ PATCH = "0"
6
+ STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe PostCommit::Hooks::Base do
4
+ it "should raise when trying to call abstract method" do
5
+ doing { subject.post }.should raise_error(PostCommit::AbstractMethodError)
6
+ end
7
+ end
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe PostCommit::Hooks::Basecamp do
4
+ before do
5
+ @url = "http://abc:x@mycompany.basecamphq.com/projects/666/posts.xml"
6
+ subject.authorize :subdomain => "mycompany", :token => "abc", :project => 666
7
+ end
8
+
9
+ it "should instantiate hook" do
10
+ hook = post_commit(:basecamp) {}
11
+ hook.should be_an_instance_of(PostCommit::Hooks::Basecamp)
12
+ end
13
+
14
+ it "should post notification" do
15
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"])
16
+ subject.post("Some title", "Some message")
17
+ FakeWeb.should have_requested(:post, @url)
18
+ end
19
+
20
+ it "should recover from unknown exceptions" do
21
+ Net::HTTP.should_receive(:new).and_raise(Exception)
22
+ subject.post("Some title", "Some message").should be_false
23
+ end
24
+
25
+ it "should post notification to secure url" do
26
+ @url = "https://abc:x@mycompany.basecamphq.com/projects/666/posts.xml"
27
+ subject.authorize :subdomain => "mycompany", :token => "abc", :project => 666, :ssl => true
28
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"])
29
+ subject.post("Some title", "Some message")
30
+
31
+ subject.uri.to_s.should match(/^https:/)
32
+ end
33
+
34
+ it "should return true when message is posted" do
35
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"])
36
+ subject.post("Some title", "Some message").should be_true
37
+ end
38
+
39
+ it "should return false when post notification fails" do
40
+ FakeWeb.register_uri(:post, @url, :status => ["401", "Unauthorized"])
41
+ subject.post("Some title", "Some message").should be_false
42
+ end
43
+
44
+ it "should set authorization headers" do
45
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"])
46
+ subject.post("Some title", "Some message")
47
+
48
+ subject.request["authorization"].should == subject.request.send(:basic_encode, "abc", "x")
49
+ end
50
+ end
@@ -0,0 +1,75 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe PostCommit::Hooks::Campfire do
4
+ before do
5
+ @url = "http://abc:x@mycompany.campfirenow.com/room/666/speak.json"
6
+ subject.authorize :subdomain => "mycompany", :token => "abc", :room => 666
7
+ end
8
+
9
+ it "should instantiate hook" do
10
+ hook = post_commit(:campfire) {}
11
+ hook.should be_an_instance_of(PostCommit::Hooks::Campfire)
12
+ end
13
+
14
+ it "should recover from unknown exceptions" do
15
+ Net::HTTP.should_receive(:new).and_raise(Exception)
16
+ subject.post("Some message").should be_false
17
+ end
18
+
19
+ it "should post notification" do
20
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"], :body => body("campfire.json"))
21
+ subject.post("Hi Campfire!")
22
+ FakeWeb.should have_requested(:post, @url)
23
+ end
24
+
25
+ it "should post notification to secure url" do
26
+ @url = "https://abc:x@mycompany.campfirenow.com/room/666/speak.json"
27
+ subject.authorize :subdomain => "mycompany", :token => "abc", :room => 666, :ssl => true
28
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"], :body => body("campfire.json"))
29
+ subject.post("Hi Campfire!")
30
+
31
+ subject.uri.to_s.should match(/^https:/)
32
+ end
33
+
34
+ it "should return tweet as hash" do
35
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"], :body => body("campfire.json"))
36
+ response = subject.post("Hi Campfire!")
37
+ response.should be_an_instance_of(Hash)
38
+ end
39
+
40
+ it "should return false when post notification fails" do
41
+ FakeWeb.register_uri(:post, @url, :status => ["401", "Unauthorized"])
42
+ subject.post("Hi Campfire!").should be_false
43
+ end
44
+
45
+ it "should set post data for text message" do
46
+ subject.post("Hi John!", :type => :text)
47
+ body = JSON.parse(subject.request.body)
48
+
49
+ body["message"]["type"].to_s.should == "TextMessage"
50
+ body["message"]["body"].to_s.should == "Hi John!"
51
+ end
52
+
53
+ it "should set post data for paste message" do
54
+ subject.post("Some pasted code", :type => :paste)
55
+ body = JSON.parse(subject.request.body)
56
+
57
+ body["message"]["type"].to_s.should == "PasteMessage"
58
+ body["message"]["body"].to_s.should == "Some pasted code"
59
+ end
60
+
61
+ it "should set post data for twitter message" do
62
+ subject.post("http://twitter.com/statuses/johndoe/1234", :type => :twitter)
63
+ body = JSON.parse(subject.request.body)
64
+
65
+ body["message"]["type"].to_s.should == "TwitterMessage"
66
+ body["message"]["body"].to_s.should == "http://twitter.com/statuses/johndoe/1234"
67
+ end
68
+
69
+ it "should set authorization headers" do
70
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"], :body => body("campfire.json"))
71
+ subject.post("Some message")
72
+
73
+ subject.request["authorization"].should == subject.request.send(:basic_encode, "abc", "x")
74
+ end
75
+ end
@@ -0,0 +1,51 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe PostCommit::Hooks::FriendFeed do
4
+ before do
5
+ @url = "http://johndoe:abc@friendfeed-api.com/v2/entry"
6
+ subject.authorize :username => "johndoe", :token => "abc"
7
+ end
8
+
9
+ it "should instantiate hook" do
10
+ hook = post_commit(:friendfeed) {}
11
+ hook.should be_an_instance_of(PostCommit::Hooks::FriendFeed)
12
+ end
13
+
14
+ it "should post notification" do
15
+ FakeWeb.register_uri(:post, @url, :status => ["200", "OK"], :body => body("friendfeed.json"))
16
+ subject.post("Google", :url => "http://google.com")
17
+ FakeWeb.should have_requested(:post, @url)
18
+ end
19
+
20
+ it "should recover from unknown exceptions" do
21
+ Net::HTTP.should_receive(:new).and_raise(Exception)
22
+ subject.post("Some message").should be_false
23
+ end
24
+
25
+ it "should return response as hash" do
26
+ FakeWeb.register_uri(:post, @url, :status => ["200", "OK"], :body => body("friendfeed.json"))
27
+ response = subject.post("Google", :url => "http://google.com")
28
+ response.should be_an_instance_of(Hash)
29
+ end
30
+
31
+ it "should return false when post notification fails" do
32
+ FakeWeb.register_uri(:post, @url, :status => ["401", "Unauthorized"])
33
+ subject.post("Some message").should be_false
34
+ end
35
+
36
+ it "should set post data" do
37
+ FakeWeb.register_uri(:post, @url, :status => ["200", "OK"], :body => body("friendfeed.json"))
38
+ subject.post("Google", :url => "http://google.com")
39
+ body = CGI.parse(subject.request.body)
40
+
41
+ body["body"].to_s.should == "Google"
42
+ body["link"].to_s.should == "http://google.com"
43
+ end
44
+
45
+ it "should set authorization headers" do
46
+ FakeWeb.register_uri(:post, @url, :status => ["200", "OK"], :body => body("friendfeed.json"))
47
+ subject.post("Google")
48
+
49
+ subject.request["authorization"].should == subject.request.send(:basic_encode, "johndoe", "abc")
50
+ end
51
+ end
@@ -0,0 +1,51 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe PostCommit::Hooks::LightHouse do
4
+ before do
5
+ @url = "http://mycompany.lighthouseapp.com/projects/666/messages.json"
6
+ subject.authorize :subdomain => "mycompany", :token => "abc", :project => 666
7
+ end
8
+
9
+ it "should instantiate hook" do
10
+ hook = post_commit(:lighthouse) {}
11
+ hook.should be_an_instance_of(PostCommit::Hooks::LightHouse)
12
+ end
13
+
14
+ it "should recover from unknown exceptions" do
15
+ Net::HTTP.should_receive(:new).and_raise(Exception)
16
+ subject.post("Some title", "Some message").should be_false
17
+ end
18
+
19
+ it "should post notification" do
20
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"], :body => body("lighthouse.json"))
21
+ subject.post("Some title", "Some message")
22
+ FakeWeb.should have_requested(:post, @url)
23
+ end
24
+
25
+ it "should return response as hash" do
26
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"], :body => body("lighthouse.json"))
27
+ response = subject.post("Some title", "Some message")
28
+ response.should be_an_instance_of(Hash)
29
+ end
30
+
31
+ it "should return false when post notification fails" do
32
+ FakeWeb.register_uri(:post, @url, :status => ["401", "Unauthorized"])
33
+ subject.post("Some title", "Some message").should be_false
34
+ end
35
+
36
+ it "should set post data" do
37
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"], :body => body("lighthouse.json"))
38
+ subject.post("Some title", "Some message")
39
+ body = JSON.parse(subject.request.body)
40
+
41
+ body["message"]["title"].should == "Some title"
42
+ body["message"]["body"].should == "Some message"
43
+ end
44
+
45
+ it "should set headers" do
46
+ FakeWeb.register_uri(:post, @url, :status => ["201", "Created"], :body => body("lighthouse.json"))
47
+ subject.post("Some title", "Some message")
48
+
49
+ subject.request["X-LighthouseToken"].should == "abc"
50
+ end
51
+ end
@@ -0,0 +1,88 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe PostCommit::Hooks::Twitter do
4
+ before do
5
+ subject.authorize :username => "johndoe", :password => "test"
6
+ end
7
+
8
+ it "should instantiate hook" do
9
+ hook = post_commit(:twitter) {}
10
+ hook.should be_an_instance_of(PostCommit::Hooks::Twitter)
11
+ end
12
+
13
+ it "should raise when an invalid type is specified" do
14
+ doing { subject.post("Invalid", :type => :invalid) }.should raise_error(PostCommit::InvalidOptionError)
15
+ end
16
+
17
+ it "should recover from unknown exceptions" do
18
+ Net::HTTP.should_receive(:new).and_raise(Exception)
19
+ subject.post("Some message").should be_false
20
+ end
21
+
22
+ context "public messages" do
23
+ before do
24
+ @url = "http://johndoe:test@twitter.com/statuses/update.json"
25
+ FakeWeb.register_uri(:post, @url, :status => ["200", "OK"], :body => body("twitter.json"))
26
+ end
27
+
28
+ it "should set authorization headers" do
29
+ FakeWeb.register_uri(:post, @url, :status => ["200", "OK"], :body => body("twitter.json"))
30
+ subject.post("Some message")
31
+
32
+ subject.request["authorization"].should == subject.request.send(:basic_encode, "johndoe", "test")
33
+ end
34
+
35
+ it "should call the proper method" do
36
+ subject.should_receive(:status).with("Hi John!", {})
37
+ subject.post("Hi John!", :type => :status)
38
+ end
39
+
40
+ it "should be posted" do
41
+ subject.post("Hi Twitter!")
42
+ FakeWeb.should have_requested(:post, @url)
43
+ end
44
+
45
+ it "should set post data" do
46
+ subject.post("Hi John!")
47
+ body = CGI.parse(subject.request.body)
48
+
49
+ body["status"].to_s.should == "Hi John!"
50
+ end
51
+ end
52
+
53
+ context "direct messages" do
54
+ before do
55
+ @url = "http://johndoe:test@twitter.com/direct_messages/new.json"
56
+ FakeWeb.register_uri(:post, @url, :status => ["200", "OK"], :body => body("twitter.json"))
57
+ end
58
+
59
+ it "should call the proper method" do
60
+ subject.should_receive(:direct_message).with("Hi John!", :screen_name => "johndoe")
61
+ subject.post("Hi John!", :type => :direct_message, :screen_name => "johndoe")
62
+ end
63
+
64
+ it "should be post" do
65
+ subject.post("Hi Twitter!", :type => :direct_message, :screen_name => "johndoe")
66
+ FakeWeb.should have_requested(:post, @url)
67
+ end
68
+
69
+ it "should set post data" do
70
+ subject.post("Hi John!", :type => :direct_message, :screen_name => "johndoe")
71
+ body = CGI.parse(subject.request.body)
72
+
73
+ body["text"].to_s.should == "Hi John!"
74
+ body["screen_name"].to_s.should == "johndoe"
75
+ end
76
+ end
77
+
78
+ it "should return tweet as hash" do
79
+ FakeWeb.register_uri(:post, "http://johndoe:test@twitter.com/statuses/update.json", :status => ["200", "OK"], :body => body("twitter.json"))
80
+ response = subject.post("Hi Twitter!")
81
+ response.should be_an_instance_of(Hash)
82
+ end
83
+
84
+ it "should return false when post notification fails" do
85
+ FakeWeb.register_uri(:post, "http://johndoe:test@twitter.com/statuses/update.json", :status => ["401", "Unauthorized"])
86
+ subject.post("Hi Twitter!").should be_false
87
+ end
88
+ end
@@ -0,0 +1,2 @@
1
+ class NotificationController < ActionController::Base
2
+ end
@@ -0,0 +1 @@
1
+ {"message":{"type":"TextMessage","room_id":666,"created_at":"2010/01/29 21:43:43 +0000","id":190621957,"user_id":609100,"body":"Hi Campfire!"}}
@@ -0,0 +1 @@
1
+ {"body":"Google - <a rel=\"nofollow\" href=\"http://google.com\" title=\"http://www.google.com/\">http://www.google.com/</a>","commands":["comment","edit","delete"],"from":{"commands":["post","dm"],"type":"user","id":"johndoe","name":"John Doe"},"url":"http://friendfeed.com/johndoe/1c6c0d97/google","date":"2010-03-01T02:13:52Z","id":"e/1c6c0d97315042509f7de4d6543b5a69"}
@@ -0,0 +1 @@
1
+ {"message": {"url": "http://mycompany.lighthouseapp.com/projects/666/messages/25667", "permalink": "some-title", "updated_at": "2010-03-01T01:03:48Z", "project_id": 47533, "body_html": "<div><p>Some message</p></div>", "title": "Some title", "body": "Some message", "all_attachments_count": 0, "token": "af63uzcd", "attachments_count": 0, "id": 25667, "comments": [], "user_id": 1234, "comments_count": 0, "user_name": "John Doe", "parent_id": null, "created_at": "2010-03-01T01:03:48Z"}}
@@ -0,0 +1 @@
1
+ {"favorited":false,"in_reply_to_user_id":null,"in_reply_to_status_id":null,"in_reply_to_screen_name":null,"contributors":null,"created_at":"Fri Jan 29 19:48:31 +0000 2010","source":"<a href=\"http://apiwiki.twitter.com/\" rel=\"nofollow\">API</a>","user":{"followers_count":1,"url":null,"description":"","statuses_count":91,"time_zone":"Greenland","profile_sidebar_fill_color":"e0ff92","notifications":false,"friends_count":0,"contributors_enabled":false,"created_at":"Mon Aug 17 17:10:55 +0000 2009","profile_sidebar_border_color":"87bc44","favourites_count":0,"profile_image_url":"http://s.twimg.com/a/1264550348/images/default_profile_3_normal.png","verified":false,"profile_text_color":"000000","lang":"en","profile_background_image_url":"http://s.twimg.com/a/1264550348/images/themes/theme1/bg.png","protected":true,"screen_name":"johndoe","following":false,"geo_enabled":false,"profile_link_color":"0000ff","location":"","name":"John Doe","profile_background_tile":false,"id":66415394,"utc_offset":-10800,"profile_background_color":"9ae4e8"},"geo":null,"truncated":false,"id":8381292275,"text":"Hi Twitter!"}
@@ -0,0 +1,27 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
2
+
3
+ require "rubygems"
4
+ require "cgi"
5
+ require "post_commit"
6
+ require "spec"
7
+ require "fakeweb"
8
+ require "fakeweb_matcher"
9
+
10
+ FakeWeb.allow_net_connect = false
11
+
12
+ module SpecHelpers
13
+ def body(filename)
14
+ File.read(File.dirname(__FILE__) + "/resources/responses/#{filename}")
15
+ end
16
+ end
17
+
18
+ Spec::Runner.configure do |config|
19
+ config.prepend_before :each do
20
+ FakeWeb.clean_registry
21
+ end
22
+
23
+ config.include SpecHelpers
24
+ end
25
+
26
+ # Create an alias for lambda
27
+ alias :doing :lambda
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: post_commit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nando Vieira
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-03-01 00:00:00 -03:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: json
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: "Five services are supported for now: Basecamp, Campfire, FriendFeed, LightHouse and Twitter."
26
+ email: fnando.vieira@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.rdoc
33
+ files:
34
+ - CHANGELOG.rdoc
35
+ - README.rdoc
36
+ - lib/post_commit.rb
37
+ - lib/post_commit/errors.rb
38
+ - lib/post_commit/hooks.rb
39
+ - lib/post_commit/hooks/base.rb
40
+ - lib/post_commit/hooks/basecamp.rb
41
+ - lib/post_commit/hooks/campfire.rb
42
+ - lib/post_commit/hooks/friend_feed.rb
43
+ - lib/post_commit/hooks/light_house.rb
44
+ - lib/post_commit/hooks/twitter.rb
45
+ - lib/post_commit/version.rb
46
+ - spec/post_commit/base_spec.rb
47
+ - spec/post_commit/basecamp_spec.rb
48
+ - spec/post_commit/campfire_spec.rb
49
+ - spec/post_commit/friend_feed_spec.rb
50
+ - spec/post_commit/light_house_spec.rb
51
+ - spec/post_commit/twitter_spec.rb
52
+ - spec/resources/controllers.rb
53
+ - spec/resources/responses/campfire.json
54
+ - spec/resources/responses/friendfeed.json
55
+ - spec/resources/responses/lighthouse.json
56
+ - spec/resources/responses/twitter.json
57
+ - spec/spec_helper.rb
58
+ has_rdoc: true
59
+ homepage: http://github.com/fnando/post_commit
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options:
64
+ - --charset=UTF-8
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ version:
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ requirements: []
80
+
81
+ rubyforge_project:
82
+ rubygems_version: 1.3.5
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Post commit allows you to notify several services with simple and elegant DSL
86
+ test_files:
87
+ - spec/post_commit/base_spec.rb
88
+ - spec/post_commit/basecamp_spec.rb
89
+ - spec/post_commit/campfire_spec.rb
90
+ - spec/post_commit/friend_feed_spec.rb
91
+ - spec/post_commit/light_house_spec.rb
92
+ - spec/post_commit/twitter_spec.rb
93
+ - spec/resources/controllers.rb
94
+ - spec/spec_helper.rb