party_foul 0.1.0 → 0.2.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
@@ -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