diff --git a/docs/smarterbase b/docs/smarterbase new file mode 100644 index 000000000..b5cfb1a1e --- /dev/null +++ b/docs/smarterbase @@ -0,0 +1,16 @@ +Smarterbase +======= + +Use this service hook to selectively update tickets with comments based on GitHub commit messages and issue updates. + +In order to update a Smarterbase ticket, all you need to do is to configure and enable this hook, and then subsequently reference the ticket you want updated with the GitHub status. The format of the ticket reference is SB#123 where 123 is the id of the ticket. Only commits/comments containing a valid SB ticket reference are sent to Smarterbase. + +Install Notes +------------- + + 1. The subdomain is your Smarterbase subdomain, i.e. "subdomain" if you visit http://subdomain.smarterbase.com or + in the case of non-GAE deployment on http://www.customer.com it will be "customer.com" + + 2. Username is username of the user you wish to authenticate as + + 3. Password is the password of the user diff --git a/services/smarterbase.rb b/services/smarterbase.rb new file mode 100644 index 000000000..643a7e20a --- /dev/null +++ b/services/smarterbase.rb @@ -0,0 +1,54 @@ +require 'oauth' + +class Service::Smarterbase < Service + default_events :commit_comment, :issues, :issue_comment + string :subdomain, :consumer_key, :consumer_secret + white_list :subdomain, :consumer_key, :consumer_secret + + def invalid_request? + puts data + data['subdomain'].to_s.empty? or + data['consumer_key'].to_s.empty? or + data['consumer_secret'].to_s.empty? + end + + def full_url(subdomain, path='') + if subdomain =~ /\./ + url = "http://#{subdomain}/#{path}" + else + url = "http://#{subdomain}.smarterbase.com/#{path}" + end + + begin + Addressable::URI.parse(url) + rescue Addressable::URI::InvalidURIError + raise_config_error("Invalid subdomain #{subdomain}") + end + + url + + end + + def service_url(subdomain) + full_url(subdomain, 'external/github') + end + + def receive_event + + consumer = OAuth::Consumer.new(data['consumer_key'], data['consumer_secret'], + :site => full_url(data['subdomain']), :http_method => :get, :scheme => :query_string) + + access_token = OAuth::AccessToken.new(consumer) + + raise_config_error "Bad configuration" if invalid_request? + + url = service_url(data['subdomain']) + res = access_token.post(url, { :payload => payload.to_json, + :subdomain => data['subdomain'], + :event => event.to_s }) + + unless res.code.to_s[/2\d+/] + raise_config_error("Unexpected response code:#{res.code}") + end + end +end diff --git a/test/smarterbase_test.rb b/test/smarterbase_test.rb new file mode 100644 index 000000000..cd522b209 --- /dev/null +++ b/test/smarterbase_test.rb @@ -0,0 +1,39 @@ +require File.expand_path("../helper", __FILE__) + +class SmarterbaseTest < Service::TestCase + def setup + @stubs = Faraday::Adapter::Test::Stubs.new + @data = { "subdomain" => "test", + "consumer_key" => "1d5ff56af429bcd3da32cc23f4982c3ccde7cf9ae3a8a68f0da507ecc8d47f7", + "consumer_secret" => "dc9ad345843e6c7f2d116f1cad8531382be386b6f6d389ba3e6f7bd1521be02"} + @payload = { :message => "Some message" } + end + + def test_subdomain + post(@data) + svc = service :event, @data, @payload + svc.receive_event + end + + def test_domain + @data.merge("subdomain" => "test.smarterbase.com") + + post(@data) + + svc = service :event, @data, @payload + svc.receive_event + end + + + def post(data) + @stubs.post "/external/github" do |env| + assert_equal "test.smarterbase.com", env[:url].host + assert_equal ({ :payload => @payload }.merge(@data).to_json), env[:body] + [ 201, {}, "" ] + end + end + + def service(*args) + super Service::Smarterbase, *args + end +end