captivus 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +2 -1
  3. data/README.md +9 -0
  4. data/captivus.gemspec +2 -1
  5. data/lib/captivus/backtrace/line.rb +14 -8
  6. data/lib/captivus/backtrace.rb +8 -2
  7. data/lib/captivus/configuration.rb +4 -2
  8. data/lib/captivus/notifier.rb +34 -0
  9. data/lib/captivus/payload.rb +70 -14
  10. data/lib/captivus/rack_capturer.rb +4 -8
  11. data/lib/captivus/rails_capturer.rb +21 -0
  12. data/lib/captivus/railtie.rb +35 -0
  13. data/lib/captivus/tasks/captivus.rake +12 -0
  14. data/lib/captivus/util.rb +24 -0
  15. data/lib/captivus/version.rb +1 -1
  16. data/lib/captivus.rb +30 -14
  17. data/rails-3.0-app/.rspec +1 -0
  18. data/rails-3.0-app/Gemfile +40 -0
  19. data/rails-3.0-app/README +256 -0
  20. data/rails-3.0-app/Rakefile +7 -0
  21. data/rails-3.0-app/app/controllers/application_controller.rb +3 -0
  22. data/rails-3.0-app/app/controllers/errors_controller.rb +5 -0
  23. data/rails-3.0-app/app/helpers/application_helper.rb +2 -0
  24. data/rails-3.0-app/app/views/layouts/application.html.erb +14 -0
  25. data/rails-3.0-app/config/application.rb +42 -0
  26. data/rails-3.0-app/config/boot.rb +6 -0
  27. data/rails-3.0-app/config/database.yml +7 -0
  28. data/rails-3.0-app/config/environment.rb +5 -0
  29. data/rails-3.0-app/config/environments/development.rb +26 -0
  30. data/rails-3.0-app/config/environments/production.rb +49 -0
  31. data/rails-3.0-app/config/environments/test.rb +35 -0
  32. data/rails-3.0-app/config/initializers/backtrace_silencers.rb +7 -0
  33. data/rails-3.0-app/config/initializers/captivus.rb +4 -0
  34. data/rails-3.0-app/config/initializers/inflections.rb +10 -0
  35. data/rails-3.0-app/config/initializers/mime_types.rb +5 -0
  36. data/rails-3.0-app/config/initializers/secret_token.rb +7 -0
  37. data/rails-3.0-app/config/initializers/session_store.rb +8 -0
  38. data/rails-3.0-app/config/locales/en.yml +5 -0
  39. data/rails-3.0-app/config/routes.rb +59 -0
  40. data/rails-3.0-app/config.ru +4 -0
  41. data/rails-3.0-app/db/seeds.rb +7 -0
  42. data/rails-3.0-app/public/404.html +26 -0
  43. data/rails-3.0-app/public/422.html +26 -0
  44. data/rails-3.0-app/public/500.html +26 -0
  45. data/rails-3.0-app/public/favicon.ico +0 -0
  46. data/rails-3.0-app/public/images/rails.png +0 -0
  47. data/rails-3.0-app/public/index.html +239 -0
  48. data/rails-3.0-app/public/javascripts/application.js +2 -0
  49. data/rails-3.0-app/public/javascripts/controls.js +965 -0
  50. data/rails-3.0-app/public/javascripts/dragdrop.js +974 -0
  51. data/rails-3.0-app/public/javascripts/effects.js +1123 -0
  52. data/rails-3.0-app/public/javascripts/prototype.js +6001 -0
  53. data/rails-3.0-app/public/javascripts/rails.js +202 -0
  54. data/rails-3.0-app/public/robots.txt +5 -0
  55. data/rails-3.0-app/script/rails +6 -0
  56. data/rails-3.0-app/spec/requests/events_from_rails_spec.rb +115 -0
  57. data/rails-3.0-app/spec/spec_helper.rb +38 -0
  58. data/rails-3.0-app/spec/support/captivus_api.rb +1 -0
  59. data/rails-3.1-app/.rspec +1 -0
  60. data/rails-3.1-app/Gemfile +44 -0
  61. data/rails-3.1-app/README +261 -0
  62. data/rails-3.1-app/Rakefile +7 -0
  63. data/rails-3.1-app/app/assets/images/rails.png +0 -0
  64. data/rails-3.1-app/app/assets/javascripts/application.js +9 -0
  65. data/rails-3.1-app/app/assets/stylesheets/application.css +7 -0
  66. data/rails-3.1-app/app/controllers/application_controller.rb +3 -0
  67. data/rails-3.1-app/app/controllers/errors_controller.rb +5 -0
  68. data/rails-3.1-app/app/helpers/application_helper.rb +2 -0
  69. data/rails-3.1-app/app/views/layouts/application.html.erb +14 -0
  70. data/rails-3.1-app/config/application.rb +54 -0
  71. data/rails-3.1-app/config/boot.rb +6 -0
  72. data/rails-3.1-app/config/database.yml +7 -0
  73. data/rails-3.1-app/config/environment.rb +5 -0
  74. data/rails-3.1-app/config/environments/development.rb +30 -0
  75. data/rails-3.1-app/config/environments/production.rb +60 -0
  76. data/rails-3.1-app/config/environments/test.rb +39 -0
  77. data/rails-3.1-app/config/initializers/backtrace_silencers.rb +7 -0
  78. data/rails-3.1-app/config/initializers/captivus.rb +4 -0
  79. data/rails-3.1-app/config/initializers/inflections.rb +10 -0
  80. data/rails-3.1-app/config/initializers/mime_types.rb +5 -0
  81. data/rails-3.1-app/config/initializers/secret_token.rb +7 -0
  82. data/rails-3.1-app/config/initializers/session_store.rb +8 -0
  83. data/rails-3.1-app/config/initializers/wrap_parameters.rb +14 -0
  84. data/rails-3.1-app/config/locales/en.yml +5 -0
  85. data/rails-3.1-app/config/routes.rb +59 -0
  86. data/rails-3.1-app/config.ru +4 -0
  87. data/rails-3.1-app/db/seeds.rb +7 -0
  88. data/rails-3.1-app/public/404.html +26 -0
  89. data/rails-3.1-app/public/422.html +26 -0
  90. data/rails-3.1-app/public/500.html +26 -0
  91. data/rails-3.1-app/public/favicon.ico +0 -0
  92. data/rails-3.1-app/public/index.html +241 -0
  93. data/rails-3.1-app/public/robots.txt +5 -0
  94. data/rails-3.1-app/script/rails +6 -0
  95. data/rails-3.1-app/spec/requests/events_from_rails_spec.rb +115 -0
  96. data/rails-3.1-app/spec/spec_helper.rb +38 -0
  97. data/rails-3.1-app/spec/support/captivus_api.rb +1 -0
  98. data/rails-3.2-app/.rspec +1 -0
  99. data/rails-3.2-app/Gemfile +47 -0
  100. data/rails-3.2-app/README.rdoc +261 -0
  101. data/rails-3.2-app/Rakefile +7 -0
  102. data/rails-3.2-app/app/assets/images/rails.png +0 -0
  103. data/rails-3.2-app/app/assets/javascripts/application.js +15 -0
  104. data/rails-3.2-app/app/assets/stylesheets/application.css +13 -0
  105. data/rails-3.2-app/app/controllers/application_controller.rb +3 -0
  106. data/rails-3.2-app/app/controllers/errors_controller.rb +5 -0
  107. data/rails-3.2-app/app/helpers/application_helper.rb +2 -0
  108. data/rails-3.2-app/app/views/layouts/application.html.erb +14 -0
  109. data/rails-3.2-app/config/application.rb +68 -0
  110. data/rails-3.2-app/config/boot.rb +6 -0
  111. data/rails-3.2-app/config/database.yml +7 -0
  112. data/rails-3.2-app/config/environment.rb +5 -0
  113. data/rails-3.2-app/config/environments/development.rb +37 -0
  114. data/rails-3.2-app/config/environments/production.rb +67 -0
  115. data/rails-3.2-app/config/environments/test.rb +37 -0
  116. data/rails-3.2-app/config/initializers/backtrace_silencers.rb +7 -0
  117. data/rails-3.2-app/config/initializers/captivus.rb +4 -0
  118. data/rails-3.2-app/config/initializers/inflections.rb +15 -0
  119. data/rails-3.2-app/config/initializers/mime_types.rb +5 -0
  120. data/rails-3.2-app/config/initializers/secret_token.rb +7 -0
  121. data/rails-3.2-app/config/initializers/session_store.rb +8 -0
  122. data/rails-3.2-app/config/initializers/wrap_parameters.rb +14 -0
  123. data/rails-3.2-app/config/locales/en.yml +5 -0
  124. data/rails-3.2-app/config/routes.rb +59 -0
  125. data/rails-3.2-app/config.ru +4 -0
  126. data/rails-3.2-app/db/schema.rb +16 -0
  127. data/rails-3.2-app/db/seeds.rb +7 -0
  128. data/rails-3.2-app/public/404.html +26 -0
  129. data/rails-3.2-app/public/422.html +26 -0
  130. data/rails-3.2-app/public/500.html +25 -0
  131. data/rails-3.2-app/public/favicon.ico +0 -0
  132. data/rails-3.2-app/public/index.html +241 -0
  133. data/rails-3.2-app/public/robots.txt +5 -0
  134. data/rails-3.2-app/script/rails +6 -0
  135. data/rails-3.2-app/spec/requests/events_from_rails_spec.rb +115 -0
  136. data/rails-3.2-app/spec/spec_helper.rb +38 -0
  137. data/rails-3.2-app/spec/support/captivus_api.rb +1 -0
  138. data/spec/captivus/backtrace/line_spec.rb +20 -10
  139. data/spec/captivus/backtrace_spec.rb +1 -3
  140. data/spec/captivus/configuration_spec.rb +3 -1
  141. data/spec/captivus/notifier_spec.rb +73 -0
  142. data/spec/captivus/payload_spec.rb +293 -28
  143. data/spec/captivus/rack_capturer_spec.rb +32 -15
  144. data/spec/captivus/rails_capturer_spec.rb +59 -0
  145. data/spec/captivus_spec.rb +50 -29
  146. data/spec/integration/events_from_rack_spec.rb +112 -74
  147. data/spec/spec_helper.rb +6 -29
  148. data/spec/support/captivus_api.rb +29 -0
  149. data/spec/support/delorean.rb +5 -0
  150. metadata +154 -4
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require 'captivus/notifier'
3
+
4
+ describe Captivus::Notifier do
5
+ describe "notify" do
6
+ before do
7
+ Timecop.freeze Time.utc(2012, 11, 28, 2, 46, 4)
8
+ @config = double 'config',
9
+ :scheme => 'http',
10
+ :host => 'api.captiv.us',
11
+ :api_key => 'api-key',
12
+ :api_secret_key => 'secret',
13
+ :environment => 'production',
14
+ :development_environments => %w[development test]
15
+ end
16
+ after { Timecop.return }
17
+
18
+ context "when the environment is a development environment" do
19
+ it "doesn't post" do
20
+ @config.stub(:environment) { 'development' }
21
+ Captivus::Notifier.new(@config).notify({})
22
+ expect(captivus_api.requests.size).to eq 0
23
+
24
+ @config.stub(:environment) { 'test' }
25
+ Captivus::Notifier.new(@config).notify({})
26
+ expect(captivus_api.requests.size).to eq 0
27
+ end
28
+ end
29
+
30
+ it "posts the given payload to the endpoint in the config" do
31
+ Captivus::Notifier.new(@config).notify({:a => 1, :b => '2'})
32
+
33
+ expect(captivus_api.requests.size).to eq 1
34
+
35
+ headers = {
36
+ "CONTENT_TYPE"=>"application/json; charset=UTF-8",
37
+ "HTTP_ACCEPT" => "*/*",
38
+ "HTTP_USER_AGENT" => "Ruby",
39
+ "HTTP_DATE" => "Wed, 28 Nov 2012 02:46:04 GMT",
40
+ "HTTP_AUTHORIZATION" => "Captivus api-key:IgBW675pSKkCuD4McYnX9QQMI5g=",
41
+ "PATH_INFO" => "/events",
42
+ "QUERY_STRING" => "",
43
+ "REQUEST_METHOD"=>"POST",
44
+ "SCRIPT_NAME" => "",
45
+ "SERVER_NAME" => "api.captiv.us",
46
+ "SERVER_PORT" => "80",
47
+ "rack.url_scheme" => "http"
48
+ }
49
+
50
+ last_request = captivus_api.requests[0]
51
+
52
+ expect(last_request.values_at(*headers.keys)).to eq headers.values
53
+
54
+ expect(last_request['rack.input'].read).to eq '{"a":1,"b":"2"}'
55
+ end
56
+ end
57
+
58
+ describe "#==" do
59
+ it "is true given another notifier with the same config" do
60
+ config = double 'config'
61
+ expect(Captivus::Notifier.new(config) == Captivus::Notifier.new(config)).to be_true
62
+ end
63
+
64
+ it "is false given another notifier with different config" do
65
+ expect(Captivus::Notifier.new(double('config')) == Captivus::Notifier.new(double('config'))).to be_false
66
+ end
67
+
68
+ it "is false given a non notifier" do
69
+ config = double 'config'
70
+ expect(Captivus::Notifier.new(config) == double('other', :config => config)).to be_false
71
+ end
72
+ end
73
+ end
@@ -2,47 +2,312 @@ require 'spec_helper'
2
2
  require 'captivus/payload'
3
3
 
4
4
  describe Captivus::Payload do
5
+ def valid_hash
6
+ {
7
+ 'notifier' => {'name' => 'captivus-gem', 'version' => '1.2.3', 'language' => 'ruby'},
8
+ 'event' => {'type' => 'SomeEvent', 'message' => "Some message.", 'timestamp' => '2012-10-22T02:25:42Z'},
9
+ 'backtrace' => [
10
+ {'file' => '/Users/austin/go.rb', 'number' => 10, 'method' => 'go'},
11
+ {'file' => '/Users/austin/go.rb', 'number' => 5}
12
+ ],
13
+ 'environment' => {'name' => 'production'}
14
+ }
15
+ end
16
+
5
17
  describe ".new" do
6
- context "when argument doesn't behave like an exception" do
7
- it "raises an argument error" do
8
- [
9
- double('exception'),
10
- double('exception', :class => double('class')),
11
- double('exception', :class => double('class', :name => 'X')),
12
- double('exception', :class => double('class'), :message => 'x')
13
- ].each do |exception|
14
- expect {
15
- Captivus::Payload.new exception
16
- }.to raise_error(ArgumentError, "Unexpected exception: #{exception.inspect}")
18
+ before do
19
+ @exception = JSON::Schema::ValidationError
20
+ @json = {
21
+ :notifier => {
22
+ :name => 'captivus-gem',
23
+ :version => '1.2.3',
24
+ :language => 'ruby'
25
+ },
26
+ :event => {
27
+ :type => 'SomeEvent',
28
+ :message => "Some message.",
29
+ :timestamp => '2012-10-22T02:25:42Z'
30
+ },
31
+ :backtrace => [
32
+ {:file => '/Users/austin/go.rb', :number => 10, :method => 'go'},
33
+ {:file => '/Users/austin/go.rb', :number => 5}
34
+ ],
35
+ :environment => {:name => 'production'}
36
+ }
37
+ end
38
+
39
+ it "does not raise an error with valid payload JSON" do
40
+ expect { Captivus::Payload.new hash_to_json(@json) }.to_not raise_error
41
+
42
+ @json[:backtrace] = []
43
+ expect { Captivus::Payload.new hash_to_json(@json) }.to_not raise_error
44
+
45
+ @json[:context] = {:controller => 'widgets', :action => 'show'}
46
+ expect { Captivus::Payload.new hash_to_json(@json) }.to_not raise_error
47
+ end
48
+
49
+ context "payload JSON" do
50
+ it "must be a string" do
51
+ expect { Captivus::Payload.new nil }.to raise_error(@exception)
52
+ expect { Captivus::Payload.new Object.new }.to raise_error(@exception)
53
+ end
54
+
55
+ it "must be valid JSON" do
56
+ expect { Captivus::Payload.new '{"not" => ["valid json"]' }.to raise_error(@exception)
57
+ end
58
+ end
59
+
60
+ context "notifier" do
61
+ it "is required" do
62
+ @json.delete :notifier
63
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
64
+ end
65
+
66
+ it "must be an object" do
67
+ @json[:notifier] = ''
68
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
69
+ end
70
+
71
+ context "name" do
72
+ it "is required" do
73
+ @json[:notifier].delete :name
74
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
75
+ end
76
+
77
+ it "must be a string" do
78
+ @json[:notifier][:name] = {}
79
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
80
+ end
81
+ end
82
+
83
+ context "version" do
84
+ it "is required" do
85
+ @json[:notifier].delete :version
86
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
87
+ end
88
+
89
+ it "must be a string" do
90
+ @json[:notifier][:version] = {}
91
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
92
+ end
93
+ end
94
+
95
+ context "language" do
96
+ it "is required" do
97
+ @json[:notifier].delete :language
98
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
99
+ end
100
+
101
+ it "must be a string" do
102
+ @json[:notifier][:language] = {}
103
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
17
104
  end
18
105
  end
19
106
  end
20
- end
21
107
 
22
- describe "as_json" do
23
- it "returns a hash of event and backtrace info" do
24
- Timecop.freeze Time.utc(2012, 8, 23, 16, 34, 19)
108
+ context "event" do
109
+ it "is required" do
110
+ @json.delete :event
111
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
112
+ end
113
+
114
+ it "must be an object" do
115
+ @json[:event] = "some event"
116
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
117
+ end
118
+
119
+ context "type" do
120
+ it "is required" do
121
+ @json[:event].delete :type
122
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
123
+ end
124
+
125
+ it "must be a string" do
126
+ @json[:event][:type] = {:foo => 'bar'}
127
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
128
+ end
129
+ end
130
+
131
+ context "message" do
132
+ it "is required" do
133
+ @json[:event].delete :message
134
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
135
+ end
136
+
137
+ it "must be a string" do
138
+ @json[:event][:message] = {:foo => 'bar'}
139
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
140
+ end
141
+ end
142
+
143
+ context "timestamp" do
144
+ it "is required" do
145
+ @json[:event].delete :timestamp
146
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
147
+ end
148
+
149
+ it "must be a date-time" do
150
+ @json[:event][:timestamp] = "2012-12-22"
151
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
152
+ end
153
+ end
154
+ end
155
+
156
+ context "backtrace" do
157
+ it "is required" do
158
+ @json.delete :backtrace
159
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
160
+ end
161
+
162
+ it "must be an array" do
163
+ @json[:backtrace] = {:foo => 'bar'}
164
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
165
+ end
166
+
167
+ it "all items must be an object" do
168
+ @json[:backtrace][0] = "some string"
169
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
170
+ end
25
171
 
26
- exception = double 'exception',
27
- :class => double('class', :name => 'ExceptionType'),
28
- :message => 'The exception message.',
29
- :backtrace => ['/Users/x.rb:1', '/Users/x.rb:2', '/Users/x.rb:3']
172
+ context "file" do
173
+ it "is required" do
174
+ @json[:backtrace][0].delete :file
175
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
176
+ end
30
177
 
31
- Captivus::Payload.new(exception).as_json.tap do |hash|
32
- expect(hash.keys).to match_array ['event', 'backtrace']
178
+ it "must be a string" do
179
+ @json[:backtrace][0][:file] = {:foo => 'bar'}
180
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
181
+ end
182
+ end
183
+
184
+ context "number" do
185
+ it "is required" do
186
+ @json[:backtrace][0].delete :number
187
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
188
+ end
33
189
 
34
- hash['event'].tap do |event|
35
- expect(event.keys).to match_array ['type', 'message', 'timestamp']
190
+ it "must be an integer" do
191
+ @json[:backtrace][0][:number] = "10"
192
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
193
+ end
194
+ end
36
195
 
37
- expect(event['type']).to eq 'ExceptionType'
38
- expect(event['message']).to eq 'The exception message.'
39
- expect(event['timestamp']).to eq '2012-08-23 16:34:19 UTC'
196
+ context "method" do
197
+ it "must be a string" do
198
+ @json[:backtrace][0][:method] = {:foo => 'bar'}
199
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
40
200
  end
201
+ end
202
+ end
203
+
204
+ context "context" do
205
+ before { @json[:context] = {} }
206
+
207
+ it "is not required" do
208
+ @json.delete :context
209
+ expect { Captivus::Payload.new hash_to_json(@json) }.to_not raise_error
210
+ end
41
211
 
42
- hash['backtrace'].should == Captivus::Backtrace.new(exception).as_json
212
+ it "must be an object when present" do
213
+ expect { Captivus::Payload.new hash_to_json(@json) }.to_not raise_error
214
+
215
+ @json[:context] = 1
216
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
217
+ end
218
+
219
+ context "controller" do
220
+ it "must be a string when present" do
221
+ @json[:context][:controller] = 1
222
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
223
+
224
+ @json[:context][:controller] = 'widgets'
225
+ expect { Captivus::Payload.new hash_to_json(@json) }.to_not raise_error
226
+ end
227
+ end
228
+
229
+ context "action" do
230
+ it "must be a string when present" do
231
+ @json[:context][:action] = 1
232
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
233
+
234
+ @json[:context][:action] = 'show'
235
+ expect { Captivus::Payload.new hash_to_json(@json) }.to_not raise_error
236
+ end
237
+ end
238
+
239
+ context "params" do
240
+ it "must be an object when present" do
241
+ @json[:context][:params] = 1
242
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
243
+
244
+ @json[:context][:params] = {'a' => 'b'}
245
+ expect { Captivus::Payload.new hash_to_json(@json) }.to_not raise_error
246
+ end
43
247
  end
248
+ end
249
+
250
+ context "environment" do
251
+ it "is required" do
252
+ @json.delete :environment
253
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
254
+ end
255
+
256
+ it "must be an object" do
257
+ @json[:environment] = 'foo'
258
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
259
+ end
260
+
261
+ context "name" do
262
+ it "is required" do
263
+ @json[:environment].delete :name
264
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
265
+ end
266
+
267
+ it "must be an string" do
268
+ @json[:environment][:name] = 3495
269
+ expect { Captivus::Payload.new hash_to_json(@json) }.to raise_error(@exception)
270
+ end
271
+ end
272
+ end
273
+ end
274
+
275
+ describe "#as_json" do
276
+ it "is the JSON converted to a hash" do
277
+ hash = valid_hash
278
+ expect(Captivus::Payload.new(hash_to_json(hash)).as_json).to eq hash
279
+ end
280
+ end
281
+
282
+ describe "#to_json" do
283
+ before { @json = hash_to_json valid_hash }
284
+
285
+ it "is the given JSON" do
286
+ expect(Captivus::Payload.new(@json).to_json).to eq @json
287
+ end
288
+
289
+ it "never returns the same instance" do
290
+ payload = Captivus::Payload.new @json
291
+ expect(payload.to_json).to_not equal payload.to_json
292
+ end
293
+ end
294
+
295
+ describe "#==" do
296
+ before { @hash = valid_hash }
297
+
298
+ it "is true given another payload with the same JSON" do
299
+ json = hash_to_json(@hash)
300
+ expect(Captivus::Payload.new json).to eq Captivus::Payload.new(json)
301
+ end
302
+
303
+ it "is false given another payload with different JSON" do
304
+ other = Captivus::Payload.new hash_to_json(@hash.merge('environment' => {'name' => 'staging'}))
305
+ expect(Captivus::Payload.new hash_to_json(@hash)).to_not eq other
306
+ end
44
307
 
45
- Timecop.return
308
+ it "is false given a non payload" do
309
+ json = hash_to_json @hash
310
+ expect(Captivus::Payload.new json).to_not eq double('other', :json => json)
46
311
  end
47
312
  end
48
313
  end
@@ -8,33 +8,50 @@ describe Captivus::RackCapturer do
8
8
  @rack_capturer = Captivus::RackCapturer.new @app
9
9
  end
10
10
 
11
- it "is delegated to the given app, passing the env along" do
12
- env = double 'env'
11
+ def env_double(hash = {})
12
+ {'rack.input' => StringIO.new, 'QUERY_STRING' => ''}.merge(hash)
13
+ end
14
+
15
+ it "calls the app with the given env" do
16
+ env = env_double
13
17
  result = double 'result'
14
18
  @app.stub(:call).with(env) { result }
15
19
  expect(@rack_capturer.call(env)).to eq result
16
20
  end
17
21
 
18
22
  context "when calling the app raises an error" do
19
- before { @app.stub(:call) { raise StandardError, 'Error raised' } }
23
+ before { @app.stub(:call) { raise Exception, 'Error raised' } }
20
24
 
21
- it "raises the error" do
22
- expect { @rack_capturer.call double('env') }.to raise_error StandardError, "Error raised"
25
+ context "when the env contains a query string" do
26
+ it "tells Captivus to notify" do
27
+ Captivus.should_receive(:notify).with kind_of(Exception),
28
+ :context => {:params => {'username' => 'austin', 'password' => 'secret'}}
29
+ begin
30
+ @rack_capturer.call(env_double('QUERY_STRING' => 'username=austin&password=secret'))
31
+ rescue Exception
32
+ end
33
+ end
23
34
  end
24
35
 
25
- it "notifies the Captivus API" do
26
- Captivus.should_receive(:notify).with kind_of(StandardError)
27
- @rack_capturer.call double('env') rescue nil
36
+ context "when the env doesn't contain a query string" do
37
+ it "tells Captivus to notify" do
38
+ Captivus.should_receive(:notify).with kind_of(Exception), :context => {:params => {}}
39
+ begin
40
+ @rack_capturer.call(env_double)
41
+ rescue Exception
42
+ end
43
+ end
28
44
  end
29
- end
30
45
 
31
- context "when calling the app does not raise an error" do
32
- before { @app.stub :call }
33
-
34
- it "does not notify the Captivus API" do
35
- @rack_capturer.call double('env')
36
- expect(captivus_api.requests.size).to eq 0
46
+ it "raises the error" do
47
+ expect { @rack_capturer.call(env_double) }.to raise_error Exception, "Error raised"
37
48
  end
38
49
  end
50
+
51
+ it "does not notify the Captivus API when calling the app does not raise an error" do
52
+ @app.stub :call
53
+ @rack_capturer.call env_double
54
+ expect(captivus_api.requests.size).to eq 0
55
+ end
39
56
  end
40
57
  end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+ require 'captivus/rails_capturer'
3
+
4
+ describe Captivus::RailsCapturer do
5
+ describe "call" do
6
+ before do
7
+ @app = double 'app'
8
+ @rails_capturer = Captivus::RailsCapturer.new @app
9
+ end
10
+
11
+ it "calls the app with the given env" do
12
+ env = double 'env'
13
+ result = double 'result'
14
+ @app.stub(:call).with(env) { result }
15
+ expect(@rails_capturer.call(env)).to eq result
16
+ end
17
+
18
+ context "when calling the app raises an error" do
19
+ before do
20
+ @app.stub(:call) { raise Exception, 'Error raised' }
21
+ @env = {'action_controller.instance' => double('controller',
22
+ :controller_name => 'widgets',
23
+ :action_name => 'show',
24
+ :request => double('request', :filtered_parameters => {
25
+ 'controller' => 'widgets',
26
+ 'action' => 'show',
27
+ 'p1' => 'v1',
28
+ 'p2' => 'v2'
29
+ })
30
+ )}
31
+ end
32
+
33
+ it "tells Captivus to notify of the exception" do
34
+ Captivus.should_receive(:notify).with kind_of(Exception), 'context' => {
35
+ 'controller' => 'widgets',
36
+ 'action' => 'show',
37
+ 'params' => {'p1' => 'v1', 'p2' => 'v2'}
38
+ }
39
+ begin
40
+ @rails_capturer.call @env
41
+ rescue Exception
42
+ end
43
+ end
44
+
45
+ it "raises the error" do
46
+ expect { @rails_capturer.call @env }.to raise_error Exception, "Error raised"
47
+ end
48
+ end
49
+
50
+ context "when calling the app does not raise an error" do
51
+ before { @app.stub :call }
52
+
53
+ it "does not notify the Captivus API" do
54
+ @rails_capturer.call double('env')
55
+ expect(captivus_api.requests.size).to eq 0
56
+ end
57
+ end
58
+ end
59
+ end
@@ -21,43 +21,64 @@ describe Captivus do
21
21
  end
22
22
  end
23
23
 
24
+ describe ".notifier" do
25
+ it "is a notifier" do
26
+ expect(Captivus.notifier).to eq Captivus::Notifier.new(Captivus.config)
27
+ end
28
+
29
+ it "always returns the same notifier" do
30
+ expect(Captivus.notifier).to equal Captivus.notifier
31
+ end
32
+ end
33
+
24
34
  describe ".notify" do
25
- it "sends a notice to the Captivus API" do
26
- Timecop.freeze Time.utc(2012, 11, 28, 2, 46, 4)
35
+ before { Timecop.freeze Time.utc(2012, 8, 23, 16, 34, 19) }
36
+ after { Timecop.return }
27
37
 
28
- exception = StandardError.new('Error raised')
38
+ it "tells the notifier to notify" do
39
+ Captivus.config.environment = 'the-environment'
29
40
 
30
- Captivus.configure do |config|
31
- config.api_key = 'api-key'
32
- config.api_secret_key = 'secret'
33
- end
41
+ exception = double 'exception',
42
+ :class => double('class', :name => 'ExceptionType'),
43
+ :message => 'The exception message.',
44
+ :backtrace => ['/Users/x.rb:1', '/Users/x.rb:2', '/Users/x.rb:3']
34
45
 
35
- Captivus.notify exception
36
-
37
- expect(captivus_api.requests.size).to eq 1
38
-
39
- headers = {
40
- "CONTENT_TYPE"=>"application/json; charset=UTF-8",
41
- "HTTP_ACCEPT" => "*/*",
42
- "HTTP_USER_AGENT" => "Ruby",
43
- "HTTP_DATE" => "Wed, 28 Nov 2012 02:46:04 GMT",
44
- "HTTP_AUTHORIZATION" => "Captivus api-key:IgBW675pSKkCuD4McYnX9QQMI5g=",
45
- "PATH_INFO" => "/events",
46
- "QUERY_STRING" => "",
47
- "REQUEST_METHOD"=>"POST",
48
- "SCRIPT_NAME" => "",
49
- "SERVER_NAME" => "api.captiv.us",
50
- "SERVER_PORT" => "80",
51
- "rack.url_scheme" => "http"
46
+ hash = {
47
+ 'notifier' => {
48
+ 'name' => 'captivus',
49
+ 'version' => Captivus::VERSION,
50
+ 'language' => 'Ruby'
51
+ },
52
+ 'event' => {
53
+ 'type' => 'ExceptionType',
54
+ 'message' => 'The exception message.',
55
+ 'timestamp' => '2012-08-23T16:34:19Z'
56
+ },
57
+ 'backtrace' => Captivus::Backtrace.new(exception).as_json,
58
+ 'environment' => {'name' => 'the-environment'}
52
59
  }
53
60
 
54
- last_request = captivus_api.requests[0]
55
-
56
- expect(last_request.values_at(*headers.keys)).to eq headers.values
61
+ Captivus.notifier.should_receive(:notify).with(Captivus::Payload.new(hash_to_json(hash)))
62
+ Captivus.notify exception, {}
57
63
 
58
- expect(last_request['rack.input'].read).to eq MultiJson.dump(Captivus::Payload.new(exception).as_json)
64
+ hash.merge!('extra' => 'data', 'goes' => 'here')
65
+ Captivus.notifier.should_receive(:notify).with(Captivus::Payload.new(hash_to_json(hash)))
66
+ Captivus.notify exception, {'extra' => 'data', 'goes' => 'here'}
67
+ end
59
68
 
60
- Timecop.return
69
+ context "when the exception doesn't behave like an one" do
70
+ it "raises an argument error" do
71
+ [
72
+ double('exception'),
73
+ double('exception', :class => double('class')),
74
+ double('exception', :class => double('class', :name => 'X')),
75
+ double('exception', :class => double('class'), :message => 'x')
76
+ ].each do |exception|
77
+ expect {
78
+ Captivus.notify exception
79
+ }.to raise_error(ArgumentError, "Unexpected exception: #{exception.inspect}")
80
+ end
81
+ end
61
82
  end
62
83
  end
63
84
  end