captivus 0.0.3 → 0.0.5

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 (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