2013-02-06 15:47:36 -05:00
# encoding: UTF-8
2013-02-05 14:16:51 -05:00
require 'spec_helper'
2013-03-18 17:52:29 -04:00
require_dependency 'post_destroyer'
2013-02-05 14:16:51 -05:00
describe Topic do
2014-03-07 11:38:24 +01:00
let ( :now ) { Time . zone . local ( 2013 , 11 , 20 , 8 , 0 ) }
2013-02-05 14:16:51 -05:00
it { should validate_presence_of :title }
it { should rate_limit }
2013-02-14 17:13:03 -05:00
context 'slug' do
let ( :title ) { " hello world topic " }
let ( :slug ) { " hello-world-slug " }
it " returns a Slug for a title " do
Slug . expects ( :for ) . with ( title ) . returns ( slug )
Fabricate . build ( :topic , title : title ) . slug . should == slug
end
it " returns 'topic' when the slug is empty (say, non-english chars) " do
Slug . expects ( :for ) . with ( title ) . returns ( " " )
Fabricate . build ( :topic , title : title ) . slug . should == " topic "
end
end
2013-02-05 14:16:51 -05:00
2013-05-31 15:22:34 -04:00
context " updating a title to be shorter " do
let! ( :topic ) { Fabricate ( :topic ) }
it " doesn't update it to be shorter due to cleaning using TextCleaner " do
topic . title = 'unread glitch'
topic . save . should be_false
end
end
2013-06-04 17:58:25 -04:00
context 'private message title' do
before do
SiteSetting . stubs ( :min_topic_title_length ) . returns ( 15 )
SiteSetting . stubs ( :min_private_message_title_length ) . returns ( 3 )
end
it 'allows shorter titles' do
pm = Fabricate . build ( :private_message_topic , title : 'a' * SiteSetting . min_private_message_title_length )
expect ( pm ) . to be_valid
end
it 'but not too short' do
pm = Fabricate . build ( :private_message_topic , title : 'a' )
expect ( pm ) . to_not be_valid
end
end
2013-06-29 17:57:10 -04:00
context 'admin topic title' do
let ( :admin ) { Fabricate ( :admin ) }
it 'allows really short titles' do
pm = Fabricate . build ( :private_message_topic , user : admin , title : 'a' )
expect ( pm ) . to be_valid
end
it 'but not blank' do
pm = Fabricate . build ( :private_message_topic , title : '' )
expect ( pm ) . to_not be_valid
end
end
2013-02-05 14:16:51 -05:00
context 'topic title uniqueness' do
let! ( :topic ) { Fabricate ( :topic ) }
let ( :new_topic ) { Fabricate . build ( :topic , title : topic . title ) }
context " when duplicates aren't allowed " do
before do
SiteSetting . expects ( :allow_duplicate_topic_titles? ) . returns ( false )
end
it " won't allow another topic to be created with the same name " do
new_topic . should_not be_valid
end
it " won't allow another topic with an upper case title to be created " do
new_topic . title = new_topic . title . upcase
new_topic . should_not be_valid
end
it " allows it when the topic is deleted " do
topic . destroy
new_topic . should be_valid
end
it " allows a private message to be created with the same topic " do
new_topic . archetype = Archetype . private_message
new_topic . should be_valid
end
end
context " when duplicates are allowed " do
before do
SiteSetting . expects ( :allow_duplicate_topic_titles? ) . returns ( true )
end
2013-05-22 21:52:12 -07:00
it " will allow another topic to be created with the same name " do
2013-02-05 14:16:51 -05:00
new_topic . should be_valid
end
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
end
2013-02-19 16:08:23 -05:00
context 'html in title' do
2013-04-22 13:48:05 +10:00
def build_topic_with_title ( title )
2013-05-22 21:52:12 -07:00
build ( :topic , title : title ) . tap { | t | t . valid? }
2013-04-22 13:48:05 +10:00
end
let ( :topic_bold ) { build_topic_with_title ( " Topic with <b>bold</b> text in its title " ) }
let ( :topic_image ) { build_topic_with_title ( " Topic with <img src='something'> image in its title " ) }
let ( :topic_script ) { build_topic_with_title ( " Topic with <script>alert('title')</script> script in its title " ) }
2013-02-19 16:08:23 -05:00
2014-04-18 21:01:21 +02:00
context " title_sanitize disabled " do
before { SiteSetting . stubs ( :title_sanitize ) . returns ( false ) }
it " escapes script contents " do
topic_script . fancy_title . should == " Topic with <script>alert(‘title’)</script> script in its title "
end
it " escapes bold contents " do
topic_bold . fancy_title . should == " Topic with <b>bold</b> text in its title "
end
it " escapes image contents " do
topic_image . fancy_title . should == " Topic with <img src=‘something’> image in its title "
end
2013-03-06 11:36:42 -05:00
end
2014-04-18 21:01:21 +02:00
context " title_sanitize enabled " do
before { SiteSetting . stubs ( :title_sanitize ) . returns ( true ) }
it " removes script contents " do
topic_script . fancy_title . should == " Topic with script in its title "
end
it " removes bold contents " do
topic_bold . fancy_title . should == " Topic with bold text in its title "
end
it " removes image contents " do
topic_image . fancy_title . should == " Topic with image in its title "
end
2013-02-19 16:08:23 -05:00
end
end
context 'fancy title' do
2013-04-22 13:48:05 +10:00
let ( :topic ) { Fabricate . build ( :topic , title : " \" this topic \" -- has ``fancy stuff'' " ) }
2013-02-19 16:08:23 -05:00
context 'title_fancy_entities disabled' do
before do
SiteSetting . stubs ( :title_fancy_entities ) . returns ( false )
end
2014-04-18 10:18:38 +05:30
it " doesn't add entities to the title " do
topic . fancy_title . should == " "this topic" -- has ``fancy stuff& # 39;& # 39; "
2013-02-19 16:08:23 -05:00
end
end
context 'title_fancy_entities enabled' do
before do
SiteSetting . stubs ( :title_fancy_entities ) . returns ( true )
end
it " converts the title to have fancy entities " do
topic . fancy_title . should == " “this topic” – has “fancy stuff” "
end
end
end
2013-10-08 14:40:31 -04:00
context 'category validation' do
context 'allow_uncategorized_topics is false' do
before do
SiteSetting . stubs ( :allow_uncategorized_topics ) . returns ( false )
end
it " does not allow nil category " do
2013-10-24 10:05:51 +11:00
topic = Fabricate . build ( :topic , category : nil )
2013-10-08 14:40:31 -04:00
topic . should_not be_valid
topic . errors [ :category_id ] . should be_present
end
2013-10-25 09:33:18 +11:00
it " allows PMs " do
topic = Fabricate . build ( :topic , category : nil , archetype : Archetype . private_message )
topic . should be_valid
end
2013-10-08 14:40:31 -04:00
it 'passes for topics with a category' do
Fabricate . build ( :topic , category : Fabricate ( :category ) ) . should be_valid
end
end
context 'allow_uncategorized_topics is true' do
before do
SiteSetting . stubs ( :allow_uncategorized_topics ) . returns ( true )
end
it " passes for topics with nil category " do
Fabricate . build ( :topic , category : nil ) . should be_valid
end
it 'passes for topics with a category' do
Fabricate . build ( :topic , category : Fabricate ( :category ) ) . should be_valid
end
end
end
2013-02-05 14:16:51 -05:00
2013-03-14 14:45:29 -04:00
context 'similar_to' do
it 'returns blank with nil params' do
Topic . similar_to ( nil , nil ) . should be_blank
end
2014-04-14 15:20:41 -04:00
context " with a category definition " do
let! ( :category ) { Fabricate ( :category ) }
it " excludes the category definition topic from similar_to " do
Topic . similar_to ( 'category definition for' , " no body " ) . should be_blank
end
end
2013-03-14 14:45:29 -04:00
context 'with a similar topic' do
let! ( :topic ) { Fabricate ( :topic , title : " Evil trout is the dude who posted this topic " ) }
it 'returns the similar topic if the title is similar' do
Topic . similar_to ( " has evil trout made any topics? " , " i am wondering has evil trout made any topics? " ) . should == [ topic ]
end
2013-06-12 13:43:59 -04:00
context " secure categories " do
let ( :user ) { Fabricate ( :user ) }
2013-07-14 11:24:16 +10:00
let ( :category ) { Fabricate ( :category , read_restricted : true ) }
2013-06-12 13:43:59 -04:00
before do
topic . category = category
topic . save
end
it " doesn't return topics from private categories " do
expect ( Topic . similar_to ( " has evil trout made any topics? " , " i am wondering has evil trout made any topics? " , user ) ) . to be_blank
end
it " should return the cat since the user can see it " do
Guardian . any_instance . expects ( :secure_category_ids ) . returns ( [ category . id ] )
expect ( Topic . similar_to ( " has evil trout made any topics? " , " i am wondering has evil trout made any topics? " , user ) ) . to include ( topic )
end
end
2013-03-14 14:45:29 -04:00
end
end
2013-02-05 14:16:51 -05:00
context 'post_numbers' do
let! ( :topic ) { Fabricate ( :topic ) }
let! ( :p1 ) { Fabricate ( :post , topic : topic , user : topic . user ) }
let! ( :p2 ) { Fabricate ( :post , topic : topic , user : topic . user ) }
let! ( :p3 ) { Fabricate ( :post , topic : topic , user : topic . user ) }
it " returns the post numbers of the topic " do
topic . post_numbers . should == [ 1 , 2 , 3 ]
p2 . destroy
2013-04-22 13:48:05 +10:00
topic . reload
2013-02-05 14:16:51 -05:00
topic . post_numbers . should == [ 1 , 3 ]
end
end
2013-02-25 19:42:20 +03:00
context 'private message' do
2014-05-06 14:41:59 +01:00
let ( :coding_horror ) { User . find_by ( username : " CodingHorror " ) }
2013-02-05 14:16:51 -05:00
let ( :evil_trout ) { Fabricate ( :evil_trout ) }
2013-05-14 11:59:55 +10:00
let ( :topic ) { Fabricate ( :private_message_topic ) }
2013-02-05 14:16:51 -05:00
2013-04-22 13:48:05 +10:00
it " should integrate correctly " do
2013-02-05 14:16:51 -05:00
Guardian . new ( topic . user ) . can_see? ( topic ) . should be_true
Guardian . new . can_see? ( topic ) . should be_false
Guardian . new ( evil_trout ) . can_see? ( topic ) . should be_false
Guardian . new ( coding_horror ) . can_see? ( topic ) . should be_true
2013-03-27 16:17:49 -04:00
TopicQuery . new ( evil_trout ) . list_latest . topics . should_not include ( topic )
2013-04-22 13:48:05 +10:00
# invites
topic . invite ( topic . user , 'duhhhhh' ) . should be_false
2013-02-05 14:16:51 -05:00
end
context 'invite' do
it " delegates to topic.invite_by_email when the user doesn't exist, but it's an email " do
topic . expects ( :invite_by_email ) . with ( topic . user , 'jake@adventuretime.ooo' )
topic . invite ( topic . user , 'jake@adventuretime.ooo' )
end
context 'existing user' do
let ( :walter ) { Fabricate ( :walter_white ) }
context 'by username' do
2013-06-18 17:17:01 +10:00
it 'adds and removes walter to the allowed users' do
2013-05-14 11:59:55 +10:00
topic . invite ( topic . user , walter . username ) . should be_true
2013-02-05 14:16:51 -05:00
topic . allowed_users . include? ( walter ) . should be_true
2013-06-18 17:17:01 +10:00
topic . remove_allowed_user ( walter . username ) . should be_true
topic . reload
topic . allowed_users . include? ( walter ) . should be_false
2013-02-05 14:16:51 -05:00
end
it 'creates a notification' do
lambda { topic . invite ( topic . user , walter . username ) } . should change ( Notification , :count )
end
end
context 'by email' do
it 'returns true' do
topic . invite ( topic . user , walter . email ) . should be_true
end
it 'adds walter to the allowed users' do
topic . invite ( topic . user , walter . email )
topic . allowed_users . include? ( walter ) . should be_true
end
it 'creates a notification' do
lambda { topic . invite ( topic . user , walter . email ) } . should change ( Notification , :count )
end
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
end
end
2013-02-25 19:42:20 +03:00
context " user actions " do
2013-02-05 14:16:51 -05:00
let ( :actions ) { topic . user . user_actions }
2013-04-22 13:48:05 +10:00
it " should set up actions correctly " do
2013-05-14 11:59:55 +10:00
ActiveRecord :: Base . observers . enable :all
2013-02-05 14:16:51 -05:00
actions . map { | a | a . action_type } . should_not include ( UserAction :: NEW_TOPIC )
actions . map { | a | a . action_type } . should include ( UserAction :: NEW_PRIVATE_MESSAGE )
coding_horror . user_actions . map { | a | a . action_type } . should include ( UserAction :: GOT_PRIVATE_MESSAGE )
end
2013-04-22 13:48:05 +10:00
2013-02-05 14:16:51 -05:00
end
end
context 'bumping topics' do
before do
@topic = Fabricate ( :topic , bumped_at : 1 . year . ago )
end
it 'updates the bumped_at field when a new post is made' do
2013-04-22 13:48:05 +10:00
@topic . bumped_at . should be_present
2013-02-05 14:16:51 -05:00
lambda {
2013-07-22 15:06:53 +10:00
create_post ( topic : @topic , user : @topic . user )
2013-02-05 14:16:51 -05:00
@topic . reload
} . should change ( @topic , :bumped_at )
end
context 'editing posts' do
before do
@earlier_post = Fabricate ( :post , topic : @topic , user : @topic . user )
@last_post = Fabricate ( :post , topic : @topic , user : @topic . user )
@topic . reload
end
it " doesn't bump the topic on an edit to the last post that doesn't result in a new version " do
lambda {
SiteSetting . expects ( :ninja_edit_window ) . returns ( 5 . minutes )
@last_post . revise ( @last_post . user , 'updated contents' , revised_at : @last_post . created_at + 10 . seconds )
@topic . reload
} . should_not change ( @topic , :bumped_at )
end
it " bumps the topic when a new version is made of the last post " do
lambda {
@last_post . revise ( Fabricate ( :moderator ) , 'updated contents' )
@topic . reload
} . should change ( @topic , :bumped_at )
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
it " doesn't bump the topic when a post that isn't the last post receives a new version " do
lambda {
@earlier_post . revise ( Fabricate ( :moderator ) , 'updated contents' )
@topic . reload
} . should_not change ( @topic , :bumped_at )
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
end
end
context 'moderator posts' do
before do
@moderator = Fabricate ( :moderator )
@topic = Fabricate ( :topic )
@mod_post = @topic . add_moderator_post ( @moderator , " Moderator did something. http://discourse.org " , post_number : 999 )
end
it 'creates a moderator post' do
2013-02-25 19:42:20 +03:00
@mod_post . should be_present
2013-03-18 16:03:46 -04:00
@mod_post . post_type . should == Post . types [ :moderator_action ]
2013-02-05 14:16:51 -05:00
@mod_post . post_number . should == 999
@mod_post . sort_order . should == 999
@topic . topic_links . count . should == 1
2013-04-22 13:48:05 +10:00
@topic . reload
@topic . moderator_posts_count . should == 1
2013-02-05 14:16:51 -05:00
end
end
context 'update_status' do
before do
@topic = Fabricate ( :topic , bumped_at : 1 . hour . ago )
@topic . reload
@original_bumped_at = @topic . bumped_at . to_f
@user = @topic . user
2013-03-29 02:38:54 -04:00
@user . admin = true
2013-02-05 14:16:51 -05:00
end
context 'visibility' do
context 'disable' do
2013-02-25 19:42:20 +03:00
before do
2013-02-05 14:16:51 -05:00
@topic . update_status ( 'visible' , false , @user )
@topic . reload
end
2013-04-22 13:48:05 +10:00
it 'should not be visible and have correct counts' do
2013-02-25 19:42:20 +03:00
@topic . should_not be_visible
2013-02-05 14:16:51 -05:00
@topic . moderator_posts_count . should == 1
@topic . bumped_at . to_f . should == @original_bumped_at
end
end
context 'enable' do
before do
@topic . update_attribute :visible , false
@topic . update_status ( 'visible' , true , @user )
@topic . reload
end
2013-04-22 13:48:05 +10:00
it 'should be visible with correct counts' do
2013-02-25 19:42:20 +03:00
@topic . should be_visible
2013-02-05 14:16:51 -05:00
@topic . moderator_posts_count . should == 1
@topic . bumped_at . to_f . should == @original_bumped_at
2013-02-25 19:42:20 +03:00
end
end
2013-02-05 14:16:51 -05:00
end
context 'pinned' do
context 'disable' do
before do
@topic . update_status ( 'pinned' , false , @user )
@topic . reload
end
2013-04-22 13:48:05 +10:00
it " doesn't have a pinned_at but has correct dates " do
2013-03-06 15:17:07 -05:00
@topic . pinned_at . should be_blank
2013-02-05 14:16:51 -05:00
@topic . moderator_posts_count . should == 1
@topic . bumped_at . to_f . should == @original_bumped_at
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
end
context 'enable' do
before do
2013-03-06 15:17:07 -05:00
@topic . update_attribute :pinned_at , nil
2013-02-05 14:16:51 -05:00
@topic . update_status ( 'pinned' , true , @user )
@topic . reload
end
2013-04-22 13:48:05 +10:00
it 'should enable correctly' do
2013-03-06 15:17:07 -05:00
@topic . pinned_at . should be_present
2013-04-22 13:48:05 +10:00
@topic . bumped_at . to_f . should == @original_bumped_at
2013-02-05 14:16:51 -05:00
@topic . moderator_posts_count . should == 1
end
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
end
context 'archived' do
context 'disable' do
before do
@topic . update_status ( 'archived' , false , @user )
@topic . reload
end
2013-04-22 13:48:05 +10:00
it 'should archive correctly' do
2013-02-25 19:42:20 +03:00
@topic . should_not be_archived
2013-02-05 14:16:51 -05:00
@topic . bumped_at . to_f . should == @original_bumped_at
2013-04-22 13:48:05 +10:00
@topic . moderator_posts_count . should == 1
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
end
context 'enable' do
before do
@topic . update_attribute :archived , false
@topic . update_status ( 'archived' , true , @user )
@topic . reload
end
it 'should be archived' do
2013-02-25 19:42:20 +03:00
@topic . should be_archived
2013-02-05 14:16:51 -05:00
@topic . moderator_posts_count . should == 1
@topic . bumped_at . to_f . should == @original_bumped_at
2013-02-25 19:42:20 +03:00
end
2013-04-22 13:48:05 +10:00
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
end
2013-05-07 14:25:41 -04:00
shared_examples_for 'a status that closes a topic' do
2013-02-05 14:16:51 -05:00
context 'disable' do
before do
2013-05-07 14:25:41 -04:00
@topic . update_status ( status , false , @user )
2013-02-05 14:16:51 -05:00
@topic . reload
end
it 'should not be pinned' do
@topic . should_not be_closed
@topic . moderator_posts_count . should == 1
@topic . bumped_at . to_f . should_not == @original_bumped_at
2013-02-25 19:42:20 +03:00
end
2013-02-05 14:16:51 -05:00
end
context 'enable' do
before do
@topic . update_attribute :closed , false
2013-05-07 14:25:41 -04:00
@topic . update_status ( status , true , @user )
2013-02-05 14:16:51 -05:00
@topic . reload
end
it 'should be closed' do
2013-02-25 19:42:20 +03:00
@topic . should be_closed
2013-02-05 14:16:51 -05:00
@topic . bumped_at . to_f . should == @original_bumped_at
2013-04-22 13:48:05 +10:00
@topic . moderator_posts_count . should == 1
2013-02-25 19:42:20 +03:00
end
end
2013-02-05 14:16:51 -05:00
end
2013-05-07 14:25:41 -04:00
context 'closed' do
let ( :status ) { 'closed' }
it_should_behave_like 'a status that closes a topic'
end
context 'autoclosed' do
let ( :status ) { 'autoclosed' }
it_should_behave_like 'a status that closes a topic'
2013-05-27 17:59:43 -07:00
2013-06-06 17:04:10 -04:00
context 'topic was set to close when it was created' do
it 'puts the autoclose duration in the moderator post' do
2014-03-10 10:11:54 +11:00
freeze_time ( Time . new ( 2000 , 1 , 1 ) ) do
@topic . created_at = 3 . days . ago
@topic . update_status ( status , true , @user )
expect ( @topic . posts . last . raw ) . to include " closed after 3 days "
end
2013-06-06 17:04:10 -04:00
end
end
2013-05-27 17:59:43 -07:00
2013-06-06 17:04:10 -04:00
context 'topic was set to close after it was created' do
it 'puts the autoclose duration in the moderator post' do
2014-03-10 10:11:54 +11:00
freeze_time ( Time . new ( 2000 , 1 , 1 ) ) do
@topic . created_at = 7 . days . ago
freeze_time ( 2 . days . ago ) do
@topic . set_auto_close ( 48 )
end
@topic . update_status ( status , true , @user )
expect ( @topic . posts . last . raw ) . to include " closed after 2 days "
2013-06-06 17:04:10 -04:00
end
end
2013-05-27 17:59:43 -07:00
end
2013-05-07 14:25:41 -04:00
end
2013-02-05 14:16:51 -05:00
end
describe 'toggle_star' do
2013-04-28 16:58:14 -04:00
shared_examples_for " adding a star to a topic " do
it 'triggers a forum topic user change with true' do
# otherwise no chance the mock will work
2013-10-10 10:32:03 +11:00
freeze_time
TopicUser . expects ( :change ) . with ( @user , @topic . id , starred : true , starred_at : DateTime . now , unstarred_at : nil )
@topic . toggle_star ( @user , true )
2013-04-28 16:58:14 -04:00
end
2013-02-05 14:16:51 -05:00
2013-04-28 16:58:14 -04:00
it 'increases the star_count of the forum topic' do
lambda {
@topic . toggle_star ( @user , true )
@topic . reload
} . should change ( @topic , :star_count ) . by ( 1 )
2013-02-05 14:16:51 -05:00
end
2013-04-28 16:58:14 -04:00
it 'triggers the rate limiter' do
2014-01-09 16:22:54 -05:00
Topic :: StarLimiter . any_instance . expects ( :performed! )
2013-02-25 19:42:20 +03:00
@topic . toggle_star ( @user , true )
2013-04-28 16:58:14 -04:00
end
2013-02-05 14:16:51 -05:00
end
2013-04-28 16:58:14 -04:00
before do
@topic = Fabricate ( :topic )
@user = @topic . user
2013-02-05 14:16:51 -05:00
end
2013-04-28 16:58:14 -04:00
it_should_behave_like " adding a star to a topic "
2013-02-05 14:16:51 -05:00
describe 'removing a star' do
before do
2013-02-25 19:42:20 +03:00
@topic . toggle_star ( @user , true )
@topic . reload
2013-02-05 14:16:51 -05:00
end
it 'rolls back the rate limiter' do
2014-01-09 16:22:54 -05:00
Topic :: StarLimiter . any_instance . expects ( :rollback! )
2013-02-05 14:16:51 -05:00
@topic . toggle_star ( @user , false )
end
it 'triggers a forum topic user change with false' do
2013-10-10 10:32:03 +11:00
freeze_time
TopicUser . expects ( :change ) . with ( @user , @topic . id , starred : false , unstarred_at : DateTime . now )
@topic . toggle_star ( @user , false )
2013-02-05 14:16:51 -05:00
end
it 'reduces the star_count' do
2013-02-25 19:42:20 +03:00
lambda {
@topic . toggle_star ( @user , false )
2013-02-05 14:16:51 -05:00
@topic . reload
2013-02-25 19:42:20 +03:00
} . should change ( @topic , :star_count ) . by ( - 1 )
2013-02-05 14:16:51 -05:00
end
2013-04-28 16:58:14 -04:00
describe 'and adding a star again' do
before do
@topic . toggle_star ( @user , false )
@topic . reload
end
it_should_behave_like " adding a star to a topic "
end
2013-02-05 14:16:51 -05:00
end
end
context 'last_poster info' do
before do
2013-07-22 15:06:53 +10:00
@post = create_post
@user = @post . user
2013-02-05 14:16:51 -05:00
@topic = @post . topic
end
it 'initially has the last_post_user_id of the OP' do
@topic . last_post_user_id . should == @user . id
end
context 'after a second post' do
before do
@second_user = Fabricate ( :coding_horror )
2013-07-22 15:06:53 +10:00
@new_post = create_post ( topic : @topic , user : @second_user )
2013-02-05 14:16:51 -05:00
@topic . reload
end
it 'updates the last_post_user_id to the second_user' do
@topic . last_post_user_id . should == @second_user . id
@topic . last_posted_at . to_i . should == @new_post . created_at . to_i
2014-05-06 14:41:59 +01:00
topic_user = @second_user . topic_users . find_by ( topic_id : @topic . id )
2013-02-05 14:16:51 -05:00
topic_user . posted? . should be_true
end
2013-04-22 13:48:05 +10:00
end
2013-02-05 14:16:51 -05:00
end
describe 'with category' do
before do
@category = Fabricate ( :category )
end
it " should not increase the topic_count with no category " do
lambda { Fabricate ( :topic , user : @category . user ) ; @category . reload } . should_not change ( @category , :topic_count )
end
it " should increase the category's topic_count " do
lambda { Fabricate ( :topic , user : @category . user , category_id : @category . id ) ; @category . reload } . should change ( @category , :topic_count ) . by ( 1 )
end
end
describe 'meta data' do
2013-07-23 20:42:52 +02:00
let ( :topic ) { Fabricate ( :topic , meta_data : { 'hello' = > 'world' } ) }
2013-02-05 14:16:51 -05:00
it 'allows us to create a topic with meta data' do
topic . meta_data [ 'hello' ] . should == 'world'
end
context 'updating' do
context 'existing key' do
before do
2013-07-23 20:42:52 +02:00
topic . update_meta_data ( 'hello' = > 'bane' )
2013-02-05 14:16:51 -05:00
end
it 'updates the key' do
topic . meta_data [ 'hello' ] . should == 'bane'
end
end
context 'new key' do
before do
2013-07-23 20:42:52 +02:00
topic . update_meta_data ( 'city' = > 'gotham' )
2013-02-05 14:16:51 -05:00
end
it 'adds the new key' do
topic . meta_data [ 'city' ] . should == 'gotham'
topic . meta_data [ 'hello' ] . should == 'world'
end
end
2014-04-25 18:24:22 +02:00
context 'new key' do
before do
topic . update_meta_data ( 'other' = > 'key' )
topic . save!
end
it " can be loaded " do
Topic . find ( topic . id ) . meta_data [ " other " ] . should == " key "
end
it " is in sync with custom_fields " do
Topic . find ( topic . id ) . custom_fields [ " other " ] . should == " key "
end
end
2013-02-05 14:16:51 -05:00
end
end
describe 'after create' do
let ( :topic ) { Fabricate ( :topic ) }
it 'is a regular topic by default' do
topic . archetype . should == Archetype . default
2013-11-18 12:48:26 -05:00
topic . has_summary . should be_false
2013-03-28 13:02:59 -04:00
topic . percent_rank . should == 1 . 0
2013-02-05 14:16:51 -05:00
topic . should be_visible
2013-03-06 15:17:07 -05:00
topic . pinned_at . should be_blank
2013-02-05 14:16:51 -05:00
topic . should_not be_closed
topic . should_not be_archived
topic . moderator_posts_count . should == 0
end
2013-09-12 17:46:43 -04:00
it " its user has a topics_count of 1 " do
topic . user . created_topic_count . should == 1
end
2013-02-05 14:16:51 -05:00
context 'post' do
let ( :post ) { Fabricate ( :post , topic : topic , user : topic . user ) }
it 'has the same archetype as the topic' do
post . archetype . should == topic . archetype
end
end
end
2013-02-25 19:42:20 +03:00
2013-12-12 03:41:34 +01:00
describe 'revisions' do
2014-03-07 18:59:47 +11:00
let ( :post ) { Fabricate ( :post ) }
let ( :topic ) { post . topic }
2013-02-05 14:16:51 -05:00
2013-12-12 03:41:34 +01:00
it " has no revisions by default " do
2014-03-07 18:59:47 +11:00
post . revisions . size . should == 0
2013-02-05 14:16:51 -05:00
end
context 'changing title' do
2013-12-12 03:41:34 +01:00
2013-02-05 14:16:51 -05:00
before do
2013-02-06 20:09:31 -05:00
topic . title = " new title for the topic "
2013-02-05 14:16:51 -05:00
topic . save
end
2013-12-12 03:41:34 +01:00
it " creates a new revision " do
2014-03-07 18:59:47 +11:00
post . revisions . size . should == 1
2013-02-05 14:16:51 -05:00
end
2013-12-12 03:41:34 +01:00
2013-02-05 14:16:51 -05:00
end
context 'changing category' do
let ( :category ) { Fabricate ( :category ) }
before do
topic . change_category ( category . name )
end
2013-12-12 03:41:34 +01:00
it " creates a new revision " do
2014-03-07 18:59:47 +11:00
post . revisions . size . should == 1
2013-02-05 14:16:51 -05:00
end
context " removing a category " do
before do
topic . change_category ( nil )
end
2013-12-12 03:41:34 +01:00
it " creates a new revision " do
2014-03-07 18:59:47 +11:00
post . revisions . size . should == 2
last_rev = post . revisions . order ( :number ) . last
last_rev . previous ( " category_id " ) . should == category . id
last_rev . current ( " category_id " ) . should == SiteSetting . uncategorized_category_id
post . reload
post . version . should == 3
2013-02-05 14:16:51 -05:00
end
end
end
context 'bumping the topic' do
before do
topic . bumped_at = 10 . minutes . from_now
topic . save
end
2013-12-12 03:41:34 +01:00
it " doesn't create a new version " do
2014-03-07 18:59:47 +11:00
post . revisions . size . should == 0
2013-02-05 14:16:51 -05:00
end
end
end
describe 'change_category' do
before do
@topic = Fabricate ( :topic )
2013-02-25 19:42:20 +03:00
@category = Fabricate ( :category , user : @topic . user )
@user = @topic . user
2013-02-05 14:16:51 -05:00
end
describe 'without a previous category' do
it 'should not change the topic_count when not changed' do
2013-10-24 10:05:51 +11:00
lambda { @topic . change_category ( @topic . category . name ) ; @category . reload } . should_not change ( @category , :topic_count )
2013-02-05 14:16:51 -05:00
end
describe 'changed category' do
before do
@topic . change_category ( @category . name )
@category . reload
end
2013-02-25 19:42:20 +03:00
it 'changes the category' do
2013-02-05 14:16:51 -05:00
@topic . category . should == @category
@category . topic_count . should == 1
end
end
it " doesn't change the category when it can't be found " do
@topic . change_category ( 'made up' )
2013-10-24 10:05:51 +11:00
@topic . category_id . should == SiteSetting . uncategorized_category_id
2013-02-05 14:16:51 -05:00
end
end
describe 'with a previous category' do
before do
@topic . change_category ( @category . name )
@topic . reload
@category . reload
end
it 'increases the topic_count' do
@category . topic_count . should == 1
end
it " doesn't change the topic_count when the value doesn't change " do
lambda { @topic . change_category ( @category . name ) ; @category . reload } . should_not change ( @category , :topic_count )
end
it " doesn't reset the category when given a name that doesn't exist " do
@topic . change_category ( 'made up' )
@topic . category_id . should be_present
end
describe 'to a different category' do
before do
@new_category = Fabricate ( :category , user : @user , name : '2nd category' )
@topic . change_category ( @new_category . name )
@topic . reload
@new_category . reload
@category . reload
end
it " should increase the new category's topic count " do
@new_category . topic_count . should == 1
end
it " should lower the original category's topic count " do
@category . topic_count . should == 0
end
2013-10-08 14:40:31 -04:00
end
context 'when allow_uncategorized_topics is false' do
before do
SiteSetting . stubs ( :allow_uncategorized_topics ) . returns ( false )
end
2013-02-25 19:42:20 +03:00
2013-10-08 14:40:31 -04:00
let! ( :topic ) { Fabricate ( :topic , category : Fabricate ( :category ) ) }
it 'returns false' do
topic . change_category ( '' ) . should eq ( false ) # don't use "be_false" here because it would also match nil
end
2013-02-05 14:16:51 -05:00
end
describe 'when the category exists' do
before do
@topic . change_category ( nil )
2013-02-25 19:42:20 +03:00
@category . reload
2013-02-05 14:16:51 -05:00
end
2013-02-25 19:42:20 +03:00
it " resets the category " do
2013-10-24 10:05:51 +11:00
@topic . category_id . should == SiteSetting . uncategorized_category_id
2013-02-05 14:16:51 -05:00
@category . topic_count . should == 0
end
end
end
end
2013-02-27 19:36:12 -08:00
describe 'scopes' do
describe '#by_most_recently_created' do
it 'returns topics ordered by created_at desc, id desc' do
now = Time . now
a = Fabricate ( :topic , created_at : now - 2 . minutes )
b = Fabricate ( :topic , created_at : now )
c = Fabricate ( :topic , created_at : now )
d = Fabricate ( :topic , created_at : now - 2 . minutes )
Topic . by_newest . should == [ c , b , d , a ]
end
end
2013-05-30 13:23:40 +02:00
describe '#created_since' do
it 'returns topics created after some date' do
now = Time . now
a = Fabricate ( :topic , created_at : now - 2 . minutes )
b = Fabricate ( :topic , created_at : now - 1 . minute )
c = Fabricate ( :topic , created_at : now )
d = Fabricate ( :topic , created_at : now + 1 . minute )
e = Fabricate ( :topic , created_at : now + 2 . minutes )
Topic . created_since ( now ) . should_not include a
Topic . created_since ( now ) . should_not include b
Topic . created_since ( now ) . should_not include c
Topic . created_since ( now ) . should include d
Topic . created_since ( now ) . should include e
end
end
describe '#visible' do
it 'returns topics set as visible' do
a = Fabricate ( :topic , visible : false )
b = Fabricate ( :topic , visible : true )
c = Fabricate ( :topic , visible : true )
Topic . visible . should_not include a
Topic . visible . should include b
Topic . visible . should include c
end
end
2013-02-27 19:36:12 -08:00
end
2013-05-07 14:25:41 -04:00
describe 'auto-close' do
context 'a new topic' do
context 'auto_close_at is set' do
it 'queues a job to close the topic' do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-12-06 16:39:35 -05:00
Jobs . expects ( :enqueue_at ) . with ( 7 . hours . from_now , :close_topic , all_of ( has_key ( :topic_id ) , has_key ( :user_id ) ) )
Fabricate ( :topic , auto_close_hours : 7 , user : Fabricate ( :admin ) )
2013-05-07 14:25:41 -04:00
end
end
it 'when auto_close_user_id is nil, it will use the topic creator as the topic closer' do
topic_creator = Fabricate ( :admin )
Jobs . expects ( :enqueue_at ) . with do | datetime , job_name , job_args |
job_args [ :user_id ] == topic_creator . id
end
2013-12-06 16:39:35 -05:00
Fabricate ( :topic , auto_close_hours : 7 , user : topic_creator )
2013-05-07 14:25:41 -04:00
end
it 'when auto_close_user_id is set, it will use it as the topic closer' do
topic_creator = Fabricate ( :admin )
topic_closer = Fabricate ( :user , admin : true )
Jobs . expects ( :enqueue_at ) . with do | datetime , job_name , job_args |
job_args [ :user_id ] == topic_closer . id
end
2013-12-06 16:39:35 -05:00
Fabricate ( :topic , auto_close_hours : 7 , auto_close_user : topic_closer , user : topic_creator )
2013-05-07 14:25:41 -04:00
end
2013-05-15 15:19:41 -04:00
it " ignores the category's default auto-close " do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-12-06 16:39:35 -05:00
Jobs . expects ( :enqueue_at ) . with ( 7 . hours . from_now , :close_topic , all_of ( has_key ( :topic_id ) , has_key ( :user_id ) ) )
Fabricate ( :topic , auto_close_hours : 7 , user : Fabricate ( :admin ) , category_id : Fabricate ( :category , auto_close_hours : 2 ) . id )
2013-06-06 17:04:10 -04:00
end
end
it 'sets the time when auto_close timer starts' do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-12-06 16:39:35 -05:00
topic = Fabricate ( :topic , auto_close_hours : 7 , user : Fabricate ( :admin ) )
2014-03-07 11:38:24 +01:00
expect ( topic . auto_close_started_at ) . to eq ( now )
2013-05-15 15:19:41 -04:00
end
end
2013-05-07 14:25:41 -04:00
end
end
context 'an existing topic' do
it 'when auto_close_at is set, it queues a job to close the topic' do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-05-07 14:25:41 -04:00
topic = Fabricate ( :topic )
Jobs . expects ( :enqueue_at ) . with ( 12 . hours . from_now , :close_topic , has_entries ( topic_id : topic . id , user_id : topic . user_id ) )
topic . auto_close_at = 12 . hours . from_now
topic . save . should be_true
end
end
it 'when auto_close_at and auto_closer_user_id are set, it queues a job to close the topic' do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-05-07 14:25:41 -04:00
topic = Fabricate ( :topic )
closer = Fabricate ( :admin )
Jobs . expects ( :enqueue_at ) . with ( 12 . hours . from_now , :close_topic , has_entries ( topic_id : topic . id , user_id : closer . id ) )
topic . auto_close_at = 12 . hours . from_now
topic . auto_close_user = closer
topic . save . should be_true
end
end
it 'when auto_close_at is removed, it cancels the job to close the topic' do
Jobs . stubs ( :enqueue_at ) . returns ( true )
topic = Fabricate ( :topic , auto_close_at : 1 . day . from_now )
Jobs . expects ( :cancel_scheduled_job ) . with ( :close_topic , { topic_id : topic . id } )
topic . auto_close_at = nil
topic . save . should be_true
topic . auto_close_user . should be_nil
end
it 'when auto_close_user is removed, it updates the job' do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-05-07 14:25:41 -04:00
Jobs . stubs ( :enqueue_at ) . with ( 1 . day . from_now , :close_topic , anything ) . returns ( true )
topic = Fabricate ( :topic , auto_close_at : 1 . day . from_now , auto_close_user : Fabricate ( :admin ) )
Jobs . expects ( :cancel_scheduled_job ) . with ( :close_topic , { topic_id : topic . id } )
Jobs . expects ( :enqueue_at ) . with ( 1 . day . from_now , :close_topic , has_entries ( topic_id : topic . id , user_id : topic . user_id ) )
topic . auto_close_user = nil
topic . save . should be_true
end
end
it 'when auto_close_at value is changed, it reschedules the job' do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-05-07 14:25:41 -04:00
Jobs . stubs ( :enqueue_at ) . returns ( true )
topic = Fabricate ( :topic , auto_close_at : 1 . day . from_now )
Jobs . expects ( :cancel_scheduled_job ) . with ( :close_topic , { topic_id : topic . id } )
Jobs . expects ( :enqueue_at ) . with ( 3 . days . from_now , :close_topic , has_entry ( topic_id : topic . id ) )
topic . auto_close_at = 3 . days . from_now
topic . save . should be_true
end
end
it 'when auto_close_user_id is changed, it updates the job' do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-05-07 14:25:41 -04:00
admin = Fabricate ( :admin )
Jobs . stubs ( :enqueue_at ) . returns ( true )
topic = Fabricate ( :topic , auto_close_at : 1 . day . from_now )
Jobs . expects ( :cancel_scheduled_job ) . with ( :close_topic , { topic_id : topic . id } )
Jobs . expects ( :enqueue_at ) . with ( 1 . day . from_now , :close_topic , has_entries ( topic_id : topic . id , user_id : admin . id ) )
topic . auto_close_user = admin
topic . save . should be_true
end
end
it 'when auto_close_at and auto_close_user_id are not changed, it should not schedule another CloseTopic job' do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-05-07 14:25:41 -04:00
Jobs . expects ( :enqueue_at ) . with ( 1 . day . from_now , :close_topic , has_key ( :topic_id ) ) . once . returns ( true )
Jobs . expects ( :cancel_scheduled_job ) . never
topic = Fabricate ( :topic , auto_close_at : 1 . day . from_now )
topic . title = 'A new title that is long enough'
topic . save . should be_true
end
end
2013-05-15 15:19:41 -04:00
it " ignores the category's default auto-close " do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-09-06 17:28:37 +10:00
mod = Fabricate ( :moderator )
# NOTE, only moderators can auto-close, if missing system user is used
2013-12-06 16:39:35 -05:00
topic = Fabricate ( :topic , category : Fabricate ( :category , auto_close_hours : 14 ) , user : mod )
2013-05-15 15:19:41 -04:00
Jobs . expects ( :enqueue_at ) . with ( 12 . hours . from_now , :close_topic , has_entries ( topic_id : topic . id , user_id : topic . user_id ) )
topic . auto_close_at = 12 . hours . from_now
2013-11-11 10:52:44 +11:00
topic . save
topic . reload
topic . closed . should == false
Timecop . freeze ( 24 . hours . from_now ) do
Topic . auto_close
topic . reload
topic . closed . should == true
end
2013-05-15 15:19:41 -04:00
end
end
2013-05-07 14:25:41 -04:00
end
end
2013-12-06 16:39:35 -05:00
describe " auto_close_hours= " do
2013-12-03 18:53:40 -05:00
subject ( :topic ) { Fabricate . build ( :topic ) }
it 'can take a number' do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-12-06 16:39:35 -05:00
topic . auto_close_hours = 2
topic . auto_close_at . should be_within_one_second_of ( 2 . hours . from_now )
2013-12-03 18:53:40 -05:00
end
end
it 'can take nil' do
2013-12-06 16:39:35 -05:00
topic . auto_close_hours = nil
2013-12-03 18:53:40 -05:00
topic . auto_close_at . should be_nil
end
end
2013-06-06 17:04:10 -04:00
describe 'set_auto_close' do
let ( :topic ) { Fabricate . build ( :topic ) }
2013-12-06 16:39:35 -05:00
let ( :closing_topic ) { Fabricate . build ( :topic , auto_close_hours : 5 ) }
2013-06-06 17:04:10 -04:00
let ( :admin ) { Fabricate . build ( :user , id : 123 ) }
before { Discourse . stubs ( :system_user ) . returns ( admin ) }
2013-11-26 19:06:20 -05:00
it 'can take a number of hours as an integer' do
2014-03-06 12:44:52 +01:00
Timecop . freeze ( now ) do
2013-11-26 19:06:20 -05:00
topic . set_auto_close ( 72 , admin )
2013-06-06 17:04:10 -04:00
expect ( topic . auto_close_at ) . to eq ( 3 . days . from_now )
end
end
2013-11-26 19:06:20 -05:00
it 'can take a number of hours as a string' do
2014-03-06 12:44:52 +01:00
Timecop . freeze ( now ) do
2013-11-26 19:06:20 -05:00
topic . set_auto_close ( '18' , admin )
expect ( topic . auto_close_at ) . to eq ( 18 . hours . from_now )
end
end
it " can take a time later in the day " do
2014-03-06 12:44:52 +01:00
Timecop . freeze ( now ) do
2013-11-26 19:06:20 -05:00
topic . set_auto_close ( '13:00' , admin )
topic . auto_close_at . should == Time . zone . local ( 2013 , 11 , 20 , 13 , 0 )
end
end
it " can take a time for the next day " do
2014-03-06 12:44:52 +01:00
Timecop . freeze ( now ) do
2013-11-26 19:06:20 -05:00
topic . set_auto_close ( '5:00' , admin )
topic . auto_close_at . should == Time . zone . local ( 2013 , 11 , 21 , 5 , 0 )
end
end
it " can take a timestamp for a future time " do
2014-03-06 12:44:52 +01:00
Timecop . freeze ( now ) do
2013-11-26 19:06:20 -05:00
topic . set_auto_close ( '2013-11-22 5:00' , admin )
topic . auto_close_at . should == Time . zone . local ( 2013 , 11 , 22 , 5 , 0 )
end
end
it " sets a validation error when given a timestamp in the past " do
2014-03-06 12:44:52 +01:00
Timecop . freeze ( now ) do
2013-11-26 19:06:20 -05:00
topic . set_auto_close ( '2013-11-19 5:00' , admin )
topic . auto_close_at . should == Time . zone . local ( 2013 , 11 , 19 , 5 , 0 )
topic . errors [ :auto_close_at ] . should be_present
end
end
it " can take a timestamp with timezone " do
2014-03-06 12:44:52 +01:00
Timecop . freeze ( now ) do
2013-11-26 19:06:20 -05:00
topic . set_auto_close ( '2013-11-25T01:35:00-08:00' , admin )
topic . auto_close_at . should == Time . utc ( 2013 , 11 , 25 , 9 , 35 )
end
end
2013-06-06 17:04:10 -04:00
it 'sets auto_close_user to given user if it is a staff user' do
topic . set_auto_close ( 3 , admin )
expect ( topic . auto_close_user_id ) . to eq ( admin . id )
end
it 'sets auto_close_user to system user if given user is not staff' do
topic . set_auto_close ( 3 , Fabricate . build ( :user , id : 444 ) )
expect ( topic . auto_close_user_id ) . to eq ( admin . id )
end
it 'sets auto_close_user to system_user if user is not given and topic creator is not staff' do
topic . set_auto_close ( 3 )
expect ( topic . auto_close_user_id ) . to eq ( admin . id )
end
it 'sets auto_close_user to topic creator if it is a staff user' do
staff_topic = Fabricate . build ( :topic , user : Fabricate . build ( :admin , id : 999 ) )
staff_topic . set_auto_close ( 3 )
expect ( staff_topic . auto_close_user_id ) . to eq ( 999 )
end
2013-11-26 19:06:20 -05:00
it 'clears auto_close_at if arg is nil' do
2013-06-06 17:04:10 -04:00
closing_topic . set_auto_close ( nil )
expect ( closing_topic . auto_close_at ) . to be_nil
end
2013-11-26 19:06:20 -05:00
it 'clears auto_close_started_at if arg is nil' do
2013-06-06 17:04:10 -04:00
closing_topic . set_auto_close ( nil )
expect ( closing_topic . auto_close_started_at ) . to be_nil
end
it 'updates auto_close_at if it was already set to close' do
2014-03-07 11:38:24 +01:00
Timecop . freeze ( now ) do
2013-11-26 19:06:20 -05:00
closing_topic . set_auto_close ( 48 )
expect ( closing_topic . auto_close_at ) . to eq ( 2 . days . from_now )
2013-06-06 17:04:10 -04:00
end
end
it 'does not update auto_close_started_at if it was already set to close' do
expect {
closing_topic . set_auto_close ( 14 )
} . to_not change ( closing_topic , :auto_close_started_at )
end
end
2013-11-06 15:05:06 -05:00
describe 'for_digest' do
let ( :user ) { Fabricate . build ( :user ) }
it " returns none when there are no topics " do
2014-04-17 16:42:40 -04:00
Topic . for_digest ( user , 1 . year . ago , top_order : true ) . should be_blank
2013-11-06 15:05:06 -05:00
end
it " doesn't return category topics " do
Fabricate ( :category )
2014-04-17 16:42:40 -04:00
Topic . for_digest ( user , 1 . year . ago , top_order : true ) . should be_blank
2013-11-06 15:05:06 -05:00
end
it " returns regular topics " do
topic = Fabricate ( :topic )
2014-04-17 16:42:40 -04:00
Topic . for_digest ( user , 1 . year . ago , top_order : true ) . should == [ topic ]
2013-11-06 15:05:06 -05:00
end
end
2013-06-08 23:52:06 +10:00
describe 'secured' do
it 'can remove secure groups' do
2013-07-14 11:24:16 +10:00
category = Fabricate ( :category , read_restricted : true )
2014-03-07 18:59:47 +11:00
Fabricate ( :topic , category : category )
2013-06-08 23:52:06 +10:00
Topic . secured ( Guardian . new ( nil ) ) . count . should == 0
Topic . secured ( Guardian . new ( Fabricate ( :admin ) ) ) . count . should == 2
# for_digest
Topic . for_digest ( Fabricate ( :user ) , 1 . year . ago ) . count . should == 0
2013-11-06 15:05:06 -05:00
Topic . for_digest ( Fabricate ( :admin ) , 1 . year . ago ) . count . should == 1
2013-06-08 23:52:06 +10:00
end
end
2013-05-19 23:04:53 -07:00
describe '#secure_category?' do
let ( :category ) { Category . new }
it " is true if the category is secure " do
2013-07-14 11:24:16 +10:00
category . stubs ( :read_restricted ) . returns ( true )
Topic . new ( :category = > category ) . should be_read_restricted_category
2013-05-19 23:04:53 -07:00
end
it " is false if the category is not secure " do
2013-07-14 11:24:16 +10:00
category . stubs ( :read_restricted ) . returns ( false )
Topic . new ( :category = > category ) . should_not be_read_restricted_category
2013-05-19 23:04:53 -07:00
end
it " is false if there is no category " do
2013-07-14 11:24:16 +10:00
Topic . new ( :category = > nil ) . should_not be_read_restricted_category
2013-05-19 23:04:53 -07:00
end
end
2013-07-08 15:23:20 -04:00
describe 'trash!' do
context " its category's topic count " do
2013-07-09 15:20:18 -04:00
let ( :moderator ) { Fabricate ( :moderator ) }
2013-07-08 15:23:20 -04:00
let ( :category ) { Fabricate ( :category ) }
it " subtracts 1 if topic is being deleted " do
topic = Fabricate ( :topic , category : category )
2013-07-09 15:20:18 -04:00
expect { topic . trash! ( moderator ) } . to change { category . reload . topic_count } . by ( - 1 )
2013-07-08 15:23:20 -04:00
end
it " doesn't subtract 1 if topic is already deleted " do
topic = Fabricate ( :topic , category : category , deleted_at : 1 . day . ago )
2013-07-09 15:20:18 -04:00
expect { topic . trash! ( moderator ) } . to_not change { category . reload . topic_count }
2013-07-08 15:23:20 -04:00
end
end
end
describe 'recover!' do
context " its category's topic count " do
let ( :category ) { Fabricate ( :category ) }
it " adds 1 if topic is deleted " do
topic = Fabricate ( :topic , category : category , deleted_at : 1 . day . ago )
expect { topic . recover! } . to change { category . reload . topic_count } . by ( 1 )
end
it " doesn't add 1 if topic is not deleted " do
topic = Fabricate ( :topic , category : category )
expect { topic . recover! } . to_not change { category . reload . topic_count }
end
end
end
2013-10-10 10:32:03 +11:00
it " limits new users to max_topics_in_first_day and max_posts_in_first_day " do
SiteSetting . stubs ( :max_topics_in_first_day ) . returns ( 1 )
SiteSetting . stubs ( :max_replies_in_first_day ) . returns ( 1 )
RateLimiter . stubs ( :disabled? ) . returns ( false )
SiteSetting . stubs ( :client_settings_json ) . returns ( SiteSetting . client_settings_json_uncached )
start = Time . now . tomorrow . beginning_of_day
freeze_time ( start )
user = Fabricate ( :user )
topic_id = create_post ( user : user ) . topic_id
freeze_time ( start + 10 . minutes )
lambda {
create_post ( user : user )
} . should raise_exception
freeze_time ( start + 20 . minutes )
create_post ( user : user , topic_id : topic_id )
freeze_time ( start + 30 . minutes )
lambda {
create_post ( user : user , topic_id : topic_id )
} . should raise_exception
end
2013-10-28 11:42:07 +05:30
describe " .count_exceeds_minimun? " do
before { SiteSetting . stubs ( :minimum_topics_similar ) . returns ( 20 ) }
context " when Topic count is geater than minimum_topics_similar " do
it " should be true " do
Topic . stubs ( :count ) . returns ( 30 )
expect ( Topic . count_exceeds_minimum? ) . to be_true
end
end
context " when topic's count is less than minimum_topics_similar " do
it " should be false " do
Topic . stubs ( :count ) . returns ( 10 )
expect ( Topic . count_exceeds_minimum? ) . to_not be_true
end
end
end
2014-02-27 11:45:20 +11:00
describe " calculate_avg_time " do
it " does not explode " do
Topic . calculate_avg_time
Topic . calculate_avg_time ( 1 . day . ago )
end
end
2014-04-01 15:29:15 -04:00
describe " expandable_first_post? " do
2014-04-18 21:01:21 +02:00
let ( :topic ) { Fabricate . build ( :topic ) }
2014-04-01 15:29:15 -04:00
before do
SiteSetting . stubs ( :embeddable_host ) . returns ( " http://eviltrout.com " )
SiteSetting . stubs ( :embed_truncate? ) . returns ( true )
topic . stubs ( :has_topic_embed? ) . returns ( true )
end
it " is true with the correct settings and topic_embed " do
topic . expandable_first_post? . should be_true
end
it " is false if embeddable_host is blank " do
SiteSetting . stubs ( :embeddable_host ) . returns ( nil )
topic . expandable_first_post? . should be_false
end
it " is false if embed_truncate? is false " do
SiteSetting . stubs ( :embed_truncate? ) . returns ( false )
topic . expandable_first_post? . should be_false
end
it " is false if has_topic_embed? is false " do
topic . stubs ( :has_topic_embed? ) . returns ( false )
topic . expandable_first_post? . should be_false
end
2014-04-25 18:24:22 +02:00
end
it " has custom fields " do
topic = Fabricate ( :topic )
topic . custom_fields [ " a " ] . should == nil
2014-04-01 15:29:15 -04:00
2014-04-25 18:24:22 +02:00
topic . custom_fields [ " bob " ] = " marley "
topic . custom_fields [ " jack " ] = " black "
topic . save
2014-04-01 15:29:15 -04:00
2014-04-25 18:24:22 +02:00
topic = Topic . find ( topic . id )
topic . custom_fields . should == { " bob " = > " marley " , " jack " = > " black " }
2014-04-01 15:29:15 -04:00
end
2013-02-05 14:16:51 -05:00
end