raygun4ruby 3.2.6 → 4.0.1

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 (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 +173 -133
  7. data/Gemfile +4 -4
  8. data/LICENSE.txt +22 -22
  9. data/README.md +430 -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 +202 -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 +25 -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 +61 -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 +122 -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