airbrake_user_attributes 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rake'
4
+
5
+ gemspec
data/README.md ADDED
@@ -0,0 +1,11 @@
1
+ Airbrake - User Attributes
2
+ =======================
3
+
4
+ Adds information about the current user to error reports.
5
+ This information can only be processed and displayed by
6
+ [Errbit, the open source error catcher](https://github.com/errbit/errbit).
7
+
8
+ This gem can be used as a replacement for the `airbrake` gem,
9
+ since it loads `airbrake` as a dependency.
10
+
11
+ Copyright (c) 2012 Cloudfuji
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'bundler/gem_helper'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the airbrake_user_attributes gem.'
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
+ Bundler::GemHelper.install_tasks
16
+
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'airbrake_user_attributes/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'airbrake_user_attributes'
7
+ s.authors = ['Nathan Broadbent']
8
+ s.email = 'nathan.f77@gmail.com'
9
+ s.homepage = 'http://cloudfuji.com'
10
+ s.summary = 'Send Airbrake notifications with user attributes'
11
+ s.description = 'Adds information about the current user to error reports'
12
+ s.files = `git ls-files`.split("\n")
13
+ s.version = AirbrakeUserAttributes::VERSION
14
+
15
+ s.add_development_dependency("actionpack", "~> 2.3.8")
16
+ s.add_development_dependency("activerecord", "~> 2.3.8")
17
+ s.add_development_dependency("activesupport", "~> 2.3.8")
18
+ s.add_development_dependency("bourne", ">= 1.0")
19
+ s.add_development_dependency("fakeweb", "~> 1.3.0")
20
+ s.add_development_dependency("nokogiri", "~> 1.4.3.1")
21
+ s.add_development_dependency("rspec", "~> 2.6.0")
22
+ s.add_development_dependency("sham_rack", "~> 1.3.0")
23
+ s.add_development_dependency("shoulda", "~> 2.11.3")
24
+
25
+ s.add_dependency 'airbrake', '>= 3.0.9'
26
+
27
+ end
@@ -0,0 +1,85 @@
1
+ require 'airbrake/notice'
2
+
3
+ module Airbrake
4
+ class Notice
5
+ # User information
6
+ # - Provides information about the currently logged in user
7
+ attr_reader :user_attributes
8
+
9
+ def initialize_with_user_attributes(args)
10
+ self.user_attributes = args[:user_attributes] || {}
11
+ initialize_without_user_attributes(args)
12
+ end
13
+ alias_method_chain :initialize, :user_attributes
14
+
15
+ # Converts the given notice to XML
16
+ # Need to override whole builder to add user-attributes at end.
17
+ def to_xml
18
+ builder = Builder::XmlMarkup.new
19
+ builder.instruct!
20
+ xml = builder.notice(:version => Airbrake::API_VERSION) do |notice|
21
+ notice.tag!("api-key", api_key)
22
+ notice.notifier do |notifier|
23
+ notifier.name(notifier_name)
24
+ notifier.version(notifier_version)
25
+ notifier.url(notifier_url)
26
+ end
27
+ notice.error do |error|
28
+ error.tag!('class', error_class)
29
+ error.message(error_message)
30
+ error.backtrace do |backtrace|
31
+ self.backtrace.lines.each do |line|
32
+ backtrace.line(:number => line.number,
33
+ :file => line.file,
34
+ :method => line.method)
35
+ end
36
+ end
37
+ end
38
+ if url ||
39
+ controller ||
40
+ action ||
41
+ !parameters.blank? ||
42
+ !cgi_data.blank? ||
43
+ !session_data.blank?
44
+ notice.request do |request|
45
+ request.url(url)
46
+ request.component(controller)
47
+ request.action(action)
48
+ unless parameters.nil? || parameters.empty?
49
+ request.params do |params|
50
+ xml_vars_for(params, parameters)
51
+ end
52
+ end
53
+ unless session_data.nil? || session_data.empty?
54
+ request.session do |session|
55
+ xml_vars_for(session, session_data)
56
+ end
57
+ end
58
+ unless cgi_data.nil? || cgi_data.empty?
59
+ request.tag!("cgi-data") do |cgi_datum|
60
+ xml_vars_for(cgi_datum, cgi_data)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ notice.tag!("server-environment") do |env|
66
+ env.tag!("project-root", project_root)
67
+ env.tag!("environment-name", environment_name)
68
+ env.tag!("hostname", hostname)
69
+ end
70
+
71
+ if user_attributes.present?
72
+ notice.tag!("user-attributes") do |user|
73
+ xml_vars_for(user, user_attributes)
74
+ end
75
+ end
76
+ end
77
+ xml.to_s
78
+ end
79
+
80
+ private
81
+
82
+ attr_writer :user_attributes
83
+
84
+ end
85
+ end
@@ -0,0 +1,31 @@
1
+ require 'airbrake/rails/controller_methods'
2
+
3
+ module Airbrake
4
+ module Rails
5
+ module ControllerMethods
6
+
7
+ def airbrake_request_data_with_user_attributes
8
+ data = airbrake_request_data_without_user_attributes
9
+ data[:user_attributes] = current_user_filtered_attributes if respond_to?(:current_user)
10
+ data
11
+ end
12
+ alias_method_chain :airbrake_request_data, :user_attributes
13
+
14
+ private
15
+
16
+ # Returns filtered attributes for current user (removes auth-related fields)
17
+ def current_user_filtered_attributes
18
+ attributes = current_user.attributes.reject do |k, v|
19
+ /password|token|login|sign_in|per_page|_at$/ =~ k
20
+ end
21
+ # Try to include a URL for the user, if possible.
22
+ if url_method = [:user_url, :admin_user_url].detect {|m| respond_to?(m) }
23
+ attributes[:url] = send(url_method, current_user)
24
+ end
25
+ attributes
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,3 @@
1
+ module AirbrakeUserAttributes
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,3 @@
1
+ require 'airbrake'
2
+ require 'airbrake_overrides/notice'
3
+ require 'airbrake_overrides/rails/controller_methods'
@@ -0,0 +1,79 @@
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:element name="user-attributes" type="varList" minOccurs="0"/>
13
+ </xs:all>
14
+ <xs:attribute name="version" type="xs:string" use="required"/>
15
+ </xs:complexType>
16
+ </xs:element>
17
+
18
+ <xs:complexType name="notifier">
19
+ <xs:all>
20
+ <xs:element name="name" type="xs:string"/>
21
+ <xs:element name="version" type="xs:string"/>
22
+ <xs:element name="url" type="xs:string"/>
23
+ </xs:all>
24
+ </xs:complexType>
25
+
26
+ <xs:complexType name="error">
27
+ <xs:all>
28
+ <xs:element name="class" type="xs:string"/>
29
+ <xs:element name="message" type="xs:string" minOccurs="0"/>
30
+ <xs:element name="backtrace" type="backtrace"/>
31
+ </xs:all>
32
+ </xs:complexType>
33
+
34
+ <xs:complexType name="backtrace">
35
+ <xs:sequence>
36
+ <xs:element name="line" maxOccurs="unbounded">
37
+ <xs:complexType>
38
+ <xs:attribute name="file" type="xs:string" use="required"/>
39
+ <xs:attribute name="number" type="xs:string" use="required"/>
40
+ <xs:attribute name="method" type="xs:string" use="optional"/>
41
+ </xs:complexType>
42
+ </xs:element>
43
+ </xs:sequence>
44
+ </xs:complexType>
45
+
46
+ <xs:complexType name="request">
47
+ <xs:all>
48
+ <xs:element name="url" type="xs:string"/>
49
+ <xs:element name="component" type="xs:string"/>
50
+ <xs:element name="action" type="xs:string" minOccurs="0"/>
51
+ <xs:element name="params" type="varList" minOccurs="0"/>
52
+ <xs:element name="session" type="varList" minOccurs="0"/>
53
+ <xs:element name="cgi-data" type="varList" minOccurs="0"/>
54
+ </xs:all>
55
+ </xs:complexType>
56
+
57
+ <xs:complexType name="varList">
58
+ <xs:sequence>
59
+ <xs:element name="var" type="var" maxOccurs="unbounded"/>
60
+ </xs:sequence>
61
+ </xs:complexType>
62
+
63
+ <xs:complexType name="var" mixed="true">
64
+ <xs:sequence>
65
+ <xs:element name="var" type="var" minOccurs="0" maxOccurs="unbounded"/>
66
+ </xs:sequence>
67
+ <xs:attribute name="key" type="xs:string" use="required"/>
68
+ </xs:complexType>
69
+
70
+ <xs:complexType name="serverEnvironment">
71
+ <xs:sequence>
72
+ <xs:element name="project-root" type="xs:string" minOccurs="0"/>
73
+ <xs:element name="environment-name" type="xs:string"/>
74
+ <xs:element name="app-version" type="xs:string" minOccurs="0"/>
75
+ <xs:element name="hostname" type="xs:string" minOccurs="0"/>
76
+ </xs:sequence>
77
+ </xs:complexType>
78
+
79
+ </xs:schema>
data/test/helper.rb ADDED
@@ -0,0 +1,262 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+
4
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
5
+
6
+ require 'thread'
7
+
8
+ require "bundler/setup"
9
+
10
+ require 'shoulda'
11
+ require 'mocha'
12
+
13
+ require 'action_controller'
14
+ require 'action_controller/test_process'
15
+ require 'active_record'
16
+ require 'active_support'
17
+ require 'nokogiri'
18
+ require 'rack'
19
+ require 'bourne'
20
+ require 'sham_rack'
21
+
22
+ require "airbrake"
23
+ require "airbrake_user_attributes"
24
+
25
+ begin require 'redgreen'; rescue LoadError; end
26
+
27
+ module TestMethods
28
+ def rescue_action e
29
+ raise e
30
+ end
31
+
32
+ def do_raise
33
+ raise "Airbrake"
34
+ end
35
+
36
+ def do_not_raise
37
+ render :text => "Success"
38
+ end
39
+
40
+ def do_raise_ignored
41
+ raise ActiveRecord::RecordNotFound.new("404")
42
+ end
43
+
44
+ def do_raise_not_ignored
45
+ raise ActiveRecord::StatementInvalid.new("Statement invalid")
46
+ end
47
+
48
+ def manual_notify
49
+ notify_airbrake(Exception.new)
50
+ render :text => "Success"
51
+ end
52
+
53
+ def manual_notify_ignored
54
+ notify_airbrake(ActiveRecord::RecordNotFound.new("404"))
55
+ render :text => "Success"
56
+ end
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_airbrake => nil)
97
+ end
98
+
99
+ def stub_sender!
100
+ Airbrake.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
+ stub_notice.tap do |notice|
109
+ Airbrake::Notice.stubs(:new => notice)
110
+ end
111
+ end
112
+
113
+ def create_dummy
114
+ Airbrake::DummySender.new
115
+ end
116
+
117
+ def reset_config
118
+ Airbrake.configuration = nil
119
+ Airbrake.configure do |config|
120
+ config.api_key = 'abc123'
121
+ end
122
+ end
123
+
124
+ def clear_backtrace_filters
125
+ Airbrake.configuration.backtrace_filters.clear
126
+ end
127
+
128
+ def build_exception(opts = {})
129
+ backtrace = ["airbrake/test/helper.rb:132:in `build_exception'",
130
+ "airbrake/test/backtrace.rb:4:in `build_notice_data'",
131
+ "/var/lib/gems/1.8/gems/airbrake-2.4.5/rails/init.rb:2:in `send_exception'"]
132
+ opts = {:backtrace => backtrace}.merge(opts)
133
+ BacktracedException.new(opts)
134
+ end
135
+
136
+ class BacktracedException < Exception
137
+ attr_accessor :backtrace
138
+ def initialize(opts)
139
+ @backtrace = opts[:backtrace]
140
+ end
141
+ def set_backtrace(bt)
142
+ @backtrace = bt
143
+ end
144
+ end
145
+
146
+ def build_notice_data(exception = nil)
147
+ exception ||= build_exception
148
+ {
149
+ :api_key => 'abc123',
150
+ :error_class => exception.class.name,
151
+ :error_message => "#{exception.class.name}: #{exception.message}",
152
+ :backtrace => exception.backtrace,
153
+ :environment => { 'PATH' => '/bin', 'REQUEST_URI' => '/users/1' },
154
+ :request => {
155
+ :params => { 'controller' => 'users', 'action' => 'show', 'id' => '1' },
156
+ :rails_root => '/path/to/application',
157
+ :url => "http://test.host/users/1"
158
+ },
159
+ :session => {
160
+ :key => '123abc',
161
+ :data => { 'user_id' => '5', 'flash' => { 'notice' => 'Logged in successfully' } }
162
+ }
163
+ }
164
+ end
165
+
166
+ def assert_caught_and_sent
167
+ assert !Airbrake.sender.collected.empty?
168
+ end
169
+
170
+ def assert_caught_and_not_sent
171
+ assert Airbrake.sender.collected.empty?
172
+ end
173
+
174
+ def assert_array_starts_with(expected, actual)
175
+ assert_respond_to actual, :to_ary
176
+ array = actual.to_ary.reverse
177
+ expected.reverse.each_with_index do |value, i|
178
+ assert_equal value, array[i]
179
+ end
180
+ end
181
+
182
+ def assert_valid_node(document, xpath, content)
183
+ nodes = document.xpath(xpath)
184
+ assert nodes.any?{|node| node.content == content },
185
+ "Expected xpath #{xpath} to have content #{content}, " +
186
+ "but found #{nodes.map { |n| n.content }} in #{nodes.size} matching nodes." +
187
+ "Document:\n#{document.to_s}"
188
+ end
189
+
190
+ def assert_logged(expected)
191
+ assert_received(Airbrake, :write_verbose_log) do |expect|
192
+ expect.with {|actual| actual =~ expected }
193
+ end
194
+ end
195
+
196
+ def assert_not_logged(expected)
197
+ assert_received(Airbrake, :write_verbose_log) do |expect|
198
+ expect.with {|actual| actual =~ expected }.never
199
+ end
200
+ end
201
+
202
+
203
+ end
204
+
205
+ module DefinesConstants
206
+ def setup
207
+ @defined_constants = []
208
+ end
209
+
210
+ def teardown
211
+ @defined_constants.each do |constant|
212
+ Object.__send__(:remove_const, constant)
213
+ end
214
+ end
215
+
216
+ def define_constant(name, value)
217
+ Object.const_set(name, value)
218
+ @defined_constants << name
219
+ end
220
+ end
221
+
222
+ # Also stolen from AS 2.3.2
223
+ class Array
224
+ # Wraps the object in an Array unless it's an Array. Converts the
225
+ # object to an Array using #to_ary if it implements that.
226
+ def self.wrap(object)
227
+ case object
228
+ when nil
229
+ []
230
+ when self
231
+ object
232
+ else
233
+ if object.respond_to?(:to_ary)
234
+ object.to_ary
235
+ else
236
+ [object]
237
+ end
238
+ end
239
+ end
240
+
241
+ end
242
+
243
+ class CollectingSender
244
+ attr_reader :collected
245
+
246
+ def initialize
247
+ @collected = []
248
+ end
249
+
250
+ def send_to_airbrake(data)
251
+ @collected << data
252
+ end
253
+ end
254
+
255
+ class FakeLogger
256
+ def info(*args); end
257
+ def debug(*args); end
258
+ def warn(*args); end
259
+ def error(*args); end
260
+ def fatal(*args); end
261
+ end
262
+
@@ -0,0 +1,131 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class NoticeTest < Test::Unit::TestCase
4
+
5
+ include DefinesConstants
6
+
7
+ def configure
8
+ Airbrake::Configuration.new.tap do |config|
9
+ config.api_key = 'abc123def456'
10
+ end
11
+ end
12
+
13
+ def build_notice(args = {})
14
+ configuration = args.delete(:configuration) || configure
15
+ Airbrake::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
+ def hostname
28
+ `hostname`.chomp
29
+ end
30
+
31
+ def assert_valid_notice_document(document)
32
+ xsd_path = File.join(File.dirname(__FILE__), "airbrake_2_2.xsd")
33
+ schema = Nokogiri::XML::Schema.new(IO.read(xsd_path))
34
+ errors = schema.validate(document)
35
+ assert errors.empty?, errors.collect{|e| e.message }.join
36
+ end
37
+
38
+ context "a Notice turned into XML" do
39
+ setup do
40
+ Airbrake.configure do |config|
41
+ config.api_key = "1234567890"
42
+ end
43
+
44
+ @exception = build_exception
45
+
46
+ @notice = build_notice({
47
+ :notifier_name => 'a name',
48
+ :notifier_version => '1.2.3',
49
+ :notifier_url => 'http://some.url/path',
50
+ :exception => @exception,
51
+ :controller => "controller",
52
+ :action => "action",
53
+ :url => "http://url.com",
54
+ :parameters => { "paramskey" => "paramsvalue",
55
+ "nestparentkey" => { "nestkey" => "nestvalue" } },
56
+ :session_data => { "sessionkey" => "sessionvalue" },
57
+ :cgi_data => { "cgikey" => "cgivalue" },
58
+ :user_attributes => { "id" => 1234, "username" => "jsmith", "url" => "http://www.example.com/users/1234" },
59
+ :project_root => "RAILS_ROOT",
60
+ :environment_name => "RAILS_ENV"
61
+ })
62
+
63
+ @xml = @notice.to_xml
64
+
65
+ @document = Nokogiri::XML::Document.parse(@xml)
66
+ end
67
+
68
+ should "validate against the XML schema" do
69
+ assert_valid_notice_document @document
70
+ end
71
+
72
+ should "serialize a Notice to XML when sent #to_xml" do
73
+ assert_valid_node(@document, "//api-key", @notice.api_key)
74
+
75
+ assert_valid_node(@document, "//notifier/name", @notice.notifier_name)
76
+ assert_valid_node(@document, "//notifier/version", @notice.notifier_version)
77
+ assert_valid_node(@document, "//notifier/url", @notice.notifier_url)
78
+
79
+ assert_valid_node(@document, "//error/class", @notice.error_class)
80
+ assert_valid_node(@document, "//error/message", @notice.error_message)
81
+
82
+ assert_valid_node(@document, "//error/backtrace/line/@number", @notice.backtrace.lines.first.number)
83
+ assert_valid_node(@document, "//error/backtrace/line/@file", @notice.backtrace.lines.first.file)
84
+ assert_valid_node(@document, "//error/backtrace/line/@method", @notice.backtrace.lines.first.method)
85
+
86
+ assert_valid_node(@document, "//request/url", @notice.url)
87
+ assert_valid_node(@document, "//request/component", @notice.controller)
88
+ assert_valid_node(@document, "//request/action", @notice.action)
89
+
90
+ assert_valid_node(@document, "//request/params/var/@key", "paramskey")
91
+ assert_valid_node(@document, "//request/params/var", "paramsvalue")
92
+ assert_valid_node(@document, "//request/params/var/@key", "nestparentkey")
93
+ assert_valid_node(@document, "//request/params/var/var/@key", "nestkey")
94
+ assert_valid_node(@document, "//request/params/var/var", "nestvalue")
95
+ assert_valid_node(@document, "//request/session/var/@key", "sessionkey")
96
+ assert_valid_node(@document, "//request/session/var", "sessionvalue")
97
+ assert_valid_node(@document, "//request/cgi-data/var/@key", "cgikey")
98
+ assert_valid_node(@document, "//request/cgi-data/var", "cgivalue")
99
+
100
+ assert_valid_node(@document, "//server-environment/project-root", "RAILS_ROOT")
101
+ assert_valid_node(@document, "//server-environment/environment-name", "RAILS_ENV")
102
+ assert_valid_node(@document, "//server-environment/hostname", hostname)
103
+
104
+ assert_valid_node(@document, "//user-attributes/var/@key", "id")
105
+ assert_valid_node(@document, "//user-attributes/var", "1234")
106
+ assert_valid_node(@document, "//user-attributes/var/@key", "username")
107
+ assert_valid_node(@document, "//user-attributes/var", "jsmith")
108
+ assert_valid_node(@document, "//user-attributes/var/@key", "url")
109
+ assert_valid_node(@document, "//user-attributes/var", "http://www.example.com/users/1234")
110
+ end
111
+ end
112
+
113
+ should "not send empty request data" do
114
+ notice = build_notice
115
+ assert_nil notice.url
116
+ assert_nil notice.controller
117
+ assert_nil notice.action
118
+ assert_empty notice.user_attributes
119
+
120
+ xml = notice.to_xml
121
+ document = Nokogiri::XML.parse(xml)
122
+ assert_nil document.at('//request/url')
123
+ assert_nil document.at('//request/component')
124
+ assert_nil document.at('//request/action')
125
+ assert_nil document.at('//user-attributes')
126
+
127
+ assert_valid_notice_document document
128
+ end
129
+
130
+
131
+ end
metadata ADDED
@@ -0,0 +1,222 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: airbrake_user_attributes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Nathan Broadbent
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: actionpack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.3.8
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 2.3.8
30
+ - !ruby/object:Gem::Dependency
31
+ name: activerecord
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.3.8
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.3.8
46
+ - !ruby/object:Gem::Dependency
47
+ name: activesupport
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 2.3.8
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.8
62
+ - !ruby/object:Gem::Dependency
63
+ name: bourne
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '1.0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '1.0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: fakeweb
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 1.3.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 1.3.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: nokogiri
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.4.3.1
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.4.3.1
110
+ - !ruby/object:Gem::Dependency
111
+ name: rspec
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: 2.6.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 2.6.0
126
+ - !ruby/object:Gem::Dependency
127
+ name: sham_rack
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 1.3.0
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 1.3.0
142
+ - !ruby/object:Gem::Dependency
143
+ name: shoulda
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ~>
148
+ - !ruby/object:Gem::Version
149
+ version: 2.11.3
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ~>
156
+ - !ruby/object:Gem::Version
157
+ version: 2.11.3
158
+ - !ruby/object:Gem::Dependency
159
+ name: airbrake
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: 3.0.9
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: 3.0.9
174
+ description: Adds information about the current user to error reports
175
+ email: nathan.f77@gmail.com
176
+ executables: []
177
+ extensions: []
178
+ extra_rdoc_files: []
179
+ files:
180
+ - .gitignore
181
+ - Gemfile
182
+ - README.md
183
+ - Rakefile
184
+ - airbrake_user_attributes.gemspec
185
+ - lib/airbrake_overrides/notice.rb
186
+ - lib/airbrake_overrides/rails/controller_methods.rb
187
+ - lib/airbrake_user_attributes.rb
188
+ - lib/airbrake_user_attributes/version.rb
189
+ - test/airbrake_2_2.xsd
190
+ - test/helper.rb
191
+ - test/notice_test.rb
192
+ homepage: http://cloudfuji.com
193
+ licenses: []
194
+ post_install_message:
195
+ rdoc_options: []
196
+ require_paths:
197
+ - lib
198
+ required_ruby_version: !ruby/object:Gem::Requirement
199
+ none: false
200
+ requirements:
201
+ - - ! '>='
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ segments:
205
+ - 0
206
+ hash: 311172291318117201
207
+ required_rubygems_version: !ruby/object:Gem::Requirement
208
+ none: false
209
+ requirements:
210
+ - - ! '>='
211
+ - !ruby/object:Gem::Version
212
+ version: '0'
213
+ segments:
214
+ - 0
215
+ hash: 311172291318117201
216
+ requirements: []
217
+ rubyforge_project:
218
+ rubygems_version: 1.8.24
219
+ signing_key:
220
+ specification_version: 3
221
+ summary: Send Airbrake notifications with user attributes
222
+ test_files: []