appsignal 1.4.0.beta.1 → 2.0.0.beta.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.
@@ -1,92 +1,201 @@
1
1
  if DependencyHelper.grape_present?
2
- require 'appsignal/integrations/grape'
2
+ require "appsignal/integrations/grape"
3
3
 
4
4
  describe Appsignal::Grape::Middleware do
5
-
6
- before :all do
7
- start_agent
5
+ let(:app) do
6
+ Class.new(::Grape::API) do
7
+ format :json
8
+ post :ping do
9
+ { :message => "Hello world!" }
10
+ end
11
+ end
8
12
  end
9
-
10
- let(:app) { double(:call => true) }
11
- let(:api_endpoint) { double(:options => options) }
12
- let(:options) { {
13
- :for => 'Api::PostPut',
14
- :method => ['POST'],
15
- :path => ['ping']
16
- }}
13
+ let(:api_endpoint) { app.endpoints.first }
17
14
  let(:env) do
18
- http_request_env_with_data('api.endpoint' => api_endpoint)
15
+ http_request_env_with_data \
16
+ "api.endpoint" => api_endpoint,
17
+ "REQUEST_METHOD" => "POST",
18
+ :path => "/ping"
19
+ end
20
+ let(:middleware) { Appsignal::Grape::Middleware.new(api_endpoint) }
21
+ around do |example|
22
+ GrapeExample = Module.new
23
+ GrapeExample.send(:const_set, :Api, app)
24
+ example.run
25
+ Object.send(:remove_const, :GrapeExample)
19
26
  end
20
- let(:middleware) { Appsignal::Grape::Middleware.new(app) }
21
27
 
22
28
  describe "#call" do
23
- context "when appsignal is active" do
24
- before { Appsignal.stub(:active? => true) }
29
+ context "when AppSignal is not active" do
30
+ before(:all) do
31
+ Appsignal.config = nil
32
+ Appsignal::Hooks.load_hooks
33
+ end
25
34
 
26
- it "should call with monitoring" do
27
- expect( middleware ).to receive(:call_with_appsignal_monitoring).with(env)
35
+ it "creates no transaction" do
36
+ expect(Appsignal::Transaction).to_not receive(:create)
28
37
  end
29
- end
30
38
 
31
- context "when appsignal is not active" do
32
- before { Appsignal.stub(:active? => false) }
39
+ it "calls the endpoint normally" do
40
+ expect(api_endpoint).to receive(:call).with(env)
41
+ end
33
42
 
34
- it "should not call with monitoring" do
35
- expect( middleware ).to_not receive(:call_with_appsignal_monitoring)
43
+ after { middleware.call(env) }
44
+ end
45
+
46
+ context "when AppSignal is active" do
47
+ let(:transaction) { http_request_transaction }
48
+ before :all do
49
+ Appsignal.config = project_fixture_config
50
+ expect(Appsignal.active?).to be_true
51
+ end
52
+ before do
53
+ expect(Appsignal::Transaction).to receive(:create).with(
54
+ kind_of(String),
55
+ Appsignal::Transaction::HTTP_REQUEST,
56
+ kind_of(::Rack::Request)
57
+ ).and_return(transaction)
36
58
  end
37
59
 
38
- it "should call the app" do
39
- expect( app ).to receive(:call).with(env)
60
+ context "without error" do
61
+ it "calls the endpoint" do
62
+ expect(api_endpoint).to receive(:call).with(env)
63
+ end
64
+
65
+ it "sets metadata" do
66
+ expect(transaction).to receive(:set_http_or_background_queue_start)
67
+ expect(transaction).to receive(:set_action).with("POST::GrapeExample::Api#/ping")
68
+ expect(transaction).to receive(:set_metadata).with("path", "/ping")
69
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
70
+ end
71
+
72
+ after { middleware.call(env) }
40
73
  end
41
- end
42
74
 
43
- after { middleware.call(env) }
44
- end
75
+ context "with error" do
76
+ let(:app) do
77
+ Class.new(::Grape::API) do
78
+ format :json
79
+ post :ping do
80
+ raise VerySpecificError
81
+ end
82
+ end
83
+ end
45
84
 
46
- describe "#call_with_appsignal_monitoring" do
47
- before { SecureRandom.stub(:uuid => '1') }
48
-
49
- it "should create a transaction" do
50
- Appsignal::Transaction.should_receive(:create).with(
51
- '1',
52
- Appsignal::Transaction::HTTP_REQUEST,
53
- kind_of(::Rack::Request)
54
- ).and_return(
55
- double(
56
- :set_action => nil,
57
- :set_http_or_background_queue_start => nil,
58
- :set_metadata => nil
59
- )
60
- )
61
- end
85
+ it "sets metadata" do
86
+ expect(transaction).to receive(:set_http_or_background_queue_start)
87
+ expect(transaction).to receive(:set_action).with("POST::GrapeExample::Api#/ping")
88
+ expect(transaction).to receive(:set_metadata).with("path", "/ping")
89
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
90
+ end
62
91
 
63
- it "should call the app" do
64
- app.should_receive(:call).with(env)
65
- end
92
+ it "sets the error" do
93
+ expect(transaction).to receive(:set_error).with(kind_of(VerySpecificError))
94
+ end
66
95
 
67
- context "with an error" do
68
- let(:error) { VerySpecificError.new }
69
- let(:app) do
70
- double.tap do |d|
71
- d.stub(:call).and_raise(error)
96
+ after do
97
+ expect { middleware.call(env) }.to raise_error VerySpecificError
72
98
  end
73
99
  end
74
100
 
75
- it "should set the error" do
76
- Appsignal::Transaction.any_instance.should_receive(:set_error).with(error)
101
+ context "with route_param" do
102
+ let(:app) do
103
+ Class.new(::Grape::API) do
104
+ format :json
105
+ resource :users do
106
+ route_param :id do
107
+ get do
108
+ { :name => "Tom" }
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ let(:env) do
115
+ http_request_env_with_data \
116
+ "api.endpoint" => api_endpoint,
117
+ "REQUEST_METHOD" => "GET",
118
+ :path => ""
119
+ end
120
+
121
+ it "sets non-unique route_param path" do
122
+ expect(transaction).to receive(:set_action).with("GET::GrapeExample::Api#/users/:id/")
123
+ expect(transaction).to receive(:set_metadata).with("path", "/users/:id/")
124
+ expect(transaction).to receive(:set_metadata).with("method", "GET")
125
+ end
126
+
127
+ after { middleware.call(env) }
77
128
  end
78
- end
79
129
 
80
- it "should set metadata" do
81
- Appsignal::Transaction.any_instance.should_receive(:set_metadata).twice
82
- end
130
+ context "with namespaced path" do
131
+ context "with symbols" do
132
+ let(:app) do
133
+ Class.new(::Grape::API) do
134
+ format :json
135
+ namespace :v1 do
136
+ namespace :beta do
137
+ post :ping do
138
+ { :message => "Hello namespaced world!" }
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ it "sets namespaced path" do
146
+ expect(transaction).to receive(:set_action).with("POST::GrapeExample::Api#/v1/beta/ping")
147
+ expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
148
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
149
+ end
150
+ end
83
151
 
84
- it "should set the action and queue start" do
85
- Appsignal::Transaction.any_instance.should_receive(:set_action).with('POST::Api::PostPut#ping')
86
- Appsignal::Transaction.any_instance.should_receive(:set_http_or_background_queue_start)
87
- end
152
+ context "with strings" do
153
+ context "without / prefix" do
154
+ let(:app) do
155
+ Class.new(::Grape::API) do
156
+ format :json
157
+ namespace "v1" do
158
+ namespace "beta" do
159
+ post "ping" do
160
+ { :message => "Hello namespaced world!" }
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ it "sets namespaced path" do
168
+ expect(transaction).to receive(:set_action).with("POST::GrapeExample::Api#/v1/beta/ping")
169
+ expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
170
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
171
+ end
172
+ end
173
+
174
+ context "with / prefix" do
175
+ let(:app) do
176
+ Class.new(::Grape::API) do
177
+ format :json
178
+ namespace "/v1" do
179
+ namespace "/beta" do
180
+ post "/ping" do
181
+ { :message => "Hello namespaced world!" }
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+
188
+ it "sets namespaced path" do
189
+ expect(transaction).to receive(:set_action).with("POST::GrapeExample::Api#/v1/beta/ping")
190
+ expect(transaction).to receive(:set_metadata).with("path", "/v1/beta/ping")
191
+ expect(transaction).to receive(:set_metadata).with("method", "POST")
192
+ end
193
+ end
194
+ end
88
195
 
89
- after { middleware.call(env) rescue VerySpecificError }
196
+ after { middleware.call(env) }
197
+ end
198
+ end
90
199
  end
91
200
  end
92
201
  end
@@ -21,22 +21,22 @@ describe Appsignal::JSExceptionTransaction do
21
21
 
22
22
  describe "#initialize" do
23
23
  it "should call all required methods" do
24
- expect( Appsignal::Extension ).to receive(:start_transaction).with('123abc', 'frontend', 0).and_return(1)
24
+ expect(Appsignal::Extension).to receive(:start_transaction).with('123abc', 'frontend', 0).and_return(1)
25
25
 
26
- expect( transaction ).to receive(:set_action)
27
- expect( transaction ).to receive(:set_metadata)
28
- expect( transaction ).to receive(:set_error)
29
- expect( transaction ).to receive(:set_sample_data)
26
+ expect(transaction).to receive(:set_action)
27
+ expect(transaction).to receive(:set_metadata)
28
+ expect(transaction).to receive(:set_error)
29
+ expect(transaction).to receive(:set_sample_data)
30
30
 
31
31
  transaction.send :initialize, data
32
32
 
33
- expect( transaction.ext ).not_to be_nil
33
+ expect(transaction.ext).to_not be_nil
34
34
  end
35
35
  end
36
36
 
37
- describe "#set_base_data" do
38
- it "should call `Appsignal::Extension.set_transaction_basedata`" do
39
- expect( transaction.ext ).to receive(:set_action).with(
37
+ describe "#set_action" do
38
+ it "should call `Appsignal::Extension.set_action`" do
39
+ expect(transaction.ext).to receive(:set_action).with(
40
40
  'ExceptionIncidentComponent'
41
41
  )
42
42
 
@@ -45,43 +45,83 @@ describe Appsignal::JSExceptionTransaction do
45
45
  end
46
46
 
47
47
  describe "#set_metadata" do
48
- it "should call `Appsignal::Extension.set_transaction_metadata`" do
49
- expect( transaction.ext ).to receive(:set_metadata).with(
50
- 'path',
51
- 'foo.bar/moo'
52
- )
53
-
54
- transaction.set_metadata
55
- end
48
+ it "should call `Appsignal::Extension.set_transaction_metadata`" do
49
+ expect(transaction.ext).to receive(:set_metadata).with(
50
+ 'path',
51
+ 'foo.bar/moo'
52
+ )
53
+
54
+ transaction.set_metadata
55
+ end
56
56
  end
57
57
 
58
58
  describe "#set_error" do
59
- it "should call `Appsignal::Extension.set_transaction_error`" do
60
- expect( transaction.ext ).to receive(:set_error).with(
61
- 'TypeError',
62
- 'foo is not a valid method',
63
- Appsignal::Utils.data_generate(['foo.bar/js:11:1', 'foo.bar/js:22:2'])
64
- )
65
-
66
- transaction.set_error
67
- end
59
+ it "should call `Appsignal::Extension.set_transaction_error`" do
60
+ expect(transaction.ext).to receive(:set_error).with(
61
+ 'TypeError',
62
+ 'foo is not a valid method',
63
+ Appsignal::Utils.data_generate(['foo.bar/js:11:1', 'foo.bar/js:22:2'])
64
+ )
65
+
66
+ transaction.set_error
67
+ end
68
68
  end
69
69
 
70
70
  describe "#set_sample_data" do
71
- it "should call `Appsignal::Extension.set_transaction_error_data`" do
72
- expect( transaction.ext ).to receive(:set_sample_data).with(
73
- 'tags',
74
- Appsignal::Utils.data_generate(['tag1'])
75
- )
76
-
77
- transaction.set_sample_data
78
- end
71
+ it "should call `Appsignal::Extension.set_transaction_error_data`" do
72
+ expect(transaction.ext).to receive(:set_sample_data).with(
73
+ 'tags',
74
+ Appsignal::Utils.data_generate(['tag1'])
75
+ )
76
+
77
+ transaction.set_sample_data
78
+ end
79
+ end
80
+
81
+ context "when sending just the name" do
82
+ let(:data) { {'name' => 'TypeError'} }
83
+
84
+ describe "#set_action" do
85
+ it "should not call `Appsignal::Extension.set_action`" do
86
+ expect(transaction.ext).to_not receive(:set_action)
87
+
88
+ transaction.set_action
89
+ end
90
+ end
91
+
92
+ describe "#set_metadata" do
93
+ it "should not call `Appsignal::Extension.set_transaction_metadata`" do
94
+ expect(transaction.ext).to_not receive(:set_metadata)
95
+
96
+ transaction.set_metadata
97
+ end
98
+ end
99
+
100
+ describe "#set_error" do
101
+ it "should call `Appsignal::Extension.set_transaction_error` with just the name" do
102
+ expect(transaction.ext).to receive(:set_error).with(
103
+ 'TypeError',
104
+ '',
105
+ Appsignal::Utils.data_generate([])
106
+ )
107
+
108
+ transaction.set_error
109
+ end
110
+ end
111
+
112
+ describe "#set_sample_data" do
113
+ it "should not call `Appsignal::Extension.set_transaction_error_data`" do
114
+ expect(transaction.ext).to_not receive(:set_sample_data)
115
+
116
+ transaction.set_sample_data
117
+ end
118
+ end
79
119
  end
80
120
 
81
121
  describe "#complete!" do
82
122
  it "should call all required methods" do
83
- expect( transaction.ext ).to receive(:finish)
84
- expect( transaction.ext ).to receive(:complete)
123
+ expect(transaction.ext).to receive(:finish)
124
+ expect(transaction.ext).to receive(:complete)
85
125
  transaction.complete!
86
126
  end
87
127
  end
@@ -30,8 +30,8 @@ describe Appsignal::Marker do
30
30
  it "outputs success" do
31
31
  output = out_stream.string
32
32
  expect(output).to include \
33
- 'Notifying Appsignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman',
34
- 'Appsignal has been notified of this deploy!'
33
+ 'Notifying AppSignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman',
34
+ 'AppSignal has been notified of this deploy!'
35
35
  end
36
36
  end
37
37
 
@@ -44,11 +44,11 @@ describe Appsignal::Marker do
44
44
  it "outputs failure" do
45
45
  output = out_stream.string
46
46
  expect(output).to include \
47
- 'Notifying Appsignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman',
48
- "Something went wrong while trying to notify Appsignal: 500 at "\
47
+ 'Notifying AppSignal of deploy with: revision: 503ce0923ed177a3ce000005, user: batman',
48
+ "Something went wrong while trying to notify AppSignal: 500 at "\
49
49
  "#{config[:endpoint]}/1/markers"
50
50
  expect(output).to_not include \
51
- 'Appsignal has been notified of this deploy!'
51
+ 'AppSignal has been notified of this deploy!'
52
52
  end
53
53
  end
54
54
  end
@@ -12,7 +12,7 @@ describe Appsignal::Rack::JSExceptionCatcher do
12
12
 
13
13
  describe "#initialize" do
14
14
  it "should log to the logger" do
15
- expect( Appsignal.logger ).to receive(:debug)
15
+ expect(Appsignal.logger).to receive(:debug)
16
16
  .with('Initializing Appsignal::Rack::JSExceptionCatcher')
17
17
 
18
18
  Appsignal::Rack::JSExceptionCatcher.new(app, options)
@@ -26,7 +26,7 @@ describe Appsignal::Rack::JSExceptionCatcher do
26
26
  let(:env) { {'PATH_INFO' => '/foo'} }
27
27
 
28
28
  it "should call the next middleware" do
29
- expect( app ).to receive(:call).with(env)
29
+ expect(app).to receive(:call).with(env)
30
30
  end
31
31
  end
32
32
 
@@ -35,16 +35,23 @@ describe Appsignal::Rack::JSExceptionCatcher do
35
35
  let(:env) do
36
36
  {
37
37
  'PATH_INFO' => '/appsignal_error_catcher',
38
- 'rack.input' => double(:read => '{"foo": "bar"}')
38
+ 'rack.input' => double(:read => '{"name": "error"}')
39
39
  }
40
40
  end
41
41
 
42
42
  it "should create a JSExceptionTransaction" do
43
- expect( Appsignal::JSExceptionTransaction ).to receive(:new)
44
- .with({'foo' => 'bar'})
43
+ expect(Appsignal::JSExceptionTransaction).to receive(:new)
44
+ .with({'name' => 'error'})
45
45
  .and_return(transaction)
46
46
 
47
- expect( transaction ).to receive(:complete!)
47
+ expect(transaction).to receive(:complete!)
48
+ end
49
+
50
+ it "should return 200" do
51
+ allow( Appsignal::JSExceptionTransaction).to receive(:new)
52
+ .and_return(transaction)
53
+
54
+ expect(catcher.call(env)).to eql([200, {}, []])
48
55
  end
49
56
 
50
57
  context "when `frontend_error_catching_path` is different" do
@@ -55,16 +62,49 @@ describe Appsignal::Rack::JSExceptionCatcher do
55
62
  end
56
63
 
57
64
  it "should not create a transaction" do
58
- expect( Appsignal::JSExceptionTransaction ).to_not receive(:new)
65
+ expect(Appsignal::JSExceptionTransaction).to_not receive(:new)
59
66
  end
60
67
 
61
68
  it "should call the next middleware" do
62
- expect( app ).to receive(:call).with(env)
69
+ expect(app).to receive(:call).with(env)
70
+ end
71
+ end
72
+
73
+ context "when `name` is empty" do
74
+ let(:env) do
75
+ {
76
+ 'PATH_INFO' => '/appsignal_error_catcher',
77
+ 'rack.input' => double(:read => '{"name": ""}')
78
+ }
79
+ end
80
+
81
+ it "should not create a transaction" do
82
+ expect(Appsignal::JSExceptionTransaction).to_not receive(:new)
83
+ end
84
+
85
+ it "should return 422" do
86
+ expect(catcher.call(env)).to eql([422, {}, []])
87
+ end
88
+ end
89
+
90
+ context "when `name` doesn't exist" do
91
+ let(:env) do
92
+ {
93
+ 'PATH_INFO' => '/appsignal_error_catcher',
94
+ 'rack.input' => double(:read => '{"foo": ""}')
95
+ }
96
+ end
97
+
98
+ it "should not create a transaction" do
99
+ expect(Appsignal::JSExceptionTransaction).to_not receive(:new)
100
+ end
101
+
102
+ it "should return 422" do
103
+ expect(catcher.call(env)).to eql([422, {}, []])
63
104
  end
64
105
  end
65
106
  end
66
107
 
67
108
  after { catcher.call(env) }
68
109
  end
69
-
70
110
  end