right_hook 0.4.2 → 0.5.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/README.md CHANGED
@@ -32,6 +32,7 @@ Or install it yourself as:
32
32
  Create an application by subclassing `RightHook::App`:
33
33
 
34
34
  ```ruby
35
+ #!/usr/bin/env ruby
35
36
  # app.rb
36
37
  require 'right_hook/app'
37
38
  require 'right_hook/event'
@@ -51,9 +52,9 @@ class MyApp < RightHook::App
51
52
  # Code to execute for GitHub's pull request hook.
52
53
  # The secret has already been verified if your code is being called.
53
54
  # See app.rb and spec/app/*_spec.rb for signatures and examples of the valid handlers.
54
- def on_pull_request(owner, repo_name, action, number, pull_request_json)
55
+ def on_pull_request(owner, repo_name, action, pull_request_json)
55
56
  message = <<-MSG
56
- GitHub user #{pull_request_json['user']['login']} has opened pull request ##{number}
57
+ GitHub user #{pull_request_json['user']['login']} has opened pull request ##{pull_request_json['number']}
57
58
  on repository #{owner}/#{repo_name}!
58
59
  MSG
59
60
  send_text_message(MY_PHONE_NUMBER, message) # or whatever you want
@@ -78,6 +79,7 @@ Typically, tokens and other secret values are stored as environment variables fo
78
79
  Here's one way you can generate and list tokens:
79
80
 
80
81
  ```ruby
82
+ #!/usr/bin/env ruby
81
83
  require 'right_hook/authenticator'
82
84
 
83
85
  puts "Please enter your username:"
@@ -101,6 +103,7 @@ Right Hook provides a way to tell GitHub you want to subscribe your Right Hook a
101
103
  It's easy!
102
104
 
103
105
  ```ruby
106
+ #!/usr/bin/env ruby
104
107
  require 'right_hook/subscriber'
105
108
 
106
109
  default_opts = {
@@ -113,7 +116,7 @@ subscriber = RightHook::Subscriber.new(default_opts)
113
116
  subscriber.subscribe(
114
117
  owner: 'octocat',
115
118
  repo_name: 'Hello-World',
116
- event_type: 'pull_request',
119
+ event_type: RightHook::Event::PULL_REQUEST,
117
120
  secret: 'secret_for_hello_world'
118
121
  )
119
122
  ```
@@ -21,12 +21,14 @@ module RightHook
21
21
  json = JSON.parse(params['payload'])
22
22
  case event_type
23
23
  when Event::PULL_REQUEST
24
- on_pull_request(owner, repo_name, json['number'], json['action'], json['pull_request'])
24
+ on_pull_request(owner, repo_name, json['action'], json['pull_request'])
25
25
  when Event::ISSUE
26
26
  on_issue(owner, repo_name, json['action'], json['issue'])
27
27
  else
28
28
  halt 500, "Server bug"
29
29
  end
30
+
31
+ 200
30
32
  end
31
33
 
32
34
  # It is up to you to override secret to determine how to look up the correct secret for an owner/repo combo.
@@ -46,4 +48,12 @@ module RightHook
46
48
  halt 202, "Signature mismatch" unless received_signature == calculated_signature
47
49
  end
48
50
  end
51
+
52
+ # Use this class if you're getting a mysterious 500 error in a test and you want to see what went wrong.
53
+ # Don't use it in production.
54
+ class DebugApp < App
55
+ disable :show_exceptions
56
+ disable :dump_errors
57
+ enable :raise_errors
58
+ end
49
59
  end
@@ -1,10 +1,13 @@
1
1
  require 'openssl'
2
2
  require 'uri'
3
+ require 'rack/test'
3
4
 
4
5
  module RightHook
5
6
  # Helpers for specs!
6
7
  # Typical usage is to include this module into your spec context, just like you would with Rack::Test::Methods.
7
8
  module SpecHelpers
9
+ include Rack::Test::Methods
10
+
8
11
  # Post to the given path, including the correct signature header based on the payload and secret.
9
12
  # @param [Hash] opts The options to use when crafting the request.
10
13
  # @option opts [String] :path The full path of the endpoint to which to post
@@ -8,6 +8,9 @@ module RightHook
8
8
  class Subscriber
9
9
  # The base URL for the binding (where your {RightHook::App} is hosted).
10
10
  attr_accessor :base_url
11
+ #
12
+ # The full target URL for the binding when used with #subscribe_direct.
13
+ attr_accessor :url
11
14
 
12
15
  # The OAuth token to use for authenticating with GitHub.
13
16
  # The token must belong to an account that has the +repo+ scope and collaborator privilege on the given repository.
@@ -20,18 +23,39 @@ module RightHook
20
23
  # See http://developer.github.com/v3/repos/hooks/ for a complete list of valid types.
21
24
  attr_accessor :event_type
22
25
 
26
+ # The user agent value to send on the request to github
27
+ # See: http://developer.github.com/v3/#user-agent-required
28
+ attr_accessor :user_agent
29
+
23
30
  # Initialize takes options which will be used as default values in other methods.
24
- # The valid keys in the options are [+base_url+, +oauth_token+, +owner+, and +event_type+].
31
+ # The valid keys in the options are [+base_url+, +oauth_token+, +owner+, +event_type+, and +user_agent+].
32
+ # @param [Hash] opts Subscription options. Defaults to attr_reader methods when such methods exist.
33
+ # @option opts [String] :owner The owner of the repository
34
+ # @option opts [String] :event_type A constant under RightHook::Event representing an event type
35
+ # @option opts [String] :base_url The URL of where the {RightHook::App} is hosted
36
+ # @option opts [String] :url The URL to receive requests from GitHub when a hook is activated
37
+ # @option opts [String] :oauth_token The OAuth token to use to authenticate with GitHub when subscribing
38
+ # @option opts [String] :user_agent The value to send for the User-Agent header when talking with GitHub
25
39
  def initialize(default_opts = {})
26
40
  @base_url = default_opts[:base_url]
41
+ @url = default_opts[:url]
27
42
  @oauth_token = default_opts[:oauth_token]
28
43
  @owner = default_opts[:owner]
29
44
  @event_type = default_opts[:event_type]
45
+ @user_agent = default_opts[:user_agent]
30
46
  end
31
47
 
32
48
  # Subscribe an instance of {RightHook::App} hosted at +base_url+ to a hook for +owner+/+repo_name+, authenticating with +oauth_token+.
33
49
  # +repo_name+ and +secret+ are required options and they are intentionally not stored as defaults on the +Subscriber+ instance.
50
+ # @param [Hash] opts Subscription options. Defaults to attr_reader methods when such methods exist.
34
51
  # @return [bool success] Whether the request was successful.
52
+ # @option opts [String] :owner The owner of the repository
53
+ # @option opts [String] :repo_name The name of the repository
54
+ # @option opts [String] :event_type A constant under RightHook::Event representing an event type
55
+ # @option opts [String] :base_url The URL of where the {RightHook::App} is hosted
56
+ # @option opts [String] :secret The secret to use to validate that a request came from GitHub. May be omitted
57
+ # @option opts [String] :oauth_token The OAuth token to use to authenticate with GitHub when subscribing
58
+ # @option opts [String] :user_agent The value to send for the User-Agent header when talking with GitHub
35
59
  def subscribe(opts)
36
60
  hub_request_with_mode('subscribe', opts)
37
61
  end
@@ -39,36 +63,82 @@ module RightHook
39
63
  # Unsubscribe an instance of {RightHook::App} hosted at +base_url+ to a hook for +owner+/+repo_name+, authenticating with +oauth_token+.
40
64
  # +repo_name+ and +secret+ are required options and they are intentionally not stored as defaults on the +Subscriber+ instance.
41
65
  # (NB: It's possible that GitHub's API *doesn't* require secret; I haven't checked.)
66
+ # @param [Hash] opts Subscription options. Defaults to attr_reader methods when such methods exist.
42
67
  # @return [bool success] Whether the request was successful.
68
+ # @option opts [String] :owner The owner of the repository
69
+ # @option opts [String] :repo_name The name of the repository
70
+ # @option opts [String] :event_type A constant under RightHook::Event representing an event type
71
+ # @option opts [String] :base_url The URL of where the {RightHook::App} is hosted
72
+ # @option opts [String] :secret The secret to use to validate that a request came from GitHub. May be omitted
73
+ # @option opts [String] :oauth_token The OAuth token to use to authenticate with GitHub when subscribing
74
+ # @option opts [String] :user_agent The value to send for the User-Agent header when talking with GitHub
43
75
  def unsubscribe(opts)
44
76
  hub_request_with_mode('unsubscribe', opts)
45
77
  end
46
78
 
79
+ # Subscribe directly to a fixed URL, rather than a calculated URL for an instance of {RightHook::App}.
80
+ # @return [bool success] Whether the request was successful.
81
+ # @param [Hash] opts Subscription options. Defaults to attr_reader methods when such methods exist.
82
+ # @option opts [String] :owner The owner of the repository
83
+ # @option opts [String] :repo_name The name of the repository
84
+ # @option opts [String] :event_type A constant under RightHook::Event representing an event type
85
+ # @option opts [String] :url The URL to receive requests from GitHub when a hook is activated
86
+ # @option opts [String] :secret The secret to use to validate that a request came from GitHub. May be omitted
87
+ # @option opts [String] :oauth_token The OAuth token to use to authenticate with GitHub when subscribing
88
+ # @option opts [String] :user_agent The value to send for the User-Agent header when talking with GitHub
89
+ def subscribe_direct(opts)
90
+ direct_hub_request_with_mode('subscribe', opts)
91
+ end
92
+
93
+ # Unsubscribe directly to a fixed URL, rather than a calculated URL for an instance of {RightHook::App}.
94
+ # @return [bool success] Whether the request was successful.
95
+ # @param [Hash] opts Subscription options. Defaults to attr_reader methods when such methods exist.
96
+ # @option opts [String] :owner The owner of the repository
97
+ # @option opts [String] :repo_name The name of the repository
98
+ # @option opts [String] :event_type A constant under RightHook::Event representing an event type
99
+ # @option opts [String] :url The URL to receive requests from GitHub when a hook is activated
100
+ # @option opts [String] :secret The secret to use to validate that a request came from GitHub. May be omitted
101
+ # @option opts [String] :oauth_token The OAuth token to use to authenticate with GitHub when subscribing
102
+ # @option opts [String] :user_agent The value to send for the User-Agent header when talking with GitHub
103
+ def unsubscribe_direct(opts)
104
+ direct_hub_request_with_mode('unsubscribe', opts)
105
+ end
106
+
47
107
  private
48
108
  def hub_request_with_mode(mode, opts)
49
109
  repo_name = opts.fetch(:repo_name) # explicitly not defaulted
50
- secret = opts.fetch(:secret) # explicitly not defaulted
51
- oauth_token = opts.fetch(:oauth_token) { self.oauth_token }
52
110
  owner = opts.fetch(:owner) { self.owner }
53
111
  base_url = opts.fetch(:base_url) { self.base_url }
54
112
  event_type = opts.fetch(:event_type) { self.event_type }
55
113
 
114
+ url = "#{base_url}/hook/#{owner}/#{repo_name}/#{event_type}"
115
+ direct_hub_request_with_mode(mode, opts.merge(url: url))
116
+ end
117
+
118
+ def direct_hub_request_with_mode(mode, opts)
119
+ repo_name = opts.fetch(:repo_name) # explicitly not defaulted
120
+ url = opts.fetch(:url) # explicitly not defaulted
121
+ secret = opts.fetch(:secret, nil)
122
+ owner = opts.fetch(:owner) { self.owner }
123
+ oauth_token = opts.fetch(:oauth_token) { self.oauth_token }
124
+ event_type = opts.fetch(:event_type) { self.event_type }
125
+ user_agent = opts.fetch(:user_agent) { self.user_agent }
126
+
56
127
  response = HTTParty.post('https://api.github.com/hub',
57
128
  headers: {
58
129
  # http://developer.github.com/v3/#authentication
59
- 'Authorization' => "token #{oauth_token}"
130
+ 'Authorization' => "token #{oauth_token}",
131
+ 'User-Agent' => user_agent.to_s
60
132
  },
61
133
  body: {
62
- 'hub.mode' => mode,
63
- 'hub.topic' => "https://github.com/#{owner}/#{repo_name}/events/#{Event.github_name(event_type)}",
64
- 'hub.callback' => "#{base_url}/hook/#{owner}/#{repo_name}/#{event_type}",
65
- 'hub.secret' => secret
66
- }
134
+ 'hub.mode' => mode,
135
+ 'hub.topic' => "https://github.com/#{owner}/#{repo_name}/events/#{Event.github_name(event_type)}",
136
+ 'hub.callback' => url,
137
+ 'hub.secret' => secret,
138
+ },
67
139
  )
68
140
 
69
- RightHook.logger.warn("Failure modifying subscription: #{response.inspect}") unless response.success?
70
-
71
- response.success?
141
+ raise "Failure modifying direct subscription: #{response.inspect}" unless response.success?
72
142
  end
73
143
  end
74
144
  end
@@ -1,3 +1,3 @@
1
1
  module RightHook
2
- VERSION = "0.4.2"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -2,18 +2,15 @@ require 'spec_helper'
2
2
 
3
3
  describe RightHook::App do
4
4
  describe 'Pull requests' do
5
- include Rack::Test::Methods
6
-
7
5
  class PullRequestApp < RightHook::App
8
6
  class << self
9
- attr_accessor :owner, :repo_name, :action, :number, :pull_request_json
7
+ attr_accessor :owner, :repo_name, :action, :pull_request_json
10
8
  end
11
9
 
12
- def on_pull_request(owner, repo_name, number, action, pull_request_json)
10
+ def on_pull_request(owner, repo_name, action, pull_request_json)
13
11
  self.class.owner = owner
14
12
  self.class.repo_name = repo_name
15
13
  self.class.action = action
16
- self.class.number = number
17
14
  self.class.pull_request_json = pull_request_json
18
15
  end
19
16
 
@@ -27,7 +24,7 @@ describe RightHook::App do
27
24
  end
28
25
 
29
26
  before do
30
- app.owner = app.repo_name = app.action = app.number = app.pull_request_json = nil
27
+ app.owner = app.repo_name = app.action = app.pull_request_json = nil
31
28
  end
32
29
 
33
30
  it 'captures the interesting data' do
@@ -36,7 +33,6 @@ describe RightHook::App do
36
33
  expect(app.owner).to eq('mark-rushakoff')
37
34
  expect(app.repo_name).to eq('right_hook')
38
35
  expect(app.action).to eq('opened')
39
- expect(app.number).to eq(1)
40
36
 
41
37
  # if it has one key it probably has them all
42
38
  expect(app.pull_request_json['body']).to eq('Please pull these awesome changes')
data/spec/app_spec.rb CHANGED
@@ -3,25 +3,42 @@ require 'spec_helper'
3
3
  describe RightHook::App do
4
4
  class BareApp < RightHook::App
5
5
  def secret(owner, repo_name, event_type)
6
- ''
6
+ 'secret'
7
7
  end
8
8
  end
9
9
 
10
- def app
11
- BareApp
12
- end
10
+ let(:app) { BareApp }
13
11
 
14
- it 'is status 501 for a non-implemented hook' do
15
- post_with_signature(path: '/hook/mark-rushakoff/right_hook/issue', payload: '{}', secret: '')
16
- expect(last_response.status).to eq(501)
17
- end
12
+ context 'An app with no hooks implemented' do
13
+ it 'is status 501 for a non-implemented hook' do
14
+ post_with_signature(path: '/hook/mark-rushakoff/right_hook/issue', payload: '{}', secret: '')
15
+ expect(last_response.status).to eq(501)
16
+ end
18
17
 
19
- it 'is 404 for an unknown hook' do
20
- post_with_signature(path: '/hook/mark-rushakoff/right_hook/not_a_real_thing', payload: '{}', secret: '')
21
- expect(last_response.status).to eq(404)
18
+ it 'is 404 for an unknown hook' do
19
+ post_with_signature(path: '/hook/mark-rushakoff/right_hook/not_a_real_thing', payload: '{}', secret: '')
20
+ expect(last_response.status).to eq(404)
21
+ end
22
22
  end
23
23
 
24
24
  it 'raises NotImplementedError for an unimplemented secret' do
25
25
  expect { RightHook::App.new!.secret('owner', 'repo', 'issue') }.to raise_error(NotImplementedError)
26
26
  end
27
+
28
+ describe 'the status of a request' do
29
+ class WeirdApp < BareApp
30
+ def on_issue(owner, repo_name, action, issue_json)
31
+ 302
32
+ end
33
+ end
34
+
35
+ let(:app) { WeirdApp }
36
+
37
+ it 'is 200 regardless of what the hook method returns' do
38
+ payload = '{}'
39
+ WeirdApp.any_instance.should_receive(:on_issue).and_call_original
40
+ post_with_signature(path: '/hook/mark-rushakoff/right_hook/issue', payload: payload, secret: 'secret')
41
+ expect(last_response.status).to eq(200)
42
+ end
43
+ end
27
44
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
1
4
  require 'right_hook'
2
5
  require 'right_hook/app'
3
6
  require 'right_hook/authenticated_client'
@@ -10,10 +13,6 @@ require 'right_hook/subscriber'
10
13
  require 'webmock/rspec'
11
14
  require 'rack/test'
12
15
 
13
- require 'coveralls'
14
- Coveralls.wear!
15
-
16
16
  RSpec.configure do |c|
17
- c.include Rack::Test::Methods
18
17
  c.include RightHook::SpecHelpers
19
18
  end
@@ -7,6 +7,7 @@ describe RightHook::Subscriber do
7
7
  owner: 'mark-rushakoff',
8
8
  base_url: 'http://example.com',
9
9
  event_type: RightHook::Event::ISSUE,
10
+ user_agent: 'My-User-Agent',
10
11
  )
11
12
  end
12
13
 
@@ -14,15 +15,16 @@ describe RightHook::Subscriber do
14
15
  let!(:stubbed_request) do
15
16
  stub_request(:post, 'https://api.github.com/hub').
16
17
  with(:body => 'hub.mode=subscribe&hub.topic=https%3A%2F%2Fgithub.com%2Fmark-rushakoff%2Fright_hook%2Fevents%2Fissues&hub.callback=http%3A%2F%2Fexample.com%2Fhook%2Fmark-rushakoff%2Fright_hook%2Fissue&hub.secret=the-secret',
17
- :headers => {'Authorization' => 'token my_token'}
18
+ :headers => {'Authorization' => 'token my_token', 'User-Agent' => 'My-User-Agent'}
18
19
  ).to_return(:status => status_code, :body => '', :headers => {})
19
20
  end
20
21
 
21
22
  context 'When the request succeeds' do
22
23
  let(:status_code) { 200 }
23
- it 'returns true' do
24
- result = subscriber.subscribe(repo_name: 'right_hook', secret: 'the-secret')
25
- expect(result).to eq(true)
24
+ it 'does not raise' do
25
+ expect {
26
+ subscriber.subscribe(repo_name: 'right_hook', secret: 'the-secret')
27
+ }.not_to raise_error
26
28
 
27
29
  expect(stubbed_request).to have_been_requested
28
30
  end
@@ -30,9 +32,10 @@ describe RightHook::Subscriber do
30
32
 
31
33
  context 'When the request fails' do
32
34
  let(:status_code) { 404 }
33
- it 'returns false' do
34
- result = subscriber.subscribe(repo_name: 'right_hook', secret: 'the-secret')
35
- expect(result).to eq(false)
35
+ it 'raises' do
36
+ expect {
37
+ subscriber.subscribe(repo_name: 'right_hook', secret: 'the-secret')
38
+ }.to raise_error
36
39
 
37
40
  expect(stubbed_request).to have_been_requested
38
41
  end
@@ -41,16 +44,67 @@ describe RightHook::Subscriber do
41
44
  context 'When everything is overridden' do
42
45
  let(:status_code) { 200 }
43
46
  it 'works' do
44
- s = described_class.new
45
- result = s.subscribe(
46
- repo_name: 'right_hook',
47
- secret: 'the-secret',
48
- oauth_token: 'my_token',
49
- owner: 'mark-rushakoff',
50
- base_url: 'http://example.com',
51
- event_type: RightHook::Event::ISSUE
52
- )
53
- expect(result).to eq(true)
47
+ expect {
48
+ described_class.new.subscribe(
49
+ repo_name: 'right_hook',
50
+ secret: 'the-secret',
51
+ oauth_token: 'my_token',
52
+ owner: 'mark-rushakoff',
53
+ base_url: 'http://example.com',
54
+ event_type: RightHook::Event::ISSUE,
55
+ user_agent: 'My-User-Agent',
56
+ )
57
+ }.not_to raise_error
58
+
59
+ expect(stubbed_request).to have_been_requested
60
+ end
61
+ end
62
+ end
63
+
64
+ describe '.subscribe_direct' do
65
+ let!(:stubbed_request) do
66
+ stub_request(:post, 'https://api.github.com/hub').
67
+ with(:body => 'hub.mode=subscribe&hub.topic=https%3A%2F%2Fgithub.com%2Fmark-rushakoff%2Fright_hook%2Fevents%2Fissues&hub.callback=http%3A%2F%2Fhook.example.com&hub.secret=the-secret',
68
+ :headers => {'Authorization' => 'token my_token', 'User-Agent' => 'My-User-Agent'}
69
+ ).to_return(:status => status_code, :body => '', :headers => {})
70
+ end
71
+
72
+ context 'When the request succeeds' do
73
+ let(:status_code) { 200 }
74
+ it 'does not raise' do
75
+ expect {
76
+ subscriber.subscribe_direct(repo_name: 'right_hook', secret: 'the-secret', url: 'http://hook.example.com')
77
+ }.not_to raise_error
78
+
79
+ expect(stubbed_request).to have_been_requested
80
+ end
81
+ end
82
+
83
+ context 'When the request fails' do
84
+ let(:status_code) { 404 }
85
+ it 'raises' do
86
+ expect {
87
+ subscriber.subscribe_direct(repo_name: 'right_hook', secret: 'the-secret', url: 'http://hook.example.com')
88
+ }.to raise_error
89
+
90
+ expect(stubbed_request).to have_been_requested
91
+ end
92
+ end
93
+
94
+ context 'When everything is overridden' do
95
+ let(:status_code) { 200 }
96
+ it 'works' do
97
+ expect {
98
+ described_class.new.subscribe_direct(
99
+ owner: 'mark-rushakoff',
100
+ repo_name: 'right_hook',
101
+ event_type: RightHook::Event::ISSUE,
102
+ url: 'http://hook.example.com',
103
+ secret: 'the-secret',
104
+ oauth_token: 'my_token',
105
+ user_agent: 'My-User-Agent',
106
+ )
107
+ }.not_to raise_error
54
108
 
55
109
  expect(stubbed_request).to have_been_requested
56
110
  end
@@ -61,16 +115,17 @@ describe RightHook::Subscriber do
61
115
  let!(:stubbed_request) do
62
116
  stub_request(:post, 'https://api.github.com/hub').
63
117
  with(:body => 'hub.mode=unsubscribe&hub.topic=https%3A%2F%2Fgithub.com%2Fmark-rushakoff%2Fright_hook%2Fevents%2Fissues&hub.callback=http%3A%2F%2Fexample.com%2Fhook%2Fmark-rushakoff%2Fright_hook%2Fissue&hub.secret=the-secret',
64
- :headers => {'Authorization' => 'token my_token'}
118
+ :headers => {'Authorization' => 'token my_token', 'User-Agent' => 'My-User-Agent'}
65
119
  ).to_return(:status => status_code, :body => '', :headers => {})
66
120
  end
67
121
 
68
122
 
69
123
  context 'When the request succeeds' do
70
124
  let(:status_code) { 200 }
71
- it 'returns true' do
72
- result = subscriber.unsubscribe(repo_name: 'right_hook', secret: 'the-secret')
73
- expect(result).to eq(true)
125
+ it 'does not raise' do
126
+ expect {
127
+ subscriber.unsubscribe(repo_name: 'right_hook', secret: 'the-secret')
128
+ }.not_to raise_error
74
129
 
75
130
  expect(stubbed_request).to have_been_requested
76
131
  end
@@ -78,9 +133,60 @@ describe RightHook::Subscriber do
78
133
 
79
134
  context 'When the request fails' do
80
135
  let(:status_code) { 404 }
81
- it 'returns false' do
82
- result = subscriber.unsubscribe(repo_name: 'right_hook', secret: 'the-secret')
83
- expect(result).to eq(false)
136
+ it 'raises' do
137
+ expect {
138
+ subscriber.unsubscribe(repo_name: 'right_hook', secret: 'the-secret')
139
+ }.to raise_error
140
+
141
+ expect(stubbed_request).to have_been_requested
142
+ end
143
+ end
144
+ end
145
+
146
+ describe '.unsubscribe_direct' do
147
+ let!(:stubbed_request) do
148
+ stub_request(:post, 'https://api.github.com/hub').
149
+ with(:body => 'hub.mode=unsubscribe&hub.topic=https%3A%2F%2Fgithub.com%2Fmark-rushakoff%2Fright_hook%2Fevents%2Fissues&hub.callback=http%3A%2F%2Fhook.example.com&hub.secret=the-secret',
150
+ :headers => {'Authorization' => 'token my_token', 'User-Agent' => 'My-User-Agent'}
151
+ ).to_return(:status => status_code, :body => '', :headers => {})
152
+ end
153
+
154
+ context 'When the request succeeds' do
155
+ let(:status_code) { 200 }
156
+ it 'does not raise' do
157
+ expect {
158
+ subscriber.unsubscribe_direct(repo_name: 'right_hook', secret: 'the-secret', url: 'http://hook.example.com')
159
+ }.not_to raise_error
160
+
161
+ expect(stubbed_request).to have_been_requested
162
+ end
163
+ end
164
+
165
+ context 'When the request fails' do
166
+ let(:status_code) { 404 }
167
+ it 'raises' do
168
+ expect {
169
+ subscriber.unsubscribe_direct(repo_name: 'right_hook', secret: 'the-secret', url: 'http://hook.example.com')
170
+ }.to raise_error
171
+
172
+ expect(stubbed_request).to have_been_requested
173
+ end
174
+ end
175
+
176
+ context 'When everything is overridden' do
177
+ let(:status_code) { 200 }
178
+ it 'works' do
179
+ expect {
180
+ described_class.new.unsubscribe_direct(
181
+ owner: 'mark-rushakoff',
182
+ repo_name: 'right_hook',
183
+ event_type: RightHook::Event::ISSUE,
184
+ url: 'http://hook.example.com',
185
+ secret: 'the-secret',
186
+ oauth_token: 'my_token',
187
+ user_agent: 'My-User-Agent',
188
+ )
189
+ }.not_to raise_error
84
190
 
85
191
  expect(stubbed_request).to have_been_requested
86
192
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: right_hook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-02 00:00:00.000000000 Z
12
+ date: 2013-12-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler