romanbsd-tarantula 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. data/CHANGELOG +47 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +162 -0
  4. data/Rakefile +69 -0
  5. data/VERSION.yml +4 -0
  6. data/examples/example_helper.rb +48 -0
  7. data/examples/relevance/core_extensions/ellipsize_example.rb +19 -0
  8. data/examples/relevance/core_extensions/file_example.rb +8 -0
  9. data/examples/relevance/core_extensions/response_example.rb +29 -0
  10. data/examples/relevance/core_extensions/test_case_example.rb +20 -0
  11. data/examples/relevance/tarantula/attack_form_submission_example.rb +79 -0
  12. data/examples/relevance/tarantula/attack_handler_example.rb +29 -0
  13. data/examples/relevance/tarantula/crawler_example.rb +386 -0
  14. data/examples/relevance/tarantula/form_example.rb +50 -0
  15. data/examples/relevance/tarantula/form_submission_example.rb +71 -0
  16. data/examples/relevance/tarantula/html_document_handler_example.rb +43 -0
  17. data/examples/relevance/tarantula/html_report_helper_example.rb +46 -0
  18. data/examples/relevance/tarantula/html_reporter_example.rb +82 -0
  19. data/examples/relevance/tarantula/invalid_html_handler_example.rb +33 -0
  20. data/examples/relevance/tarantula/io_reporter_example.rb +11 -0
  21. data/examples/relevance/tarantula/link_example.rb +67 -0
  22. data/examples/relevance/tarantula/log_grabber_example.rb +26 -0
  23. data/examples/relevance/tarantula/rails_integration_proxy_example.rb +88 -0
  24. data/examples/relevance/tarantula/result_example.rb +85 -0
  25. data/examples/relevance/tarantula/tidy_handler_example.rb +58 -0
  26. data/examples/relevance/tarantula/transform_example.rb +20 -0
  27. data/examples/relevance/tarantula/w3c_validator_example.rb +71 -0
  28. data/examples/relevance/tarantula_example.rb +23 -0
  29. data/laf/images/button_active.png +0 -0
  30. data/laf/images/button_hover.png +0 -0
  31. data/laf/images/button_inactive.png +0 -0
  32. data/laf/images/header_bg.jpg +0 -0
  33. data/laf/images/logo.png +0 -0
  34. data/laf/images/tagline.png +0 -0
  35. data/laf/javascripts/jquery-1.2.3.js +3408 -0
  36. data/laf/javascripts/jquery-ui-tabs.js +890 -0
  37. data/laf/javascripts/jquery.tablesorter.js +861 -0
  38. data/laf/javascripts/niftyLayout.js +11 -0
  39. data/laf/javascripts/niftycube-details.js +298 -0
  40. data/laf/javascripts/niftycube.js +298 -0
  41. data/laf/javascripts/tarantula.js +10 -0
  42. data/laf/stylesheets/tarantula.css +345 -0
  43. data/laf/v2/detail.html +59 -0
  44. data/laf/v2/images/button_active.png +0 -0
  45. data/laf/v2/images/button_hover.png +0 -0
  46. data/laf/v2/images/button_inactive.png +0 -0
  47. data/laf/v2/images/header_bg.jpg +0 -0
  48. data/laf/v2/images/logo.png +0 -0
  49. data/laf/v2/images/tagline.png +0 -0
  50. data/laf/v2/index.html +77 -0
  51. data/laf/v2/stylesheets/tarantula.v2.css +324 -0
  52. data/lib/relevance/core_extensions/ellipsize.rb +34 -0
  53. data/lib/relevance/core_extensions/file.rb +9 -0
  54. data/lib/relevance/core_extensions/metaclass.rb +78 -0
  55. data/lib/relevance/core_extensions/response.rb +9 -0
  56. data/lib/relevance/core_extensions/string_chars_fix.rb +11 -0
  57. data/lib/relevance/core_extensions/test_case.rb +19 -0
  58. data/lib/relevance/tarantula/attack.rb +15 -0
  59. data/lib/relevance/tarantula/attack_form_submission.rb +75 -0
  60. data/lib/relevance/tarantula/attack_handler.rb +37 -0
  61. data/lib/relevance/tarantula/crawler.rb +264 -0
  62. data/lib/relevance/tarantula/detail.html.erb +82 -0
  63. data/lib/relevance/tarantula/form.rb +21 -0
  64. data/lib/relevance/tarantula/form_submission.rb +70 -0
  65. data/lib/relevance/tarantula/html_document_handler.rb +36 -0
  66. data/lib/relevance/tarantula/html_report_helper.rb +39 -0
  67. data/lib/relevance/tarantula/html_reporter.rb +105 -0
  68. data/lib/relevance/tarantula/index.html.erb +37 -0
  69. data/lib/relevance/tarantula/invalid_html_handler.rb +18 -0
  70. data/lib/relevance/tarantula/io_reporter.rb +34 -0
  71. data/lib/relevance/tarantula/link.rb +56 -0
  72. data/lib/relevance/tarantula/log_grabber.rb +16 -0
  73. data/lib/relevance/tarantula/rails_integration_proxy.rb +68 -0
  74. data/lib/relevance/tarantula/recording.rb +12 -0
  75. data/lib/relevance/tarantula/response.rb +13 -0
  76. data/lib/relevance/tarantula/result.rb +66 -0
  77. data/lib/relevance/tarantula/test_report.html.erb +32 -0
  78. data/lib/relevance/tarantula/tidy_handler.rb +32 -0
  79. data/lib/relevance/tarantula/transform.rb +17 -0
  80. data/lib/relevance/tarantula/w3c_validator.rb +33 -0
  81. data/lib/relevance/tarantula.rb +59 -0
  82. data/tasks/tarantula_tasks.rake +36 -0
  83. data/template/tarantula_test.rb +22 -0
  84. data/vendor/w3c_validators/CHANGELOG +14 -0
  85. data/vendor/w3c_validators/LICENSE +60 -0
  86. data/vendor/w3c_validators/README +120 -0
  87. data/vendor/w3c_validators/README.svn +4 -0
  88. data/vendor/w3c_validators/lib/w3c_validators/constants.rb +80 -0
  89. data/vendor/w3c_validators/lib/w3c_validators/css_validator.rb +149 -0
  90. data/vendor/w3c_validators/lib/w3c_validators/exceptions.rb +4 -0
  91. data/vendor/w3c_validators/lib/w3c_validators/feed_validator.rb +110 -0
  92. data/vendor/w3c_validators/lib/w3c_validators/markup_validator.rb +227 -0
  93. data/vendor/w3c_validators/lib/w3c_validators/message.rb +82 -0
  94. data/vendor/w3c_validators/lib/w3c_validators/results.rb +62 -0
  95. data/vendor/w3c_validators/lib/w3c_validators/validator.rb +157 -0
  96. data/vendor/w3c_validators/lib/w3c_validators.rb +5 -0
  97. data/vendor/w3c_validators/rakefile.rb +53 -0
  98. data/vendor/w3c_validators/test/fixtures/invalid_css.css +2 -0
  99. data/vendor/w3c_validators/test/fixtures/invalid_encoding.html +10 -0
  100. data/vendor/w3c_validators/test/fixtures/invalid_feed.xml +19 -0
  101. data/vendor/w3c_validators/test/fixtures/invalid_html5.html +16 -0
  102. data/vendor/w3c_validators/test/fixtures/invalid_markup.html +11 -0
  103. data/vendor/w3c_validators/test/fixtures/valid_css.css +2 -0
  104. data/vendor/w3c_validators/test/fixtures/valid_feed.xml +20 -0
  105. data/vendor/w3c_validators/test/fixtures/valid_html5.html +16 -0
  106. data/vendor/w3c_validators/test/fixtures/valid_markup.html +11 -0
  107. data/vendor/w3c_validators/test/test_css_validator.rb +51 -0
  108. data/vendor/w3c_validators/test/test_exceptions.rb +35 -0
  109. data/vendor/w3c_validators/test/test_feed_validator.rb +61 -0
  110. data/vendor/w3c_validators/test/test_helper.rb +6 -0
  111. data/vendor/w3c_validators/test/test_html5_validator.rb +64 -0
  112. data/vendor/w3c_validators/test/test_markup_validator.rb +94 -0
  113. data/vendor/xss-shield/MIT-LICENSE +20 -0
  114. data/vendor/xss-shield/README +76 -0
  115. data/vendor/xss-shield/init.rb +16 -0
  116. data/vendor/xss-shield/lib/xss_shield/erb_hacks.rb +111 -0
  117. data/vendor/xss-shield/lib/xss_shield/haml_hacks.rb +42 -0
  118. data/vendor/xss-shield/lib/xss_shield/safe_string.rb +47 -0
  119. data/vendor/xss-shield/lib/xss_shield/secure_helpers.rb +40 -0
  120. data/vendor/xss-shield/lib/xss_shield.rb +6 -0
  121. data/vendor/xss-shield/test/test_actionview_integration.rb +40 -0
  122. data/vendor/xss-shield/test/test_erb.rb +44 -0
  123. data/vendor/xss-shield/test/test_haml.rb +43 -0
  124. data/vendor/xss-shield/test/test_helpers.rb +25 -0
  125. data/vendor/xss-shield/test/test_safe_string.rb +55 -0
  126. metadata +218 -0
@@ -0,0 +1,386 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb"))
2
+
3
+ describe Relevance::Tarantula::Crawler do
4
+
5
+ describe "transform_url" do
6
+
7
+ before { @crawler = Relevance::Tarantula::Crawler.new }
8
+
9
+ it "de-obfuscates unicode obfuscated urls" do
10
+ obfuscated_mailto = "mailto:"
11
+ @crawler.transform_url(obfuscated_mailto).should == "mailto:"
12
+ end
13
+
14
+ it "strips the trailing name portion of a link" do
15
+ @crawler.transform_url('http://host/path#name').should == 'http://host/path'
16
+ end
17
+ end
18
+
19
+
20
+ describe "log grabbing" do
21
+
22
+ it "returns nil if no grabber is specified" do
23
+ crawler = Relevance::Tarantula::Crawler.new
24
+ crawler.grab_log!.should == nil
25
+ end
26
+
27
+ it "returns grabber.grab if grabber is specified" do
28
+ crawler = Relevance::Tarantula::Crawler.new
29
+ crawler.log_grabber = stub(:grab! => "fake log entry")
30
+ crawler.grab_log!.should == "fake log entry"
31
+ end
32
+
33
+ end
34
+
35
+ describe "interrupt" do
36
+
37
+ it 'catches interruption and writes the partial report' do
38
+ crawler = Relevance::Tarantula::Crawler.new
39
+ crawler.stubs(:queue_link)
40
+ crawler.stubs(:do_crawl).raises(Interrupt)
41
+ crawler.expects(:report_results)
42
+ $stderr.expects(:puts).with("CTRL-C")
43
+ crawler.crawl
44
+ end
45
+
46
+ end
47
+
48
+ describe 'handle_form_results' do
49
+
50
+ it 'captures the result values (bugfix)' do
51
+ response = stub_everything
52
+ result_args = {:url => :action_stub,
53
+ :data => 'nil',
54
+ :response => response,
55
+ :referrer => :action_stub,
56
+ :log => nil,
57
+ :method => :stub_method,
58
+ :test_name => nil}
59
+ result = Relevance::Tarantula::Result.new(result_args)
60
+ Relevance::Tarantula::Result.expects(:new).with(result_args).returns(result)
61
+ crawler = Relevance::Tarantula::Crawler.new
62
+ crawler.handle_form_results(stub_everything(:method => :stub_method, :action => :action_stub),
63
+ response)
64
+ end
65
+
66
+ end
67
+
68
+ describe "crawl" do
69
+
70
+ it 'queues the first url, does crawl, and then reports results' do
71
+ crawler = Relevance::Tarantula::Crawler.new
72
+ crawler.expects(:queue_link).with("/foobar")
73
+ crawler.expects(:do_crawl)
74
+ crawler.expects(:report_results)
75
+ crawler.crawl("/foobar")
76
+ end
77
+
78
+ it 'reports results even if the crawl fails' do
79
+ crawler = Relevance::Tarantula::Crawler.new
80
+ crawler.expects(:do_crawl).raises(RuntimeError)
81
+ crawler.expects(:report_results)
82
+ lambda {crawler.crawl('/')}.should raise_error(RuntimeError)
83
+ end
84
+
85
+ end
86
+
87
+ describe "queueing" do
88
+
89
+ it 'queues and remembers links' do
90
+ crawler = Relevance::Tarantula::Crawler.new
91
+ crawler.expects(:transform_url).with("/url").returns("/transformed")
92
+ crawler.queue_link("/url")
93
+ crawler.links_to_crawl.should == [Relevance::Tarantula::Link.new("/transformed")]
94
+ crawler.links_queued.should == Set.new([Relevance::Tarantula::Link.new("/transformed")])
95
+ end
96
+
97
+ it 'queues and remembers forms' do
98
+ crawler = Relevance::Tarantula::Crawler.new
99
+ form = Hpricot('<form action="/action" method="post"/>').at('form')
100
+ signature = Relevance::Tarantula::FormSubmission.new(Relevance::Tarantula::Form.new(form)).signature
101
+ crawler.queue_form(form)
102
+ crawler.forms_to_crawl.size.should == 1
103
+ crawler.form_signatures_queued.should == Set.new([signature])
104
+ end
105
+
106
+ it 'remembers link referrer if there is one' do
107
+ crawler = Relevance::Tarantula::Crawler.new
108
+ crawler.queue_link("/url", "/some-referrer")
109
+ crawler.referrers.should == {Relevance::Tarantula::Link.new("/url") => "/some-referrer"}
110
+ end
111
+
112
+ end
113
+
114
+ describe "crawling" do
115
+
116
+ it "converts ActiveRecord::RecordNotFound into a 404" do
117
+ (proxy = stub_everything).expects(:send).raises(ActiveRecord::RecordNotFound)
118
+ crawler = Relevance::Tarantula::Crawler.new
119
+ crawler.proxy = proxy
120
+ response = crawler.crawl_form stub_everything(:method => nil)
121
+ response.code.should == "404"
122
+ response.content_type.should == "text/plain"
123
+ response.body.should == "ActiveRecord::RecordNotFound"
124
+ end
125
+
126
+ it "does four things with each link: get, log, handle, and blip" do
127
+ crawler = Relevance::Tarantula::Crawler.new
128
+ crawler.proxy = stub
129
+ response = stub(:code => "200")
130
+ crawler.links_to_crawl = [stub(:href => "/foo1", :method => :get), stub(:href => "/foo2", :method => :get)]
131
+ crawler.proxy.expects(:get).returns(response).times(2)
132
+ crawler.expects(:log).times(2)
133
+ crawler.expects(:handle_link_results).times(2)
134
+ crawler.expects(:blip).times(2)
135
+ crawler.crawl_queued_links
136
+ crawler.links_to_crawl.should == []
137
+ end
138
+
139
+ it "invokes queued forms, logs responses, and calls handlers" do
140
+ crawler = Relevance::Tarantula::Crawler.new
141
+ crawler.forms_to_crawl << stub_everything(:method => "get",
142
+ :action => "/foo",
143
+ :data => "some data",
144
+ :to_s => "stub")
145
+ crawler.proxy = stub_everything(:send => stub(:code => "200" ))
146
+ crawler.expects(:log).with("Response 200 for stub")
147
+ crawler.expects(:blip)
148
+ crawler.crawl_queued_forms
149
+ end
150
+
151
+ it "breaks out early if a timeout is set" do
152
+ crawler = Relevance::Tarantula::Crawler.new
153
+ stub_puts_and_print(crawler)
154
+ crawler.proxy = stub
155
+ response = stub(:code => "200")
156
+ crawler.links_to_crawl = [stub(:href => "/foo", :method => :get)]
157
+ crawler.proxy.expects(:get).returns(response).times(4)
158
+ crawler.forms_to_crawl << stub_everything(:method => "post",
159
+ :action => "/foo",
160
+ :data => "some data",
161
+ :to_s => "stub")
162
+ crawler.proxy.expects(:post).returns(response).times(2)
163
+ crawler.expects(:links_completed_count).returns(0,1,2,3,4,5).times(6)
164
+ crawler.times_to_crawl = 2
165
+ crawler.crawl
166
+
167
+ end
168
+
169
+ it "resets to the initial links/forms on subsequent crawls when times_to_crawl > 1" do
170
+ crawler = Relevance::Tarantula::Crawler.new
171
+ stub_puts_and_print(crawler)
172
+ crawler.proxy = stub
173
+ response = stub(:code => "200")
174
+ crawler.links_to_crawl = [stub(:href => "/foo", :method => :get)]
175
+ crawler.proxy.expects(:get).returns(response).times(4) # (stub and "/") * 2
176
+ crawler.forms_to_crawl << stub_everything(:method => "post",
177
+ :action => "/foo",
178
+ :data => "some data",
179
+ :to_s => "stub")
180
+ crawler.proxy.expects(:post).returns(response).times(2)
181
+ crawler.expects(:links_completed_count).returns(0,1,2,3,4,5).times(6)
182
+ crawler.times_to_crawl = 2
183
+ crawler.crawl
184
+ end
185
+
186
+ end
187
+
188
+ describe "report_results" do
189
+
190
+ it "delegates to generate_reports" do
191
+ crawler = Relevance::Tarantula::Crawler.new
192
+ crawler.expects(:generate_reports)
193
+ crawler.report_results
194
+ end
195
+
196
+ end
197
+
198
+ describe "blip" do
199
+
200
+ it "blips the current progress if !verbose" do
201
+ crawler = Relevance::Tarantula::Crawler.new
202
+ crawler.stubs(:verbose).returns false
203
+ crawler.stubs(:timeout_if_too_long)
204
+ crawler.expects(:print).with("\r 0 of 0 links completed ")
205
+ crawler.blip
206
+ end
207
+
208
+ it "blips nothing if verbose" do
209
+ crawler = Relevance::Tarantula::Crawler.new
210
+ crawler.stubs(:verbose).returns true
211
+ crawler.expects(:print).never
212
+ crawler.blip
213
+ end
214
+
215
+ end
216
+
217
+ describe "finished?" do
218
+
219
+ it "is finished when the links and forms are crawled" do
220
+ crawler = Relevance::Tarantula::Crawler.new
221
+ crawler.finished?.should == true
222
+ end
223
+
224
+ it "isn't finished when links remain" do
225
+ crawler = Relevance::Tarantula::Crawler.new
226
+ crawler.links_to_crawl = [:stub_link]
227
+ crawler.finished?.should == false
228
+ end
229
+
230
+ it "isn't finished when links remain" do
231
+ crawler = Relevance::Tarantula::Crawler.new
232
+ crawler.forms_to_crawl = [:stub_form]
233
+ crawler.finished?.should == false
234
+ end
235
+
236
+ end
237
+
238
+ it "crawls links and forms again and again until finished?==true" do
239
+ crawler = Relevance::Tarantula::Crawler.new
240
+ crawler.expects(:finished?).times(3).returns(false, false, true)
241
+ crawler.expects(:crawl_queued_links).times(2)
242
+ crawler.expects(:crawl_queued_forms).times(2)
243
+ crawler.do_crawl(1)
244
+ end
245
+
246
+ it "asks each reporter to write its report in report_dir" do
247
+ crawler = Relevance::Tarantula::Crawler.new
248
+ crawler.stubs(:report_dir).returns(test_output_dir)
249
+ reporter = stub_everything
250
+ reporter.expects(:report)
251
+ reporter.expects(:finish_report)
252
+ crawler.reporters = [reporter]
253
+ crawler.save_result stub(:code => "404", :url => "/uh-oh")
254
+ crawler.generate_reports
255
+ end
256
+
257
+ it "builds a report dir relative to rails root" do
258
+ crawler = Relevance::Tarantula::Crawler.new
259
+ crawler.expects(:rails_root).returns("faux_rails_root")
260
+ crawler.report_dir.should == "faux_rails_root/tmp/tarantula"
261
+ end
262
+
263
+ it "skips links that are already queued" do
264
+ crawler = Relevance::Tarantula::Crawler.new
265
+ crawler.should_skip_link?(Relevance::Tarantula::Link.new("/foo")).should == false
266
+ crawler.queue_link("/foo").should == Relevance::Tarantula::Link.new("/foo")
267
+ crawler.should_skip_link?(Relevance::Tarantula::Link.new("/foo")).should == true
268
+ end
269
+
270
+ describe "link skipping" do
271
+
272
+ before { @crawler = Relevance::Tarantula::Crawler.new }
273
+
274
+ it "skips links that are too long" do
275
+ @crawler.should_skip_link?(Relevance::Tarantula::Link.new("/foo")).should == false
276
+ @crawler.max_url_length = 2
277
+ @crawler.expects(:log).with("Skipping long url /foo")
278
+ @crawler.should_skip_link?(Relevance::Tarantula::Link.new("/foo")).should == true
279
+ end
280
+
281
+ it "skips outbound links (those that begin with http)" do
282
+ @crawler.expects(:log).with("Skipping http-anything")
283
+ @crawler.should_skip_link?(Relevance::Tarantula::Link.new("http-anything")).should == true
284
+ end
285
+
286
+ it "skips javascript links (those that begin with javascript)" do
287
+ @crawler.expects(:log).with("Skipping javascript-anything")
288
+ @crawler.should_skip_link?(Relevance::Tarantula::Link.new("javascript-anything")).should == true
289
+ end
290
+
291
+ it "skips mailto links (those that begin with http)" do
292
+ @crawler.expects(:log).with("Skipping mailto-anything")
293
+ @crawler.should_skip_link?(Relevance::Tarantula::Link.new("mailto-anything")).should == true
294
+ end
295
+
296
+ it 'skips blank links' do
297
+ @crawler.queue_link(nil)
298
+ @crawler.links_to_crawl.should == []
299
+ @crawler.queue_link("")
300
+ @crawler.links_to_crawl.should == []
301
+ end
302
+
303
+ it "logs and skips links that match a pattern" do
304
+ @crawler.expects(:log).with("Skipping /the-red-button")
305
+ @crawler.skip_uri_patterns << /red-button/
306
+ @crawler.queue_link("/blue-button").should == Relevance::Tarantula::Link.new("/blue-button")
307
+ @crawler.queue_link("/the-red-button").should == nil
308
+ end
309
+
310
+ it "logs and skips form submissions that match a pattern" do
311
+ @crawler.expects(:log).with("Skipping /reset-password-form")
312
+ @crawler.skip_uri_patterns << /reset-password/
313
+ fs = stub_everything(:action => "/reset-password-form")
314
+ @crawler.should_skip_form_submission?(fs).should == true
315
+ end
316
+ end
317
+
318
+ describe "allow_nnn_for" do
319
+
320
+ it "installs result as a response_code_handler" do
321
+ crawler = Relevance::Tarantula::Crawler.new
322
+ crawler.response_code_handler.should == Relevance::Tarantula::Result
323
+ end
324
+
325
+ it "delegates to the response_code_handler" do
326
+ crawler = Relevance::Tarantula::Crawler.new
327
+ (response_code_handler = mock).expects(:allow_404_for).with(:stub)
328
+ crawler.response_code_handler = response_code_handler
329
+ crawler.allow_404_for(:stub)
330
+ end
331
+
332
+ it "chains up to super for method_missing" do
333
+ crawler = Relevance::Tarantula::Crawler.new
334
+ lambda{crawler.foo}.should raise_error(NoMethodError)
335
+ end
336
+
337
+ end
338
+
339
+ describe "timeouts" do
340
+
341
+ it "sets start and end times for a single crawl" do
342
+ start_time = Time.parse("March 1st, 2008 10:00am")
343
+ end_time = Time.parse("March 1st, 2008 10:10am")
344
+ Time.stubs(:now).returns(start_time, end_time)
345
+
346
+ crawler = Relevance::Tarantula::Crawler.new
347
+ stub_puts_and_print(crawler)
348
+ crawler.proxy = stub_everything(:get => response = stub(:code => "200"))
349
+ crawler.crawl
350
+ crawler.crawl_start_times.first.should == start_time
351
+ crawler.crawl_end_times.first.should == end_time
352
+ end
353
+
354
+ it "has elasped time for a crawl" do
355
+ start_time = Time.parse("March 1st, 2008 10:00am")
356
+ elasped_time_check = Time.parse("March 1st, 2008, 10:10:00am")
357
+ Time.stubs(:now).returns(start_time, elasped_time_check)
358
+
359
+ crawler = Relevance::Tarantula::Crawler.new
360
+ stub_puts_and_print(crawler)
361
+ crawler.proxy = stub_everything(:get => response = stub(:code => "200"))
362
+ crawler.crawl
363
+ crawler.elasped_time_for_pass(0).should == 600.seconds
364
+ end
365
+
366
+ it "raises out of the crawl if elasped time is greater then the crawl timeout" do
367
+ start_time = Time.parse("March 1st, 2008 10:00am")
368
+ elasped_time_check = Time.parse("March 1st, 2008, 10:35:00am")
369
+ Time.stubs(:now).returns(start_time, elasped_time_check)
370
+
371
+ crawler = Relevance::Tarantula::Crawler.new
372
+ crawler.crawl_timeout = 5.minutes
373
+
374
+ crawler.links_to_crawl = [stub(:href => "/foo1", :method => :get), stub(:href => "/foo2", :method => :get)]
375
+ crawler.proxy = stub
376
+ crawler.proxy.stubs(:get).returns(response = stub(:code => "200"))
377
+
378
+ stub_puts_and_print(crawler)
379
+ lambda {
380
+ crawler.do_crawl(0)
381
+ }.should raise_error
382
+ end
383
+
384
+ end
385
+
386
+ end
@@ -0,0 +1,50 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb"))
2
+
3
+ describe "Relevance::Tarantula::Form large example" do
4
+ before do
5
+ @tag = Hpricot(<<END)
6
+ <form action="/session" method="post">
7
+ <input name="authenticity_token" type="hidden" value="1be0d07c6e13669a87b8f52a3c7e1d1ffa77708d" />
8
+ <input id="email" name="email" size="30" type="text" />
9
+ <input id="password" name="password" size="30" type="password" />
10
+ <input id="remember_me" name="remember_me" type="checkbox" value="1" />
11
+ <input name="commit" type="submit" value="Log in" />
12
+ </form>
13
+ END
14
+ @form = Relevance::Tarantula::Form.new(@tag.at('form'))
15
+ end
16
+
17
+ it "has an action" do
18
+ @form.action.should == "/session"
19
+ end
20
+
21
+ it "has a method" do
22
+ @form.method.should == "post"
23
+ end
24
+
25
+ end
26
+
27
+ describe "A Relevance::Tarantula::Form" do
28
+ it "defaults method to 'get'" do
29
+ @tag = Hpricot("<form/>")
30
+ @form = Relevance::Tarantula::Form.new(@tag.at('form'))
31
+ @form.method.should == 'get'
32
+ end
33
+ end
34
+
35
+ describe "A Relevance::Tarantula::Form with a hacked _method" do
36
+ before do
37
+ @tag = Hpricot(<<END)
38
+ <form action="/foo">
39
+ <input name="authenticity_token" type="hidden" value="1be0d07c6e13669a87b8f52a3c7e1d1ffa77708d" />
40
+ <input id="_method" name="_method" size="30" type="text" value="PUT"/>
41
+ </form>
42
+ END
43
+ @form = Relevance::Tarantula::Form.new(@tag.at('form'))
44
+ end
45
+
46
+ it "has a method" do
47
+ @form.method.should == "put"
48
+ end
49
+
50
+ end
@@ -0,0 +1,71 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb"))
2
+
3
+ describe "Relevance::Tarantula::FormSubmission" do
4
+
5
+ # TODO: add more from field types to this example form as needed
6
+ before do
7
+ @tag = Hpricot(<<END)
8
+ <form action="/session" method="post">
9
+ <input id="email" name="email" size="30" type="text" />
10
+ <textarea id="comment" name="comment"value="1" />
11
+ <input name="commit" type="submit" value="Postit" />
12
+ <input name="secret" type="hidden" value="secret" />
13
+ <select id="foo_opened_on_1i" name="foo[opened_on(1i)]">
14
+ <option value="2003">2003</option>
15
+ <option value="2004">2004</option>
16
+ </select>
17
+ </form>
18
+ END
19
+ @form = Relevance::Tarantula::Form.new(@tag.at('form'))
20
+ @fs = Relevance::Tarantula::FormSubmission.new(@form)
21
+ end
22
+
23
+ it "can mutate text areas" do
24
+ @fs.stubs(:random_int).returns("42")
25
+ @fs.mutate_text_areas(@form).should == {"comment" => "42"}
26
+ end
27
+
28
+ it "can mutate selects" do
29
+ Hpricot::Elements.any_instance.stubs(:rand).returns(stub(:[] => "2006-stub"))
30
+ @fs.mutate_selects(@form).should == {"foo[opened_on(1i)]" => "2006-stub"}
31
+ end
32
+
33
+ it "can mutate inputs" do
34
+ @fs.stubs(:random_int).returns("43")
35
+ @fs.mutate_inputs(@form).should == {"commit"=>"43", "secret"=>"43", "email"=>"43"}
36
+ end
37
+
38
+ it "has a signature based on action and fields" do
39
+ @fs.signature.should == ['/session', [
40
+ "comment",
41
+ "commit",
42
+ "email",
43
+ "foo[opened_on(1i)]",
44
+ "secret"]]
45
+ end
46
+
47
+ it "has a friendly to_s" do
48
+ @fs.to_s.should =~ %r{^/session post}
49
+ end
50
+
51
+ it "can generate a random whole number" do
52
+ @fs.random_whole_number.should >= 0
53
+ Fixnum.should === @fs.random_whole_number
54
+ end
55
+ end
56
+
57
+ describe "Relevance::Tarantula::FormSubmission for a crummy form" do
58
+ before do
59
+ @tag = Hpricot(<<END)
60
+ <form action="/session" method="post">
61
+ <input value="no_name" />
62
+ </form>
63
+ END
64
+ @form = Relevance::Tarantula::Form.new(@tag.at('form'))
65
+ @fs = Relevance::Tarantula::FormSubmission.new(@form)
66
+ end
67
+
68
+ it "ignores unnamed inputs" do
69
+ @fs.mutate_inputs(@form).should == {}
70
+ end
71
+ end
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb"))
2
+
3
+ describe "Relevance::Tarantula::HtmlDocumentHandler" do
4
+
5
+ before do
6
+ @handler = Relevance::Tarantula::HtmlDocumentHandler.new(nil)
7
+ end
8
+
9
+ it "does not write HTML Scanner warnings to the console" do
10
+ bad_html = "<html><div></form></html>"
11
+ err = Recording.stderr do
12
+ @handler.handle(Relevance::Tarantula::Result.new(:response => stub(:html? => true, :body => bad_html)))
13
+ end
14
+ err.should == ""
15
+ end
16
+
17
+ it "ignores non-html" do
18
+ @handler.expects(:queue_link).never
19
+ @handler.handle(Relevance::Tarantula::Result.new(:response => stub(:html? => false, :body => '<a href="/foo">foo</a>')))
20
+ end
21
+
22
+ it "queues anchor tags" do
23
+ @handler.expects(:queue_link).with {|*args| args[0]['href'] == "/foo" && args[1] == nil}
24
+ @handler.handle(Relevance::Tarantula::Result.new(:response => stub(:html? => true, :body => '<a href="/foo">foo</a>')))
25
+ end
26
+
27
+ it "queues link tags" do
28
+ @handler.expects(:queue_link).with {|*args| args[0]['href'] == "/bar" && args[1] == nil}
29
+ @handler.handle(Relevance::Tarantula::Result.new(:response => stub(:html? => true, :body => '<link href="/bar">bar</a>')))
30
+ end
31
+
32
+ it "queues forms" do
33
+ @handler.expects(:queue_form).with{|tag,referrer| Hpricot::Elem === tag}
34
+ @handler.handle(Relevance::Tarantula::Result.new(:url => "/page-url", :response => stub(:html? => true, :body => '<form>stuff</form>')))
35
+ end
36
+
37
+ it "infers form action from page url if form is not explicit" do
38
+ @handler.expects(:queue_form).with{|tag,referrer| tag['action'].should == '/page-url'; true }
39
+ @handler.handle(Relevance::Tarantula::Result.new(:url => "/page-url", :response => stub(:html? => true, :body => '<form>stuff</form>')))
40
+ end
41
+
42
+ end
43
+
@@ -0,0 +1,46 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb"))
2
+
3
+ module HtmlReportHelperSpec
4
+ # Is there an idiom for this?
5
+ def self.included(base)
6
+ base.before do
7
+ @reporter = Object.new
8
+ @reporter.extend Relevance::Tarantula::HtmlReportHelper
9
+ end
10
+ end
11
+ end
12
+
13
+ describe 'Relevance::Tarantula::HtmlReportHelper#wrap_in_line_number_table' do
14
+ include HtmlReportHelperSpec
15
+ it "can wrap text in a table row used for displaying lines and line numbers" do
16
+ html = @reporter.wrap_in_line_number_table_row("Line 1\nLine 2")
17
+ html.should == <<-END.strip
18
+ <tr><td class=\"numbers\"><span class=\"line number\">1</span><span class=\"line number\">2</span></td><td class=\"lines\"><span class=\"line\">Line 1</span><span class=\"line\">Line 2</span></td></tr>
19
+ END
20
+ end
21
+ end
22
+
23
+ describe 'Relevance::Tarantula::HtmlReportHelper#wrap_stack_trace_line' do
24
+ include HtmlReportHelperSpec
25
+ it "can wrap stack trace line in links" do
26
+ line = %{/action_controller/filters.rb:697:in `call_filters'}
27
+ @reporter.stubs(:textmate_url).returns("ide_url")
28
+ html = @reporter.wrap_stack_trace_line(line)
29
+ html.should == "<a href='ide_url'>/action_controller/filters.rb:697</a>:in `call_filters'"
30
+ end
31
+
32
+ it "converts html entities for non-stack trace lines" do
33
+ line = %{<a href="foo">escape me</a>}
34
+ html = @reporter.wrap_stack_trace_line(line)
35
+ html.should == %{&lt;a href=&quot;foo&quot;&gt;escape me&lt;/a&gt;}
36
+ end
37
+
38
+ end
39
+
40
+ describe 'Relevance::Tarantula::HtmlReportHelper IDE help' do
41
+ include HtmlReportHelperSpec
42
+ it "can create a textmate url" do
43
+ @reporter.stubs(:rails_root).returns("STUB_RAILS_ROOT")
44
+ @reporter.textmate_url("/etc/somewhere", 100).should =~ %r{txmt://open\?url=.*/STUB_RAILS_ROOT/etc/somewhere&line_no=100}
45
+ end
46
+ end
@@ -0,0 +1,82 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb"))
2
+
3
+ describe "Relevance::Tarantula::HtmlReporter file output" do
4
+
5
+ before do
6
+ FileUtils.rm_rf(test_output_dir)
7
+ FileUtils.mkdir_p(test_output_dir)
8
+ @test_name = "test_user_pages"
9
+ Relevance::Tarantula::Result.next_number = 0
10
+ @success_results = (1..10).map do |index|
11
+ Relevance::Tarantula::Result.new(
12
+ :success => true,
13
+ :method => "get",
14
+ :url => "/widgets/#{index}",
15
+ :response => stub(:code => "200", :body => "<h1>header</h1>\n<p>text</p>"),
16
+ :referrer => "/random/#{rand(100)}",
17
+ :test_name => @test_name,
18
+ :log => <<-END,
19
+ Made-up stack trace:
20
+ /some_module/some_class.rb:697:in `bad_method'
21
+ /some_module/other_class.rb:12345677:in `long_method'
22
+ this link should be <a href="#">escaped</a>
23
+ blah blah blah
24
+ END
25
+ :data => "{:param1 => :value, :param2 => :another_value}"
26
+ )
27
+ end
28
+ @fail_results = (1..10).map do |index|
29
+ Relevance::Tarantula::Result.new(
30
+ :success => false,
31
+ :method => "get",
32
+ :url => "/widgets/#{index}",
33
+ :response => stub(:code => "500", :body => "<h1>header</h1>\n<p>text</p>"),
34
+ :referrer => "/random/#{rand(100)}",
35
+ :test_name => @test_name,
36
+ :log => <<-END,
37
+ Made-up stack trace:
38
+ /some_module/some_class.rb:697:in `bad_method'
39
+ /some_module/other_class.rb:12345677:in `long_method'
40
+ this link should be <a href="#">escaped</a>
41
+ blah blah blah
42
+ END
43
+ :data => "{:param1 => :value, :param2 => :another_value}"
44
+ )
45
+ end
46
+ @index = File.join(test_output_dir, "index.html")
47
+ FileUtils.rm_f @index
48
+ @detail = File.join(test_output_dir, @test_name,"1.html")
49
+ FileUtils.rm_f @detail
50
+ end
51
+
52
+ it "creates a final report based on tarantula results" do
53
+ Relevance::Tarantula::Result.any_instance.stubs(:rails_root).returns("STUB_ROOT")
54
+ reporter = Relevance::Tarantula::HtmlReporter.new(test_output_dir)
55
+ stub_puts_and_print(reporter)
56
+ (@success_results + @fail_results).each {|r| reporter.report(r)}
57
+ reporter.finish_report(@test_name)
58
+ File.exist?(@index).should be_true
59
+ end
60
+
61
+ it "creates a final report with links to detailed reports in subdirs" do
62
+ Relevance::Tarantula::Result.any_instance.stubs(:rails_root).returns("STUB_ROOT")
63
+ reporter = Relevance::Tarantula::HtmlReporter.new(test_output_dir)
64
+ stub_puts_and_print(reporter)
65
+ (@success_results + @fail_results).each {|r| reporter.report(r)}
66
+ reporter.finish_report(@test_name)
67
+ links = Hpricot(File.read(@index)).search('.left a')
68
+ links.each do |link|
69
+ link['href'].should match(/#{@test_name}\/\d+\.html/)
70
+ end
71
+ end
72
+
73
+ it "creates detailed reports based on tarantula results" do
74
+ Relevance::Tarantula::Result.any_instance.stubs(:rails_root).returns("STUB_ROOT")
75
+ reporter = Relevance::Tarantula::HtmlReporter.new(test_output_dir)
76
+ stub_puts_and_print(reporter)
77
+ (@success_results + @fail_results).each {|r| reporter.report(r)}
78
+ reporter.finish_report(@test_name)
79
+ File.exist?(@detail).should be_true
80
+ end
81
+
82
+ end