appsignal 1.4.0.beta.1 → 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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