raygun4ruby 3.2.3 → 3.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +18 -18
  3. data/.rspec +1 -1
  4. data/.travis.yml +20 -20
  5. data/CHANGELOG.md +127 -124
  6. data/Gemfile +4 -4
  7. data/LICENSE.txt +22 -22
  8. data/README.md +420 -420
  9. data/Rakefile +27 -27
  10. data/examples/sinatras_raygun.rb +17 -17
  11. data/lib/generators/raygun/install_generator.rb +26 -26
  12. data/lib/raygun.rb +179 -179
  13. data/lib/raygun/affected_user.rb +59 -59
  14. data/lib/raygun/breadcrumbs.rb +34 -34
  15. data/lib/raygun/breadcrumbs/breadcrumb.rb +34 -34
  16. data/lib/raygun/breadcrumbs/store.rb +86 -86
  17. data/lib/raygun/client.rb +305 -305
  18. data/lib/raygun/configuration.rb +194 -194
  19. data/lib/raygun/error.rb +10 -10
  20. data/lib/raygun/javascript_tracker.rb +42 -42
  21. data/lib/raygun/middleware/breadcrumbs_store_initializer.rb +19 -19
  22. data/lib/raygun/middleware/javascript_exception_tracking.rb +32 -32
  23. data/lib/raygun/middleware/rack_exception_interceptor.rb +18 -18
  24. data/lib/raygun/middleware/rails_insert_affected_user.rb +26 -26
  25. data/lib/raygun/railtie.rb +39 -39
  26. data/lib/raygun/services/apply_whitelist_filter_to_payload.rb +27 -27
  27. data/lib/raygun/sidekiq.rb +71 -70
  28. data/lib/raygun/testable.rb +22 -22
  29. data/lib/raygun/version.rb +3 -3
  30. data/lib/raygun4ruby.rb +1 -1
  31. data/lib/resque/failure/raygun.rb +25 -25
  32. data/lib/tasks/raygun.tasks +7 -7
  33. data/raygun4ruby.gemspec +45 -45
  34. data/spec/dummy/.gitignore +17 -17
  35. data/spec/dummy/Gemfile +47 -47
  36. data/spec/dummy/README.rdoc +28 -28
  37. data/spec/dummy/Rakefile +6 -6
  38. data/spec/dummy/app/assets/config/manifest.js +2 -2
  39. data/spec/dummy/app/assets/javascripts/application.js +13 -13
  40. data/spec/dummy/app/assets/stylesheets/application.css +15 -15
  41. data/spec/dummy/app/controllers/application_controller.rb +5 -5
  42. data/spec/dummy/app/controllers/home_controller.rb +4 -4
  43. data/spec/dummy/app/helpers/application_helper.rb +2 -2
  44. data/spec/dummy/app/views/home/index.html.erb +3 -3
  45. data/spec/dummy/app/views/home/index.json.erb +1 -1
  46. data/spec/dummy/app/views/layouts/application.html.erb +14 -14
  47. data/spec/dummy/bin/bundle +3 -3
  48. data/spec/dummy/bin/rails +9 -9
  49. data/spec/dummy/bin/rake +9 -9
  50. data/spec/dummy/bin/setup +29 -29
  51. data/spec/dummy/bin/spring +17 -17
  52. data/spec/dummy/config.ru +4 -4
  53. data/spec/dummy/config/application.rb +26 -26
  54. data/spec/dummy/config/boot.rb +3 -3
  55. data/spec/dummy/config/database.yml +25 -25
  56. data/spec/dummy/config/environment.rb +5 -5
  57. data/spec/dummy/config/environments/development.rb +41 -41
  58. data/spec/dummy/config/environments/production.rb +79 -79
  59. data/spec/dummy/config/environments/test.rb +42 -42
  60. data/spec/dummy/config/initializers/assets.rb +11 -11
  61. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -7
  62. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -3
  63. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -4
  64. data/spec/dummy/config/initializers/inflections.rb +16 -16
  65. data/spec/dummy/config/initializers/mime_types.rb +4 -4
  66. data/spec/dummy/config/initializers/session_store.rb +3 -3
  67. data/spec/dummy/config/initializers/to_time_preserves_timezone.rb +10 -10
  68. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -14
  69. data/spec/dummy/config/locales/en.yml +23 -23
  70. data/spec/dummy/config/routes.rb +58 -58
  71. data/spec/dummy/config/secrets.yml +22 -22
  72. data/spec/dummy/db/seeds.rb +7 -7
  73. data/spec/dummy/public/404.html +67 -67
  74. data/spec/dummy/public/422.html +67 -67
  75. data/spec/dummy/public/500.html +66 -66
  76. data/spec/dummy/public/robots.txt +5 -5
  77. data/spec/dummy/test/test_helper.rb +10 -10
  78. data/spec/features/javascript_spec.rb +48 -48
  79. data/spec/rails_helper.rb +4 -4
  80. data/spec/raygun/breadcrumbs/breadcrumb_spec.rb +171 -171
  81. data/spec/raygun/breadcrumbs/store_spec.rb +170 -170
  82. data/spec/raygun/raygun_spec.rb +47 -47
  83. data/spec/services/apply_whitelist_filter_to_payload_spec.rb +251 -251
  84. data/spec/spec_helper.rb +24 -24
  85. data/spec/support/fake_logger.rb +17 -17
  86. data/test/integration/client_test.rb +19 -19
  87. data/test/test_helper.rb +72 -72
  88. data/test/unit/affected_user_test.rb +136 -136
  89. data/test/unit/client_test.rb +792 -792
  90. data/test/unit/configuration_test.rb +206 -206
  91. data/test/unit/raygun_test.rb +25 -25
  92. data/test/unit/resque_failure_test.rb +24 -24
  93. data/test/unit/sidekiq_failure_test.rb +32 -32
  94. metadata +7 -7
@@ -1,170 +1,170 @@
1
- require "spec_helper"
2
-
3
- module Raygun
4
- module Breadcrumbs
5
- describe Store do
6
- let(:subject) { Store }
7
- after { subject.clear }
8
-
9
- describe "#initialize" do
10
- before do
11
- expect(subject.stored).to eq(nil)
12
-
13
- subject.initialize
14
- end
15
-
16
- it "creates the store on the current Thread" do
17
- expect(subject.stored).to eq([])
18
- end
19
-
20
- it "does not effect other threads" do
21
- Thread.new do
22
- expect(subject.stored).to eq(nil)
23
- end.join
24
- end
25
- end
26
-
27
- describe "#any?" do
28
- it "returns true if any breadcrumbs have been logged" do
29
- subject.initialize
30
-
31
- subject.record(message: "test")
32
-
33
- expect(subject.any?).to eq(true)
34
- end
35
-
36
- it "returns false if none have been logged" do
37
- subject.initialize
38
-
39
- expect(subject.any?).to eq(false)
40
- end
41
-
42
- it "returns false if the store is uninitialized" do
43
- expect(subject.any?).to eq(false)
44
- end
45
- end
46
-
47
- describe "#clear" do
48
- before do
49
- subject.initialize
50
- end
51
-
52
- it "resets the store back to nil" do
53
- subject.clear
54
-
55
- expect(subject.stored).to eq(nil)
56
- end
57
- end
58
-
59
- describe "#should_record?" do
60
- it "returns false when the log level is above the breadcrumbs level" do
61
- allow(Raygun.configuration).to receive(:breadcrumb_level).and_return(:error)
62
-
63
- crumb = Breadcrumb.new
64
- crumb.level = :warning
65
-
66
- expect(subject.send(:should_record?, crumb)).to eq(false)
67
- end
68
- end
69
-
70
- describe "#take_until_size" do
71
- before do
72
- subject.initialize
73
- end
74
-
75
- it "takes the most recent breadcrumbs until the size limit is reached" do
76
- subject.record(message: '1' * 100)
77
- subject.record(message: '2' * 100)
78
- subject.record(message: '3' * 100)
79
-
80
- crumbs = subject.take_until_size(500)
81
-
82
- expect(crumbs.length).to eq(2)
83
- expect(crumbs[0].message).to eq('2' * 100)
84
- expect(crumbs[1].message).to eq('3' * 100)
85
- end
86
-
87
- it "does not crash with no recorded breadcrumbs" do
88
- crumbs = subject.take_until_size(500)
89
-
90
- expect(crumbs).to eq([])
91
- end
92
- end
93
-
94
- context "adding a breadcrumb" do
95
- class Foo
96
- include ::Raygun::Breadcrumbs
97
-
98
- def bar
99
- record_breadcrumb(message: "test")
100
- end
101
- end
102
-
103
- before do
104
- subject.clear
105
- subject.initialize
106
- end
107
-
108
- it "gets stored" do
109
- subject.record(message: "test")
110
-
111
- expect(subject.stored.length).to eq(1)
112
- expect(subject.stored[0].message).to eq("test")
113
- end
114
-
115
- it "automatically sets the class name" do
116
- Foo.new.bar
117
-
118
- bc = subject.stored[0]
119
- expect(bc.class_name).to eq("Raygun::Breadcrumbs::Foo")
120
- end
121
-
122
- it "automatically sets the method name" do
123
- Foo.new.bar
124
-
125
- bc = subject.stored[0]
126
- expect(bc.method_name).to eq("bar")
127
- end
128
-
129
- it "does not set the method name if it is already set" do
130
- subject.record(message: 'test', method_name: "foo")
131
-
132
- expect(subject.stored[0].method_name).to eq("foo")
133
- end
134
-
135
-
136
- it "automatically sets the timestamp" do
137
- Timecop.freeze do
138
- Foo.new.bar
139
-
140
- bc = subject.stored[0]
141
- expect(bc.timestamp).to eq(Time.now.utc.to_i)
142
- end
143
- end
144
-
145
- it "does not set the timestamp if it is already set" do
146
- time = Time.now.utc
147
-
148
- Timecop.freeze do
149
- subject.record(message: 'test', timestamp: time)
150
-
151
- expect(subject.stored[0].timestamp).to_not eq(Time.now.utc)
152
- end
153
- end
154
-
155
- it "sets the log level to :info if one is not supplied" do
156
- Foo.new.bar
157
-
158
- expect(subject.stored[0].level).to eq(:info)
159
- end
160
-
161
- it "does not record the breadcrumb if should_record? is false" do
162
- expect(subject).to receive(:should_record?).and_return(false)
163
- Foo.new.bar
164
-
165
- expect(subject.stored.length).to eq(0)
166
- end
167
- end
168
- end
169
- end
170
- end
1
+ require "spec_helper"
2
+
3
+ module Raygun
4
+ module Breadcrumbs
5
+ describe Store do
6
+ let(:subject) { Store }
7
+ after { subject.clear }
8
+
9
+ describe "#initialize" do
10
+ before do
11
+ expect(subject.stored).to eq(nil)
12
+
13
+ subject.initialize
14
+ end
15
+
16
+ it "creates the store on the current Thread" do
17
+ expect(subject.stored).to eq([])
18
+ end
19
+
20
+ it "does not effect other threads" do
21
+ Thread.new do
22
+ expect(subject.stored).to eq(nil)
23
+ end.join
24
+ end
25
+ end
26
+
27
+ describe "#any?" do
28
+ it "returns true if any breadcrumbs have been logged" do
29
+ subject.initialize
30
+
31
+ subject.record(message: "test")
32
+
33
+ expect(subject.any?).to eq(true)
34
+ end
35
+
36
+ it "returns false if none have been logged" do
37
+ subject.initialize
38
+
39
+ expect(subject.any?).to eq(false)
40
+ end
41
+
42
+ it "returns false if the store is uninitialized" do
43
+ expect(subject.any?).to eq(false)
44
+ end
45
+ end
46
+
47
+ describe "#clear" do
48
+ before do
49
+ subject.initialize
50
+ end
51
+
52
+ it "resets the store back to nil" do
53
+ subject.clear
54
+
55
+ expect(subject.stored).to eq(nil)
56
+ end
57
+ end
58
+
59
+ describe "#should_record?" do
60
+ it "returns false when the log level is above the breadcrumbs level" do
61
+ allow(Raygun.configuration).to receive(:breadcrumb_level).and_return(:error)
62
+
63
+ crumb = Breadcrumb.new
64
+ crumb.level = :warning
65
+
66
+ expect(subject.send(:should_record?, crumb)).to eq(false)
67
+ end
68
+ end
69
+
70
+ describe "#take_until_size" do
71
+ before do
72
+ subject.initialize
73
+ end
74
+
75
+ it "takes the most recent breadcrumbs until the size limit is reached" do
76
+ subject.record(message: '1' * 100)
77
+ subject.record(message: '2' * 100)
78
+ subject.record(message: '3' * 100)
79
+
80
+ crumbs = subject.take_until_size(500)
81
+
82
+ expect(crumbs.length).to eq(2)
83
+ expect(crumbs[0].message).to eq('2' * 100)
84
+ expect(crumbs[1].message).to eq('3' * 100)
85
+ end
86
+
87
+ it "does not crash with no recorded breadcrumbs" do
88
+ crumbs = subject.take_until_size(500)
89
+
90
+ expect(crumbs).to eq([])
91
+ end
92
+ end
93
+
94
+ context "adding a breadcrumb" do
95
+ class Foo
96
+ include ::Raygun::Breadcrumbs
97
+
98
+ def bar
99
+ record_breadcrumb(message: "test")
100
+ end
101
+ end
102
+
103
+ before do
104
+ subject.clear
105
+ subject.initialize
106
+ end
107
+
108
+ it "gets stored" do
109
+ subject.record(message: "test")
110
+
111
+ expect(subject.stored.length).to eq(1)
112
+ expect(subject.stored[0].message).to eq("test")
113
+ end
114
+
115
+ it "automatically sets the class name" do
116
+ Foo.new.bar
117
+
118
+ bc = subject.stored[0]
119
+ expect(bc.class_name).to eq("Raygun::Breadcrumbs::Foo")
120
+ end
121
+
122
+ it "automatically sets the method name" do
123
+ Foo.new.bar
124
+
125
+ bc = subject.stored[0]
126
+ expect(bc.method_name).to eq("bar")
127
+ end
128
+
129
+ it "does not set the method name if it is already set" do
130
+ subject.record(message: 'test', method_name: "foo")
131
+
132
+ expect(subject.stored[0].method_name).to eq("foo")
133
+ end
134
+
135
+
136
+ it "automatically sets the timestamp" do
137
+ Timecop.freeze do
138
+ Foo.new.bar
139
+
140
+ bc = subject.stored[0]
141
+ expect(bc.timestamp).to eq(Time.now.utc.to_i)
142
+ end
143
+ end
144
+
145
+ it "does not set the timestamp if it is already set" do
146
+ time = Time.now.utc
147
+
148
+ Timecop.freeze do
149
+ subject.record(message: 'test', timestamp: time)
150
+
151
+ expect(subject.stored[0].timestamp).to_not eq(Time.now.utc)
152
+ end
153
+ end
154
+
155
+ it "sets the log level to :info if one is not supplied" do
156
+ Foo.new.bar
157
+
158
+ expect(subject.stored[0].level).to eq(:info)
159
+ end
160
+
161
+ it "does not record the breadcrumb if should_record? is false" do
162
+ expect(subject).to receive(:should_record?).and_return(false)
163
+ Foo.new.bar
164
+
165
+ expect(subject.stored.length).to eq(0)
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
@@ -1,47 +1,47 @@
1
- require 'spec_helper'
2
-
3
- describe Raygun do
4
- let(:failsafe_logger) { FakeLogger.new }
5
-
6
- describe '#track_exception' do
7
- context 'send in background' do
8
- before do
9
- Raygun.setup do |c|
10
- c.silence_reporting = false
11
- c.send_in_background = true
12
- c.api_url = 'http://example.api'
13
- c.api_key = 'foo'
14
- c.debug = true
15
- c.failsafe_logger = failsafe_logger
16
- end
17
- end
18
-
19
- context 'request times out' do
20
- before do
21
- stub_request(:post, 'http://example.api/entries').to_timeout
22
- end
23
-
24
- it 'logs the failure to the failsafe logger' do
25
- error = StandardError.new
26
-
27
- Raygun.track_exception(error)
28
-
29
- # Occasionally doesn't write to the failsafe logger, add small timeout to add some safety
30
- sleep 0.1
31
- expect(failsafe_logger.get).to match /Problem reporting exception to Raygun/
32
- end
33
- end
34
- end
35
- end
36
-
37
- describe '#reset_configuration' do
38
- subject { Raygun.reset_configuration }
39
- it 'clears any customized configuration options' do
40
- Raygun.setup do |c|
41
- c.api_url = 'http://test.api'
42
- end
43
-
44
- expect { subject }.to change { Raygun.configuration.api_url }.from('http://test.api').to(Raygun.default_configuration.api_url)
45
- end
46
- end
47
- end
1
+ require 'spec_helper'
2
+
3
+ describe Raygun do
4
+ let(:failsafe_logger) { FakeLogger.new }
5
+
6
+ describe '#track_exception' do
7
+ context 'send in background' do
8
+ before do
9
+ Raygun.setup do |c|
10
+ c.silence_reporting = false
11
+ c.send_in_background = true
12
+ c.api_url = 'http://example.api'
13
+ c.api_key = 'foo'
14
+ c.debug = true
15
+ c.failsafe_logger = failsafe_logger
16
+ end
17
+ end
18
+
19
+ context 'request times out' do
20
+ before do
21
+ stub_request(:post, 'http://example.api/entries').to_timeout
22
+ end
23
+
24
+ it 'logs the failure to the failsafe logger' do
25
+ error = StandardError.new
26
+
27
+ Raygun.track_exception(error)
28
+
29
+ # Occasionally doesn't write to the failsafe logger, add small timeout to add some safety
30
+ sleep 0.1
31
+ expect(failsafe_logger.get).to match /Problem reporting exception to Raygun/
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ describe '#reset_configuration' do
38
+ subject { Raygun.reset_configuration }
39
+ it 'clears any customized configuration options' do
40
+ Raygun.setup do |c|
41
+ c.api_url = 'http://test.api'
42
+ end
43
+
44
+ expect { subject }.to change { Raygun.configuration.api_url }.from('http://test.api').to(Raygun.default_configuration.api_url)
45
+ end
46
+ end
47
+ end
@@ -1,251 +1,251 @@
1
- require "spec_helper"
2
-
3
- module Raygun
4
- module Services
5
- describe ApplyWhitelistFilterToPayload do
6
- let(:service) { ApplyWhitelistFilterToPayload.new }
7
-
8
- describe "top level keys" do
9
- let(:payload) do
10
- { foo: 1, bar: 2 }
11
- end
12
- let(:expected) do
13
- { foo: 1 , bar: '[FILTERED]'}
14
- end
15
-
16
- it "filters out keys that are not present in the shape" do
17
- shape = {
18
- foo: true
19
- }
20
-
21
- new_payload = service.call(shape, payload)
22
-
23
- expect(new_payload).to eq(expected)
24
- end
25
-
26
- it "filters out keys that are set to false" do
27
- shape = {
28
- foo: true,
29
- bar: false
30
- }
31
-
32
- new_payload = service.call(shape, payload)
33
-
34
- expect(new_payload).to eq(expected)
35
- end
36
- end
37
-
38
- describe "nested hashes" do
39
- let(:payload) {{
40
- foo: 1,
41
- bar: {
42
- baz: 2,
43
- qux: 3
44
- }
45
- }}
46
- let(:expected) {{
47
- foo: 1,
48
- bar: {
49
- baz: 2,
50
- qux: '[FILTERED]'
51
- }
52
- }}
53
-
54
- it "filters out keys in nested hashes" do
55
- shape = {
56
- foo: true,
57
- bar: {
58
- baz: true
59
- }
60
- }
61
-
62
- new_payload = service.call(shape, payload)
63
-
64
- expect(new_payload).to eq(expected)
65
- end
66
-
67
- it "filters out a nested hash if the whitelist does not contain it" do
68
- shape = {
69
- foo: true
70
- }
71
- expected[:bar] = "[FILTERED]"
72
-
73
- new_payload = service.call(shape, payload)
74
-
75
- expect(new_payload).to eq(expected)
76
- end
77
-
78
- it "handles nested hashes when the whitelist is set to allow the whole hash" do
79
- shape = {
80
- bar: true
81
- }
82
- expected = {
83
- foo: '[FILTERED]',
84
- bar: {
85
- baz: 2,
86
- qux: 3
87
- }
88
- }
89
-
90
- new_payload = service.call(shape, payload)
91
-
92
- expect(new_payload).to eq(expected)
93
- end
94
-
95
- it "handles nested hashes when the whitelist is set to not allow the whole hash" do
96
- shape = {
97
- foo: true,
98
- bar: false
99
- }
100
- expected = {
101
- foo: 1,
102
- bar: '[FILTERED]'
103
- }
104
-
105
- new_payload = service.call(shape, payload)
106
-
107
- expect(new_payload).to eq(expected)
108
- end
109
- end
110
-
111
- describe "string keys" do
112
- it "handles the case where a payload key is a string and a whitelist key is a symbol" do
113
- shape = {
114
- foo: true
115
- }
116
- payload = {
117
- "foo" => 1,
118
- "bar" => 2
119
- }
120
- expected = {
121
- "foo" => 1,
122
- "bar" => '[FILTERED]'
123
- }
124
-
125
- new_payload = service.call(shape, payload)
126
-
127
- expect(new_payload).to eq(expected)
128
- end
129
- end
130
-
131
- it "handles a very complex shape" do
132
- shape = {
133
- machineName: true,
134
- version: true,
135
- client: true,
136
- error: {
137
- className: true,
138
- message: true,
139
- stackTrace: true
140
- },
141
- userCustomData: true,
142
- tags: true,
143
- request: {
144
- hostName: true,
145
- url: true,
146
- httpMethod: true,
147
- iPAddress: true,
148
- queryString: {
149
- param1: true,
150
- param2: true,
151
- },
152
- headers: {
153
- "Host" => true,
154
- "Connection" => true,
155
- "Upgrade-Insecure_requests" => true,
156
- "User-Agent" => false,
157
- "Accept" => true,
158
- },
159
- form: {
160
- controller: true,
161
- action: false
162
- },
163
- rawData: {
164
- controller: true,
165
- action: false
166
- }
167
- },
168
- user: false,
169
- }
170
- payload = {
171
- machineName: "mindscapes-MacBook-Pro.local",
172
- version: nil,
173
- client: {name: "Raygun4Ruby Gem", version: "1.1.12", clientUrl: "https://github.com/MindscapeHQ/raygun4ruby"},
174
- error: {className: "Exception", message: "foo", stackTrace: []},
175
- userCustomData: {},
176
- tags: ["development"],
177
- request: {
178
- hostName: "localhost",
179
- url: "/make-me-an-error-charlie",
180
- httpMethod: "GET",
181
- iPAddress: "::1",
182
- queryString: {
183
- param1: "1",
184
- param2: "2",
185
- param3: "3",
186
- },
187
- headers: {
188
- "Host"=>"localhost:3000",
189
- "Connection"=>"keep-alive",
190
- "Upgrade-Insecure_requests"=>"1",
191
- "User-Agent"=> "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
192
- "Accept"=>"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
193
- "Accept-Encoding"=>"gzip, deflate, sdch, br",
194
- "Accept-Language"=>"en-US,en;q=0.8",
195
- "Version"=>"HTTP/1.1"
196
- },
197
- form: {
198
- controller: "home",
199
- action: "raise_error"
200
- },
201
- rawData: {
202
- controller: "home",
203
- action: "raise_error"
204
- }
205
- }
206
- }
207
- expected = {
208
- machineName: "mindscapes-MacBook-Pro.local",
209
- version: nil,
210
- client: {name: "Raygun4Ruby Gem", version: "1.1.12", clientUrl: "https://github.com/MindscapeHQ/raygun4ruby"},
211
- error: {className: "Exception", message: "foo", stackTrace: []},
212
- userCustomData: {},
213
- tags: ["development"],
214
- request: {
215
- hostName: "localhost",
216
- url: "/make-me-an-error-charlie",
217
- httpMethod: "GET",
218
- iPAddress: "::1",
219
- queryString: {
220
- param1: "1",
221
- param2: "2",
222
- param3: '[FILTERED]'
223
- },
224
- headers: {
225
- "Host"=>"localhost:3000",
226
- "Connection"=>"keep-alive",
227
- "Upgrade-Insecure_requests"=>"1",
228
- "User-Agent" => "[FILTERED]",
229
- "Accept"=>"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
230
- "Accept-Encoding" => "[FILTERED]",
231
- "Accept-Language" => "[FILTERED]",
232
- "Version" => "[FILTERED]"
233
- },
234
- form: {
235
- controller: "home",
236
- action: "[FILTERED]"
237
- },
238
- rawData: {
239
- controller: "home",
240
- action: "[FILTERED]"
241
- }
242
- }
243
- }
244
-
245
- new_payload = service.call(shape, payload)
246
-
247
- expect(new_payload).to eq(expected)
248
- end
249
- end
250
- end
251
- end
1
+ require "spec_helper"
2
+
3
+ module Raygun
4
+ module Services
5
+ describe ApplyWhitelistFilterToPayload do
6
+ let(:service) { ApplyWhitelistFilterToPayload.new }
7
+
8
+ describe "top level keys" do
9
+ let(:payload) do
10
+ { foo: 1, bar: 2 }
11
+ end
12
+ let(:expected) do
13
+ { foo: 1 , bar: '[FILTERED]'}
14
+ end
15
+
16
+ it "filters out keys that are not present in the shape" do
17
+ shape = {
18
+ foo: true
19
+ }
20
+
21
+ new_payload = service.call(shape, payload)
22
+
23
+ expect(new_payload).to eq(expected)
24
+ end
25
+
26
+ it "filters out keys that are set to false" do
27
+ shape = {
28
+ foo: true,
29
+ bar: false
30
+ }
31
+
32
+ new_payload = service.call(shape, payload)
33
+
34
+ expect(new_payload).to eq(expected)
35
+ end
36
+ end
37
+
38
+ describe "nested hashes" do
39
+ let(:payload) {{
40
+ foo: 1,
41
+ bar: {
42
+ baz: 2,
43
+ qux: 3
44
+ }
45
+ }}
46
+ let(:expected) {{
47
+ foo: 1,
48
+ bar: {
49
+ baz: 2,
50
+ qux: '[FILTERED]'
51
+ }
52
+ }}
53
+
54
+ it "filters out keys in nested hashes" do
55
+ shape = {
56
+ foo: true,
57
+ bar: {
58
+ baz: true
59
+ }
60
+ }
61
+
62
+ new_payload = service.call(shape, payload)
63
+
64
+ expect(new_payload).to eq(expected)
65
+ end
66
+
67
+ it "filters out a nested hash if the whitelist does not contain it" do
68
+ shape = {
69
+ foo: true
70
+ }
71
+ expected[:bar] = "[FILTERED]"
72
+
73
+ new_payload = service.call(shape, payload)
74
+
75
+ expect(new_payload).to eq(expected)
76
+ end
77
+
78
+ it "handles nested hashes when the whitelist is set to allow the whole hash" do
79
+ shape = {
80
+ bar: true
81
+ }
82
+ expected = {
83
+ foo: '[FILTERED]',
84
+ bar: {
85
+ baz: 2,
86
+ qux: 3
87
+ }
88
+ }
89
+
90
+ new_payload = service.call(shape, payload)
91
+
92
+ expect(new_payload).to eq(expected)
93
+ end
94
+
95
+ it "handles nested hashes when the whitelist is set to not allow the whole hash" do
96
+ shape = {
97
+ foo: true,
98
+ bar: false
99
+ }
100
+ expected = {
101
+ foo: 1,
102
+ bar: '[FILTERED]'
103
+ }
104
+
105
+ new_payload = service.call(shape, payload)
106
+
107
+ expect(new_payload).to eq(expected)
108
+ end
109
+ end
110
+
111
+ describe "string keys" do
112
+ it "handles the case where a payload key is a string and a whitelist key is a symbol" do
113
+ shape = {
114
+ foo: true
115
+ }
116
+ payload = {
117
+ "foo" => 1,
118
+ "bar" => 2
119
+ }
120
+ expected = {
121
+ "foo" => 1,
122
+ "bar" => '[FILTERED]'
123
+ }
124
+
125
+ new_payload = service.call(shape, payload)
126
+
127
+ expect(new_payload).to eq(expected)
128
+ end
129
+ end
130
+
131
+ it "handles a very complex shape" do
132
+ shape = {
133
+ machineName: true,
134
+ version: true,
135
+ client: true,
136
+ error: {
137
+ className: true,
138
+ message: true,
139
+ stackTrace: true
140
+ },
141
+ userCustomData: true,
142
+ tags: true,
143
+ request: {
144
+ hostName: true,
145
+ url: true,
146
+ httpMethod: true,
147
+ iPAddress: true,
148
+ queryString: {
149
+ param1: true,
150
+ param2: true,
151
+ },
152
+ headers: {
153
+ "Host" => true,
154
+ "Connection" => true,
155
+ "Upgrade-Insecure_requests" => true,
156
+ "User-Agent" => false,
157
+ "Accept" => true,
158
+ },
159
+ form: {
160
+ controller: true,
161
+ action: false
162
+ },
163
+ rawData: {
164
+ controller: true,
165
+ action: false
166
+ }
167
+ },
168
+ user: false,
169
+ }
170
+ payload = {
171
+ machineName: "mindscapes-MacBook-Pro.local",
172
+ version: nil,
173
+ client: {name: "Raygun4Ruby Gem", version: "1.1.12", clientUrl: "https://github.com/MindscapeHQ/raygun4ruby"},
174
+ error: {className: "Exception", message: "foo", stackTrace: []},
175
+ userCustomData: {},
176
+ tags: ["development"],
177
+ request: {
178
+ hostName: "localhost",
179
+ url: "/make-me-an-error-charlie",
180
+ httpMethod: "GET",
181
+ iPAddress: "::1",
182
+ queryString: {
183
+ param1: "1",
184
+ param2: "2",
185
+ param3: "3",
186
+ },
187
+ headers: {
188
+ "Host"=>"localhost:3000",
189
+ "Connection"=>"keep-alive",
190
+ "Upgrade-Insecure_requests"=>"1",
191
+ "User-Agent"=> "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
192
+ "Accept"=>"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
193
+ "Accept-Encoding"=>"gzip, deflate, sdch, br",
194
+ "Accept-Language"=>"en-US,en;q=0.8",
195
+ "Version"=>"HTTP/1.1"
196
+ },
197
+ form: {
198
+ controller: "home",
199
+ action: "raise_error"
200
+ },
201
+ rawData: {
202
+ controller: "home",
203
+ action: "raise_error"
204
+ }
205
+ }
206
+ }
207
+ expected = {
208
+ machineName: "mindscapes-MacBook-Pro.local",
209
+ version: nil,
210
+ client: {name: "Raygun4Ruby Gem", version: "1.1.12", clientUrl: "https://github.com/MindscapeHQ/raygun4ruby"},
211
+ error: {className: "Exception", message: "foo", stackTrace: []},
212
+ userCustomData: {},
213
+ tags: ["development"],
214
+ request: {
215
+ hostName: "localhost",
216
+ url: "/make-me-an-error-charlie",
217
+ httpMethod: "GET",
218
+ iPAddress: "::1",
219
+ queryString: {
220
+ param1: "1",
221
+ param2: "2",
222
+ param3: '[FILTERED]'
223
+ },
224
+ headers: {
225
+ "Host"=>"localhost:3000",
226
+ "Connection"=>"keep-alive",
227
+ "Upgrade-Insecure_requests"=>"1",
228
+ "User-Agent" => "[FILTERED]",
229
+ "Accept"=>"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
230
+ "Accept-Encoding" => "[FILTERED]",
231
+ "Accept-Language" => "[FILTERED]",
232
+ "Version" => "[FILTERED]"
233
+ },
234
+ form: {
235
+ controller: "home",
236
+ action: "[FILTERED]"
237
+ },
238
+ rawData: {
239
+ controller: "home",
240
+ action: "[FILTERED]"
241
+ }
242
+ }
243
+ }
244
+
245
+ new_payload = service.call(shape, payload)
246
+
247
+ expect(new_payload).to eq(expected)
248
+ end
249
+ end
250
+ end
251
+ end