post_commit 0.1.0

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/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