2013-02-06 03:16:51 +08:00
require 'spec_helper'
2013-03-19 05:52:29 +08:00
require_dependency 'post_destroyer'
2013-02-06 03:16:51 +08:00
describe Post do
2013-06-19 15:19:42 +08:00
before { Oneboxer . stubs :onebox }
2013-05-11 04:58:23 +08:00
# Help us build a post with a raw body
def post_with_body ( body , user = nil )
args = post_args . merge ( raw : body )
args [ :user ] = user if user . present?
Fabricate . build ( :post , args )
end
2013-02-06 03:16:51 +08:00
it { should validate_presence_of :raw }
# Min/max body lengths, respecting padding
it { should_not allow_value ( " x " ) . for ( :raw ) }
it { should_not allow_value ( " x " * ( SiteSetting . max_post_length + 1 ) ) . for ( :raw ) }
it { should_not allow_value ( ( " " * SiteSetting . min_post_length ) + " x " ) . for ( :raw ) }
it { should rate_limit }
let ( :topic ) { Fabricate ( :topic ) }
let ( :post_args ) do
2013-12-12 10:41:34 +08:00
{ user : topic . user , topic : topic }
2013-02-06 03:16:51 +08:00
end
2013-02-22 02:20:00 +08:00
describe 'scopes' do
describe '#by_newest' do
it 'returns posts ordered by created_at desc' do
2013-08-21 03:45:58 +08:00
2 . times do | t |
Fabricate ( :post , created_at : t . seconds . from_now )
end
2013-02-22 02:20:00 +08:00
Post . by_newest . first . created_at . should > Post . by_newest . last . created_at
end
end
describe '#with_user' do
it 'gives you a user' do
2013-06-25 22:15:41 +08:00
Fabricate ( :post , user : Fabricate . build ( :user ) )
2013-02-22 02:20:00 +08:00
Post . with_user . first . user . should be_a User
end
end
end
2013-12-12 10:41:34 +08:00
describe " revisions and deleting/recovery " do
2013-03-14 00:35:55 +08:00
2013-06-14 01:41:45 +08:00
context 'a post without links' do
let ( :post ) { Fabricate ( :post , post_args ) }
before do
post . trash!
post . reload
end
2013-03-14 00:35:55 +08:00
2013-12-12 10:41:34 +08:00
it " doesn't create a new revision when deleted " do
post . revisions . count . should == 0
2013-06-14 01:41:45 +08:00
end
describe " recovery " do
before do
post . recover!
post . reload
end
2013-12-12 10:41:34 +08:00
it " doesn't create a new revision when recovered " do
post . revisions . count . should == 0
2013-06-14 01:41:45 +08:00
end
end
2013-03-14 00:35:55 +08:00
end
2013-06-14 01:41:45 +08:00
context 'a post with links' do
let ( :post ) { Fabricate ( :post_with_external_links ) }
2013-03-14 00:35:55 +08:00
before do
2013-06-14 01:41:45 +08:00
post . trash!
2013-03-14 00:35:55 +08:00
post . reload
end
2013-06-14 01:41:45 +08:00
describe 'recovery' do
it 'recreates the topic_link records' do
TopicLink . expects ( :extract_from ) . with ( post )
post . recover!
end
2013-03-14 00:35:55 +08:00
end
end
end
2013-02-26 00:42:20 +08:00
describe 'flagging helpers' do
it 'isFlagged is accurate' do
2013-02-07 12:15:48 +08:00
post = Fabricate ( :post )
user = Fabricate ( :coding_horror )
2013-03-01 20:07:44 +08:00
PostAction . act ( user , post , PostActionType . types [ :off_topic ] )
2013-02-07 12:15:48 +08:00
2013-02-26 00:42:20 +08:00
post . reload
2013-02-07 12:15:48 +08:00
post . is_flagged? . should == true
2013-02-26 00:42:20 +08:00
2013-03-01 20:07:44 +08:00
PostAction . remove_act ( user , post , PostActionType . types [ :off_topic ] )
2013-02-26 00:42:20 +08:00
post . reload
2013-02-07 12:15:48 +08:00
post . is_flagged? . should == false
end
end
2013-02-06 03:16:51 +08:00
describe " maximum images " do
2013-04-18 07:11:13 +08:00
let ( :newuser ) { Fabricate ( :user , trust_level : TrustLevel . levels [ :newuser ] ) }
let ( :post_no_images ) { Fabricate . build ( :post , post_args . merge ( user : newuser ) ) }
2013-05-11 04:58:23 +08:00
let ( :post_one_image ) { post_with_body ( " ![sherlock](http://bbc.co.uk/sherlock.jpg) " , newuser ) }
let ( :post_two_images ) { post_with_body ( " <img src='http://discourse.org/logo.png'> <img src='http://bbc.co.uk/sherlock.jpg'> " , newuser ) }
let ( :post_with_avatars ) { post_with_body ( '<img alt="smiley" title=":smiley:" src="/assets/emoji/smiley.png" class="avatar"> <img alt="wink" title=":wink:" src="/assets/emoji/wink.png" class="avatar">' , newuser ) }
let ( :post_with_favicon ) { post_with_body ( '<img src="/assets/favicons/wikipedia.png" class="favicon">' , newuser ) }
let ( :post_with_thumbnail ) { post_with_body ( '<img src="/assets/emoji/smiley.png" class="thumbnail">' , newuser ) }
let ( :post_with_two_classy_images ) { post_with_body ( " <img src='http://discourse.org/logo.png' class='classy'> <img src='http://bbc.co.uk/sherlock.jpg' class='classy'> " , newuser ) }
2013-02-06 03:16:51 +08:00
it " returns 0 images for an empty post " do
Fabricate . build ( :post ) . image_count . should == 0
end
it " finds images from markdown " do
post_one_image . image_count . should == 1
end
it " finds images from HTML " do
post_two_images . image_count . should == 2
end
2013-02-12 15:43:48 +08:00
it " doesn't count avatars as images " do
post_with_avatars . image_count . should == 0
2013-02-06 03:16:51 +08:00
end
2013-04-12 00:36:45 +08:00
it " doesn't count favicons as images " do
post_with_favicon . image_count . should == 0
end
it " doesn't count thumbnails as images " do
post_with_thumbnail . image_count . should == 0
end
2013-02-12 15:43:48 +08:00
it " doesn't count whitelisted images " do
2013-02-26 00:42:20 +08:00
Post . stubs ( :white_listed_image_classes ) . returns ( [ " classy " ] )
2013-02-12 15:43:48 +08:00
post_with_two_classy_images . image_count . should == 0
end
2013-02-06 03:16:51 +08:00
context " validation " do
2013-03-26 00:24:46 +08:00
before do
2013-04-18 07:11:13 +08:00
SiteSetting . stubs ( :newuser_max_images ) . returns ( 1 )
2013-02-06 03:16:51 +08:00
end
2013-04-18 07:11:13 +08:00
context 'newuser' do
it " allows a new user to post below the limit " do
2013-03-26 00:24:46 +08:00
post_one_image . should be_valid
end
it " doesn't allow more than the maximum " do
post_two_images . should_not be_valid
end
2013-04-18 07:11:13 +08:00
it " doesn't allow a new user to edit their post to insert an image " do
2013-03-26 00:24:46 +08:00
post_no_images . user . trust_level = TrustLevel . levels [ :new ]
post_no_images . save
- > {
post_no_images . revise ( post_no_images . user , post_two_images . raw )
post_no_images . reload
} . should_not change ( post_no_images , :raw )
end
2013-02-06 03:16:51 +08:00
end
2013-04-18 07:11:13 +08:00
it " allows more images from a not-new account " do
2013-03-26 00:24:46 +08:00
post_two_images . user . trust_level = TrustLevel . levels [ :basic ]
post_two_images . should be_valid
2013-02-06 03:16:51 +08:00
end
end
end
2013-07-22 08:39:17 +08:00
describe " maximum attachments " do
let ( :newuser ) { Fabricate ( :user , trust_level : TrustLevel . levels [ :newuser ] ) }
let ( :post_no_attachments ) { Fabricate . build ( :post , post_args . merge ( user : newuser ) ) }
let ( :post_one_attachment ) { post_with_body ( '<a class="attachment" href="/uploads/default/1/2082985.txt">file.txt</a>' , newuser ) }
let ( :post_two_attachments ) { post_with_body ( '<a class="attachment" href="/uploads/default/2/20947092.log">errors.log</a> <a class="attachment" href="/uploads/default/3/283572385.3ds">model.3ds</a>' , newuser ) }
it " returns 0 attachments for an empty post " do
Fabricate . build ( :post ) . attachment_count . should == 0
end
it " finds attachments from HTML " do
post_two_attachments . attachment_count . should == 2
end
context " validation " do
before do
SiteSetting . stubs ( :newuser_max_attachments ) . returns ( 1 )
end
context 'newuser' do
it " allows a new user to post below the limit " do
post_one_attachment . should be_valid
end
it " doesn't allow more than the maximum " do
post_two_attachments . should_not be_valid
end
it " doesn't allow a new user to edit their post to insert an attachment " do
post_no_attachments . user . trust_level = TrustLevel . levels [ :new ]
post_no_attachments . save
- > {
post_no_attachments . revise ( post_no_attachments . user , post_two_attachments . raw )
post_no_attachments . reload
} . should_not change ( post_no_attachments , :raw )
end
end
it " allows more attachments from a not-new account " do
post_two_attachments . user . trust_level = TrustLevel . levels [ :basic ]
post_two_attachments . should be_valid
end
end
end
2013-05-11 04:58:23 +08:00
context " links " do
let ( :newuser ) { Fabricate ( :user , trust_level : TrustLevel . levels [ :newuser ] ) }
let ( :no_links ) { post_with_body ( " hello world my name is evil trout " , newuser ) }
let ( :one_link ) { post_with_body ( " [jlawr](http://www.imdb.com/name/nm2225369) " , newuser ) }
let ( :two_links ) { post_with_body ( " <a href='http://disneyland.disney.go.com/'>disney</a> <a href='http://reddit.com'>reddit</a> " , newuser ) }
let ( :three_links ) { post_with_body ( " http://discourse.org and http://discourse.org/another_url and http://www.imdb.com/name/nm2225369 " , newuser ) }
describe " raw_links " do
it " returns a blank collection for a post with no links " do
no_links . raw_links . should be_blank
end
it " finds a link within markdown " do
one_link . raw_links . should == [ " http://www.imdb.com/name/nm2225369 " ]
end
it " can find two links from html " do
two_links . raw_links . should == [ " http://disneyland.disney.go.com/ " , " http://reddit.com " ]
end
it " can find three links without markup " do
three_links . raw_links . should == [ " http://discourse.org " , " http://discourse.org/another_url " , " http://www.imdb.com/name/nm2225369 " ]
end
end
describe " linked_hosts " do
it " returns blank with no links " do
no_links . linked_hosts . should be_blank
end
it " returns the host and a count for links " do
two_links . linked_hosts . should == { " disneyland.disney.go.com " = > 1 , " reddit.com " = > 1 }
end
it " it counts properly with more than one link on the same host " do
2013-05-25 03:20:58 +08:00
three_links . linked_hosts . should == { " discourse.org " = > 1 , " www.imdb.com " = > 1 }
2013-05-11 04:58:23 +08:00
end
end
describe " total host usage " do
it " has none for a regular post " do
no_links . total_hosts_usage . should be_blank
end
context " with a previous host " do
let ( :user ) { old_post . newuser }
let ( :another_disney_link ) { post_with_body ( " [radiator springs](http://disneyland.disney.go.com/disney-california-adventure/radiator-springs-racers/) " , newuser ) }
before do
another_disney_link . save
TopicLink . extract_from ( another_disney_link )
end
it " contains the new post's links, PLUS the previous one " do
two_links . total_hosts_usage . should == { 'disneyland.disney.go.com' = > 2 , 'reddit.com' = > 1 }
end
end
end
end
2013-02-06 03:16:51 +08:00
describe " maximum links " do
2013-04-18 07:11:13 +08:00
let ( :newuser ) { Fabricate ( :user , trust_level : TrustLevel . levels [ :newuser ] ) }
2013-05-11 04:58:23 +08:00
let ( :post_one_link ) { post_with_body ( " [sherlock](http://www.bbc.co.uk/programmes/b018ttws) " , newuser ) }
let ( :post_two_links ) { post_with_body ( " <a href='http://discourse.org'>discourse</a> <a href='http://twitter.com'>twitter</a> " , newuser ) }
let ( :post_with_mentions ) { post_with_body ( " hello @ #{ newuser . username } how are you doing? " , newuser ) }
2013-02-06 03:16:51 +08:00
2013-03-26 01:12:15 +08:00
it " returns 0 links for an empty post " do
2013-02-06 03:16:51 +08:00
Fabricate . build ( :post ) . link_count . should == 0
end
2013-03-26 01:12:15 +08:00
it " returns 0 links for a post with mentions " do
post_with_mentions . link_count . should == 0
end
it " finds links from markdown " do
2013-02-06 03:16:51 +08:00
post_one_link . link_count . should == 1
end
2013-03-26 01:12:15 +08:00
it " finds links from HTML " do
2013-02-06 03:16:51 +08:00
post_two_links . link_count . should == 2
end
context " validation " do
2013-03-26 00:24:46 +08:00
before do
2013-04-18 07:11:13 +08:00
SiteSetting . stubs ( :newuser_max_links ) . returns ( 1 )
2013-02-06 03:16:51 +08:00
end
2013-04-18 07:11:13 +08:00
context 'newuser' do
2013-03-26 00:24:46 +08:00
it " returns true when within the amount of links allowed " do
post_one_link . should be_valid
end
it " doesn't allow more links than allowed " do
post_two_links . should_not be_valid
end
2013-02-06 03:16:51 +08:00
end
it " allows multiple images for basic accounts " do
2013-03-01 20:07:44 +08:00
post_two_links . user . trust_level = TrustLevel . levels [ :basic ]
2013-02-06 03:16:51 +08:00
post_two_links . should be_valid
end
2013-03-26 00:24:46 +08:00
2013-02-06 03:16:51 +08:00
end
end
2013-03-26 00:24:46 +08:00
describe " @mentions " do
2013-02-06 03:16:51 +08:00
context 'raw_mentions' do
it " returns an empty array with no matches " do
post = Fabricate . build ( :post , post_args . merge ( raw : " Hello Jake and Finn! " ) )
post . raw_mentions . should == [ ]
end
it " returns lowercase unique versions of the mentions " do
post = Fabricate . build ( :post , post_args . merge ( raw : " @Jake @Finn @Jake " ) )
post . raw_mentions . should == [ 'jake' , 'finn' ]
end
it " ignores pre " do
post = Fabricate . build ( :post , post_args . merge ( raw : " <pre>@Jake</pre> @Finn " ) )
post . raw_mentions . should == [ 'finn' ]
end
it " catches content between pre tags " do
post = Fabricate . build ( :post , post_args . merge ( raw : " <pre>hello</pre> @Finn <pre></pre> " ) )
post . raw_mentions . should == [ 'finn' ]
end
it " ignores code " do
2013-09-12 03:52:37 +08:00
post = Fabricate . build ( :post , post_args . merge ( raw : " @Jake `@Finn` " ) )
2013-02-06 03:16:51 +08:00
post . raw_mentions . should == [ 'jake' ]
2013-02-26 00:42:20 +08:00
end
2013-02-06 03:16:51 +08:00
it " ignores quotes " do
post = Fabricate . build ( :post , post_args . merge ( raw : " [quote= \" Evil Trout \" ]@Jake[/quote] @Finn " ) )
post . raw_mentions . should == [ 'finn' ]
2013-02-26 00:42:20 +08:00
end
2013-02-06 03:16:51 +08:00
2013-03-24 08:57:00 +08:00
it " handles underscore in username " do
post = Fabricate . build ( :post , post_args . merge ( raw : " @Jake @Finn @Jake_Old " ) )
post . raw_mentions . should == [ 'jake' , 'finn' , 'jake_old' ]
end
2013-02-06 03:16:51 +08:00
end
2013-03-26 00:24:46 +08:00
context " max mentions " do
2013-04-18 07:11:13 +08:00
let ( :newuser ) { Fabricate ( :user , trust_level : TrustLevel . levels [ :newuser ] ) }
2013-05-11 04:58:23 +08:00
let ( :post_with_one_mention ) { post_with_body ( " @Jake is the person I'm mentioning " , newuser ) }
let ( :post_with_two_mentions ) { post_with_body ( " @Jake @Finn are the people I'm mentioning " , newuser ) }
2013-03-26 00:24:46 +08:00
2013-04-18 07:11:13 +08:00
context 'new user' do
2013-03-26 00:24:46 +08:00
before do
2013-04-18 07:11:13 +08:00
SiteSetting . stubs ( :newuser_max_mentions_per_post ) . returns ( 1 )
2013-03-26 00:24:46 +08:00
SiteSetting . stubs ( :max_mentions_per_post ) . returns ( 5 )
end
2013-04-18 07:11:13 +08:00
it " allows a new user to have newuser_max_mentions_per_post mentions " do
2013-03-26 00:24:46 +08:00
post_with_one_mention . should be_valid
end
2013-04-18 07:11:13 +08:00
it " doesn't allow a new user to have more than newuser_max_mentions_per_post mentions " do
2013-03-26 00:24:46 +08:00
post_with_two_mentions . should_not be_valid
end
2013-02-06 03:16:51 +08:00
end
2013-04-18 07:11:13 +08:00
context " not a new user " do
2013-03-26 00:24:46 +08:00
before do
2013-04-18 07:11:13 +08:00
SiteSetting . stubs ( :newuser_max_mentions_per_post ) . returns ( 0 )
2013-03-26 00:24:46 +08:00
SiteSetting . stubs ( :max_mentions_per_post ) . returns ( 1 )
end
it " allows vmax_mentions_per_post mentions " do
post_with_one_mention . user . trust_level = TrustLevel . levels [ :basic ]
post_with_one_mention . should be_valid
end
it " doesn't allow to have more than max_mentions_per_post mentions " do
post_with_two_mentions . user . trust_level = TrustLevel . levels [ :basic ]
post_with_two_mentions . should_not be_valid
end
2013-02-06 03:16:51 +08:00
end
2013-03-26 00:24:46 +08:00
2013-02-06 03:16:51 +08:00
end
end
2013-06-13 16:18:17 +08:00
context 'validation' do
it 'validates our default post' do
Fabricate . build ( :post , post_args ) . should be_valid
end
it 'treate blank posts as invalid' do
Fabricate . build ( :post , raw : " " ) . should_not be_valid
end
2013-02-06 03:16:51 +08:00
end
context " raw_hash " do
let ( :raw ) { " this is our test post body " }
2013-05-11 04:58:23 +08:00
let ( :post ) { post_with_body ( raw ) }
2013-02-26 00:42:20 +08:00
2013-02-06 03:16:51 +08:00
it " returns a value " do
post . raw_hash . should be_present
end
it " returns blank for a nil body " do
post . raw = nil
post . raw_hash . should be_blank
end
it " returns the same value for the same raw " do
2013-05-11 04:58:23 +08:00
post . raw_hash . should == post_with_body ( raw ) . raw_hash
2013-02-06 03:16:51 +08:00
end
it " returns a different value for a different raw " do
2013-05-11 04:58:23 +08:00
post . raw_hash . should_not == post_with_body ( " something else " ) . raw_hash
2013-02-06 03:16:51 +08:00
end
2013-06-18 03:57:13 +08:00
it " returns a different value with different text case " do
post . raw_hash . should_not == post_with_body ( " THIS is OUR TEST post BODy " ) . raw_hash
2013-02-06 03:16:51 +08:00
end
end
context 'revise' do
let ( :post ) { Fabricate ( :post , post_args ) }
let ( :first_version_at ) { post . last_version_at }
2013-12-12 10:41:34 +08:00
it 'has no revision' do
post . revisions . size . should == 0
2013-02-06 03:16:51 +08:00
first_version_at . should be_present
2013-04-22 15:45:03 +08:00
post . revise ( post . user , post . raw ) . should be_false
2013-02-06 03:16:51 +08:00
end
2013-04-22 15:45:03 +08:00
describe 'with the same body' do
2013-12-12 10:41:34 +08:00
it " doesn't change version " do
lambda { post . revise ( post . user , post . raw ) ; post . reload } . should_not change ( post , :version )
2013-02-06 03:16:51 +08:00
end
end
describe 'ninja editing' do
before do
SiteSetting . expects ( :ninja_edit_window ) . returns ( 1 . minute . to_i )
post . revise ( post . user , 'updated body' , revised_at : post . updated_at + 10 . seconds )
post . reload
end
2013-04-30 20:54:30 +08:00
it 'causes no update' do
2013-12-12 10:41:34 +08:00
post . version . should == 1
post . revisions . size . should == 0
2013-02-06 03:16:51 +08:00
post . last_version_at . should == first_version_at
end
2013-04-30 20:54:30 +08:00
2013-02-06 03:16:51 +08:00
end
describe 'revision much later' do
let! ( :revised_at ) { post . updated_at + 2 . minutes }
before do
SiteSetting . stubs ( :ninja_edit_window ) . returns ( 1 . minute . to_i )
post . revise ( post . user , 'updated body' , revised_at : revised_at )
post . reload
end
2013-12-12 10:41:34 +08:00
it 'updates the version' do
post . version . should == 2
post . revisions . size . should == 1
2013-02-06 03:16:51 +08:00
post . last_version_at . to_i . should == revised_at . to_i
end
describe " new edit window " do
before do
post . revise ( post . user , 'yet another updated body' , revised_at : revised_at )
post . reload
end
it " doesn't create a new version if you do another " do
2013-12-12 10:41:34 +08:00
post . version . should == 2
2013-02-06 03:16:51 +08:00
end
it " doesn't change last_version_at " do
2013-02-26 00:42:20 +08:00
post . last_version_at . to_i . should == revised_at . to_i
2013-02-06 03:16:51 +08:00
end
context " after second window " do
let! ( :new_revised_at ) { revised_at + 2 . minutes }
before do
post . revise ( post . user , 'yet another, another updated body' , revised_at : new_revised_at )
post . reload
end
it " does create a new version after the edit window " do
2013-12-12 10:41:34 +08:00
post . version . should == 3
2013-02-06 03:16:51 +08:00
end
it " does create a new version after the edit window " do
post . last_version_at . to_i . should == new_revised_at . to_i
end
end
end
end
describe 'rate limiter' do
let ( :changed_by ) { Fabricate ( :coding_horror ) }
2013-02-26 00:42:20 +08:00
2013-02-06 03:16:51 +08:00
it " triggers a rate limiter " do
2013-02-09 23:33:07 +08:00
EditRateLimiter . any_instance . expects ( :performed! )
2013-02-06 03:16:51 +08:00
post . revise ( changed_by , 'updated body' )
end
end
describe 'with a new body' do
let ( :changed_by ) { Fabricate ( :coding_horror ) }
let! ( :result ) { post . revise ( changed_by , 'updated body' ) }
2013-04-22 15:45:03 +08:00
it 'acts correctly' do
2013-02-06 03:16:51 +08:00
result . should be_true
post . raw . should == 'updated body'
post . invalidate_oneboxes . should == true
2013-12-12 10:41:34 +08:00
post . version . should == 2
post . revisions . size . should == 1
post . revisions . first . user . should be_present
2013-02-06 03:16:51 +08:00
end
context 'second poster posts again quickly' do
before do
SiteSetting . expects ( :ninja_edit_window ) . returns ( 1 . minute . to_i )
post . revise ( changed_by , 'yet another updated body' , revised_at : post . updated_at + 10 . seconds )
post . reload
end
it 'is a ninja edit, because the second poster posted again quickly' do
2013-12-12 10:41:34 +08:00
post . version . should == 2
post . revisions . size . should == 1
2013-02-26 00:42:20 +08:00
end
2013-02-06 03:16:51 +08:00
end
end
end
describe 'after save' do
let ( :post ) { Fabricate ( :post , post_args ) }
2013-04-22 15:45:03 +08:00
it " has correct info set " do
2013-02-08 04:12:55 +08:00
post . user_deleted? . should be_false
2013-02-06 03:16:51 +08:00
post . post_number . should be_present
post . excerpt . should be_present
2013-03-19 04:03:46 +08:00
post . post_type . should == Post . types [ :regular ]
2013-12-12 10:41:34 +08:00
post . revisions . should be_blank
2013-02-06 03:16:51 +08:00
post . cooked . should be_present
2013-02-26 00:42:20 +08:00
post . external_id . should be_present
2013-02-06 03:16:51 +08:00
post . quote_count . should == 0
post . replies . should be_blank
end
2013-03-19 03:54:08 +08:00
describe 'extract_quoted_post_numbers' do
2013-02-06 03:16:51 +08:00
let! ( :post ) { Fabricate ( :post , post_args ) }
let ( :reply ) { Fabricate . build ( :post , post_args ) }
it " finds the quote when in the same topic " do
reply . raw = " [quote= \" EvilTrout, post: #{ post . post_number } , topic: #{ post . topic_id } \" ]hello[/quote] "
reply . extract_quoted_post_numbers
reply . quoted_post_numbers . should == [ post . post_number ]
end
it " doesn't find the quote in a different topic " do
reply . raw = " [quote= \" EvilTrout, post: #{ post . post_number } , topic: #{ post . topic_id + 1 } \" ]hello[/quote] "
reply . extract_quoted_post_numbers
reply . quoted_post_numbers . should be_blank
end
end
describe 'a new reply' do
2013-03-19 03:54:08 +08:00
let ( :topic ) { Fabricate ( :topic ) }
let ( :other_user ) { Fabricate ( :coding_horror ) }
let ( :reply_text ) { " [quote= \" Evil Trout, post:1 \" ] \n hello \n [/quote] \n Hmmm! " }
let! ( :post ) { PostCreator . new ( topic . user , raw : Fabricate . build ( :post ) . raw , topic_id : topic . id ) . create }
let! ( :reply ) { PostCreator . new ( other_user , raw : reply_text , topic_id : topic . id , reply_to_post_number : post . post_number ) . create }
2013-02-06 03:16:51 +08:00
it 'has a quote' do
reply . quote_count . should == 1
end
it 'has a reply to the user of the original user' do
reply . reply_to_user . should == post . user
end
it 'increases the reply count of the parent' do
post . reload
post . reply_count . should == 1
end
it 'increases the reply count of the topic' do
topic . reload
topic . reply_count . should == 1
end
it 'is the child of the parent post' do
post . replies . should == [ reply ]
end
it " doesn't change the post count when you edit the reply " do
reply . raw = 'updated raw'
reply . save
post . reload
post . reply_count . should == 1
end
context 'a multi-quote reply' do
2013-03-19 03:54:08 +08:00
let! ( :multi_reply ) do
raw = " [quote= \" Evil Trout, post:1 \" ]post1 quote[/quote] \n Aha! \n [quote= \" Evil Trout, post:2 \" ]post2 quote[/quote] \n Neat-o "
PostCreator . new ( other_user , raw : raw , topic_id : topic . id , reply_to_post_number : post . post_number ) . create
end
2013-02-06 03:16:51 +08:00
2013-04-22 15:45:03 +08:00
it 'has the correct info set' do
2013-02-06 03:16:51 +08:00
multi_reply . quote_count . should == 2
post . replies . include? ( multi_reply ) . should be_true
reply . replies . include? ( multi_reply ) . should be_true
end
end
end
end
2013-11-19 01:48:26 +08:00
context 'summary' do
2013-03-23 03:43:57 +08:00
let! ( :p1 ) { Fabricate ( :post , post_args . merge ( score : 4 , percent_rank : 0 . 33 ) ) }
let! ( :p2 ) { Fabricate ( :post , post_args . merge ( score : 10 , percent_rank : 0 . 66 ) ) }
let! ( :p3 ) { Fabricate ( :post , post_args . merge ( score : 5 , percent_rank : 0 . 99 ) ) }
2013-02-06 03:16:51 +08:00
2013-11-19 01:48:26 +08:00
it " returns the OP and posts above the threshold in summary mode " do
SiteSetting . stubs ( :summary_percent_filter ) . returns ( 66 )
Post . summary . order ( :post_number ) . should == [ p1 , p2 ]
2013-02-06 03:16:51 +08:00
end
end
context 'sort_order' do
context 'regular topic' do
let! ( :p1 ) { Fabricate ( :post , post_args ) }
let! ( :p2 ) { Fabricate ( :post , post_args ) }
let! ( :p3 ) { Fabricate ( :post , post_args ) }
it 'defaults to created order' do
Post . regular_order . should == [ p1 , p2 , p3 ]
end
end
2013-08-07 05:42:36 +08:00
end
context " reply_history " do
let! ( :p1 ) { Fabricate ( :post , post_args ) }
let! ( :p2 ) { Fabricate ( :post , post_args . merge ( reply_to_post_number : p1 . post_number ) ) }
let! ( :p3 ) { Fabricate ( :post , post_args ) }
let! ( :p4 ) { Fabricate ( :post , post_args . merge ( reply_to_post_number : p2 . post_number ) ) }
it " returns the posts in reply to this post " do
p4 . reply_history . should == [ p1 , p2 ]
p3 . reply_history . should be_blank
p2 . reply_history . should == [ p1 ]
end
2013-02-06 03:16:51 +08:00
end
2013-04-22 15:45:03 +08:00
describe 'urls' do
2013-05-11 04:58:23 +08:00
it 'no-ops for empty list' do
2013-04-22 15:45:03 +08:00
Post . urls ( [ ] ) . should == { }
end
2013-05-11 04:58:23 +08:00
# integration test -> should move to centralized integration test
it 'finds urls for posts presented' do
2013-04-22 15:45:03 +08:00
p1 = Fabricate ( :post )
p2 = Fabricate ( :post )
Post . urls ( [ p1 . id , p2 . id ] ) . should == { p1 . id = > p1 . url , p2 . id = > p2 . url }
end
end
2013-10-15 22:21:30 +08:00
describe " details " do
it " adds details " do
post = Fabricate . build ( :post )
post . add_detail ( " key " , " value " )
post . post_details . size . should == 1
post . post_details . first . key . should == " key "
post . post_details . first . value . should == " value "
end
it " can find a post by a detail " do
detail = Fabricate ( :post_detail )
post = detail . post
Post . find_by_detail ( detail . key , detail . value ) . id . should == post . id
end
end
2014-01-16 00:34:17 +08:00
describe " cooking " do
let ( :post ) { Fabricate . build ( :post , post_args . merge ( raw : " please read my blog http://blog.example.com " ) ) }
it " should add nofollow to links in the post for trust levels below 3 " do
post . user . trust_level = 2
post . save
post . cooked . should =~ / nofollow /
end
2014-07-15 01:34:21 +08:00
it " when leader_links_no_follow is false, should not add nofollow for trust level 3 and higher " do
SiteSetting . stubs ( :leader_links_no_follow ) . returns ( false )
2014-01-16 00:34:17 +08:00
post . user . trust_level = 3
post . save
( post . cooked =~ / nofollow / ) . should be_false
end
2014-07-15 01:34:21 +08:00
it " when leader_links_no_follow is true, should add nofollow for trust level 3 and higher " do
SiteSetting . stubs ( :leader_links_no_follow ) . returns ( true )
post . user . trust_level = 3
post . save
( post . cooked =~ / nofollow / ) . should be_true
end
2014-01-16 00:34:17 +08:00
end
2014-02-27 08:45:20 +08:00
describe " calculate_avg_time " do
it " should not crash " do
Post . calculate_avg_time
Post . calculate_avg_time ( 1 . day . ago )
end
end
2014-02-27 12:43:45 +08:00
describe " has_host_spam " do
it " correctly detects host spam " do
2014-04-28 22:37:28 +08:00
post = Fabricate ( :post , raw : " hello from my site http://www.somesite.com http:// #{ GlobalSetting . hostname } http:// #{ RailsMultisite :: ConnectionManagement . current_hostname } " )
2014-02-27 12:43:45 +08:00
post . total_hosts_usage . should == { " www.somesite.com " = > 1 }
post . acting_user . trust_level = 0
post . has_host_spam? . should == false
2014-05-28 10:30:43 +08:00
SiteSetting . newuser_spam_host_threshold = 1
2014-02-27 12:43:45 +08:00
post . has_host_spam? . should == true
2014-05-28 10:30:43 +08:00
SiteSetting . white_listed_spam_host_domains = " bla.com|boo.com | somesite.com "
2014-02-27 12:43:45 +08:00
post . has_host_spam? . should == false
end
end
2014-04-25 21:14:05 +08:00
it " has custom fields " do
post = Fabricate ( :post )
post . custom_fields [ " a " ] . should == nil
post . custom_fields [ " Tommy " ] = " Hanks "
post . custom_fields [ " Vincent " ] = " Vega "
post . save
post = Post . find ( post . id )
post . custom_fields . should == { " Tommy " = > " Hanks " , " Vincent " = > " Vega " }
end
2014-05-28 10:30:43 +08:00
describe " # rebake! " do
it " will rebake a post correctly " do
post = create_post
post . baked_at . should_not == nil
first_baked = post . baked_at
first_cooked = post . cooked
Post . exec_sql ( " UPDATE posts SET cooked = 'frogs' WHERE id = ? " , post . id )
post . reload
result = post . rebake!
post . baked_at . should_not == first_baked
post . cooked . should == first_cooked
result . should == true
end
end
describe " .rebake_old " do
it " will catch posts it needs to rebake " do
post = create_post
2014-05-30 12:45:39 +08:00
post . update_columns ( baked_at : Time . new ( 2000 , 1 , 1 ) , baked_version : - 1 )
2014-05-28 10:30:43 +08:00
Post . rebake_old ( 100 )
post . reload
2014-05-30 12:45:39 +08:00
post . baked_at . should be > 1 . day . ago
baked = post . baked_at
Post . rebake_old ( 100 )
post . reload
post . baked_at . should == baked
2014-05-28 10:30:43 +08:00
end
end
2014-08-11 16:48:00 +08:00
describe " .unhide! " do
before { SiteSetting . stubs ( :unique_posts_mins ) . returns ( 5 ) }
it " will unhide the post " do
post = create_post ( user : Fabricate ( :newuser ) )
post . update_columns ( hidden : true , hidden_at : Time . now , hidden_reason_id : 1 )
post . reload
post . hidden . should == true
post . unhide!
post . reload
post . hidden . should == false
end
end
2013-02-06 03:16:51 +08:00
end