2013-02-05 14:16:51 -05:00
require 'spec_helper'
describe TopicLink do
it { should validate_presence_of :url }
def test_uri
URI . parse ( Discourse . base_url )
end
2014-07-11 14:17:01 +10:00
let ( :topic ) do
Fabricate ( :topic , title : 'unique topic name' )
end
let ( :user ) do
topic . user
2013-02-05 14:16:51 -05:00
end
it " can't link to the same topic " do
2014-07-11 14:17:01 +10:00
ftl = TopicLink . new ( url : " /t/ #{ topic . id } " ,
topic_id : topic . id ,
link_topic_id : topic . id )
2014-09-25 17:44:48 +02:00
ftl . valid? . should == false
2013-02-05 14:16:51 -05:00
end
describe 'external links' do
before do
2014-07-11 14:17:01 +10:00
post = Fabricate ( :post , raw : "
2014-06-26 11:38:23 +10:00
http : / / a . com /
http : / / b . com / b
http : / / #{'a'*200}.com/invalid
http : / / b . com / #{'a'*500}
2014-07-11 14:17:01 +10:00
" , user: user, topic: topic)
2014-06-26 11:38:23 +10:00
2014-07-11 14:17:01 +10:00
TopicLink . extract_from ( post )
2013-02-05 14:16:51 -05:00
end
2013-06-05 12:48:34 +10:00
it 'works' do
# has the forum topic links
2014-07-11 14:17:01 +10:00
topic . topic_links . count . should == 2
2013-02-05 14:16:51 -05:00
2013-06-05 12:48:34 +10:00
# works with markdown links
2014-09-25 17:44:48 +02:00
topic . topic_links . exists? ( url : " http://a.com/ " ) . should == true
2013-02-05 14:16:51 -05:00
2013-06-05 12:48:34 +10:00
#works with markdown links followed by a period
2014-09-25 17:44:48 +02:00
topic . topic_links . exists? ( url : " http://b.com/b " ) . should == true
2013-02-05 14:16:51 -05:00
end
end
2013-02-11 11:11:48 -05:00
describe 'internal links' do
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
it " extracts onebox " do
other_topic = Fabricate ( :topic , user : user )
other_topic . posts . create ( user : user , raw : " some content for the first post " )
other_post = other_topic . posts . create ( user : user , raw : " some content for the second post " )
2013-02-13 15:22:04 -05:00
2014-07-11 14:17:01 +10:00
url = " http:// #{ test_uri . host } /t/ #{ other_topic . slug } / #{ other_topic . id } / #{ other_post . post_number } "
invalid_url = " http:// #{ test_uri . host } /t/ #{ other_topic . slug } /9999999999999999999999999999999 "
2013-08-08 18:14:12 -04:00
2014-07-11 14:17:01 +10:00
topic . posts . create ( user : user , raw : 'initial post' )
post = topic . posts . create ( user : user , raw : " Link to another topic: \n \n #{ url } \n \n #{ invalid_url } " )
post . reload
2013-02-13 15:22:04 -05:00
2014-07-11 14:17:01 +10:00
TopicLink . extract_from ( post )
2013-02-13 15:22:04 -05:00
2014-07-11 14:17:01 +10:00
link = topic . topic_links . first
# should have a link
link . should be_present
# should be the canonical URL
link . url . should == url
2013-02-13 15:22:04 -05:00
end
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
context 'topic link' do
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
let ( :other_topic ) do
Fabricate ( :topic , user : user )
end
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
let ( :post ) do
other_topic . posts . create ( user : user , raw : " some content " )
2013-02-11 11:11:48 -05:00
end
2013-02-05 14:16:51 -05:00
2013-06-05 12:48:34 +10:00
it 'works' do
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
# ensure other_topic has a post
post
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
url = " http:// #{ test_uri . host } /t/ #{ other_topic . slug } / #{ other_topic . id } "
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
topic . posts . create ( user : user , raw : 'initial post' )
linked_post = topic . posts . create ( user : user , raw : " Link to another topic: #{ url } " )
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
TopicLink . extract_from ( linked_post )
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
link = topic . topic_links . first
link . should be_present
link . should be_internal
link . url . should == url
link . domain . should == test_uri . host
link . link_topic_id == other_topic . id
link . should_not be_reflection
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
reflection = other_topic . topic_links . first
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
reflection . should be_present
reflection . should be_reflection
reflection . post_id . should be_present
reflection . domain . should == test_uri . host
reflection . url . should == " http:// #{ test_uri . host } /t/unique-topic-name/ #{ topic . id } / #{ linked_post . post_number } "
reflection . link_topic_id . should == topic . id
reflection . link_post_id . should == linked_post . id
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
reflection . user_id . should == link . user_id
2013-02-05 14:16:51 -05:00
end
2013-02-11 11:11:48 -05:00
context 'removing a link' do
2013-02-05 14:16:51 -05:00
2013-02-11 11:11:48 -05:00
before do
2014-10-27 22:06:43 +01:00
post . revise ( post . user , { raw : " no more linkies " } )
2014-07-11 14:17:01 +10:00
TopicLink . extract_from ( post )
2013-02-11 11:11:48 -05:00
end
2013-02-05 14:16:51 -05:00
2013-02-11 11:11:48 -05:00
it 'should remove the link' do
2014-07-11 14:17:01 +10:00
topic . topic_links . where ( post_id : post . id ) . should be_blank
2013-06-05 12:48:34 +10:00
# should remove the reflected link
2014-07-11 14:17:01 +10:00
other_topic . topic_links . should be_blank
2013-02-11 11:11:48 -05:00
end
2013-02-25 19:42:20 +03:00
end
2013-02-11 11:11:48 -05:00
end
2013-02-05 14:16:51 -05:00
2013-02-11 12:27:32 -05:00
context " link to a user on discourse " do
2014-07-11 14:17:01 +10:00
let ( :post ) { topic . posts . create ( user : user , raw : " <a href='/users/ #{ user . username_lower } '>user</a> " ) }
2013-02-05 14:16:51 -05:00
before do
2013-02-11 11:11:48 -05:00
TopicLink . extract_from ( post )
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
it 'does not extract a link' do
2014-07-11 14:17:01 +10:00
topic . topic_links . should be_blank
2013-02-05 14:16:51 -05:00
end
2013-02-11 11:11:48 -05:00
end
2013-02-05 14:16:51 -05:00
2013-02-11 12:27:32 -05:00
context " link to a discourse resource like a FAQ " do
2014-07-11 14:17:01 +10:00
let ( :post ) { topic . posts . create ( user : user , raw : " <a href='/faq'>faq link here</a> " ) }
2013-02-11 12:27:32 -05:00
before do
TopicLink . extract_from ( post )
end
2013-02-25 19:42:20 +03:00
it 'does not extract a link' do
2014-07-11 14:17:01 +10:00
topic . topic_links . should be_present
2013-02-11 12:27:32 -05:00
end
end
2014-07-11 14:17:01 +10:00
context " mention links " do
let ( :post ) { topic . posts . create ( user : user , raw : " Hey #{ user . username_lower } " ) }
2013-02-05 14:16:51 -05:00
2013-02-11 11:11:48 -05:00
before do
TopicLink . extract_from ( post )
end
2013-02-05 14:16:51 -05:00
2013-02-25 19:42:20 +03:00
it 'does not extract a link' do
2014-07-11 14:17:01 +10:00
topic . topic_links . should be_blank
end
end
context " quote links " do
it " sets quote correctly " do
linked_post = topic . posts . create ( user : user , raw : " my test post " )
quoting_post = Fabricate ( :post , raw : " [quote= \" #{ user . username } , post: #{ linked_post . post_number } , topic: #{ topic . id } \" ] \n quote \n [/quote] " )
TopicLink . extract_from ( quoting_post )
link = quoting_post . topic . topic_links . first
link . link_post_id . should == linked_post . id
link . quote . should == true
2013-02-11 11:11:48 -05:00
end
2013-02-25 19:42:20 +03:00
end
2013-07-19 01:26:23 +02:00
context " link to a local attachments " do
2014-07-11 14:17:01 +10:00
let ( :post ) { topic . posts . create ( user : user , raw : '<a class="attachment" href="/uploads/default/208/87bb3d8428eb4783.rb">ruby.rb</a>' ) }
2013-07-19 01:26:23 +02:00
it " extracts the link " do
TopicLink . extract_from ( post )
2014-07-11 14:17:01 +10:00
link = topic . topic_links . first
2013-07-19 01:26:23 +02:00
# extracted the link
link . should be_present
# is set to internal
link . should be_internal
# has the correct url
link . url . should == " /uploads/default/208/87bb3d8428eb4783.rb "
# should not be the reflection
link . should_not be_reflection
end
end
context " link to an attachments uploaded on S3 " do
2014-07-11 14:17:01 +10:00
let ( :post ) { topic . posts . create ( user : user , raw : '<a class="attachment" href="//s3.amazonaws.com/bucket/2104a0211c9ce41ed67989a1ed62e9a394c1fbd1446.rb">ruby.rb</a>' ) }
2013-07-19 01:26:23 +02:00
it " extracts the link " do
TopicLink . extract_from ( post )
2014-07-11 14:17:01 +10:00
link = topic . topic_links . first
2013-07-19 01:26:23 +02:00
# extracted the link
link . should be_present
# is not internal
link . should_not be_internal
# has the correct url
link . url . should == " //s3.amazonaws.com/bucket/2104a0211c9ce41ed67989a1ed62e9a394c1fbd1446.rb "
# should not be the reflection
link . should_not be_reflection
end
end
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
describe 'internal link from pm' do
2014-07-11 14:17:01 +10:00
it 'works' do
2014-09-11 17:39:20 +10:00
pm = Fabricate ( :topic , user : user , category_id : nil , archetype : 'private_message' )
2014-07-11 14:17:01 +10:00
pm . posts . create ( user : user , raw : " some content " )
2013-02-25 19:42:20 +03:00
2014-07-11 14:17:01 +10:00
url = " http:// #{ test_uri . host } /t/topic-slug/ #{ topic . id } "
2013-02-25 19:42:20 +03:00
2014-07-11 14:17:01 +10:00
pm . posts . create ( user : user , raw : 'initial post' )
linked_post = pm . posts . create ( user : user , raw : " Link to another topic: #{ url } " )
2013-02-05 14:16:51 -05:00
2014-07-11 14:17:01 +10:00
TopicLink . extract_from ( linked_post )
2013-02-05 14:16:51 -05:00
2014-09-25 17:44:48 +02:00
topic . topic_links . first . should == nil
pm . topic_links . first . should_not == nil
2013-02-05 14:16:51 -05:00
end
end
describe 'internal link with non-standard port' do
it 'includes the non standard port if present' do
2014-07-11 14:17:01 +10:00
other_topic = Fabricate ( :topic , user : user )
SiteSetting . port = 5678
2013-02-05 14:16:51 -05:00
alternate_uri = URI . parse ( Discourse . base_url )
2014-07-11 14:17:01 +10:00
url = " http:// #{ alternate_uri . host } :5678/t/topic-slug/ #{ other_topic . id } "
post = topic . posts . create ( user : user ,
raw : " Link to another topic: #{ url } " )
TopicLink . extract_from ( post )
reflection = other_topic . topic_links . first
reflection . url . should == " http:// #{ alternate_uri . host } :5678/t/unique-topic-name/ #{ topic . id } "
2013-02-05 14:16:51 -05:00
end
end
2013-11-15 12:15:46 -05:00
describe 'counts_for and topic_map' do
2013-06-05 16:10:26 +10:00
it 'returns blank without posts' do
TopicLink . counts_for ( Guardian . new , nil , nil ) . should be_blank
end
context 'with data' do
let ( :post ) do
topic = Fabricate ( :topic )
Fabricate ( :post_with_external_links , user : topic . user , topic : topic )
end
let ( :counts_for ) do
TopicLink . counts_for ( Guardian . new , post . topic , [ post ] )
end
it 'has the correct results' do
TopicLink . extract_from ( post )
topic_link = post . topic . topic_links . first
2013-06-24 18:30:32 -04:00
TopicLinkClick . create ( topic_link : topic_link , ip_address : '192.168.1.1' )
2013-06-05 16:10:26 +10:00
counts_for [ post . id ] . should be_present
counts_for [ post . id ] . find { | l | l [ :url ] == 'http://google.com' } [ :clicks ] . should == 0
counts_for [ post . id ] . first [ :clicks ] . should == 1
2013-11-15 12:15:46 -05:00
array = TopicLink . topic_map ( Guardian . new , post . topic_id )
2013-06-05 16:10:26 +10:00
array . length . should == 4
array [ 0 ] [ " clicks " ] . should == " 1 "
end
it 'secures internal links correctly' do
category = Fabricate ( :category )
secret_topic = Fabricate ( :topic , category : category )
url = " http:// #{ test_uri . host } /t/topic-slug/ #{ secret_topic . id } "
post = Fabricate ( :post , raw : " hello test topic #{ url } " )
TopicLink . extract_from ( post )
2013-11-15 12:15:46 -05:00
TopicLink . topic_map ( Guardian . new , post . topic_id ) . count . should == 1
2013-06-05 16:10:26 +10:00
TopicLink . counts_for ( Guardian . new , post . topic , [ post ] ) . length . should == 1
2013-07-14 11:24:16 +10:00
category . set_permissions ( :staff = > :full )
2013-06-05 16:10:26 +10:00
category . save
admin = Fabricate ( :admin )
2013-11-15 12:15:46 -05:00
TopicLink . topic_map ( Guardian . new , post . topic_id ) . count . should == 0
TopicLink . topic_map ( Guardian . new ( admin ) , post . topic_id ) . count . should == 1
2013-06-05 16:10:26 +10:00
TopicLink . counts_for ( Guardian . new , post . topic , [ post ] ) . length . should == 0
TopicLink . counts_for ( Guardian . new ( admin ) , post . topic , [ post ] ) . length . should == 1
end
end
end
2013-02-05 14:16:51 -05:00
end