rollbar 2.18.2 → 2.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +15 -0
  3. data/.travis.yml +155 -93
  4. data/Gemfile +19 -13
  5. data/README.md +12 -0
  6. data/gemfiles/rails30.gemfile +17 -10
  7. data/gemfiles/rails31.gemfile +20 -12
  8. data/gemfiles/rails32.gemfile +16 -7
  9. data/gemfiles/rails40.gemfile +16 -5
  10. data/gemfiles/rails41.gemfile +15 -5
  11. data/gemfiles/rails42.gemfile +25 -14
  12. data/gemfiles/rails50.gemfile +15 -8
  13. data/gemfiles/rails51.gemfile +15 -8
  14. data/gemfiles/rails52.gemfile +62 -0
  15. data/gemfiles/ruby_1_8_and_1_9_2.gemfile +2 -2
  16. data/lib/rails/rollbar_runner.rb +16 -1
  17. data/lib/rollbar/capistrano.rb +71 -39
  18. data/lib/rollbar/capistrano3.rb +53 -1
  19. data/lib/rollbar/capistrano_tasks.rb +131 -0
  20. data/lib/rollbar/configuration.rb +13 -4
  21. data/lib/rollbar/delay/active_job.rb +17 -0
  22. data/lib/rollbar/delay/sidekiq.rb +3 -1
  23. data/lib/rollbar/delay/thread.rb +1 -1
  24. data/lib/rollbar/deploy.rb +69 -0
  25. data/lib/rollbar/item.rb +17 -6
  26. data/lib/rollbar/middleware/js.rb +25 -3
  27. data/lib/rollbar/middleware/js/json_value.rb +26 -0
  28. data/lib/rollbar/notifier.rb +32 -13
  29. data/lib/rollbar/plugins/active_job.rb +3 -0
  30. data/lib/rollbar/plugins/rails/controller_methods.rb +2 -1
  31. data/lib/rollbar/plugins/rails/railtie_mixin.rb +7 -1
  32. data/lib/rollbar/rake_tasks.rb +126 -67
  33. data/lib/rollbar/scrubbers/params.rb +6 -0
  34. data/lib/rollbar/util.rb +75 -45
  35. data/lib/rollbar/util/hash.rb +15 -6
  36. data/lib/rollbar/version.rb +1 -1
  37. data/rollbar.gemspec +2 -3
  38. metadata +9 -261
  39. data/lib/rollbar/tasks/rollbar.cap +0 -47
  40. data/spec/cacert.pem +0 -3988
  41. data/spec/controllers/home_controller_spec.rb +0 -480
  42. data/spec/delay/sidekiq_spec.rb +0 -61
  43. data/spec/delay/sucker_punch_spec.rb +0 -25
  44. data/spec/delayed/backend/test.rb +0 -140
  45. data/spec/delayed/serialization/test.rb +0 -0
  46. data/spec/dummyapp/.gitignore +0 -73
  47. data/spec/dummyapp/Rakefile +0 -7
  48. data/spec/dummyapp/app/assets/javascripts/application.js +0 -3
  49. data/spec/dummyapp/app/assets/stylesheets/application.css.scss +0 -37
  50. data/spec/dummyapp/app/controllers/application_controller.rb +0 -3
  51. data/spec/dummyapp/app/controllers/home_controller.rb +0 -60
  52. data/spec/dummyapp/app/controllers/users_controller.rb +0 -17
  53. data/spec/dummyapp/app/helpers/.gitkeep +0 -0
  54. data/spec/dummyapp/app/mailers/.gitkeep +0 -0
  55. data/spec/dummyapp/app/models/.gitkeep +0 -0
  56. data/spec/dummyapp/app/models/book.rb +0 -5
  57. data/spec/dummyapp/app/models/post.rb +0 -9
  58. data/spec/dummyapp/app/models/user.rb +0 -9
  59. data/spec/dummyapp/app/views/devise/registrations/edit.html.erb +0 -27
  60. data/spec/dummyapp/app/views/devise/registrations/new.html.erb +0 -20
  61. data/spec/dummyapp/app/views/devise/shared/_links.html.erb +0 -25
  62. data/spec/dummyapp/app/views/home/cause_exception.html.erb +0 -1
  63. data/spec/dummyapp/app/views/home/index.html.erb +0 -4
  64. data/spec/dummyapp/app/views/home/report_exception.html.erb +0 -1
  65. data/spec/dummyapp/app/views/js/test.html.erb +0 -1
  66. data/spec/dummyapp/app/views/layouts/_messages.html.erb +0 -5
  67. data/spec/dummyapp/app/views/layouts/_navigation.html.erb +0 -21
  68. data/spec/dummyapp/app/views/layouts/application.html.erb +0 -25
  69. data/spec/dummyapp/app/views/layouts/simple.html.erb +0 -18
  70. data/spec/dummyapp/app/views/users/index.html.erb +0 -8
  71. data/spec/dummyapp/app/views/users/show.html.erb +0 -3
  72. data/spec/dummyapp/config.ru +0 -4
  73. data/spec/dummyapp/config/application.rb +0 -59
  74. data/spec/dummyapp/config/boot.rb +0 -10
  75. data/spec/dummyapp/config/database.yml +0 -25
  76. data/spec/dummyapp/config/environment.rb +0 -5
  77. data/spec/dummyapp/config/environments/development.rb +0 -37
  78. data/spec/dummyapp/config/environments/production.rb +0 -67
  79. data/spec/dummyapp/config/environments/test.rb +0 -37
  80. data/spec/dummyapp/config/initializers/backtrace_silencers.rb +0 -7
  81. data/spec/dummyapp/config/initializers/inflections.rb +0 -15
  82. data/spec/dummyapp/config/initializers/mime_types.rb +0 -5
  83. data/spec/dummyapp/config/initializers/rollbar.rb +0 -26
  84. data/spec/dummyapp/config/initializers/secret_token.rb +0 -7
  85. data/spec/dummyapp/config/initializers/session_store.rb +0 -8
  86. data/spec/dummyapp/config/initializers/wrap_parameters.rb +0 -16
  87. data/spec/dummyapp/config/locales/devise.en.yml +0 -58
  88. data/spec/dummyapp/config/locales/en.yml +0 -5
  89. data/spec/dummyapp/config/routes.rb +0 -17
  90. data/spec/dummyapp/config/secrets.yml +0 -2
  91. data/spec/dummyapp/db/migrate/20121121184652_devise_create_users.rb +0 -46
  92. data/spec/dummyapp/db/migrate/20121121184654_add_name_to_users.rb +0 -5
  93. data/spec/dummyapp/db/migrate/20161219184410_create_books.rb +0 -10
  94. data/spec/dummyapp/db/migrate/20161219185529_add_username_to_users.rb +0 -5
  95. data/spec/dummyapp/db/schema.rb +0 -41
  96. data/spec/dummyapp/db/seeds.rb +0 -12
  97. data/spec/dummyapp/lib/assets/.gitkeep +0 -0
  98. data/spec/dummyapp/public/404.html +0 -26
  99. data/spec/dummyapp/public/422.html +0 -26
  100. data/spec/dummyapp/public/500.html +0 -25
  101. data/spec/dummyapp/public/favicon.ico +0 -0
  102. data/spec/dummyapp/script/rails +0 -6
  103. data/spec/fixtures/file1 +0 -1
  104. data/spec/fixtures/file2 +0 -1
  105. data/spec/fixtures/payloads/message.json +0 -25
  106. data/spec/fixtures/payloads/sample.trace.json +0 -275
  107. data/spec/fixtures/payloads/sample.trace_chain.json +0 -530
  108. data/spec/fixtures/plugins/dummy1.rb +0 -5
  109. data/spec/fixtures/plugins/dummy2.rb +0 -5
  110. data/spec/generators/rollbar/rollbar_generator_rails30_spec.rb +0 -31
  111. data/spec/generators/rollbar/rollbar_generator_spec.rb +0 -51
  112. data/spec/requests/home_spec.rb +0 -49
  113. data/spec/rollbar/configuration_spec.rb +0 -74
  114. data/spec/rollbar/delay/delayed_job_spec.rb +0 -22
  115. data/spec/rollbar/delay/girl_friday_spec.rb +0 -41
  116. data/spec/rollbar/delay/resque_spec.rb +0 -37
  117. data/spec/rollbar/delay/shoryuken_spec.rb +0 -44
  118. data/spec/rollbar/delay/thread_spec.rb +0 -27
  119. data/spec/rollbar/encoding/encoder_spec.rb +0 -63
  120. data/spec/rollbar/item/backtrace_spec.rb +0 -26
  121. data/spec/rollbar/item/frame_spec.rb +0 -267
  122. data/spec/rollbar/item_spec.rb +0 -736
  123. data/spec/rollbar/json/oj_spec.rb +0 -18
  124. data/spec/rollbar/json_spec.rb +0 -110
  125. data/spec/rollbar/lazy_store_spec.rb +0 -99
  126. data/spec/rollbar/logger_proxy_spec.rb +0 -69
  127. data/spec/rollbar/logger_spec.rb +0 -124
  128. data/spec/rollbar/middleware/js_spec.rb +0 -428
  129. data/spec/rollbar/middleware/sinatra_spec.rb +0 -197
  130. data/spec/rollbar/notifier_spec.rb +0 -67
  131. data/spec/rollbar/plugin_spec.rb +0 -209
  132. data/spec/rollbar/plugins/active_job_spec.rb +0 -45
  133. data/spec/rollbar/plugins/delayed_job/job_data_spec.rb +0 -48
  134. data/spec/rollbar/plugins/delayed_job_spec.rb +0 -129
  135. data/spec/rollbar/plugins/rack_spec.rb +0 -152
  136. data/spec/rollbar/plugins/rails_js_spec.rb +0 -19
  137. data/spec/rollbar/plugins/rake_spec.rb +0 -34
  138. data/spec/rollbar/plugins/resque/failure_spec.rb +0 -36
  139. data/spec/rollbar/plugins/sidekiq_spec.rb +0 -169
  140. data/spec/rollbar/plugins/validations_spec.rb +0 -56
  141. data/spec/rollbar/plugins_spec.rb +0 -68
  142. data/spec/rollbar/request_data_extractor_spec.rb +0 -321
  143. data/spec/rollbar/scrubbers/params_spec.rb +0 -598
  144. data/spec/rollbar/scrubbers/url_spec.rb +0 -240
  145. data/spec/rollbar/scrubbers_spec.rb +0 -31
  146. data/spec/rollbar/sidekig/clear_scope_spec.rb +0 -19
  147. data/spec/rollbar/truncation/frames_strategy_spec.rb +0 -70
  148. data/spec/rollbar/truncation/min_body_strategy_spec.rb +0 -57
  149. data/spec/rollbar/truncation/strings_strategy_spec.rb +0 -89
  150. data/spec/rollbar/truncation_spec.rb +0 -27
  151. data/spec/rollbar/util/hash_spec.rb +0 -22
  152. data/spec/rollbar/util/ip_anonymizer_spec.rb +0 -30
  153. data/spec/rollbar/util_spec.rb +0 -80
  154. data/spec/rollbar_bc_spec.rb +0 -380
  155. data/spec/rollbar_spec.rb +0 -1737
  156. data/spec/spec_helper.rb +0 -84
  157. data/spec/support/cause_exception.rb +0 -1
  158. data/spec/support/encoding_helpers.rb +0 -8
  159. data/spec/support/encodings/iso_8859_9 +0 -1
  160. data/spec/support/fixture_helpers.rb +0 -10
  161. data/spec/support/get_ip_raising.rb +0 -7
  162. data/spec/support/helpers.rb +0 -5
  163. data/spec/support/matchers.rb +0 -23
  164. data/spec/support/notifier_helpers.rb +0 -57
  165. data/spec/support/rollbar_api.rb +0 -57
  166. data/spec/support/secure_headers_mocks.rb +0 -83
  167. data/spec/support/shared_contexts.rb +0 -12
@@ -1,18 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'rollbar/json/oj'
4
-
5
- describe Rollbar::JSON::Oj do
6
- let(:options) do
7
- {
8
- :mode => :compat,
9
- :use_to_json => false,
10
- :symbol_keys => false,
11
- :circular => false
12
- }
13
- end
14
-
15
- it 'returns correct options' do
16
- expect(described_class.options).to be_eql(options)
17
- end
18
- end
@@ -1,110 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'multi_json'
4
- require 'rollbar/json'
5
- require 'rollbar/configuration'
6
-
7
- class Rollbar::JSON::MockAdapter
8
- def self.options
9
- { 'mock' => 'adapter' }
10
- end
11
- end
12
-
13
- module MultiJson
14
- module Adapters
15
- module MockAdapter
16
- end
17
- end
18
- end
19
-
20
- module MultiJson
21
- module Adapters
22
- module MissingCustomOptions
23
- end
24
- end
25
- end
26
-
27
- module MissingCustomOptions
28
- # Consider the fact that there's MultiJson::Adapters::Yajl but not
29
- # Rollbar::JSON::Yajl, it should not look for ::Yajl but only
30
- # Rollbar::JSON::Yajl.
31
- end
32
-
33
- describe Rollbar::JSON do
34
- let(:payload) do
35
- { :foo => :bar }
36
- end
37
- let(:adapter_options) { { 'option' => 'value' } }
38
-
39
- describe '.dump' do
40
- before do
41
- allow(described_class).to receive(:adapter_options).and_return(adapter_options)
42
- end
43
-
44
- it 'calls MultiJson.dump' do
45
- expect(::MultiJson).to receive(:dump).once.with(payload, adapter_options)
46
-
47
- described_class.dump(payload)
48
- end
49
- end
50
-
51
- describe '.load' do
52
- before do
53
- allow(described_class).to receive(:adapter_options).and_return(adapter_options)
54
- end
55
-
56
- it 'calls MultiJson.load' do
57
- expect(::MultiJson).to receive(:load).once.with(payload, adapter_options)
58
-
59
- described_class.load(payload)
60
- end
61
- end
62
-
63
- describe '.with_adapter' do
64
- let(:object) { double(:foo => 'bar') }
65
- let(:callback) do
66
- proc { object.foo }
67
- end
68
- let(:adapter) { described_class.detect_multi_json_adapter }
69
-
70
- it 'calls mock.something with an adapter' do
71
- expect(MultiJson).to receive(:with_adapter).with(adapter).and_call_original
72
- expect(object).to receive(:foo).once
73
-
74
- described_class.with_adapter(&callback)
75
- end
76
- end
77
-
78
- describe '.adapter_options' do
79
- it 'calls .options in adapter module' do
80
- expect(described_class.options_module).to receive(:options)
81
-
82
- described_class.adapter_options
83
- end
84
- end
85
-
86
- describe '.options_module' do
87
- before do
88
- described_class.options_module = nil
89
- allow(MultiJson).to receive(:current_adapter).and_return(multi_json_module)
90
- end
91
-
92
- context 'with a defined rollbar adapter' do
93
- let(:multi_json_module) { MultiJson::Adapters::MockAdapter }
94
- let(:expected_adapter) { Rollbar::JSON::MockAdapter }
95
-
96
- it 'returns the correct options' do
97
- expect(described_class.options_module).to be(expected_adapter)
98
- end
99
- end
100
-
101
- context 'without a defined rollbar adapter' do
102
- let(:multi_json_module) { MultiJson::Adapters::MissingCustomOptions }
103
- let(:expected_adapter) { Rollbar::JSON::Default }
104
-
105
- it 'returns the correct options' do
106
- expect(described_class.options_module).to be(expected_adapter)
107
- end
108
- end
109
- end
110
- end
@@ -1,99 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'rollbar/lazy_store'
4
-
5
-
6
- describe Rollbar::LazyStore do
7
- subject { Rollbar::LazyStore.new(data) }
8
- let(:lazy_value) do
9
- proc { :bar }
10
- end
11
- let(:data) do
12
- {
13
- :somekey => :value,
14
- :foo => lazy_value
15
- }
16
- end
17
-
18
- describe '#[]' do
19
- it 'gets the regular values' do
20
- expect(subject[:somekey]).to be_eql(:value)
21
- end
22
-
23
- it 'gets the lazy values and evaluates them just once' do
24
- expect(lazy_value).to receive(:call).once.and_call_original
25
-
26
- value1 = subject[:foo]
27
- value2 = subject[:foo]
28
-
29
- expect(value1).to be_eql(:bar)
30
- expect(value2).to be_eql(:bar)
31
- end
32
- end
33
-
34
- describe '#[]=' do
35
- before do
36
- # load data in :foo
37
- subject[:foo]
38
- end
39
-
40
- it 'sets the data and clears the loaded data' do
41
- subject[:foo] = 'something-else'
42
-
43
- expect(subject[:foo]).to be_eql('something-else')
44
- end
45
- end
46
-
47
- describe '#eql?' do
48
- context 'passing a Hash' do
49
- it 'checks correctly eql?' do
50
- expect(subject.eql?(data)).to be(true)
51
- expect(subject.eql?({})).to be(false)
52
- end
53
- end
54
-
55
- context 'passing a LazyStore' do
56
- it 'checks correctly eql?' do
57
- expect(subject.eql?(Rollbar::LazyStore.new(data))).to be(true)
58
- expect(subject.eql?(Rollbar::LazyStore.new({}))).to be(false)
59
- end
60
- end
61
- end
62
-
63
- describe '#==' do
64
- context 'passing a Hash' do
65
- it 'checks correctly eql?' do
66
- expect(subject == data).to be(true)
67
- expect(subject == {}).to be(false)
68
- end
69
- end
70
-
71
- context 'passing a LazyStore' do
72
- it 'checks correctly eql?' do
73
- expect(subject == Rollbar::LazyStore.new(data)).to be(true)
74
- expect(subject == Rollbar::LazyStore.new({})).to be(false)
75
- end
76
- end
77
- end
78
-
79
- describe '#data' do
80
- it 'returns the data with lazy values loaded' do
81
- value = subject.data
82
-
83
- expected_value = {
84
- :somekey => :value,
85
- :foo => :bar
86
- }
87
- expect(value).to be_eql(expected_value)
88
- end
89
- end
90
-
91
- describe '#clone' do
92
- it 'returns a new object, with same data and empty loaded_data' do
93
- new_scope = subject.clone
94
-
95
- expect(new_scope.instance_variable_get('@loaded_data')).to be_empty
96
- expect(new_scope.raw).to be_eql(subject.raw)
97
- end
98
- end
99
- end
@@ -1,69 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Rollbar::LoggerProxy do
4
- let(:logger) { double(:logger) }
5
- let(:message) { 'the-message' }
6
-
7
- subject { described_class.new(logger) }
8
-
9
- before do
10
- allow(Rollbar.configuration).to receive(:enabled).and_return(true)
11
- allow(Rollbar.configuration).to receive(:logger_level).and_return(:debug)
12
- end
13
-
14
- shared_examples 'delegate to logger' do
15
- it 'logs with correct level' do
16
- expect(logger).to receive(level).with(message)
17
-
18
- subject.send(level, message)
19
- end
20
- end
21
-
22
- %w(info error warn debug).each do |level|
23
- describe "#{level}" do
24
- it_should_behave_like 'delegate to logger' do
25
- let(:level) { level }
26
- end
27
- end
28
- end
29
-
30
- describe '#log' do
31
- context 'if Rollbar is disabled' do
32
- before do
33
- expect(Rollbar.configuration).to receive(:enabled).and_return(false)
34
- end
35
-
36
- it 'doesnt call the logger' do
37
- expect(logger).to_not receive(:error)
38
-
39
- subject.log('error', 'foo')
40
- end
41
- end
42
-
43
- context 'if the logger fails' do
44
- it 'doesnt raise' do
45
- allow(logger).to receive(:info).and_raise(StandardError.new)
46
-
47
- expect { subject.log('info', message) }.not_to raise_error
48
- end
49
- end
50
-
51
- context 'if logger_level is :info' do
52
- before do
53
- allow(Rollbar.configuration).to receive(:logger_level).and_return(:info)
54
- end
55
-
56
- it 'doesnt call the logger (debug)' do
57
- expect(logger).to_not receive(:debug)
58
-
59
- subject.log('debug', 'foo')
60
- end
61
-
62
- it 'calls the logger (error)' do
63
- expect(logger).to receive(:error)
64
-
65
- subject.log('error', 'foo')
66
- end
67
- end
68
- end
69
- end
@@ -1,124 +0,0 @@
1
- require 'spec_helper'
2
- require 'rollbar/logger'
3
-
4
- describe Rollbar::Logger do
5
- describe '#add' do
6
- context 'with severity under level' do
7
- it 'returns true' do
8
- result = subject.add(Logger::DEBUG, 'foo')
9
-
10
- expect(result).to be_truthy
11
- end
12
- end
13
-
14
- context 'with blank message' do
15
- it 'returns true' do
16
- result = subject.add(subject.level)
17
-
18
- expect(result).to be_truthy
19
- end
20
- end
21
-
22
- context 'with ERROR severity' do
23
- let(:message) { 'foo' }
24
-
25
- it 'calls Rollbar to send the message' do
26
- expect_any_instance_of(Rollbar::Notifier).to receive(:log).with(:error, message)
27
-
28
- subject.add(Logger::ERROR, message)
29
- end
30
- end
31
-
32
- context 'with FATAL severity' do
33
- let(:message) { 'foo' }
34
-
35
- it 'calls Rollbar to send the message with critical level' do
36
- expect_any_instance_of(Rollbar::Notifier).to receive(:log).with(:critical, message)
37
-
38
- subject.add(Logger::FATAL, message)
39
- end
40
- end
41
-
42
- context 'with UNKNOWN severity' do
43
- let(:message) { 'foo' }
44
-
45
- it 'calls Rollbar to send the message with error level' do
46
- expect_any_instance_of(Rollbar::Notifier).to receive(:log).with(:error, message)
47
-
48
- subject.add(Logger::UNKNOWN, message)
49
- end
50
- end
51
-
52
- context 'with out of range severity' do
53
- let(:message) { 'foo' }
54
-
55
- it 'calls Rollbar to send the message with error level' do
56
- expect_any_instance_of(Rollbar::Notifier).to receive(:log).with(:error, message)
57
-
58
- subject.add(10, message)
59
- end
60
- end
61
-
62
- context 'without active_support/core_ext/object/blank' do
63
- let(:message) { 'foo'.tap { |message| message.instance_eval('undef :blank?') } }
64
-
65
- it 'calls Rollbar to send the message' do
66
- expect_any_instance_of(Rollbar::Notifier).to receive(:log).with(:error, message)
67
-
68
- subject.add(Logger::ERROR, message)
69
- end
70
- end
71
- end
72
-
73
- describe '#<<' do
74
- let(:message) { 'foo' }
75
-
76
- it 'calls #error' do
77
- expect(subject).to receive(:error).with(message)
78
-
79
- subject << message
80
- end
81
- end
82
-
83
- describe '#formatter=' do
84
- it 'fails with FormatterNotSupported' do
85
- expect do
86
- subject.formatter = double
87
- end.to raise_error(Rollbar::Logger::FormatterNotSupported)
88
- end
89
- end
90
-
91
- describe '#formatter' do
92
- it 'fails with FormatterNotSupported' do
93
- expect do
94
- subject.formatter
95
- end.to raise_error(Rollbar::Logger::FormatterNotSupported)
96
- end
97
- end
98
-
99
- describe '#datetime_format=' do
100
- it 'fails with DatetimeFormatNotSupported' do
101
- expect do
102
- subject.datetime_format = double
103
- end.to raise_error(Rollbar::Logger::DatetimeFormatNotSupported)
104
- end
105
- end
106
-
107
- describe '#datetime_format' do
108
- it 'fails with DatetimeFormatNotSupported' do
109
- expect do
110
- subject.datetime_format
111
- end.to raise_error(Rollbar::Logger::DatetimeFormatNotSupported)
112
- end
113
- end
114
-
115
- describe '#rollbar' do
116
- it 'returns a Rollbar notifier with a logger pointing to /dev/null' do
117
- notifier = subject.rollbar
118
- logger = notifier.configuration.logger
119
- logdev = logger.instance_eval { @logdev }
120
-
121
- expect(logdev.filename).to be_eql('/dev/null')
122
- end
123
- end
124
- end
@@ -1,428 +0,0 @@
1
- require 'spec_helper'
2
- require 'rollbar/middleware/js'
3
-
4
-
5
- shared_examples 'secure_headers' do
6
- it 'renders the snippet and config in the response with nonce in script tag when SecureHeaders installed' do
7
- SecureHeadersMocks::CSP.config = {
8
- :opt_out? => false
9
- }
10
-
11
- _, _, response = subject.call(env)
12
-
13
- new_body = response.body.join
14
-
15
- expect(new_body).to include('<script type="text/javascript" nonce="lorem-ipsum-nonce">')
16
- expect(new_body).to include("var _rollbarConfig = #{config[:options].to_json};")
17
- expect(new_body).to include(snippet)
18
- end
19
-
20
- it 'renders the snippet in the response without nonce if SecureHeaders script_src includes \'unsafe-inline\'' do
21
- SecureHeadersMocks::CSP.config = {
22
- :opt_out? => false,
23
- :script_src => %w('unsafe-inline')
24
- }
25
-
26
- _, _, response = subject.call(env)
27
- new_body = response.body.join
28
-
29
- expect(new_body).to include('<script type="text/javascript">')
30
- expect(new_body).to include("var _rollbarConfig = #{config[:options].to_json};")
31
- expect(new_body).to include(snippet)
32
- end
33
-
34
- it 'renders the snippet in the response without nonce if SecureHeaders CSP is OptOut' do
35
- SecureHeadersMocks::CSP.config = {
36
- :opt_out? => true
37
- }
38
-
39
- _, _, response = subject.call(env)
40
- new_body = response.body.join
41
-
42
- expect(new_body).to include('<script type="text/javascript">')
43
- expect(new_body).to include("var _rollbarConfig = #{config[:options].to_json};")
44
- expect(new_body).to include(snippet)
45
- end
46
- end
47
-
48
- describe Rollbar::Middleware::Js do
49
- subject { described_class.new(app, config) }
50
-
51
- let(:env) { {} }
52
- let(:config) { {} }
53
- let(:app) do
54
- proc do |_|
55
- [status, headers, body]
56
- end
57
- end
58
- let(:html) do
59
- <<-END
60
- <html>
61
- <head>
62
- <link rel="stylesheet" href="url" type="text/css" media="screen" />
63
- <script type="text/javascript" src="foo"></script>
64
- </head>
65
- <body>
66
- <h1>Testing the middleware</h1>
67
- </body>
68
- </html>
69
- END
70
- end
71
- let(:minified_html) do
72
- <<-END
73
- <html><head><link rel="stylesheet" href="url" type="text/css" media="screen" /><script type="text/javascript" src="foo"></script></head><body><h1>Testing the middleware</h1></body></html>
74
- END
75
- end
76
- let(:meta_charset_html) do
77
- <<-END
78
- <html>
79
- <head>
80
- <meta charset="UTF-8"/>
81
- <link rel="stylesheet" href="url" type="text/css" media="screen" />
82
- <script type="text/javascript" src="foo"></script>
83
- </head>
84
- <body>
85
- <h1>Testing the middleware</h1>
86
- </body>
87
- </html>
88
- END
89
- end
90
- let(:meta_content_html) do
91
- <<-END
92
- <html>
93
- <head>
94
- <meta content="origin" id="mref" name="referrer">
95
- <link rel="stylesheet" href="url" type="text/css" media="screen" />
96
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
97
- <script type="text/javascript" src="foo"></script>
98
- </head>
99
- <body>
100
- <h1>Testing the middleware</h1>
101
- </body>
102
- </html>
103
- END
104
- end
105
- let(:snippet) { 'THIS IS THE SNIPPET' }
106
- let(:content_type) { 'text/html' }
107
-
108
- before do
109
- reconfigure_notifier
110
- allow(subject).to receive(:js_snippet).and_return(snippet)
111
- end
112
-
113
- shared_examples "doesn't add the snippet or config", :add_js => false do
114
- it "doesn't add the snippet or config" do
115
- res_status, res_headers, response = subject.call(env)
116
- new_body = response.join
117
-
118
- expect(new_body).not_to include(snippet)
119
- expect(new_body).not_to include(config[:options].to_json)
120
- expect(new_body).to be_eql(body.join)
121
- expect(res_status).to be_eql(status)
122
- expect(res_headers['Content-Type']).to be_eql(content_type)
123
- end
124
- end
125
-
126
- describe '#call' do
127
- context 'with enabled config' do
128
- let(:config) do
129
- {
130
- :enabled => true,
131
- :options => { :foo => :bar }
132
- }
133
- end
134
-
135
- context 'having a html 200 response' do
136
- let(:body) { [html] }
137
- let(:status) { 200 }
138
- let(:headers) do
139
- { 'Content-Type' => content_type }
140
- end
141
-
142
- it 'adds the config and the snippet to the response' do
143
- res_status, res_headers, response = subject.call(env)
144
- new_body = response.body.join
145
-
146
- expect(new_body).to_not include('>>')
147
- expect(new_body).to include(snippet)
148
- expect(new_body).to include(config[:options].to_json)
149
- expect(res_status).to be_eql(status)
150
- expect(res_headers['Content-Type']).to be_eql(content_type)
151
- end
152
- end
153
-
154
- context 'having a html 200 response with minified body' do
155
- let(:body) { [minified_html] }
156
- let(:status) { 200 }
157
- let(:headers) do
158
- { 'Content-Type' => content_type }
159
- end
160
-
161
- it 'adds the config and the snippet to the response' do
162
- res_status, res_headers, response = subject.call(env)
163
- new_body = response.body.join
164
-
165
- expect(new_body).to_not include('>>')
166
- expect(new_body).to include(snippet)
167
- expect(new_body).to include(config[:options].to_json)
168
- expect(res_status).to be_eql(status)
169
- expect(res_headers['Content-Type']).to be_eql(content_type)
170
- end
171
- end
172
-
173
- context 'having a html 200 resposne with meta charset tag' do
174
- let(:body) { [meta_charset_html] }
175
- let(:status) { 200 }
176
- let(:headers) do
177
- { 'Content-Type' => content_type }
178
- end
179
- it 'adds the config and the snippet to the response' do
180
- res_status, res_headers, response = subject.call(env)
181
- new_body = response.body.join
182
-
183
- expect(new_body).to_not include('>>')
184
- expect(new_body).to include(snippet)
185
- expect(new_body).to include(config[:options].to_json)
186
- expect(res_status).to be_eql(status)
187
- expect(res_headers['Content-Type']).to be_eql(content_type)
188
- meta_tag = '<meta charset="UTF-8"/>'
189
- expect(new_body.index(snippet)).to be > new_body.index(meta_tag)
190
- end
191
- end
192
-
193
- context 'having a html 200 resposne with meta content-type tag' do
194
- let(:body) { [meta_content_html] }
195
- let(:status) { 200 }
196
- let(:headers) do
197
- { 'Content-Type' => content_type }
198
- end
199
- it 'adds the config and the snippet to the response' do
200
- res_status, res_headers, response = subject.call(env)
201
- new_body = response.body.join
202
-
203
- expect(new_body).to_not include('>>')
204
- expect(new_body).to include(snippet)
205
- expect(new_body).to include(config[:options].to_json)
206
- expect(res_status).to be_eql(status)
207
- expect(res_headers['Content-Type']).to be_eql(content_type)
208
- meta_tag = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>'
209
- expect(new_body.index(snippet)).to be > new_body.index(meta_tag)
210
- end
211
- end
212
-
213
- context 'having a html 200 response and SecureHeaders >= 3.0.0 defined' do
214
- let(:body) { [html] }
215
- let(:status) { 200 }
216
- let(:headers) do
217
- { 'Content-Type' => content_type }
218
- end
219
-
220
- before do
221
- stub_const('::SecureHeaders', secure_headers_mock)
222
- SecureHeadersMocks::CSP.config = {}
223
- end
224
-
225
- context 'with secure headers 3.0.x-3.4.x' do
226
- let(:secure_headers_mock) { SecureHeadersMocks::SecureHeaders30 }
227
-
228
- include_examples 'secure_headers'
229
- end
230
-
231
- context 'with secure headers 3.5' do
232
- let(:secure_headers_mock) { SecureHeadersMocks::SecureHeaders35 }
233
-
234
- include_examples 'secure_headers'
235
- end
236
-
237
- context 'with secure headers 6.0' do
238
- let(:secure_headers_mock) { SecureHeadersMocks::SecureHeaders60 }
239
-
240
- include_examples 'secure_headers'
241
- end
242
- end
243
-
244
- context 'having a html 200 response and SecureHeaders < 3.0.0 defined' do
245
- let(:body) { [html] }
246
- let(:status) { 200 }
247
- let(:headers) do
248
- { 'Content-Type' => content_type }
249
- end
250
-
251
- before do
252
- stub_const('::SecureHeaders', ::SecureHeadersMocks::SecureHeaders20)
253
- end
254
-
255
- it 'renders the snippet and config in the response without nonce in script tag when too old SecureHeaders installed' do
256
- _, _, response = subject.call(env)
257
- new_body = response.body.join
258
-
259
- expect(new_body).to include('<script type="text/javascript">')
260
- expect(new_body).to include("var _rollbarConfig = #{config[:options].to_json};")
261
- expect(new_body).to include(snippet)
262
- end
263
- end
264
-
265
- context 'having a html 200 response without head', :add_js => false do
266
- let(:body) { ['foobar'] }
267
- let(:status) { 200 }
268
- let(:headers) do
269
- { 'Content-Type' => content_type }
270
- end
271
- end
272
-
273
- context 'having a html 200 response without head but with an header tag', :add_js => false do
274
- let(:body) { ['<header>foobar</header>'] }
275
- let(:status) { 200 }
276
- let(:headers) do
277
- { 'Content-Type' => content_type }
278
- end
279
- end
280
-
281
- context 'having a html 302 response', :add_js => false do
282
- let(:body) { ['foobar'] }
283
- let(:status) { 302 }
284
- let(:headers) do
285
- { 'Content-Type' => content_type }
286
- end
287
- end
288
-
289
- context 'having the js already injected key in env', :add_js => false do
290
- let(:body) { ['foobar'] }
291
- let(:status) { 200 }
292
- let(:headers) do
293
- { 'Content-Type' => content_type }
294
- end
295
- let(:env) do
296
- { described_class::JS_IS_INJECTED_KEY => true }
297
- end
298
- end
299
-
300
- context 'having an attachment', :add_js => false do
301
- let(:content_type) { 'text/plain' }
302
- let(:body) { ['foobar'] }
303
- let(:status) { 200 }
304
- let(:headers) do
305
- { 'Content-Disposition' => 'attachment',
306
- 'Content-Type' => content_type
307
- }
308
- end
309
- end
310
-
311
- context 'with an exception raised while adding the js', :add_js => false do
312
- let(:body) { [html] }
313
- let(:status) { 200 }
314
- let(:headers) do
315
- { 'Content-Type' => content_type }
316
- end
317
-
318
- before do
319
- allow(subject).to receive(:add_js).and_raise(StandardError.new)
320
- end
321
- end
322
-
323
- context 'with person data' do
324
- let(:body) { [html] }
325
- let(:status) { 200 }
326
- let(:headers) do
327
- { 'Content-Type' => content_type }
328
- end
329
- let(:config) do
330
- {
331
- :enabled => true,
332
- :options => { :foo => :bar, :payload => { :a => 42 } }
333
- }
334
- end
335
- let(:env) do
336
- {
337
- 'rollbar.person_data' => {
338
- :id => 100,
339
- :username => 'foo',
340
- :email => 'foo@bar.com'
341
- }
342
- }
343
- end
344
- let(:expected_js_options) do
345
- {
346
- :foo => 'bar',
347
- :payload => {
348
- :a => 42,
349
- :person => {
350
- :id => 100,
351
- :username => 'foo',
352
- :email => 'foo@bar.com'
353
- }
354
- }
355
- }
356
- end
357
-
358
- it 'adds the person data to the configuration' do
359
- _, _, response = subject.call(env)
360
- new_body = response.body.join
361
-
362
- rollbar_config = new_body[/var _rollbarConfig = (.*);<\/script>/, 1]
363
- rollbar_config = JSON.parse(rollbar_config, { :symbolize_names => true})
364
-
365
- expect(rollbar_config).to eql(expected_js_options)
366
- end
367
-
368
- context 'when the person data is nil' do
369
- let(:env) do
370
- {
371
- 'rollbar.person_data' => nil
372
- }
373
- end
374
-
375
- it 'works correctly and doesnt add anything about person data' do
376
- _, _, response = subject.call(env)
377
- new_body = response.body.join
378
-
379
- expect(new_body).not_to include('person')
380
- end
381
-
382
- it 'doesnt include old data when called a second time' do
383
- _, _, _ = subject.call({
384
- 'rollbar.person_data' => {
385
- :id => 100,
386
- :username => 'foo',
387
- :email => 'foo@bar.com'
388
- }
389
- })
390
- _, _, response = subject.call(env)
391
- new_body = response.body.join
392
-
393
- expect(new_body).not_to include('person')
394
- end
395
- end
396
- end
397
- end
398
-
399
- context 'having the config disabled', :add_js => false do
400
- let(:body) { ['foobar'] }
401
- let(:status) { 302 }
402
- let(:headers) do
403
- { 'Content-Type' => content_type }
404
- end
405
- let(:config) do
406
- {
407
- :enabled => false,
408
- :options => { :foo => :bar }
409
- }
410
- end
411
- end
412
-
413
- context 'if the app raises' do
414
- let(:exception) { StandardError.new }
415
- let(:app) do
416
- proc do |_|
417
- raise exception
418
- end
419
- end
420
-
421
- it 'propagates the exception' do
422
- expect do
423
- app.call(env)
424
- end.to raise_exception(exception)
425
- end
426
- end
427
- end
428
- end