rollbar 2.7.1 → 2.8.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.
@@ -0,0 +1,5 @@
1
+ module Rollbar
2
+ module Js
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,83 @@
1
+ module Rollbar
2
+ class LazyStore
3
+ attr_reader :loaded_data
4
+ private :loaded_data
5
+
6
+ attr_reader :raw
7
+
8
+ def initialize(initial_data)
9
+ initial_data ||= {}
10
+
11
+ @raw = initial_data
12
+ @loaded_data = {}
13
+ end
14
+
15
+ def eql?(other)
16
+ if other.is_a?(self.class)
17
+ raw.eql?(other.raw)
18
+ else
19
+ raw.eql?(other)
20
+ end
21
+ end
22
+
23
+ def ==(other)
24
+ if other.is_a?(self.class)
25
+ raw == other.raw
26
+ else
27
+ raw == other
28
+ end
29
+ end
30
+
31
+ # With this version of clone we ensure that the loaded_data is empty
32
+ def clone
33
+ self.class.new(raw.clone)
34
+ end
35
+
36
+ def [](key)
37
+ load_value(key)
38
+ end
39
+
40
+ def []=(key, value)
41
+ raw[key] = value
42
+
43
+ loaded_data.delete(key)
44
+
45
+ value
46
+ end
47
+
48
+ def data
49
+ raw.reduce({}) do |acc, (k, _)|
50
+ acc[k] = self[k]
51
+
52
+ acc
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def load_value(key)
59
+ return loaded_data[key] if loaded_data.key?(key)
60
+ return unless raw.key?(key)
61
+
62
+ value = find_value(key)
63
+ loaded_data[key] = value
64
+
65
+ value
66
+ end
67
+
68
+ def find_value(key)
69
+ value = raw[key]
70
+ value.respond_to?(:call) ? value.call : value
71
+ end
72
+
73
+ def method_missing(method_sym, *args, &block)
74
+ return raw.send(method_sym, *args, &block) if raw.respond_to?(method_sym)
75
+
76
+ super
77
+ end
78
+
79
+ def respond_to?(method_sym)
80
+ super || raw.respond_to?(method_sym)
81
+ end
82
+ end
83
+ end
@@ -6,7 +6,7 @@ namespace :rollbar do
6
6
 
7
7
  desc 'Send the deployment notification to Rollbar.'
8
8
  task :deploy do
9
- on roles fetch(:rollbar_role) do
9
+ on primary fetch(:rollbar_role) do
10
10
  warn("You need to upgrade capistrano to '>= 3.1' version in order to correctly report deploys to Rollbar. (On 3.0, the reported revision will be incorrect.)") if Capistrano::VERSION =~ /^3\.0/
11
11
 
12
12
  uri = URI.parse 'https://api.rollbar.com/api/1/deploy/'
@@ -1,3 +1,3 @@
1
1
  module Rollbar
2
- VERSION = "2.7.1"
2
+ VERSION = "2.8.0"
3
3
  end
@@ -0,0 +1,13 @@
1
+ require 'fileutils'
2
+
3
+ desc 'Update rollbar.js snippet'
4
+ task :update_snippet do
5
+ input_path = File.expand_path("../../../rollbar.js/dist/rollbar.snippet.js", __FILE__)
6
+ output_path = File.expand_path("../../../data/rollbar.snippet.js", __FILE__)
7
+ output_dir = File.expand_path("../../../data/", __FILE__)
8
+
9
+ $stdout.write("Copying #{input_path} to #{output_path}\n")
10
+
11
+ FileUtils.mkdir_p(output_dir)
12
+ FileUtils.copy(input_path, output_path)
13
+ end
@@ -23,7 +23,7 @@ Gem::Specification.new do |gem|
23
23
  gem.add_development_dependency 'rspec-rails', '>= 2.14.0'
24
24
  gem.add_development_dependency 'database_cleaner', '~> 1.0.0'
25
25
  gem.add_development_dependency 'girl_friday', '>= 0.11.1'
26
- gem.add_development_dependency 'sucker_punch', '>= 1.0.0' if RUBY_VERSION != '1.8.7'
26
+ gem.add_development_dependency 'sucker_punch', '~> 1.0.0' if RUBY_VERSION != '1.8.7'
27
27
  gem.add_development_dependency 'sidekiq', '>= 2.13.0' if RUBY_VERSION != '1.8.7'
28
28
  gem.add_development_dependency 'genspec', '>= 0.2.8'
29
29
  gem.add_development_dependency 'sinatra'
@@ -28,6 +28,10 @@ class HomeController < ApplicationController
28
28
  foo = bar
29
29
  end
30
30
 
31
+ def test_rollbar_js
32
+ render 'js/test', :layout => 'simple'
33
+ end
34
+
31
35
  def file_upload
32
36
  this = will_crash
33
37
  end
@@ -0,0 +1 @@
1
+ Testing Rollbar JS
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
+ <title><%= content_for?(:title) ? yield(:title) : "Dummyapp" %></title>
6
+ <meta name="description" content="<%= content_for?(:description) ? yield(:description) : "Dummyapp" %>">
7
+ <%= yield(:head) %>
8
+ </head>
9
+ <body class="<%= controller_name %> <%= action_name %>">
10
+ <div id="container" class="container">
11
+ <div id="main" role="main">
12
+ <%= yield %>
13
+ </div>
14
+ <footer>
15
+ </footer>
16
+ </div> <!--! end of #container -->
17
+ </body>
18
+ </html>
@@ -1,7 +1,10 @@
1
1
  Rollbar.configure do |config|
2
2
  config.access_token = 'aaaabbbbccccddddeeeeffff00001111'
3
3
  config.request_timeout = 60
4
-
4
+ config.js_enabled = true
5
+ config.js_options = {
6
+ :foo => :bar
7
+ }
5
8
  # By default, Rollbar will try to call the `current_user` controller method
6
9
  # to fetch the logged-in user object, and then call that object's `id`,
7
10
  # `username`, and `email` methods to fetch those properties. To customize:
@@ -17,4 +20,4 @@ Rollbar.configure do |config|
17
20
  # Valid levels: 'critical', 'error', 'warning', 'info', 'debug', 'ignore'
18
21
  # 'ignore' will cause the exception to not be reported at all.
19
22
  # config.exception_level_filters.merge!('MyCriticalException' => 'critical')
20
- end unless ENV['SKIP_DUMMY_ROLLBAR'] == "true"
23
+ end
@@ -13,4 +13,5 @@ Dummy::Application.routes.draw do
13
13
 
14
14
  get '/set_session_data' => 'home#set_session_data'
15
15
  get '/use_session_data' => 'home#use_session_data'
16
+ get '/test_rollbar_js' => 'home#test_rollbar_js'
16
17
  end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApplicationController, :type => 'request' do
4
+ before do
5
+ Rollbar.configure do |config|
6
+ config.js_options = { :foo => :bar }
7
+ config.js_enabled = true
8
+ end
9
+ end
10
+
11
+ it 'renders the snippet and config in the response', :type => 'request' do
12
+ get '/test_rollbar_js'
13
+
14
+ snippet_from_submodule = File.read(File.expand_path('../../../../../rollbar.js/dist/rollbar.snippet.js', __FILE__))
15
+
16
+ expect(response.body).to include("var _rollbarConfig = #{Rollbar::configuration.js_options.to_json};")
17
+ expect(response.body).to include(snippet_from_submodule)
18
+ end
19
+ end
@@ -0,0 +1,154 @@
1
+ require 'spec_helper'
2
+ require 'rollbar/js/middleware'
3
+
4
+ describe Rollbar::Js::Middleware do
5
+ subject { described_class.new(app, config) }
6
+
7
+ let(:env) { {} }
8
+ let(:config) { {} }
9
+ let(:app) do
10
+ proc do |_|
11
+ [status, headers, body]
12
+ end
13
+ end
14
+ let(:html) do
15
+ <<-END
16
+ <html>
17
+ <head>
18
+ <link rel="stylesheet" href="url" type="text/css" media="screen" />
19
+ <script type="text/javascript" src="foo"></script>
20
+ </head>
21
+ <body>
22
+ <h1>Testing the middleware</h1>
23
+ </body>
24
+ </html>
25
+ END
26
+ end
27
+ let(:snippet) { 'THIS IS THE SNIPPET' }
28
+ let(:content_type) { 'text/html' }
29
+
30
+ before do
31
+ allow(subject).to receive(:js_snippet).and_return(snippet)
32
+ end
33
+
34
+ shared_examples "doesn't add the snippet or config", :add_js => false do
35
+ it "doesn't add the snippet or config" do
36
+ res_status, res_headers, response = subject.call(env)
37
+ new_body = response.join
38
+
39
+ expect(new_body).not_to include(snippet)
40
+ expect(new_body).not_to include(config[:options].to_json)
41
+ expect(new_body).to be_eql(body.join)
42
+ expect(res_status).to be_eql(status)
43
+ expect(res_headers['Content-Type']).to be_eql(content_type)
44
+ end
45
+ end
46
+
47
+ describe '#call' do
48
+ context 'with enabled config' do
49
+ let(:config) do
50
+ {
51
+ :enabled => true,
52
+ :options => { :foo => :bar }
53
+ }
54
+ end
55
+
56
+ context 'having a html 200 response' do
57
+ let(:body) { [html] }
58
+ let(:status) { 200 }
59
+ let(:headers) do
60
+ { 'Content-Type' => content_type }
61
+ end
62
+
63
+ it 'adds the config and the snippet to the response' do
64
+ res_status, res_headers, response = subject.call(env)
65
+ new_body = response.body.join
66
+
67
+ expect(new_body).to include(snippet)
68
+ expect(new_body).to include(config[:options].to_json)
69
+ expect(res_status).to be_eql(status)
70
+ expect(res_headers['Content-Type']).to be_eql(content_type)
71
+ end
72
+ end
73
+
74
+ context 'having a html 200 response without head', :add_js => false do
75
+ let(:body) { ['foobar'] }
76
+ let(:status) { 200 }
77
+ let(:headers) do
78
+ { 'Content-Type' => content_type }
79
+ end
80
+ end
81
+
82
+ context 'having a html 302 response', :add_js => false do
83
+ let(:body) { ['foobar'] }
84
+ let(:status) { 302 }
85
+ let(:headers) do
86
+ { 'Content-Type' => content_type }
87
+ end
88
+ end
89
+
90
+ context 'having the js already injected key in env', :add_js => false do
91
+ let(:body) { ['foobar'] }
92
+ let(:status) { 200 }
93
+ let(:headers) do
94
+ { 'Content-Type' => content_type }
95
+ end
96
+ let(:env) do
97
+ { described_class::JS_IS_INJECTED_KEY => true }
98
+ end
99
+ end
100
+
101
+ context 'having an attachment', :add_js => false do
102
+ let(:content_type) { 'text/plain' }
103
+ let(:body) { ['foobar'] }
104
+ let(:status) { 200 }
105
+ let(:headers) do
106
+ { 'Content-Disposition' => 'attachment',
107
+ 'Content-Type' => content_type
108
+ }
109
+ end
110
+ end
111
+
112
+ context 'with an exception raised while adding the js', :add_js => false do
113
+ let(:body) { [html] }
114
+ let(:status) { 200 }
115
+ let(:headers) do
116
+ { 'Content-Type' => content_type }
117
+ end
118
+
119
+ before do
120
+ allow(subject).to receive(:add_js).and_raise(StandardError.new)
121
+ end
122
+ end
123
+ end
124
+
125
+ context 'having the config disabled', :add_js => false do
126
+ let(:body) { ['foobar'] }
127
+ let(:status) { 302 }
128
+ let(:headers) do
129
+ { 'Content-Type' => content_type }
130
+ end
131
+ let(:config) do
132
+ {
133
+ :enabled => false,
134
+ :options => { :foo => :bar }
135
+ }
136
+ end
137
+ end
138
+
139
+ context 'if the app raises' do
140
+ let(:exception) { StandardError.new }
141
+ let(:app) do
142
+ proc do |_|
143
+ raise exception
144
+ end
145
+ end
146
+
147
+ it 'propagates the exception' do
148
+ expect do
149
+ app.call(env)
150
+ end.to raise_exception(exception)
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,99 @@
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