party_foul 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -14,22 +14,20 @@ following:
14
14
  1. Will attempt to find a matching issue in your Github repo
15
15
  2. If no matching issue is found an new issue will be created with a
16
16
  unique title, session information, and stack trace. The issue will be
17
- tagged as a `bug`
17
+ tagged as a `bug`. A new comment will be added with relevant data on the
18
+ application state.
18
19
  3. If an open issue is found the occurance count and time stamp will be
19
- updated
20
+ updated. A new comment will be added with relevant data on the
21
+ application state.
20
22
  4. If a closed issue is found the occurance count and time stamp will be
21
23
  updated. The issue will be reopened and a `regression` tag will be
22
- added.
24
+ added. A new comment will be added with relevant data on the
25
+ application state.
23
26
  5. If the issue is marked as `wontfix` the issue is not updated nor is
24
- a new issue created.
27
+ a new issue created. No comments will be added.
25
28
 
26
29
  ## Installation ##
27
30
 
28
- Prior to installing the gem you will need to set up an OAuth application
29
- on Github to provide access to your repository. Once this OAuth
30
- application is setup you will have a `ClientID` and `ClientSecret` that
31
- you will need to complete the installation.
32
-
33
31
  **Note** We highly recommend that you create a new Github account that is
34
32
  a collaborator on your repository. Use this new account's credentials
35
33
  for the installation below. If you use your own account you will
@@ -58,7 +56,7 @@ token in version control.
58
56
  Add as the very last middleware in your production `Rack` stack in `config/environments/production.rb`
59
57
 
60
58
  ```ruby
61
- config.middleware.insert_before(-1, 'PartyFoul::Middleware')
59
+ config.middleware.use('PartyFoul::Middleware')
62
60
  ```
63
61
  ### Other ###
64
62
 
@@ -69,7 +67,7 @@ so:
69
67
  PartyFoul.configure do |config|
70
68
  # the collection of exceptions to be ignored by PartyFoul
71
69
  # The constants here *must* be represented as strings
72
- config.ignored_exceptions = ['ActiveRecord::RecordNotFound']
70
+ config.ignored_exceptions = ['ActiveRecord::RecordNotFound', 'ActionController::RoutingError']
73
71
 
74
72
  # The OAuth token for the account that will be opening the issues on Github
75
73
  config.oauth_token = 'abcdefgh1234567890'
@@ -86,10 +84,63 @@ PartyFoul.configure do |config|
86
84
  end
87
85
  ```
88
86
 
87
+ You can generate an OAuth token from via the
88
+ [OAuth Authorizations API](http://developer.github.com/v3/oauth/#oauth-authorizations-api)
89
+ with cURL:
90
+
91
+ ```bash
92
+ curl -X POST -i -d "{ \"scopes\": [\"repo\"] }" \
93
+ https://<github_login>:<github_password>@api.github.com/authorizations
94
+ ```
95
+
89
96
  Add as the very last middleware in your production `Rack` stack.
90
97
 
91
- ## Usage ##
98
+ ## Customization ##
99
+
100
+ ### Async Adapters ###
101
+
102
+ You can specify the adapter with which the exceptions should be
103
+ handled. By default, PartyFoul includes the
104
+ [`PartyFoul::SyncAdapter`](https://github.com/dockyard/party_foul/tree/master/lib/party_foul/sync_adapter.rb)
105
+ which will handle the exception synchronously. To use your own adapter,
106
+ include the following in your `PartyFoul.configure` block:
107
+
108
+ ```ruby
109
+ PartyFoul.configure do |config|
110
+ config.adapter = MyAsyncAdatper
111
+ end
112
+
113
+ class MyAsyncAdapter
114
+ def self.handle(exception, env)
115
+ # Enqueue the exception, then in your worker, call
116
+ # PartyFoul::ExceptionHandler.new(exception, env).run
117
+ end
118
+ end
119
+
120
+ ```
121
+
122
+ ## Changing How Issues Are Reported ##
123
+
124
+ `PartyFoul` comes with default templates for what the body of issues and
125
+ comments are. If you want to override these templates you simply need to
126
+ add them as an option in your initializer:
127
+
128
+ ```ruby
129
+ PartyFoul.configure do |config|
130
+ config.issue_body = <<-TEMPLATE
131
+ :issue_title
132
+ TEMPLATE
133
+
134
+ config.comment_body = <<-TEMPLATE
135
+ :occurred_at
136
+ TEMPLATE
137
+ ```
92
138
 
139
+ In this over-simplistic example the words that start with `:` in the
140
+ templates will be evaluated with the value of the corresponding named
141
+ instance method on the instance of `PartyFoul::ExceptionHandler`. If you
142
+ want to add additional values for replacement you should open that class
143
+ to add the methods.
93
144
 
94
145
  ## Authors ##
95
146
 
@@ -111,7 +162,7 @@ on how to properly submit issues and pull requests.
111
162
 
112
163
  ## Legal ##
113
164
 
114
- [DockYard](http://dockyard.com), LLC &copy; 2012
165
+ [DockYard](http://dockyard.com), LLC &copy; 2013
115
166
 
116
167
  [@dockyard](http://twitter.com/dockyard)
117
168
 
@@ -4,71 +4,42 @@ require 'net/http'
4
4
 
5
5
  module PartyFoul
6
6
  class InstallGenerator < Rails::Generators::Base
7
+ source_root File.expand_path('../templates', __FILE__)
7
8
 
8
9
  def create_initializer_file
9
- puts 'A Github Application is required'
10
-
11
- client_id = ask 'Github App Client ID:'
12
- client_secret = ask 'Github App Client Secret:'
13
- username = ask 'Github username:'
14
- password = STDIN.noecho do
10
+ username = ask 'Github username:'
11
+ password = STDIN.noecho do
15
12
  ask 'Github password:'
16
13
  end
17
- say ''
18
-
19
- owner = ask 'Repository owner:'
20
- repo = ask 'Repository name:'
21
- auth_uri = URI("https://api.github.com/authorizations")
22
-
23
- response = nil
24
- Net::HTTP.start(auth_uri.host, auth_uri.port, :use_ssl => auth_uri.scheme == 'https') do |http|
25
- request = Net::HTTP::Post.new auth_uri.request_uri
26
- body = { :scopes => ['repo'], :client_id => client_id, :client_secret => client_secret }
27
- request.body = body.to_json
28
-
29
- request.basic_auth username, password
30
-
31
- response = http.request request
32
- end
33
14
 
34
- if response.code == '201'
35
- oauth_token = JSON.parse(response.body)['token']
36
-
37
- File.open('config/initializers/party_foul.rb', 'w') do |f|
38
- f.puts <<-CONTENTS
39
- PartyFoul.configure do |config|
40
- # the collection of exceptions to be ignored by PartyFoul
41
- # The constants here *must* be represented as strings
42
- config.ignored_exceptions = ['ActiveRecord::RecordNotFound']
43
-
44
- # The OAuth token for the account that will be opening the issues on Github
45
- config.oauth_token = '#{oauth_token}'
15
+ say ''
46
16
 
47
- # The API endpoint for Github. Unless you are hosting a private
48
- # instance of Enterprise Github you do not need to include this
49
- config.endpoint = 'https://api.github.com'
17
+ @owner = ask_with_default 'Repository owner:', username
18
+ @repo = ask 'Repository name:'
19
+ @endpoint = ask_with_default 'Endpoint:', 'https://api.github.com'
50
20
 
51
- # The organization or user that owns the target repository
52
- config.owner = '#{owner}'
21
+ github = Github.new :login => username, :password => password, :endpoint => @endpoint
53
22
 
54
- # The repository for this application
55
- config.repo = '#{repo}'
56
- end
57
- CONTENTS
58
- end
59
- else
23
+ begin
24
+ github.oauth.create 'scopes' => ['repo']
25
+ @oauth_token = github.oauth_token
26
+ template 'party_foul.rb', 'config/initializers/party_foul.rb'
27
+ rescue Github::Error::Unauthorized
60
28
  say 'There was an error retrieving your Github OAuth token'
61
29
  end
62
-
63
- say 'Done'
64
30
  end
65
31
 
66
32
  private
67
33
 
68
34
  def self.installation_message
69
- 'Generates the configuration file'
35
+ 'Generates the initializer'
70
36
  end
71
37
 
72
38
  desc installation_message
39
+
40
+ def ask_with_default(prompt, default)
41
+ value = ask("#{prompt} [#{default}]")
42
+ value.blank? ? default : value
43
+ end
73
44
  end
74
45
  end
@@ -0,0 +1,18 @@
1
+ PartyFoul.configure do |config|
2
+ # the collection of exceptions to be ignored by PartyFoul
3
+ # The constants here *must* be represented as strings
4
+ config.ignored_exceptions = ['ActiveRecord::RecordNotFound', 'ActionController::RoutingError']
5
+
6
+ # The OAuth token for the account that will be opening the issues on Github
7
+ config.oauth_token = '<%= @oauth_token %>'
8
+
9
+ # The API endpoint for Github. Unless you are hosting a private
10
+ # instance of Enterprise Github you do not need to include this
11
+ config.endpoint = '<%= @endpoint %>'
12
+
13
+ # The organization or user that owns the target repository
14
+ config.owner = '<%= @owner %>'
15
+
16
+ # The repository for this application
17
+ config.repo = '<%= @repo %>'
18
+ end
@@ -2,8 +2,7 @@ class PartyFoul::ExceptionHandler
2
2
  attr_accessor :exception, :env
3
3
 
4
4
  def self.handle(exception, env)
5
- handler = self.new(exception, env)
6
- handler.run
5
+ PartyFoul.adapter.handle(exception, env)
7
6
  end
8
7
 
9
8
  def initialize(exception, env)
@@ -38,7 +37,8 @@ class PartyFoul::ExceptionHandler
38
37
  end
39
38
 
40
39
  def create_issue
41
- PartyFoul.github.issues.create(PartyFoul.owner, PartyFoul.repo, title: issue_title, body: issue_body, labels: ['bug'])
40
+ issue = PartyFoul.github.issues.create(PartyFoul.owner, PartyFoul.repo, title: issue_title, body: issue_body, labels: ['bug'])
41
+ PartyFoul.github.issues.comments.create(PartyFoul.owner, PartyFoul.repo, issue['number'], body: comment_body)
42
42
  end
43
43
 
44
44
  def update_issue(issue)
@@ -50,6 +50,7 @@ class PartyFoul::ExceptionHandler
50
50
  end
51
51
 
52
52
  PartyFoul.github.issues.edit(PartyFoul.owner, PartyFoul.repo, issue['number'], params)
53
+ PartyFoul.github.issues.comments.create(PartyFoul.owner, PartyFoul.repo, issue['number'], body: comment_body)
53
54
  end
54
55
  end
55
56
 
@@ -67,7 +68,7 @@ class PartyFoul::ExceptionHandler
67
68
  begin
68
69
  current_count = body.match(/<th>Count<\/th><td>(\d+)<\/td>/)[1].to_i
69
70
  body.sub!("<th>Count</th><td>#{current_count}</td>", "<th>Count</th><td>#{current_count + 1}</td>")
70
- body.sub!(/<th>Last Occurance<\/th><td>.+<\/td>/, "<th>Last Occurance</th><td>#{Time.now}</td>")
71
+ body.sub!(/<th>Last Occurance<\/th><td>.+<\/td>/, "<th>Last Occurance</th><td>#{occurred_at}</td>")
71
72
  body
72
73
  rescue
73
74
  issue_body
@@ -84,18 +85,29 @@ class PartyFoul::ExceptionHandler
84
85
  end
85
86
 
86
87
  def issue_body
87
- <<-BODY
88
- <table>
89
- <tr><th>Count</th><td>1</td></tr>
90
- <tr><th>Last Occurance</th><td>#{Time.now}</td></tr>
91
- <tr><th>Params</th><td>#{params}</td></tr>
92
- <tr><th>Exception</th><td>#{exception}</td></tr>
93
- </table>
94
-
95
- ## Stack Trace
96
- <pre>#{stack_trace}</pre>
97
- Fingerprint: `#{fingerprint}`
98
- BODY
88
+ compile_template(PartyFoul.issue_template)
89
+ end
90
+
91
+ def comment_body
92
+ compile_template(PartyFoul.comment_template)
93
+ end
94
+
95
+ def compile_template(template)
96
+ template.gsub(/:\w+/) do |method|
97
+ self.send(method.split(':').last)
98
+ end
99
+ end
100
+
101
+ def occurred_at
102
+ Time.now.strftime('%B %d, %Y %H:%M:%S %z')
103
+ end
104
+
105
+ def ip_address
106
+ env['REMOTE_ADDR']
107
+ end
108
+
109
+ def http_headers
110
+ "<table>#{env.keys.select { |k| k =~ /^HTTP_/ }.sort.map { |k| "<tr><th>#{k.split('HTTP_').last.split('_').map(&:capitalize).join(' ')}</th><td>#{env[k]}</td></tr>" }.join }</table>"
99
111
  end
100
112
 
101
113
  private
@@ -0,0 +1,5 @@
1
+ class PartyFoul::SyncAdapter
2
+ def self.handle(exception, env)
3
+ PartyFoul::ExceptionHandler.new(exception, env).run
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  module PartyFoul
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/party_foul.rb CHANGED
@@ -2,7 +2,34 @@ require 'github_api'
2
2
 
3
3
  module PartyFoul
4
4
  class << self
5
- attr_accessor :github, :oauth_token, :endpoint, :owner, :repo, :ignored_exceptions
5
+ attr_accessor :github, :oauth_token, :endpoint, :owner, :repo, :ignored_exceptions, :adapter, :issue_template, :comment_template
6
+ end
7
+
8
+ def self.issue_template
9
+ @issue_template ||=
10
+ <<-TEMPLATE
11
+ <table>
12
+ <tr><th>Exception</th><td>:exception</td></tr>
13
+ <tr><th>Count</th><td>1</td></tr>
14
+ <tr><th>Last Occurance</th><td>:occurred_at</td></tr>
15
+ </table>
16
+
17
+ ## Stack Trace
18
+ <pre>:stack_trace</pre>
19
+ Fingerprint: `:fingerprint`
20
+ TEMPLATE
21
+ end
22
+
23
+ def self.comment_template
24
+ @comment_template ||=
25
+ <<-TEMPLATE
26
+ <table>
27
+ <tr><th>Occurred at</th><td>:occurred_at</td></tr>
28
+ <tr><th>Params</th><td>:params</td></tr>
29
+ <tr><th>IP Address</th><td>:ip_address</td></tr>
30
+ <tr><th>HTTP Headers</th><td>:http_headers</td></tr>
31
+ </table>
32
+ TEMPLATE
6
33
  end
7
34
 
8
35
  def self.ignored_exceptions
@@ -11,6 +38,7 @@ module PartyFoul
11
38
 
12
39
  def self.configure(&block)
13
40
  yield self
41
+ self.adapter ||= SyncAdapter
14
42
  _self = self
15
43
  self.github ||= Github.new do |config|
16
44
  %w{endpoint oauth_token}.each do |option|
@@ -22,3 +50,4 @@ end
22
50
 
23
51
  require 'party_foul/exception_handler'
24
52
  require 'party_foul/middleware'
53
+ require 'party_foul/sync_adapter'
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+ require 'rails/generators/test_case'
3
+ require 'generators/party_foul/install_generator'
4
+
5
+ class PartyFoul::GeneratorTest < Rails::Generators::TestCase
6
+ destination File.expand_path('../tmp', __FILE__)
7
+ tests PartyFoul::InstallGenerator
8
+ test 'it copies the initializer' do
9
+ oauth = mock('Oauth')
10
+ oauth.stubs(:create)
11
+ oauth.expects(:create).with('scopes' => ['repo'])
12
+ github = mock('Github')
13
+ github.stubs(:oauth).returns(oauth)
14
+ github.stubs(:oauth_token).returns('test_token')
15
+ Github.stubs(:new).with(:login => 'test_login', :password => 'test_password', :endpoint => 'test_endpoint').returns(github)
16
+ $stdin.stubs(:gets).returns('test_login').then.returns('test_password').then.returns('').then.returns('test_repo').then.returns("test_endpoint").then.returns('')
17
+ run_generator
18
+
19
+ assert_file 'config/initializers/party_foul.rb' do |initializer|
20
+ assert_match(/config.endpoint\s+=\s'test_endpoint'/, initializer)
21
+ assert_match(/config.owner\s+=\s'test_login'/, initializer)
22
+ assert_match(/config.repo\s+=\s'test_repo'/, initializer)
23
+ assert_match(/config.oauth_token\s+=\s'test_token'/, initializer)
24
+ end
25
+ end
26
+ end
@@ -11,19 +11,17 @@ describe 'Party Foul Exception Handler' do
11
11
  describe 'updating issue body' do
12
12
  before do
13
13
  @handler = PartyFoul::ExceptionHandler.new(nil, nil)
14
+ @handler.stubs(:exception).returns('Test Exception')
14
15
  @handler.stubs(:fingerprint).returns('abcdefg1234567890')
15
16
  @handler.stubs(:stack_trace)
16
- @handler.stubs(:params)
17
- @handler.stubs(:exception)
18
17
  end
19
18
 
20
19
  it 'updates count and timestamp' do
21
20
  body = <<-BODY
22
21
  <table>
22
+ <tr><th>Exception</th><td>Test Exception</td></tr>
23
23
  <tr><th>Count</th><td>1</td></tr>
24
- <tr><th>Last Occurance</th><td>#{Time.now}</td></tr>
25
- <tr><th>Params</th><td></td></tr>
26
- <tr><th>Exception</th><td></td></tr>
24
+ <tr><th>Last Occurance</th><td>December 31, 1969 19:00:00 -0500</td></tr>
27
25
  </table>
28
26
 
29
27
  ## Stack Trace
@@ -35,10 +33,9 @@ Fingerprint: `abcdefg1234567890`
35
33
 
36
34
  expected_body = <<-BODY
37
35
  <table>
36
+ <tr><th>Exception</th><td>Test Exception</td></tr>
38
37
  <tr><th>Count</th><td>2</td></tr>
39
- <tr><th>Last Occurance</th><td>#{Time.now}</td></tr>
40
- <tr><th>Params</th><td></td></tr>
41
- <tr><th>Exception</th><td></td></tr>
38
+ <tr><th>Last Occurance</th><td>October 25, 1985 01:22:00 -0500</td></tr>
42
39
  </table>
43
40
 
44
41
  ## Stack Trace
@@ -53,19 +50,17 @@ Fingerprint: `abcdefg1234567890`
53
50
  describe 'empty body' do
54
51
  before do
55
52
  @handler = PartyFoul::ExceptionHandler.new(nil, nil)
53
+ @handler.stubs(:exception).returns('Test Exception')
56
54
  @handler.stubs(:fingerprint).returns('abcdefg1234567890')
57
55
  @handler.stubs(:stack_trace)
58
- @handler.stubs(:params)
59
- @handler.stubs(:exception)
60
56
  end
61
57
 
62
58
  it 'resets body' do
63
59
  expected_body = <<-BODY
64
60
  <table>
61
+ <tr><th>Exception</th><td>Test Exception</td></tr>
65
62
  <tr><th>Count</th><td>1</td></tr>
66
- <tr><th>Last Occurance</th><td>#{Time.now}</td></tr>
67
- <tr><th>Params</th><td></td></tr>
68
- <tr><th>Exception</th><td></td></tr>
63
+ <tr><th>Last Occurance</th><td>December 31, 1969 19:00:00 -0500</td></tr>
69
64
  </table>
70
65
 
71
66
  ## Stack Trace
@@ -99,4 +94,40 @@ Fingerprint: `abcdefg1234567890`
99
94
  end
100
95
  end
101
96
  end
97
+
98
+ describe '#issue_comment' do
99
+ before do
100
+ env = {
101
+ 'REQUEST_URI' => 'http://example.com/',
102
+ 'HTTP_USER_AGENT' => 'test_user_agent',
103
+ 'REMOTE_ADDR' => '127.0.0.1',
104
+ 'HTTP_HOST' => 'localhost:3000',
105
+ 'QUERY_STRING' => { :controller => 'landing', :action => 'index' }
106
+ }
107
+ @handler = PartyFoul::ExceptionHandler.new(nil, env)
108
+ end
109
+
110
+ it 'renders a new comment' do
111
+ expected_comment = <<-COMMENT
112
+ <table>
113
+ <tr><th>Occurred at</th><td>December 31, 1969 19:00:00 -0500</td></tr>
114
+ <tr><th>Params</th><td>{:controller=>"landing", :action=>"index"}</td></tr>
115
+ <tr><th>IP Address</th><td>127.0.0.1</td></tr>
116
+ <tr><th>HTTP Headers</th><td><table><tr><th>Host</th><td>localhost:3000</td></tr><tr><th>User Agent</th><td>test_user_agent</td></tr></table></td></tr>
117
+ </table>
118
+ COMMENT
119
+
120
+ @handler.comment_body.must_equal expected_comment
121
+ end
122
+ end
123
+
124
+ describe '#compile_template' do
125
+ it 'it parses the tags and inserts proper data' do
126
+ template = '<span>:data1</span><div>:data2</div>'
127
+ @handler = PartyFoul::ExceptionHandler.new(nil, nil)
128
+ @handler.stubs(:data1).returns('123')
129
+ @handler.stubs(:data2).returns('abc')
130
+ @handler.compile_template(template).must_equal '<span>123</span><div>abc</div>'
131
+ end
132
+ end
102
133
  end
@@ -31,6 +31,8 @@ describe 'Party Foul Middleware' do
31
31
  PartyFoul.github.stubs(:search).returns(mock('Search'))
32
32
  PartyFoul.github.issues.stubs(:create)
33
33
  PartyFoul.github.issues.stubs(:edit)
34
+ PartyFoul.github.issues.stubs(:comments).returns(mock('Comments'))
35
+ PartyFoul.github.issues.comments.stubs(:create)
34
36
  PartyFoul::ExceptionHandler.any_instance.stubs(:issue_title).returns('Test Title')
35
37
  PartyFoul::ExceptionHandler.any_instance.stubs(:fingerprint).returns('test_fingerprint')
36
38
  end
@@ -38,9 +40,11 @@ describe 'Party Foul Middleware' do
38
40
  context 'when error is new' do
39
41
  it 'will open a new error on Github' do
40
42
  PartyFoul::ExceptionHandler.any_instance.stubs(:issue_body).returns('Test Body')
43
+ PartyFoul::ExceptionHandler.any_instance.stubs(:comment_body).returns('Test Comment')
41
44
  PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
42
45
  PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'closed').returns(Hashie::Mash.new(issues: []))
43
- PartyFoul.github.issues.expects(:create).with('test_owner', 'test_repo', title: 'Test Title', body: 'Test Body', :labels => ['bug'])
46
+ PartyFoul.github.issues.expects(:create).with('test_owner', 'test_repo', title: 'Test Title', body: 'Test Body', :labels => ['bug']).returns(Hashie::Mash.new('number' => 1))
47
+ PartyFoul.github.issues.comments.expects(:create).with('test_owner', 'test_repo', 1, body: 'Test Comment')
44
48
  lambda {
45
49
  get '/'
46
50
  }.must_raise(Exception)
@@ -50,12 +54,14 @@ describe 'Party Foul Middleware' do
50
54
  context 'when error is not new' do
51
55
  before do
52
56
  PartyFoul::ExceptionHandler.any_instance.stubs(:update_body).returns('New Body')
57
+ PartyFoul::ExceptionHandler.any_instance.stubs(:comment_body).returns('Test Comment')
53
58
  end
54
59
 
55
60
  context 'and open' do
56
61
  it 'will update the issue' do
57
62
  PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: [{title: 'Test Title', body: 'Test Body', state: 'open', number: 1}]))
58
63
  PartyFoul.github.issues.expects(:edit).with('test_owner', 'test_repo', 1, body: 'New Body', state: 'open')
64
+ PartyFoul.github.issues.comments.expects(:create).with('test_owner', 'test_repo', 1, body: 'Test Comment')
59
65
  lambda {
60
66
  get '/'
61
67
  }.must_raise(Exception)
@@ -67,6 +73,7 @@ describe 'Party Foul Middleware' do
67
73
  PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
68
74
  PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'closed').returns(Hashie::Mash.new(issues: [{title: 'Test Title', body: 'Test Body', state: 'closed', number: 1}]))
69
75
  PartyFoul.github.issues.expects(:edit).with('test_owner', 'test_repo', 1, body: 'New Body', state: 'open', labels: ['bug', 'regression'])
76
+ PartyFoul.github.issues.comments.expects(:create).with('test_owner', 'test_repo', 1, body: 'Test Comment')
70
77
  lambda {
71
78
  get '/'
72
79
  }.must_raise(Exception)
@@ -81,6 +88,7 @@ describe 'Party Foul Middleware' do
81
88
  PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'closed').returns(Hashie::Mash.new(issues: [{title: 'Test Title', body: 'Test Body', state: 'closed', number: 1, 'labels' => ['wontfix']}]))
82
89
  PartyFoul.github.issues.expects(:create).never
83
90
  PartyFoul.github.issues.expects(:edit).never
91
+ PartyFoul.github.issues.comments.expects(:create).never
84
92
  lambda {
85
93
  get '/'
86
94
  }.must_raise(Exception)
@@ -98,6 +106,7 @@ describe 'Party Foul Middleware' do
98
106
  PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
99
107
  PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'closed').returns(Hashie::Mash.new(issues: []))
100
108
  PartyFoul.github.issues.expects(:create).never
109
+ PartyFoul.github.issues.comments.expects(:create).never
101
110
  lambda {
102
111
  get '/'
103
112
  }.must_raise(StandardError)
data/test/test_helper.rb CHANGED
@@ -5,8 +5,9 @@ else
5
5
  end
6
6
  require 'rack/test'
7
7
  require 'mocha/setup'
8
- require 'bourne'
9
- require 'debugger'
8
+ unless ENV['CI']
9
+ require 'debugger'
10
+ end
10
11
  require 'party_foul'
11
12
 
12
13
  class MiniTest::Spec
@@ -0,0 +1,18 @@
1
+ PartyFoul.configure do |config|
2
+ # the collection of exceptions to be ignored by PartyFoul
3
+ # The constants here *must* be represented as strings
4
+ config.ignored_exceptions = ['ActiveRecord::RecordNotFound', 'ActionController::RoutingError']
5
+
6
+ # The OAuth token for the account that will be opening the issues on Github
7
+ config.oauth_token = 'test_token'
8
+
9
+ # The API endpoint for Github. Unless you are hosting a private
10
+ # instance of Enterprise Github you do not need to include this
11
+ config.endpoint = 'test_endpoint'
12
+
13
+ # The organization or user that owns the target repository
14
+ config.owner = 'test_login'
15
+
16
+ # The repository for this application
17
+ config.repo = 'test_repo'
18
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: party_foul
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-22 00:00:00.000000000 Z
13
+ date: 2013-01-25 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: github_api
@@ -33,33 +33,49 @@ dependencies:
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  none: false
35
35
  requirements:
36
- - - ! '>='
36
+ - - ~>
37
37
  - !ruby/object:Gem::Version
38
- version: '0'
38
+ version: 3.2.11
39
39
  type: :development
40
40
  prerelease: false
41
41
  version_requirements: !ruby/object:Gem::Requirement
42
42
  none: false
43
43
  requirements:
44
- - - ! '>='
44
+ - - ~>
45
45
  - !ruby/object:Gem::Version
46
- version: '0'
46
+ version: 3.2.11
47
47
  - !ruby/object:Gem::Dependency
48
- name: sqlite3
48
+ name: activesupport
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
- - - ! '>='
52
+ - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 3.2.11
55
55
  type: :development
56
56
  prerelease: false
57
57
  version_requirements: !ruby/object:Gem::Requirement
58
58
  none: false
59
59
  requirements:
60
- - - ! '>='
60
+ - - ~>
61
61
  - !ruby/object:Gem::Version
62
- version: '0'
62
+ version: 3.2.11
63
+ - !ruby/object:Gem::Dependency
64
+ name: railties
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: 3.2.11
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: 3.2.11
63
79
  - !ruby/object:Gem::Dependency
64
80
  name: minitest
65
81
  requirement: !ruby/object:Gem::Requirement
@@ -109,7 +125,7 @@ dependencies:
109
125
  - !ruby/object:Gem::Version
110
126
  version: '0'
111
127
  - !ruby/object:Gem::Dependency
112
- name: bourne
128
+ name: mocha
113
129
  requirement: !ruby/object:Gem::Requirement
114
130
  none: false
115
131
  requirements:
@@ -149,16 +165,20 @@ extensions: []
149
165
  extra_rdoc_files: []
150
166
  files:
151
167
  - lib/generators/party_foul/install_generator.rb
168
+ - lib/generators/party_foul/templates/party_foul.rb
152
169
  - lib/party_foul/exception_handler.rb
153
170
  - lib/party_foul/middleware.rb
171
+ - lib/party_foul/sync_adapter.rb
154
172
  - lib/party_foul/version.rb
155
173
  - lib/party_foul.rb
156
174
  - Rakefile
157
175
  - README.md
176
+ - test/generator_test.rb
158
177
  - test/party_foul/configure_test.rb
159
178
  - test/party_foul/exception_handler_test.rb
160
179
  - test/party_foul/middleware_test.rb
161
180
  - test/test_helper.rb
181
+ - test/tmp/config/initializers/party_foul.rb
162
182
  homepage: https://github.com/dockyard/party_foul
163
183
  licenses: []
164
184
  post_install_message:
@@ -173,7 +193,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
173
193
  version: '0'
174
194
  segments:
175
195
  - 0
176
- hash: 4161555137727730749
196
+ hash: -1173897567857159302
177
197
  required_rubygems_version: !ruby/object:Gem::Requirement
178
198
  none: false
179
199
  requirements:
@@ -182,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
182
202
  version: '0'
183
203
  segments:
184
204
  - 0
185
- hash: 4161555137727730749
205
+ hash: -1173897567857159302
186
206
  requirements: []
187
207
  rubyforge_project:
188
208
  rubygems_version: 1.8.23
@@ -190,7 +210,9 @@ signing_key:
190
210
  specification_version: 3
191
211
  summary: Auto-submit Rails exceptions as new isues on Github
192
212
  test_files:
213
+ - test/generator_test.rb
193
214
  - test/party_foul/configure_test.rb
194
215
  - test/party_foul/exception_handler_test.rb
195
216
  - test/party_foul/middleware_test.rb
196
217
  - test/test_helper.rb
218
+ - test/tmp/config/initializers/party_foul.rb