Commit 93cf2659cdad67e293b49e0dcd54b01e8425d072

Authored by Thomas Cioppettini
2 parents 4cd3fc46 4678fd1d
Exists in master and in 1 other branch production

Merge remote-tracking branch 'upstream/master'

@@ -4,13 +4,14 @@ env: @@ -4,13 +4,14 @@ env:
4 rvm: 4 rvm:
5 - 2.0.0 5 - 2.0.0
6 - 1.9.3 6 - 1.9.3
7 - - rbx-19mode 7 + - 2.1.2
  8 + - rbx-2
8 - ruby-head 9 - ruby-head
9 services: mongodb 10 services: mongodb
10 #script: ./script/rspec-queue-mongoid.rb --format progress spec 11 #script: ./script/rspec-queue-mongoid.rb --format progress spec
11 matrix: 12 matrix:
12 allow_failures: 13 allow_failures:
13 - - rvm: rbx-19mode 14 + - rvm: rbx-2
14 - rvm: ruby-head 15 - rvm: ruby-head
15 16
16 17
CONTRIBUTORS.md
@@ -42,11 +42,14 @@ @@ -42,11 +42,14 @@
42 - [@nashby][] 42 - [@nashby][]
43 - [@shingara][] 43 - [@shingara][]
44 - [@tscolari][] 44 - [@tscolari][]
  45 +- [@callumd][]
  46 +
45 47
46 [@anicet]: https://github.com/anicet 48 [@anicet]: https://github.com/anicet
47 [@nashby]: https://github.com/nashby 49 [@nashby]: https://github.com/nashby
48 [@shingara]: https://github.com/shingara 50 [@shingara]: https://github.com/shingara
49 [@tscolari]: https://github.com/tscolari 51 [@tscolari]: https://github.com/tscolari
  52 +[@callumd]: https://github.com/callumd
50 53
51 ## 0.2.0 - 2013-09-11 54 ## 0.2.0 - 2013-09-11
52 55
1 source 'https://rubygems.org' 1 source 'https://rubygems.org'
2 2
3 -RAILS_VERSION = '~> 3.2.17' 3 +RAILS_VERSION = '~> 3.2.19'
4 4
5 gem 'actionmailer', RAILS_VERSION 5 gem 'actionmailer', RAILS_VERSION
6 gem 'actionpack', RAILS_VERSION 6 gem 'actionpack', RAILS_VERSION
@@ -79,8 +79,6 @@ group :development, :test do @@ -79,8 +79,6 @@ group :development, :test do
79 gem 'rspec-rails' 79 gem 'rspec-rails'
80 gem 'webmock', :require => false 80 gem 'webmock', :require => false
81 gem 'airbrake', :require => false 81 gem 'airbrake', :require => false
82 - gem 'ruby-debug', :platform => :mri_18  
83 - gem 'debugger', :platform => :mri_19  
84 gem 'pry-rails' 82 gem 'pry-rails'
85 # gem 'rpm_contrib' 83 # gem 'rpm_contrib'
86 # gem 'newrelic_rpm' 84 # gem 'newrelic_rpm'
1 GEM 1 GEM
2 remote: https://rubygems.org/ 2 remote: https://rubygems.org/
3 specs: 3 specs:
4 - actionmailer (3.2.17)  
5 - actionpack (= 3.2.17) 4 + actionmailer (3.2.19)
  5 + actionpack (= 3.2.19)
6 mail (~> 2.5.4) 6 mail (~> 2.5.4)
7 actionmailer_inline_css (1.5.3) 7 actionmailer_inline_css (1.5.3)
8 actionmailer (>= 3.0.0) 8 actionmailer (>= 3.0.0)
9 nokogiri (>= 1.4.4) 9 nokogiri (>= 1.4.4)
10 premailer (>= 1.7.1) 10 premailer (>= 1.7.1)
11 - actionpack (3.2.17)  
12 - activemodel (= 3.2.17)  
13 - activesupport (= 3.2.17) 11 + actionpack (3.2.19)
  12 + activemodel (= 3.2.19)
  13 + activesupport (= 3.2.19)
14 builder (~> 3.0.0) 14 builder (~> 3.0.0)
15 erubis (~> 2.7.0) 15 erubis (~> 2.7.0)
16 journey (~> 1.0.4) 16 journey (~> 1.0.4)
@@ -18,18 +18,18 @@ GEM @@ -18,18 +18,18 @@ GEM
18 rack-cache (~> 1.2) 18 rack-cache (~> 1.2)
19 rack-test (~> 0.6.1) 19 rack-test (~> 0.6.1)
20 sprockets (~> 2.2.1) 20 sprockets (~> 2.2.1)
21 - activemodel (3.2.17)  
22 - activesupport (= 3.2.17) 21 + activemodel (3.2.19)
  22 + activesupport (= 3.2.19)
23 builder (~> 3.0.0) 23 builder (~> 3.0.0)
24 - activerecord (3.2.17)  
25 - activemodel (= 3.2.17)  
26 - activesupport (= 3.2.17) 24 + activerecord (3.2.19)
  25 + activemodel (= 3.2.19)
  26 + activesupport (= 3.2.19)
27 arel (~> 3.0.2) 27 arel (~> 3.0.2)
28 tzinfo (~> 0.3.29) 28 tzinfo (~> 0.3.29)
29 - activeresource (3.2.17)  
30 - activemodel (= 3.2.17)  
31 - activesupport (= 3.2.17)  
32 - activesupport (3.2.17) 29 + activeresource (3.2.19)
  30 + activemodel (= 3.2.19)
  31 + activesupport (= 3.2.19)
  32 + activesupport (3.2.19)
33 i18n (~> 0.6, >= 0.6.4) 33 i18n (~> 0.6, >= 0.6.4)
34 multi_json (~> 1.0) 34 multi_json (~> 1.0)
35 addressable (2.3.5) 35 addressable (2.3.5)
@@ -67,7 +67,6 @@ GEM @@ -67,7 +67,6 @@ GEM
67 rack-test (>= 0.5.4) 67 rack-test (>= 0.5.4)
68 xpath (~> 2.0) 68 xpath (~> 2.0)
69 coderay (1.0.9) 69 coderay (1.0.9)
70 - columnize (0.3.6)  
71 coveralls (0.7.0) 70 coveralls (0.7.0)
72 multi_json (~> 1.3) 71 multi_json (~> 1.3)
73 rest-client 72 rest-client
@@ -80,12 +79,6 @@ GEM @@ -80,12 +79,6 @@ GEM
80 addressable 79 addressable
81 database_cleaner (1.2.0) 80 database_cleaner (1.2.0)
82 debug_inspector (0.0.2) 81 debug_inspector (0.0.2)
83 - debugger (1.6.3)  
84 - columnize (>= 0.3.1)  
85 - debugger-linecache (~> 1.2.0)  
86 - debugger-ruby_core_source (~> 1.2.4)  
87 - debugger-linecache (1.2.0)  
88 - debugger-ruby_core_source (1.2.4)  
89 decent_exposure (2.3.0) 82 decent_exposure (2.3.0)
90 devise (3.1.1) 83 devise (3.1.1)
91 bcrypt-ruby (~> 3.0) 84 bcrypt-ruby (~> 3.0)
@@ -133,7 +126,7 @@ GEM @@ -133,7 +126,7 @@ GEM
133 json (~> 1.8) 126 json (~> 1.8)
134 multi_xml (>= 0.5.2) 127 multi_xml (>= 0.5.2)
135 httpauth (0.2.0) 128 httpauth (0.2.0)
136 - i18n (0.6.9) 129 + i18n (0.6.11)
137 jira-ruby (0.1.2) 130 jira-ruby (0.1.2)
138 activesupport 131 activesupport
139 oauth 132 oauth
@@ -156,8 +149,6 @@ GEM @@ -156,8 +149,6 @@ GEM
156 lighthouse-api (2.0) 149 lighthouse-api (2.0)
157 activeresource (>= 3.0.0) 150 activeresource (>= 3.0.0)
158 activesupport (>= 3.0.0) 151 activesupport (>= 3.0.0)
159 - linecache (0.46)  
160 - rbx-require-relative (> 0.0.4)  
161 mail (2.5.4) 152 mail (2.5.4)
162 mime-types (~> 1.16) 153 mime-types (~> 1.16)
163 treetop (~> 1.4.8) 154 treetop (~> 1.4.8)
@@ -183,7 +174,7 @@ GEM @@ -183,7 +174,7 @@ GEM
183 rails (>= 3.2.0) 174 rails (>= 3.2.0)
184 railties (>= 3.2.0) 175 railties (>= 3.2.0)
185 moped (1.5.1) 176 moped (1.5.1)
186 - multi_json (1.9.2) 177 + multi_json (1.10.1)
187 multi_xml (0.5.5) 178 multi_xml (0.5.5)
188 multipart-post (1.2.0) 179 multipart-post (1.2.0)
189 net-scp (1.1.2) 180 net-scp (1.1.2)
@@ -231,7 +222,7 @@ GEM @@ -231,7 +222,7 @@ GEM
231 rest-client (~> 1.6.0) 222 rest-client (~> 1.6.0)
232 pjax_rails (0.3.4) 223 pjax_rails (0.3.4)
233 jquery-rails 224 jquery-rails
234 - polyglot (0.3.4) 225 + polyglot (0.3.5)
235 premailer (1.7.3) 226 premailer (1.7.3)
236 css_parser (>= 1.1.9) 227 css_parser (>= 1.1.9)
237 htmlentities (>= 4.0.0) 228 htmlentities (>= 4.0.0)
@@ -250,31 +241,30 @@ GEM @@ -250,31 +241,30 @@ GEM
250 rack (>= 0.4) 241 rack (>= 0.4)
251 rack-contrib (1.1.0) 242 rack-contrib (1.1.0)
252 rack (>= 0.9.1) 243 rack (>= 0.9.1)
253 - rack-ssl (1.3.3) 244 + rack-ssl (1.3.4)
254 rack 245 rack
255 rack-ssl-enforcer (0.2.6) 246 rack-ssl-enforcer (0.2.6)
256 rack-test (0.6.2) 247 rack-test (0.6.2)
257 rack (>= 1.0) 248 rack (>= 1.0)
258 - rails (3.2.17)  
259 - actionmailer (= 3.2.17)  
260 - actionpack (= 3.2.17)  
261 - activerecord (= 3.2.17)  
262 - activeresource (= 3.2.17)  
263 - activesupport (= 3.2.17) 249 + rails (3.2.19)
  250 + actionmailer (= 3.2.19)
  251 + actionpack (= 3.2.19)
  252 + activerecord (= 3.2.19)
  253 + activeresource (= 3.2.19)
  254 + activesupport (= 3.2.19)
264 bundler (~> 1.0) 255 bundler (~> 1.0)
265 - railties (= 3.2.17) 256 + railties (= 3.2.19)
266 rails_autolink (1.1.4) 257 rails_autolink (1.1.4)
267 rails (> 3.1) 258 rails (> 3.1)
268 - railties (3.2.17)  
269 - actionpack (= 3.2.17)  
270 - activesupport (= 3.2.17) 259 + railties (3.2.19)
  260 + actionpack (= 3.2.19)
  261 + activesupport (= 3.2.19)
271 rack-ssl (~> 1.3.2) 262 rack-ssl (~> 1.3.2)
272 rake (>= 0.8.7) 263 rake (>= 0.8.7)
273 rdoc (~> 3.4) 264 rdoc (~> 3.4)
274 thor (>= 0.14.6, < 2.0) 265 thor (>= 0.14.6, < 2.0)
275 raindrops (0.12.0) 266 raindrops (0.12.0)
276 - rake (10.1.1)  
277 - rbx-require-relative (0.0.9) 267 + rake (10.3.2)
278 rdoc (3.12.2) 268 rdoc (3.12.2)
279 json (~> 1.4) 269 json (~> 1.4)
280 ref (1.0.5) 270 ref (1.0.5)
@@ -296,11 +286,6 @@ GEM @@ -296,11 +286,6 @@ GEM
296 rspec-core (~> 2.14.0) 286 rspec-core (~> 2.14.0)
297 rspec-expectations (~> 2.14.0) 287 rspec-expectations (~> 2.14.0)
298 rspec-mocks (~> 2.14.0) 288 rspec-mocks (~> 2.14.0)
299 - ruby-debug (0.10.4)  
300 - columnize (>= 0.1)  
301 - ruby-debug-base (~> 0.10.4.0)  
302 - ruby-debug-base (0.10.4)  
303 - linecache (>= 0.3)  
304 ruby-fogbugz (0.1.1) 289 ruby-fogbugz (0.1.1)
305 crack 290 crack
306 rushover (0.3.0) 291 rushover (0.3.0)
@@ -330,7 +315,7 @@ GEM @@ -330,7 +315,7 @@ GEM
330 therubyracer (0.12.0) 315 therubyracer (0.12.0)
331 libv8 (~> 3.16.14.0) 316 libv8 (~> 3.16.14.0)
332 ref 317 ref
333 - thor (0.18.1) 318 + thor (0.19.1)
334 thread_safe (0.1.3) 319 thread_safe (0.1.3)
335 atomic 320 atomic
336 tilt (1.4.1) 321 tilt (1.4.1)
@@ -342,7 +327,7 @@ GEM @@ -342,7 +327,7 @@ GEM
342 turbo-sprockets-rails3 (0.3.10) 327 turbo-sprockets-rails3 (0.3.10)
343 railties (> 3.2.8, < 4.0.0) 328 railties (> 3.2.8, < 4.0.0)
344 sprockets (>= 2.0.0) 329 sprockets (>= 2.0.0)
345 - tzinfo (0.3.38) 330 + tzinfo (0.3.41)
346 uglifier (2.2.1) 331 uglifier (2.2.1)
347 execjs (>= 0.3.0) 332 execjs (>= 0.3.0)
348 multi_json (~> 1.0, >= 1.0.2) 333 multi_json (~> 1.0, >= 1.0.2)
@@ -366,9 +351,9 @@ PLATFORMS @@ -366,9 +351,9 @@ PLATFORMS
366 ruby 351 ruby
367 352
368 DEPENDENCIES 353 DEPENDENCIES
369 - actionmailer (~> 3.2.17) 354 + actionmailer (~> 3.2.19)
370 actionmailer_inline_css 355 actionmailer_inline_css
371 - actionpack (~> 3.2.17) 356 + actionpack (~> 3.2.19)
372 airbrake 357 airbrake
373 better_errors 358 better_errors
374 binding_of_caller 359 binding_of_caller
@@ -378,7 +363,6 @@ DEPENDENCIES @@ -378,7 +363,6 @@ DEPENDENCIES
378 capybara 363 capybara
379 coveralls 364 coveralls
380 database_cleaner 365 database_cleaner
381 - debugger  
382 decent_exposure 366 decent_exposure
383 devise 367 devise
384 email_spec 368 email_spec
@@ -413,10 +397,9 @@ DEPENDENCIES @@ -413,10 +397,9 @@ DEPENDENCIES
413 rack-ssl 397 rack-ssl
414 rack-ssl-enforcer 398 rack-ssl-enforcer
415 rails_autolink 399 rails_autolink
416 - railties (~> 3.2.17) 400 + railties (~> 3.2.19)
417 ri_cal 401 ri_cal
418 rspec-rails 402 rspec-rails
419 - ruby-debug  
420 ruby-fogbugz 403 ruby-fogbugz
421 rushover 404 rushover
422 strong_parameters 405 strong_parameters
@@ -175,9 +175,6 @@ heroku config:add HEROKU=true @@ -175,9 +175,6 @@ heroku config:add HEROKU=true
175 heroku config:add SECRET_TOKEN="$(bundle exec rake secret)" 175 heroku config:add SECRET_TOKEN="$(bundle exec rake secret)"
176 heroku config:add ERRBIT_HOST=some-hostname.example.com 176 heroku config:add ERRBIT_HOST=some-hostname.example.com
177 heroku config:add ERRBIT_EMAIL_FROM=example@example.com 177 heroku config:add ERRBIT_EMAIL_FROM=example@example.com
178 -# This next line is required to access env variables during asset compilation.  
179 -# For more info, go to this link: https://devcenter.heroku.com/articles/labs-user-env-compile  
180 -heroku labs:enable user-env-compile  
181 git push heroku master 178 git push heroku master
182 ``` 179 ```
183 180
app/controllers/api/v1/problems_controller.rb
1 class Api::V1::ProblemsController < ApplicationController 1 class Api::V1::ProblemsController < ApplicationController
2 respond_to :json, :xml 2 respond_to :json, :xml
  3 + FIELDS = %w{app_id app_name environment message where first_notice_at last_notice_at resolved resolved_at notices_count}
  4 +
  5 + def show
  6 + result = benchmark("[api/v1/problems_controller/show] query time") do
  7 + begin
  8 + Problem.only(FIELDS).find(params[:id])
  9 + rescue Mongoid::Errors::DocumentNotFound
  10 + head :not_found
  11 + return false
  12 + end
  13 + end
  14 +
  15 + respond_to do |format|
  16 + format.any(:html, :json) { render :json => result } # render JSON if no extension specified on path
  17 + format.xml { render :xml => result }
  18 + end
  19 + end
3 20
4 def index 21 def index
5 query = {} 22 query = {}
6 - fields = %w{app_id app_name environment message where first_notice_at last_notice_at resolved resolved_at notices_count}  
7 23
8 if params.key?(:start_date) && params.key?(:end_date) 24 if params.key?(:start_date) && params.key?(:end_date)
9 start_date = Time.parse(params[:start_date]).utc 25 start_date = Time.parse(params[:start_date]).utc
@@ -11,8 +27,8 @@ class Api::V1::ProblemsController &lt; ApplicationController @@ -11,8 +27,8 @@ class Api::V1::ProblemsController &lt; ApplicationController
11 query = {:first_notice_at=>{"$lte"=>end_date}, "$or"=>[{:resolved_at=>nil}, {:resolved_at=>{"$gte"=>start_date}}]} 27 query = {:first_notice_at=>{"$lte"=>end_date}, "$or"=>[{:resolved_at=>nil}, {:resolved_at=>{"$gte"=>start_date}}]}
12 end 28 end
13 29
14 - results = benchmark("[api/v1/problems_controller] query time") do  
15 - Problem.where(query).with(:consistency => :strong).only(fields).to_a 30 + results = benchmark("[api/v1/problems_controller/index] query time") do
  31 + Problem.where(query).with(:consistency => :strong).only(FIELDS).to_a
16 end 32 end
17 33
18 respond_to do |format| 34 respond_to do |format|
app/controllers/apps_controller.rb
@@ -36,6 +36,10 @@ class AppsController &lt; ApplicationController @@ -36,6 +36,10 @@ class AppsController &lt; ApplicationController
36 app.deploys.order_by(:created_at.desc).limit(5) 36 app.deploys.order_by(:created_at.desc).limit(5)
37 } 37 }
38 38
  39 + expose(:users) {
  40 + User.all.sort_by {|u| u.name.downcase }
  41 + }
  42 +
39 def index; end 43 def index; end
40 def show 44 def show
41 app 45 app
app/mailers/mailer.rb
@@ -6,7 +6,12 @@ class Mailer &lt; ActionMailer::Base @@ -6,7 +6,12 @@ class Mailer &lt; ActionMailer::Base
6 helper ApplicationHelper 6 helper ApplicationHelper
7 helper BacktraceLineHelper 7 helper BacktraceLineHelper
8 8
9 - default :from => Errbit::Config.email_from 9 + default :from => Errbit::Config.email_from,
  10 + 'X-Errbit-Host' => Errbit::Config.host,
  11 + 'X-Mailer' => 'Errbit',
  12 + 'X-Auto-Response-Suppress' => 'OOF, AutoReply',
  13 + 'Precedence' => 'bulk',
  14 + 'Auto-Submitted' => 'auto-generated'
10 15
11 def err_notification(notice) 16 def err_notification(notice)
12 @notice = notice 17 @notice = notice
@@ -15,6 +20,10 @@ class Mailer &lt; ActionMailer::Base @@ -15,6 +20,10 @@ class Mailer &lt; ActionMailer::Base
15 count = @notice.similar_count 20 count = @notice.similar_count
16 count = count > 1 ? "(#{count}) " : "" 21 count = count > 1 ? "(#{count}) " : ""
17 22
  23 + errbit_headers 'App' => @app.name,
  24 + 'Environment' => @notice.environment_name,
  25 + 'Error-Id' => @notice.err_id
  26 +
18 mail :to => @app.notification_recipients, 27 mail :to => @app.notification_recipients,
19 :subject => "#{count}[#{@app.name}][#{@notice.environment_name}] #{@notice.message.truncate(50)}" 28 :subject => "#{count}[#{@app.name}][#{@notice.environment_name}] #{@notice.message.truncate(50)}"
20 end 29 end
@@ -23,6 +32,11 @@ class Mailer &lt; ActionMailer::Base @@ -23,6 +32,11 @@ class Mailer &lt; ActionMailer::Base
23 @deploy = deploy 32 @deploy = deploy
24 @app = deploy.app 33 @app = deploy.app
25 34
  35 + errbit_headers 'App' => @app.name,
  36 + 'Environment' => @deploy.environment,
  37 + 'Deploy-Revision' => @deploy.revision,
  38 + 'Deploy-User' => @deploy.username
  39 +
26 mail :to => @app.notification_recipients, 40 mail :to => @app.notification_recipients,
27 :subject => "[#{@app.name}] Deployed to #{@deploy.environment} by #{@deploy.username}" 41 :subject => "[#{@app.name}] Deployed to #{@deploy.environment} by #{@deploy.username}"
28 end 42 end
@@ -36,7 +50,18 @@ class Mailer &lt; ActionMailer::Base @@ -36,7 +50,18 @@ class Mailer &lt; ActionMailer::Base
36 50
37 recipients = @comment.notification_recipients 51 recipients = @comment.notification_recipients
38 52
  53 + errbit_headers 'App' => @app.name,
  54 + 'Environment' => @notice.environment_name,
  55 + 'Problem-Id' => @problem.id,
  56 + 'Comment-Author' => @user.name
  57 +
39 mail :to => recipients, 58 mail :to => recipients,
40 :subject => "#{@user.name} commented on [#{@app.name}][#{@notice.environment_name}] #{@notice.message.truncate(50)}" 59 :subject => "#{@user.name} commented on [#{@app.name}][#{@notice.environment_name}] #{@notice.message.truncate(50)}"
41 end 60 end
  61 +
  62 + private
  63 +
  64 + def errbit_headers(header)
  65 + header.each { |key,value| headers["X-Errbit-#{key}"] = value.to_s }
  66 + end
42 end 67 end
app/models/error_report.rb
@@ -15,15 +15,18 @@ require &#39;hoptoad_notifier&#39; @@ -15,15 +15,18 @@ require &#39;hoptoad_notifier&#39;
15 # * <tt>:notifier</tt> - information to identify the source of the error report 15 # * <tt>:notifier</tt> - information to identify the source of the error report
16 # 16 #
17 class ErrorReport 17 class ErrorReport
18 - attr_reader :error_class, :message, :request, :server_environment, :api_key, :notifier, :user_attributes, :framework 18 + attr_reader :error_class, :message, :request, :server_environment, :api_key,
  19 + :notifier, :user_attributes, :framework, :notice
19 20
20 cattr_accessor :fingerprint_strategy do 21 cattr_accessor :fingerprint_strategy do
21 Fingerprint 22 Fingerprint
22 end 23 end
23 24
24 def initialize(xml_or_attributes) 25 def initialize(xml_or_attributes)
25 - @attributes = (xml_or_attributes.is_a?(String) ? Hoptoad.parse_xml!(xml_or_attributes) : xml_or_attributes).with_indifferent_access  
26 - @attributes.each{|k, v| instance_variable_set(:"@#{k}", v) } 26 + @attributes = xml_or_attributes
  27 + @attributes = Hoptoad.parse_xml!(@attributes) if @attributes.is_a? String
  28 + @attributes = @attributes.with_indifferent_access
  29 + @attributes.each { |k, v| instance_variable_set(:"@#{k}", v) }
27 end 30 end
28 31
29 def rails_env 32 def rails_env
@@ -33,30 +36,29 @@ class ErrorReport @@ -33,30 +36,29 @@ class ErrorReport
33 end 36 end
34 37
35 def app 38 def app
36 - @app ||= App.where(:api_key => api_key).first 39 + @app ||= App.where(api_key: api_key).first
37 end 40 end
38 41
39 def backtrace 42 def backtrace
40 - @normalized_backtrace ||= Backtrace.find_or_create(:raw => @backtrace) 43 + @normalized_backtrace ||= Backtrace.find_or_create(raw: @backtrace)
41 end 44 end
42 45
43 def generate_notice! 46 def generate_notice!
44 return unless valid? 47 return unless valid?
45 return @notice if @notice 48 return @notice if @notice
46 @notice = Notice.new( 49 @notice = Notice.new(
47 - :message => message,  
48 - :error_class => error_class,  
49 - :backtrace_id => backtrace.id,  
50 - :request => request,  
51 - :server_environment => server_environment,  
52 - :notifier => notifier,  
53 - :user_attributes => user_attributes,  
54 - :framework => framework 50 + message: message,
  51 + error_class: error_class,
  52 + backtrace_id: backtrace.id,
  53 + request: request,
  54 + server_environment: server_environment,
  55 + notifier: notifier,
  56 + user_attributes: user_attributes,
  57 + framework: framework
55 ) 58 )
56 error.notices << @notice 59 error.notices << @notice
57 @notice 60 @notice
58 end 61 end
59 - attr_reader :notice  
60 62
61 ## 63 ##
62 # Error associate to this error_report 64 # Error associate to this error_report
@@ -66,23 +68,22 @@ class ErrorReport @@ -66,23 +68,22 @@ class ErrorReport
66 # @return [ Error ] 68 # @return [ Error ]
67 def error 69 def error
68 @error ||= app.find_or_create_err!( 70 @error ||= app.find_or_create_err!(
69 - :error_class => error_class,  
70 - :environment => rails_env,  
71 - :fingerprint => fingerprint 71 + error_class: error_class,
  72 + environment: rails_env,
  73 + fingerprint: fingerprint
72 ) 74 )
73 end 75 end
74 76
75 def valid? 77 def valid?
76 - !!app 78 + app.present?
77 end 79 end
78 80
79 def should_keep? 81 def should_keep?
80 app_version = server_environment['app-version'] || '' 82 app_version = server_environment['app-version'] || ''
81 - if self.app.current_app_version.present? && ( app_version.length <= 0 || Gem::Version.new(app_version) < Gem::Version.new(self.app.current_app_version) )  
82 - false  
83 - else  
84 - true  
85 - end 83 + current_version = app.current_app_version
  84 + return true unless current_version.present?
  85 + return false if app_version.length <= 0
  86 + Gem::Version.new(app_version) >= Gem::Version.new(current_version)
86 end 87 end
87 88
88 private 89 private
@@ -90,5 +91,4 @@ class ErrorReport @@ -90,5 +91,4 @@ class ErrorReport
90 def fingerprint 91 def fingerprint
91 @fingerprint ||= fingerprint_strategy.generate(notice, api_key) 92 @fingerprint ||= fingerprint_strategy.generate(notice, api_key)
92 end 93 end
93 -  
94 end 94 end
app/models/notice.rb
@@ -78,6 +78,17 @@ class Notice @@ -78,6 +78,17 @@ class Notice
78 "N/A" 78 "N/A"
79 end 79 end
80 80
  81 + def to_curl
  82 + return "N/A" if url.blank?
  83 + headers = %w(Accept Accept-Encoding Accept-Language Cookie Referer User-Agent).each_with_object([]) do |name, h|
  84 + if value = env_vars["HTTP_#{name.underscore.upcase}"]
  85 + h << "-H '#{name}: #{value}'"
  86 + end
  87 + end
  88 +
  89 + "curl -X #{env_vars['REQUEST_METHOD'] || 'GET'} #{headers.join(' ')} #{url}"
  90 + end
  91 +
81 def env_vars 92 def env_vars
82 request['cgi-data'] || {} 93 request['cgi-data'] || {}
83 end 94 end
app/models/notification_service.rb
@@ -54,6 +54,6 @@ class NotificationService @@ -54,6 +54,6 @@ class NotificationService
54 end 54 end
55 55
56 def problem_url(problem) 56 def problem_url(problem)
57 - "http://#{Errbit::Config.host}/apps/#{problem.app.id}/problems/#{problem.id}" 57 + "#{Errbit::Config.protocol}://#{Errbit::Config.host}/apps/#{problem.app.id}/problems/#{problem.id}"
58 end 58 end
59 end 59 end
app/models/notification_services/campfire_service.rb
@@ -30,7 +30,7 @@ if defined? Campy @@ -30,7 +30,7 @@ if defined? Campy
30 # build the campfire client 30 # build the campfire client
31 campy = Campy::Room.new(:account => subdomain, :token => api_token, :room_id => room_id) 31 campy = Campy::Room.new(:account => subdomain, :token => api_token, :room_id => room_id)
32 # post the issue to the campfire room 32 # post the issue to the campfire room
33 - campy.speak "[errbit] #{problem.app.name} #{notification_description problem} - http://#{Errbit::Config.host}/apps/#{problem.app.id.to_s}/problems/#{problem.id.to_s}" 33 + campy.speak "[errbit] #{problem.app.name} #{notification_description problem} - #{Errbit::Config.protocol}://#{Errbit::Config.host}/apps/#{problem.app.id.to_s}/problems/#{problem.id.to_s}"
34 end 34 end
35 end 35 end
36 end 36 end
app/models/notification_services/gtalk_service.rb
@@ -47,7 +47,7 @@ class NotificationServices::GtalkService &lt; NotificationService @@ -47,7 +47,7 @@ class NotificationServices::GtalkService &lt; NotificationService
47 47
48 #has to look like this to be formatted properly in the client 48 #has to look like this to be formatted properly in the client
49 message = """#{problem.app.name.to_s} 49 message = """#{problem.app.name.to_s}
50 -http://#{Errbit::Config.host}/apps/#{problem.app.id.to_s} 50 +#{Errbit::Config.protocol}://#{Errbit::Config.host}/apps/#{problem.app.id.to_s}
51 #{notification_description problem}""" 51 #{notification_description problem}"""
52 52
53 # post the issue to the xmpp room(s) 53 # post the issue to the xmpp room(s)
app/models/notification_services/hoiio_service.rb
@@ -35,7 +35,7 @@ class NotificationServices::HoiioService &lt; NotificationService @@ -35,7 +35,7 @@ class NotificationServices::HoiioService &lt; NotificationService
35 35
36 # send sms 36 # send sms
37 room_id.split(',').each do |number| 37 room_id.split(',').each do |number|
38 - sms.send :dest => number, :msg => "http://#{Errbit::Config.host}/apps/#{problem.app.id.to_s} #{notification_description problem}" 38 + sms.send :dest => number, :msg => "#{Errbit::Config.protocol}://#{Errbit::Config.host}/apps/#{problem.app.id.to_s} #{notification_description problem}"
39 end 39 end
40 40
41 end 41 end
app/models/notification_services/pushover_service.rb
@@ -26,7 +26,7 @@ class NotificationServices::PushoverService &lt; NotificationService @@ -26,7 +26,7 @@ class NotificationServices::PushoverService &lt; NotificationService
26 notification = Rushover::Client.new(subdomain) 26 notification = Rushover::Client.new(subdomain)
27 27
28 # send push notification to pushover 28 # send push notification to pushover
29 - notification.notify(api_token, "#{notification_description problem}", :priority => 1, :title => "Errbit Notification", :url => "http://#{Errbit::Config.host}/apps/#{problem.app.id.to_s}", :url_title => "Link to error") 29 + notification.notify(api_token, "#{notification_description problem}", :priority => 1, :title => "Errbit Notification", :url => "#{Errbit::Config.protocol}://#{Errbit::Config.host}/apps/#{problem.app.id.to_s}", :url_title => "Link to error")
30 30
31 end 31 end
32 end 32 end
app/models/problem.rb
@@ -50,7 +50,6 @@ class Problem @@ -50,7 +50,6 @@ class Problem
50 50
51 validates_presence_of :last_notice_at, :first_notice_at 51 validates_presence_of :last_notice_at, :first_notice_at
52 52
53 -  
54 def self.all_else_unresolved(fetch_all) 53 def self.all_else_unresolved(fetch_all)
55 if fetch_all 54 if fetch_all
56 all 55 all
app/views/apps/_fields.html.haml
@@ -55,7 +55,7 @@ @@ -55,7 +55,7 @@
55 = w.radio_button :watcher_type, :email 55 = w.radio_button :watcher_type, :email
56 = label_tag :watcher_type_email, 'Email Address', :for => label_for_attr(w, 'watcher_type_email') 56 = label_tag :watcher_type_email, 'Email Address', :for => label_for_attr(w, 'watcher_type_email')
57 %div.watcher_params.user{:class => w.object.email.blank? ? 'chosen' : nil} 57 %div.watcher_params.user{:class => w.object.email.blank? ? 'chosen' : nil}
58 - = w.select :user_id, User.all.map{|u| [u.name,u.id.to_s]}, :include_blank => '-- Select a User --' 58 + = w.select :user_id, users.map{|u| [u.name,u.id.to_s]}, :include_blank => '-- Select a User --'
59 %div.watcher_params.email{:class => w.object.email.present? ? 'chosen' : nil} 59 %div.watcher_params.email{:class => w.object.email.present? ? 'chosen' : nil}
60 = w.text_field :email 60 = w.text_field :email
61 61
@@ -65,4 +65,3 @@ @@ -65,4 +65,3 @@
65 65
66 = render "issue_tracker_fields", :f => f 66 = render "issue_tracker_fields", :f => f
67 = render "service_notification_fields", :f => f 67 = render "service_notification_fields", :f => f
68 -  
app/views/notices/_summary.html.haml
@@ -10,6 +10,9 @@ @@ -10,6 +10,9 @@
10 %tr 10 %tr
11 %th URL 11 %th URL
12 %td.nowrap= link_to notice.request['url'], notice.request['url'] 12 %td.nowrap= link_to notice.request['url'], notice.request['url']
  13 + %tr
  14 + %th &nbsp;
  15 + %td= notice.to_curl
13 %tr 16 %tr
14 %th Where 17 %th Where
15 %td= notice.where 18 %td= notice.where
config/cloud/cloud66/files/_load_config.rb
@@ -17,6 +17,7 @@ unless defined?(Errbit::Config) @@ -17,6 +17,7 @@ unless defined?(Errbit::Config)
17 Errbit::Config.use_gravatar = ENV['ERRBIT_USE_GRAVATAR'] 17 Errbit::Config.use_gravatar = ENV['ERRBIT_USE_GRAVATAR']
18 Errbit::Config.gravatar_default = ENV['ERRBIT_GRAVATAR_DEFAULT'] 18 Errbit::Config.gravatar_default = ENV['ERRBIT_GRAVATAR_DEFAULT']
19 19
  20 + Errbit::Config.github_url = ENV['GITHUB_URL']
20 Errbit::Config.github_authentication = ENV['GITHUB_AUTHENTICATION'] 21 Errbit::Config.github_authentication = ENV['GITHUB_AUTHENTICATION']
21 Errbit::Config.github_client_id = ENV['GITHUB_CLIENT_ID'] 22 Errbit::Config.github_client_id = ENV['GITHUB_CLIENT_ID']
22 Errbit::Config.github_secret = ENV['GITHUB_SECRET'] 23 Errbit::Config.github_secret = ENV['GITHUB_SECRET']
config/initializers/_load_config.rb
@@ -6,9 +6,12 @@ unless defined?(Errbit::Config) @@ -6,9 +6,12 @@ unless defined?(Errbit::Config)
6 Errbit::Config = OpenStruct.new 6 Errbit::Config = OpenStruct.new
7 use_env = ENV['HEROKU'] || ENV['USE_ENV'] 7 use_env = ENV['HEROKU'] || ENV['USE_ENV']
8 8
  9 + Errbit::Config.protocol = 'http'
  10 +
9 # If Errbit is running on Heroku, config can be set from environment variables. 11 # If Errbit is running on Heroku, config can be set from environment variables.
10 if use_env 12 if use_env
11 Errbit::Config.host = ENV['ERRBIT_HOST'] 13 Errbit::Config.host = ENV['ERRBIT_HOST']
  14 + Errbit::Config.protocol = ENV['ERRBIT_PROTOCOL'] || 'http'
12 Errbit::Config.port = ENV['ERRBIT_PORT'] 15 Errbit::Config.port = ENV['ERRBIT_PORT']
13 Errbit::Config.email_from = ENV['ERRBIT_EMAIL_FROM'] 16 Errbit::Config.email_from = ENV['ERRBIT_EMAIL_FROM']
14 # Not really easy to use like an env because need an array and ENV return a string :( 17 # Not really easy to use like an env because need an array and ENV return a string :(
@@ -34,7 +37,8 @@ unless defined?(Errbit::Config) @@ -34,7 +37,8 @@ unless defined?(Errbit::Config)
34 :authentication => :plain, 37 :authentication => :plain,
35 :user_name => ENV['SMTP_USERNAME'] || ENV['SENDGRID_USERNAME'], 38 :user_name => ENV['SMTP_USERNAME'] || ENV['SENDGRID_USERNAME'],
36 :password => ENV['SMTP_PASSWORD'] || ENV['SENDGRID_PASSWORD'], 39 :password => ENV['SMTP_PASSWORD'] || ENV['SENDGRID_PASSWORD'],
37 - :domain => ENV['SMTP_DOMAIN'] || ENV['SENDGRID_DOMAIN'] || ENV['ERRBIT_EMAIL_FROM'].split('@').last 40 + :domain => ENV['SMTP_DOMAIN'] || ENV['SENDGRID_DOMAIN'] ||
  41 + (ENV['ERRBIT_EMAIL_FROM'] ? ENV['ERRBIT_EMAIL_FROM'].split('@').last : nil)
38 } 42 }
39 end 43 end
40 44
config/initializers/mongo.rb
@@ -6,7 +6,7 @@ if config_file.file? &amp;&amp; @@ -6,7 +6,7 @@ if config_file.file? &amp;&amp;
6 elsif ENV['HEROKU'] || ENV['USE_ENV'] 6 elsif ENV['HEROKU'] || ENV['USE_ENV']
7 # No mongoid.yml file. Use ENV variable to define your MongoDB 7 # No mongoid.yml file. Use ENV variable to define your MongoDB
8 # configuration 8 # configuration
9 - if mongo = ENV['MONGOLAB_URI'] || ENV['MONGOHQ_URL'] || ENV['MONGODB_URL'] 9 + if mongo = ENV['MONGOLAB_URI'] || ENV['MONGOHQ_URL'] || ENV['MONGODB_URL'] || ENV['MONGO_URL']
10 settings = URI.parse(mongo) 10 settings = URI.parse(mongo)
11 database_name = settings.path.gsub(/^\//, '') 11 database_name = settings.path.gsub(/^\//, '')
12 else 12 else
config/routes.rb
@@ -50,7 +50,7 @@ Errbit::Application.routes.draw do @@ -50,7 +50,7 @@ Errbit::Application.routes.draw do
50 50
51 namespace :api do 51 namespace :api do
52 namespace :v1 do 52 namespace :v1 do
53 - resources :problems, :only => [:index], :defaults => { :format => 'json' } 53 + resources :problems, :only => [:index, :show], :defaults => { :format => 'json' }
54 resources :notices, :only => [:index], :defaults => { :format => 'json' } 54 resources :notices, :only => [:index], :defaults => { :format => 'json' }
55 resources :stats, :only => [], :defaults => { :format => 'json' } do 55 resources :stats, :only => [], :defaults => { :format => 'json' } do
56 collection do 56 collection do
lib/tasks/errbit/demo.rake
@@ -49,7 +49,8 @@ namespace :errbit do @@ -49,7 +49,8 @@ namespace :errbit do
49 :backtrace => random_backtrace, 49 :backtrace => random_backtrace,
50 :request => { 50 :request => {
51 'component' => 'main', 51 'component' => 'main',
52 - 'action' => 'error' 52 + 'action' => 'error',
  53 + 'url' => "http://example.com/post/#{[111, 222, 333].sample}",
53 }, 54 },
54 :server_environment => {'environment-name' => Rails.env.to_s}, 55 :server_environment => {'environment-name' => Rails.env.to_s},
55 :notifier => {:name => "seeds.rb"}, 56 :notifier => {:name => "seeds.rb"},
spec/controllers/api/v1/problems_controller_spec.rb
@@ -7,6 +7,70 @@ describe Api::V1::ProblemsController do @@ -7,6 +7,70 @@ describe Api::V1::ProblemsController do
7 @user = Fabricate(:user) 7 @user = Fabricate(:user)
8 end 8 end
9 9
  10 + describe "GET /api/v1/problems/:id" do
  11 + before do
  12 + notice = Fabricate(:notice)
  13 + err = Fabricate(:err, :notices => [notice])
  14 + @problem = Fabricate(:problem, :errs => [err])
  15 + end
  16 +
  17 + it "should return JSON if JSON is requested" do
  18 + get :show, :auth_token => @user.authentication_token, :format => "json", :id => Problem.first.id
  19 + expect { JSON.load(response.body) }.not_to raise_error() #JSON::ParserError
  20 + end
  21 +
  22 + it "should return XML if XML is requested" do
  23 + get :index, :auth_token => @user.authentication_token, :format => "xml", :id => @problem.id
  24 + expect(Nokogiri::XML(response.body).errors).to be_empty
  25 + end
  26 +
  27 + it "should return JSON by default" do
  28 + get :show, :auth_token => @user.authentication_token, :id => @problem.id
  29 + expect { JSON.load(response.body) }.not_to raise_error()#JSON::ParserError)
  30 + end
  31 +
  32 + it "should return the correct problem" do
  33 + get :show, :auth_token => @user.authentication_token, :format => "json", :id => @problem.id
  34 +
  35 + returned_problem = JSON.parse(response.body)
  36 + expect( returned_problem["_id"] ).to eq(@problem.id.to_s)
  37 + end
  38 +
  39 + it "should return only the correct fields" do
  40 + get :show, :auth_token => @user.authentication_token, :format => "json", :id => @problem.id
  41 + returned_problem = JSON.parse(response.body)
  42 +
  43 + expect( returned_problem.keys ).to match_array([
  44 + "app_name",
  45 + "first_notice_at",
  46 + "error_class",
  47 + "messages",
  48 + "hosts",
  49 + "created_at",
  50 + "app_id",
  51 + "last_notice_at",
  52 + "_id",
  53 + "issue_link",
  54 + "resolved",
  55 + "updated_at",
  56 + "resolved_at",
  57 + "last_deploy_at",
  58 + "where",
  59 + "issue_type",
  60 + "notices_count",
  61 + "user_agents",
  62 + "comments_count",
  63 + "message",
  64 + "environment"
  65 + ])
  66 + end
  67 +
  68 + it "returns a 404 if the problem cannot be found" do
  69 + get :show, :auth_token => @user.authentication_token, :format => "json", :id => 'IdontExist'
  70 + expect( response.status ).to eq(404)
  71 + end
  72 + end
  73 +
10 describe "GET /api/v1/problems" do 74 describe "GET /api/v1/problems" do
11 before do 75 before do
12 Fabricate(:problem, :first_notice_at => Date.new(2012, 8, 01), :resolved_at => Date.new(2012, 8, 02)) 76 Fabricate(:problem, :first_notice_at => Date.new(2012, 8, 01), :resolved_at => Date.new(2012, 8, 02))
spec/controllers/apps_controller_spec.rb
@@ -73,6 +73,16 @@ describe AppsController do @@ -73,6 +73,16 @@ describe AppsController do
73 expect(response).to be_success 73 expect(response).to be_success
74 end 74 end
75 75
  76 + it "should list available watchers by name" do
  77 + Fabricate(:user, :name => "Carol")
  78 + Fabricate(:user, :name => "Alice")
  79 + Fabricate(:user, :name => "Betty")
  80 +
  81 + get :show, :id => app.id
  82 +
  83 + expect(controller.users.to_a).to eq(User.all.to_a.sort_by(&:name))
  84 + end
  85 +
76 context "pagination" do 86 context "pagination" do
77 before(:each) do 87 before(:each) do
78 35.times { Fabricate(:err, :problem => Fabricate(:problem, :app => app)) } 88 35.times { Fabricate(:err, :problem => Fabricate(:problem, :app => app)) }
@@ -392,4 +402,3 @@ describe AppsController do @@ -392,4 +402,3 @@ describe AppsController do
392 end 402 end
393 403
394 end 404 end
395 -  
spec/mailers/mailer_spec.rb
1 require 'spec_helper' 1 require 'spec_helper'
2 2
  3 +shared_examples "a notification email" do
  4 + it "should have X-Mailer header" do
  5 + expect(@email).to have_header('X-Mailer', 'Errbit')
  6 + end
  7 +
  8 + it "should have X-Errbit-Host header" do
  9 + expect(@email).to have_header('X-Errbit-Host', Errbit::Config.host)
  10 + end
  11 +
  12 + it "should have Precedence header" do
  13 + expect(@email).to have_header('Precedence', 'bulk')
  14 + end
  15 +
  16 + it "should have Auto-Submitted header" do
  17 + expect(@email).to have_header('Auto-Submitted', 'auto-generated')
  18 + end
  19 +
  20 + it "should have X-Auto-Response-Suppress header" do
  21 + # http://msdn.microsoft.com/en-us/library/ee219609(v=EXCHG.80).aspx
  22 + expect(@email).to have_header('X-Auto-Response-Suppress', 'OOF, AutoReply')
  23 + end
  24 +
  25 + it "should send the email" do
  26 + expect(ActionMailer::Base.deliveries.size).to eq 1
  27 + end
  28 +end
  29 +
3 describe Mailer do 30 describe Mailer do
4 context "Err Notification" do 31 context "Err Notification" do
5 include EmailSpec::Helpers 32 include EmailSpec::Helpers
@@ -19,9 +46,8 @@ describe Mailer do @@ -19,9 +46,8 @@ describe Mailer do
19 @email = Mailer.err_notification(notice).deliver 46 @email = Mailer.err_notification(notice).deliver
20 end 47 end
21 48
22 - it "should send the email" do  
23 - expect(ActionMailer::Base.deliveries.size).to eq 1  
24 - end 49 + it_should_behave_like "a notification email"
  50 +
25 51
26 it "should html-escape the notice's message for the html part" do 52 it "should html-escape the notice's message for the html part" do
27 expect(@email).to have_body_text("class &lt; ActionController::Base") 53 expect(@email).to have_body_text("class &lt; ActionController::Base")
@@ -62,10 +88,6 @@ describe Mailer do @@ -62,10 +88,6 @@ describe Mailer do
62 @email = Mailer.comment_notification(comment).deliver 88 @email = Mailer.comment_notification(comment).deliver
63 end 89 end
64 90
65 - it "should send the email" do  
66 - expect(ActionMailer::Base.deliveries.size).to eq 1  
67 - end  
68 -  
69 it "should be sent to comment notification recipients" do 91 it "should be sent to comment notification recipients" do
70 expect(@email.to).to eq recipients 92 expect(@email.to).to eq recipients
71 end 93 end
spec/models/notice_spec.rb
@@ -35,6 +35,28 @@ describe Notice do @@ -35,6 +35,28 @@ describe Notice do
35 end 35 end
36 end 36 end
37 37
  38 + describe "to_curl" do
  39 + let(:notice) { Fabricate.build(:notice, request: request) }
  40 +
  41 + context "when it has a request url" do
  42 + let(:request) { {'url' => "http://example.com/resource/12", 'cgi-data' => {'HTTP_USER_AGENT' => 'Mozilla/5.0'}} }
  43 +
  44 + it 'has a curl representation' do
  45 + cmd = notice.to_curl
  46 + expect(cmd).to eq(%q[curl -X GET -H 'User-Agent: Mozilla/5.0' http://example.com/resource/12])
  47 + end
  48 + end
  49 +
  50 + context "when it has not a request url" do
  51 + let(:request) { {'cgi-data' => {'HTTP_USER_AGENT' => 'Mozilla/5.0'}} }
  52 +
  53 + it 'has a curl representation' do
  54 + cmd = notice.to_curl
  55 + expect(cmd).to eq "N/A"
  56 + end
  57 + end
  58 + end
  59 +
38 describe "user agent" do 60 describe "user agent" do
39 it "should be parsed and human-readable" do 61 it "should be parsed and human-readable" do
40 notice = Fabricate.build(:notice, :request => {'cgi-data' => { 62 notice = Fabricate.build(:notice, :request => {'cgi-data' => {
spec/models/notification_service/gtalk_service_spec.rb
@@ -17,7 +17,7 @@ describe NotificationService::GtalkService do @@ -17,7 +17,7 @@ describe NotificationService::GtalkService do
17 expect(gtalk).to receive(:connect).with(notification_service.service) 17 expect(gtalk).to receive(:connect).with(notification_service.service)
18 expect(gtalk).to receive(:auth).with(notification_service.api_token) 18 expect(gtalk).to receive(:auth).with(notification_service.api_token)
19 message_value = """#{problem.app.name.to_s} 19 message_value = """#{problem.app.name.to_s}
20 -http://#{Errbit::Config.host}/apps/#{problem.app.id.to_s} 20 +#{Errbit::Config.protocol}://#{Errbit::Config.host}/apps/#{problem.app.id.to_s}
21 #{notification_service.notification_description problem}""" 21 #{notification_service.notification_description problem}"""
22 22
23 expect(Jabber::Message).to receive(:new).with(notification_service.user_id, message_value).and_return(message) 23 expect(Jabber::Message).to receive(:new).with(notification_service.user_id, message_value).and_return(message)
@@ -39,7 +39,7 @@ http://#{Errbit::Config.host}/apps/#{problem.app.id.to_s} @@ -39,7 +39,7 @@ http://#{Errbit::Config.host}/apps/#{problem.app.id.to_s}
39 @notification_service = Fabricate :gtalk_notification_service, :app => @notice.app 39 @notification_service = Fabricate :gtalk_notification_service, :app => @notice.app
40 @problem = @notice.problem 40 @problem = @notice.problem
41 @error_msg = """#{@problem.app.name.to_s} 41 @error_msg = """#{@problem.app.name.to_s}
42 -http://#{Errbit::Config.host}/apps/#{@problem.app.id.to_s} 42 +#{Errbit::Config.protocol}://#{Errbit::Config.host}/apps/#{@problem.app.id.to_s}
43 #{@notification_service.notification_description @problem}""" 43 #{@notification_service.notification_description @problem}"""
44 44
45 # gtalk stubbing 45 # gtalk stubbing
@@ -105,7 +105,7 @@ http://#{Errbit::Config.host}/apps/#{@problem.app.id.to_s} @@ -105,7 +105,7 @@ http://#{Errbit::Config.host}/apps/#{@problem.app.id.to_s}
105 expect(gtalk).to receive(:connect) 105 expect(gtalk).to receive(:connect)
106 expect(gtalk).to receive(:auth).with(notification_service.api_token) 106 expect(gtalk).to receive(:auth).with(notification_service.api_token)
107 message_value = """#{problem.app.name.to_s} 107 message_value = """#{problem.app.name.to_s}
108 -http://#{Errbit::Config.host}/apps/#{problem.app.id.to_s} 108 +#{Errbit::Config.protocol}://#{Errbit::Config.host}/apps/#{problem.app.id.to_s}
109 #{notification_service.notification_description problem}""" 109 #{notification_service.notification_description problem}"""
110 110
111 expect(Jabber::Message).to receive(:new).with(notification_service.room_id, message_value).and_return(message) 111 expect(Jabber::Message).to receive(:new).with(notification_service.room_id, message_value).and_return(message)
spec/models/notification_service/notification_service_spec.rb 0 → 100644
@@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
  1 +require 'spec_helper'
  2 +
  3 +describe NotificationService do
  4 +
  5 + let(:notice) { Fabricate :notice }
  6 + let(:notification_service) { Fabricate :notification_service, :app => notice.app }
  7 + let(:problem) { notice.problem }
  8 +
  9 + it "it should use http by default in #problem_url" do
  10 + notification_service.problem_url(problem).should start_with 'http://'
  11 + end
  12 +
  13 + it "it should use the protocol value specified in the config in #problem_url" do
  14 + Errbit::Config.protocol = 'https'
  15 + notification_service.problem_url(problem).should start_with 'https://'
  16 + end
  17 +
  18 +end