Commit 4bafab9d837bced1c384fe1c8d3653b3b6768e81

Authored by Pius Uzamere
1 parent 61ec5114

API level protection against users deactivating too many choice to have a valid prompt

Showing 49 changed files with 13 additions and 3832 deletions   Show diff stats
app/controllers/choices_controller.rb
... ... @@ -25,7 +25,7 @@ class ChoicesController < InheritedResources::Base
25 25 end
26 26 end
27 27 index! do |format|
28   - format.xml { render :xml => @choices.to_xml(:only => [ :data, :score, :id ])}
  28 + format.xml { render :xml => @choices.to_xml(:only => [ :data, :score, :id, :active ])}
29 29 end
30 30  
31 31 end
... ... @@ -97,17 +97,20 @@ class ChoicesController < InheritedResources::Base
97 97  
98 98 def deactivate_from_abroad
99 99 authenticate
100   - expire_page :action => :index
101 100 @question = current_user.questions.find(params[:question_id])
102 101 @choice = @question.choices.find(params[:id])
103 102  
104 103 respond_to do |format|
105   - if @choice.deactivate!
  104 + if @question.choices.active.size < 3
  105 + logger.info "will not deactivate choice because that would lead to fewer than two active choices for the question, #{@question.name}"
  106 + format.xml { render(:xml => false) and return}
  107 + format.json { render :json => false }
  108 + elsif @choice.deactivate!
106 109 logger.info "successfully deactivated choice #{@choice.inspect}"
107 110 format.xml { render :xml => true }
108 111 format.json { render :json => true }
109 112 else
110   - logger.info "failed to deactivate choice #{@choice.inspect}"
  113 + logger.info "failed to deactivate choice #{@choice.inspect}"
111 114 format.xml { render :xml => @choice.to_xml(:methods => [:data, :votes_count, :wins_plus_losses])}
112 115 format.json { render :json => @choice.to_json(:methods => [:data])}
113 116 end
... ... @@ -116,7 +119,6 @@ class ChoicesController &lt; InheritedResources::Base
116 119  
117 120 def activate
118 121 authenticate
119   - expire_page :action => :index
120 122 @question = current_user.questions.find(params[:question_id])
121 123 @choice = @question.choices.find(params[:id])
122 124 respond_to do |format|
... ... @@ -133,7 +135,6 @@ class ChoicesController &lt; InheritedResources::Base
133 135  
134 136 def suspend
135 137 authenticate
136   - expire_page :action => :index
137 138 @question = current_user.questions.find(params[:question_id])
138 139 @choice = @question.choices.find(params[:id])
139 140 respond_to do |format|
... ...
config/environment.rb
... ... @@ -14,6 +14,7 @@ Rails::Initializer.run do |config|
14 14 #config.action_mailer.delivery_method = :smtp
15 15 config.action_mailer.delivery_method = :sendmail
16 16  
  17 + config.gem 'hoptoad_notifier'
17 18 config.gem "ambethia-smtp-tls",
18 19 :lib => "smtp-tls",
19 20 :version => "1.1.2",
... ...
lib/tasks/hoptoad_notifier_tasks.rake 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +Dir[File.join(RAILS_ROOT, 'vendor', 'gems', 'hoptoad_notifier-*')].each do |vendored_notifier|
  2 + $: << File.join(vendored_notifier, 'lib')
  3 +end
  4 +
  5 +require 'hoptoad_notifier/tasks'
... ...
vendor/plugins/hoptoad_notifier/.yardopts
... ... @@ -1,3 +0,0 @@
1   --
2   -TESTING.rdoc
3   -MIT-LICENSE
vendor/plugins/hoptoad_notifier/INSTALL
... ... @@ -1,25 +0,0 @@
1   -=== Configuration
2   -
3   -You should have something like this in config/initializers/hoptoad.rb.
4   -
5   - HoptoadNotifier.configure do |config|
6   - config.api_key = '1234567890abcdef'
7   - end
8   -
9   -(Please note that this configuration should be in a global configuration, and
10   -is *not* environment-specific. Hoptoad is smart enough to know what errors are
11   -caused by what environments, so your staging errors don't get mixed in with
12   -your production errors.)
13   -
14   -You can test that Hoptoad is working in your production environment by using
15   -this rake task (from RAILS_ROOT):
16   -
17   - rake hoptoad:test
18   -
19   -If everything is configured properly, that task will send a notice to Hoptoad
20   -which will be visible immediately.
21   -
22   -NOTE FOR RAILS 1.2.* USERS:
23   -
24   -You will need to copy the hoptoad_notifier_tasks.rake file into your
25   -RAILS_ROOT/lib/tasks directory in order for the rake hoptoad:test task to work.
vendor/plugins/hoptoad_notifier/MIT-LICENSE
... ... @@ -1,22 +0,0 @@
1   -Copyright (c) 2007, Tammer Saleh, Thoughtbot, Inc.
2   -
3   -Permission is hereby granted, free of charge, to any person
4   -obtaining a copy of this software and associated documentation
5   -files (the "Software"), to deal in the Software without
6   -restriction, including without limitation the rights to use,
7   -copy, modify, merge, publish, distribute, sublicense, and/or sell
8   -copies of the Software, and to permit persons to whom the
9   -Software is furnished to do so, subject to the following
10   -conditions:
11   -
12   -The above copyright notice and this permission notice shall be
13   -included in all copies or substantial portions of the Software.
14   -
15   -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16   -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17   -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18   -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19   -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20   -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21   -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22   -OTHER DEALINGS IN THE SOFTWARE.
vendor/plugins/hoptoad_notifier/README.rdoc
... ... @@ -1,227 +0,0 @@
1   -= HoptoadNotifier
2   -
3   -This is the notifier plugin for integrating apps with Hoptoad.
4   -
5   -When an uncaught exception occurs, HoptoadNotifier will POST the relevant data
6   -to the Hoptoad server specified in your environment.
7   -
8   -== Help
9   -
10   -* {IRC}[irc://irc.freenode.net/thoughtbot]
11   -* {mailing list}[http://groups.google.com/group/hoptoad-notifier-dev]
12   -
13   -== Installation
14   -
15   -=== Remove exception_notifier
16   -
17   -in your ApplicationController, REMOVE this line:
18   -
19   - include ExceptionNotifiable
20   -
21   -In your config/environment* files, remove all references to ExceptionNotifier
22   -
23   -Remove the vendor/plugins/exception_notifier directory.
24   -
25   -=== Install hoptoad_notifier
26   -
27   -from your project's RAILS_ROOT, run:
28   -
29   - script/plugin install -f git://github.com/thoughtbot/hoptoad_notifier.git
30   -
31   -=== Configuration
32   -
33   -You should have something like this in config/initializers/hoptoad.rb.
34   -
35   - HoptoadNotifier.configure do |config|
36   - config.api_key = '1234567890abcdef'
37   - end
38   -
39   -(Please note that this configuration should be in a global configuration, and
40   -is *not* environment-specific. Hoptoad is smart enough to know what errors are
41   -caused by what environments, so your staging errors don't get mixed in with
42   -your production errors.)
43   -
44   -After adding to your config/initializers like this you must restart your
45   -server. This will not affect the rake task but it bears stating.
46   -
47   -That should be it! Now all exceptions will be logged to Hoptoad where they can
48   -be aggregated, filtered, sorted, analyzed, massaged, and searched. In previous
49   -releases you had to include HoptoadNotifier::Catcher into your
50   -ApplicationController, but the plugin takes care of that now.
51   -
52   -You can test that Hoptoad is working in your production environment by using
53   -this rake task (from RAILS_ROOT):
54   -
55   - rake hoptoad:test
56   -
57   -If everything is configured properly, that task will send a notice to Hoptoad
58   -which will be visible immediately.
59   -
60   -=== NOTE FOR RAILS 1.2.* USERS:
61   -
62   -You will need to copy the hoptoad_notifier_tasks.rake file into your
63   -RAILS_ROOT/lib/tasks directory in order for the rake hoptoad:test task to work.
64   -
65   -== Usage
66   -
67   -for the most part, Hoptoad works for itself. Once you've included the notifier
68   -in your ApplicationController (which is now done automatically by the plugin),
69   -all errors will be rescued by the #rescue_action_in_public provided by the plugin.
70   -
71   -If you want to log arbitrary things which you've rescued yourself from a
72   -controller, you can do something like this:
73   -
74   - ...
75   - rescue => ex
76   - notify_hoptoad(ex)
77   - flash[:failure] = 'Encryptions could not be rerouted, try again.'
78   - end
79   - ...
80   -
81   -The #notify_hoptoad call will send the notice over to Hoptoad for later analysis. While in your controllers you use the notify_hoptoad method, anywhere else in your code, use HoptoadNotifier.notify.
82   -
83   -To perform custom error processing after Hoptoad has been notified, define the instance method #rescue_action_in_public_without_hoptoad(exception) in your controller.
84   -
85   -== Tracking deployments in Hoptoad
86   -
87   -Paying Hoptoad plans support the ability to track deployments of your application in Hoptoad.
88   -By notifying Hoptoad of your application deployments, all errors are resolved when a deploy occurs,
89   -so that you'll be notified again about any errors that reoccur after a deployment.
90   -
91   -Additionally, it's possible to review the errors in Hoptoad that occurred before and after a deploy.
92   -
93   -When Hoptoad is installed as a plugin this functionality is loaded automatically (if you have Capistrano version 2.0.0 or greater).
94   -
95   -When Hoptoad is installed as a gem, you need to add
96   -
97   - require 'hoptoad_notifier/recipes/hoptoad'
98   -
99   -to your deploy.rb
100   -
101   -== Going beyond exceptions
102   -
103   -You can also pass a hash to notify_hoptoad method and store whatever you want, not just an exception. And you can also use it anywhere, not just in controllers:
104   -
105   - begin
106   - params = {
107   - # params that you pass to a method that can throw an exception
108   - }
109   - my_unpredicable_method(params)
110   - rescue => e
111   - HoptoadNotifier.notify(
112   - :error_class => "Special Error",
113   - :error_message => "Special Error: #{e.message}",
114   - :parameters => params
115   - )
116   - end
117   -
118   -While in your controllers you use the notify_hoptoad method, anywhere else in your code, use HoptoadNotifier.notify. Hoptoad will get all the information about the error itself. As for a hash, these are the keys you should pass:
119   -
120   -* :error_class – Use this to group similar errors together. When Hoptoad catches an exception it sends the class name of that exception object.
121   -* :error_message – This is the title of the error you see in the errors list. For exceptions it is "#{exception.class.name}: #{exception.message}"
122   -* :parameters – While there are several ways to send additional data to Hoptoad, passing a Hash as :parameters as in the example above is the most common use case. When Hoptoad catches an exception in a controller, the actual HTTP client request parameters are sent using this key.
123   -
124   -Hoptoad merges the hash you pass with these default options:
125   -
126   - {
127   - :api_key => HoptoadNotifier.api_key,
128   - :error_message => 'Notification',
129   - :backtrace => caller,
130   - :parameters => {},
131   - :session => {}
132   - }
133   -
134   -You can override any of those parameters.
135   -
136   -== Filtering
137   -
138   -You can specify a whitelist of errors, that Hoptoad will not report on. Use
139   -this feature when you are so apathetic to certain errors that you don't want
140   -them even logged.
141   -
142   -This filter will only be applied to automatic notifications, not manual
143   -notifications (when #notify is called directly).
144   -
145   -Hoptoad ignores the following exceptions by default:
146   -
147   - ActiveRecord::RecordNotFound
148   - ActionController::RoutingError
149   - ActionController::InvalidAuthenticityToken
150   - ActionController::UnknownAction
151   - CGI::Session::CookieStore::TamperedWithCookie
152   -
153   -To ignore errors in addition to those, specify their names in your Hoptoad
154   -configuration block.
155   -
156   - HoptoadNotifier.configure do |config|
157   - config.api_key = '1234567890abcdef'
158   - config.ignore << ActiveRecord::IgnoreThisError
159   - end
160   -
161   -To ignore *only* certain errors (and override the defaults), use the
162   -#ignore_only attribute.
163   -
164   - HoptoadNotifier.configure do |config|
165   - config.api_key = '1234567890abcdef'
166   - config.ignore_only = [ActiveRecord::IgnoreThisError]
167   - end
168   -
169   -To ignore certain user agents, add in the #ignore_user_agent attribute as a
170   -string or regexp:
171   -
172   - HoptoadNotifier.configure do |config|
173   - config.api_key = '1234567890abcdef'
174   - config.ignore_user_agent << /Ignored/
175   - config.ignore_user_agent << 'IgnoredUserAgent'
176   - end
177   -
178   -To ignore exceptions based on other conditions, use #ignore_by_filter:
179   -
180   - HoptoadNotifier.configure do |config|
181   - config.api_key = '1234567890abcdef'
182   - config.ignore_by_filter do |exception_data|
183   - true if exception_data[:error_class] == "RuntimeError"
184   - end
185   - end
186   -
187   -To replace sensitive information sent to the Hoptoad service with [FILTERED] use #params_filters:
188   -
189   - HoptoadNotifier.configure do |config|
190   - config.api_key = '1234567890abcdef'
191   - config.params_filters << "credit_card_number"
192   - end
193   -
194   -Note that, when rescuing exceptions within an ActionController method,
195   -hoptoad_notifier will reuse filters specified by #filter_params_logging.
196   -
197   -== Testing
198   -
199   -When you run your tests, you might notice that the Hoptoad service is recording
200   -notices generated using #notify when you don't expect it to. You can
201   -use code like this in your test_helper.rb to redefine that method so those
202   -errors are not reported while running tests.
203   -
204   - module HoptoadNotifier::Catcher
205   - def notify(thing)
206   - # do nothing.
207   - end
208   - end
209   -
210   -== Supported rails versions
211   -
212   -the notifier currently supports the following versions of Rails:
213   -
214   -* 1.2.6
215   -* 2.0.2
216   -* 2.1.0
217   -* 2.1.2
218   -* 2.2.2
219   -* 2.3.2
220   -* 2.3.3
221   -* 2.3.4
222   -
223   -Please open up a support ticket on Tender ( http://help.hoptoadapp.com ) if you're using a version of Rails that is not listed above and the notifier is not working properly.
224   -
225   -== Thanks
226   -
227   -Thanks to Eugene Bolshakov for the excellent write-up on GOING BEYOND EXCEPTIONS, which we have included above.
vendor/plugins/hoptoad_notifier/Rakefile
... ... @@ -1,29 +0,0 @@
1   -require 'rake'
2   -require 'rake/testtask'
3   -require 'rake/rdoctask'
4   -
5   -desc 'Default: run unit tests.'
6   -task :default => :test
7   -
8   -desc 'Test the hoptoad_notifier plugin.'
9   -Rake::TestTask.new(:test) do |t|
10   - t.libs << 'lib'
11   - t.pattern = 'test/**/*_test.rb'
12   - t.verbose = true
13   -end
14   -
15   -desc 'Run ginger tests'
16   -task :ginger do
17   - $LOAD_PATH << File.join(*%w[vendor ginger lib])
18   - ARGV.clear
19   - ARGV << 'test'
20   - load File.join(*%w[vendor ginger bin ginger])
21   -end
22   -
23   -begin
24   - require 'yard'
25   - YARD::Rake::YardocTask.new do |t|
26   - t.files = ['lib/**/*.rb', 'TESTING.rdoc']
27   - end
28   -rescue LoadError
29   -end
vendor/plugins/hoptoad_notifier/TESTING.rdoc
... ... @@ -1,8 +0,0 @@
1   -= For Maintainers:
2   -
3   -When developing the Hoptoad Notifier, be sure to use the integration test
4   -against an existing project on staging before pushing to master.
5   -
6   -+./script/integration_test.rb <test project's api key> <staging server hostname>+
7   -
8   -+./script/integration_test.rb <test project's api key> <staging server hostname> secure+
vendor/plugins/hoptoad_notifier/ginger_scenarios.rb
... ... @@ -1,31 +0,0 @@
1   -require 'ginger'
2   -
3   -def create_scenario(version)
4   - scenario = Ginger::Scenario.new
5   - scenario[/^active_?support$/] = version
6   - scenario[/^active_?record$/] = version
7   - scenario[/^action_?pack$/] = version
8   - scenario[/^action_?controller$/] = version
9   - scenario
10   -end
11   -
12   -Ginger.configure do |config|
13   - config.aliases["active_record"] = "activerecord"
14   - config.aliases["active_support"] = "activesupport"
15   - config.aliases["action_controller"] = "actionpack"
16   -
17   - rails_1_2_6 = Ginger::Scenario.new
18   - rails_1_2_6[/^active_?support$/] = "1.4.4"
19   - rails_1_2_6[/^active_?record$/] = "1.15.6"
20   - rails_1_2_6[/^action_?pack$/] = "1.13.6"
21   - rails_1_2_6[/^action_?controller$/] = "1.13.6"
22   -
23   - config.scenarios << rails_1_2_6
24   - config.scenarios << create_scenario("2.0.2")
25   - config.scenarios << create_scenario("2.1.2")
26   - config.scenarios << create_scenario("2.2.2")
27   - config.scenarios << create_scenario("2.3.2")
28   - # Rails 2.3.3 has broken params filtering
29   - # config.scenarios << create_scenario("2.3.3")
30   - config.scenarios << create_scenario("2.3.4")
31   -end
vendor/plugins/hoptoad_notifier/init.rb
... ... @@ -1 +0,0 @@
1   -require File.join(File.dirname(__FILE__), 'rails', 'init')
vendor/plugins/hoptoad_notifier/install.rb
... ... @@ -1 +0,0 @@
1   -puts IO.read(File.join(File.dirname(__FILE__), 'INSTALL'))
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier.rb
... ... @@ -1,150 +0,0 @@
1   -require 'net/http'
2   -require 'net/https'
3   -require 'rubygems'
4   -require 'active_support'
5   -require 'hoptoad_notifier/configuration'
6   -require 'hoptoad_notifier/notice'
7   -require 'hoptoad_notifier/sender'
8   -require 'hoptoad_notifier/catcher'
9   -require 'hoptoad_notifier/backtrace'
10   -
11   -# Plugin for applications to automatically post errors to the Hoptoad of their choice.
12   -module HoptoadNotifier
13   -
14   - VERSION = "2.0.18"
15   - API_VERSION = "2.0"
16   - LOG_PREFIX = "** [Hoptoad] "
17   -
18   - HEADERS = {
19   - 'Content-type' => 'text/xml',
20   - 'Accept' => 'text/xml, application/xml'
21   - }
22   -
23   - class << self
24   - # The sender object is responsible for delivering formatted data to the Hoptoad server.
25   - # Must respond to #send_to_hoptoad. See HoptoadNotifier::Sender.
26   - attr_accessor :sender
27   -
28   - # A Hoptoad configuration object. Must act like a hash and return sensible
29   - # values for all Hoptoad configuration options. See HoptoadNotifier::Configuration.
30   - attr_accessor :configuration
31   -
32   - # Tell the log that the Notifier is good to go
33   - def report_ready
34   - write_verbose_log("Notifier #{VERSION} ready to catch errors")
35   - end
36   -
37   - # Prints out the environment info to the log for debugging help
38   - def report_environment_info
39   - write_verbose_log("Environment Info: #{environment_info}")
40   - end
41   -
42   - # Prints out the response body from Hoptoad for debugging help
43   - def report_response_body(response)
44   - write_verbose_log("Response from Hoptoad: \n#{response}")
45   - end
46   -
47   - # Returns the Ruby version, Rails version, and current Rails environment
48   - def environment_info
49   - info = "[Ruby: #{RUBY_VERSION}]"
50   - info << " [Rails: #{::Rails::VERSION::STRING}]" if defined?(Rails)
51   - info << " [Env: #{configuration.environment_name}]"
52   - end
53   -
54   - # Writes out the given message to the #logger
55   - def write_verbose_log(message)
56   - logger.info LOG_PREFIX + message if logger
57   - end
58   -
59   - # Look for the Rails logger currently defined
60   - def logger
61   - if defined?(Rails.logger)
62   - Rails.logger
63   - elsif defined?(RAILS_DEFAULT_LOGGER)
64   - RAILS_DEFAULT_LOGGER
65   - end
66   - end
67   -
68   - # Call this method to modify defaults in your initializers.
69   - #
70   - # @example
71   - # HoptoadNotifier.configure do |config|
72   - # config.api_key = '1234567890abcdef'
73   - # config.secure = false
74   - # end
75   - def configure(silent = false)
76   - self.configuration ||= Configuration.new
77   - yield(configuration)
78   - self.sender = Sender.new(configuration)
79   - report_ready unless silent
80   - end
81   -
82   - # Sends an exception manually using this method, even when you are not in a controller.
83   - #
84   - # @param [Exception] exception The exception you want to notify Hoptoad about.
85   - # @param [Hash] opts Data that will be sent to Hoptoad.
86   - #
87   - # @option opts [String] :api_key The API key for this project. The API key is a unique identifier that Hoptoad uses for identification.
88   - # @option opts [String] :error_message The error returned by the exception (or the message you want to log).
89   - # @option opts [String] :backtrace A backtrace, usually obtained with +caller+.
90   - # @option opts [String] :request The controller's request object.
91   - # @option opts [String] :session The contents of the user's session.
92   - # @option opts [String] :environment ENV merged with the contents of the request's environment.
93   - def notify(exception, opts = {})
94   - send_notice(build_notice_for(exception, opts))
95   - end
96   -
97   - # Sends the notice unless it is one of the default ignored exceptions
98   - # @see HoptoadNotifier.notify
99   - def notify_or_ignore(exception, opts = {})
100   - notice = build_notice_for(exception, opts)
101   - send_notice(notice) unless notice.ignore?
102   - end
103   -
104   - def build_lookup_hash_for(exception, options = {})
105   - notice = build_notice_for(exception, options)
106   -
107   - result = {}
108   - result[:action] = notice.action rescue nil
109   - result[:component] = notice.component rescue nil
110   - result[:error_class] = notice.error_class if notice.error_class
111   - result[:environment_name] = 'production'
112   -
113   - unless notice.backtrace.lines.empty?
114   - result[:file] = notice.backtrace.lines.first.file
115   - result[:line_number] = notice.backtrace.lines.first.number
116   - end
117   -
118   - result
119   - end
120   -
121   - private
122   -
123   - def send_notice(notice)
124   - if configuration.public?
125   - sender.send_to_hoptoad(notice.to_xml)
126   - end
127   - end
128   -
129   - def build_notice_for(exception, opts = {})
130   - exception = unwrap_exception(exception)
131   - if exception.respond_to?(:to_hash)
132   - opts = opts.merge(exception)
133   - else
134   - opts = opts.merge(:exception => exception)
135   - end
136   - Notice.new(configuration.merge(opts))
137   - end
138   -
139   - def unwrap_exception(exception)
140   - if exception.respond_to?(:original_exception)
141   - exception.original_exception
142   - elsif exception.respond_to?(:continued_exception)
143   - exception.continued_exception
144   - else
145   - exception
146   - end
147   - end
148   - end
149   -end
150   -
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier/backtrace.rb
... ... @@ -1,99 +0,0 @@
1   -module HoptoadNotifier
2   - # Front end to parsing the backtrace for each notice
3   - class Backtrace
4   -
5   - # Handles backtrace parsing line by line
6   - class Line
7   -
8   - INPUT_FORMAT = %r{^([^:]+):(\d+)(?::in `([^']+)')?$}.freeze
9   -
10   - # The file portion of the line (such as app/models/user.rb)
11   - attr_reader :file
12   -
13   - # The line number portion of the line
14   - attr_reader :number
15   -
16   - # The method of the line (such as index)
17   - attr_reader :method
18   -
19   - # Parses a single line of a given backtrace
20   - # @param [String] unparsed_line The raw line from +caller+ or some backtrace
21   - # @return [Line] The parsed backtrace line
22   - def self.parse(unparsed_line)
23   - _, file, number, method = unparsed_line.match(INPUT_FORMAT).to_a
24   - new(file, number, method)
25   - end
26   -
27   - def initialize(file, number, method)
28   - self.file = file
29   - self.number = number
30   - self.method = method
31   - end
32   -
33   - # Reconstructs the line in a readable fashion
34   - def to_s
35   - "#{file}:#{number}:in `#{method}'"
36   - end
37   -
38   - def ==(other)
39   - to_s == other.to_s
40   - end
41   -
42   - def inspect
43   - "<Line:#{to_s}>"
44   - end
45   -
46   - private
47   -
48   - attr_writer :file, :number, :method
49   - end
50   -
51   - # holder for an Array of Backtrace::Line instances
52   - attr_reader :lines
53   -
54   - def self.parse(ruby_backtrace, opts = {})
55   - ruby_lines = split_multiline_backtrace(ruby_backtrace)
56   -
57   - filters = opts[:filters] || []
58   - filtered_lines = ruby_lines.to_a.map do |line|
59   - filters.inject(line) do |line, proc|
60   - proc.call(line)
61   - end
62   - end.compact
63   -
64   - lines = filtered_lines.collect do |unparsed_line|
65   - Line.parse(unparsed_line)
66   - end
67   -
68   - instance = new(lines)
69   - end
70   -
71   - def initialize(lines)
72   - self.lines = lines
73   - end
74   -
75   - def inspect
76   - "<Backtrace: " + lines.collect { |line| line.inspect }.join(", ") + ">"
77   - end
78   -
79   - def ==(other)
80   - if other.respond_to?(:lines)
81   - lines == other.lines
82   - else
83   - false
84   - end
85   - end
86   -
87   - private
88   -
89   - attr_writer :lines
90   -
91   - def self.split_multiline_backtrace(backtrace)
92   - if backtrace.to_a.size == 1
93   - backtrace.to_a.first.split(/\n\s*/)
94   - else
95   - backtrace
96   - end
97   - end
98   - end
99   -end
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier/catcher.rb
... ... @@ -1,95 +0,0 @@
1   -module HoptoadNotifier
2   - # Include this module in Controllers in which you want to be notified of errors.
3   - module Catcher
4   -
5   - # Sets up an alias chain to catch exceptions when Rails does
6   - def self.included(base) #:nodoc:
7   - if base.instance_methods.map(&:to_s).include? 'rescue_action_in_public' and !base.instance_methods.map(&:to_s).include? 'rescue_action_in_public_without_hoptoad'
8   - base.send(:alias_method, :rescue_action_in_public_without_hoptoad, :rescue_action_in_public)
9   - base.send(:alias_method, :rescue_action_in_public, :rescue_action_in_public_with_hoptoad)
10   - base.send(:alias_method, :rescue_action_locally_without_hoptoad, :rescue_action_locally)
11   - base.send(:alias_method, :rescue_action_locally, :rescue_action_locally_with_hoptoad)
12   - end
13   - end
14   -
15   - private
16   -
17   - # Overrides the rescue_action method in ActionController::Base, but does not inhibit
18   - # any custom processing that is defined with Rails 2's exception helpers.
19   - def rescue_action_in_public_with_hoptoad(exception)
20   - unless hoptoad_ignore_user_agent?
21   - HoptoadNotifier.notify_or_ignore(exception, hoptoad_request_data)
22   - end
23   - rescue_action_in_public_without_hoptoad(exception)
24   - end
25   -
26   - def rescue_action_locally_with_hoptoad(exception)
27   - result = rescue_action_locally_without_hoptoad(exception)
28   -
29   - if HoptoadNotifier.configuration.development_lookup
30   - path = File.join(File.dirname(__FILE__), '..', 'templates', 'rescue.erb')
31   - notice = HoptoadNotifier.build_lookup_hash_for(exception, hoptoad_request_data)
32   -
33   - result << @template.render(
34   - :file => path,
35   - :use_full_path => false,
36   - :locals => { :host => HoptoadNotifier.configuration.host,
37   - :api_key => HoptoadNotifier.configuration.api_key,
38   - :notice => notice })
39   - end
40   -
41   - result
42   - end
43   -
44   - # This method should be used for sending manual notifications while you are still
45   - # inside the controller. Otherwise it works like HoptoadNotifier.notify.
46   - def notify_hoptoad(hash_or_exception)
47   - unless consider_all_requests_local || local_request?
48   - HoptoadNotifier.notify(hash_or_exception, hoptoad_request_data)
49   - end
50   - end
51   -
52   - def hoptoad_ignore_user_agent? #:nodoc:
53   - # Rails 1.2.6 doesn't have request.user_agent, so check for it here
54   - user_agent = request.respond_to?(:user_agent) ? request.user_agent : request.env["HTTP_USER_AGENT"]
55   - HoptoadNotifier.configuration.ignore_user_agent.flatten.any? { |ua| ua === user_agent }
56   - end
57   -
58   - def hoptoad_request_data
59   - { :parameters => hoptoad_filter_if_filtering(params.to_hash),
60   - :session_data => hoptoad_session_data,
61   - :controller => params[:controller],
62   - :action => params[:action],
63   - :url => hoptoad_request_url,
64   - :cgi_data => hoptoad_filter_if_filtering(request.env),
65   - :environment_vars => hoptoad_filter_if_filtering(ENV) }
66   - end
67   -
68   - def hoptoad_filter_if_filtering(hash)
69   - if respond_to?(:filter_parameters)
70   - filter_parameters(hash) rescue hash
71   - else
72   - hash
73   - end
74   - end
75   -
76   - def hoptoad_session_data
77   - if session.respond_to?(:to_hash)
78   - session.to_hash
79   - else
80   - session.data
81   - end
82   - end
83   -
84   - def hoptoad_request_url
85   - url = "#{request.protocol}#{request.host}"
86   -
87   - unless [80, 443].include?(request.port)
88   - url << ":#{request.port}"
89   - end
90   -
91   - url << request.request_uri
92   - url
93   - end
94   - end
95   -end
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier/configuration.rb
... ... @@ -1,229 +0,0 @@
1   -module HoptoadNotifier
2   - # Used to set up and modify settings for the notifier.
3   - class Configuration
4   -
5   - OPTIONS = [:api_key, :backtrace_filters, :development_environments,
6   - :development_lookup, :environment_name, :host,
7   - :http_open_timeout, :http_read_timeout, :ignore, :ignore_by_filters,
8   - :ignore_user_agent, :notifier_name, :notifier_url, :notifier_version,
9   - :params_filters, :project_root, :port, :protocol, :proxy_host,
10   - :proxy_pass, :proxy_port, :proxy_user, :secure].freeze
11   -
12   - # The API key for your project, found on the project edit form.
13   - attr_accessor :api_key
14   -
15   - # The host to connect to (defaults to hoptoadapp.com).
16   - attr_accessor :host
17   -
18   - # The port on which your Hoptoad server runs (defaults to 443 for secure
19   - # connections, 80 for insecure connections).
20   - attr_accessor :port
21   -
22   - # +true+ for https connections, +false+ for http connections.
23   - attr_accessor :secure
24   -
25   - # The HTTP open timeout in seconds (defaults to 2).
26   - attr_accessor :http_open_timeout
27   -
28   - # The HTTP read timeout in seconds (defaults to 5).
29   - attr_accessor :http_read_timeout
30   -
31   - # The hostname of your proxy server (if using a proxy)
32   - attr_accessor :proxy_host
33   -
34   - # The port of your proxy server (if using a proxy)
35   - attr_accessor :proxy_port
36   -
37   - # The username to use when logging into your proxy server (if using a proxy)
38   - attr_accessor :proxy_user
39   -
40   - # The password to use when logging into your proxy server (if using a proxy)
41   - attr_accessor :proxy_pass
42   -
43   - # A list of parameters that should be filtered out of what is sent to Hoptoad.
44   - # By default, all "password" attributes will have their contents replaced.
45   - attr_reader :params_filters
46   -
47   - # A list of filters for cleaning and pruning the backtrace. See #filter_backtrace.
48   - attr_reader :backtrace_filters
49   -
50   - # A list of filters for ignoring exceptions. See #ignore_by_filter.
51   - attr_reader :ignore_by_filters
52   -
53   - # A list of exception classes to ignore. The array can be appended to.
54   - attr_reader :ignore
55   -
56   - # A list of user agents that are being ignored. The array can be appended to.
57   - attr_reader :ignore_user_agent
58   -
59   - # A list of environments in which notifications should not be sent.
60   - attr_accessor :development_environments
61   -
62   - # +true+ if you want to check for production errors matching development errors, +false+ otherwise.
63   - attr_accessor :development_lookup
64   -
65   - # The name of the environment the application is running in
66   - attr_accessor :environment_name
67   -
68   - # The path to the project in which the error occurred, such as the RAILS_ROOT
69   - attr_accessor :project_root
70   -
71   - # The name of the notifier library being used to send notifications (such as "Hoptoad Notifier")
72   - attr_accessor :notifier_name
73   -
74   - # The version of the notifier library being used to send notifications (such as "1.0.2")
75   - attr_accessor :notifier_version
76   -
77   - # The url of the notifier library being used to send notifications
78   - attr_accessor :notifier_url
79   -
80   - DEFAULT_PARAMS_FILTERS = %w(password password_confirmation).freeze
81   -
82   - DEFAULT_BACKTRACE_FILTERS = [
83   - lambda { |line|
84   - if defined?(HoptoadNotifier.configuration.project_root)
85   - line.gsub(/#{HoptoadNotifier.configuration.project_root}/, "[PROJECT_ROOT]")
86   - else
87   - line
88   - end
89   - },
90   - lambda { |line| line.gsub(/^\.\//, "") },
91   - lambda { |line|
92   - if defined?(Gem)
93   - Gem.path.inject(line) do |line, path|
94   - line.gsub(/#{path}/, "[GEM_ROOT]")
95   - end
96   - end
97   - },
98   - lambda { |line| line if line !~ %r{lib/hoptoad_notifier} }
99   - ].freeze
100   -
101   - IGNORE_DEFAULT = ['ActiveRecord::RecordNotFound',
102   - 'ActionController::RoutingError',
103   - 'ActionController::InvalidAuthenticityToken',
104   - 'CGI::Session::CookieStore::TamperedWithCookie',
105   - 'ActionController::UnknownAction']
106   -
107   - # Some of these don't exist for Rails 1.2.*, so we have to consider that.
108   - IGNORE_DEFAULT.map!{|e| eval(e) rescue nil }.compact!
109   - IGNORE_DEFAULT.freeze
110   -
111   - alias_method :secure?, :secure
112   -
113   - def initialize
114   - @secure = false
115   - @host = 'hoptoadapp.com'
116   - @http_open_timeout = 2
117   - @http_read_timeout = 5
118   - @params_filters = DEFAULT_PARAMS_FILTERS.dup
119   - @backtrace_filters = DEFAULT_BACKTRACE_FILTERS.dup
120   - @ignore_by_filters = []
121   - @ignore = IGNORE_DEFAULT.dup
122   - @ignore_user_agent = []
123   - @development_environments = %w(development test cucumber)
124   - @development_lookup = true
125   - @notifier_name = 'Hoptoad Notifier'
126   - @notifier_version = VERSION
127   - @notifier_url = 'http://hoptoadapp.com'
128   - end
129   -
130   - # Takes a block and adds it to the list of backtrace filters. When the filters
131   - # run, the block will be handed each line of the backtrace and can modify
132   - # it as necessary.
133   - #
134   - # @example
135   - # config.filter_bracktrace do |line|
136   - # line.gsub(/^#{Rails.root}/, "[RAILS_ROOT]")
137   - # end
138   - #
139   - # @param [Proc] block The new backtrace filter.
140   - # @yieldparam [String] line A line in the backtrace.
141   - def filter_backtrace(&block)
142   - self.backtrace_filters << block
143   - end
144   -
145   - # Takes a block and adds it to the list of ignore filters.
146   - # When the filters run, the block will be handed the exception.
147   - # @example
148   - # config.ignore_by_filter do |exception_data|
149   - # true if exception_data[:error_class] == "RuntimeError"
150   - # end
151   - #
152   - # @param [Proc] block The new ignore filter
153   - # @yieldparam [Hash] data The exception data given to +HoptoadNotifier.notify+
154   - # @yieldreturn [Boolean] If the block returns true the exception will be ignored, otherwise it will be processed by hoptoad.
155   - def ignore_by_filter(&block)
156   - self.ignore_by_filters << block
157   - end
158   -
159   - # Overrides the list of default ignored errors.
160   - #
161   - # @param [Array<Exception>] names A list of exceptions to ignore.
162   - def ignore_only=(names)
163   - @ignore = [names].flatten
164   - end
165   -
166   - # Overrides the list of default ignored user agents
167   - #
168   - # @param [Array<String>] A list of user agents to ignore
169   - def ignore_user_agent_only=(names)
170   - @ignore_user_agent = [names].flatten
171   - end
172   -
173   - # Allows config options to be read like a hash
174   - #
175   - # @param [Symbol] option Key for a given attribute
176   - def [](option)
177   - send(option)
178   - end
179   -
180   - # Returns a hash of all configurable options
181   - def to_hash
182   - OPTIONS.inject({}) do |hash, option|
183   - hash.merge(option.to_sym => send(option))
184   - end
185   - end
186   -
187   - # Returns a hash of all configurable options merged with +hash+
188   - #
189   - # @param [Hash] hash A set of configuration options that will take precedence over the defaults
190   - def merge(hash)
191   - to_hash.merge(hash)
192   - end
193   -
194   - # Determines if the notifier will send notices.
195   - # @return [Boolean] Returns +false+ if in a development environment, +true+ otherwise.
196   - def public?
197   - !development_environments.include?(environment_name)
198   - end
199   -
200   - def port
201   - @port || default_port
202   - end
203   -
204   - def protocol
205   - if secure?
206   - 'https'
207   - else
208   - 'http'
209   - end
210   - end
211   -
212   - def environment_filters
213   - warn 'config.environment_filters has been deprecated and has no effect.'
214   - []
215   - end
216   -
217   - private
218   -
219   - def default_port
220   - if secure?
221   - 443
222   - else
223   - 80
224   - end
225   - end
226   -
227   - end
228   -
229   -end
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier/notice.rb
... ... @@ -1,295 +0,0 @@
1   -module HoptoadNotifier
2   - class Notice
3   -
4   - # The exception that caused this notice, if any
5   - attr_reader :exception
6   -
7   - # The API key for the project to which this notice should be sent
8   - attr_reader :api_key
9   -
10   - # The backtrace from the given exception or hash.
11   - attr_reader :backtrace
12   -
13   - # The name of the class of error (such as RuntimeError)
14   - attr_reader :error_class
15   -
16   - # The name of the server environment (such as "production")
17   - attr_reader :environment_name
18   -
19   - # CGI variables such as HTTP_METHOD
20   - attr_reader :cgi_data
21   -
22   - # The message from the exception, or a general description of the error
23   - attr_reader :error_message
24   -
25   - # See Configuration#backtrace_filters
26   - attr_reader :backtrace_filters
27   -
28   - # See Configuration#params_filters
29   - attr_reader :params_filters
30   -
31   - # A hash of parameters from the query string or post body.
32   - attr_reader :parameters
33   - alias_method :params, :parameters
34   -
35   - # The component (if any) which was used in this request (usually the controller)
36   - attr_reader :component
37   - alias_method :controller, :component
38   -
39   - # The action (if any) that was called in this request
40   - attr_reader :action
41   -
42   - # A hash of session data from the request
43   - attr_reader :session_data
44   -
45   - # The path to the project that caused the error (usually RAILS_ROOT)
46   - attr_reader :project_root
47   -
48   - # The URL at which the error occurred (if any)
49   - attr_reader :url
50   -
51   - # See Configuration#ignore
52   - attr_reader :ignore
53   -
54   - # See Configuration#ignore_by_filters
55   - attr_reader :ignore_by_filters
56   -
57   - # The name of the notifier library sending this notice, such as "Hoptoad Notifier"
58   - attr_reader :notifier_name
59   -
60   - # The version number of the notifier library sending this notice, such as "2.1.3"
61   - attr_reader :notifier_version
62   -
63   - # A URL for more information about the notifier library sending this notice
64   - attr_reader :notifier_url
65   -
66   - def initialize(args)
67   - self.args = args
68   - self.exception = args[:exception]
69   - self.api_key = args[:api_key]
70   - self.project_root = args[:project_root]
71   - self.url = args[:url]
72   -
73   - self.notifier_name = args[:notifier_name]
74   - self.notifier_version = args[:notifier_version]
75   - self.notifier_url = args[:notifier_url]
76   -
77   - self.ignore = args[:ignore] || []
78   - self.ignore_by_filters = args[:ignore_by_filters] || []
79   - self.backtrace_filters = args[:backtrace_filters] || []
80   - self.params_filters = args[:params_filters] || []
81   - self.parameters = args[:parameters] || {}
82   - self.component = args[:component] || args[:controller]
83   - self.action = args[:action]
84   -
85   - self.environment_name = args[:environment_name]
86   - self.cgi_data = args[:cgi_data]
87   - self.backtrace = Backtrace.parse(exception_attribute(:backtrace, caller))
88   - self.error_class = exception_attribute(:error_class) {|exception| exception.class.name }
89   - self.error_message = exception_attribute(:error_message, 'Notification') do |exception|
90   - "#{exception.class.name}: #{exception.message}"
91   - end
92   -
93   - find_session_data
94   - clean_params
95   - end
96   -
97   - # Converts the given notice to XML
98   - def to_xml
99   - builder = Builder::XmlMarkup.new
100   - builder.instruct!
101   - xml = builder.notice(:version => HoptoadNotifier::API_VERSION) do |notice|
102   - notice.tag!("api-key", api_key)
103   - notice.notifier do |notifier|
104   - notifier.name(notifier_name)
105   - notifier.version(notifier_version)
106   - notifier.url(notifier_url)
107   - end
108   - notice.error do |error|
109   - error.tag!('class', error_class)
110   - error.message(error_message)
111   - error.backtrace do |backtrace|
112   - self.backtrace.lines.each do |line|
113   - backtrace.line(:number => line.number,
114   - :file => line.file,
115   - :method => line.method)
116   - end
117   - end
118   - end
119   - if url ||
120   - controller ||
121   - action ||
122   - !parameters.blank? ||
123   - !cgi_data.blank? ||
124   - !session_data.blank?
125   - notice.request do |request|
126   - request.url(url)
127   - request.component(controller)
128   - request.action(action)
129   - unless parameters.blank?
130   - request.params do |params|
131   - xml_vars_for(params, parameters)
132   - end
133   - end
134   - unless session_data.blank?
135   - request.session do |session|
136   - xml_vars_for(session, session_data)
137   - end
138   - end
139   - unless cgi_data.blank?
140   - request.tag!("cgi-data") do |cgi_datum|
141   - xml_vars_for(cgi_datum, cgi_data)
142   - end
143   - end
144   - end
145   - end
146   - notice.tag!("server-environment") do |env|
147   - env.tag!("project-root", project_root)
148   - env.tag!("environment-name", environment_name)
149   - end
150   - end
151   - xml.to_s
152   - end
153   -
154   - # Determines if this notice should be ignored
155   - def ignore?
156   - ignored_class_names.include?(error_class) ||
157   - ignore_by_filters.any? {|filter| filter.call(self) }
158   - end
159   -
160   - # Allows properties to be accessed using a hash-like syntax
161   - #
162   - # @example
163   - # notice[:error_message]
164   - # @param [String] method The given key for an attribute
165   - # @return The attribute value, or self if given +:request+
166   - def [](method)
167   - case method
168   - when :request
169   - self
170   - else
171   - send(method)
172   - end
173   - end
174   -
175   - private
176   -
177   - attr_writer :exception, :api_key, :backtrace, :error_class, :error_message,
178   - :backtrace_filters, :parameters, :params_filters,
179   - :environment_filters, :session_data, :project_root, :url, :ignore,
180   - :ignore_by_filters, :notifier_name, :notifier_url, :notifier_version,
181   - :component, :action, :cgi_data, :environment_name
182   -
183   - # Arguments given in the initializer
184   - attr_accessor :args
185   -
186   - # Gets a property named +attribute+ of an exception, either from an actual
187   - # exception or a hash.
188   - #
189   - # If an exception is available, #from_exception will be used. Otherwise,
190   - # a key named +attribute+ will be used from the #args.
191   - #
192   - # If no exception or hash key is available, +default+ will be used.
193   - def exception_attribute(attribute, default = nil, &block)
194   - (exception && from_exception(attribute, &block)) || args[attribute] || default
195   - end
196   -
197   - # Gets a property named +attribute+ from an exception.
198   - #
199   - # If a block is given, it will be used when getting the property from an
200   - # exception. The block should accept and exception and return the value for
201   - # the property.
202   - #
203   - # If no block is given, a method with the same name as +attribute+ will be
204   - # invoked for the value.
205   - def from_exception(attribute)
206   - if block_given?
207   - yield(exception)
208   - else
209   - exception.send(attribute)
210   - end
211   - end
212   -
213   - # Removes non-serializable data from the given attribute.
214   - # See #clean_unserializable_data
215   - def clean_unserializable_data_from(attribute)
216   - self.send(:"#{attribute}=", clean_unserializable_data(send(attribute)))
217   - end
218   -
219   - # Removes non-serializable data. Allowed data types are strings, arrays,
220   - # and hashes. All other types are converted to strings.
221   - # TODO: move this onto Hash
222   - def clean_unserializable_data(data)
223   - if data.respond_to?(:to_hash)
224   - data.to_hash.inject({}) do |result, (key, value)|
225   - result.merge(key => clean_unserializable_data(value))
226   - end
227   - elsif data.respond_to?(:to_ary)
228   - data.collect do |value|
229   - clean_unserializable_data(value)
230   - end
231   - else
232   - data.to_s
233   - end
234   - end
235   -
236   - # Replaces the contents of params that match params_filters.
237   - # TODO: extract this to a different class
238   - def clean_params
239   - clean_unserializable_data_from(:parameters)
240   - filter(parameters)
241   - if cgi_data
242   - clean_unserializable_data_from(:cgi_data)
243   - filter(cgi_data)
244   - end
245   - if session_data
246   - clean_unserializable_data_from(:session_data)
247   - end
248   - end
249   -
250   - def filter(hash)
251   - if params_filters
252   - hash.each do |key, value|
253   - if filter_key?(key)
254   - hash[key] = "[FILTERED]"
255   - elsif value.respond_to?(:to_hash)
256   - filter(hash[key])
257   - end
258   - end
259   - end
260   - end
261   -
262   - def filter_key?(key)
263   - params_filters.any? do |filter|
264   - key.to_s.include?(filter)
265   - end
266   - end
267   -
268   - def find_session_data
269   - self.session_data = args[:session_data] || args[:session] || {}
270   - self.session_data = session_data[:data] if session_data[:data]
271   - end
272   -
273   - # Converts the mixed class instances and class names into just names
274   - # TODO: move this into Configuration or another class
275   - def ignored_class_names
276   - ignore.collect do |string_or_class|
277   - if string_or_class.respond_to?(:name)
278   - string_or_class.name
279   - else
280   - string_or_class
281   - end
282   - end
283   - end
284   -
285   - def xml_vars_for(builder, hash)
286   - hash.each do |key, value|
287   - if value.respond_to?(:to_hash)
288   - builder.var(:key => key){|b| xml_vars_for(b, value.to_hash) }
289   - else
290   - builder.var(value.to_s, :key => key)
291   - end
292   - end
293   - end
294   - end
295   -end
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier/sender.rb
... ... @@ -1,63 +0,0 @@
1   -module HoptoadNotifier
2   - # Sends out the notice to Hoptoad
3   - class Sender
4   -
5   - NOTICES_URI = '/notifier_api/v2/notices/'.freeze
6   -
7   - def initialize(options = {})
8   - [:proxy_host, :proxy_port, :proxy_user, :proxy_pass, :protocol,
9   - :host, :port, :secure, :http_open_timeout, :http_read_timeout].each do |option|
10   - instance_variable_set("@#{option}", options[option])
11   - end
12   - end
13   -
14   - # Sends the notice data off to Hoptoad for processing.
15   - #
16   - # @param [String] data The XML notice to be sent off
17   - def send_to_hoptoad(data)
18   - logger.debug { "Sending request to #{url.to_s}:\n#{data}" }
19   -
20   - http =
21   - Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass).
22   - new(url.host, url.port)
23   -
24   - http.read_timeout = http_read_timeout
25   - http.open_timeout = http_open_timeout
26   - http.use_ssl = secure
27   -
28   - response = begin
29   - http.post(url.path, data, HEADERS)
30   - rescue TimeoutError => e
31   - log :error, "Timeout while contacting the Hoptoad server."
32   - nil
33   - end
34   -
35   - case response
36   - when Net::HTTPSuccess then
37   - log :info, "Success: #{response.class}", response
38   - else
39   - log :error, "Failure: #{response.class}", response
40   - end
41   - end
42   -
43   - private
44   -
45   - attr_reader :proxy_host, :proxy_port, :proxy_user, :proxy_pass, :protocol,
46   - :host, :port, :secure, :http_open_timeout, :http_read_timeout
47   -
48   - def url
49   - URI.parse("#{protocol}://#{host}:#{port}").merge(NOTICES_URI)
50   - end
51   -
52   - def log(level, message, response = nil)
53   - logger.send level, LOG_PREFIX + message if logger
54   - HoptoadNotifier.report_environment_info
55   - HoptoadNotifier.report_response_body(response.body) if response && response.respond_to?(:body)
56   - end
57   -
58   - def logger
59   - HoptoadNotifier.logger
60   - end
61   -
62   - end
63   -end
vendor/plugins/hoptoad_notifier/lib/hoptoad_tasks.rb
... ... @@ -1,37 +0,0 @@
1   -require 'net/http'
2   -require 'uri'
3   -require 'active_support'
4   -
5   -# Capistrano tasks for notifying Hoptoad of deploys
6   -module HoptoadTasks
7   -
8   - # Alerts Hoptoad of a deploy.
9   - #
10   - # @param [Hash] opts Data about the deploy that is set to Hoptoad
11   - #
12   - # @option opts [String] :rails_env Environment of the deploy (production, staging)
13   - # @option opts [String] :scm_revision The given revision/sha that is being deployed
14   - # @option opts [String] :scm_repository Address of your repository to help with code lookups
15   - # @option opts [String] :local_username Who is deploying
16   - def self.deploy(opts = {})
17   - if HoptoadNotifier.configuration.api_key.blank?
18   - puts "I don't seem to be configured with an API key. Please check your configuration."
19   - return false
20   - end
21   -
22   - if opts[:rails_env].blank?
23   - puts "I don't know to which Rails environment you are deploying (use the TO=production option)."
24   - return false
25   - end
26   -
27   - params = {'api_key' => opts.delete(:api_key) ||
28   - HoptoadNotifier.configuration.api_key}
29   - opts.each {|k,v| params["deploy[#{k}]"] = v }
30   -
31   - url = URI.parse("http://#{HoptoadNotifier.configuration.host || 'hoptoadapp.com'}/deploys.txt")
32   - response = Net::HTTP.post_form(url, params)
33   - puts response.body
34   - return Net::HTTPSuccess === response
35   - end
36   -end
37   -
vendor/plugins/hoptoad_notifier/lib/templates/rescue.erb
... ... @@ -1,91 +0,0 @@
1   -<script type="text/javascript">
2   -var Hoptoad = {
3   - host : <%= host.to_json %>,
4   - api_key : <%= api_key.to_json %>,
5   - notice : <%= notice.to_json %>,
6   - message : 'This error exists in production!',
7   -
8   - initialize: function() {
9   - if (this.initialized) {
10   - return;
11   - } else {
12   - this.initialized = true;
13   - }
14   -
15   - var data = [];
16   -
17   - for (var key in this.notice) {
18   - data[data.length] = 'notice[' + key + ']=' + this.notice[key];
19   - }
20   -
21   - data[data.length] = 'notice[api_key]=' + this.api_key;
22   - data[data.length] = 'callback=Hoptoad.onSuccess';
23   - data[data.length] = '_=' + (new Date()).getTime();
24   -
25   - var head = document.getElementsByTagName('head')[0];
26   - var done = false;
27   -
28   - var
29   - script = document.createElement('script');
30   - script.src = 'http://' + this.host + '/notices_api/v1/notices/exist?' +
31   - data.join('&');
32   - script.type = 'text/javascript';
33   - script.onload = script.onreadystatechange = function(){
34   - if (!done && (!this.readyState ||
35   - this.readyState == 'loaded' || this.readyState == 'complete')) {
36   -
37   - done = true;
38   -
39   - // Handle memory leak in IE. (via jQuery)
40   - script.onload = script.onreadystatechange = null;
41   - head.removeChild(script);
42   - }
43   - };
44   -
45   - head.appendChild(script);
46   - },
47   -
48   - onSuccess: function(error) {
49   - var body = document.getElementsByTagName('body')[0];
50   - var text = document.createTextNode(this.message);
51   - var element = document.createElement('a');
52   -
53   - element.id = 'hoptoad';
54   - element.href = 'http://' + error.subdomain + '.' + this.host +
55   - '/projects/' + error.project_id + '/errors/' + error.id;
56   - element.appendChild(text);
57   -
58   - body.insertBefore(element, body.firstChild);
59   -
60   - var h1 = document.getElementsByTagName('h1')[0];
61   - var pre = document.getElementsByTagName('pre')[0];
62   - var wrapper = document.createElement('div');
63   -
64   - wrapper.id = 'wrapper';
65   - wrapper.appendChild(h1);
66   - wrapper.appendChild(pre);
67   -
68   - body.insertBefore(wrapper, body.children[1]);
69   - }
70   -};
71   -
72   -window.onload = function() {
73   - Hoptoad.initialize.apply(Hoptoad);
74   -};
75   -</script>
76   -
77   -<style type="text/css">
78   -#hoptoad {
79   - background: #FFF url(http://hoptoadapp.com/images/fell-off-the-toad.gif) no-repeat top right;
80   - color: #F00;
81   - padding: 45px 101px 45px 12px;
82   - font-size: 14px;
83   - font-weight: bold;
84   - display: block;
85   - float: right;
86   -}
87   -
88   -#wrapper {
89   - padding-right: 360px;
90   -}
91   -</style>
vendor/plugins/hoptoad_notifier/rails/init.rb
... ... @@ -1,8 +0,0 @@
1   -if defined?(ActionController::Base) && !ActionController::Base.include?(HoptoadNotifier::Catcher)
2   - ActionController::Base.send(:include, HoptoadNotifier::Catcher)
3   -end
4   -
5   -HoptoadNotifier.configure(true) do |config|
6   - config.environment_name = RAILS_ENV
7   - config.project_root = RAILS_ROOT
8   -end
vendor/plugins/hoptoad_notifier/recipes/hoptoad.rb
... ... @@ -1,24 +0,0 @@
1   -# When Hoptoad is installed as a plugin this is loaded automatically.
2   -#
3   -# When Hoptoad installed as a gem, you need to add
4   -# require 'hoptoad_notifier/recipes/hoptoad'
5   -# to your deploy.rb
6   -#
7   -# Defines deploy:notify_hoptoad which will send information about the deploy to Hoptoad.
8   -#
9   -after "deploy", "deploy:notify_hoptoad"
10   -after "deploy:migrations", "deploy:notify_hoptoad"
11   -
12   -namespace :deploy do
13   - desc "Notify Hoptoad of the deployment"
14   - task :notify_hoptoad, :except => { :no_release => true } do
15   - rails_env = fetch(:hoptoad_env, fetch(:rails_env, "production"))
16   - local_user = ENV['USER'] || ENV['USERNAME']
17   - executable = RUBY_PLATFORM.downcase.include?('mswin') ? 'rake.bat' : 'rake'
18   - notify_command = "#{executable} hoptoad:deploy TO=#{rails_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}"
19   - notify_command << " API_KEY=#{ENV['API_KEY']}" if ENV['API_KEY']
20   - puts "Notifying Hoptoad of Deploy (#{notify_command})"
21   - `#{notify_command}`
22   - puts "Hoptoad Notification Complete."
23   - end
24   -end
vendor/plugins/hoptoad_notifier/script/integration_test.rb
... ... @@ -1,38 +0,0 @@
1   -#!/usr/bin/env ruby
2   -
3   -require 'logger'
4   -require 'fileutils'
5   -
6   -RAILS_ENV = "production"
7   -RAILS_ROOT = FileUtils.pwd
8   -RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
9   -
10   -$: << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
11   -require 'hoptoad_notifier'
12   -require 'rails/init'
13   -
14   -fail "Please supply an API Key as the first argument" if ARGV.empty?
15   -
16   -host = ARGV[1]
17   -host ||= "hoptoadapp.com"
18   -
19   -secure = (ARGV[2] == "secure")
20   -
21   -exception = begin
22   - raise "Testing hoptoad notifier with secure = #{secure}. If you can see this, it works."
23   - rescue => foo
24   - foo
25   - end
26   -
27   -HoptoadNotifier.configure do |config|
28   - config.secure = secure
29   - config.host = host
30   - config.api_key = ARGV.first
31   -end
32   -puts "Configuration:"
33   -HoptoadNotifier.configuration.to_hash.each do |key, value|
34   - puts sprintf("%25s: %s", key.to_s, value.inspect.slice(0, 55))
35   -end
36   -puts "Sending #{secure ? "" : "in"}secure notification to project with key #{ARGV.first}"
37   -HoptoadNotifier.notify(exception)
38   -
vendor/plugins/hoptoad_notifier/tasks/hoptoad_notifier_tasks.rake
... ... @@ -1,89 +0,0 @@
1   -namespace :hoptoad do
2   - desc "Notify Hoptoad of a new deploy."
3   - task :deploy => :environment do
4   - require 'hoptoad_tasks'
5   - HoptoadTasks.deploy(:rails_env => ENV['TO'],
6   - :scm_revision => ENV['REVISION'],
7   - :scm_repository => ENV['REPO'],
8   - :local_username => ENV['USER'],
9   - :api_key => ENV['API_KEY'])
10   - end
11   -
12   - task :log_stdout do
13   - require 'logger'
14   - RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
15   - end
16   -
17   - desc "Verify your plugin installation by sending a test exception to the hoptoad service"
18   - task :test => ['hoptoad:log_stdout', :environment] do
19   - RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
20   -
21   - require 'action_controller/test_process'
22   - require 'app/controllers/application' if File.exists?('app/controllers/application.rb')
23   -
24   - request = ActionController::TestRequest.new
25   - response = ActionController::TestResponse.new
26   -
27   - class HoptoadTestingException < RuntimeError; end
28   -
29   - unless HoptoadNotifier.configuration.api_key
30   - puts "Hoptoad needs an API key configured! Check the README to see how to add it."
31   - exit
32   - end
33   -
34   - HoptoadNotifier.configuration.development_environments = []
35   -
36   - in_controller = ApplicationController.included_modules.include? HoptoadNotifier::Catcher
37   - in_base = ActionController::Base.included_modules.include? HoptoadNotifier::Catcher
38   - if !in_controller || !in_base
39   - puts "HoptoadNotifier::Catcher must be included inside your ApplicationController class."
40   - exit
41   - end
42   -
43   - puts "Configuration:"
44   - HoptoadNotifier.configuration.to_hash.each do |key, value|
45   - puts sprintf("%25s: %s", key.to_s, value.inspect.slice(0, 55))
46   - end
47   -
48   - puts 'Setting up the Controller.'
49   - class ApplicationController
50   - # This is to bypass any filters that may prevent access to the action.
51   - prepend_before_filter :test_hoptoad
52   - def test_hoptoad
53   - puts "Raising '#{exception_class.name}' to simulate application failure."
54   - raise exception_class.new, 'Testing hoptoad via "rake hoptoad:test". If you can see this, it works.'
55   - end
56   -
57   - def rescue_action exception
58   - rescue_action_in_public exception
59   - end
60   -
61   - # Ensure we actually have an action to go to.
62   - def verify; end
63   -
64   - def consider_all_requests_local
65   - false
66   - end
67   -
68   - def local_request?
69   - false
70   - end
71   -
72   - def exception_class
73   - exception_name = ENV['EXCEPTION'] || "HoptoadTestingException"
74   - Object.const_get(exception_name)
75   - rescue
76   - Object.const_set(exception_name, Class.new(Exception))
77   - end
78   -
79   - def logger
80   - nil
81   - end
82   - end
83   -
84   - puts 'Processing request.'
85   - class HoptoadVerificationController < ApplicationController; end
86   - HoptoadVerificationController.new.process(request, response)
87   - end
88   -end
89   -
vendor/plugins/hoptoad_notifier/test/backtrace_test.rb
... ... @@ -1,94 +0,0 @@
1   -require File.dirname(__FILE__) + '/helper'
2   -
3   -class BacktraceTest < Test::Unit::TestCase
4   -
5   - should "parse a backtrace into lines" do
6   - array = [
7   - "app/models/user.rb:13:in `magic'",
8   - "app/controllers/users_controller.rb:8:in `index'"
9   - ]
10   -
11   - backtrace = HoptoadNotifier::Backtrace.parse(array)
12   -
13   - line = backtrace.lines.first
14   - assert_equal '13', line.number
15   - assert_equal 'app/models/user.rb', line.file
16   - assert_equal 'magic', line.method
17   -
18   - line = backtrace.lines.last
19   - assert_equal '8', line.number
20   - assert_equal 'app/controllers/users_controller.rb', line.file
21   - assert_equal 'index', line.method
22   - end
23   -
24   - should "be equal with equal lines" do
25   - one = build_backtrace_array
26   - two = one.dup
27   - assert_equal one, two
28   -
29   - assert_equal HoptoadNotifier::Backtrace.parse(one), HoptoadNotifier::Backtrace.parse(two)
30   - end
31   -
32   - should "parse massive one-line exceptions into multiple lines" do
33   - original_backtrace = HoptoadNotifier::Backtrace.
34   - parse(["one:1:in `one'\n two:2:in `two'\n three:3:in `three`"])
35   - expected_backtrace = HoptoadNotifier::Backtrace.
36   - parse(["one:1:in `one'", "two:2:in `two'", "three:3:in `three`"])
37   -
38   - assert_equal expected_backtrace, original_backtrace
39   - end
40   -
41   - context "with a project root" do
42   - setup do
43   - @project_root = '/some/path'
44   - HoptoadNotifier.configure {|config| config.project_root = @project_root }
45   - end
46   -
47   - teardown do
48   - reset_config
49   - end
50   -
51   - should "filter out the project root" do
52   - backtrace_with_root = HoptoadNotifier::Backtrace.parse(
53   - ["#{@project_root}/app/models/user.rb:7:in `latest'",
54   - "#{@project_root}/app/controllers/users_controller.rb:13:in `index'",
55   - "/lib/something.rb:41:in `open'"],
56   - :filters => default_filters)
57   - backtrace_without_root = HoptoadNotifier::Backtrace.parse(
58   - ["[PROJECT_ROOT]/app/models/user.rb:7:in `latest'",
59   - "[PROJECT_ROOT]/app/controllers/users_controller.rb:13:in `index'",
60   - "/lib/something.rb:41:in `open'"])
61   -
62   - assert_equal backtrace_without_root, backtrace_with_root
63   - end
64   - end
65   -
66   - should "remove notifier trace" do
67   - inside_notifier = ['lib/hoptoad_notifier.rb:13:in `voodoo`']
68   - outside_notifier = ['users_controller:8:in `index`']
69   -
70   - without_inside = HoptoadNotifier::Backtrace.parse(outside_notifier)
71   - with_inside = HoptoadNotifier::Backtrace.parse(inside_notifier + outside_notifier,
72   - :filters => default_filters)
73   -
74   - assert_equal without_inside, with_inside
75   - end
76   -
77   - should "run filters on the backtrace" do
78   - filters = [lambda { |line| line.sub('foo', 'bar') }]
79   - input = HoptoadNotifier::Backtrace.parse(["foo:13:in `one'", "baz:14:in `two'"],
80   - :filters => filters)
81   - expected = HoptoadNotifier::Backtrace.parse(["bar:13:in `one'", "baz:14:in `two'"])
82   - assert_equal expected, input
83   - end
84   -
85   - def build_backtrace_array
86   - ["app/models/user.rb:13:in `magic'",
87   - "app/controllers/users_controller.rb:8:in `index'"]
88   - end
89   -
90   - def default_filters
91   - HoptoadNotifier::Configuration::DEFAULT_BACKTRACE_FILTERS
92   - end
93   -
94   -end
vendor/plugins/hoptoad_notifier/test/catcher_test.rb
... ... @@ -1,314 +0,0 @@
1   -require File.dirname(__FILE__) + '/helper'
2   -
3   -class CatcherTest < Test::Unit::TestCase
4   -
5   - include DefinesConstants
6   -
7   - def setup
8   - super
9   - reset_config
10   - HoptoadNotifier.sender = CollectingSender.new
11   - define_constant('RAILS_ROOT', '/path/to/rails/root')
12   - end
13   -
14   - def ignore(exception_class)
15   - HoptoadNotifier.configuration.ignore << exception_class
16   - end
17   -
18   - def build_controller_class(&definition)
19   - returning Class.new(ActionController::Base) do |klass|
20   - klass.__send__(:include, HoptoadNotifier::Catcher)
21   - klass.class_eval(&definition) if definition
22   - define_constant('HoptoadTestController', klass)
23   - end
24   - end
25   -
26   - def assert_sent_hash(hash, xpath)
27   - hash.each do |key, value|
28   - element_xpath = "#{xpath}/var[@key = '#{key}']"
29   - if value.respond_to?(:to_hash)
30   - assert_sent_hash value.to_hash, element_xpath
31   - else
32   - assert_sent_element value.to_s, element_xpath
33   - end
34   - end
35   - end
36   -
37   - def assert_sent_element(value, xpath)
38   - assert_valid_node last_sent_notice_document, xpath, value
39   - end
40   -
41   - def assert_sent_request_info_for(request)
42   - params = request.parameters.to_hash
43   - assert_sent_hash params, '/notice/request/params'
44   - assert_sent_element params['controller'], '/notice/request/component'
45   - assert_sent_element params['action'], '/notice/request/action'
46   - assert_sent_element url_from_request(request), '/notice/request/url'
47   - assert_sent_hash request.env, '/notice/request/cgi-data'
48   - end
49   -
50   - def url_from_request(request)
51   - url = "#{request.protocol}#{request.host}"
52   -
53   - unless [80, 443].include?(request.port)
54   - url << ":#{request.port}"
55   - end
56   -
57   - url << request.request_uri
58   - url
59   - end
60   -
61   - def sender
62   - HoptoadNotifier.sender
63   - end
64   -
65   - def last_sent_notice_xml
66   - sender.collected.last
67   - end
68   -
69   - def last_sent_notice_document
70   - assert_not_nil xml = last_sent_notice_xml, "No xml was sent"
71   - Nokogiri::XML.parse(xml)
72   - end
73   -
74   - def process_action(opts = {}, &action)
75   - opts[:request] ||= ActionController::TestRequest.new
76   - opts[:response] ||= ActionController::TestResponse.new
77   - klass = build_controller_class do
78   - cattr_accessor :local
79   - define_method(:index, &action)
80   - def local_request?
81   - local
82   - end
83   - end
84   - if opts[:filters]
85   - klass.filter_parameter_logging *opts[:filters]
86   - end
87   - if opts[:user_agent]
88   - if opts[:request].respond_to?(:user_agent=)
89   - opts[:request].user_agent = opts[:user_agent]
90   - else
91   - opts[:request].env["HTTP_USER_AGENT"] = opts[:user_agent]
92   - end
93   - end
94   - if opts[:port]
95   - opts[:request].port = opts[:port]
96   - end
97   - klass.consider_all_requests_local = opts[:all_local]
98   - klass.local = opts[:local]
99   - controller = klass.new
100   - controller.stubs(:rescue_action_in_public_without_hoptoad)
101   - opts[:request].query_parameters = opts[:request].query_parameters.merge(opts[:params] || {})
102   - opts[:request].session = ActionController::TestSession.new(opts[:session] || {})
103   - controller.process(opts[:request], opts[:response])
104   - controller
105   - end
106   -
107   - def process_action_with_manual_notification(args = {})
108   - process_action(args) do
109   - notify_hoptoad(:error_message => 'fail')
110   - # Rails will raise a template error if we don't render something
111   - render :nothing => true
112   - end
113   - end
114   -
115   - def process_action_with_automatic_notification(args = {})
116   - process_action(args) { raise "Hello" }
117   - end
118   -
119   - should "deliver notices from exceptions raised in public requests" do
120   - process_action_with_automatic_notification
121   - assert_caught_and_sent
122   - end
123   -
124   - should "not deliver notices from exceptions in local requests" do
125   - process_action_with_automatic_notification(:local => true)
126   - assert_caught_and_not_sent
127   - end
128   -
129   - should "not deliver notices from exceptions when all requests are local" do
130   - process_action_with_automatic_notification(:all_local => true)
131   - assert_caught_and_not_sent
132   - end
133   -
134   - should "not deliver notices from actions that don't raise" do
135   - controller = process_action { render :text => 'Hello' }
136   - assert_caught_and_not_sent
137   - assert_equal 'Hello', controller.response.body
138   - end
139   -
140   - should "not deliver ignored exceptions raised by actions" do
141   - ignore(RuntimeError)
142   - process_action_with_automatic_notification
143   - assert_caught_and_not_sent
144   - end
145   -
146   - should "deliver ignored exception raised manually" do
147   - ignore(RuntimeError)
148   - process_action_with_manual_notification
149   - assert_caught_and_sent
150   - end
151   -
152   - should "deliver manually sent notices in public requests" do
153   - process_action_with_manual_notification
154   - assert_caught_and_sent
155   - end
156   -
157   - should "not deliver manually sent notices in local requests" do
158   - process_action_with_manual_notification(:local => true)
159   - assert_caught_and_not_sent
160   - end
161   -
162   - should "not deliver manually sent notices when all requests are local" do
163   - process_action_with_manual_notification(:all_local => true)
164   - assert_caught_and_not_sent
165   - end
166   -
167   - should "continue with default behavior after delivering an exception" do
168   - controller = process_action_with_automatic_notification(:public => true)
169   - # TODO: can we test this without stubbing?
170   - assert_received(controller, :rescue_action_in_public_without_hoptoad)
171   - end
172   -
173   - should "not create actions from Hoptoad methods" do
174   - controller = build_controller_class.new
175   - assert_equal [], HoptoadNotifier::Catcher.instance_methods
176   - end
177   -
178   - should "ignore exceptions when user agent is being ignored by regular expression" do
179   - HoptoadNotifier.configuration.ignore_user_agent_only = [/Ignored/]
180   - process_action_with_automatic_notification(:user_agent => 'ShouldBeIgnored')
181   - assert_caught_and_not_sent
182   - end
183   -
184   - should "ignore exceptions when user agent is being ignored by string" do
185   - HoptoadNotifier.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
186   - process_action_with_automatic_notification(:user_agent => 'IgnoredUserAgent')
187   - assert_caught_and_not_sent
188   - end
189   -
190   - should "not ignore exceptions when user agent is not being ignored" do
191   - HoptoadNotifier.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
192   - process_action_with_automatic_notification(:user_agent => 'NonIgnoredAgent')
193   - assert_caught_and_sent
194   - end
195   -
196   - should "send session data for manual notifications" do
197   - data = { 'one' => 'two' }
198   - process_action_with_manual_notification(:session => data)
199   - assert_sent_hash data, "/notice/request/session"
200   - end
201   -
202   - should "send session data for automatic notification" do
203   - data = { 'one' => 'two' }
204   - process_action_with_automatic_notification(:session => data)
205   - assert_sent_hash data, "/notice/request/session"
206   - end
207   -
208   - should "send request data for manual notification" do
209   - params = { 'controller' => "hoptoad_test", 'action' => "index" }
210   - controller = process_action_with_manual_notification(:params => params)
211   - assert_sent_request_info_for controller.request
212   - end
213   -
214   - should "send request data for manual notification with non-standard port" do
215   - params = { 'controller' => "hoptoad_test", 'action' => "index" }
216   - controller = process_action_with_manual_notification(:params => params, :port => 81)
217   - assert_sent_request_info_for controller.request
218   - end
219   -
220   - should "send request data for automatic notification" do
221   - params = { 'controller' => "hoptoad_test", 'action' => "index" }
222   - controller = process_action_with_automatic_notification(:params => params)
223   - assert_sent_request_info_for controller.request
224   - end
225   -
226   - should "send request data for automatic notification with non-standard port" do
227   - params = { 'controller' => "hoptoad_test", 'action' => "index" }
228   - controller = process_action_with_automatic_notification(:params => params, :port => 81)
229   - assert_sent_request_info_for controller.request
230   - end
231   -
232   - should "use standard rails logging filters on params and env" do
233   - filtered_params = { "abc" => "123",
234   - "def" => "456",
235   - "ghi" => "[FILTERED]" }
236   - ENV['ghi'] = 'abc'
237   - filtered_env = { 'ghi' => '[FILTERED]' }
238   - filtered_cgi = { 'REQUEST_METHOD' => '[FILTERED]' }
239   -
240   - process_action_with_automatic_notification(:filters => [:ghi, :request_method],
241   - :params => { "abc" => "123",
242   - "def" => "456",
243   - "ghi" => "789" })
244   - assert_sent_hash filtered_params, '/notice/request/params'
245   - assert_sent_hash filtered_cgi, '/notice/request/cgi-data'
246   - end
247   -
248   - context "for a local error with development lookup enabled" do
249   - setup do
250   - HoptoadNotifier.configuration.development_lookup = true
251   - HoptoadNotifier.stubs(:build_lookup_hash_for).returns({ :awesome => 2 })
252   -
253   - @controller = process_action_with_automatic_notification(:local => true)
254   - @response = @controller.response
255   - end
256   -
257   - should "append custom CSS and JS to response body for a local error" do
258   - assert_match /text\/css/, @response.body
259   - assert_match /text\/javascript/, @response.body
260   - end
261   -
262   - should "contain host, API key and notice JSON" do
263   - assert_match HoptoadNotifier.configuration.host.to_json, @response.body
264   - assert_match HoptoadNotifier.configuration.api_key.to_json, @response.body
265   - assert_match ({ :awesome => 2 }).to_json, @response.body
266   - end
267   - end
268   -
269   - context "for a local error with development lookup disabled" do
270   - setup do
271   - HoptoadNotifier.configuration.development_lookup = false
272   -
273   - @controller = process_action_with_automatic_notification(:local => true)
274   - @response = @controller.response
275   - end
276   -
277   - should "not append custom CSS and JS to response for a local error" do
278   - assert_no_match /text\/css/, @response.body
279   - assert_no_match /text\/javascript/, @response.body
280   - end
281   - end
282   -
283   - should "call session.to_hash if available" do
284   - hash_data = {:key => :value}
285   -
286   - session = ActionController::TestSession.new
287   - ActionController::TestSession.stubs(:new).returns(session)
288   - session.stubs(:to_hash).returns(hash_data)
289   -
290   - process_action_with_automatic_notification
291   - assert_received(session, :to_hash)
292   - assert_received(session, :data) { |expect| expect.never }
293   - assert_caught_and_sent
294   - end
295   -
296   - should "call session.data if session.to_hash is undefined" do
297   - hash_data = {:key => :value}
298   -
299   - session = ActionController::TestSession.new
300   - ActionController::TestSession.stubs(:new).returns(session)
301   - session.stubs(:data).returns(hash_data)
302   - if session.respond_to?(:to_hash)
303   - class << session
304   - undef to_hash
305   - end
306   - end
307   -
308   - process_action_with_automatic_notification
309   - assert_received(session, :to_hash) { |expect| expect.never }
310   - assert_received(session, :data) { |expect| expect.at_least_once }
311   - assert_caught_and_sent
312   - end
313   -
314   -end
vendor/plugins/hoptoad_notifier/test/configuration_test.rb
... ... @@ -1,199 +0,0 @@
1   -require File.dirname(__FILE__) + '/helper'
2   -
3   -class ConfigurationTest < Test::Unit::TestCase
4   -
5   - include DefinesConstants
6   -
7   - should "provide default values" do
8   - assert_config_default :proxy_host, nil
9   - assert_config_default :proxy_port, nil
10   - assert_config_default :proxy_user, nil
11   - assert_config_default :proxy_pass, nil
12   - assert_config_default :project_root, nil
13   - assert_config_default :environment_name, nil
14   - assert_config_default :notifier_version, HoptoadNotifier::VERSION
15   - assert_config_default :notifier_name, 'Hoptoad Notifier'
16   - assert_config_default :notifier_url, 'http://hoptoadapp.com'
17   - assert_config_default :secure, false
18   - assert_config_default :host, 'hoptoadapp.com'
19   - assert_config_default :http_open_timeout, 2
20   - assert_config_default :http_read_timeout, 5
21   - assert_config_default :ignore_by_filters, []
22   - assert_config_default :ignore_user_agent, []
23   - assert_config_default :params_filters,
24   - HoptoadNotifier::Configuration::DEFAULT_PARAMS_FILTERS
25   - assert_config_default :backtrace_filters,
26   - HoptoadNotifier::Configuration::DEFAULT_BACKTRACE_FILTERS
27   - assert_config_default :ignore,
28   - HoptoadNotifier::Configuration::IGNORE_DEFAULT
29   - assert_config_default :development_lookup, true
30   - end
31   -
32   - should "provide default values for secure connections" do
33   - config = HoptoadNotifier::Configuration.new
34   - config.secure = true
35   - assert_equal 443, config.port
36   - assert_equal 'https', config.protocol
37   - end
38   -
39   - should "provide default values for insecure connections" do
40   - config = HoptoadNotifier::Configuration.new
41   - config.secure = false
42   - assert_equal 80, config.port
43   - assert_equal 'http', config.protocol
44   - end
45   -
46   - should "not cache inferred ports" do
47   - config = HoptoadNotifier::Configuration.new
48   - config.secure = false
49   - config.port
50   - config.secure = true
51   - assert_equal 443, config.port
52   - end
53   -
54   - should "allow values to be overwritten" do
55   - assert_config_overridable :proxy_host
56   - assert_config_overridable :proxy_port
57   - assert_config_overridable :proxy_user
58   - assert_config_overridable :proxy_pass
59   - assert_config_overridable :secure
60   - assert_config_overridable :host
61   - assert_config_overridable :port
62   - assert_config_overridable :http_open_timeout
63   - assert_config_overridable :http_read_timeout
64   - assert_config_overridable :project_root
65   - assert_config_overridable :notifier_version
66   - assert_config_overridable :notifier_name
67   - assert_config_overridable :notifier_url
68   - assert_config_overridable :environment_name
69   - assert_config_overridable :development_lookup
70   - end
71   -
72   - should "have an api key" do
73   - assert_config_overridable :api_key
74   - end
75   -
76   - should "act like a hash" do
77   - config = HoptoadNotifier::Configuration.new
78   - hash = config.to_hash
79   - [:api_key, :backtrace_filters, :development_environments,
80   - :environment_name, :host, :http_open_timeout,
81   - :http_read_timeout, :ignore, :ignore_by_filters, :ignore_user_agent,
82   - :notifier_name, :notifier_url, :notifier_version, :params_filters,
83   - :project_root, :port, :protocol, :proxy_host, :proxy_pass, :proxy_port,
84   - :proxy_user, :secure, :development_lookup].each do |option|
85   - assert_equal config[option], hash[option], "Wrong value for #{option}"
86   - end
87   - end
88   -
89   - should "be mergable" do
90   - config = HoptoadNotifier::Configuration.new
91   - hash = config.to_hash
92   - assert_equal hash.merge(:key => 'value'), config.merge(:key => 'value')
93   - end
94   -
95   - should "allow param filters to be appended" do
96   - assert_appends_value :params_filters
97   - end
98   -
99   - should "warn when attempting to read environment filters" do
100   - config = HoptoadNotifier::Configuration.new
101   - config.
102   - expects(:warn).
103   - with(regexp_matches(/deprecated/i))
104   - assert_equal [], config.environment_filters
105   - end
106   -
107   - should "allow ignored user agents to be appended" do
108   - assert_appends_value :ignore_user_agent
109   - end
110   -
111   - should "allow backtrace filters to be appended" do
112   - assert_appends_value(:backtrace_filters) do |config|
113   - new_filter = lambda {}
114   - config.filter_backtrace(&new_filter)
115   - new_filter
116   - end
117   - end
118   -
119   - should "allow ignore by filters to be appended" do
120   - assert_appends_value(:ignore_by_filters) do |config|
121   - new_filter = lambda {}
122   - config.ignore_by_filter(&new_filter)
123   - new_filter
124   - end
125   - end
126   -
127   - should "allow ignored exceptions to be appended" do
128   - config = HoptoadNotifier::Configuration.new
129   - original_filters = config.ignore.dup
130   - new_filter = 'hello'
131   - config.ignore << new_filter
132   - assert_same_elements original_filters + [new_filter], config.ignore
133   - end
134   -
135   - should "allow ignored exceptions to be replaced" do
136   - assert_replaces(:ignore, :ignore_only=)
137   - end
138   -
139   - should "allow ignored user agents to be replaced" do
140   - assert_replaces(:ignore_user_agent, :ignore_user_agent_only=)
141   - end
142   -
143   - should "use development and test as development environments by default" do
144   - config = HoptoadNotifier::Configuration.new
145   - assert_same_elements %w(development test cucumber), config.development_environments
146   - end
147   -
148   - should "be public in a public environment" do
149   - config = HoptoadNotifier::Configuration.new
150   - config.development_environments = %w(development)
151   - config.environment_name = 'production'
152   - assert config.public?
153   - end
154   -
155   - should "not be public in a development environment" do
156   - config = HoptoadNotifier::Configuration.new
157   - config.development_environments = %w(staging)
158   - config.environment_name = 'staging'
159   - assert !config.public?
160   - end
161   -
162   - should "be public without an environment name" do
163   - config = HoptoadNotifier::Configuration.new
164   - assert config.public?
165   - end
166   -
167   - def assert_config_default(option, default_value, config = nil)
168   - config ||= HoptoadNotifier::Configuration.new
169   - assert_equal default_value, config.send(option)
170   - end
171   -
172   - def assert_config_overridable(option, value = 'a value')
173   - config = HoptoadNotifier::Configuration.new
174   - config.send(:"#{option}=", value)
175   - assert_equal value, config.send(option)
176   - end
177   -
178   - def assert_appends_value(option, &block)
179   - config = HoptoadNotifier::Configuration.new
180   - original_values = config.send(option).dup
181   - block ||= lambda do |config|
182   - new_value = 'hello'
183   - config.send(option) << new_value
184   - new_value
185   - end
186   - new_value = block.call(config)
187   - assert_same_elements original_values + [new_value], config.send(option)
188   - end
189   -
190   - def assert_replaces(option, setter)
191   - config = HoptoadNotifier::Configuration.new
192   - new_value = 'hello'
193   - config.send(setter, [new_value])
194   - assert_equal [new_value], config.send(option)
195   - config.send(setter, new_value)
196   - assert_equal [new_value], config.send(option)
197   - end
198   -
199   -end
vendor/plugins/hoptoad_notifier/test/helper.rb
... ... @@ -1,238 +0,0 @@
1   -require 'test/unit'
2   -require 'rubygems'
3   -
4   -gem 'jferris-mocha', '0.9.5.0.1241126838'
5   -
6   -require 'shoulda'
7   -require 'mocha'
8   -
9   -$LOAD_PATH << File.join(File.dirname(__FILE__), *%w[.. vendor ginger lib])
10   -require 'ginger'
11   -
12   -require 'action_controller'
13   -require 'action_controller/test_process'
14   -require 'active_record'
15   -require 'active_record/base'
16   -require 'active_support'
17   -require 'nokogiri'
18   -
19   -require File.join(File.dirname(__FILE__), "..", "lib", "hoptoad_notifier")
20   -
21   -begin require 'redgreen'; rescue LoadError; end
22   -
23   -module TestMethods
24   - def rescue_action e
25   - raise e
26   - end
27   -
28   - def do_raise
29   - raise "Hoptoad"
30   - end
31   -
32   - def do_not_raise
33   - render :text => "Success"
34   - end
35   -
36   - def do_raise_ignored
37   - raise ActiveRecord::RecordNotFound.new("404")
38   - end
39   -
40   - def do_raise_not_ignored
41   - raise ActiveRecord::StatementInvalid.new("Statement invalid")
42   - end
43   -
44   - def manual_notify
45   - notify_hoptoad(Exception.new)
46   - render :text => "Success"
47   - end
48   -
49   - def manual_notify_ignored
50   - notify_hoptoad(ActiveRecord::RecordNotFound.new("404"))
51   - render :text => "Success"
52   - end
53   -end
54   -
55   -class HoptoadController < ActionController::Base
56   - include TestMethods
57   -end
58   -
59   -class Test::Unit::TestCase
60   - def request(action = nil, method = :get, user_agent = nil, params = {})
61   - @request = ActionController::TestRequest.new
62   - @request.action = action ? action.to_s : ""
63   -
64   - if user_agent
65   - if @request.respond_to?(:user_agent=)
66   - @request.user_agent = user_agent
67   - else
68   - @request.env["HTTP_USER_AGENT"] = user_agent
69   - end
70   - end
71   - @request.query_parameters = @request.query_parameters.merge(params)
72   - @response = ActionController::TestResponse.new
73   - @controller.process(@request, @response)
74   - end
75   -
76   - # Borrowed from ActiveSupport 2.3.2
77   - def assert_difference(expression, difference = 1, message = nil, &block)
78   - b = block.send(:binding)
79   - exps = Array.wrap(expression)
80   - before = exps.map { |e| eval(e, b) }
81   -
82   - yield
83   -
84   - exps.each_with_index do |e, i|
85   - error = "#{e.inspect} didn't change by #{difference}"
86   - error = "#{message}.\n#{error}" if message
87   - assert_equal(before[i] + difference, eval(e, b), error)
88   - end
89   - end
90   -
91   - def assert_no_difference(expression, message = nil, &block)
92   - assert_difference expression, 0, message, &block
93   - end
94   -
95   - def stub_sender
96   - stub('sender', :send_to_hoptoad => nil)
97   - end
98   -
99   - def stub_sender!
100   - HoptoadNotifier.sender = stub_sender
101   - end
102   -
103   - def stub_notice
104   - stub('notice', :to_xml => 'some yaml', :ignore? => false)
105   - end
106   -
107   - def stub_notice!
108   - returning stub_notice do |notice|
109   - HoptoadNotifier::Notice.stubs(:new => notice)
110   - end
111   - end
112   -
113   - def create_dummy
114   - HoptoadNotifier::DummySender.new
115   - end
116   -
117   - def reset_config
118   - HoptoadNotifier.configuration = nil
119   - HoptoadNotifier.configure do |config|
120   - config.api_key = 'abc123'
121   - end
122   - end
123   -
124   - def clear_backtrace_filters
125   - HoptoadNotifier.configuration.backtrace_filters.clear
126   - end
127   -
128   - def build_exception
129   - raise
130   - rescue => caught_exception
131   - caught_exception
132   - end
133   -
134   - def build_notice_data(exception = nil)
135   - exception ||= build_exception
136   - {
137   - :api_key => 'abc123',
138   - :error_class => exception.class.name,
139   - :error_message => "#{exception.class.name}: #{exception.message}",
140   - :backtrace => exception.backtrace,
141   - :environment => { 'PATH' => '/bin', 'REQUEST_URI' => '/users/1' },
142   - :request => {
143   - :params => { 'controller' => 'users', 'action' => 'show', 'id' => '1' },
144   - :rails_root => '/path/to/application',
145   - :url => "http://test.host/users/1"
146   - },
147   - :session => {
148   - :key => '123abc',
149   - :data => { 'user_id' => '5', 'flash' => { 'notice' => 'Logged in successfully' } }
150   - }
151   - }
152   - end
153   -
154   - def assert_caught_and_sent
155   - assert !HoptoadNotifier.sender.collected.empty?
156   - end
157   -
158   - def assert_caught_and_not_sent
159   - assert HoptoadNotifier.sender.collected.empty?
160   - end
161   -
162   - def assert_array_starts_with(expected, actual)
163   - assert_respond_to actual, :to_ary
164   - array = actual.to_ary.reverse
165   - expected.reverse.each_with_index do |value, i|
166   - assert_equal value, array[i]
167   - end
168   - end
169   -
170   - def assert_valid_node(document, xpath, content)
171   - nodes = document.xpath(xpath)
172   - assert nodes.any?{|node| node.content == content },
173   - "Expected xpath #{xpath} to have content #{content}, " +
174   - "but found #{nodes.map { |n| n.content }} in #{nodes.size} matching nodes." +
175   - "Document:\n#{document.to_s}"
176   - end
177   -end
178   -
179   -module DefinesConstants
180   - def setup
181   - @defined_constants = []
182   - end
183   -
184   - def teardown
185   - @defined_constants.each do |constant|
186   - Object.__send__(:remove_const, constant)
187   - end
188   - end
189   -
190   - def define_constant(name, value)
191   - Object.const_set(name, value)
192   - @defined_constants << name
193   - end
194   -end
195   -
196   -# Also stolen from AS 2.3.2
197   -class Array
198   - # Wraps the object in an Array unless it's an Array. Converts the
199   - # object to an Array using #to_ary if it implements that.
200   - def self.wrap(object)
201   - case object
202   - when nil
203   - []
204   - when self
205   - object
206   - else
207   - if object.respond_to?(:to_ary)
208   - object.to_ary
209   - else
210   - [object]
211   - end
212   - end
213   - end
214   -
215   -end
216   -
217   -class CollectingSender
218   - attr_reader :collected
219   -
220   - def initialize
221   - @collected = []
222   - end
223   -
224   - def send_to_hoptoad(data)
225   - @collected << data
226   - end
227   -end
228   -
229   -class FakeLogger
230   - def info(*args); end
231   - def debug(*args); end
232   - def warn(*args); end
233   - def error(*args); end
234   - def fatal(*args); end
235   -end
236   -
237   -RAILS_DEFAULT_LOGGER = FakeLogger.new
238   -
vendor/plugins/hoptoad_notifier/test/hoptoad_2_0.xsd
... ... @@ -1,76 +0,0 @@
1   -<?xml version="1.0"?>
2   -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3   -
4   - <xs:element name="notice">
5   - <xs:complexType>
6   - <xs:all>
7   - <xs:element name="api-key" type="xs:string"/>
8   - <xs:element name="notifier" type="notifier"/>
9   - <xs:element name="error" type="error"/>
10   - <xs:element name="request" type="request" minOccurs="0"/>
11   - <xs:element name="server-environment" type="serverEnvironment"/>
12   - </xs:all>
13   - <xs:attribute name="version" type="xs:string" use="required"/>
14   - </xs:complexType>
15   - </xs:element>
16   -
17   - <xs:complexType name="notifier">
18   - <xs:all>
19   - <xs:element name="name" type="xs:string"/>
20   - <xs:element name="version" type="xs:string"/>
21   - <xs:element name="url" type="xs:string"/>
22   - </xs:all>
23   - </xs:complexType>
24   -
25   - <xs:complexType name="error">
26   - <xs:all>
27   - <xs:element name="class" type="xs:string"/>
28   - <xs:element name="message" type="xs:string" minOccurs="0"/>
29   - <xs:element name="backtrace" type="backtrace"/>
30   - </xs:all>
31   - </xs:complexType>
32   -
33   - <xs:complexType name="backtrace">
34   - <xs:sequence>
35   - <xs:element name="line" maxOccurs="unbounded">
36   - <xs:complexType>
37   - <xs:attribute name="file" type="xs:string" use="required"/>
38   - <xs:attribute name="number" type="xs:string" use="required"/>
39   - <xs:attribute name="method" type="xs:string" use="optional"/>
40   - </xs:complexType>
41   - </xs:element>
42   - </xs:sequence>
43   - </xs:complexType>
44   -
45   - <xs:complexType name="request">
46   - <xs:all>
47   - <xs:element name="url" type="xs:string"/>
48   - <xs:element name="component" type="xs:string"/>
49   - <xs:element name="action" type="xs:string" minOccurs="0"/>
50   - <xs:element name="params" type="varList" minOccurs="0"/>
51   - <xs:element name="session" type="varList" minOccurs="0"/>
52   - <xs:element name="cgi-data" type="varList" minOccurs="0"/>
53   - </xs:all>
54   - </xs:complexType>
55   -
56   - <xs:complexType name="varList">
57   - <xs:sequence>
58   - <xs:element name="var" type="var" maxOccurs="unbounded"/>
59   - </xs:sequence>
60   - </xs:complexType>
61   -
62   - <xs:complexType name="var" mixed="true">
63   - <xs:sequence>
64   - <xs:element name="var" type="var" minOccurs="0" maxOccurs="unbounded"/>
65   - </xs:sequence>
66   - <xs:attribute name="key" type="xs:string" use="required"/>
67   - </xs:complexType>
68   -
69   - <xs:complexType name="serverEnvironment">
70   - <xs:sequence>
71   - <xs:element name="project-root" type="xs:string" minOccurs="0"/>
72   - <xs:element name="environment-name" type="xs:string"/>
73   - </xs:sequence>
74   - </xs:complexType>
75   -
76   -</xs:schema>
vendor/plugins/hoptoad_notifier/test/hoptoad_tasks_test.rb
... ... @@ -1,138 +0,0 @@
1   -require File.dirname(__FILE__) + '/helper'
2   -require 'rubygems'
3   -
4   -require File.dirname(__FILE__) + '/../lib/hoptoad_tasks'
5   -require 'fakeweb'
6   -
7   -FakeWeb.allow_net_connect = false
8   -
9   -class HoptoadTasksTest < Test::Unit::TestCase
10   - def successful_response(body = "")
11   - response = Net::HTTPSuccess.new('1.2', '200', 'OK')
12   - response.stubs(:body).returns(body)
13   - return response
14   - end
15   -
16   - def unsuccessful_response(body = "")
17   - response = Net::HTTPClientError.new('1.2', '200', 'OK')
18   - response.stubs(:body).returns(body)
19   - return response
20   - end
21   -
22   - context "being quiet" do
23   - setup { HoptoadTasks.stubs(:puts) }
24   -
25   - context "in a configured project" do
26   - setup { HoptoadNotifier.configure { |config| config.api_key = "1234123412341234" } }
27   -
28   - context "on deploy({})" do
29   - setup { @output = HoptoadTasks.deploy({}) }
30   -
31   - before_should "complain about missing rails env" do
32   - HoptoadTasks.expects(:puts).with(regexp_matches(/rails environment/i))
33   - end
34   -
35   - should "return false" do
36   - assert !@output
37   - end
38   - end
39   -
40   - context "given valid options" do
41   - setup { @options = {:rails_env => "staging"} }
42   -
43   - context "on deploy(options)" do
44   - setup { @output = HoptoadTasks.deploy(@options) }
45   -
46   - before_should "post to http://hoptoadapp.com/deploys.txt" do
47   - URI.stubs(:parse).with('http://hoptoadapp.com/deploys.txt').returns(:uri)
48   - Net::HTTP.expects(:post_form).with(:uri, kind_of(Hash)).returns(successful_response)
49   - end
50   -
51   - before_should "use the project api key" do
52   - Net::HTTP.expects(:post_form).
53   - with(kind_of(URI), has_entries('api_key' => "1234123412341234")).
54   - returns(successful_response)
55   - end
56   -
57   - before_should "use send the rails_env param" do
58   - Net::HTTP.expects(:post_form).
59   - with(kind_of(URI), has_entries("deploy[rails_env]" => "staging")).
60   - returns(successful_response)
61   - end
62   -
63   - [:local_username, :scm_repository, :scm_revision].each do |key|
64   - before_should "use send the #{key} param if it's passed in." do
65   - @options[key] = "value"
66   - Net::HTTP.expects(:post_form).
67   - with(kind_of(URI), has_entries("deploy[#{key}]" => "value")).
68   - returns(successful_response)
69   - end
70   - end
71   -
72   - before_should "use the :api_key param if it's passed in." do
73   - @options[:api_key] = "value"
74   - Net::HTTP.expects(:post_form).
75   - with(kind_of(URI), has_entries("api_key" => "value")).
76   - returns(successful_response)
77   - end
78   -
79   - before_should "puts the response body on success" do
80   - HoptoadTasks.expects(:puts).with("body")
81   - Net::HTTP.expects(:post_form).with(any_parameters).returns(successful_response('body'))
82   - end
83   -
84   - before_should "puts the response body on failure" do
85   - HoptoadTasks.expects(:puts).with("body")
86   - Net::HTTP.expects(:post_form).with(any_parameters).returns(unsuccessful_response('body'))
87   - end
88   -
89   - should "return false on failure", :before => lambda {
90   - Net::HTTP.expects(:post_form).with(any_parameters).returns(unsuccessful_response('body'))
91   - } do
92   - assert !@output
93   - end
94   -
95   - should "return true on success", :before => lambda {
96   - Net::HTTP.expects(:post_form).with(any_parameters).returns(successful_response('body'))
97   - } do
98   - assert @output
99   - end
100   - end
101   - end
102   - end
103   -
104   - context "in a configured project with custom host" do
105   - setup do
106   - HoptoadNotifier.configure do |config|
107   - config.api_key = "1234123412341234"
108   - config.host = "custom.host"
109   - end
110   - end
111   -
112   - context "on deploy(:rails_env => 'staging')" do
113   - setup { @output = HoptoadTasks.deploy(:rails_env => "staging") }
114   -
115   - before_should "post to the custom host" do
116   - URI.stubs(:parse).with('http://custom.host/deploys.txt').returns(:uri)
117   - Net::HTTP.expects(:post_form).with(:uri, kind_of(Hash)).returns(successful_response)
118   - end
119   - end
120   - end
121   -
122   - context "when not configured" do
123   - setup { HoptoadNotifier.configure { |config| config.api_key = "" } }
124   -
125   - context "on deploy(:rails_env => 'staging')" do
126   - setup { @output = HoptoadTasks.deploy(:rails_env => "staging") }
127   -
128   - before_should "complain about missing api key" do
129   - HoptoadTasks.expects(:puts).with(regexp_matches(/api key/i))
130   - end
131   -
132   - should "return false" do
133   - assert !@output
134   - end
135   - end
136   - end
137   - end
138   -end
vendor/plugins/hoptoad_notifier/test/logger_test.rb
... ... @@ -1,85 +0,0 @@
1   -require File.dirname(__FILE__) + '/helper'
2   -
3   -class LoggerTest < Test::Unit::TestCase
4   - def stub_http(response, body = nil)
5   - response.stubs(:body => body) if body
6   - @http = stub(:post => response,
7   - :read_timeout= => nil,
8   - :open_timeout= => nil,
9   - :use_ssl= => nil)
10   - Net::HTTP.stubs(:new).returns(@http)
11   - end
12   -
13   - def send_notice
14   - HoptoadNotifier.sender.send_to_hoptoad('data')
15   - end
16   -
17   - def stub_verbose_log
18   - HoptoadNotifier.stubs(:write_verbose_log)
19   - end
20   -
21   - def assert_logged(expected)
22   - assert_received(HoptoadNotifier, :write_verbose_log) do |expect|
23   - expect.with {|actual| actual =~ expected }
24   - end
25   - end
26   -
27   - def assert_not_logged(expected)
28   - assert_received(HoptoadNotifier, :write_verbose_log) do |expect|
29   - expect.with {|actual| actual =~ expected }.never
30   - end
31   - end
32   -
33   - def configure
34   - HoptoadNotifier.configure { |config| }
35   - end
36   -
37   - should "report that notifier is ready when configured" do
38   - stub_verbose_log
39   - configure
40   - assert_logged /Notifier (.*) ready/
41   - end
42   -
43   - should "not report that notifier is ready when internally configured" do
44   - stub_verbose_log
45   - HoptoadNotifier.configure(true) { |config | }
46   - assert_not_logged /.*/
47   - end
48   -
49   - should "print environment info a successful notification without a body" do
50   - reset_config
51   - stub_verbose_log
52   - stub_http(Net::HTTPSuccess)
53   - send_notice
54   - assert_logged /Environment Info:/
55   - assert_not_logged /Response from Hoptoad:/
56   - end
57   -
58   - should "print environment info on a failed notification without a body" do
59   - reset_config
60   - stub_verbose_log
61   - stub_http(Net::HTTPError)
62   - send_notice
63   - assert_logged /Environment Info:/
64   - assert_not_logged /Response from Hoptoad:/
65   - end
66   -
67   - should "print environment info and response on a success with a body" do
68   - reset_config
69   - stub_verbose_log
70   - stub_http(Net::HTTPSuccess, 'test')
71   - send_notice
72   - assert_logged /Environment Info:/
73   - assert_logged /Response from Hoptoad:/
74   - end
75   -
76   - should "print environment info and response on a failure with a body" do
77   - reset_config
78   - stub_verbose_log
79   - stub_http(Net::HTTPError, 'test')
80   - send_notice
81   - assert_logged /Environment Info:/
82   - assert_logged /Response from Hoptoad:/
83   - end
84   -
85   -end
vendor/plugins/hoptoad_notifier/test/notice_test.rb
... ... @@ -1,363 +0,0 @@
1   -require File.dirname(__FILE__) + '/helper'
2   -
3   -class NoticeTest < Test::Unit::TestCase
4   -
5   - include DefinesConstants
6   -
7   - def configure
8   - returning HoptoadNotifier::Configuration.new do |config|
9   - config.api_key = 'abc123def456'
10   - end
11   - end
12   -
13   - def build_notice(args = {})
14   - configuration = args.delete(:configuration) || configure
15   - HoptoadNotifier::Notice.new(configuration.merge(args))
16   - end
17   -
18   - def stub_request(attrs = {})
19   - stub('request', { :parameters => { 'one' => 'two' },
20   - :protocol => 'http',
21   - :host => 'some.host',
22   - :request_uri => '/some/uri',
23   - :session => { :to_hash => { 'a' => 'b' } },
24   - :env => { 'three' => 'four' } }.update(attrs))
25   - end
26   -
27   - should "set the api key" do
28   - api_key = 'key'
29   - notice = build_notice(:api_key => api_key)
30   - assert_equal api_key, notice.api_key
31   - end
32   -
33   - should "accept a project root" do
34   - project_root = '/path/to/project'
35   - notice = build_notice(:project_root => project_root)
36   - assert_equal project_root, notice.project_root
37   - end
38   -
39   - should "accept a component" do
40   - assert_equal 'users_controller', build_notice(:component => 'users_controller').controller
41   - end
42   -
43   - should "alias the component as controller" do
44   - assert_equal 'users_controller', build_notice(:controller => 'users_controller').component
45   - assert_equal 'users_controller', build_notice(:component => 'users_controller').controller
46   - end
47   -
48   - should "accept a action" do
49   - assert_equal 'index', build_notice(:action => 'index').action
50   - end
51   -
52   - should "accept a url" do
53   - url = 'http://some.host/uri'
54   - notice = build_notice(:url => url)
55   - assert_equal url, notice.url
56   - end
57   -
58   - should "accept a backtrace from an exception or hash" do
59   - array = ["user.rb:34:in `crazy'"]
60   - exception = build_exception
61   - exception.set_backtrace array
62   - backtrace = HoptoadNotifier::Backtrace.parse(array)
63   - notice_from_exception = build_notice(:exception => exception)
64   -
65   -
66   - assert_equal notice_from_exception.backtrace,
67   - backtrace,
68   - "backtrace was not correctly set from an exception"
69   -
70   - notice_from_hash = build_notice(:backtrace => array)
71   - assert_equal notice_from_hash.backtrace,
72   - backtrace,
73   - "backtrace was not correctly set from a hash"
74   - end
75   -
76   - should "set the error class from an exception or hash" do
77   - assert_accepts_exception_attribute :error_class do |exception|
78   - exception.class.name
79   - end
80   - end
81   -
82   - should "set the error message from an exception or hash" do
83   - assert_accepts_exception_attribute :error_message do |exception|
84   - "#{exception.class.name}: #{exception.message}"
85   - end
86   - end
87   -
88   - should "accept parameters from a request or hash" do
89   - parameters = { 'one' => 'two' }
90   - notice_from_hash = build_notice(:parameters => parameters)
91   - assert_equal notice_from_hash.parameters, parameters
92   - end
93   -
94   - should "accept session data from a session[:data] hash" do
95   - data = { 'one' => 'two' }
96   - notice = build_notice(:session => { :data => data })
97   - assert_equal data, notice.session_data
98   - end
99   -
100   - should "accept session data from a session_data hash" do
101   - data = { 'one' => 'two' }
102   - notice = build_notice(:session_data => data)
103   - assert_equal data, notice.session_data
104   - end
105   -
106   - should "accept an environment name" do
107   - assert_equal 'development', build_notice(:environment_name => 'development').environment_name
108   - end
109   -
110   - should "accept CGI data from a hash" do
111   - data = { 'string' => 'value' }
112   - notice = build_notice(:cgi_data => data)
113   - assert_equal data, notice.cgi_data, "should take CGI data from a hash"
114   - end
115   -
116   - should "accept notifier information" do
117   - params = { :notifier_name => 'a name for a notifier',
118   - :notifier_version => '1.0.5',
119   - :notifier_url => 'http://notifiers.r.us/download' }
120   - notice = build_notice(params)
121   - assert_equal params[:notifier_name], notice.notifier_name
122   - assert_equal params[:notifier_version], notice.notifier_version
123   - assert_equal params[:notifier_url], notice.notifier_url
124   - end
125   -
126   - should "set sensible defaults without an exception" do
127   - backtrace = HoptoadNotifier::Backtrace.parse(caller)
128   - notice = build_notice
129   -
130   - assert_equal 'Notification', notice.error_message
131   - assert_array_starts_with backtrace.lines, notice.backtrace.lines
132   - assert_equal({}, notice.parameters)
133   - assert_equal({}, notice.session_data)
134   - end
135   -
136   - should "use the caller as the backtrace for an exception without a backtrace" do
137   - backtrace = HoptoadNotifier::Backtrace.parse(caller)
138   - notice = build_notice(:exception => StandardError.new('error'), :backtrace => nil)
139   -
140   - assert_array_starts_with backtrace.lines, notice.backtrace.lines
141   - end
142   -
143   - should "convert unserializable objects to strings" do
144   - assert_serializes_hash(:parameters)
145   - assert_serializes_hash(:cgi_data)
146   - assert_serializes_hash(:session_data)
147   - end
148   -
149   - should "filter parameters" do
150   - assert_filters_hash(:parameters)
151   - end
152   -
153   - should "filter cgi data" do
154   - assert_filters_hash(:cgi_data)
155   - end
156   -
157   - context "a Notice turned into XML" do
158   - setup do
159   - HoptoadNotifier.configure do |config|
160   - config.api_key = "1234567890"
161   - end
162   -
163   - @exception = build_exception
164   -
165   - @notice = build_notice({
166   - :notifier_name => 'a name',
167   - :notifier_version => '1.2.3',
168   - :notifier_url => 'http://some.url/path',
169   - :exception => @exception,
170   - :controller => "controller",
171   - :action => "action",
172   - :url => "http://url.com",
173   - :parameters => { "paramskey" => "paramsvalue",
174   - "nestparentkey" => { "nestkey" => "nestvalue" } },
175   - :session_data => { "sessionkey" => "sessionvalue" },
176   - :cgi_data => { "cgikey" => "cgivalue" },
177   - :project_root => "RAILS_ROOT",
178   - :environment_name => "RAILS_ENV"
179   - })
180   -
181   - @xml = @notice.to_xml
182   -
183   - @document = Nokogiri::XML::Document.parse(@xml)
184   - end
185   -
186   - should "validate against the XML schema" do
187   - assert_valid_notice_document @document
188   - end
189   -
190   - should "serialize a Notice to XML when sent #to_xml" do
191   - assert_valid_node(@document, "//api-key", @notice.api_key)
192   -
193   - assert_valid_node(@document, "//notifier/name", @notice.notifier_name)
194   - assert_valid_node(@document, "//notifier/version", @notice.notifier_version)
195   - assert_valid_node(@document, "//notifier/url", @notice.notifier_url)
196   -
197   - assert_valid_node(@document, "//error/class", @notice.error_class)
198   - assert_valid_node(@document, "//error/message", @notice.error_message)
199   -
200   - assert_valid_node(@document, "//error/backtrace/line/@number", @notice.backtrace.lines.first.number)
201   - assert_valid_node(@document, "//error/backtrace/line/@file", @notice.backtrace.lines.first.file)
202   - assert_valid_node(@document, "//error/backtrace/line/@method", @notice.backtrace.lines.first.method)
203   -
204   - assert_valid_node(@document, "//request/url", @notice.url)
205   - assert_valid_node(@document, "//request/component", @notice.controller)
206   - assert_valid_node(@document, "//request/action", @notice.action)
207   -
208   - assert_valid_node(@document, "//request/params/var/@key", "paramskey")
209   - assert_valid_node(@document, "//request/params/var", "paramsvalue")
210   - assert_valid_node(@document, "//request/params/var/@key", "nestparentkey")
211   - assert_valid_node(@document, "//request/params/var/var/@key", "nestkey")
212   - assert_valid_node(@document, "//request/params/var/var", "nestvalue")
213   - assert_valid_node(@document, "//request/session/var/@key", "sessionkey")
214   - assert_valid_node(@document, "//request/session/var", "sessionvalue")
215   - assert_valid_node(@document, "//request/cgi-data/var/@key", "cgikey")
216   - assert_valid_node(@document, "//request/cgi-data/var", "cgivalue")
217   -
218   - assert_valid_node(@document, "//server-environment/project-root", "RAILS_ROOT")
219   - assert_valid_node(@document, "//server-environment/environment-name", "RAILS_ENV")
220   - end
221   - end
222   -
223   - should "not send empty request data" do
224   - notice = build_notice
225   - assert_nil notice.url
226   - assert_nil notice.controller
227   - assert_nil notice.action
228   -
229   - xml = notice.to_xml
230   - document = Nokogiri::XML.parse(xml)
231   - assert_nil document.at('//request/url')
232   - assert_nil document.at('//request/component')
233   - assert_nil document.at('//request/action')
234   -
235   - assert_valid_notice_document document
236   - end
237   -
238   - %w(url controller action).each do |var|
239   - should "send a request if #{var} is present" do
240   - notice = build_notice(var.to_sym => 'value')
241   - xml = notice.to_xml
242   - document = Nokogiri::XML.parse(xml)
243   - assert_not_nil document.at('//request')
244   - end
245   - end
246   -
247   - %w(parameters cgi_data session_data).each do |var|
248   - should "send a request if #{var} is present" do
249   - notice = build_notice(var.to_sym => { 'key' => 'value' })
250   - xml = notice.to_xml
251   - document = Nokogiri::XML.parse(xml)
252   - assert_not_nil document.at('//request')
253   - end
254   - end
255   -
256   - should "not ignore an exception not matching ignore filters" do
257   - notice = build_notice(:error_class => 'ArgumentError',
258   - :ignore => ['Argument'],
259   - :ignore_by_filters => [lambda { |notice| false }])
260   - assert !notice.ignore?
261   - end
262   -
263   - should "ignore an exception with a matching error class" do
264   - notice = build_notice(:error_class => 'ArgumentError',
265   - :ignore => [ArgumentError])
266   - assert notice.ignore?
267   - end
268   -
269   - should "ignore an exception with a matching error class name" do
270   - notice = build_notice(:error_class => 'ArgumentError',
271   - :ignore => ['ArgumentError'])
272   - assert notice.ignore?
273   - end
274   -
275   - should "ignore an exception with a matching filter" do
276   - filter = lambda {|notice| notice.error_class == 'ArgumentError' }
277   - notice = build_notice(:error_class => 'ArgumentError',
278   - :ignore_by_filters => [filter])
279   - assert notice.ignore?
280   - end
281   -
282   - should "not raise without an ignore list" do
283   - notice = build_notice(:ignore => nil, :ignore_by_filters => nil)
284   - assert_nothing_raised do
285   - notice.ignore?
286   - end
287   - end
288   -
289   - should "act like a hash" do
290   - notice = build_notice(:error_message => 'some message')
291   - assert_equal notice.error_message, notice[:error_message]
292   - end
293   -
294   - should "return params on notice[:request][:params]" do
295   - params = { 'one' => 'two' }
296   - notice = build_notice(:parameters => params)
297   - assert_equal params, notice[:request][:params]
298   - end
299   -
300   - should "ensure #to_hash is called on objects that support it" do
301   - assert_nothing_raised do
302   - build_notice(:session => { :object => stub(:to_hash => {}) })
303   - end
304   - end
305   -
306   - def assert_accepts_exception_attribute(attribute, args = {}, &block)
307   - exception = build_exception
308   - block ||= lambda { exception.send(attribute) }
309   - value = block.call(exception)
310   -
311   - notice_from_exception = build_notice(args.merge(:exception => exception))
312   -
313   - assert_equal notice_from_exception.send(attribute),
314   - value,
315   - "#{attribute} was not correctly set from an exception"
316   -
317   - notice_from_hash = build_notice(args.merge(attribute => value))
318   - assert_equal notice_from_hash.send(attribute),
319   - value,
320   - "#{attribute} was not correctly set from a hash"
321   - end
322   -
323   - def assert_serializes_hash(attribute)
324   - [File.open(__FILE__), Proc.new { puts "boo!" }, Module.new].each do |object|
325   - hash = {
326   - :strange_object => object,
327   - :sub_hash => {
328   - :sub_object => object
329   - },
330   - :array => [object]
331   - }
332   - notice = build_notice(attribute => hash)
333   - hash = notice.send(attribute)
334   - assert_equal object.to_s, hash[:strange_object], "objects should be serialized"
335   - assert_kind_of Hash, hash[:sub_hash], "subhashes should be kept"
336   - assert_equal object.to_s, hash[:sub_hash][:sub_object], "subhash members should be serialized"
337   - assert_kind_of Array, hash[:array], "arrays should be kept"
338   - assert_equal object.to_s, hash[:array].first, "array members should be serialized"
339   - end
340   - end
341   -
342   - def assert_valid_notice_document(document)
343   - xsd_path = File.join(File.dirname(__FILE__), "hoptoad_2_0.xsd")
344   - schema = Nokogiri::XML::Schema.new(IO.read(xsd_path))
345   - errors = schema.validate(document)
346   - assert errors.empty?, errors.collect{|e| e.message }.join
347   - end
348   -
349   - def assert_filters_hash(attribute)
350   - filters = %w(abc def)
351   - original = { 'abc' => "123", 'def' => "456", 'ghi' => "789", 'nested' => { 'abc' => '100' } }
352   - filtered = { 'abc' => "[FILTERED]",
353   - 'def' => "[FILTERED]",
354   - 'ghi' => "789",
355   - 'nested' => { 'abc' => '[FILTERED]' } }
356   -
357   - notice = build_notice(:params_filters => filters, attribute => original)
358   -
359   - assert_equal(filtered,
360   - notice.send(attribute))
361   - end
362   -
363   -end
vendor/plugins/hoptoad_notifier/test/notifier_test.rb
... ... @@ -1,222 +0,0 @@
1   -require File.dirname(__FILE__) + '/helper'
2   -
3   -class NotifierTest < Test::Unit::TestCase
4   -
5   - class OriginalException < Exception
6   - end
7   -
8   - class ContinuedException < Exception
9   - end
10   -
11   - include DefinesConstants
12   -
13   - def setup
14   - super
15   - reset_config
16   - end
17   -
18   - def assert_sent(notice, notice_args)
19   - assert_received(HoptoadNotifier::Notice, :new) {|expect| expect.with(has_entries(notice_args)) }
20   - assert_received(notice, :to_xml)
21   - assert_received(HoptoadNotifier.sender, :send_to_hoptoad) {|expect| expect.with(notice.to_xml) }
22   - end
23   -
24   - def set_public_env
25   - HoptoadNotifier.configure { |config| config.environment_name = 'production' }
26   - end
27   -
28   - def set_development_env
29   - HoptoadNotifier.configure { |config| config.environment_name = 'development' }
30   - end
31   -
32   - should "yield and save a configuration when configuring" do
33   - yielded_configuration = nil
34   - HoptoadNotifier.configure do |config|
35   - yielded_configuration = config
36   - end
37   -
38   - assert_kind_of HoptoadNotifier::Configuration, yielded_configuration
39   - assert_equal yielded_configuration, HoptoadNotifier.configuration
40   - end
41   -
42   - should "not remove existing config options when configuring twice" do
43   - first_config = nil
44   - HoptoadNotifier.configure do |config|
45   - first_config = config
46   - end
47   - HoptoadNotifier.configure do |config|
48   - assert_equal first_config, config
49   - end
50   - end
51   -
52   - should "configure the sender" do
53   - sender = stub_sender
54   - HoptoadNotifier::Sender.stubs(:new => sender)
55   - configuration = nil
56   -
57   - HoptoadNotifier.configure { |yielded_config| configuration = yielded_config }
58   -
59   - assert_received(HoptoadNotifier::Sender, :new) { |expect| expect.with(configuration) }
60   - assert_equal sender, HoptoadNotifier.sender
61   - end
62   -
63   - should "create and send a notice for an exception" do
64   - set_public_env
65   - exception = build_exception
66   - stub_sender!
67   - notice = stub_notice!
68   -
69   - HoptoadNotifier.notify(exception)
70   -
71   - assert_sent notice, :exception => exception
72   - end
73   -
74   - should "create and send a notice for a hash" do
75   - set_public_env
76   - notice = stub_notice!
77   - notice_args = { :error_message => 'uh oh' }
78   - stub_sender!
79   -
80   - HoptoadNotifier.notify(notice_args)
81   -
82   - assert_sent(notice, notice_args)
83   - end
84   -
85   - should "create and sent a notice for an exception and hash" do
86   - set_public_env
87   - exception = build_exception
88   - notice = stub_notice!
89   - notice_args = { :error_message => 'uh oh' }
90   - stub_sender!
91   -
92   - HoptoadNotifier.notify(exception, notice_args)
93   -
94   - assert_sent(notice, notice_args.merge(:exception => exception))
95   - end
96   -
97   - should "not create a notice in a development environment" do
98   - set_development_env
99   - sender = stub_sender!
100   -
101   - HoptoadNotifier.notify(build_exception)
102   - HoptoadNotifier.notify_or_ignore(build_exception)
103   -
104   - assert_received(sender, :send_to_hoptoad) {|expect| expect.never }
105   - end
106   -
107   - should "not deliver an ignored exception when notifying implicitly" do
108   - set_public_env
109   - exception = build_exception
110   - sender = stub_sender!
111   - notice = stub_notice!
112   - notice.stubs(:ignore? => true)
113   -
114   - HoptoadNotifier.notify_or_ignore(exception)
115   -
116   - assert_received(sender, :send_to_hoptoad) {|expect| expect.never }
117   - end
118   -
119   - should "deliver an ignored exception when notifying manually" do
120   - set_public_env
121   - exception = build_exception
122   - sender = stub_sender!
123   - notice = stub_notice!
124   - notice.stubs(:ignore? => true)
125   -
126   - HoptoadNotifier.notify(exception)
127   -
128   - assert_sent(notice, :exception => exception)
129   - end
130   -
131   - should "pass config to created notices" do
132   - exception = build_exception
133   - config_opts = { 'one' => 'two', 'three' => 'four' }
134   - notice = stub_notice!
135   - stub_sender!
136   - HoptoadNotifier.configuration = stub('config', :merge => config_opts, :public? => true)
137   -
138   - HoptoadNotifier.notify(exception)
139   -
140   - assert_received(HoptoadNotifier::Notice, :new) do |expect|
141   - expect.with(has_entries(config_opts))
142   - end
143   - end
144   -
145   - context "building notice JSON for an exception" do
146   - setup do
147   - @params = { :controller => "users", :action => "create" }
148   - @exception = build_exception
149   - @hash = HoptoadNotifier.build_lookup_hash_for(@exception, @params)
150   - end
151   -
152   - should "set action" do
153   - assert_equal @params[:action], @hash[:action]
154   - end
155   -
156   - should "set controller" do
157   - assert_equal @params[:controller], @hash[:component]
158   - end
159   -
160   - should "set line number" do
161   - assert @hash[:line_number] =~ /\d+/
162   - end
163   -
164   - should "set file" do
165   - assert_match /\/test\/helper\.rb$/, @hash[:file]
166   - end
167   -
168   - should "set rails_env to production" do
169   - assert_equal 'production', @hash[:environment_name]
170   - end
171   -
172   - should "set error class" do
173   - assert_equal 'RuntimeError', @hash[:error_class]
174   - end
175   -
176   - should "not set file or line number with no backtrace" do
177   - @exception.stubs(:backtrace).returns([])
178   -
179   - @hash = HoptoadNotifier.build_lookup_hash_for(@exception)
180   -
181   - assert_nil @hash[:line_number]
182   - assert_nil @hash[:file]
183   - end
184   -
185   - should "not set action or controller when not provided" do
186   - @hash = HoptoadNotifier.build_lookup_hash_for(@exception)
187   -
188   - assert_nil @hash[:action]
189   - assert_nil @hash[:controller]
190   - end
191   -
192   - context "when an exception that provides #original_exception is raised" do
193   - setup do
194   - @exception.stubs(:original_exception).returns(begin
195   - raise NotifierTest::OriginalException.new
196   - rescue Exception => e
197   - e
198   - end)
199   - end
200   -
201   - should "unwrap exceptions that provide #original_exception" do
202   - @hash = HoptoadNotifier.build_lookup_hash_for(@exception)
203   - assert_equal "NotifierTest::OriginalException", @hash[:error_class]
204   - end
205   - end
206   -
207   - context "when an exception that provides #continued_exception is raised" do
208   - setup do
209   - @exception.stubs(:continued_exception).returns(begin
210   - raise NotifierTest::ContinuedException.new
211   - rescue Exception => e
212   - e
213   - end)
214   - end
215   -
216   - should "unwrap exceptions that provide #continued_exception" do
217   - @hash = HoptoadNotifier.build_lookup_hash_for(@exception)
218   - assert_equal "NotifierTest::ContinuedException", @hash[:error_class]
219   - end
220   - end
221   - end
222   -end
vendor/plugins/hoptoad_notifier/test/sender_test.rb
... ... @@ -1,123 +0,0 @@
1   -require File.dirname(__FILE__) + '/helper'
2   -
3   -class SenderTest < Test::Unit::TestCase
4   -
5   - def setup
6   - reset_config
7   - end
8   -
9   - def build_sender(opts = {})
10   - config = HoptoadNotifier::Configuration.new
11   - opts.each {|opt, value| config.send(:"#{opt}=", value) }
12   - HoptoadNotifier::Sender.new(config)
13   - end
14   -
15   - def send_exception(args = {})
16   - notice = args.delete(:notice) || build_notice_data
17   - sender = args.delete(:sender) || build_sender(args)
18   - sender.send_to_hoptoad(notice)
19   - sender
20   - end
21   -
22   - def stub_http
23   - response = stub(:body => 'body')
24   - http = stub(:post => response,
25   - :read_timeout= => nil,
26   - :open_timeout= => nil,
27   - :use_ssl= => nil)
28   - Net::HTTP.stubs(:new => http)
29   - http
30   - end
31   -
32   - should "post to Hoptoad when using an HTTP proxy" do
33   - response = stub(:body => 'body')
34   - http = stub(:post => response,
35   - :read_timeout= => nil,
36   - :open_timeout= => nil,
37   - :use_ssl= => nil)
38   - proxy = stub(:new => http)
39   - Net::HTTP.stubs(:Proxy => proxy)
40   -
41   - url = "http://hoptoadapp.com:80#{HoptoadNotifier::Sender::NOTICES_URI}"
42   - uri = URI.parse(url)
43   -
44   - proxy_host = 'some.host'
45   - proxy_port = 88
46   - proxy_user = 'login'
47   - proxy_pass = 'passwd'
48   -
49   - send_exception(:proxy_host => proxy_host,
50   - :proxy_port => proxy_port,
51   - :proxy_user => proxy_user,
52   - :proxy_pass => proxy_pass)
53   - assert_received(http, :post) do |expect|
54   - expect.with(uri.path, anything, HoptoadNotifier::HEADERS)
55   - end
56   - assert_received(Net::HTTP, :Proxy) do |expect|
57   - expect.with(proxy_host, proxy_port, proxy_user, proxy_pass)
58   - end
59   - end
60   -
61   - should "post to the right url for non-ssl" do
62   - http = stub_http
63   - url = "http://hoptoadapp.com:80#{HoptoadNotifier::Sender::NOTICES_URI}"
64   - uri = URI.parse(url)
65   - send_exception(:secure => false)
66   - assert_received(http, :post) {|expect| expect.with(uri.path, anything, HoptoadNotifier::HEADERS) }
67   - end
68   -
69   - should "post to the right path for ssl" do
70   - http = stub_http
71   - send_exception(:secure => true)
72   - assert_received(http, :post) {|expect| expect.with(HoptoadNotifier::Sender::NOTICES_URI, anything, HoptoadNotifier::HEADERS) }
73   - end
74   -
75   - should "default the open timeout to 2 seconds" do
76   - http = stub_http
77   - send_exception
78   - assert_received(http, :open_timeout=) {|expect| expect.with(2) }
79   - end
80   -
81   - should "default the read timeout to 5 seconds" do
82   - http = stub_http
83   - send_exception
84   - assert_received(http, :read_timeout=) {|expect| expect.with(5) }
85   - end
86   -
87   - should "allow override of the open timeout" do
88   - http = stub_http
89   - send_exception(:http_open_timeout => 4)
90   - assert_received(http, :open_timeout=) {|expect| expect.with(4) }
91   - end
92   -
93   - should "allow override of the read timeout" do
94   - http = stub_http
95   - send_exception(:http_read_timeout => 10)
96   - assert_received(http, :read_timeout=) {|expect| expect.with(10) }
97   - end
98   -
99   - should "connect to the right port for ssl" do
100   - stub_http
101   - send_exception(:secure => true)
102   - assert_received(Net::HTTP, :new) {|expect| expect.with("hoptoadapp.com", 443) }
103   - end
104   -
105   - should "connect to the right port for non-ssl" do
106   - stub_http
107   - send_exception(:secure => false)
108   - assert_received(Net::HTTP, :new) {|expect| expect.with("hoptoadapp.com", 80) }
109   - end
110   -
111   - should "use ssl if secure" do
112   - stub_http
113   - send_exception(:secure => true, :host => 'example.org')
114   - assert_received(Net::HTTP, :new) {|expect| expect.with('example.org', 443) }
115   - end
116   -
117   - should "not use ssl if not secure" do
118   - stub_http
119   - send_exception(:secure => false, :host => 'example.org')
120   - assert_received(Net::HTTP, :new) {|expect| expect.with('example.org', 80) }
121   - end
122   -
123   -end
vendor/plugins/hoptoad_notifier/vendor/ginger/.gitignore
... ... @@ -1 +0,0 @@
1   -ginger*.gem
2 0 \ No newline at end of file
vendor/plugins/hoptoad_notifier/vendor/ginger/LICENCE
... ... @@ -1,20 +0,0 @@
1   -Copyright (c) 2008 Pat Allan
2   -
3   -Permission is hereby granted, free of charge, to any person obtaining
4   -a copy of this software and associated documentation files (the
5   -"Software"), to deal in the Software without restriction, including
6   -without limitation the rights to use, copy, modify, merge, publish,
7   -distribute, sublicense, and/or sell copies of the Software, and to
8   -permit persons to whom the Software is furnished to do so, subject to
9   -the following conditions:
10   -
11   -The above copyright notice and this permission notice shall be
12   -included in all copies or substantial portions of the Software.
13   -
14   -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15   -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16   -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17   -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18   -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19   -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20   -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
vendor/plugins/hoptoad_notifier/vendor/ginger/README.textile
... ... @@ -1,50 +0,0 @@
1   -Ginger is a small gem that allows you to test your projects using multiple versions of gem libraries. The idea is from "Ian White's garlic":http://github.com/ianwhite/garlic/tree - hence the related name of this - but my approach is a bit different, since I don't test my plugins from within a rails application. Maybe they can be merged at some point - I just hacked this up quickly to fit my needs.
2   -
3   -To get it all working, you need to do four things. The first is, of course, to install this gem.
4   -
5   -<pre><code>sudo gem install freelancing-god-ginger --source=http://gems.github.com</code></pre>
6   -
7   -Next, add the following line of code to your @spec_helper.rb@ file (or equivalent):
8   -
9   -<pre><code>require 'ginger'</code></pre>
10   -
11   -You'll want to put it as high up as possible - in particular, before any @require@ calls to libraries you want to cover multiple versions of.
12   -
13   -Step number three is creating the sets of scenarios in a file called @ginger_scenarios.rb@, which should go in the root, spec or test directory of your project. Here's an example, showing off the syntax possibilities.
14   -
15   -<pre><code>require 'ginger'
16   -
17   -Ginger.configure do |config|
18   - config.aliases["active_record"] = "activerecord"
19   -
20   - ar_1_2_6 = Ginger::Scenario.new
21   - ar_1_2_6[/^active_?record$/] = "1.15.6"
22   -
23   - ar_2_0_2 = Ginger::Scenario.new
24   - ar_2_0_2[/^active_?record$/] = "2.0.2"
25   -
26   - ar_2_1_1 = Ginger::Scenario.new
27   - ar_2_1_1[/^active_?record$/] = "2.1.1"
28   -
29   - config.scenarios << ar_1_2_6 << ar_2_0_2 << ar_2_1_1
30   -end</code></pre>
31   -
32   -Above, I've added three different scenarios, for three different versions of ActiveRecord. I also added an alias, as people sometimes use the underscore, and sometimes don't. The gem's name has no underscore though, so the _value_ of the alias matches the gem name (whereas the key would be alternative usage).
33   -
34   -You can have multiple gems set in each scenario - and you don't have to use regular expressions, you can just use straight strings.
35   -
36   -<pre><code>sphinx_scenario = Ginger::Scenario.new
37   -sphinx_scenario["riddle"] = "0.9.8"
38   -sphinx_scenario["thinking_sphinx"] = "0.9.8"</code></pre>
39   -
40   -Don't forget to add them to @config@'s scenarios collection, else they're not saved anywhere.
41   -
42   -And finally, you'll want to run the tests or specs for each scenario. This is done using the @ginger@ CLI tool, which parrots whatever parameters you give it onto @rake@. So just do something like:
43   -
44   -<pre><code>ginger spec
45   -ginger test
46   -ginger spec:unit</code></pre>
47   -
48   -h2. Contributors
49   -
50   -* "Adam Meehan":http://duckpunching.com/
vendor/plugins/hoptoad_notifier/vendor/ginger/Rakefile
... ... @@ -1,57 +0,0 @@
1   -require 'rubygems'
2   -require 'spec'
3   -require 'rake/rdoctask'
4   -require 'spec/rake/spectask'
5   -require 'rake/gempackagetask'
6   -
7   -$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib'
8   -
9   -require 'ginger'
10   -
11   -spec = Gem::Specification.new do |s|
12   - s.name = "ginger"
13   - s.version = Ginger::Version::String
14   - s.summary = "Run specs/tests multiple times through different gem versions."
15   - s.description = "Run specs/tests multiple times through different gem versions."
16   - s.author = "Pat Allan"
17   - s.email = "pat@freelancing-gods.com"
18   - s.homepage = "http://github.com/freelancing_god/ginger/tree"
19   - s.has_rdoc = true
20   - s.rdoc_options << "--title" << "Ginger" <<
21   - "--line-numbers"
22   - s.rubyforge_project = "ginger"
23   - s.test_files = FileList["spec/**/*_spec.rb"]
24   - s.files = FileList[
25   - "lib/**/*.rb",
26   - "LICENCE",
27   - "README.textile"
28   - ]
29   - s.executables = ["ginger"]
30   -end
31   -
32   -Rake::GemPackageTask.new(spec) do |p|
33   - p.gem_spec = spec
34   - p.need_tar = true
35   - p.need_zip = true
36   -end
37   -
38   -desc "Generate ginger.gemspec file"
39   -task :gemspec do
40   - File.open('ginger.gemspec', 'w') { |f|
41   - f.write spec.to_ruby
42   - }
43   -end
44   -
45   -desc "Run the specs under spec"
46   -Spec::Rake::SpecTask.new do |t|
47   - t.spec_files = FileList['spec/**/*_spec.rb']
48   - t.spec_opts << "-c"
49   -end
50   -
51   -desc "Generate RCov reports"
52   -Spec::Rake::SpecTask.new(:rcov) do |t|
53   - t.libs << 'lib'
54   - t.spec_files = FileList['spec/**/*_spec.rb']
55   - t.rcov = true
56   - t.rcov_opts = ['--exclude', 'spec', '--exclude', 'gems']
57   -end
58 0 \ No newline at end of file
vendor/plugins/hoptoad_notifier/vendor/ginger/bin/ginger
... ... @@ -1,42 +0,0 @@
1   -#!/usr/bin/env ruby
2   -
3   -require 'rubygems'
4   -require 'ginger'
5   -require 'rake'
6   -
7   -if ARGV.length == 0
8   - puts <<-USAGE
9   -ginger #{Ginger::Version::String}
10   -Use ginger to run specs for each scenario defined. Scenarios must be set out in
11   -a file called ginger_scenarios.rb wherever this tool is run. Once they're
12   -defined, then you can run this tool and provide the rake task that would
13   -normally be called.
14   -
15   -Examples:
16   - ginger spec
17   - ginger test
18   - ginger spec:models
19   -USAGE
20   - exit 0
21   -end
22   -
23   -file_path = File.join Dir.pwd, ".ginger"
24   -
25   -File.delete(file_path) if File.exists?(file_path)
26   -
27   -scenarios = Ginger::Configuration.instance.scenarios
28   -puts "No Ginger Scenarios defined" if scenarios.empty?
29   -
30   -scenarios.each_with_index do |scenario, index|
31   - puts <<-SCENARIO
32   -
33   --------------------
34   -Ginger Scenario #{index+1}
35   --------------------
36   - SCENARIO
37   -
38   - File.open('.ginger', 'w') { |f| f.write index.to_s }
39   - system("rake #{ARGV.join(" ")}")
40   -end
41   -
42   -File.delete(file_path) if File.exists?(file_path)
vendor/plugins/hoptoad_notifier/vendor/ginger/ginger.gemspec
... ... @@ -1,33 +0,0 @@
1   -# -*- encoding: utf-8 -*-
2   -
3   -Gem::Specification.new do |s|
4   - s.name = %q{ginger}
5   - s.version = "1.0.0"
6   -
7   - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8   - s.authors = ["Pat Allan"]
9   - s.date = %q{2008-10-11}
10   - s.default_executable = %q{ginger}
11   - s.description = %q{Run specs/tests multiple times through different gem versions.}
12   - s.email = %q{pat@freelancing-gods.com}
13   - s.executables = ["ginger"]
14   - s.files = ["lib/ginger/configuration.rb", "lib/ginger/kernel.rb", "lib/ginger/scenario.rb", "lib/ginger.rb", "LICENCE", "README.textile", "spec/ginger/configuration_spec.rb", "spec/ginger/kernel_spec.rb", "spec/ginger/scenario_spec.rb", "spec/ginger_spec.rb", "bin/ginger"]
15   - s.has_rdoc = true
16   - s.homepage = %q{http://github.com/freelancing_god/ginger/tree}
17   - s.rdoc_options = ["--title", "Ginger", "--line-numbers"]
18   - s.require_paths = ["lib"]
19   - s.rubyforge_project = %q{ginger}
20   - s.rubygems_version = %q{1.3.0}
21   - s.summary = %q{Run specs/tests multiple times through different gem versions.}
22   - s.test_files = ["spec/ginger/configuration_spec.rb", "spec/ginger/kernel_spec.rb", "spec/ginger/scenario_spec.rb", "spec/ginger_spec.rb"]
23   -
24   - if s.respond_to? :specification_version then
25   - current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26   - s.specification_version = 2
27   -
28   - if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
29   - else
30   - end
31   - else
32   - end
33   -end
vendor/plugins/hoptoad_notifier/vendor/ginger/lib/ginger.rb
... ... @@ -1,21 +0,0 @@
1   -require 'ginger/configuration'
2   -require 'ginger/scenario'
3   -require 'ginger/kernel'
4   -
5   -module Ginger
6   - module Version
7   - Major = 1
8   - Minor = 0
9   - Tiny = 0
10   -
11   - String = [Major, Minor, Tiny].join('.')
12   - end
13   -
14   - def self.configure(&block)
15   - yield Ginger::Configuration.instance
16   - end
17   -end
18   -
19   -Kernel.send(:include, Ginger::Kernel)
20   -
21   -Ginger::Configuration.detect_scenario_file
22 0 \ No newline at end of file
vendor/plugins/hoptoad_notifier/vendor/ginger/lib/ginger/configuration.rb
... ... @@ -1,20 +0,0 @@
1   -require 'singleton'
2   -
3   -module Ginger
4   - class Configuration
5   - include Singleton
6   -
7   - attr_accessor :scenarios, :aliases
8   -
9   - def initialize
10   - @scenarios = []
11   - @aliases = {}
12   - end
13   -
14   - def self.detect_scenario_file
15   - ['.','spec','test'].each do |path|
16   - require "#{path}/ginger_scenarios" and break if File.exists?("#{path}/ginger_scenarios.rb")
17   - end
18   - end
19   - end
20   -end
vendor/plugins/hoptoad_notifier/vendor/ginger/lib/ginger/kernel.rb
... ... @@ -1,56 +0,0 @@
1   -module Ginger
2   - module Kernel
3   - def self.included(base)
4   - base.class_eval do
5   - def require_with_ginger(req)
6   - unless scenario = ginger_scenario
7   - require_without_ginger(req)
8   - return
9   - end
10   -
11   - if scenario.version(req)
12   - gem ginger_gem_name(req)
13   - end
14   -
15   - require_without_ginger(req)
16   - end
17   -
18   - alias_method :require_without_ginger, :require
19   - alias_method :require, :require_with_ginger
20   -
21   - def gem_with_ginger(gem_name, *version_requirements)
22   - unless scenario = ginger_scenario
23   - gem_without_ginger(gem_name, *version_requirements)
24   - return
25   - end
26   -
27   - if version_requirements.length == 0 &&
28   - version = scenario.version(gem_name)
29   - version_requirements << "= #{version}"
30   - end
31   -
32   - gem_without_ginger(gem_name, *version_requirements)
33   - end
34   -
35   - alias_method :gem_without_ginger, :gem
36   - alias_method :gem, :gem_with_ginger
37   -
38   - private
39   -
40   - def ginger_scenario
41   - return nil unless File.exists?(".ginger")
42   -
43   - scenario = nil
44   - File.open('.ginger') { |f| scenario = f.read }
45   - return nil unless scenario
46   -
47   - Ginger::Configuration.instance.scenarios[scenario.to_i]
48   - end
49   -
50   - def ginger_gem_name(gem_name)
51   - Ginger::Configuration.instance.aliases[gem_name] || gem_name
52   - end
53   - end
54   - end
55   - end
56   -end
57 0 \ No newline at end of file
vendor/plugins/hoptoad_notifier/vendor/ginger/lib/ginger/scenario.rb
... ... @@ -1,24 +0,0 @@
1   -module Ginger
2   - class Scenario < Hash
3   - def add(gem, version)
4   - self[gem] = version
5   - end
6   -
7   - def version(gem)
8   - self.keys.each do |key|
9   - case key
10   - when String
11   - return self[key] if gem == key
12   - when Regexp
13   - return self[key] if gem =~ key
14   - end
15   - end
16   -
17   - return nil
18   - end
19   -
20   - def gems
21   - self.keys
22   - end
23   - end
24   -end
25 0 \ No newline at end of file
vendor/plugins/hoptoad_notifier/vendor/ginger/spec/ginger/configuration_spec.rb
... ... @@ -1,7 +0,0 @@
1   -require File.dirname(__FILE__) + '/../spec_helper'
2   -
3   -describe Ginger::Configuration do
4   - it "should be a singleton class" do
5   - Ginger::Configuration.should respond_to(:instance)
6   - end
7   -end
vendor/plugins/hoptoad_notifier/vendor/ginger/spec/ginger/kernel_spec.rb
... ... @@ -1,7 +0,0 @@
1   -require File.dirname(__FILE__) + '/../spec_helper'
2   -
3   -describe "Ginger::Kernel" do
4   - it "should description" do
5   - #
6   - end
7   -end
vendor/plugins/hoptoad_notifier/vendor/ginger/spec/ginger/scenario_spec.rb
... ... @@ -1,50 +0,0 @@
1   -require File.dirname(__FILE__) + '/../spec_helper'
2   -
3   -describe Ginger::Scenario do
4   - it "should allow for multiple gem/version pairs" do
5   - scenario = Ginger::Scenario.new
6   - scenario.add "thinking_sphinx", "1.0"
7   - scenario.add "riddle", "0.9.8"
8   -
9   - scenario.gems.should include("thinking_sphinx")
10   - scenario.gems.should include("riddle")
11   - end
12   -
13   - it "should be able to be used as a hash" do
14   - scenario = Ginger::Scenario.new
15   - scenario["thinking_sphinx"] = "1.0"
16   - scenario["riddle"] = "0.9.8"
17   -
18   - scenario.gems.should include("thinking_sphinx")
19   - scenario.gems.should include("riddle")
20   - end
21   -
22   - it "should allow gem names to be regular expressions" do
23   - scenario = Ginger::Scenario.new
24   - scenario.add /^active_?record$/, "2.1.0"
25   -
26   - scenario.gems.first.should be_kind_of(Regexp)
27   - end
28   -
29   - it "should return the appropriate version for a given gem" do
30   - scenario = Ginger::Scenario.new
31   - scenario.add "riddle", "0.9.8"
32   -
33   - scenario.version("riddle").should == "0.9.8"
34   - end
35   -
36   - it "should use regular expressions to figure out matching version" do
37   - scenario = Ginger::Scenario.new
38   - scenario[/^active_?record$/] = "2.1.0"
39   -
40   - scenario.version("activerecord").should == "2.1.0"
41   - scenario.version("active_record").should == "2.1.0"
42   - end
43   -
44   - it "should return nil if no matching gem" do
45   - scenario = Ginger::Scenario.new
46   - scenario.add "riddle", "0.9.8"
47   -
48   - scenario.version("thinking_sphinx").should be_nil
49   - end
50   -end
vendor/plugins/hoptoad_notifier/vendor/ginger/spec/ginger_spec.rb
... ... @@ -1,14 +0,0 @@
1   -require File.dirname(__FILE__) + '/spec_helper'
2   -
3   -describe "Ginger" do
4   - it "should add scenarios to the Configuration instance" do
5   - Ginger.configure do |config|
6   - scenario = Ginger::Scenario.new
7   - scenario["riddle"] = "0.9.8"
8   -
9   - config.scenarios << scenario
10   - end
11   -
12   - Ginger::Configuration.instance.scenarios.length.should == 1
13   - end
14   -end
vendor/plugins/hoptoad_notifier/vendor/ginger/spec/spec_helper.rb
... ... @@ -1,7 +0,0 @@
1   -$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2   -
3   -require 'ginger'
4   -
5   -Spec::Runner.configure do |config|
6   - # ...
7   -end
8 0 \ No newline at end of file