party_foul 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -8,23 +8,23 @@ Rails exceptions automatically opened as issues on Github
8
8
 
9
9
  ## About ##
10
10
 
11
- `PartyFoul` will capture exceptions in your application and will do the
11
+ `PartyFoul` captures exceptions in your application and does the
12
12
  following:
13
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`. A new comment will be added with relevant data on the
14
+ 1. Attempt to find a matching issue in your Github repo
15
+ 2. If no matching issue is found an new issue is created with a
16
+ unique title, session information, and stack trace. The issue is
17
+ tagged as a `bug`. A new comment is added with relevant data on the
18
18
  application state.
19
- 3. If an open issue is found the occurance count and time stamp will be
20
- updated. A new comment will be added with relevant data on the
19
+ 3. If an open issue is found the occurance count and time stamp is
20
+ updated. A new comment is added with relevant data on the
21
21
  application state.
22
- 4. If a closed issue is found the occurance count and time stamp will be
23
- updated. The issue will be reopened and a `regression` tag will be
24
- added. A new comment will be added with relevant data on the
22
+ 4. If a closed issue is found the occurance count and time stamp is
23
+ updated. The issue is reopened and a `regression` tag is
24
+ added. A new comment is added with relevant data on the
25
25
  application state.
26
26
  5. If the issue is marked as `wontfix` the issue is not updated nor is
27
- a new issue created. No comments will be added.
27
+ a new issue created. No comments are added.
28
28
 
29
29
  ## Installation ##
30
30
 
@@ -32,7 +32,7 @@ application state.
32
32
  a collaborator on your repository. Use this new account's credentials
33
33
  for the installation below. If you use your own account you will
34
34
  not receive emails when issues are created, updated, reopened, etc...
35
- because all of the work will be done as your account.
35
+ because all of the work is done as your account.
36
36
 
37
37
  In your Gemfile add the following:
38
38
 
@@ -47,8 +47,8 @@ If you are using Rails you can run the install generator.
47
47
  rails g party_foul:install
48
48
  ```
49
49
 
50
- This will prompt you for the Github credentials of the account that will
51
- be opening the issues. The OAuth token for that account will be stored
50
+ This prompts you for the Github credentials of the account that is
51
+ opening the issues. The OAuth token for that account is stored
52
52
  in `config/initializers/party_foul.rb`. You may want to remove the token
53
53
  string and store in an environment variable. It is best not to store the
54
54
  token in version control.
@@ -60,30 +60,33 @@ config.middleware.use('PartyFoul::Middleware')
60
60
  ```
61
61
  ### Other ###
62
62
 
63
- You will need to initialize `PartyFoul`, you can use the following to do
64
- so:
63
+ You need to initialize `PartyFoul`, use the following:
65
64
 
66
65
  ```ruby
67
66
  PartyFoul.configure do |config|
68
67
  # the collection of exceptions to be ignored by PartyFoul
69
68
  # The constants here *must* be represented as strings
70
- config.ignored_exceptions = ['ActiveRecord::RecordNotFound', 'ActionController::RoutingError']
69
+ config.ignored_exceptions = ['ActiveRecord::RecordNotFound', 'ActionController::RoutingError']
71
70
 
72
71
  # The names of the HTTP headers to not report
73
72
  config.filtered_http_headers = ['Cookie']
74
73
 
75
- # The OAuth token for the account that will be opening the issues on Github
76
- config.oauth_token = 'abcdefgh1234567890'
74
+ # The OAuth token for the account that is opening the issues on Github
75
+ config.oauth_token = 'abcdefgh1234567890'
77
76
 
78
77
  # The API endpoint for Github. Unless you are hosting a private
79
78
  # instance of Enterprise Github you do not need to include this
80
- config.endpoint = 'https://api.github.com'
79
+ config.endpoint = 'https://api.github.com'
80
+
81
+ # The Web URL for Github. Unless you are hosting a private
82
+ # instance of Enterprise Github you do not need to include this
83
+ config.web_url = 'https://github.com'
81
84
 
82
85
  # The organization or user that owns the target repository
83
- config.owner = 'owner_name'
86
+ config.owner = 'owner_name'
84
87
 
85
88
  # The repository for this application
86
- config.repo = 'repo_name'
89
+ config.repo = 'repo_name'
87
90
  end
88
91
  ```
89
92
 
@@ -100,20 +103,20 @@ Add as the very last middleware in your production `Rack` stack.
100
103
 
101
104
  ## Customization ##
102
105
 
103
- ### Async Adapters ###
106
+ ### Background Processing ###
104
107
 
105
108
  You can specify the adapter with which the exceptions should be
106
109
  handled. By default, PartyFoul includes the
107
110
  [`PartyFoul::SyncAdapter`](https://github.com/dockyard/party_foul/tree/master/lib/party_foul/sync_adapter.rb)
108
- which will handle the exception synchronously. To use your own adapter,
111
+ which handles the exception synchronously. To use your own adapter,
109
112
  include the following in your `PartyFoul.configure` block:
110
113
 
111
114
  ```ruby
112
115
  PartyFoul.configure do |config|
113
- config.adapter = MyAsyncAdatper
116
+ config.adapter = PartyFoul::Processors::MyBackgroundProcessor
114
117
  end
115
118
 
116
- class MyAsyncAdapter
119
+ class PartyFoul::Processors::MyBackgroundProcessor
117
120
  def self.handle(exception, env)
118
121
  # Enqueue the exception, then in your worker, call
119
122
  # PartyFoul::ExceptionHandler.new(exception, env).run
@@ -122,7 +125,7 @@ end
122
125
 
123
126
  ```
124
127
 
125
- ## Changing How Issues Are Reported ##
128
+ ### Changing How Issues Are Reported ###
126
129
 
127
130
  `PartyFoul` comes with default templates for what the body of issues and
128
131
  comments are. If you want to override these templates you simply need to
@@ -130,20 +133,17 @@ add them as an option in your initializer:
130
133
 
131
134
  ```ruby
132
135
  PartyFoul.configure do |config|
133
- config.issue_body = <<-TEMPLATE
134
- :issue_title
135
- TEMPLATE
136
-
137
- config.comment_body = <<-TEMPLATE
138
- :occurred_at
139
- TEMPLATE
136
+ config.issue_body = ':issue_title'
137
+ config.comment_body = ':occurred_at'
138
+ end
140
139
  ```
141
140
 
142
141
  In this over-simplistic example the words that start with `:` in the
143
- templates will be evaluated with the value of the corresponding named
144
- instance method on the instance of `PartyFoul::ExceptionHandler`. If you
142
+ templates are evaluated with the value of the corresponding named
143
+ instance method on the instance of `PartyFoul::IssueRenderer`. If you
145
144
  want to add additional values for replacement you should open that class
146
- to add the methods.
145
+ to add the methods. Depending upon the data point you may want o make
146
+ the change in one of the [different issue renderer adapters](https://github.com/dockyard/party_foul/tree/master/lib/party_foul/issue_renderers).
147
147
 
148
148
  ## Authors ##
149
149
 
@@ -11,11 +11,12 @@ module PartyFoul
11
11
  password = STDIN.noecho { ask 'Github password:' }
12
12
  @owner = ask_with_default "\nRepository owner:", login
13
13
  @repo = ask 'Repository name:'
14
- @endpoint = ask_with_default 'Endpoint:', 'https://api.github.com'
14
+ @endpoint = ask_with_default 'Api Endpoint:', 'https://api.github.com'
15
+ @web_url = ask_with_default 'Web URL:', 'https://github.com'
15
16
 
16
17
  begin
17
18
  github = Github.new :login => login, :password => password, :endpoint => @endpoint
18
- @oauth_token = github.oauth.create('scopes' => ['repo']).token
19
+ @oauth_token = github.oauth.create(scopes: ['repo'], note: "PartyFoul #{@owner}/#{@repo}", note_url: "#{@web_url}/#{@owner}/#{@repo}").token
19
20
  template 'party_foul.rb', 'config/initializers/party_foul.rb'
20
21
  rescue Github::Error::Unauthorized
21
22
  say 'There was an error retrieving your Github OAuth token'
@@ -6,13 +6,17 @@ PartyFoul.configure do |config|
6
6
  # The names of the HTTP headers to not report
7
7
  config.filtered_http_headers = ['Cookie']
8
8
 
9
- # The OAuth token for the account that will be opening the issues on Github
9
+ # The OAuth token for the account that is opening the issues on Github
10
10
  config.oauth_token = '<%= @oauth_token %>'
11
11
 
12
12
  # The API endpoint for Github. Unless you are hosting a private
13
13
  # instance of Enterprise Github you do not need to include this
14
14
  config.endpoint = '<%= @endpoint %>'
15
15
 
16
+ # The Web URL for Github. Unless you are hosting a private
17
+ # instance of Enterprise Github you do not need to include this
18
+ config.web_url = '<%= @web_url %>'
19
+
16
20
  # The organization or user that owns the target repository
17
21
  config.owner = '<%= @owner %>'
18
22
 
@@ -1,13 +1,18 @@
1
1
  class PartyFoul::ExceptionHandler
2
- attr_accessor :exception, :env
2
+ attr_accessor :rendered_issue
3
3
 
4
4
  def self.handle(exception, env)
5
- PartyFoul.adapter.handle(exception, env)
5
+ PartyFoul.processor.handle(exception, env)
6
6
  end
7
7
 
8
8
  def initialize(exception, env)
9
- self.exception = exception
10
- self.env = env
9
+ renderer_klass = if defined?(Rails)
10
+ PartyFoul::RailsIssueRenderer
11
+ else
12
+ PartyFoul::RackIssueRenderer
13
+ end
14
+
15
+ self.rendered_issue = renderer_klass.new(exception, env)
11
16
  end
12
17
 
13
18
  def run
@@ -26,121 +31,27 @@ class PartyFoul::ExceptionHandler
26
31
  issue
27
32
  end
28
33
 
29
- def stack_trace
30
- exception.backtrace.map do |line|
31
- if matches = extract_file_name_and_line_number(line)
32
- "<a href='../tree/master/#{matches[2]}#L#{matches[3]}'>#{line}</a>"
33
- else
34
- line
35
- end
36
- end.join("\n")
37
- end
38
-
39
34
  def create_issue
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)
35
+ issue = PartyFoul.github.issues.create(PartyFoul.owner, PartyFoul.repo, title: rendered_issue.title, body: rendered_issue.body, labels: ['bug'])
36
+ PartyFoul.github.issues.comments.create(PartyFoul.owner, PartyFoul.repo, issue['number'], body: rendered_issue.comment)
42
37
  end
43
38
 
44
39
  def update_issue(issue)
45
40
  unless issue.key?('labels') && issue['labels'].include?('wontfix')
46
- params = {body: update_body(issue['body']), state: 'open'}
41
+ params = {body: rendered_issue.update_body(issue['body']), state: 'open'}
47
42
 
48
43
  if issue['state'] == 'closed'
49
44
  params[:labels] = ['bug', 'regression']
50
45
  end
51
46
 
52
47
  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)
54
- end
55
- end
56
-
57
- def issue_title
58
- line = exception.backtrace.select {|p| p =~ /#{app_root}/ }.first
59
- name_and_number = extract_file_name_and_line_number(line)[1]
60
- "#{exception} - #{name_and_number}"
61
- end
62
-
63
- def fingerprint
64
- Digest::SHA1.hexdigest(issue_title)
65
- end
66
-
67
- def update_body(body)
68
- begin
69
- current_count = body.match(/<th>Count<\/th><td>(\d+)<\/td>/)[1].to_i
70
- body.sub!("<th>Count</th><td>#{current_count}</td>", "<th>Count</th><td>#{current_count + 1}</td>")
71
- body.sub!(/<th>Last Occurance<\/th><td>.+<\/td>/, "<th>Last Occurance</th><td>#{occurred_at}</td>")
72
- body
73
- rescue
74
- issue_body
75
- end
76
- end
77
-
78
- def params
79
- if env["action_dispatch.parameter_filter"]
80
- parameter_filter = ActionDispatch::Http::ParameterFilter.new(env["action_dispatch.parameter_filter"])
81
- parameter_filter.filter(env['action_dispatch.request.path_parameters'])
82
- else
83
- env['QUERY_STRING']
84
- end
85
- end
86
-
87
- def issue_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
- value = self.send(method.split(':').last)
98
- if value.kind_of?(Hash)
99
- hash_as_table(value)
100
- else
101
- value
102
- end
103
- end
104
- end
105
-
106
- def hash_as_table(value)
107
- "<table>#{value.map {|key, value| "<tr><th>#{key}</th><td>#{value}</td></tr>"}.join}</table>"
108
- end
109
-
110
- def occurred_at
111
- Time.now.strftime('%B %d, %Y %H:%M:%S %z')
112
- end
113
-
114
- def ip_address
115
- env['REMOTE_ADDR']
116
- end
117
-
118
- def session
119
- env['rack.session']
120
- end
121
-
122
- def http_headers
123
- env.keys.select { |key| key =~ /^HTTP_(\w+)/ && !(PartyFoul.filtered_http_headers || []).include?($1.split('_').map(&:capitalize).join('-')) }.sort.inject({}) do |hash, key|
124
- hash[key.split('HTTP_').last.split('_').map(&:capitalize).join('-')] = env[key]
125
- hash
48
+ PartyFoul.github.issues.comments.create(PartyFoul.owner, PartyFoul.repo, issue['number'], body: rendered_issue.comment)
126
49
  end
127
50
  end
128
51
 
129
52
  private
130
53
 
131
- def app_root
132
- if defined?(Rails)
133
- Rails.root
134
- else
135
- Dir.pwd
136
- end
137
- end
138
-
139
- def file_and_line_regex
140
- /#{app_root}\/((.+?):(\d+))/
141
- end
142
-
143
- def extract_file_name_and_line_number(backtrace_line)
144
- backtrace_line.match(file_and_line_regex)
54
+ def fingerprint
55
+ rendered_issue.fingerprint
145
56
  end
146
57
  end
@@ -0,0 +1,96 @@
1
+ class PartyFoul::IssueRenderer
2
+ attr_accessor :exception, :env
3
+
4
+ def initialize(exception, env)
5
+ self.exception = exception
6
+ self.env = env
7
+ end
8
+
9
+ def title
10
+ raise NotImplementedError
11
+ end
12
+
13
+ def body
14
+ compile_template(PartyFoul.issue_template)
15
+ end
16
+
17
+ def comment
18
+ compile_template(PartyFoul.comment_template)
19
+ end
20
+
21
+ def stack_trace
22
+ exception.backtrace.map do |line|
23
+ if matches = extract_file_name_and_line_number(line)
24
+ "<a href='#{PartyFoul.repo_url}/tree/master/#{matches[2]}#L#{matches[3]}'>#{line}</a>"
25
+ else
26
+ line
27
+ end
28
+ end.join("\n")
29
+ end
30
+
31
+ def fingerprint
32
+ Digest::SHA1.hexdigest(title)
33
+ end
34
+
35
+ def update_body(old_body)
36
+ begin
37
+ current_count = old_body.match(/<th>Count<\/th><td>(\d+)<\/td>/)[1].to_i
38
+ old_body.sub!("<th>Count</th><td>#{current_count}</td>", "<th>Count</th><td>#{current_count + 1}</td>")
39
+ old_body.sub!(/<th>Last Occurance<\/th><td>.+<\/td>/, "<th>Last Occurance</th><td>#{occurred_at}</td>")
40
+ old_body
41
+ rescue
42
+ self.body
43
+ end
44
+ end
45
+
46
+ def params
47
+ raise NotImplementedError
48
+ end
49
+
50
+ def occurred_at
51
+ Time.now.strftime('%B %d, %Y %H:%M:%S %z')
52
+ end
53
+
54
+ def ip_address
55
+ env['REMOTE_ADDR']
56
+ end
57
+
58
+ def session
59
+ env['rack.session']
60
+ end
61
+
62
+ def http_headers
63
+ env.keys.select { |key| key =~ /^HTTP_(\w+)/ && !(PartyFoul.filtered_http_headers || []).include?($1.split('_').map(&:capitalize).join('-')) }.sort.inject({}) do |hash, key|
64
+ hash[key.split('HTTP_').last.split('_').map(&:capitalize).join('-')] = env[key]
65
+ hash
66
+ end
67
+ end
68
+
69
+ def compile_template(template)
70
+ template.gsub(/:\w+/) do |method|
71
+ value = self.send(method.split(':').last)
72
+ if value.kind_of?(Hash)
73
+ hash_as_table(value)
74
+ else
75
+ value
76
+ end
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ def hash_as_table(value)
83
+ "<table>#{value.map {|key, value| "<tr><th>#{key}</th><td>#{value}</td></tr>"}.join}</table>"
84
+ end
85
+
86
+ def app_root
87
+ Dir.pwd
88
+ end
89
+
90
+ def extract_file_name_and_line_number(backtrace_line)
91
+ backtrace_line.match(/#{app_root}\/((.+?):(\d+))/)
92
+ end
93
+ end
94
+
95
+ require 'party_foul/issue_renderers/rack'
96
+ require 'party_foul/issue_renderers/rails'
@@ -0,0 +1,13 @@
1
+ require 'party_foul/issue_renderer'
2
+
3
+ module PartyFoul
4
+ class RackIssueRenderer < IssueRenderer
5
+ def params
6
+ env['QUERY_STRING']
7
+ end
8
+
9
+ def title
10
+ %{(#{exception.class}) "#{exception.message}"}
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ require 'party_foul/issue_renderer'
2
+
3
+ module PartyFoul
4
+ class RailsIssueRenderer < IssueRenderer
5
+ def params
6
+ parameter_filter = ActionDispatch::Http::ParameterFilter.new(env["action_dispatch.parameter_filter"])
7
+ parameter_filter.filter(env['action_dispatch.request.path_parameters'])
8
+ end
9
+
10
+ def title
11
+ %{#{env['action_controller.instance'].class}##{env['action_dispatch.request.path_parameters']['action']} (#{exception.class}) "#{exception.message}"}
12
+ end
13
+
14
+ private
15
+
16
+ def app_root
17
+ Rails.root
18
+ end
19
+ end
20
+ end
@@ -1,4 +1,4 @@
1
- class PartyFoul::SyncAdapter
1
+ class PartyFoul::Processors::Sync
2
2
  def self.handle(exception, env)
3
3
  PartyFoul::ExceptionHandler.new(exception, env).run
4
4
  end
@@ -0,0 +1,4 @@
1
+ module PartyFoul::Processors
2
+ end
3
+
4
+ require 'party_foul/processors/sync'
@@ -1,3 +1,3 @@
1
1
  module PartyFoul
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
data/lib/party_foul.rb CHANGED
@@ -2,7 +2,13 @@ require 'github_api'
2
2
 
3
3
  module PartyFoul
4
4
  class << self
5
- attr_accessor :github, :oauth_token, :endpoint, :owner, :repo, :ignored_exceptions, :adapter, :issue_template, :comment_template, :filtered_http_headers
5
+ attr_accessor :github, :oauth_token, :endpoint, :owner, :repo,
6
+ :ignored_exceptions, :processor, :issue_template,
7
+ :comment_template, :filtered_http_headers, :web_url
8
+ end
9
+
10
+ def self.web_url
11
+ @web_url ||= 'https://github.com'
6
12
  end
7
13
 
8
14
  def self.issue_template
@@ -37,9 +43,13 @@ Fingerprint: `:fingerprint`
37
43
  @ignored_exceptions || []
38
44
  end
39
45
 
46
+ def self.repo_url
47
+ "#{web_url}/#{owner}/#{repo}"
48
+ end
49
+
40
50
  def self.configure(&block)
41
51
  yield self
42
- self.adapter ||= SyncAdapter
52
+ self.processor ||= PartyFoul::Processors::Sync
43
53
  _self = self
44
54
  self.github ||= Github.new do |config|
45
55
  %w{endpoint oauth_token}.each do |option|
@@ -50,5 +60,6 @@ Fingerprint: `:fingerprint`
50
60
  end
51
61
 
52
62
  require 'party_foul/exception_handler'
63
+ require 'party_foul/issue_renderer'
53
64
  require 'party_foul/middleware'
54
- require 'party_foul/sync_adapter'
65
+ require 'party_foul/processors'
@@ -6,20 +6,23 @@ class PartyFoul::GeneratorTest < Rails::Generators::TestCase
6
6
  destination File.expand_path('../tmp', __FILE__)
7
7
  tests PartyFoul::InstallGenerator
8
8
  test 'it copies the initializer' do
9
+ owner = 'test_owner'
10
+ repo = 'test_repo'
9
11
  oauth = mock('Oauth')
10
12
  oauth.stubs(:create)
11
- oauth.expects(:create).with('scopes' => ['repo']).returns(Hashie::Mash.new(token: 'test_token'))
13
+ oauth.expects(:create).with(scopes: ['repo'], note: 'PartyFoul test_owner/test_repo', note_url: 'http://example.com/test_owner/test_repo').returns(Hashie::Mash.new(token: 'test_token'))
12
14
  github = mock('Github')
13
15
  github.stubs(:oauth).returns(oauth)
14
- Github.stubs(:new).with(:login => 'test_login', :password => 'test_password', :endpoint => 'test_endpoint').returns(github)
15
- $stdin.stubs(:gets).returns('test_login').then.returns('test_password').then.returns('').then.returns('test_repo').then.returns("test_endpoint").then.returns('')
16
+ Github.stubs(:new).with(:login => 'test_login', :password => 'test_password', :endpoint => 'http://api.example.com').returns(github)
17
+ $stdin.stubs(:gets).returns('test_login').then.returns('test_password').then.returns(owner).then.returns(repo).then.returns('http://api.example.com').then.returns('http://example.com').then.returns('')
16
18
  run_generator
17
19
 
18
20
  assert_file 'config/initializers/party_foul.rb' do |initializer|
19
- assert_match(/config.endpoint\s+=\s'test_endpoint'/, initializer)
20
- assert_match(/config.owner\s+=\s'test_login'/, initializer)
21
- assert_match(/config.repo\s+=\s'test_repo'/, initializer)
22
- assert_match(/config.oauth_token\s+=\s'test_token'/, initializer)
21
+ assert_match(/config\.endpoint\s+=\s'http:\/\/api\.example\.com'/, initializer)
22
+ assert_match(/config\.web_url\s+=\s'http:\/\/example\.com'/, initializer)
23
+ assert_match(/config\.owner\s+=\s'test_owner'/, initializer)
24
+ assert_match(/config\.repo\s+=\s'test_repo'/, initializer)
25
+ assert_match(/config\.oauth_token\s+=\s'test_token'/, initializer)
23
26
  end
24
27
  end
25
28
  end
@@ -10,7 +10,8 @@ describe 'Party Foul Confg' do
10
10
  PartyFoul.configure do |config|
11
11
  config.ignored_exceptions = ['StandardError']
12
12
  config.oauth_token = 'test_token'
13
- config.endpoint = 'test_endpoint'
13
+ config.web_url = 'http://example.com'
14
+ config.endpoint = 'http://api.example.com'
14
15
  config.owner = 'test_owner'
15
16
  config.repo = 'test_repo'
16
17
  end
@@ -18,8 +19,9 @@ describe 'Party Foul Confg' do
18
19
  PartyFoul.ignored_exceptions.must_equal ['StandardError']
19
20
  PartyFoul.github.must_be_instance_of Github::Client
20
21
  PartyFoul.github.oauth_token.must_equal 'test_token'
21
- PartyFoul.github.endpoint.must_equal 'test_endpoint'
22
+ PartyFoul.github.endpoint.must_equal 'http://api.example.com'
22
23
  PartyFoul.owner.must_equal 'test_owner'
23
24
  PartyFoul.repo.must_equal 'test_repo'
25
+ PartyFoul.repo_url.must_equal 'http://example.com/test_owner/test_repo'
24
26
  end
25
27
  end
@@ -1,161 +1,70 @@
1
1
  require 'test_helper'
2
- require 'active_support/core_ext/object/blank'
3
- require 'action_dispatch/http/parameter_filter'
4
2
 
5
3
  describe 'Party Foul Exception Handler' do
6
4
  before do
7
- Time.stubs(:now).returns(Time.new(1970, 1, 1, 0, 0, 0, '-05:00'))
8
- end
9
-
10
- after do
11
- clean_up_party
12
- end
13
-
14
- describe '#body' do
15
- describe 'updating issue body' do
16
- before do
17
- @handler = PartyFoul::ExceptionHandler.new(nil, nil)
18
- @handler.stubs(:exception).returns('Test Exception')
19
- @handler.stubs(:fingerprint).returns('abcdefg1234567890')
20
- @handler.stubs(:stack_trace)
21
- end
22
-
23
- it 'updates count and timestamp' do
24
- body = <<-BODY
25
- <table>
26
- <tr><th>Exception</th><td>Test Exception</td></tr>
27
- <tr><th>Count</th><td>1</td></tr>
28
- <tr><th>Last Occurance</th><td>January 01, 1970 00:00:00 -0500</td></tr>
29
- </table>
30
-
31
- ## Stack Trace
32
- <pre></pre>
33
- Fingerprint: `abcdefg1234567890`
34
- BODY
35
-
36
- Time.stubs(:now).returns(Time.new(1985, 10, 25, 1, 22, 0, '-05:00'))
37
-
38
- expected_body = <<-BODY
39
- <table>
40
- <tr><th>Exception</th><td>Test Exception</td></tr>
41
- <tr><th>Count</th><td>2</td></tr>
42
- <tr><th>Last Occurance</th><td>October 25, 1985 01:22:00 -0500</td></tr>
43
- </table>
44
-
45
- ## Stack Trace
46
- <pre></pre>
47
- Fingerprint: `abcdefg1234567890`
48
- BODY
49
-
50
- @handler.update_body(body).must_equal expected_body
51
- end
5
+ PartyFoul.configure do |config|
6
+ config.oauth_token = 'abcdefg1234567890'
7
+ config.owner = 'test_owner'
8
+ config.repo = 'test_repo'
52
9
  end
53
10
 
54
- describe 'empty body' do
55
- before do
56
- @handler = PartyFoul::ExceptionHandler.new(nil, nil)
57
- @handler.stubs(:exception).returns('Test Exception')
58
- @handler.stubs(:fingerprint).returns('abcdefg1234567890')
59
- @handler.stubs(:stack_trace)
60
- end
61
-
62
- it 'resets body' do
63
- expected_body = <<-BODY
64
- <table>
65
- <tr><th>Exception</th><td>Test Exception</td></tr>
66
- <tr><th>Count</th><td>1</td></tr>
67
- <tr><th>Last Occurance</th><td>January 01, 1970 00:00:00 -0500</td></tr>
68
- </table>
69
-
70
- ## Stack Trace
71
- <pre></pre>
72
- Fingerprint: `abcdefg1234567890`
73
- BODY
74
- @handler.update_body(nil).must_equal expected_body
75
- end
76
- end
11
+ PartyFoul.github.stubs(:issues).returns(mock('Issues'))
12
+ PartyFoul.github.stubs(:search).returns(mock('Search'))
13
+ PartyFoul.github.issues.stubs(:create)
14
+ PartyFoul.github.issues.stubs(:edit)
15
+ PartyFoul.github.issues.stubs(:comments).returns(mock('Comments'))
16
+ PartyFoul.github.issues.comments.stubs(:create)
17
+ PartyFoul::RailsIssueRenderer.any_instance.stubs(:title).returns('Test Title')
18
+ PartyFoul::RailsIssueRenderer.any_instance.stubs(:fingerprint).returns('test_fingerprint')
77
19
  end
78
20
 
79
- describe '#params' do
80
- context 'with Rails' do
81
- before do
82
- @handler = PartyFoul::ExceptionHandler.new(nil, {'action_dispatch.parameter_filter' => ['password'], 'action_dispatch.request.path_parameters' => { 'status' => 'ok', 'password' => 'test' }, 'QUERY_STRING' => { 'status' => 'fail' } })
83
- end
84
-
85
- it 'returns ok' do
86
- @handler.params['status'].must_equal 'ok'
87
- @handler.params['password'].must_equal '[FILTERED]'
88
- end
89
- end
90
-
91
- context 'without Rails' do
92
- before do
93
- @handler = PartyFoul::ExceptionHandler.new(nil, {'QUERY_STRING' => { 'status' => 'ok' } })
94
- end
95
-
96
- it 'returns ok' do
97
- @handler.params['status'].must_equal 'ok'
98
- end
21
+ context 'when error is new' do
22
+ it 'will open a new error on Github' do
23
+ PartyFoul::RailsIssueRenderer.any_instance.stubs(:body).returns('Test Body')
24
+ PartyFoul::RailsIssueRenderer.any_instance.stubs(:comment).returns('Test Comment')
25
+ PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
26
+ PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'closed').returns(Hashie::Mash.new(issues: []))
27
+ PartyFoul.github.issues.expects(:create).with('test_owner', 'test_repo', title: 'Test Title', body: 'Test Body', :labels => ['bug']).returns(Hashie::Mash.new('number' => 1))
28
+ PartyFoul.github.issues.comments.expects(:create).with('test_owner', 'test_repo', 1, body: 'Test Comment')
29
+ PartyFoul::ExceptionHandler.new(nil, {}).run
99
30
  end
100
31
  end
101
32
 
102
- describe '#issue_comment' do
33
+ context 'when error is not new' do
103
34
  before do
104
- env = {
105
- 'REQUEST_URI' => 'http://example.com/',
106
- 'HTTP_USER_AGENT' => 'test_user_agent',
107
- 'REMOTE_ADDR' => '127.0.0.1',
108
- 'HTTP_HOST' => 'localhost:3000',
109
- 'QUERY_STRING' => { :controller => 'landing', :action => 'index' },
110
- 'rack.session' => { :id => 1 }
111
- }
112
- @handler = PartyFoul::ExceptionHandler.new(nil, env)
35
+ PartyFoul::RailsIssueRenderer.any_instance.stubs(:update_body).returns('New Body')
36
+ PartyFoul::RailsIssueRenderer.any_instance.stubs(:comment).returns('Test Comment')
113
37
  end
114
38
 
115
- it 'renders a new comment' do
116
- expected_comment = <<-COMMENT
117
- <table>
118
- <tr><th>Occurred at</th><td>January 01, 1970 00:00:00 -0500</td></tr>
119
- <tr><th>Params</th><td><table><tr><th>controller</th><td>landing</td></tr><tr><th>action</th><td>index</td></tr></table></td></tr>
120
- <tr><th>IP Address</th><td>127.0.0.1</td></tr>
121
- <tr><th>Session</th><td><table><tr><th>id</th><td>1</td></tr></table></td></tr>
122
- <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>
123
- </table>
124
- COMMENT
125
-
126
- @handler.comment_body.must_equal expected_comment
127
- end
128
- end
129
-
130
- describe '#compile_template' do
131
- it 'it parses the tags and inserts proper data' do
132
- template = '<span>:data1</span><div>:data2</div>'
133
- @handler = PartyFoul::ExceptionHandler.new(nil, nil)
134
- @handler.stubs(:data1).returns('123')
135
- @handler.stubs(:data2).returns('abc')
136
- @handler.compile_template(template).must_equal '<span>123</span><div>abc</div>'
137
- end
138
- end
139
-
140
- describe '#http_headers' do
141
- before do
142
- PartyFoul.filtered_http_headers = ['Cookie']
143
- env = {
144
- 'HTTP_USER_AGENT' => 'test_user_agent',
145
- 'HTTP_COOKIE' => 'test_cookie',
146
- }
147
- @handler = PartyFoul::ExceptionHandler.new(nil, env)
39
+ context 'and open' do
40
+ it 'will update the issue' do
41
+ 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}]))
42
+ PartyFoul.github.issues.expects(:edit).with('test_owner', 'test_repo', 1, body: 'New Body', state: 'open')
43
+ PartyFoul.github.issues.comments.expects(:create).with('test_owner', 'test_repo', 1, body: 'Test Comment')
44
+ PartyFoul::ExceptionHandler.new(nil, {}).run
45
+ end
148
46
  end
149
47
 
150
- it 'ignored Cookie' do
151
- @handler.http_headers.must_equal('User-Agent' => 'test_user_agent')
48
+ context 'and closed' do
49
+ it 'will update the count on the body and re-open the issue' do
50
+ PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
51
+ 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}]))
52
+ PartyFoul.github.issues.expects(:edit).with('test_owner', 'test_repo', 1, body: 'New Body', state: 'open', labels: ['bug', 'regression'])
53
+ PartyFoul.github.issues.comments.expects(:create).with('test_owner', 'test_repo', 1, body: 'Test Comment')
54
+ PartyFoul::ExceptionHandler.new(nil, {}).run
55
+ end
152
56
  end
153
57
  end
154
58
 
155
- describe '#hash_as_table' do
156
- it 'renders as an HTML table' do
157
- expected = '<table><tr><th>Value 1</th><td>A</td></tr><tr><th>Value B</th><td>2</td></tr></table>'
158
- PartyFoul::ExceptionHandler.new(nil, nil).hash_as_table('Value 1' => 'A', 'Value B' => 2).must_equal expected
59
+ context 'when issue is marked as "wontfix"' do
60
+ it 'does nothing' do
61
+ PartyFoul::RailsIssueRenderer.any_instance.stubs(:body).returns('Test Body')
62
+ PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
63
+ 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']}]))
64
+ PartyFoul.github.issues.expects(:create).never
65
+ PartyFoul.github.issues.expects(:edit).never
66
+ PartyFoul.github.issues.comments.expects(:create).never
67
+ PartyFoul::ExceptionHandler.new(nil, {}).run
159
68
  end
160
69
  end
161
70
  end
@@ -0,0 +1,139 @@
1
+ require 'test_helper'
2
+ require 'active_support/core_ext/object/blank'
3
+ require 'action_dispatch/http/parameter_filter'
4
+
5
+ describe 'Party Foul Issue Renderer' do
6
+ before do
7
+ Time.stubs(:now).returns(Time.new(1970, 1, 1, 0, 0, 0, '-05:00'))
8
+ end
9
+
10
+ after do
11
+ clean_up_party
12
+ end
13
+
14
+ describe '#body' do
15
+ describe 'updating issue body' do
16
+ before do
17
+ @rendered_issue = PartyFoul::IssueRenderer.new(nil, nil)
18
+ @rendered_issue.stubs(:exception).returns('Test Exception')
19
+ @rendered_issue.stubs(:fingerprint).returns('abcdefg1234567890')
20
+ @rendered_issue.stubs(:stack_trace)
21
+ end
22
+
23
+ it 'updates count and timestamp' do
24
+ body = <<-BODY
25
+ <table>
26
+ <tr><th>Exception</th><td>Test Exception</td></tr>
27
+ <tr><th>Count</th><td>1</td></tr>
28
+ <tr><th>Last Occurance</th><td>January 01, 1970 00:00:00 -0500</td></tr>
29
+ </table>
30
+
31
+ ## Stack Trace
32
+ <pre></pre>
33
+ Fingerprint: `abcdefg1234567890`
34
+ BODY
35
+
36
+ Time.stubs(:now).returns(Time.new(1985, 10, 25, 1, 22, 0, '-05:00'))
37
+
38
+ expected_body = <<-BODY
39
+ <table>
40
+ <tr><th>Exception</th><td>Test Exception</td></tr>
41
+ <tr><th>Count</th><td>2</td></tr>
42
+ <tr><th>Last Occurance</th><td>October 25, 1985 01:22:00 -0500</td></tr>
43
+ </table>
44
+
45
+ ## Stack Trace
46
+ <pre></pre>
47
+ Fingerprint: `abcdefg1234567890`
48
+ BODY
49
+
50
+ @rendered_issue.update_body(body).must_equal expected_body
51
+ end
52
+ end
53
+
54
+ describe 'empty body' do
55
+ before do
56
+ @rendered_issue = PartyFoul::IssueRenderer.new(nil, nil)
57
+ @rendered_issue.stubs(:exception).returns('Test Exception')
58
+ @rendered_issue.stubs(:fingerprint).returns('abcdefg1234567890')
59
+ @rendered_issue.stubs(:stack_trace)
60
+ end
61
+
62
+ it 'resets body' do
63
+ expected_body = <<-BODY
64
+ <table>
65
+ <tr><th>Exception</th><td>Test Exception</td></tr>
66
+ <tr><th>Count</th><td>1</td></tr>
67
+ <tr><th>Last Occurance</th><td>January 01, 1970 00:00:00 -0500</td></tr>
68
+ </table>
69
+
70
+ ## Stack Trace
71
+ <pre></pre>
72
+ Fingerprint: `abcdefg1234567890`
73
+ BODY
74
+ @rendered_issue.update_body(nil).must_equal expected_body
75
+ end
76
+ end
77
+ end
78
+
79
+ describe '#issue_comment' do
80
+ before do
81
+ env = {
82
+ 'REQUEST_URI' => 'http://example.com/',
83
+ 'HTTP_USER_AGENT' => 'test_user_agent',
84
+ 'REMOTE_ADDR' => '127.0.0.1',
85
+ 'HTTP_HOST' => 'localhost:3000',
86
+ 'rack.session' => { :id => 1 }
87
+ }
88
+ @rendered_issue = PartyFoul::IssueRenderer.new(nil, env)
89
+ @rendered_issue.stubs(:params).returns({})
90
+ end
91
+
92
+ it 'renders a new comment' do
93
+ expected_comment = <<-COMMENT
94
+ <table>
95
+ <tr><th>Occurred at</th><td>January 01, 1970 00:00:00 -0500</td></tr>
96
+ <tr><th>Params</th><td><table></table></td></tr>
97
+ <tr><th>IP Address</th><td>127.0.0.1</td></tr>
98
+ <tr><th>Session</th><td><table><tr><th>id</th><td>1</td></tr></table></td></tr>
99
+ <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>
100
+ </table>
101
+ COMMENT
102
+
103
+ @rendered_issue.comment.must_equal expected_comment
104
+ end
105
+ end
106
+
107
+ describe '#compile_template' do
108
+ it 'it parses the tags and inserts proper data' do
109
+ template = '<span>:data1</span><div>:data2</div>'
110
+ @rendered_issue = PartyFoul::IssueRenderer.new(nil, nil)
111
+ @rendered_issue.stubs(:data1).returns('123')
112
+ @rendered_issue.stubs(:data2).returns('abc')
113
+ @rendered_issue.compile_template(template).must_equal '<span>123</span><div>abc</div>'
114
+ end
115
+ end
116
+
117
+ describe '#http_headers' do
118
+ before do
119
+ PartyFoul.filtered_http_headers = ['Cookie']
120
+ env = {
121
+ 'HTTP_USER_AGENT' => 'test_user_agent',
122
+ 'HTTP_COOKIE' => 'test_cookie',
123
+ }
124
+ @rendered_issue = PartyFoul::IssueRenderer.new(nil, env)
125
+ end
126
+
127
+ it 'ignored Cookie' do
128
+ @rendered_issue.http_headers.must_equal('User-Agent' => 'test_user_agent')
129
+ end
130
+ end
131
+
132
+ describe '#fingerprint' do
133
+ it 'SHA1s the title' do
134
+ rendered_issue = PartyFoul::IssueRenderer.new(nil, nil)
135
+ rendered_issue.stubs(:title).returns('abcdefg1234567890')
136
+ rendered_issue.fingerprint.must_equal Digest::SHA1.hexdigest(rendered_issue.title)
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,24 @@
1
+ require 'test_helper'
2
+
3
+ describe 'Rack Issue Renderer' do
4
+ describe '#params' do
5
+ before do
6
+ @rendered_issue = PartyFoul::RackIssueRenderer.new(nil, {'QUERY_STRING' => { 'status' => 'ok' } })
7
+ end
8
+
9
+ it 'returns ok' do
10
+ @rendered_issue.params['status'].must_equal 'ok'
11
+ end
12
+ end
13
+
14
+ describe '#title' do
15
+ before do
16
+ @exception = Exception.new('message')
17
+ end
18
+
19
+ it 'constructs the title with the class and instance method' do
20
+ @rendered_issue = PartyFoul::RackIssueRenderer.new(@exception, {})
21
+ @rendered_issue.title.must_equal %{(Exception) "message"}
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+
3
+ describe 'Rails Issue Renderer' do
4
+ describe '#params' do
5
+ before do
6
+ @rendered_issue = PartyFoul::RailsIssueRenderer.new(nil, {'action_dispatch.parameter_filter' => ['password'], 'action_dispatch.request.path_parameters' => { 'status' => 'ok', 'password' => 'test' }, 'QUERY_STRING' => { 'status' => 'fail' } })
7
+ end
8
+
9
+ it 'returns ok' do
10
+ @rendered_issue.params['status'].must_equal 'ok'
11
+ @rendered_issue.params['password'].must_equal '[FILTERED]'
12
+ end
13
+ end
14
+
15
+ describe '#title' do
16
+ before do
17
+ @exception = Exception.new('message')
18
+ controller_instance = mock('Controller')
19
+ controller_instance.stubs(:class).returns('LandingController')
20
+ env = {
21
+ 'action_dispatch.request.path_parameters' => { 'controller' => 'landing', 'action' => 'index' },
22
+ 'action_controller.instance' => controller_instance
23
+ }
24
+ @rendered_issue = PartyFoul::RailsIssueRenderer.new(@exception, env)
25
+ end
26
+
27
+ it 'constructs the title with the controller and action' do
28
+ @rendered_issue.title.must_equal %{LandingController#index (Exception) "message"}
29
+ end
30
+ end
31
+ end
@@ -21,74 +21,10 @@ describe 'Party Foul Middleware' do
21
21
  }
22
22
  end
23
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.github.issues.stubs(:comments).returns(mock('Comments'))
35
- PartyFoul.github.issues.comments.stubs(:create)
36
- PartyFoul::ExceptionHandler.any_instance.stubs(:issue_title).returns('Test Title')
37
- PartyFoul::ExceptionHandler.any_instance.stubs(:fingerprint).returns('test_fingerprint')
38
- end
39
-
40
- context 'when error is new' do
41
- it 'will open a new error on Github' do
42
- PartyFoul::ExceptionHandler.any_instance.stubs(:issue_body).returns('Test Body')
43
- PartyFoul::ExceptionHandler.any_instance.stubs(:comment_body).returns('Test Comment')
44
- PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
45
- PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'closed').returns(Hashie::Mash.new(issues: []))
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')
48
- lambda {
49
- get '/'
50
- }.must_raise(Exception)
51
- end
52
- end
53
-
54
- context 'when error is not new' do
55
- before do
56
- PartyFoul::ExceptionHandler.any_instance.stubs(:update_body).returns('New Body')
57
- PartyFoul::ExceptionHandler.any_instance.stubs(:comment_body).returns('Test Comment')
58
- end
59
-
60
- context 'and open' do
61
- it 'will update the issue' do
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}]))
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')
65
- lambda {
66
- get '/'
67
- }.must_raise(Exception)
68
- end
69
- end
70
-
71
- context 'and closed' do
72
- it 'will update the count on the body and re-open the issue' do
73
- PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
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}]))
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')
77
- lambda {
78
- get '/'
79
- }.must_raise(Exception)
80
- end
81
- end
82
- end
83
-
84
- context 'when issue is marked as "wontfix"' do
85
- it 'does nothing' do
86
- PartyFoul::ExceptionHandler.any_instance.stubs(:issue_body).returns('Test Body')
87
- PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
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']}]))
89
- PartyFoul.github.issues.expects(:create).never
90
- PartyFoul.github.issues.expects(:edit).never
91
- PartyFoul.github.issues.comments.expects(:create).never
24
+ context 'handling an exception' do
25
+ it 'does not handle exception' do
26
+ PartyFoul::ExceptionHandler.stubs(:handle)
27
+ PartyFoul::ExceptionHandler.expects(:handle)
92
28
  lambda {
93
29
  get '/'
94
30
  }.must_raise(Exception)
@@ -102,11 +38,8 @@ describe 'Party Foul Middleware' do
102
38
  end
103
39
 
104
40
  it 'does not handle exception' do
105
- PartyFoul::ExceptionHandler.any_instance.stubs(:issue_body).returns('Test Body')
106
- PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'open').returns(Hashie::Mash.new(issues: []))
107
- PartyFoul.github.search.stubs(:issues).with(owner: 'test_owner', repo: 'test_repo', keyword: 'test_fingerprint', state: 'closed').returns(Hashie::Mash.new(issues: []))
108
- PartyFoul.github.issues.expects(:create).never
109
- PartyFoul.github.issues.comments.expects(:create).never
41
+ PartyFoul::ExceptionHandler.stubs(:handle)
42
+ PartyFoul::ExceptionHandler.expects(:handle).never
110
43
  lambda {
111
44
  get '/'
112
45
  }.must_raise(StandardError)
data/test/test_helper.rb CHANGED
@@ -21,7 +21,7 @@ module MiniTest::Expectations
21
21
  end
22
22
 
23
23
  def clean_up_party
24
- %w{github oauth_token endpoint owner repo ignored_exceptions adapter issue_template comment_template filtered_http_headers}.each do |attr|
24
+ %w{github oauth_token endpoint owner repo ignored_exceptions processor issue_template comment_template filtered_http_headers web_url}.each do |attr|
25
25
  PartyFoul.send("#{attr}=", nil)
26
26
  end
27
27
  end
@@ -6,15 +6,19 @@ PartyFoul.configure do |config|
6
6
  # The names of the HTTP headers to not report
7
7
  config.filtered_http_headers = ['Cookie']
8
8
 
9
- # The OAuth token for the account that will be opening the issues on Github
9
+ # The OAuth token for the account that is opening the issues on Github
10
10
  config.oauth_token = 'test_token'
11
11
 
12
12
  # The API endpoint for Github. Unless you are hosting a private
13
13
  # instance of Enterprise Github you do not need to include this
14
- config.endpoint = 'test_endpoint'
14
+ config.endpoint = 'http://api.example.com'
15
+
16
+ # The Web URL for Github. Unless you are hosting a private
17
+ # instance of Enterprise Github you do not need to include this
18
+ config.web_url = 'http://example.com'
15
19
 
16
20
  # The organization or user that owns the target repository
17
- config.owner = 'test_login'
21
+ config.owner = 'test_owner'
18
22
 
19
23
  # The repository for this application
20
24
  config.repo = 'test_repo'
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.3.0
4
+ version: 0.4.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-25 00:00:00.000000000 Z
13
+ date: 2013-01-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: github_api
@@ -167,8 +167,12 @@ files:
167
167
  - lib/generators/party_foul/install_generator.rb
168
168
  - lib/generators/party_foul/templates/party_foul.rb
169
169
  - lib/party_foul/exception_handler.rb
170
+ - lib/party_foul/issue_renderer.rb
171
+ - lib/party_foul/issue_renderers/rack.rb
172
+ - lib/party_foul/issue_renderers/rails.rb
170
173
  - lib/party_foul/middleware.rb
171
- - lib/party_foul/sync_adapter.rb
174
+ - lib/party_foul/processors/sync.rb
175
+ - lib/party_foul/processors.rb
172
176
  - lib/party_foul/version.rb
173
177
  - lib/party_foul.rb
174
178
  - Rakefile
@@ -176,6 +180,9 @@ files:
176
180
  - test/generator_test.rb
177
181
  - test/party_foul/configure_test.rb
178
182
  - test/party_foul/exception_handler_test.rb
183
+ - test/party_foul/issue_renderer_test.rb
184
+ - test/party_foul/issue_renderers/rack_test.rb
185
+ - test/party_foul/issue_renderers/rails_test.rb
179
186
  - test/party_foul/middleware_test.rb
180
187
  - test/test_helper.rb
181
188
  - test/tmp/config/initializers/party_foul.rb
@@ -193,7 +200,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
193
200
  version: '0'
194
201
  segments:
195
202
  - 0
196
- hash: 3070115477891214928
203
+ hash: -3123915090860232817
197
204
  required_rubygems_version: !ruby/object:Gem::Requirement
198
205
  none: false
199
206
  requirements:
@@ -202,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
209
  version: '0'
203
210
  segments:
204
211
  - 0
205
- hash: 3070115477891214928
212
+ hash: -3123915090860232817
206
213
  requirements: []
207
214
  rubyforge_project:
208
215
  rubygems_version: 1.8.23
@@ -213,6 +220,9 @@ test_files:
213
220
  - test/generator_test.rb
214
221
  - test/party_foul/configure_test.rb
215
222
  - test/party_foul/exception_handler_test.rb
223
+ - test/party_foul/issue_renderer_test.rb
224
+ - test/party_foul/issue_renderers/rack_test.rb
225
+ - test/party_foul/issue_renderers/rails_test.rb
216
226
  - test/party_foul/middleware_test.rb
217
227
  - test/test_helper.rb
218
228
  - test/tmp/config/initializers/party_foul.rb