party_foul 0.0.0 → 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.
Files changed (42) hide show
  1. data/README.md +74 -4
  2. data/Rakefile +0 -19
  3. data/lib/generators/party_foul/install_generator.rb +74 -0
  4. data/lib/party_foul/exception_handler.rb +118 -0
  5. data/lib/party_foul/middleware.rb +32 -0
  6. data/lib/party_foul/version.rb +1 -1
  7. data/lib/party_foul.rb +22 -0
  8. data/test/party_foul/configure_test.rb +25 -0
  9. data/test/party_foul/exception_handler_test.rb +102 -0
  10. data/test/party_foul/middleware_test.rb +106 -0
  11. data/test/test_helper.rb +22 -11
  12. metadata +112 -66
  13. data/lib/tasks/party_foul_tasks.rake +0 -4
  14. data/test/dummy/README.rdoc +0 -261
  15. data/test/dummy/Rakefile +0 -7
  16. data/test/dummy/app/assets/javascripts/application.js +0 -15
  17. data/test/dummy/app/assets/stylesheets/application.css +0 -13
  18. data/test/dummy/app/controllers/application_controller.rb +0 -3
  19. data/test/dummy/app/helpers/application_helper.rb +0 -2
  20. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  21. data/test/dummy/config/application.rb +0 -59
  22. data/test/dummy/config/boot.rb +0 -10
  23. data/test/dummy/config/database.yml +0 -25
  24. data/test/dummy/config/environment.rb +0 -5
  25. data/test/dummy/config/environments/development.rb +0 -37
  26. data/test/dummy/config/environments/production.rb +0 -67
  27. data/test/dummy/config/environments/test.rb +0 -37
  28. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  29. data/test/dummy/config/initializers/inflections.rb +0 -15
  30. data/test/dummy/config/initializers/mime_types.rb +0 -5
  31. data/test/dummy/config/initializers/secret_token.rb +0 -7
  32. data/test/dummy/config/initializers/session_store.rb +0 -8
  33. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  34. data/test/dummy/config/locales/en.yml +0 -5
  35. data/test/dummy/config/routes.rb +0 -58
  36. data/test/dummy/config.ru +0 -4
  37. data/test/dummy/public/404.html +0 -26
  38. data/test/dummy/public/422.html +0 -26
  39. data/test/dummy/public/500.html +0 -25
  40. data/test/dummy/public/favicon.ico +0 -0
  41. data/test/dummy/script/rails +0 -6
  42. data/test/party_foul_test.rb +0 -7
data/README.md CHANGED
@@ -6,25 +6,96 @@
6
6
 
7
7
  Rails exceptions automatically opened as issues on Github
8
8
 
9
+ ## About ##
10
+
11
+ `PartyFoul` will capture exceptions in your application and will do the
12
+ following:
13
+
14
+ 1. Will attempt to find a matching issue in your Github repo
15
+ 2. If no matching issue is found an new issue will be created with a
16
+ unique title, session information, and stack trace. The issue will be
17
+ tagged as a `bug`
18
+ 3. If an open issue is found the occurance count and time stamp will be
19
+ updated
20
+ 4. If a closed issue is found the occurance count and time stamp will be
21
+ updated. The issue will be reopened and a `regression` tag will be
22
+ added.
23
+ 5. If the issue is marked as `wontfix` the issue is not updated nor is
24
+ a new issue created.
25
+
9
26
  ## Installation ##
10
27
 
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
+ **Note** We highly recommend that you create a new Github account that is
34
+ a collaborator on your repository. Use this new account's credentials
35
+ for the installation below. If you use your own account you will
36
+ not receive emails when issues are created, updated, reopened, etc...
37
+ because all of the work will be done as your account.
38
+
11
39
  In your Gemfile add the following:
12
40
 
13
41
  ```ruby
14
42
  gem 'party_foul'
15
43
  ```
16
44
 
45
+ ### Rails ###
46
+ If you are using Rails you can run the install generator.
17
47
 
18
- ## Usage ##
48
+ ```
49
+ rails g party_foul:install
50
+ ```
51
+
52
+ This will prompt you for the Github credentials of the account that will
53
+ be opening the issues. The OAuth token for that account will be stored
54
+ in `config/initializers/party_foul.rb`. You may want to remove the token
55
+ string and store in an environment variable. It is best not to store the
56
+ token in version control.
57
+
58
+ Add as the very last middleware in your production `Rack` stack in `config/environments/production.rb`
59
+
60
+ ```ruby
61
+ config.middleware.insert_before(-1, 'PartyFoul::Middleware')
62
+ ```
63
+ ### Other ###
19
64
 
65
+ You will need to initialize `PartyFoul`, you can use the following to do
66
+ so:
20
67
 
21
- ## What you get ##
68
+ ```ruby
69
+ PartyFoul.configure do |config|
70
+ # the collection of exceptions to be ignored by PartyFoul
71
+ # The constants here *must* be represented as strings
72
+ config.ignored_exceptions = ['ActiveRecord::RecordNotFound']
73
+
74
+ # The OAuth token for the account that will be opening the issues on Github
75
+ config.oauth_token = 'abcdefgh1234567890'
76
+
77
+ # The API endpoint for Github. Unless you are hosting a private
78
+ # instance of Enterprise Github you do not need to include this
79
+ config.endpoint = 'https://api.github.com'
80
+
81
+ # The organization or user that owns the target repository
82
+ config.owner = 'owner_name'
83
+
84
+ # The repository for this application
85
+ config.repo = 'repo_name'
86
+ end
87
+ ```
88
+
89
+ Add as the very last middleware in your production `Rack` stack.
90
+
91
+ ## Usage ##
22
92
 
23
93
 
24
94
  ## Authors ##
25
95
 
26
96
  [Brian Cardarella](http://twitter.com/bcardarella)
27
- [Dan McClain](http://twitter.com/danmcclain)
97
+
98
+ [Dan McClain](http://twitter.com/_danmcclain)
28
99
 
29
100
  [We are very thankful for the many contributors](https://github.com/dockyard/party_foul/graphs/contributors)
30
101
 
@@ -45,4 +116,3 @@ on how to properly submit issues and pull requests.
45
116
  [@dockyard](http://twitter.com/dockyard)
46
117
 
47
118
  [Licensed under the MIT license](http://www.opensource.org/licenses/mit-license.php)
48
-
data/Rakefile CHANGED
@@ -4,24 +4,6 @@ begin
4
4
  rescue LoadError
5
5
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
6
  end
7
- begin
8
- require 'rdoc/task'
9
- rescue LoadError
10
- require 'rdoc/rdoc'
11
- require 'rake/rdoctask'
12
- RDoc::Task = Rake::RDocTask
13
- end
14
-
15
- RDoc::Task.new(:rdoc) do |rdoc|
16
- rdoc.rdoc_dir = 'rdoc'
17
- rdoc.title = 'PartyFoul'
18
- rdoc.options << '--line-numbers'
19
- rdoc.rdoc_files.include('README.rdoc')
20
- rdoc.rdoc_files.include('lib/**/*.rb')
21
- end
22
-
23
-
24
-
25
7
 
26
8
  Bundler::GemHelper.install_tasks
27
9
 
@@ -34,5 +16,4 @@ Rake::TestTask.new(:test) do |t|
34
16
  t.verbose = false
35
17
  end
36
18
 
37
-
38
19
  task :default => :test
@@ -0,0 +1,74 @@
1
+ require 'rails/generators'
2
+ require 'io/console'
3
+ require 'net/http'
4
+
5
+ module PartyFoul
6
+ class InstallGenerator < Rails::Generators::Base
7
+
8
+ 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
15
+ ask 'Github password:'
16
+ 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
+
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}'
46
+
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'
50
+
51
+ # The organization or user that owns the target repository
52
+ config.owner = '#{owner}'
53
+
54
+ # The repository for this application
55
+ config.repo = '#{repo}'
56
+ end
57
+ CONTENTS
58
+ end
59
+ else
60
+ say 'There was an error retrieving your Github OAuth token'
61
+ end
62
+
63
+ say 'Done'
64
+ end
65
+
66
+ private
67
+
68
+ def self.installation_message
69
+ 'Generates the configuration file'
70
+ end
71
+
72
+ desc installation_message
73
+ end
74
+ end
@@ -0,0 +1,118 @@
1
+ class PartyFoul::ExceptionHandler
2
+ attr_accessor :exception, :env
3
+
4
+ def self.handle(exception, env)
5
+ handler = self.new(exception, env)
6
+ handler.run
7
+ end
8
+
9
+ def initialize(exception, env)
10
+ self.exception = exception
11
+ self.env = env
12
+ end
13
+
14
+ def run
15
+ if issue = find_issue
16
+ update_issue(issue)
17
+ else
18
+ create_issue
19
+ end
20
+ end
21
+
22
+ def find_issue
23
+ unless issue = PartyFoul.github.search.issues(owner: PartyFoul.owner, repo: PartyFoul.repo, state: 'open', keyword: fingerprint).issues.first
24
+ issue = PartyFoul.github.search.issues(owner: PartyFoul.owner, repo: PartyFoul.repo, state: 'closed', keyword: fingerprint).issues.first
25
+ end
26
+
27
+ issue
28
+ end
29
+
30
+ def stack_trace
31
+ exception.backtrace.map do |line|
32
+ if matches = extract_file_name_and_line_number(line)
33
+ "<a href='../tree/master/#{matches[2]}#L#{matches[3]}'>#{line}</a>"
34
+ else
35
+ line
36
+ end
37
+ end.join("\n")
38
+ end
39
+
40
+ def create_issue
41
+ PartyFoul.github.issues.create(PartyFoul.owner, PartyFoul.repo, title: issue_title, body: issue_body, labels: ['bug'])
42
+ end
43
+
44
+ def update_issue(issue)
45
+ unless issue.key?('labels') && issue['labels'].include?('wontfix')
46
+ params = {body: update_body(issue['body']), state: 'open'}
47
+
48
+ if issue['state'] == 'closed'
49
+ params[:labels] = ['bug', 'regression']
50
+ end
51
+
52
+ PartyFoul.github.issues.edit(PartyFoul.owner, PartyFoul.repo, issue['number'], params)
53
+ end
54
+ end
55
+
56
+ def issue_title
57
+ line = exception.backtrace.select {|p| p =~ /#{app_root}/ }.first
58
+ name_and_number = extract_file_name_and_line_number(line)[1]
59
+ "#{exception} - #{name_and_number}"
60
+ end
61
+
62
+ def fingerprint
63
+ Digest::SHA1.hexdigest(issue_title)
64
+ end
65
+
66
+ def update_body(body)
67
+ begin
68
+ current_count = body.match(/<th>Count<\/th><td>(\d+)<\/td>/)[1].to_i
69
+ 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
72
+ rescue
73
+ issue_body
74
+ end
75
+ end
76
+
77
+ def params
78
+ if env["action_dispatch.parameter_filter"]
79
+ parameter_filter = ActionDispatch::Http::ParameterFilter.new(env["action_dispatch.parameter_filter"])
80
+ parameter_filter.filter(env['action_dispatch.request.path_parameters'])
81
+ else
82
+ env['QUERY_STRING']
83
+ end
84
+ end
85
+
86
+ 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
99
+ end
100
+
101
+ private
102
+
103
+ def app_root
104
+ if defined?(Rails)
105
+ Rails.root
106
+ else
107
+ Dir.pwd
108
+ end
109
+ end
110
+
111
+ def file_and_line_regex
112
+ /#{app_root}\/((.+?):(\d+))/
113
+ end
114
+
115
+ def extract_file_name_and_line_number(backtrace_line)
116
+ backtrace_line.match(file_and_line_regex)
117
+ end
118
+ end
@@ -0,0 +1,32 @@
1
+ module PartyFoul
2
+ class Middleware
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ @app.call(env)
9
+ rescue Exception => captured_exception
10
+ if allow_handling?(captured_exception)
11
+ PartyFoul::ExceptionHandler.handle(captured_exception, env)
12
+ end
13
+ raise captured_exception
14
+ end
15
+
16
+ private
17
+
18
+ def allow_handling?(captured_exception)
19
+ !PartyFoul.ignored_exceptions.find do |ignored_exception|
20
+ names = ignored_exception.split('::')
21
+ names.shift if names.empty? || names.first.empty?
22
+
23
+ constant = Object
24
+ names.each do |name|
25
+ constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
26
+ end
27
+
28
+ constant === captured_exception
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,3 @@
1
1
  module PartyFoul
2
- VERSION = "0.0.0"
2
+ VERSION = '0.1.0'
3
3
  end
data/lib/party_foul.rb CHANGED
@@ -1,2 +1,24 @@
1
+ require 'github_api'
2
+
1
3
  module PartyFoul
4
+ class << self
5
+ attr_accessor :github, :oauth_token, :endpoint, :owner, :repo, :ignored_exceptions
6
+ end
7
+
8
+ def self.ignored_exceptions
9
+ @ignored_exceptions || []
10
+ end
11
+
12
+ def self.configure(&block)
13
+ yield self
14
+ _self = self
15
+ self.github ||= Github.new do |config|
16
+ %w{endpoint oauth_token}.each do |option|
17
+ config.send("#{option}=", _self.send(option)) if !_self.send(option).nil?
18
+ end
19
+ end
20
+ end
2
21
  end
22
+
23
+ require 'party_foul/exception_handler'
24
+ require 'party_foul/middleware'
@@ -0,0 +1,25 @@
1
+ require 'test_helper'
2
+
3
+ describe 'Party Foul Confg' do
4
+
5
+ after do
6
+ clean_up_party
7
+ end
8
+
9
+ it 'sets the proper config variables' do
10
+ PartyFoul.configure do |config|
11
+ config.ignored_exceptions = ['StandardError']
12
+ config.oauth_token = 'test_token'
13
+ config.endpoint = 'test_endpoint'
14
+ config.owner = 'test_owner'
15
+ config.repo = 'test_repo'
16
+ end
17
+
18
+ PartyFoul.ignored_exceptions.must_equal ['StandardError']
19
+ PartyFoul.github.must_be_instance_of Github::Client
20
+ PartyFoul.github.oauth_token.must_equal 'test_token'
21
+ PartyFoul.github.endpoint.must_equal 'test_endpoint'
22
+ PartyFoul.owner.must_equal 'test_owner'
23
+ PartyFoul.repo.must_equal 'test_repo'
24
+ end
25
+ end
@@ -0,0 +1,102 @@
1
+ require 'test_helper'
2
+ require 'active_support/core_ext/object/blank'
3
+ require 'action_dispatch/http/parameter_filter'
4
+
5
+ describe 'Party Foul Exception Handler' do
6
+ before do
7
+ Time.stubs(:now).returns(Time.at(0))
8
+ end
9
+
10
+ describe '#body' do
11
+ describe 'updating issue body' do
12
+ before do
13
+ @handler = PartyFoul::ExceptionHandler.new(nil, nil)
14
+ @handler.stubs(:fingerprint).returns('abcdefg1234567890')
15
+ @handler.stubs(:stack_trace)
16
+ @handler.stubs(:params)
17
+ @handler.stubs(:exception)
18
+ end
19
+
20
+ it 'updates count and timestamp' do
21
+ body = <<-BODY
22
+ <table>
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>
27
+ </table>
28
+
29
+ ## Stack Trace
30
+ <pre></pre>
31
+ Fingerprint: `abcdefg1234567890`
32
+ BODY
33
+
34
+ Time.stubs(:now).returns(Time.new(1985, 10, 25, 1, 22, 0, '-05:00'))
35
+
36
+ expected_body = <<-BODY
37
+ <table>
38
+ <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>
42
+ </table>
43
+
44
+ ## Stack Trace
45
+ <pre></pre>
46
+ Fingerprint: `abcdefg1234567890`
47
+ BODY
48
+
49
+ @handler.update_body(body).must_equal expected_body
50
+ end
51
+ end
52
+
53
+ describe 'empty body' do
54
+ before do
55
+ @handler = PartyFoul::ExceptionHandler.new(nil, nil)
56
+ @handler.stubs(:fingerprint).returns('abcdefg1234567890')
57
+ @handler.stubs(:stack_trace)
58
+ @handler.stubs(:params)
59
+ @handler.stubs(:exception)
60
+ end
61
+
62
+ it 'resets body' do
63
+ expected_body = <<-BODY
64
+ <table>
65
+ <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>
69
+ </table>
70
+
71
+ ## Stack Trace
72
+ <pre></pre>
73
+ Fingerprint: `abcdefg1234567890`
74
+ BODY
75
+ @handler.update_body(nil).must_equal expected_body
76
+ end
77
+ end
78
+ end
79
+
80
+ describe '#params' do
81
+ context 'with Rails' do
82
+ before do
83
+ @handler = PartyFoul::ExceptionHandler.new(nil, {'action_dispatch.parameter_filter' => ['password'], 'action_dispatch.request.path_parameters' => { 'status' => 'ok', 'password' => 'test' }, 'QUERY_STRING' => { 'status' => 'fail' } })
84
+ end
85
+
86
+ it 'returns ok' do
87
+ @handler.params['status'].must_equal 'ok'
88
+ @handler.params['password'].must_equal '[FILTERED]'
89
+ end
90
+ end
91
+
92
+ context 'without Rails' do
93
+ before do
94
+ @handler = PartyFoul::ExceptionHandler.new(nil, {'QUERY_STRING' => { 'status' => 'ok' } })
95
+ end
96
+
97
+ it 'returns ok' do
98
+ @handler.params['status'].must_equal 'ok'
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,106 @@
1
+ require 'test_helper'
2
+
3
+ describe 'Party Foul Middleware' do
4
+ include Rack::Test::Methods
5
+
6
+ after do
7
+ clean_up_party
8
+ end
9
+
10
+ def error_to_raise
11
+ Exception
12
+ end
13
+
14
+ def app
15
+ _self = self
16
+ Rack::Builder.new {
17
+ map '/' do
18
+ use PartyFoul::Middleware
19
+ run lambda { |env| raise _self.error_to_raise }
20
+ end
21
+ }
22
+ end
23
+
24
+ before do
25
+ PartyFoul.configure do |config|
26
+ config.oauth_token = 'abcdefg1234567890'
27
+ config.owner = 'test_owner'
28
+ config.repo = 'test_repo'
29
+ end
30
+ PartyFoul.github.stubs(:issues).returns(mock('Issues'))
31
+ PartyFoul.github.stubs(:search).returns(mock('Search'))
32
+ PartyFoul.github.issues.stubs(:create)
33
+ PartyFoul.github.issues.stubs(:edit)
34
+ PartyFoul::ExceptionHandler.any_instance.stubs(:issue_title).returns('Test Title')
35
+ PartyFoul::ExceptionHandler.any_instance.stubs(:fingerprint).returns('test_fingerprint')
36
+ end
37
+
38
+ context 'when error is new' do
39
+ it 'will open a new error on Github' do
40
+ PartyFoul::ExceptionHandler.any_instance.stubs(:issue_body).returns('Test Body')
41
+ PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
42
+ 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'])
44
+ lambda {
45
+ get '/'
46
+ }.must_raise(Exception)
47
+ end
48
+ end
49
+
50
+ context 'when error is not new' do
51
+ before do
52
+ PartyFoul::ExceptionHandler.any_instance.stubs(:update_body).returns('New Body')
53
+ end
54
+
55
+ context 'and open' do
56
+ it 'will update the issue' do
57
+ 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
+ PartyFoul.github.issues.expects(:edit).with('test_owner', 'test_repo', 1, body: 'New Body', state: 'open')
59
+ lambda {
60
+ get '/'
61
+ }.must_raise(Exception)
62
+ end
63
+ end
64
+
65
+ context 'and closed' do
66
+ it 'will update the count on the body and re-open the issue' do
67
+ PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
68
+ 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
+ PartyFoul.github.issues.expects(:edit).with('test_owner', 'test_repo', 1, body: 'New Body', state: 'open', labels: ['bug', 'regression'])
70
+ lambda {
71
+ get '/'
72
+ }.must_raise(Exception)
73
+ end
74
+ end
75
+ end
76
+
77
+ context 'when issue is marked as "wontfix"' do
78
+ it 'does nothing' do
79
+ PartyFoul::ExceptionHandler.any_instance.stubs(:issue_body).returns('Test Body')
80
+ PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
81
+ 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
+ PartyFoul.github.issues.expects(:create).never
83
+ PartyFoul.github.issues.expects(:edit).never
84
+ lambda {
85
+ get '/'
86
+ }.must_raise(Exception)
87
+ end
88
+ end
89
+
90
+ context 'filtering based upon exception' do
91
+ before do
92
+ PartyFoul.ignored_exceptions = ['StandardError']
93
+ self.stubs(:error_to_raise).returns(StandardError)
94
+ end
95
+
96
+ it 'does not handle exception' do
97
+ PartyFoul::ExceptionHandler.any_instance.stubs(:issue_body).returns('Test Body')
98
+ PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
99
+ PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'closed').returns(Hashie::Mash.new(issues: []))
100
+ PartyFoul.github.issues.expects(:create).never
101
+ lambda {
102
+ get '/'
103
+ }.must_raise(StandardError)
104
+ end
105
+ end
106
+ end
data/test/test_helper.rb CHANGED
@@ -1,15 +1,26 @@
1
- # Configure Rails Environment
2
- ENV["RAILS_ENV"] = "test"
3
-
4
- require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
- require "rails/test_help"
1
+ if defined?(M)
2
+ require 'minitest/spec'
3
+ else
4
+ require 'minitest/autorun'
5
+ end
6
+ require 'rack/test'
7
+ require 'mocha/setup'
8
+ require 'bourne'
9
+ require 'debugger'
10
+ require 'party_foul'
6
11
 
7
- Rails.backtrace_cleaner.remove_silencers!
12
+ class MiniTest::Spec
13
+ class << self
14
+ alias :context :describe
15
+ end
16
+ end
8
17
 
9
- # Load support files
10
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
18
+ module MiniTest::Expectations
19
+ infect_an_assertion :assert_received, :must_have_received
20
+ end
11
21
 
12
- # Load fixtures from the engine
13
- if ActiveSupport::TestCase.method_defined?(:fixture_path=)
14
- ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
22
+ def clean_up_party
23
+ %w{github oauth_token endpoint owner repo ignored_exceptions}.each do |attr|
24
+ PartyFoul.send("#{attr}=", nil)
25
+ end
15
26
  end