tarantula 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 (118) hide show
  1. data/CHANGELOG +2 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +106 -0
  4. data/Rakefile +80 -0
  5. data/init.rb +1 -0
  6. data/install.rb +1 -0
  7. data/laf/images/background.jpg +0 -0
  8. data/laf/images/relevance-os-logo.gif +0 -0
  9. data/laf/images/tab.png +0 -0
  10. data/laf/images/table-sort.gif +0 -0
  11. data/laf/images/tarantula-sprites.png +0 -0
  12. data/laf/javascripts/jquery-1.2.3.js +3408 -0
  13. data/laf/javascripts/jquery-ui-tabs.js +890 -0
  14. data/laf/javascripts/jquery.tablesorter.js +861 -0
  15. data/laf/javascripts/tarantula.js +10 -0
  16. data/laf/stylesheets/tarantula.css +638 -0
  17. data/laf/stylesheets/ui.tabs.css +113 -0
  18. data/lib/relevance/core_extensions/ellipsize.rb +34 -0
  19. data/lib/relevance/core_extensions/file.rb +9 -0
  20. data/lib/relevance/core_extensions/response.rb +9 -0
  21. data/lib/relevance/core_extensions/test_case.rb +12 -0
  22. data/lib/relevance/tarantula.rb +63 -0
  23. data/lib/relevance/tarantula/attack.rb +15 -0
  24. data/lib/relevance/tarantula/attack_form_submission.rb +75 -0
  25. data/lib/relevance/tarantula/attack_handler.rb +37 -0
  26. data/lib/relevance/tarantula/crawler.rb +240 -0
  27. data/lib/relevance/tarantula/detail.html.erb +77 -0
  28. data/lib/relevance/tarantula/form.rb +21 -0
  29. data/lib/relevance/tarantula/form_submission.rb +70 -0
  30. data/lib/relevance/tarantula/html_document_handler.rb +36 -0
  31. data/lib/relevance/tarantula/html_report_helper.rb +56 -0
  32. data/lib/relevance/tarantula/html_reporter.rb +105 -0
  33. data/lib/relevance/tarantula/index.html.erb +48 -0
  34. data/lib/relevance/tarantula/invalid_html_handler.rb +18 -0
  35. data/lib/relevance/tarantula/io_reporter.rb +34 -0
  36. data/lib/relevance/tarantula/link.rb +56 -0
  37. data/lib/relevance/tarantula/log_grabber.rb +16 -0
  38. data/lib/relevance/tarantula/rails_integration_proxy.rb +70 -0
  39. data/lib/relevance/tarantula/recording.rb +12 -0
  40. data/lib/relevance/tarantula/response.rb +13 -0
  41. data/lib/relevance/tarantula/result.rb +66 -0
  42. data/lib/relevance/tarantula/test_report.html.erb +34 -0
  43. data/lib/relevance/tarantula/tidy_handler.rb +32 -0
  44. data/lib/relevance/tarantula/transform.rb +17 -0
  45. data/manifest.txt +117 -0
  46. data/rails/init.rb +1 -0
  47. data/tarantula.gemspec +48 -0
  48. data/tasks/tarantula_tasks.rake +34 -0
  49. data/template/tarantula_test.rb +12 -0
  50. data/test/relevance/core_extensions/ellipsize_test.rb +19 -0
  51. data/test/relevance/core_extensions/file_test.rb +8 -0
  52. data/test/relevance/core_extensions/response_test.rb +29 -0
  53. data/test/relevance/core_extensions/test_case_test.rb +16 -0
  54. data/test/relevance/tarantula/attack_form_submission_test.rb +79 -0
  55. data/test/relevance/tarantula/attack_handler_test.rb +29 -0
  56. data/test/relevance/tarantula/crawler_test.rb +296 -0
  57. data/test/relevance/tarantula/form_submission_test.rb +71 -0
  58. data/test/relevance/tarantula/form_test.rb +50 -0
  59. data/test/relevance/tarantula/html_document_handler_test.rb +43 -0
  60. data/test/relevance/tarantula/html_report_helper_test.rb +47 -0
  61. data/test/relevance/tarantula/html_reporter_test.rb +82 -0
  62. data/test/relevance/tarantula/invalid_html_handler_test.rb +33 -0
  63. data/test/relevance/tarantula/io_reporter_test.rb +11 -0
  64. data/test/relevance/tarantula/link_test.rb +61 -0
  65. data/test/relevance/tarantula/log_grabber_test.rb +26 -0
  66. data/test/relevance/tarantula/rails_integration_proxy_test.rb +94 -0
  67. data/test/relevance/tarantula/result_test.rb +85 -0
  68. data/test/relevance/tarantula/tidy_handler_test.rb +58 -0
  69. data/test/relevance/tarantula/transform_test.rb +21 -0
  70. data/test/relevance/tarantula_test.rb +23 -0
  71. data/test/test_helper.rb +34 -0
  72. data/tmp/test_output/images/background.jpg +0 -0
  73. data/tmp/test_output/images/relevance-os-logo.gif +0 -0
  74. data/tmp/test_output/images/tab.png +0 -0
  75. data/tmp/test_output/images/table-sort.gif +0 -0
  76. data/tmp/test_output/images/tarantula-sprites.png +0 -0
  77. data/tmp/test_output/index.html +255 -0
  78. data/tmp/test_output/javascripts/jquery-1.2.3.js +3408 -0
  79. data/tmp/test_output/javascripts/jquery-ui-tabs.js +890 -0
  80. data/tmp/test_output/javascripts/jquery.tablesorter.js +861 -0
  81. data/tmp/test_output/javascripts/tarantula.js +10 -0
  82. data/tmp/test_output/stylesheets/tarantula.css +638 -0
  83. data/tmp/test_output/stylesheets/ui.tabs.css +113 -0
  84. data/tmp/test_output/test_user_pages/1.html +71 -0
  85. data/tmp/test_output/test_user_pages/10.html +71 -0
  86. data/tmp/test_output/test_user_pages/11.html +71 -0
  87. data/tmp/test_output/test_user_pages/12.html +71 -0
  88. data/tmp/test_output/test_user_pages/13.html +71 -0
  89. data/tmp/test_output/test_user_pages/14.html +71 -0
  90. data/tmp/test_output/test_user_pages/15.html +71 -0
  91. data/tmp/test_output/test_user_pages/16.html +71 -0
  92. data/tmp/test_output/test_user_pages/17.html +71 -0
  93. data/tmp/test_output/test_user_pages/18.html +71 -0
  94. data/tmp/test_output/test_user_pages/19.html +71 -0
  95. data/tmp/test_output/test_user_pages/2.html +71 -0
  96. data/tmp/test_output/test_user_pages/20.html +71 -0
  97. data/tmp/test_output/test_user_pages/3.html +71 -0
  98. data/tmp/test_output/test_user_pages/4.html +71 -0
  99. data/tmp/test_output/test_user_pages/5.html +71 -0
  100. data/tmp/test_output/test_user_pages/6.html +71 -0
  101. data/tmp/test_output/test_user_pages/7.html +71 -0
  102. data/tmp/test_output/test_user_pages/8.html +71 -0
  103. data/tmp/test_output/test_user_pages/9.html +71 -0
  104. data/uninstall.rb +1 -0
  105. data/vendor/xss-shield/MIT-LICENSE +20 -0
  106. data/vendor/xss-shield/README +76 -0
  107. data/vendor/xss-shield/init.rb +16 -0
  108. data/vendor/xss-shield/lib/xss_shield.rb +6 -0
  109. data/vendor/xss-shield/lib/xss_shield/erb_hacks.rb +111 -0
  110. data/vendor/xss-shield/lib/xss_shield/haml_hacks.rb +42 -0
  111. data/vendor/xss-shield/lib/xss_shield/safe_string.rb +47 -0
  112. data/vendor/xss-shield/lib/xss_shield/secure_helpers.rb +40 -0
  113. data/vendor/xss-shield/test/test_actionview_integration.rb +40 -0
  114. data/vendor/xss-shield/test/test_erb.rb +44 -0
  115. data/vendor/xss-shield/test/test_haml.rb +43 -0
  116. data/vendor/xss-shield/test/test_helpers.rb +25 -0
  117. data/vendor/xss-shield/test/test_safe_string.rb +55 -0
  118. metadata +283 -0
@@ -0,0 +1,71 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_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,50 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_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,43 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_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,47 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
2
+
3
+ module HtmlReportHelperSpec
4
+
5
+ # Is there an idiom for this?
6
+ def self.included(base)
7
+ base.before do
8
+ @reporter = Object.new
9
+ @reporter.extend Relevance::Tarantula::HtmlReportHelper
10
+ end
11
+ end
12
+ end
13
+
14
+ describe 'Relevance::Tarantula::HtmlReportHelper#wrap_in_line_number_table' do
15
+ include HtmlReportHelperSpec
16
+ it "can wrap text in a line number table" do
17
+ html = @reporter.wrap_in_line_number_table("Line 1\nLine 2")
18
+ html.should == <<-END.strip
19
+ <table class="grid tablesorter"><thead><tr><th class="sort asc"><span>Line #</span><span class="sort"><em>&#8613;</em></span></th><th class="sort left"><span>Line</span><span class="sort"><em>&#8613;</em></span></th></tr></thead><tr><td>1</td><td>Line 1</td></tr><tr><td>2</td><td>Line 2</td></tr></table>
20
+ END
21
+ end
22
+ end
23
+
24
+ describe 'Relevance::Tarantula::HtmlReportHelper#wrap_stack_trace_line' do
25
+ include HtmlReportHelperSpec
26
+ it "can wrap stack trace line in links" do
27
+ line = %{/action_controller/filters.rb:697:in `call_filters'}
28
+ @reporter.stubs(:textmate_url).returns("ide_url")
29
+ html = @reporter.wrap_stack_trace_line(line)
30
+ html.should == "<a href='ide_url'>/action_controller/filters.rb:697</a>:in `call_filters'"
31
+ end
32
+
33
+ it "converts html entities for non-stack trace lines" do
34
+ line = %{<a href="foo">escape me</a>}
35
+ html = @reporter.wrap_stack_trace_line(line)
36
+ html.should == %{&lt;a href=&quot;foo&quot;&gt;escape me&lt;/a&gt;}
37
+ end
38
+
39
+ end
40
+
41
+ describe 'Relevance::Tarantula::HtmlReportHelper IDE help' do
42
+ include HtmlReportHelperSpec
43
+ it "can create a textmate url" do
44
+ @reporter.stubs(:rails_root).returns("STUB_RAILS_ROOT")
45
+ @reporter.textmate_url("/etc/somewhere", 100).should =~ %r{txmt://open\?url=.*/STUB_RAILS_ROOT/etc/somewhere&line_no=100}
46
+ end
47
+ end
@@ -0,0 +1,82 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_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.should.exist @index
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.should.exist @detail
80
+ end
81
+
82
+ end
@@ -0,0 +1,33 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
2
+
3
+ describe "Relevance::Tarantula::InvalidHtmlHandler" do
4
+ before do
5
+ @handler = Relevance::Tarantula::InvalidHtmlHandler.new
6
+ end
7
+
8
+ it "does not write HTML Scanner warnings to the console" do
9
+ bad_html = "<html><div></form></html>"
10
+ err = Recording.stderr do
11
+ @handler.handle(Relevance::Tarantula::Result.new(:response => stub(:html? => true, :body => bad_html)))
12
+ end
13
+ err.should == ""
14
+ end
15
+
16
+ it "rejects unclosed html" do
17
+ response = stub(:html? => true, :body => '<html><div></html>', :code => 200)
18
+ result = @handler.handle(Relevance::Tarantula::Result.new(:response => response))
19
+ result.success.should == false
20
+ result.description.should == "Bad HTML (Scanner)"
21
+ end
22
+
23
+ it "loves the good html" do
24
+ response = stub(:html? => true, :body => '<html><div></div></html>', :code => 200)
25
+ @handler.handle(Relevance::Tarantula::Result.new(:response => response)).should == nil
26
+ end
27
+
28
+ it "ignores non html" do
29
+ response = stub(:html? => false, :body => '<html><div></html>', :code => 200)
30
+ @handler.handle(Relevance::Tarantula::Result.new(:response => response)).should == nil
31
+ end
32
+ end
33
+
@@ -0,0 +1,11 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
2
+
3
+ describe 'Relevance::Tarantula::IOReporter' do
4
+ it "reports errors to stderr and then raises" do
5
+ reporter = Relevance::Tarantula::IOReporter.new($stderr)
6
+ reporter.report stub(:code => "404", :url => "/uh-oh", :success => false)
7
+ $stderr.expects(:puts).with("****** FAILURES")
8
+ $stderr.expects(:puts).with("404: /uh-oh")
9
+ lambda {reporter.finish_report("test_user_pages")}.should.raise RuntimeError
10
+ end
11
+ end
@@ -0,0 +1,61 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
2
+
3
+ describe "Relevance::Tarantula::Link" do
4
+ include ActionView::Helpers::UrlHelper
5
+
6
+ it "parses anchor tags" do
7
+ link = Relevance::Tarantula::Link.new(Hpricot('<a href="/foo">foo</a>').at('a'))
8
+ assert_equal "/foo", link.href
9
+ assert_equal :get, link.method
10
+ end
11
+
12
+ it "parses anchor tags with POST 'method'" do
13
+ link = Relevance::Tarantula::Link.new(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:post)}">foo</a>}).at('a'))
14
+ assert_equal "/foo", link.href
15
+ assert_equal :post, link.method
16
+ end
17
+
18
+ it "parses anchor tags with PUT 'method'" do
19
+ link = Relevance::Tarantula::Link.new(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:put)}">foo</a>}).at('a'))
20
+ assert_equal "/foo", link.href
21
+ assert_equal :put, link.method
22
+ end
23
+
24
+ it "parses anchor tags with DELETE 'method'" do
25
+ link = Relevance::Tarantula::Link.new(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:delete)}">foo</a>}).at('a'))
26
+ assert_equal "/foo", link.href
27
+ assert_equal :delete, link.method
28
+ end
29
+
30
+ it "parses link tags with text" do
31
+ link = Relevance::Tarantula::Link.new(Hpricot('<link href="/bar">bar</a>').at('link'))
32
+ assert_equal "/bar", link.href
33
+ assert_equal :get, link.method
34
+ end
35
+
36
+ it "parses link tags without text" do
37
+ link = Relevance::Tarantula::Link.new(Hpricot('<link href="/bar" />').at('link'))
38
+ assert_equal "/bar", link.href
39
+ assert_equal :get, link.method
40
+ end
41
+
42
+ # method_javascript_function needs this method
43
+ def protect_against_forgery?
44
+ false
45
+ end
46
+
47
+ end
48
+
49
+ describe "possible conflict when user has an AR model named Link" do
50
+ it "does not taint Object with Relevance::Tarantula" do
51
+ Object.ancestors.should.not.include Relevance::Tarantula
52
+ end
53
+
54
+ it "doesnt break with a Link model" do
55
+ lambda {
56
+ class Link < ActiveRecord::Base
57
+ end
58
+ }.should.not.raise
59
+ end
60
+
61
+ end
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
2
+
3
+ describe 'Relevance::Tarantula::LogGrabber' do
4
+ before do
5
+ @grabber = Relevance::Tarantula::LogGrabber.new(log_file)
6
+ FileUtils.mkdir_p(test_output_dir)
7
+ end
8
+
9
+ def log_file
10
+ File.join(File.join(test_output_dir, "example.log"))
11
+ end
12
+
13
+ it "can clear the log file" do
14
+ File.open(log_file, "w") {|f| f.print "sample log"}
15
+ File.size(log_file).should == 10
16
+ @grabber.clear!
17
+ File.size(log_file).should == 0
18
+ end
19
+
20
+ it "can grab the log file" do
21
+ File.open(log_file, "w") {|f| f.print "sample log"}
22
+ @grabber.grab!.should == "sample log"
23
+ File.size(log_file).should == 0
24
+ end
25
+
26
+ end
@@ -0,0 +1,94 @@
1
+ require File.join(File.dirname(__FILE__), "..", "..", "test_helper.rb")
2
+
3
+ describe "Relevance::Tarantula::RailsIntegrationProxy rails_integration_test" do
4
+ before {
5
+ Relevance::Tarantula::Crawler.any_instance.stubs(:crawl)
6
+ Relevance::Tarantula::Crawler.any_instance.stubs(:rails_root).returns("STUB_RAILS_ROOT")
7
+ Relevance::Tarantula::RailsIntegrationProxy.stubs(:rails_root).returns("STUB_RAILS_ROOT")
8
+ Relevance::Tarantula::RailsIntegrationProxy.stubs(:new).returns(stub(:integration_test => stub(:method_name => @test_name)))
9
+ @test_name = "test_user_pages"
10
+ }
11
+
12
+ it "strips leading hostname from link urls" do
13
+ crawler = Relevance::Tarantula::RailsIntegrationProxy.rails_integration_test(stub(:host => "foo.com"))
14
+ crawler.transform_url("http://foo.com/path").should == "/path"
15
+ crawler.transform_url("http://bar.com/path").should == "http://bar.com/path"
16
+ end
17
+
18
+ it "allows override of max_url_length" do
19
+ crawler = Relevance::Tarantula::RailsIntegrationProxy.rails_integration_test(stub(:host => "foo.com"),
20
+ :max_url_length => 16)
21
+ crawler.max_url_length.should == 16
22
+ end
23
+
24
+ it "has some useful defaults" do
25
+ crawler = Relevance::Tarantula::RailsIntegrationProxy.rails_integration_test(stub(:host => "foo.com"))
26
+ crawler.log_grabber.should.not.be nil
27
+ end
28
+ end
29
+
30
+
31
+ describe "Relevance::Tarantula::RailsIntegrationProxy" do
32
+ %w{get post}.each do |http_method|
33
+ it "can #{http_method}" do
34
+ @rip = Relevance::Tarantula::RailsIntegrationProxy.new(stub)
35
+ @response = stub({:code => :foo})
36
+ @rip.integration_test = stub_everything(:response => @response)
37
+ @rip.send(http_method, "/url").should.be @response
38
+ end
39
+ end
40
+
41
+ it "adds a response accessor to its delegate rails integration test" do
42
+ o = Object.new
43
+ Relevance::Tarantula::RailsIntegrationProxy.new(o)
44
+ o.methods(false).sort.should == %w{response response=}
45
+ end
46
+
47
+ end
48
+
49
+ describe "Relevance::Tarantula::RailsIntegrationProxy patching" do
50
+ before do
51
+ @rip = Relevance::Tarantula::RailsIntegrationProxy.new(stub)
52
+ @rip.stubs(:rails_root).returns("faux_rails_root")
53
+ @response = stub_everything({:code => "404", :headers => {}})
54
+ File.stubs(:exist?).returns(true)
55
+ end
56
+
57
+ it "patches in Relevance::CoreExtensions::Response" do
58
+ @rip = Relevance::Tarantula::RailsIntegrationProxy.new(stub)
59
+ @rip.stubs(:rails_root).returns("faux_rails_root")
60
+ @response = stub_everything({:code => "404", :headers => {}, :content_type => "text/html"})
61
+ @response.meta.ancestors.should.not.include Relevance::CoreExtensions::Response
62
+ @rip.patch_response("/url", @response)
63
+ @response.meta.ancestors.should.include Relevance::CoreExtensions::Response
64
+ @response.html?.should == true
65
+ end
66
+
67
+ it "ignores 404s for known static binary types" do
68
+ File.expects(:extension).returns("pdf")
69
+ @rip.expects(:log).with("Skipping /url (for now)")
70
+ @rip.patch_response("/url", @response)
71
+ end
72
+
73
+ it "replaces 404s with 200s, pulling content from public, for known text types" do
74
+ File.expects(:extension).returns("html")
75
+ @rip.expects(:static_content_file).with("/url").returns("File body")
76
+ @rip.patch_response("/url", @response)
77
+ @response.headers.should == {"type" => "text/html"}
78
+ end
79
+
80
+ it "logs and skips types we haven't dealt with yet" do
81
+ File.expects(:extension).returns("whizzy")
82
+ @rip.expects(:log).with("Skipping unknown type /url")
83
+ @rip.patch_response("/url", @response)
84
+ end
85
+
86
+ it "can find static content relative to rails root" do
87
+ @rip.static_content_path("foo").should == File.expand_path("faux_rails_root/public/foo")
88
+ end
89
+
90
+ it "can read static content relative to rails root" do
91
+ File.expects(:read).with(@rip.static_content_path("foo"))
92
+ @rip.static_content_file("foo")
93
+ end
94
+ end