raygun4ruby 3.2.6 → 4.0.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (232) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests.yml +48 -0
  3. data/.gitignore +22 -21
  4. data/.rspec +1 -1
  5. data/Appraisals +19 -0
  6. data/CHANGELOG.md +169 -133
  7. data/Gemfile +4 -4
  8. data/LICENSE.txt +22 -22
  9. data/README.md +424 -420
  10. data/Rakefile +32 -27
  11. data/examples/sinatras_raygun.rb +17 -17
  12. data/gemfiles/rails_6.gemfile +9 -0
  13. data/gemfiles/rails_7.gemfile +10 -0
  14. data/gemfiles/rails_7_sidekiq_6.gemfile +10 -0
  15. data/lib/generators/raygun/install_generator.rb +26 -26
  16. data/lib/raygun/affected_user.rb +59 -59
  17. data/lib/raygun/breadcrumbs/breadcrumb.rb +34 -34
  18. data/lib/raygun/breadcrumbs/store.rb +86 -86
  19. data/lib/raygun/breadcrumbs.rb +34 -34
  20. data/lib/raygun/client.rb +313 -308
  21. data/lib/raygun/configuration.rb +197 -194
  22. data/lib/raygun/demo_exception.rb +22 -22
  23. data/lib/raygun/error.rb +10 -10
  24. data/lib/raygun/error_subscriber.rb +21 -0
  25. data/lib/raygun/javascript_tracker.rb +42 -42
  26. data/lib/raygun/middleware/breadcrumbs_store_initializer.rb +19 -19
  27. data/lib/raygun/middleware/javascript_exception_tracking.rb +40 -32
  28. data/lib/raygun/middleware/rack_exception_interceptor.rb +18 -18
  29. data/lib/raygun/middleware/rails_insert_affected_user.rb +26 -26
  30. data/lib/raygun/railtie.rb +47 -39
  31. data/lib/raygun/services/apply_whitelist_filter_to_payload.rb +27 -27
  32. data/lib/raygun/sidekiq.rb +51 -71
  33. data/lib/raygun/version.rb +3 -3
  34. data/lib/raygun.rb +197 -179
  35. data/lib/raygun4ruby.rb +1 -1
  36. data/lib/resque/failure/raygun.rb +25 -25
  37. data/lib/tasks/raygun.tasks +7 -7
  38. data/raygun4ruby.gemspec +43 -45
  39. data/spec/features/javascript_spec.rb +48 -48
  40. data/spec/rails_applications/6.1.4/Gemfile +56 -0
  41. data/spec/{dummy/README.rdoc → rails_applications/6.1.4/README.md} +24 -28
  42. data/spec/{dummy → rails_applications/6.1.4}/Rakefile +6 -6
  43. data/spec/rails_applications/6.1.4/app/assets/config/manifest.js +2 -0
  44. data/spec/{dummy → rails_applications/6.1.4}/app/assets/images/.keep +0 -0
  45. data/spec/{dummy → rails_applications/6.1.4}/app/assets/stylesheets/application.css +15 -15
  46. data/spec/rails_applications/6.1.4/app/channels/application_cable/channel.rb +4 -0
  47. data/spec/rails_applications/6.1.4/app/channels/application_cable/connection.rb +4 -0
  48. data/spec/rails_applications/6.1.4/app/controllers/application_controller.rb +2 -0
  49. data/spec/{dummy → rails_applications/6.1.4}/app/controllers/concerns/.keep +0 -0
  50. data/spec/{dummy → rails_applications/6.1.4}/app/controllers/home_controller.rb +4 -4
  51. data/spec/{dummy → rails_applications/6.1.4}/app/helpers/application_helper.rb +2 -2
  52. data/spec/rails_applications/6.1.4/app/javascript/channels/consumer.js +6 -0
  53. data/spec/rails_applications/6.1.4/app/javascript/channels/index.js +5 -0
  54. data/spec/rails_applications/6.1.4/app/javascript/packs/application.js +13 -0
  55. data/spec/rails_applications/6.1.4/app/jobs/application_job.rb +7 -0
  56. data/spec/rails_applications/6.1.4/app/mailers/application_mailer.rb +4 -0
  57. data/spec/rails_applications/6.1.4/app/models/application_record.rb +3 -0
  58. data/spec/{dummy/app/mailers → rails_applications/6.1.4/app/models/concerns}/.keep +0 -0
  59. data/spec/{dummy → rails_applications/6.1.4}/app/views/home/index.html.erb +3 -3
  60. data/spec/{dummy → rails_applications/6.1.4}/app/views/home/index.json.erb +1 -1
  61. data/spec/rails_applications/6.1.4/app/views/layouts/application.html.erb +13 -0
  62. data/spec/rails_applications/6.1.4/app/views/layouts/mailer.html.erb +13 -0
  63. data/spec/rails_applications/6.1.4/app/views/layouts/mailer.text.erb +1 -0
  64. data/spec/rails_applications/6.1.4/bin/rails +5 -0
  65. data/spec/rails_applications/6.1.4/bin/rake +5 -0
  66. data/spec/rails_applications/6.1.4/bin/setup +36 -0
  67. data/spec/rails_applications/6.1.4/bin/spring +14 -0
  68. data/spec/rails_applications/6.1.4/bin/yarn +17 -0
  69. data/spec/rails_applications/6.1.4/config/application.rb +22 -0
  70. data/spec/rails_applications/6.1.4/config/boot.rb +3 -0
  71. data/spec/rails_applications/6.1.4/config/cable.yml +10 -0
  72. data/spec/rails_applications/6.1.4/config/credentials.yml.enc +1 -0
  73. data/spec/{dummy → rails_applications/6.1.4}/config/database.yml +25 -25
  74. data/spec/{dummy → rails_applications/6.1.4}/config/environment.rb +5 -5
  75. data/spec/rails_applications/6.1.4/config/environments/development.rb +76 -0
  76. data/spec/rails_applications/6.1.4/config/environments/production.rb +120 -0
  77. data/spec/rails_applications/6.1.4/config/environments/test.rb +60 -0
  78. data/spec/rails_applications/6.1.4/config/initializers/application_controller_renderer.rb +8 -0
  79. data/spec/rails_applications/6.1.4/config/initializers/assets.rb +14 -0
  80. data/spec/rails_applications/6.1.4/config/initializers/backtrace_silencers.rb +8 -0
  81. data/spec/rails_applications/6.1.4/config/initializers/content_security_policy.rb +30 -0
  82. data/spec/{dummy → rails_applications/6.1.4}/config/initializers/cookies_serializer.rb +5 -3
  83. data/spec/{dummy → rails_applications/6.1.4}/config/initializers/filter_parameter_logging.rb +6 -4
  84. data/spec/{dummy → rails_applications/6.1.4}/config/initializers/inflections.rb +16 -16
  85. data/spec/{dummy → rails_applications/6.1.4}/config/initializers/mime_types.rb +4 -4
  86. data/spec/rails_applications/6.1.4/config/initializers/permissions_policy.rb +11 -0
  87. data/spec/{dummy → rails_applications/6.1.4}/config/initializers/wrap_parameters.rb +14 -14
  88. data/spec/{dummy → rails_applications/6.1.4}/config/locales/en.yml +33 -23
  89. data/spec/rails_applications/6.1.4/config/master.key +1 -0
  90. data/spec/rails_applications/6.1.4/config/puma.rb +43 -0
  91. data/spec/rails_applications/6.1.4/config/routes.rb +4 -0
  92. data/spec/rails_applications/6.1.4/config/spring.rb +6 -0
  93. data/spec/rails_applications/6.1.4/config/storage.yml +34 -0
  94. data/spec/{dummy → rails_applications/6.1.4}/config.ru +6 -4
  95. data/spec/rails_applications/6.1.4/db/seeds.rb +7 -0
  96. data/spec/{dummy → rails_applications/6.1.4}/db/test.sqlite3 +0 -0
  97. data/spec/{dummy/app/models → rails_applications/6.1.4/lib/assets}/.keep +0 -0
  98. data/spec/{dummy/app/models/concerns → rails_applications/6.1.4/lib/tasks}/.keep +0 -0
  99. data/spec/rails_applications/6.1.4/package.json +11 -0
  100. data/spec/{dummy → rails_applications/6.1.4}/public/404.html +67 -67
  101. data/spec/{dummy → rails_applications/6.1.4}/public/422.html +67 -67
  102. data/spec/{dummy → rails_applications/6.1.4}/public/500.html +66 -66
  103. data/spec/{dummy/lib/assets/.keep → rails_applications/6.1.4/public/apple-touch-icon-precomposed.png} +0 -0
  104. data/spec/{dummy/lib/tasks/.keep → rails_applications/6.1.4/public/apple-touch-icon.png} +0 -0
  105. data/spec/{dummy → rails_applications/6.1.4}/public/favicon.ico +0 -0
  106. data/spec/rails_applications/6.1.4/public/robots.txt +1 -0
  107. data/spec/{dummy/log → rails_applications/6.1.4/storage}/.keep +0 -0
  108. data/spec/rails_applications/7.1.3/.dockerignore +37 -0
  109. data/spec/rails_applications/7.1.3/.gitattributes +9 -0
  110. data/spec/rails_applications/7.1.3/.gitignore +35 -0
  111. data/spec/rails_applications/7.1.3/.ruby-version +1 -0
  112. data/spec/rails_applications/7.1.3/Dockerfile +62 -0
  113. data/spec/rails_applications/7.1.3/Gemfile +67 -0
  114. data/spec/rails_applications/7.1.3/README.md +24 -0
  115. data/spec/rails_applications/7.1.3/Rakefile +6 -0
  116. data/spec/rails_applications/7.1.3/app/assets/config/manifest.js +4 -0
  117. data/spec/{dummy/test/controllers → rails_applications/7.1.3/app/assets/images}/.keep +0 -0
  118. data/spec/rails_applications/7.1.3/app/assets/stylesheets/application.css +15 -0
  119. data/spec/rails_applications/7.1.3/app/channels/application_cable/channel.rb +4 -0
  120. data/spec/rails_applications/7.1.3/app/channels/application_cable/connection.rb +4 -0
  121. data/spec/rails_applications/7.1.3/app/controllers/application_controller.rb +2 -0
  122. data/spec/{dummy/test/fixtures → rails_applications/7.1.3/app/controllers/concerns}/.keep +0 -0
  123. data/spec/rails_applications/7.1.3/app/controllers/home_controller.rb +2 -0
  124. data/spec/rails_applications/7.1.3/app/helpers/application_helper.rb +2 -0
  125. data/spec/rails_applications/7.1.3/app/helpers/home_helper.rb +2 -0
  126. data/spec/rails_applications/7.1.3/app/javascript/application.js +3 -0
  127. data/spec/rails_applications/7.1.3/app/javascript/controllers/application.js +9 -0
  128. data/spec/rails_applications/7.1.3/app/javascript/controllers/hello_controller.js +7 -0
  129. data/spec/rails_applications/7.1.3/app/javascript/controllers/index.js +11 -0
  130. data/spec/rails_applications/7.1.3/app/jobs/application_job.rb +7 -0
  131. data/spec/rails_applications/7.1.3/app/mailers/application_mailer.rb +4 -0
  132. data/spec/rails_applications/7.1.3/app/models/application_record.rb +3 -0
  133. data/spec/{dummy/test/helpers → rails_applications/7.1.3/app/models/concerns}/.keep +0 -0
  134. data/spec/rails_applications/7.1.3/app/views/home/index.html.erb +3 -0
  135. data/spec/rails_applications/7.1.3/app/views/home/index.json.erb +1 -0
  136. data/spec/rails_applications/7.1.3/app/views/layouts/application.html.erb +16 -0
  137. data/spec/rails_applications/7.1.3/app/views/layouts/mailer.html.erb +13 -0
  138. data/spec/rails_applications/7.1.3/app/views/layouts/mailer.text.erb +1 -0
  139. data/spec/rails_applications/7.1.3/bin/bundle +109 -0
  140. data/spec/rails_applications/7.1.3/bin/docker-entrypoint +8 -0
  141. data/spec/rails_applications/7.1.3/bin/importmap +4 -0
  142. data/spec/rails_applications/7.1.3/bin/rails +4 -0
  143. data/spec/rails_applications/7.1.3/bin/rake +4 -0
  144. data/spec/rails_applications/7.1.3/bin/setup +33 -0
  145. data/spec/rails_applications/7.1.3/config/application.rb +27 -0
  146. data/spec/rails_applications/7.1.3/config/boot.rb +4 -0
  147. data/spec/rails_applications/7.1.3/config/cable.yml +11 -0
  148. data/spec/rails_applications/7.1.3/config/credentials.yml.enc +1 -0
  149. data/spec/rails_applications/7.1.3/config/database.yml +25 -0
  150. data/spec/rails_applications/7.1.3/config/environment.rb +5 -0
  151. data/spec/rails_applications/7.1.3/config/environments/development.rb +76 -0
  152. data/spec/rails_applications/7.1.3/config/environments/production.rb +97 -0
  153. data/spec/rails_applications/7.1.3/config/environments/test.rb +64 -0
  154. data/spec/rails_applications/7.1.3/config/importmap.rb +7 -0
  155. data/spec/rails_applications/7.1.3/config/initializers/assets.rb +12 -0
  156. data/spec/rails_applications/7.1.3/config/initializers/content_security_policy.rb +25 -0
  157. data/spec/rails_applications/7.1.3/config/initializers/filter_parameter_logging.rb +8 -0
  158. data/spec/rails_applications/7.1.3/config/initializers/inflections.rb +16 -0
  159. data/spec/rails_applications/7.1.3/config/initializers/permissions_policy.rb +13 -0
  160. data/spec/rails_applications/7.1.3/config/locales/en.yml +31 -0
  161. data/spec/rails_applications/7.1.3/config/puma.rb +35 -0
  162. data/spec/rails_applications/7.1.3/config/routes.rb +11 -0
  163. data/spec/rails_applications/7.1.3/config/storage.yml +34 -0
  164. data/spec/rails_applications/7.1.3/config.ru +6 -0
  165. data/spec/rails_applications/7.1.3/db/seeds.rb +9 -0
  166. data/spec/{dummy/test/integration → rails_applications/7.1.3/lib/assets}/.keep +0 -0
  167. data/spec/{dummy/test/mailers → rails_applications/7.1.3/lib/tasks}/.keep +0 -0
  168. data/spec/rails_applications/7.1.3/public/404.html +67 -0
  169. data/spec/rails_applications/7.1.3/public/422.html +67 -0
  170. data/spec/rails_applications/7.1.3/public/500.html +66 -0
  171. data/spec/{dummy/test/models/.keep → rails_applications/7.1.3/public/apple-touch-icon-precomposed.png} +0 -0
  172. data/spec/{dummy/vendor/assets/javascripts/.keep → rails_applications/7.1.3/public/apple-touch-icon.png} +0 -0
  173. data/spec/{dummy/vendor/assets/stylesheets/.keep → rails_applications/7.1.3/public/favicon.ico} +0 -0
  174. data/spec/rails_applications/7.1.3/public/robots.txt +1 -0
  175. data/spec/rails_applications/7.1.3/storage/.keep +0 -0
  176. data/spec/rails_applications/7.1.3/test/application_system_test_case.rb +5 -0
  177. data/spec/rails_applications/7.1.3/test/channels/application_cable/connection_test.rb +13 -0
  178. data/spec/rails_applications/7.1.3/test/controllers/.keep +0 -0
  179. data/spec/rails_applications/7.1.3/test/controllers/home_controller_test.rb +7 -0
  180. data/spec/rails_applications/7.1.3/test/fixtures/files/.keep +0 -0
  181. data/spec/rails_applications/7.1.3/test/helpers/.keep +0 -0
  182. data/spec/rails_applications/7.1.3/test/integration/.keep +0 -0
  183. data/spec/rails_applications/7.1.3/test/mailers/.keep +0 -0
  184. data/spec/rails_applications/7.1.3/test/models/.keep +0 -0
  185. data/spec/rails_applications/7.1.3/test/system/.keep +0 -0
  186. data/spec/rails_applications/7.1.3/test/test_helper.rb +15 -0
  187. data/spec/rails_applications/7.1.3/vendor/.keep +0 -0
  188. data/spec/rails_applications/7.1.3/vendor/javascript/.keep +0 -0
  189. data/spec/rails_helper.rb +8 -4
  190. data/spec/raygun/breadcrumbs/breadcrumb_spec.rb +171 -171
  191. data/spec/raygun/breadcrumbs/store_spec.rb +170 -170
  192. data/spec/services/apply_whitelist_filter_to_payload_spec.rb +251 -251
  193. data/spec/spec_helper.rb +24 -24
  194. data/spec/support/fake_logger.rb +17 -17
  195. data/test/integration/client_test.rb +19 -19
  196. data/test/rails_helper.rb +6 -0
  197. data/test/test_helper.rb +76 -72
  198. data/test/unit/affected_user_test.rb +136 -136
  199. data/test/unit/client_test.rb +812 -812
  200. data/test/unit/configuration_test.rb +202 -206
  201. data/test/unit/error_subscriber_test.rb +43 -0
  202. data/test/unit/raygun_test.rb +106 -25
  203. data/test/unit/resque_failure_test.rb +27 -24
  204. data/test/unit/sidekiq_failure_test.rb +42 -32
  205. metadata +186 -125
  206. data/.travis.yml +0 -20
  207. data/spec/dummy/.gitignore +0 -17
  208. data/spec/dummy/Gemfile +0 -47
  209. data/spec/dummy/app/assets/config/manifest.js +0 -3
  210. data/spec/dummy/app/assets/javascripts/application.js +0 -13
  211. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  212. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  213. data/spec/dummy/bin/bundle +0 -3
  214. data/spec/dummy/bin/rails +0 -9
  215. data/spec/dummy/bin/rake +0 -9
  216. data/spec/dummy/bin/setup +0 -29
  217. data/spec/dummy/bin/spring +0 -17
  218. data/spec/dummy/config/application.rb +0 -26
  219. data/spec/dummy/config/boot.rb +0 -3
  220. data/spec/dummy/config/environments/development.rb +0 -41
  221. data/spec/dummy/config/environments/production.rb +0 -79
  222. data/spec/dummy/config/environments/test.rb +0 -42
  223. data/spec/dummy/config/initializers/assets.rb +0 -11
  224. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  225. data/spec/dummy/config/initializers/session_store.rb +0 -3
  226. data/spec/dummy/config/initializers/to_time_preserves_timezone.rb +0 -10
  227. data/spec/dummy/config/routes.rb +0 -58
  228. data/spec/dummy/config/secrets.yml +0 -22
  229. data/spec/dummy/db/seeds.rb +0 -7
  230. data/spec/dummy/public/robots.txt +0 -5
  231. data/spec/dummy/test/test_helper.rb +0 -10
  232. data/spec/raygun/raygun_spec.rb +0 -47
@@ -1,812 +1,812 @@
1
- # -*- coding: utf-8 -*-
2
- require_relative "../test_helper.rb"
3
- require 'stringio'
4
-
5
- class ClientTest < Raygun::UnitTest
6
-
7
- class TestException < StandardError
8
- def initialize(message = nil)
9
- super(message || "A test message")
10
- end
11
- end
12
-
13
- class NilMessageError < StandardError
14
- def message
15
- nil
16
- end
17
- end
18
-
19
- class FakeActionDispatcherIp
20
- attr_reader :ip
21
- def initialize remote_ip
22
- @ip = remote_ip
23
- end
24
- def to_s
25
- return ip
26
- end
27
- end
28
-
29
- def setup
30
- super
31
- @client = Raygun::Client.new
32
- Raygun.configuration.record_raw_data = true
33
- fake_successful_entry
34
-
35
- # Force NZ time zone for utcOffset tests
36
- ENV['TZ'] = 'UTC-13'
37
- end
38
-
39
- def test_record_breadcrumb_does_not_crash_without_initialized_store
40
- Raygun.record_breadcrumb(
41
- message: 'aliens',
42
- category: 'exceptions',
43
- level: :info
44
- )
45
- end
46
-
47
- def test_api_key_required_message
48
- Raygun.configuration.api_key = nil
49
-
50
- $stderr.expects(:puts).with(Raygun::Client::NO_API_KEY_MESSAGE).once
51
- second_client = Raygun::Client.new
52
- end
53
-
54
- def test_track_exception
55
- response = Raygun.track_exceptions do
56
- raise TestException.new
57
- end
58
-
59
- assert response.success?
60
- end
61
-
62
- def test_error_details
63
- assert_equal exception_hash, @client.send(:error_details, test_exception)
64
- end
65
-
66
- def test_error_details_with_nil_message
67
- e = NilMessageError.new
68
- expected_message = ""
69
- assert_equal expected_message, @client.send(:error_details, e)[:message]
70
- end
71
-
72
- def test_utc_offset
73
- expected = 13
74
-
75
- assert_equal expected, @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details][:environment][:utcOffset]
76
- end
77
-
78
- def test_inner_error_details
79
- oe = TestException.new("A test message")
80
- oe.set_backtrace(["/some/folder/some_file.rb:123:in `some_method_name'"])
81
-
82
- ie = TestException.new("Inner test message")
83
- ie.set_backtrace(["/another/path/foo.rb:1234:in `block (3 levels) run'"])
84
-
85
- e = nest_exceptions(oe, ie)
86
-
87
- expected_hash = {
88
- className: "ClientTest::TestException",
89
- message: oe.message,
90
- stackTrace: [
91
- { lineNumber: "123", fileName: "/some/folder/some_file.rb", methodName: "some_method_name" }
92
- ]
93
- }
94
-
95
- # test inner error according with its availability (ruby >= 2.1)
96
- if e.respond_to? :cause
97
- expected_hash[:innerError] = {
98
- className: "ClientTest::TestException",
99
- message: ie.message,
100
- stackTrace: [
101
- { lineNumber: "1234", fileName: "/another/path/foo.rb", methodName: "block (3 levels) run"}
102
- ]
103
- }
104
- end
105
-
106
- assert_equal expected_hash, @client.send(:error_details, e)
107
- end
108
-
109
- def test_client_details
110
- expected_hash = {
111
- name: Raygun::CLIENT_NAME,
112
- version: Raygun::VERSION,
113
- clientUrl: Raygun::CLIENT_URL
114
- }
115
-
116
- assert_equal expected_hash, @client.send(:client_details)
117
- end
118
-
119
-
120
- def test_version
121
- Raygun.setup do |config|
122
- config.version = 123
123
- end
124
-
125
- assert_equal 123, @client.send(:version)
126
- end
127
-
128
- def test_affected_user
129
- test_env = { "raygun.affected_user" => { :identifier => "somepooruser@yourapp.com" } }
130
- expected_hash = test_env["raygun.affected_user"]
131
-
132
- assert_equal expected_hash, @client.send(:build_payload_hash, test_exception, test_env)[:details][:user]
133
- end
134
-
135
- def test_tags
136
- configuration_tags = %w[alpha beta gaga]
137
- explicit_env_tags = %w[one two three four]
138
- rack_env_tag = %w[test]
139
-
140
- Raygun.setup do |config|
141
- config.tags = configuration_tags
142
- end
143
-
144
- test_env = { tags: explicit_env_tags }
145
- expected_tags = configuration_tags + explicit_env_tags + rack_env_tag
146
-
147
- assert_equal expected_tags, @client.send(:build_payload_hash, test_exception, test_env)[:details][:tags]
148
- end
149
-
150
- def test_tags_with_proc
151
- configuration_tags = %w[bar]
152
- explicit_env_tags = %w[one two three four]
153
- rack_env_tag = %w[test]
154
-
155
- Raygun.setup do |config|
156
- config.tags = ->(exception, env) {
157
- [env[:foo]]
158
- }
159
- end
160
-
161
- test_env = { tags: explicit_env_tags, foo: 'bar' }
162
- expected_tags = configuration_tags + explicit_env_tags + rack_env_tag
163
-
164
- assert_equal expected_tags, @client.send(:build_payload_hash, test_exception, test_env)[:details][:tags]
165
- end
166
-
167
- def test_tags_with_multiple_send_calls
168
- configuration_tags = %w[config-tag]
169
- explicit_env_tags = %w[explicit-env-tag]
170
- rack_env_tag = %w[test]
171
-
172
- Raygun.setup do |config|
173
- config.tags = configuration_tags
174
- end
175
-
176
- test_env = { tags: explicit_env_tags }
177
- expected_tags_1 = configuration_tags + explicit_env_tags + rack_env_tag
178
-
179
- assert_equal expected_tags_1, @client.send(:build_payload_hash, test_exception, test_env)[:details][:tags]
180
-
181
- # Tags passed in via the `env` parameter should not persist once the crash report has been sent
182
- expected_tags_2 = configuration_tags + rack_env_tag
183
-
184
- assert_equal expected_tags_2, @client.send(:build_payload_hash, test_exception)[:details][:tags]
185
- end
186
-
187
- def test_hostname
188
- assert_equal Socket.gethostname, @client.send(:hostname)
189
- end
190
-
191
- def test_unicode
192
- e = TestException.new('日本語のメッセージ です')
193
-
194
- assert_silent { @client.track_exception(e) }
195
- end
196
-
197
- def test_bad_encoding
198
- bad_message = (100..1000).to_a.pack('c*').force_encoding('utf-8')
199
- bad_exception = TestException.new(bad_message)
200
-
201
- assert !bad_message.valid_encoding?
202
- assert_silent { @client.track_exception(bad_exception) }
203
- end
204
-
205
- def test_backtrace_without_method_name
206
-
207
- expected = {
208
- lineNumber: "123",
209
- fileName: "/some/folder/some_file.rb",
210
- methodName: "(none)"
211
- }
212
-
213
- # note lack of "in method name" in this stack trace line
214
- assert_equal expected, @client.send(:stack_trace_for, "/some/folder/some_file.rb:123")
215
- end
216
-
217
- def test_full_payload_hash
218
- Timecop.freeze do
219
- Raygun.configuration.version = 123
220
- grouping_key = "my custom group"
221
- correlation_id = "my correlation id"
222
-
223
- expected_hash = {
224
- occurredOn: Time.now.utc.iso8601,
225
- details: {
226
- machineName: Socket.gethostname,
227
- version: 123,
228
- client: {
229
- name: Raygun::CLIENT_NAME,
230
- version: Raygun::VERSION,
231
- clientUrl: Raygun::CLIENT_URL
232
- },
233
- error: exception_hash,
234
- userCustomData: {},
235
- tags: ["test"],
236
- request: {},
237
- groupingKey: grouping_key,
238
- correlationId: correlation_id,
239
- environment: {
240
- utcOffset: 13
241
- }
242
- }
243
- }
244
-
245
- assert_equal expected_hash, @client.send(:build_payload_hash, test_exception, { grouping_key: grouping_key, correlation_id: correlation_id })
246
- end
247
- end
248
-
249
- def test_getting_request_information
250
- env_hash = sample_env_hash.merge({
251
- "QUERY_STRING"=>"a=b&c=4945438",
252
- "REQUEST_URI"=>"/?a=b&c=4945438",
253
- })
254
-
255
- expected_hash = {
256
- hostName: "localhost",
257
- url: "/",
258
- httpMethod: "GET",
259
- iPAddress: "127.0.0.1",
260
- queryString: { "a" => "b", "c" => "4945438" },
261
- headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
262
- form: {},
263
- rawData: nil
264
- }
265
-
266
- assert_equal expected_hash, @client.send(:request_information, env_hash)
267
- end
268
-
269
- def test_getting_request_information_with_nil_env
270
- assert_equal({}, @client.send(:request_information, nil))
271
- end
272
-
273
- def test_raw_post_body
274
- env_hash = sample_env_hash.merge({
275
- "CONTENT_TYPE" => "application/json",
276
- "REQUEST_METHOD" => "POST",
277
- "rack.input" => StringIO.new('{"foo": "bar"}')
278
- })
279
-
280
- assert_equal '{"foo": "bar"}', @client.send(:request_information, env_hash)[:rawData]
281
- end
282
-
283
- def test_raw_post_body_with_more_than_4096_chars
284
- input = "0" * 5000;
285
- env_hash = sample_env_hash.merge({
286
- "CONTENT_TYPE" => "application/json",
287
- "REQUEST_METHOD" => "POST",
288
- "rack.input" => StringIO.new(input)
289
- })
290
-
291
- assert_equal input.slice(0, 4096), @client.send(:request_information, env_hash)[:rawData]
292
- end
293
-
294
- def test_raw_post_body_with_config_disabled
295
- Raygun.configuration.record_raw_data = false
296
- env_hash = sample_env_hash.merge({
297
- "CONTENT_TYPE" => "application/json",
298
- "REQUEST_METHOD" => "POST",
299
- "rack.input" => StringIO.new('{"foo": "bar"}')
300
- })
301
-
302
- assert_equal(nil, @client.send(:request_information, env_hash)[:rawData])
303
- end
304
-
305
- def test_error_raygun_custom_data
306
- custom_data = { "kappa" => "keepo" }
307
- e = Raygun::Error.new("A test message", custom_data)
308
- test_env = {}
309
- expected_form_hash = test_env.merge(custom_data)
310
-
311
- assert_equal expected_form_hash, @client.send(:build_payload_hash, e, test_env)[:details][:userCustomData]
312
- end
313
-
314
- def test_custom_data_configuration_with_hash
315
- custom_data = {foo: '123'}
316
- Raygun.configuration.custom_data = custom_data
317
-
318
- assert_equal custom_data, @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details][:userCustomData]
319
- end
320
-
321
- def test_custom_data_configuration_with_proc
322
- Raygun.configuration.custom_data do |exception, env|
323
- {exception_message: exception.message, server_name: env["SERVER_NAME"]}
324
- end
325
- expected = {
326
- exception_message: "A test message",
327
- server_name: "localhost"
328
- }
329
-
330
- assert_equal expected, @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details][:userCustomData]
331
- end
332
-
333
- def test_filtering_parameters
334
- post_body_env_hash = sample_env_hash.merge(
335
- "REQUEST_METHOD" => "POST",
336
- "rack.input"=>StringIO.new("a=b&c=4945438&password=swordfish")
337
- )
338
-
339
- expected_form_hash = { "a" => "b", "c" => "4945438", "password" => "[FILTERED]" }
340
-
341
- assert_equal expected_form_hash, @client.send(:request_information, post_body_env_hash)[:form]
342
- end
343
-
344
- def test_filtering_nested_params
345
- post_body_env_hash = sample_env_hash.merge(
346
- "REQUEST_METHOD" => "POST",
347
- "rack.input" => StringIO.new("a=b&bank%5Bcredit_card%5D%5Bcard_number%5D=my_secret_bank_number&bank%5Bname%5D=something&c=123456&user%5Bpassword%5D=my_fancy_password")
348
- )
349
-
350
- expected_form_hash = { "a" => "b", "bank" => { "credit_card" => { "card_number" => "[FILTERED]" }, "name" => "something" }, "c" => "123456", "user" => { "password" => "[FILTERED]" } }
351
-
352
- assert_equal expected_form_hash, @client.send(:request_information, post_body_env_hash)[:form]
353
- end
354
-
355
- def test_filter_parameters_using_proc
356
- # filter any parameters that start with "nsa_only"
357
- Raygun.configuration.filter_parameters do |hash|
358
- hash.inject({}) do |sanitized_hash, (k, v)|
359
- sanitized_hash[k] = if k.start_with? "nsa_only"
360
- "[OUREYESONLY]"
361
- else
362
- v
363
- end
364
- sanitized_hash
365
- end
366
- end
367
-
368
- post_body_env_hash = sample_env_hash.merge(
369
- "REQUEST_METHOD" => "POST",
370
- "rack.input" => StringIO.new("nsa_only_info=123&nsa_only_metadata=seekrit&something_normal=hello")
371
- )
372
-
373
- expected_form_hash = { "nsa_only_info" => "[OUREYESONLY]", "nsa_only_metadata" => "[OUREYESONLY]", "something_normal" => "hello" }
374
-
375
- assert_equal expected_form_hash, @client.send(:request_information, post_body_env_hash)[:form]
376
- ensure
377
- Raygun.configuration.filter_parameters = nil
378
- end
379
-
380
- def test_filter_parameters_using_array
381
- filter_params_as_from_rails = [:password]
382
- Raygun.configuration.filter_parameters = filter_params_as_from_rails
383
-
384
- parameters = {
385
- "something_normal" => "hello",
386
- "password" => "wouldntyouliketoknow",
387
- "password_confirmation" => "wouldntyouliketoknow",
388
- "PasswORD_weird_case" => "anythingatall"
389
- }
390
-
391
- expected_form_hash = {
392
- "something_normal" => "hello",
393
- "password" => "[FILTERED]",
394
- "password_confirmation" => "[FILTERED]",
395
- "PasswORD_weird_case" => "[FILTERED]"
396
- }
397
-
398
- post_body_env_hash = sample_env_hash.merge(
399
- "REQUEST_METHOD" => "POST",
400
- "rack.input" => StringIO.new(URI.encode_www_form(parameters))
401
- )
402
-
403
- assert_equal expected_form_hash, @client.send(:request_information, post_body_env_hash)[:form]
404
- ensure
405
- Raygun.configuration.filter_parameters = nil
406
- end
407
-
408
- def test_ip_address_from_action_dispatch
409
- env_hash = sample_env_hash.merge({
410
- "action_dispatch.remote_ip"=> "123.456.789.012"
411
- })
412
-
413
- assert_equal "123.456.789.012", @client.send(:ip_address_from, env_hash)
414
- assert_equal "123.456.789.012", @client.send(:request_information, env_hash)[:iPAddress]
415
- end
416
-
417
- def test_ip_address_from_old_action_dispatch
418
- old_action_dispatch_ip = FakeActionDispatcherIp.new("123.456.789.012")
419
- env_hash = sample_env_hash.merge({
420
- "action_dispatch.remote_ip"=> old_action_dispatch_ip
421
- })
422
-
423
- assert_equal old_action_dispatch_ip, @client.send(:ip_address_from, env_hash)
424
- assert_equal "123.456.789.012", @client.send(:request_information, env_hash)[:iPAddress]
425
- end
426
-
427
- def test_ip_address_from_raygun_specific_key
428
- env_hash = sample_env_hash.merge({
429
- "raygun.remote_ip"=>"123.456.789.012"
430
- })
431
-
432
- assert_equal "123.456.789.012", @client.send(:ip_address_from, env_hash)
433
- assert_equal "123.456.789.012", @client.send(:request_information, env_hash)[:iPAddress]
434
- end
435
-
436
- def test_ip_address_returns_not_available_if_not_set
437
- env_hash = sample_env_hash.dup
438
- env_hash.delete("REMOTE_ADDR")
439
-
440
- assert_equal "(Not Available)", @client.send(:ip_address_from, env_hash)
441
- end
442
-
443
- def test_setting_up_http_proxy
444
- begin
445
- Raygun.configuration.proxy_settings[:address] = "http://proxy.com"
446
- Raygun::Client.expects(:http_proxy).with("http://proxy.com", "80", nil, nil)
447
-
448
- Raygun.track_exceptions do
449
- raise TestException.new
450
- end
451
- ensure
452
- Raygun.configuration.proxy_settings = {}
453
- end
454
- end
455
-
456
- def test_filter_payload_with_whitelist_never_filters_toplevel
457
- Timecop.freeze do
458
- Raygun.configuration.filter_payload_with_whitelist = true
459
- Raygun.configuration.whitelist_payload_shape = {}
460
-
461
- e = test_exception
462
-
463
- assert_equal Time.now.utc.iso8601, @client.send(:build_payload_hash, e)[:occurredOn]
464
- assert_equal Hash, @client.send(:build_payload_hash, e)[:details].class
465
- end
466
- end
467
-
468
- def test_filter_payload_with_whitelist_never_filters_client
469
- Raygun.configuration.filter_payload_with_whitelist = true
470
- Raygun.configuration.whitelist_payload_shape = {}
471
-
472
- client_details = @client.send(:client_details)
473
-
474
- assert_equal client_details, @client.send(:build_payload_hash, test_exception)[:details][:client]
475
- end
476
-
477
- def test_filter_payload_with_whitelist_default_error
478
- Raygun.configuration.filter_payload_with_whitelist = true
479
-
480
- details = @client.send(:build_payload_hash, test_exception)[:details]
481
-
482
- assert_equal exception_hash, details[:error]
483
- end
484
-
485
- def test_filter_payload_with_whitelist_exclude_error_keys
486
- Raygun.configuration.filter_payload_with_whitelist = true
487
- Raygun.configuration.whitelist_payload_shape = {
488
- error: {
489
- className: true,
490
- message: true,
491
- stackTrace: true
492
- }
493
- }
494
-
495
- details = @client.send(:build_payload_hash, test_exception)[:details]
496
-
497
- assert_equal exception_hash, details[:error]
498
- end
499
-
500
- def test_filter_payload_with_whitelist_exclude_error_except_stacktrace
501
- Raygun.configuration.filter_payload_with_whitelist = true
502
- Raygun.configuration.whitelist_payload_shape = {
503
- error: {
504
- className: true,
505
- message: true,
506
- }
507
- }
508
-
509
- details = @client.send(:build_payload_hash, test_exception)[:details]
510
-
511
- expected_hash = exception_hash.merge({
512
- stackTrace: "[FILTERED]"
513
- })
514
-
515
- assert_equal expected_hash, details[:error]
516
- end
517
-
518
- def test_filter_payload_with_whitelist_proc
519
- Raygun.configuration.filter_payload_with_whitelist = true
520
- Raygun.configuration.whitelist_payload_shape do |payload|
521
- payload
522
- end
523
-
524
- details = @client.send(:build_payload_hash, test_exception)[:details]
525
-
526
- assert_equal exception_hash, details[:error]
527
- end
528
-
529
- def test_filter_payload_with_whitelist_default_request_post
530
- Raygun.configuration.filter_payload_with_whitelist = true
531
-
532
- post_body_env_hash = sample_env_hash.merge(
533
- "CONTENT_TYPE" => 'application/x-www-form-urlencoded',
534
- "REQUEST_METHOD" => "POST",
535
- "rack.input"=>StringIO.new("a=b&c=4945438&password=swordfish")
536
- )
537
-
538
- details = @client.send(:build_payload_hash, test_exception, post_body_env_hash)[:details]
539
-
540
- expected_hash = {
541
- hostName: "localhost",
542
- url: "/",
543
- httpMethod: "POST",
544
- iPAddress: "127.0.0.1",
545
- queryString: { },
546
- headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
547
- form: { "a" => "[FILTERED]", "c" => "[FILTERED]", "password" => "[FILTERED]" },
548
- rawData: {}
549
- }
550
-
551
- assert_equal expected_hash, details[:request]
552
- end
553
-
554
- def test_filter_payload_with_whitelist_request_post_except_formkey
555
- Raygun.configuration.filter_payload_with_whitelist = true
556
- shape = Raygun.configuration.whitelist_payload_shape.dup
557
- shape[:request] = Raygun.configuration.whitelist_payload_shape[:request].merge(
558
- form: {
559
- username: true
560
- }
561
- )
562
- Raygun.configuration.whitelist_payload_shape = shape
563
-
564
- post_body_env_hash = sample_env_hash.merge(
565
- "REQUEST_METHOD" => "POST",
566
- "rack.input"=>StringIO.new("username=foo&password=swordfish")
567
- )
568
-
569
- details = @client.send(:build_payload_hash, test_exception, post_body_env_hash)[:details]
570
-
571
- expected_hash = {
572
- hostName: "localhost",
573
- url: "/",
574
- httpMethod: "POST",
575
- iPAddress: "127.0.0.1",
576
- queryString: { },
577
- headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
578
- form: { "username" => "foo", "password" => "[FILTERED]" },
579
- rawData: {}
580
- }
581
-
582
- assert_equal expected_hash, details[:request]
583
- end
584
-
585
- def test_filter_payload_with_whitelist_default_request_get
586
- Raygun.configuration.filter_payload_with_whitelist = true
587
-
588
- env_hash = sample_env_hash.merge({
589
- "QUERY_STRING"=>"a=b&c=4945438",
590
- "REQUEST_URI"=>"/?a=b&c=4945438",
591
- })
592
- expected_hash = {
593
- hostName: "localhost",
594
- url: "/",
595
- httpMethod: "GET",
596
- iPAddress: "127.0.0.1",
597
- queryString: { "a" => "b", "c" => "4945438" },
598
- headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
599
- form: {},
600
- rawData: nil
601
- }
602
-
603
- details = @client.send(:build_payload_hash, test_exception, env_hash)[:details]
604
-
605
- assert_equal expected_hash, details[:request]
606
- end
607
-
608
- def test_filter_payload_with_whitelist_default_request_get_except_querystring
609
- Raygun.configuration.filter_payload_with_whitelist = true
610
- shape = Raygun.configuration.whitelist_payload_shape.dup
611
- shape[:request] = Raygun::Configuration::DEFAULT_WHITELIST_PAYLOAD_SHAPE_REQUEST.dup.tap do |h|
612
- h.delete(:queryString)
613
- end
614
- Raygun.configuration.whitelist_payload_shape = shape
615
-
616
- expected_hash = {
617
- hostName: "localhost",
618
- url: "/",
619
- httpMethod: "GET",
620
- iPAddress: "127.0.0.1",
621
- queryString: "[FILTERED]",
622
- headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
623
- form: {},
624
- rawData: nil
625
- }
626
-
627
- details = @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details]
628
-
629
- assert_equal expected_hash, details[:request]
630
- end
631
-
632
- def test_filter_payload_with_whitelist_being_false_does_not_filter_query_string
633
- Raygun.configuration.filter_payload_with_whitelist = false
634
-
635
- env_hash = sample_env_hash.merge({
636
- "QUERY_STRING"=>"a=b&c=4945438",
637
- "REQUEST_URI"=>"/?a=b&c=4945438",
638
- })
639
- expected_hash = {
640
- hostName: "localhost",
641
- url: "/",
642
- httpMethod: "GET",
643
- iPAddress: "127.0.0.1",
644
- queryString: { "a" => "b", "c" => "4945438" },
645
- headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
646
- form: {},
647
- rawData: nil
648
- }
649
-
650
- details = @client.send(:build_payload_hash, test_exception, env_hash)[:details]
651
-
652
- assert_equal expected_hash, details[:request]
653
- end
654
-
655
- def test_filter_payload_with_whitelist_request_specific_keys
656
- Raygun.configuration.filter_payload_with_whitelist = true
657
- Raygun.configuration.whitelist_payload_shape = {
658
- request: {
659
- url: true,
660
- httpMethod: true,
661
- hostName: true
662
- }
663
- }
664
-
665
- details = @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details]
666
-
667
- expected_hash = {
668
- hostName: "localhost",
669
- url: "/",
670
- httpMethod: "GET",
671
- iPAddress: "[FILTERED]",
672
- queryString: "[FILTERED]",
673
- headers: "[FILTERED]",
674
- form: "[FILTERED]",
675
- rawData: "[FILTERED]"
676
- }
677
-
678
- assert_equal expected_hash, details[:request]
679
- end
680
-
681
-
682
- def test_filter_payload_with_whitelist_and_filter_parameters_applies_both
683
- Raygun.configuration.filter_parameters = [:password]
684
- Raygun.configuration.filter_payload_with_whitelist = true
685
- Raygun.configuration.whitelist_payload_shape = proc do |payload|
686
- payload[:request][:headers]["Cookie"] = "[FILTERED]"
687
- payload
688
- end
689
-
690
- parameters = {
691
- "something_normal" => "hello",
692
- "password" => "wouldntyouliketoknow"
693
- }
694
-
695
- post_body_env_hash = sample_env_hash.merge(
696
- "REQUEST_METHOD" => "POST",
697
- "rack.input" => StringIO.new(URI.encode_www_form(parameters))
698
- )
699
-
700
- payload = @client.send(:build_payload_hash, test_exception, post_body_env_hash)
701
- request_payload = payload[:details][:request]
702
-
703
- expected_form = {
704
- "something_normal" => "hello",
705
- "password" => "[FILTERED]"
706
- }
707
-
708
- assert_equal expected_form, request_payload[:form]
709
-
710
- expected_headers = {
711
- "Version" => "HTTP/1.1",
712
- "Host" => "localhost:3000",
713
- "Cookie" => "[FILTERED]"
714
- }
715
-
716
- assert_equal expected_headers, request_payload[:headers]
717
- end
718
-
719
- def test_build_payload_hash_adds_affected_user_details_when_supplied_with_user
720
- user = OpenStruct.new(id: '123', email: 'test@email.com', first_name: 'Taylor')
721
- expected_details = {
722
- :isAnonymous => false,
723
- :identifier => '123',
724
- :email => 'test@email.com',
725
- :firstName => 'Taylor',
726
- }
727
-
728
- user_details = @client.send(:build_payload_hash, test_exception, sample_env_hash, user)[:details][:user]
729
-
730
- assert_equal expected_details, user_details
731
- end
732
-
733
- def test_build_payload_includes_breadcrumbs
734
- ::Raygun::Breadcrumbs::Store.initialize
735
- ::Raygun::Breadcrumbs::Store.record(message: "foo")
736
-
737
- breadcrumbs = @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details][:breadcrumbs]
738
- ::Raygun::Breadcrumbs::Store.clear
739
-
740
- assert_equal breadcrumbs.length, 1
741
- assert breadcrumbs[0].is_a? Hash
742
- end
743
-
744
- def test_raw_data_does_not_crash_on_buffer_without_pos
745
- buffer = StringIO.new('123456789')
746
- rack_env = {
747
- REQUEST_METHOD: 'POST',
748
- 'rack.input' => buffer
749
- }
750
-
751
- buffer.instance_eval('undef :pos')
752
-
753
- raw_data = @client.send(:raw_data, rack_env)
754
-
755
- assert_equal('123456789', raw_data)
756
- end
757
-
758
- private
759
-
760
- def test_exception
761
- e = TestException.new
762
- e.set_backtrace(["/some/folder/some_file.rb:123:in `some_method_name'",
763
- "/another/path/foo.rb:1234:in `block (3 levels) run'"])
764
-
765
- e
766
- end
767
-
768
- def nest_exceptions(outer_exception, inner_exception)
769
- begin
770
- begin
771
- raise inner_exception.class, inner_exception.message
772
- rescue => e
773
- e.set_backtrace inner_exception.backtrace
774
- raise outer_exception.class, outer_exception.message
775
- end
776
- rescue => nested_exception
777
- nested_exception.set_backtrace outer_exception.backtrace
778
- end
779
-
780
- nested_exception
781
- end
782
-
783
- def exception_hash
784
- {
785
- className: "ClientTest::TestException",
786
- message: "A test message",
787
- stackTrace: [
788
- { lineNumber: "123", fileName: "/some/folder/some_file.rb", methodName: "some_method_name" },
789
- { lineNumber: "1234", fileName: "/another/path/foo.rb", methodName: "block (3 levels) run"}
790
- ]
791
- }
792
- end
793
-
794
- def sample_env_hash
795
- {
796
- "SERVER_NAME"=>"localhost",
797
- "REQUEST_METHOD"=>"GET",
798
- "REQUEST_PATH"=>"/",
799
- "PATH_INFO"=>"/",
800
- "QUERY_STRING"=>"",
801
- "REQUEST_URI"=>"/",
802
- "HTTP_VERSION"=>"HTTP/1.1",
803
- "HTTP_HOST"=>"localhost:3000",
804
- "HTTP_COOKIE"=>"cookieval",
805
- "GATEWAY_INTERFACE"=>"CGI/1.2",
806
- "SERVER_PORT"=>"3000",
807
- "SERVER_PROTOCOL"=>"HTTP/1.1",
808
- "SCRIPT_NAME"=>"",
809
- "REMOTE_ADDR"=>"127.0.0.1"
810
- }
811
- end
812
- end
1
+ # -*- coding: utf-8 -*-
2
+ require_relative "../test_helper.rb"
3
+ require 'stringio'
4
+
5
+ class ClientTest < Raygun::UnitTest
6
+
7
+ class TestException < StandardError
8
+ def initialize(message = nil)
9
+ super(message || "A test message")
10
+ end
11
+ end
12
+
13
+ class NilMessageError < StandardError
14
+ def message
15
+ nil
16
+ end
17
+ end
18
+
19
+ class FakeActionDispatcherIp
20
+ attr_reader :ip
21
+ def initialize remote_ip
22
+ @ip = remote_ip
23
+ end
24
+ def to_s
25
+ return ip
26
+ end
27
+ end
28
+
29
+ def setup
30
+ super
31
+ @client = Raygun::Client.new
32
+ Raygun.configuration.record_raw_data = true
33
+ fake_successful_entry
34
+
35
+ # Force NZ time zone for utcOffset tests
36
+ ENV['TZ'] = 'UTC-13'
37
+ end
38
+
39
+ def test_record_breadcrumb_does_not_crash_without_initialized_store
40
+ Raygun.record_breadcrumb(
41
+ message: 'aliens',
42
+ category: 'exceptions',
43
+ level: :info
44
+ )
45
+ end
46
+
47
+ def test_api_key_required_message
48
+ Raygun.configuration.api_key = nil
49
+
50
+ $stderr.expects(:puts).with(Raygun::Client::NO_API_KEY_MESSAGE).once
51
+ Raygun::Client.new
52
+ end
53
+
54
+ def test_track_exception
55
+ response = Raygun.track_exceptions do
56
+ raise TestException.new
57
+ end
58
+
59
+ assert response.success?
60
+ end
61
+
62
+ def test_error_details
63
+ assert_equal exception_hash, @client.send(:error_details, test_exception)
64
+ end
65
+
66
+ def test_error_details_with_nil_message
67
+ e = NilMessageError.new
68
+ expected_message = ""
69
+ assert_equal expected_message, @client.send(:error_details, e)[:message]
70
+ end
71
+
72
+ def test_utc_offset
73
+ expected = 13
74
+
75
+ assert_equal expected, @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details][:environment][:utcOffset]
76
+ end
77
+
78
+ def test_inner_error_details
79
+ oe = TestException.new("A test message")
80
+ oe.set_backtrace(["/some/folder/some_file.rb:123:in `some_method_name'"])
81
+
82
+ ie = TestException.new("Inner test message")
83
+ ie.set_backtrace(["/another/path/foo.rb:1234:in `block (3 levels) run'"])
84
+
85
+ e = nest_exceptions(oe, ie)
86
+
87
+ expected_hash = {
88
+ className: "ClientTest::TestException",
89
+ message: oe.message,
90
+ stackTrace: [
91
+ { lineNumber: "123", fileName: "/some/folder/some_file.rb", methodName: "some_method_name" }
92
+ ]
93
+ }
94
+
95
+ # test inner error according with its availability (ruby >= 2.1)
96
+ if e.respond_to? :cause
97
+ expected_hash[:innerError] = {
98
+ className: "ClientTest::TestException",
99
+ message: ie.message,
100
+ stackTrace: [
101
+ { lineNumber: "1234", fileName: "/another/path/foo.rb", methodName: "block (3 levels) run"}
102
+ ]
103
+ }
104
+ end
105
+
106
+ assert_equal expected_hash, @client.send(:error_details, e)
107
+ end
108
+
109
+ def test_client_details
110
+ expected_hash = {
111
+ name: Raygun::CLIENT_NAME,
112
+ version: Raygun::VERSION,
113
+ clientUrl: Raygun::CLIENT_URL
114
+ }
115
+
116
+ assert_equal expected_hash, @client.send(:client_details)
117
+ end
118
+
119
+
120
+ def test_version
121
+ Raygun.setup do |config|
122
+ config.version = 123
123
+ end
124
+
125
+ assert_equal 123, @client.send(:version)
126
+ end
127
+
128
+ def test_affected_user
129
+ test_env = { "raygun.affected_user" => { :identifier => "somepooruser@yourapp.com" } }
130
+ expected_hash = test_env["raygun.affected_user"]
131
+
132
+ assert_equal expected_hash, @client.send(:build_payload_hash, test_exception, test_env)[:details][:user]
133
+ end
134
+
135
+ def test_tags
136
+ configuration_tags = %w[alpha beta gaga]
137
+ explicit_env_tags = %w[one two three four]
138
+ rack_env_tag = %w[test]
139
+
140
+ Raygun.setup do |config|
141
+ config.tags = configuration_tags
142
+ end
143
+
144
+ test_env = { tags: explicit_env_tags }
145
+ expected_tags = configuration_tags + explicit_env_tags + rack_env_tag
146
+
147
+ assert_equal expected_tags, @client.send(:build_payload_hash, test_exception, test_env)[:details][:tags]
148
+ end
149
+
150
+ def test_tags_with_proc
151
+ configuration_tags = %w[bar]
152
+ explicit_env_tags = %w[one two three four]
153
+ rack_env_tag = %w[test]
154
+
155
+ Raygun.setup do |config|
156
+ config.tags = ->(exception, env) {
157
+ [env[:foo]]
158
+ }
159
+ end
160
+
161
+ test_env = { tags: explicit_env_tags, foo: 'bar' }
162
+ expected_tags = configuration_tags + explicit_env_tags + rack_env_tag
163
+
164
+ assert_equal expected_tags, @client.send(:build_payload_hash, test_exception, test_env)[:details][:tags]
165
+ end
166
+
167
+ def test_tags_with_multiple_send_calls
168
+ configuration_tags = %w[config-tag]
169
+ explicit_env_tags = %w[explicit-env-tag]
170
+ rack_env_tag = %w[test]
171
+
172
+ Raygun.setup do |config|
173
+ config.tags = configuration_tags
174
+ end
175
+
176
+ test_env = { tags: explicit_env_tags }
177
+ expected_tags_1 = configuration_tags + explicit_env_tags + rack_env_tag
178
+
179
+ assert_equal expected_tags_1, @client.send(:build_payload_hash, test_exception, test_env)[:details][:tags]
180
+
181
+ # Tags passed in via the `env` parameter should not persist once the crash report has been sent
182
+ expected_tags_2 = configuration_tags + rack_env_tag
183
+
184
+ assert_equal expected_tags_2, @client.send(:build_payload_hash, test_exception)[:details][:tags]
185
+ end
186
+
187
+ def test_hostname
188
+ assert_equal Socket.gethostname, @client.send(:hostname)
189
+ end
190
+
191
+ def test_unicode
192
+ e = TestException.new('日本語のメッセージ です')
193
+
194
+ assert_silent { @client.track_exception(e) }
195
+ end
196
+
197
+ def test_bad_encoding
198
+ bad_message = (100..1000).to_a.pack('c*').force_encoding('utf-8')
199
+ bad_exception = TestException.new(bad_message)
200
+
201
+ assert !bad_message.valid_encoding?
202
+ assert_silent { @client.track_exception(bad_exception) }
203
+ end
204
+
205
+ def test_backtrace_without_method_name
206
+
207
+ expected = {
208
+ lineNumber: "123",
209
+ fileName: "/some/folder/some_file.rb",
210
+ methodName: "(none)"
211
+ }
212
+
213
+ # note lack of "in method name" in this stack trace line
214
+ assert_equal expected, @client.send(:stack_trace_for, "/some/folder/some_file.rb:123")
215
+ end
216
+
217
+ def test_full_payload_hash
218
+ Timecop.freeze do
219
+ Raygun.configuration.version = 123
220
+ grouping_key = "my custom group"
221
+ correlation_id = "my correlation id"
222
+
223
+ expected_hash = {
224
+ occurredOn: Time.now.utc.iso8601,
225
+ details: {
226
+ machineName: Socket.gethostname,
227
+ version: 123,
228
+ client: {
229
+ name: Raygun::CLIENT_NAME,
230
+ version: Raygun::VERSION,
231
+ clientUrl: Raygun::CLIENT_URL
232
+ },
233
+ error: exception_hash,
234
+ userCustomData: {},
235
+ tags: ["test"],
236
+ request: {},
237
+ groupingKey: grouping_key,
238
+ correlationId: correlation_id,
239
+ environment: {
240
+ utcOffset: 13
241
+ }
242
+ }
243
+ }
244
+
245
+ assert_equal expected_hash, @client.send(:build_payload_hash, test_exception, { grouping_key: grouping_key, correlation_id: correlation_id })
246
+ end
247
+ end
248
+
249
+ def test_getting_request_information
250
+ env_hash = sample_env_hash.merge({
251
+ "QUERY_STRING"=>"a=b&c=4945438",
252
+ "REQUEST_URI"=>"/?a=b&c=4945438",
253
+ })
254
+
255
+ expected_hash = {
256
+ hostName: "localhost",
257
+ url: "/",
258
+ httpMethod: "GET",
259
+ iPAddress: "127.0.0.1",
260
+ queryString: { "a" => "b", "c" => "4945438" },
261
+ headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
262
+ form: {},
263
+ rawData: nil
264
+ }
265
+
266
+ assert_equal expected_hash, @client.send(:request_information, env_hash)
267
+ end
268
+
269
+ def test_getting_request_information_with_nil_env
270
+ assert_equal({}, @client.send(:request_information, nil))
271
+ end
272
+
273
+ def test_raw_post_body
274
+ env_hash = sample_env_hash.merge({
275
+ "CONTENT_TYPE" => "application/json",
276
+ "REQUEST_METHOD" => "POST",
277
+ "rack.input" => StringIO.new('{"foo": "bar"}')
278
+ })
279
+
280
+ assert_equal '{"foo": "bar"}', @client.send(:request_information, env_hash)[:rawData]
281
+ end
282
+
283
+ def test_raw_post_body_with_more_than_4096_chars
284
+ input = "0" * 5000;
285
+ env_hash = sample_env_hash.merge({
286
+ "CONTENT_TYPE" => "application/json",
287
+ "REQUEST_METHOD" => "POST",
288
+ "rack.input" => StringIO.new(input)
289
+ })
290
+
291
+ assert_equal input.slice(0, 4096), @client.send(:request_information, env_hash)[:rawData]
292
+ end
293
+
294
+ def test_raw_post_body_with_config_disabled
295
+ Raygun.configuration.record_raw_data = false
296
+ env_hash = sample_env_hash.merge({
297
+ "CONTENT_TYPE" => "application/json",
298
+ "REQUEST_METHOD" => "POST",
299
+ "rack.input" => StringIO.new('{"foo": "bar"}')
300
+ })
301
+
302
+ assert_nil(@client.send(:request_information, env_hash)[:rawData])
303
+ end
304
+
305
+ def test_error_raygun_custom_data
306
+ custom_data = { "kappa" => "keepo" }
307
+ e = Raygun::Error.new("A test message", custom_data)
308
+ test_env = {}
309
+ expected_form_hash = test_env.merge(custom_data)
310
+
311
+ assert_equal expected_form_hash, @client.send(:build_payload_hash, e, test_env)[:details][:userCustomData]
312
+ end
313
+
314
+ def test_custom_data_configuration_with_hash
315
+ custom_data = {foo: '123'}
316
+ Raygun.configuration.custom_data = custom_data
317
+
318
+ assert_equal custom_data, @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details][:userCustomData]
319
+ end
320
+
321
+ def test_custom_data_configuration_with_proc
322
+ Raygun.configuration.custom_data do |exception, env|
323
+ {exception_message: exception.message, server_name: env["SERVER_NAME"]}
324
+ end
325
+ expected = {
326
+ exception_message: "A test message",
327
+ server_name: "localhost"
328
+ }
329
+
330
+ assert_equal expected, @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details][:userCustomData]
331
+ end
332
+
333
+ def test_filtering_parameters
334
+ post_body_env_hash = sample_env_hash.merge(
335
+ "REQUEST_METHOD" => "POST",
336
+ "rack.input"=>StringIO.new("a=b&c=4945438&password=swordfish")
337
+ )
338
+
339
+ expected_form_hash = { "a" => "b", "c" => "4945438", "password" => "[FILTERED]" }
340
+
341
+ assert_equal expected_form_hash, @client.send(:request_information, post_body_env_hash)[:form]
342
+ end
343
+
344
+ def test_filtering_nested_params
345
+ post_body_env_hash = sample_env_hash.merge(
346
+ "REQUEST_METHOD" => "POST",
347
+ "rack.input" => StringIO.new("a=b&bank%5Bcredit_card%5D%5Bcard_number%5D=my_secret_bank_number&bank%5Bname%5D=something&c=123456&user%5Bpassword%5D=my_fancy_password")
348
+ )
349
+
350
+ expected_form_hash = { "a" => "b", "bank" => { "credit_card" => { "card_number" => "[FILTERED]" }, "name" => "something" }, "c" => "123456", "user" => { "password" => "[FILTERED]" } }
351
+
352
+ assert_equal expected_form_hash, @client.send(:request_information, post_body_env_hash)[:form]
353
+ end
354
+
355
+ def test_filter_parameters_using_proc
356
+ # filter any parameters that start with "nsa_only"
357
+ Raygun.configuration.filter_parameters do |hash|
358
+ hash.inject({}) do |sanitized_hash, (k, v)|
359
+ sanitized_hash[k] = if k.start_with? "nsa_only"
360
+ "[OUREYESONLY]"
361
+ else
362
+ v
363
+ end
364
+ sanitized_hash
365
+ end
366
+ end
367
+
368
+ post_body_env_hash = sample_env_hash.merge(
369
+ "REQUEST_METHOD" => "POST",
370
+ "rack.input" => StringIO.new("nsa_only_info=123&nsa_only_metadata=seekrit&something_normal=hello")
371
+ )
372
+
373
+ expected_form_hash = { "nsa_only_info" => "[OUREYESONLY]", "nsa_only_metadata" => "[OUREYESONLY]", "something_normal" => "hello" }
374
+
375
+ assert_equal expected_form_hash, @client.send(:request_information, post_body_env_hash)[:form]
376
+ ensure
377
+ Raygun.configuration.filter_parameters = nil
378
+ end
379
+
380
+ def test_filter_parameters_using_array
381
+ filter_params_as_from_rails = [:password]
382
+ Raygun.configuration.filter_parameters = filter_params_as_from_rails
383
+
384
+ parameters = {
385
+ "something_normal" => "hello",
386
+ "password" => "wouldntyouliketoknow",
387
+ "password_confirmation" => "wouldntyouliketoknow",
388
+ "PasswORD_weird_case" => "anythingatall"
389
+ }
390
+
391
+ expected_form_hash = {
392
+ "something_normal" => "hello",
393
+ "password" => "[FILTERED]",
394
+ "password_confirmation" => "[FILTERED]",
395
+ "PasswORD_weird_case" => "[FILTERED]"
396
+ }
397
+
398
+ post_body_env_hash = sample_env_hash.merge(
399
+ "REQUEST_METHOD" => "POST",
400
+ "rack.input" => StringIO.new(URI.encode_www_form(parameters))
401
+ )
402
+
403
+ assert_equal expected_form_hash, @client.send(:request_information, post_body_env_hash)[:form]
404
+ ensure
405
+ Raygun.configuration.filter_parameters = nil
406
+ end
407
+
408
+ def test_ip_address_from_action_dispatch
409
+ env_hash = sample_env_hash.merge({
410
+ "action_dispatch.remote_ip"=> "123.456.789.012"
411
+ })
412
+
413
+ assert_equal "123.456.789.012", @client.send(:ip_address_from, env_hash)
414
+ assert_equal "123.456.789.012", @client.send(:request_information, env_hash)[:iPAddress]
415
+ end
416
+
417
+ def test_ip_address_from_old_action_dispatch
418
+ old_action_dispatch_ip = FakeActionDispatcherIp.new("123.456.789.012")
419
+ env_hash = sample_env_hash.merge({
420
+ "action_dispatch.remote_ip"=> old_action_dispatch_ip
421
+ })
422
+
423
+ assert_equal old_action_dispatch_ip, @client.send(:ip_address_from, env_hash)
424
+ assert_equal "123.456.789.012", @client.send(:request_information, env_hash)[:iPAddress]
425
+ end
426
+
427
+ def test_ip_address_from_raygun_specific_key
428
+ env_hash = sample_env_hash.merge({
429
+ "raygun.remote_ip"=>"123.456.789.012"
430
+ })
431
+
432
+ assert_equal "123.456.789.012", @client.send(:ip_address_from, env_hash)
433
+ assert_equal "123.456.789.012", @client.send(:request_information, env_hash)[:iPAddress]
434
+ end
435
+
436
+ def test_ip_address_returns_not_available_if_not_set
437
+ env_hash = sample_env_hash.dup
438
+ env_hash.delete("REMOTE_ADDR")
439
+
440
+ assert_equal "(Not Available)", @client.send(:ip_address_from, env_hash)
441
+ end
442
+
443
+ def test_setting_up_http_proxy
444
+ begin
445
+ Raygun.configuration.proxy_settings[:address] = "http://proxy.com"
446
+ Raygun::Client.expects(:http_proxy).with("http://proxy.com", "80", nil, nil)
447
+
448
+ Raygun.track_exceptions do
449
+ raise TestException.new
450
+ end
451
+ ensure
452
+ Raygun.configuration.proxy_settings = {}
453
+ end
454
+ end
455
+
456
+ def test_filter_payload_with_whitelist_never_filters_toplevel
457
+ Timecop.freeze do
458
+ Raygun.configuration.filter_payload_with_whitelist = true
459
+ Raygun.configuration.whitelist_payload_shape = {}
460
+
461
+ e = test_exception
462
+
463
+ assert_equal Time.now.utc.iso8601, @client.send(:build_payload_hash, e)[:occurredOn]
464
+ assert_equal Hash, @client.send(:build_payload_hash, e)[:details].class
465
+ end
466
+ end
467
+
468
+ def test_filter_payload_with_whitelist_never_filters_client
469
+ Raygun.configuration.filter_payload_with_whitelist = true
470
+ Raygun.configuration.whitelist_payload_shape = {}
471
+
472
+ client_details = @client.send(:client_details)
473
+
474
+ assert_equal client_details, @client.send(:build_payload_hash, test_exception)[:details][:client]
475
+ end
476
+
477
+ def test_filter_payload_with_whitelist_default_error
478
+ Raygun.configuration.filter_payload_with_whitelist = true
479
+
480
+ details = @client.send(:build_payload_hash, test_exception)[:details]
481
+
482
+ assert_equal exception_hash, details[:error]
483
+ end
484
+
485
+ def test_filter_payload_with_whitelist_exclude_error_keys
486
+ Raygun.configuration.filter_payload_with_whitelist = true
487
+ Raygun.configuration.whitelist_payload_shape = {
488
+ error: {
489
+ className: true,
490
+ message: true,
491
+ stackTrace: true
492
+ }
493
+ }
494
+
495
+ details = @client.send(:build_payload_hash, test_exception)[:details]
496
+
497
+ assert_equal exception_hash, details[:error]
498
+ end
499
+
500
+ def test_filter_payload_with_whitelist_exclude_error_except_stacktrace
501
+ Raygun.configuration.filter_payload_with_whitelist = true
502
+ Raygun.configuration.whitelist_payload_shape = {
503
+ error: {
504
+ className: true,
505
+ message: true,
506
+ }
507
+ }
508
+
509
+ details = @client.send(:build_payload_hash, test_exception)[:details]
510
+
511
+ expected_hash = exception_hash.merge({
512
+ stackTrace: "[FILTERED]"
513
+ })
514
+
515
+ assert_equal expected_hash, details[:error]
516
+ end
517
+
518
+ def test_filter_payload_with_whitelist_proc
519
+ Raygun.configuration.filter_payload_with_whitelist = true
520
+ Raygun.configuration.whitelist_payload_shape do |payload|
521
+ payload
522
+ end
523
+
524
+ details = @client.send(:build_payload_hash, test_exception)[:details]
525
+
526
+ assert_equal exception_hash, details[:error]
527
+ end
528
+
529
+ def test_filter_payload_with_whitelist_default_request_post
530
+ Raygun.configuration.filter_payload_with_whitelist = true
531
+
532
+ post_body_env_hash = sample_env_hash.merge(
533
+ "CONTENT_TYPE" => 'application/x-www-form-urlencoded',
534
+ "REQUEST_METHOD" => "POST",
535
+ "rack.input"=>StringIO.new("a=b&c=4945438&password=swordfish")
536
+ )
537
+
538
+ details = @client.send(:build_payload_hash, test_exception, post_body_env_hash)[:details]
539
+
540
+ expected_hash = {
541
+ hostName: "localhost",
542
+ url: "/",
543
+ httpMethod: "POST",
544
+ iPAddress: "127.0.0.1",
545
+ queryString: { },
546
+ headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
547
+ form: { "a" => "[FILTERED]", "c" => "[FILTERED]", "password" => "[FILTERED]" },
548
+ rawData: {}
549
+ }
550
+
551
+ assert_equal expected_hash, details[:request]
552
+ end
553
+
554
+ def test_filter_payload_with_whitelist_request_post_except_formkey
555
+ Raygun.configuration.filter_payload_with_whitelist = true
556
+ shape = Raygun.configuration.whitelist_payload_shape.dup
557
+ shape[:request] = Raygun.configuration.whitelist_payload_shape[:request].merge(
558
+ form: {
559
+ username: true
560
+ }
561
+ )
562
+ Raygun.configuration.whitelist_payload_shape = shape
563
+
564
+ post_body_env_hash = sample_env_hash.merge(
565
+ "REQUEST_METHOD" => "POST",
566
+ "rack.input"=>StringIO.new("username=foo&password=swordfish")
567
+ )
568
+
569
+ details = @client.send(:build_payload_hash, test_exception, post_body_env_hash)[:details]
570
+
571
+ expected_hash = {
572
+ hostName: "localhost",
573
+ url: "/",
574
+ httpMethod: "POST",
575
+ iPAddress: "127.0.0.1",
576
+ queryString: { },
577
+ headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
578
+ form: { "username" => "foo", "password" => "[FILTERED]" },
579
+ rawData: {}
580
+ }
581
+
582
+ assert_equal expected_hash, details[:request]
583
+ end
584
+
585
+ def test_filter_payload_with_whitelist_default_request_get
586
+ Raygun.configuration.filter_payload_with_whitelist = true
587
+
588
+ env_hash = sample_env_hash.merge({
589
+ "QUERY_STRING"=>"a=b&c=4945438",
590
+ "REQUEST_URI"=>"/?a=b&c=4945438",
591
+ })
592
+ expected_hash = {
593
+ hostName: "localhost",
594
+ url: "/",
595
+ httpMethod: "GET",
596
+ iPAddress: "127.0.0.1",
597
+ queryString: { "a" => "b", "c" => "4945438" },
598
+ headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
599
+ form: {},
600
+ rawData: nil
601
+ }
602
+
603
+ details = @client.send(:build_payload_hash, test_exception, env_hash)[:details]
604
+
605
+ assert_equal expected_hash, details[:request]
606
+ end
607
+
608
+ def test_filter_payload_with_whitelist_default_request_get_except_querystring
609
+ Raygun.configuration.filter_payload_with_whitelist = true
610
+ shape = Raygun.configuration.whitelist_payload_shape.dup
611
+ shape[:request] = Raygun::Configuration::DEFAULT_WHITELIST_PAYLOAD_SHAPE_REQUEST.dup.tap do |h|
612
+ h.delete(:queryString)
613
+ end
614
+ Raygun.configuration.whitelist_payload_shape = shape
615
+
616
+ expected_hash = {
617
+ hostName: "localhost",
618
+ url: "/",
619
+ httpMethod: "GET",
620
+ iPAddress: "127.0.0.1",
621
+ queryString: "[FILTERED]",
622
+ headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
623
+ form: {},
624
+ rawData: nil
625
+ }
626
+
627
+ details = @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details]
628
+
629
+ assert_equal expected_hash, details[:request]
630
+ end
631
+
632
+ def test_filter_payload_with_whitelist_being_false_does_not_filter_query_string
633
+ Raygun.configuration.filter_payload_with_whitelist = false
634
+
635
+ env_hash = sample_env_hash.merge({
636
+ "QUERY_STRING"=>"a=b&c=4945438",
637
+ "REQUEST_URI"=>"/?a=b&c=4945438",
638
+ })
639
+ expected_hash = {
640
+ hostName: "localhost",
641
+ url: "/",
642
+ httpMethod: "GET",
643
+ iPAddress: "127.0.0.1",
644
+ queryString: { "a" => "b", "c" => "4945438" },
645
+ headers: { "Version"=>"HTTP/1.1", "Host"=>"localhost:3000", "Cookie"=>"cookieval" },
646
+ form: {},
647
+ rawData: nil
648
+ }
649
+
650
+ details = @client.send(:build_payload_hash, test_exception, env_hash)[:details]
651
+
652
+ assert_equal expected_hash, details[:request]
653
+ end
654
+
655
+ def test_filter_payload_with_whitelist_request_specific_keys
656
+ Raygun.configuration.filter_payload_with_whitelist = true
657
+ Raygun.configuration.whitelist_payload_shape = {
658
+ request: {
659
+ url: true,
660
+ httpMethod: true,
661
+ hostName: true
662
+ }
663
+ }
664
+
665
+ details = @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details]
666
+
667
+ expected_hash = {
668
+ hostName: "localhost",
669
+ url: "/",
670
+ httpMethod: "GET",
671
+ iPAddress: "[FILTERED]",
672
+ queryString: "[FILTERED]",
673
+ headers: "[FILTERED]",
674
+ form: "[FILTERED]",
675
+ rawData: "[FILTERED]"
676
+ }
677
+
678
+ assert_equal expected_hash, details[:request]
679
+ end
680
+
681
+
682
+ def test_filter_payload_with_whitelist_and_filter_parameters_applies_both
683
+ Raygun.configuration.filter_parameters = [:password]
684
+ Raygun.configuration.filter_payload_with_whitelist = true
685
+ Raygun.configuration.whitelist_payload_shape = proc do |payload|
686
+ payload[:request][:headers]["Cookie"] = "[FILTERED]"
687
+ payload
688
+ end
689
+
690
+ parameters = {
691
+ "something_normal" => "hello",
692
+ "password" => "wouldntyouliketoknow"
693
+ }
694
+
695
+ post_body_env_hash = sample_env_hash.merge(
696
+ "REQUEST_METHOD" => "POST",
697
+ "rack.input" => StringIO.new(URI.encode_www_form(parameters))
698
+ )
699
+
700
+ payload = @client.send(:build_payload_hash, test_exception, post_body_env_hash)
701
+ request_payload = payload[:details][:request]
702
+
703
+ expected_form = {
704
+ "something_normal" => "hello",
705
+ "password" => "[FILTERED]"
706
+ }
707
+
708
+ assert_equal expected_form, request_payload[:form]
709
+
710
+ expected_headers = {
711
+ "Version" => "HTTP/1.1",
712
+ "Host" => "localhost:3000",
713
+ "Cookie" => "[FILTERED]"
714
+ }
715
+
716
+ assert_equal expected_headers, request_payload[:headers]
717
+ end
718
+
719
+ def test_build_payload_hash_adds_affected_user_details_when_supplied_with_user
720
+ user = OpenStruct.new(id: '123', email: 'test@email.com', first_name: 'Taylor')
721
+ expected_details = {
722
+ :isAnonymous => false,
723
+ :identifier => '123',
724
+ :email => 'test@email.com',
725
+ :firstName => 'Taylor',
726
+ }
727
+
728
+ user_details = @client.send(:build_payload_hash, test_exception, sample_env_hash, user)[:details][:user]
729
+
730
+ assert_equal expected_details, user_details
731
+ end
732
+
733
+ def test_build_payload_includes_breadcrumbs
734
+ ::Raygun::Breadcrumbs::Store.initialize
735
+ ::Raygun::Breadcrumbs::Store.record(message: "foo")
736
+
737
+ breadcrumbs = @client.send(:build_payload_hash, test_exception, sample_env_hash)[:details][:breadcrumbs]
738
+ ::Raygun::Breadcrumbs::Store.clear
739
+
740
+ assert_equal breadcrumbs.length, 1
741
+ assert breadcrumbs[0].is_a? Hash
742
+ end
743
+
744
+ def test_raw_data_does_not_crash_on_buffer_without_pos
745
+ buffer = StringIO.new('123456789')
746
+ rack_env = {
747
+ REQUEST_METHOD: 'POST',
748
+ 'rack.input' => buffer
749
+ }
750
+
751
+ buffer.instance_eval('undef :pos')
752
+
753
+ raw_data = @client.send(:raw_data, rack_env)
754
+
755
+ assert_equal('123456789', raw_data)
756
+ end
757
+
758
+ private
759
+
760
+ def test_exception
761
+ e = TestException.new
762
+ e.set_backtrace(["/some/folder/some_file.rb:123:in `some_method_name'",
763
+ "/another/path/foo.rb:1234:in `block (3 levels) run'"])
764
+
765
+ e
766
+ end
767
+
768
+ def nest_exceptions(outer_exception, inner_exception)
769
+ begin
770
+ begin
771
+ raise inner_exception.class, inner_exception.message
772
+ rescue => e
773
+ e.set_backtrace inner_exception.backtrace
774
+ raise outer_exception.class, outer_exception.message
775
+ end
776
+ rescue => nested_exception
777
+ nested_exception.set_backtrace outer_exception.backtrace
778
+ end
779
+
780
+ nested_exception
781
+ end
782
+
783
+ def exception_hash
784
+ {
785
+ className: "ClientTest::TestException",
786
+ message: "A test message",
787
+ stackTrace: [
788
+ { lineNumber: "123", fileName: "/some/folder/some_file.rb", methodName: "some_method_name" },
789
+ { lineNumber: "1234", fileName: "/another/path/foo.rb", methodName: "block (3 levels) run"}
790
+ ]
791
+ }
792
+ end
793
+
794
+ def sample_env_hash
795
+ {
796
+ "SERVER_NAME"=>"localhost",
797
+ "REQUEST_METHOD"=>"GET",
798
+ "REQUEST_PATH"=>"/",
799
+ "PATH_INFO"=>"/",
800
+ "QUERY_STRING"=>"",
801
+ "REQUEST_URI"=>"/",
802
+ "HTTP_VERSION"=>"HTTP/1.1",
803
+ "HTTP_HOST"=>"localhost:3000",
804
+ "HTTP_COOKIE"=>"cookieval",
805
+ "GATEWAY_INTERFACE"=>"CGI/1.2",
806
+ "SERVER_PORT"=>"3000",
807
+ "SERVER_PROTOCOL"=>"HTTP/1.1",
808
+ "SCRIPT_NAME"=>"",
809
+ "REMOTE_ADDR"=>"127.0.0.1"
810
+ }
811
+ end
812
+ end