tarantula-rails3 0.3.3

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 (68) hide show
  1. data/CHANGELOG +49 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +161 -0
  4. data/Rakefile +83 -0
  5. data/VERSION.yml +4 -0
  6. data/examples/example_helper.rb +57 -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_handler_example.rb +29 -0
  12. data/examples/relevance/tarantula/basic_attack_example.rb +12 -0
  13. data/examples/relevance/tarantula/crawler_example.rb +375 -0
  14. data/examples/relevance/tarantula/form_example.rb +50 -0
  15. data/examples/relevance/tarantula/form_submission_example.rb +171 -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 +84 -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_example.rb +23 -0
  28. data/laf/images/header_bg.jpg +0 -0
  29. data/laf/images/logo.png +0 -0
  30. data/laf/images/tagline.png +0 -0
  31. data/laf/javascripts/jquery-1.2.3.js +3408 -0
  32. data/laf/javascripts/jquery-ui-tabs.js +890 -0
  33. data/laf/javascripts/jquery.tablesorter.js +861 -0
  34. data/laf/javascripts/tarantula.js +10 -0
  35. data/laf/stylesheets/tarantula.css +346 -0
  36. data/lib/relevance/core_extensions/ellipsize.rb +34 -0
  37. data/lib/relevance/core_extensions/file.rb +9 -0
  38. data/lib/relevance/core_extensions/metaclass.rb +78 -0
  39. data/lib/relevance/core_extensions/response.rb +9 -0
  40. data/lib/relevance/core_extensions/string_chars_fix.rb +11 -0
  41. data/lib/relevance/core_extensions/test_case.rb +19 -0
  42. data/lib/relevance/tarantula.rb +58 -0
  43. data/lib/relevance/tarantula/attack.rb +18 -0
  44. data/lib/relevance/tarantula/attack_handler.rb +37 -0
  45. data/lib/relevance/tarantula/basic_attack.rb +40 -0
  46. data/lib/relevance/tarantula/crawler.rb +254 -0
  47. data/lib/relevance/tarantula/detail.html.erb +81 -0
  48. data/lib/relevance/tarantula/form.rb +23 -0
  49. data/lib/relevance/tarantula/form_submission.rb +88 -0
  50. data/lib/relevance/tarantula/html_document_handler.rb +36 -0
  51. data/lib/relevance/tarantula/html_report_helper.rb +39 -0
  52. data/lib/relevance/tarantula/html_reporter.rb +105 -0
  53. data/lib/relevance/tarantula/index.html.erb +37 -0
  54. data/lib/relevance/tarantula/invalid_html_handler.rb +18 -0
  55. data/lib/relevance/tarantula/io_reporter.rb +34 -0
  56. data/lib/relevance/tarantula/link.rb +94 -0
  57. data/lib/relevance/tarantula/log_grabber.rb +16 -0
  58. data/lib/relevance/tarantula/rails_integration_proxy.rb +68 -0
  59. data/lib/relevance/tarantula/recording.rb +12 -0
  60. data/lib/relevance/tarantula/response.rb +13 -0
  61. data/lib/relevance/tarantula/result.rb +77 -0
  62. data/lib/relevance/tarantula/test_report.html.erb +32 -0
  63. data/lib/relevance/tarantula/tidy_handler.rb +32 -0
  64. data/lib/relevance/tarantula/transform.rb +17 -0
  65. data/lib/relevance/tasks/tarantula_tasks.rake +42 -0
  66. data/lib/tarantula-rails3.rb +9 -0
  67. data/template/tarantula_test.rb +22 -0
  68. metadata +164 -0
@@ -0,0 +1,171 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb"))
2
+
3
+ describe Relevance::Tarantula::FormSubmission do
4
+
5
+ describe "with a good form" do
6
+ # TODO: add more from field types to this example form as needed
7
+ before do
8
+ @tag = Hpricot(%q{
9
+ <form action="/session" method="post">
10
+ <input id="email" name="email" size="30" type="text" />
11
+ <textarea id="comment" name="comment"value="1" />
12
+ <input name="commit" type="submit" value="Postit" />
13
+ <input name="secret" type="hidden" value="secret" />
14
+ <select id="foo_opened_on_1i" name="foo[opened_on(1i)]">
15
+ <option value="2003">2003</option>
16
+ <option value="2004">2004</option>
17
+ </select>
18
+ </form>
19
+ })
20
+ end
21
+
22
+ describe "crawl" do
23
+
24
+ it "converts ActiveRecord::RecordNotFound into a 404" do
25
+ (crawler = stub_everything).expects(:submit).raises(ActiveRecord::RecordNotFound)
26
+ form = Relevance::Tarantula::FormSubmission.new(make_form(@tag.at('form'), crawler))
27
+ response = form.crawl
28
+ response.code.should == "404"
29
+ response.content_type.should == "text/plain"
30
+ response.body.should == "ActiveRecord::RecordNotFound"
31
+ end
32
+
33
+ it "submits the form and logs response" do
34
+ doc = Hpricot('<form action="/action" method="post"/>')
35
+ form = make_form(doc.at('form'))
36
+ fs = Relevance::Tarantula::FormSubmission.new(form)
37
+ form.crawler.expects(:submit).returns(stub(:code => "200"))
38
+ fs.expects(:log).with("Response 200 for #{fs}")
39
+ fs.crawl
40
+ end
41
+
42
+ end
43
+
44
+ describe "with default attack" do
45
+ before do
46
+ @form = make_form(@tag.at('form'))
47
+ @fs = Relevance::Tarantula::FormSubmission.new(@form)
48
+ end
49
+
50
+ it "can mutate text areas" do
51
+ @fs.attack.stubs(:random_int).returns("42")
52
+ @fs.mutate_text_areas(@form).should == {"comment" => "42"}
53
+ end
54
+
55
+ it "can mutate selects" do
56
+ Hpricot::Elements.any_instance.stubs(:rand).returns(stub(:[] => "2006-stub"))
57
+ @fs.mutate_selects(@form).should == {"foo[opened_on(1i)]" => "2006-stub"}
58
+ end
59
+
60
+ it "can mutate inputs" do
61
+ @fs.attack.stubs(:random_int).returns("43")
62
+ @fs.mutate_inputs(@form).should == {"commit"=>"43", "secret"=>"43", "email"=>"43"}
63
+ end
64
+
65
+ it "has a signature based on action and fields" do
66
+ @fs.signature.should == ['/session', [
67
+ "comment",
68
+ "commit",
69
+ "email",
70
+ "foo[opened_on(1i)]",
71
+ "secret"],
72
+ @fs.attack.name]
73
+ end
74
+
75
+ it "has a friendly to_s" do
76
+ @fs.to_s.should =~ %r{^/session post}
77
+ end
78
+ end
79
+
80
+ describe "with a custom attack" do
81
+ before do
82
+ @form = make_form(@tag.at('form'))
83
+ @attack = Relevance::Tarantula::Attack.new(:name => 'foo_name',
84
+ :input => 'foo_code',
85
+ :output => 'foo_code')
86
+ @fs = Relevance::Tarantula::FormSubmission.new(@form, @attack)
87
+ end
88
+
89
+ it "can mutate text areas" do
90
+ @fs.mutate_text_areas(@form).should == {"comment" => "foo_code"}
91
+ end
92
+
93
+ it "can mutate selects" do
94
+ Hpricot::Elements.any_instance.stubs(:rand).returns(stub(:[] => "2006-stub"))
95
+ @fs.mutate_selects(@form).should == {"foo[opened_on(1i)]" => "2006-stub"}
96
+ end
97
+
98
+ it "can mutate inputs" do
99
+ @fs.mutate_inputs(@form).should == {"commit"=>"foo_code", "secret"=>"foo_code", "email"=>"foo_code"}
100
+ end
101
+
102
+ it "has a signature based on action, fields, and attack name" do
103
+ @fs.signature.should == ['/session', [
104
+ "comment",
105
+ "commit",
106
+ "email",
107
+ "foo[opened_on(1i)]",
108
+ "secret"],
109
+ "foo_name"
110
+ ]
111
+ end
112
+
113
+ it "has a friendly to_s" do
114
+ @fs.to_s.should =~ %r{^/session post}
115
+ end
116
+
117
+ it "processes all its attacks" do
118
+ Relevance::Tarantula::FormSubmission.stubs(:attacks).returns([
119
+ Relevance::Tarantula::Attack.new({:name => 'foo_name1', :input => 'foo_input', :output => 'foo_output'}),
120
+ Relevance::Tarantula::Attack.new({:name => 'foo_name2', :input => 'foo_input', :output => 'foo_output'}),
121
+ ])
122
+ Relevance::Tarantula::FormSubmission.mutate(@form).size.should == 2
123
+ end
124
+
125
+ it "maps hash attacks to Attack instances" do
126
+ saved_attacks = Relevance::Tarantula::FormSubmission.instance_variable_get("@attacks")
127
+ begin
128
+ Relevance::Tarantula::FormSubmission.instance_variable_set("@attacks", [{ :name => "attack name"}])
129
+ Relevance::Tarantula::FormSubmission.attacks.should == [Relevance::Tarantula::Attack.new({:name => "attack name"})]
130
+ ensure
131
+ # isolate this test properly
132
+ Relevance::Tarantula::FormSubmission.instance_variable_set("@attacks", saved_attacks)
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ describe "with a crummy form" do
139
+ before do
140
+ @tag = Hpricot(%q{
141
+ <form action="/session" method="post">
142
+ <input value="no_name" />
143
+ </form>
144
+ })
145
+ end
146
+
147
+ describe "with default attack" do
148
+ before do
149
+ @form = make_form(@tag.at('form'))
150
+ @fs = Relevance::Tarantula::FormSubmission.new(@form)
151
+ end
152
+
153
+ it "ignores unnamed inputs" do
154
+ @fs.mutate_inputs(@form).should == {}
155
+ end
156
+ end
157
+
158
+ describe "with a custom attack" do
159
+ before do
160
+ @form = make_form(@tag.at('form'))
161
+ @fs = Relevance::Tarantula::FormSubmission.new(@form, {:name => 'foo_name', :input => 'foo_code', :output => 'foo_code'})
162
+ end
163
+
164
+ it "ignores unnamed inputs" do
165
+ @fs.mutate_inputs(@form).should == {}
166
+ end
167
+ end
168
+
169
+ end
170
+
171
+ 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
@@ -0,0 +1,33 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "example_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.expand_path(File.join(File.dirname(__FILE__), "..", "..", "example_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_error(RuntimeError)
10
+ end
11
+ end
@@ -0,0 +1,84 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb"))
2
+
3
+ describe "Relevance::Tarantula::Link" do
4
+ include ActionView::Helpers::UrlHelper
5
+
6
+ it "does not raise an error when initializing without href attribtue" do
7
+ link = make_link(Hpricot('<a="/foo">foo</a>').at('a'))
8
+ link.href.should == nil
9
+ link.method.should == :get
10
+ end
11
+
12
+ it "parses anchor tags" do
13
+ link = make_link(Hpricot('<a href="/foo">foo</a>').at('a'))
14
+ link.href.should == '/foo'
15
+ link.method.should == :get
16
+ end
17
+
18
+ it "parses anchor tags with POST 'method'" do
19
+ link = make_link(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:post)}">foo</a>}).at('a'))
20
+ link.href.should == '/foo'
21
+ link.method.should == :post
22
+ end
23
+
24
+ it "parses anchor tags with PUT 'method'" do
25
+ link = make_link(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:put)}">foo</a>}).at('a'))
26
+ link.href.should == '/foo'
27
+ link.method.should == :put
28
+ end
29
+
30
+ it "parses anchor tags with DELETE 'method'" do
31
+ link = make_link(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:delete)}">foo</a>}).at('a'))
32
+ link.href.should == '/foo'
33
+ link.method.should == :delete
34
+ end
35
+
36
+ it "parses link tags with text" do
37
+ link = make_link(Hpricot('<link href="/bar">bar</a>').at('link'))
38
+ link.href.should == '/bar'
39
+ link.method.should == :get
40
+ end
41
+
42
+ it "parses link tags without text" do
43
+ link = make_link(Hpricot('<link href="/bar" />').at('link'))
44
+ link.href.should == '/bar'
45
+ link.method.should == :get
46
+ end
47
+
48
+ it 'remembers link referrer if there is one' do
49
+ link = make_link('/url', stub_everything, '/some-referrer')
50
+ link.referrer.should == '/some-referrer'
51
+ end
52
+
53
+ it "does two things when crawled: follow, log, and handle" do
54
+ crawler = Relevance::Tarantula::Crawler.new
55
+ link = make_link('/foo', crawler)
56
+
57
+ response = stub(:code => "200")
58
+ crawler.expects(:follow).returns(response)
59
+ link.expects(:log)
60
+ crawler.expects(:handle_link_results)
61
+
62
+ link.crawl
63
+ end
64
+
65
+ # method_javascript_function needs this method
66
+ def protect_against_forgery?
67
+ false
68
+ end
69
+
70
+ end
71
+
72
+ describe "possible conflict when user has an AR model named Link" do
73
+ it "does not taint Object with Relevance::Tarantula" do
74
+ Object.ancestors.should_not include(Relevance::Tarantula)
75
+ end
76
+
77
+ it "doesnt break with a Link model" do
78
+ lambda {
79
+ class Link < ActiveRecord::Base
80
+ end
81
+ }.should_not raise_error
82
+ end
83
+
84
+ end