2015-10-11 17:41:23 +08:00
require 'rails_helper'
2013-02-06 03:16:51 +08:00
require 'post_creator'
2013-04-17 04:56:18 +08:00
require 'topic_subtype'
2013-02-06 03:16:51 +08:00
describe PostCreator do
let ( :user ) { Fabricate ( :user ) }
2016-07-15 11:36:06 +08:00
let ( :topic ) { Fabricate ( :topic , user : user ) }
2013-02-06 03:16:51 +08:00
2013-07-08 10:44:55 +08:00
context " new topic " do
2013-02-06 03:16:51 +08:00
let ( :category ) { Fabricate ( :category , user : user ) }
2013-07-08 10:44:55 +08:00
let ( :basic_topic_params ) { { title : " hello world topic " , raw : " my name is fred " , archetype_id : 1 } }
let ( :image_sizes ) { { 'http://an.image.host/image.jpg' = > { " width " = > 111 , " height " = > 222 } } }
2013-02-06 03:16:51 +08:00
let ( :creator ) { PostCreator . new ( user , basic_topic_params ) }
2013-07-18 06:58:25 +08:00
let ( :creator_with_category ) { PostCreator . new ( user , basic_topic_params . merge ( category : category . id ) ) }
2013-07-08 10:44:55 +08:00
let ( :creator_with_meta_data ) { PostCreator . new ( user , basic_topic_params . merge ( meta_data : { hello : " world " } ) ) }
2013-02-06 03:16:51 +08:00
let ( :creator_with_image_sizes ) { PostCreator . new ( user , basic_topic_params . merge ( image_sizes : image_sizes ) ) }
2016-12-10 02:28:12 +08:00
let ( :creator_with_featured_link ) { PostCreator . new ( user , title : " featured link topic " , archetype_id : 1 , featured_link : " http://www.discourse.org " , raw : " http://www.discourse.org " ) }
2013-02-06 03:16:51 +08:00
2015-08-19 10:15:38 +08:00
it " can create a topic with null byte central " do
post = PostCreator . create ( user , title : " hello \ u0000world this is title " , raw : " this is my \ u0000 first topic " )
expect ( post . raw ) . to eq 'this is my first topic'
expect ( post . topic . title ) . to eq 'Helloworld this is title'
end
2013-07-22 09:40:39 +08:00
it " can be created with auto tracking disabled " do
p = PostCreator . create ( user , basic_topic_params . merge ( auto_track : false ) )
2013-07-22 13:06:53 +08:00
# must be 0 otherwise it will think we read the topic which is clearly untrue
2015-01-10 00:34:37 +08:00
expect ( TopicUser . where ( user_id : p . user_id , topic_id : p . topic_id ) . count ) . to eq ( 0 )
2013-07-22 09:40:39 +08:00
end
2016-12-18 21:38:55 +08:00
it " can be created with first post as wiki " do
cat = Fabricate ( :category )
cat . all_topics_wiki = true
cat . save
post = PostCreator . create ( user , basic_topic_params . merge ( category : cat . id ) )
expect ( post . wiki ) . to eq ( true )
end
2013-07-08 10:44:55 +08:00
it " ensures the user can create the topic " do
2013-02-06 03:16:51 +08:00
Guardian . any_instance . expects ( :can_create? ) . with ( Topic , nil ) . returns ( false )
2015-01-10 00:34:37 +08:00
expect { creator . create } . to raise_error ( Discourse :: InvalidAccess )
2013-02-06 03:16:51 +08:00
end
2015-09-23 01:32:19 +08:00
context " reply to post number " do
it " omits reply to post number if received on a new topic " do
p = PostCreator . new ( user , basic_topic_params . merge ( reply_to_post_number : 3 ) ) . create
expect ( p . reply_to_post_number ) . to be_nil
end
end
2013-06-08 00:36:37 +08:00
context " invalid title " do
let ( :creator_invalid_title ) { PostCreator . new ( user , basic_topic_params . merge ( title : 'a' ) ) }
it " has errors " do
creator_invalid_title . create
expect ( creator_invalid_title . errors ) . to be_present
end
end
2013-10-23 09:14:31 +08:00
context " invalid raw " do
let ( :creator_invalid_raw ) { PostCreator . new ( user , basic_topic_params . merge ( raw : '' ) ) }
it " has errors " do
creator_invalid_raw . create
expect ( creator_invalid_raw . errors ) . to be_present
end
end
2013-07-08 10:44:55 +08:00
context " success " do
2016-09-13 16:03:17 +08:00
before { creator }
2013-02-06 03:16:51 +08:00
2013-05-11 04:58:23 +08:00
it " doesn't return true for spam " do
creator . create
2015-01-10 00:34:37 +08:00
expect ( creator . spam? ) . to eq ( false )
2013-05-11 04:58:23 +08:00
end
2015-04-24 01:33:29 +08:00
it " triggers extensibility events " do
DiscourseEvent . expects ( :trigger ) . with ( :before_create_post , anything ) . once
DiscourseEvent . expects ( :trigger ) . with ( :validate_post , anything ) . once
DiscourseEvent . expects ( :trigger ) . with ( :topic_created , anything , anything , user ) . once
DiscourseEvent . expects ( :trigger ) . with ( :post_created , anything , anything , user ) . once
2015-08-11 14:01:28 +08:00
DiscourseEvent . expects ( :trigger ) . with ( :after_validate_topic , anything , anything ) . once
DiscourseEvent . expects ( :trigger ) . with ( :before_create_topic , anything , anything ) . once
2015-09-04 11:35:25 +08:00
DiscourseEvent . expects ( :trigger ) . with ( :after_trigger_post_process , anything ) . once
2016-01-29 22:59:15 +08:00
DiscourseEvent . expects ( :trigger ) . with ( :markdown_context , anything ) . at_least_once
2017-04-12 15:52:02 +08:00
DiscourseEvent . expects ( :trigger ) . with ( :topic_notification_level_changed , anything , anything , anything ) . at_least_once
2015-04-24 01:33:29 +08:00
creator . create
end
2013-07-08 10:44:55 +08:00
it " does not notify on system messages " do
admin = Fabricate ( :admin )
2015-05-04 10:21:00 +08:00
messages = MessageBus . track_publish do
2013-07-08 10:44:55 +08:00
p = PostCreator . create ( admin , basic_topic_params . merge ( post_type : Post . types [ :moderator_action ] ) )
PostCreator . create ( admin , basic_topic_params . merge ( topic_id : p . topic_id , post_type : Post . types [ :moderator_action ] ) )
end
# don't notify on system messages they introduce too much noise
channels = messages . map ( & :channel )
2015-01-10 00:34:37 +08:00
expect ( channels . find { | s | s =~ / unread / } ) . to eq ( nil )
expect ( channels . find { | s | s =~ / new / } ) . to eq ( nil )
2013-07-08 10:44:55 +08:00
end
it " generates the correct messages for a secure topic " do
2013-05-16 13:03:03 +08:00
2016-12-22 12:03:40 +08:00
UserActionCreator . enable
2013-05-16 13:03:03 +08:00
admin = Fabricate ( :admin )
cat = Fabricate ( :category )
2013-07-14 09:24:16 +08:00
cat . set_permissions ( :admins = > :full )
2013-05-16 13:03:03 +08:00
cat . save
created_post = nil
reply = nil
2015-05-04 10:21:00 +08:00
messages = MessageBus . track_publish do
2013-07-18 06:58:25 +08:00
created_post = PostCreator . new ( admin , basic_topic_params . merge ( category : cat . id ) ) . create
2013-07-08 10:44:55 +08:00
reply = PostCreator . new ( admin , raw : " this is my test reply 123 testing " , topic_id : created_post . topic_id ) . create
2013-05-16 13:03:03 +08:00
end
2014-06-25 08:55:50 +08:00
# 2 for topic, one to notify of new topic another for tracking state
2015-01-10 00:34:37 +08:00
expect ( messages . map { | m | m . channel } . sort ) . to eq ( [ " /new " ,
2017-03-29 02:27:54 +08:00
" /u/ #{ admin . username } " ,
" /u/ #{ admin . username } " ,
2013-06-03 15:07:44 +08:00
" /unread/ #{ admin . id } " ,
" /unread/ #{ admin . id } " ,
2014-08-05 11:40:44 +08:00
" /latest " ,
" /latest " ,
2014-06-25 08:55:50 +08:00
" /topic/ #{ created_post . topic_id } " ,
2013-06-03 15:07:44 +08:00
" /topic/ #{ created_post . topic_id } "
2015-01-10 00:34:37 +08:00
] . sort )
2013-05-16 13:03:03 +08:00
admin_ids = [ Group [ :admins ] . id ]
2013-06-03 15:07:44 +08:00
2015-01-10 00:34:37 +08:00
expect ( messages . any? { | m | m . group_ids != admin_ids && m . user_ids != [ admin . id ] } ) . to eq ( false )
2013-02-06 03:16:51 +08:00
end
2013-06-03 15:07:44 +08:00
it 'generates the correct messages for a normal topic' do
2013-05-16 13:03:03 +08:00
2016-12-22 12:03:40 +08:00
UserActionCreator . enable
2013-05-16 13:03:03 +08:00
p = nil
2015-05-04 10:21:00 +08:00
messages = MessageBus . track_publish do
2013-05-16 13:03:03 +08:00
p = creator . create
end
2014-08-05 11:40:44 +08:00
latest = messages . find { | m | m . channel == " /latest " }
2015-01-10 00:34:37 +08:00
expect ( latest ) . not_to eq ( nil )
2014-08-05 11:40:44 +08:00
2013-06-03 15:07:44 +08:00
latest = messages . find { | m | m . channel == " /new " }
2015-01-10 00:34:37 +08:00
expect ( latest ) . not_to eq ( nil )
2013-05-16 13:03:03 +08:00
2013-06-03 15:07:44 +08:00
read = messages . find { | m | m . channel == " /unread/ #{ p . user_id } " }
2015-01-10 00:34:37 +08:00
expect ( read ) . not_to eq ( nil )
2013-06-03 15:07:44 +08:00
2017-03-29 02:27:54 +08:00
user_action = messages . find { | m | m . channel == " /u/ #{ p . user . username } " }
2015-01-10 00:34:37 +08:00
expect ( user_action ) . not_to eq ( nil )
2013-05-16 13:03:03 +08:00
2015-01-10 00:34:37 +08:00
expect ( messages . length ) . to eq ( 5 )
2013-03-19 02:45:05 +08:00
end
2013-05-16 13:03:03 +08:00
it 'extracts links from the post' do
2016-04-12 10:28:18 +08:00
create_post ( raw : " this is a link to the best site at https://google.com " )
2013-03-19 01:55:34 +08:00
creator . create
2016-04-12 10:28:18 +08:00
expect ( TopicLink . count ) . to eq ( 1 )
2013-03-19 01:55:34 +08:00
end
it 'queues up post processing job when saved' do
2013-05-16 13:03:03 +08:00
Jobs . expects ( :enqueue ) . with ( :feature_topic_users , has_key ( :topic_id ) )
2013-03-19 01:55:34 +08:00
Jobs . expects ( :enqueue ) . with ( :process_post , has_key ( :post_id ) )
2015-04-21 01:34:57 +08:00
Jobs . expects ( :enqueue ) . with ( :post_alert , has_key ( :post_id ) )
2014-03-05 11:26:42 +08:00
Jobs . expects ( :enqueue ) . with ( :notify_mailing_list_subscribers , has_key ( :post_id ) )
2013-03-19 01:55:34 +08:00
creator . create
end
it 'passes the invalidate_oneboxes along to the job if present' do
Jobs . stubs ( :enqueue ) . with ( :feature_topic_users , has_key ( :topic_id ) )
2014-03-05 11:26:42 +08:00
Jobs . expects ( :enqueue ) . with ( :notify_mailing_list_subscribers , has_key ( :post_id ) )
2015-04-21 01:34:57 +08:00
Jobs . expects ( :enqueue ) . with ( :post_alert , has_key ( :post_id ) )
2013-03-19 01:55:34 +08:00
Jobs . expects ( :enqueue ) . with ( :process_post , has_key ( :invalidate_oneboxes ) )
creator . opts [ :invalidate_oneboxes ] = true
creator . create
end
it 'passes the image_sizes along to the job if present' do
Jobs . stubs ( :enqueue ) . with ( :feature_topic_users , has_key ( :topic_id ) )
2014-03-05 11:26:42 +08:00
Jobs . expects ( :enqueue ) . with ( :notify_mailing_list_subscribers , has_key ( :post_id ) )
2015-04-21 01:34:57 +08:00
Jobs . expects ( :enqueue ) . with ( :post_alert , has_key ( :post_id ) )
2013-03-19 01:55:34 +08:00
Jobs . expects ( :enqueue ) . with ( :process_post , has_key ( :image_sizes ) )
creator . opts [ :image_sizes ] = { 'http://an.image.host/image.jpg' = > { 'width' = > 17 , 'height' = > 31 } }
creator . create
end
2013-02-06 03:16:51 +08:00
it 'assigns a category when supplied' do
2015-01-10 00:34:37 +08:00
expect ( creator_with_category . create . topic . category ) . to eq ( category )
2013-02-06 03:16:51 +08:00
end
it 'adds meta data from the post' do
2015-01-10 00:34:37 +08:00
expect ( creator_with_meta_data . create . topic . meta_data [ 'hello' ] ) . to eq ( 'world' )
2013-02-06 03:16:51 +08:00
end
it 'passes the image sizes through' do
Post . any_instance . expects ( :image_sizes = ) . with ( image_sizes )
creator_with_image_sizes . create
2013-02-26 00:42:20 +08:00
end
2013-04-05 12:29:46 +08:00
it 'increases topic response counts' do
first_post = creator . create
2013-07-22 13:06:53 +08:00
# ensure topic user is correct
2014-05-06 21:41:59 +08:00
topic_user = first_post . user . topic_users . find_by ( topic_id : first_post . topic_id )
2015-01-10 00:34:37 +08:00
expect ( topic_user ) . to be_present
expect ( topic_user ) . to be_posted
expect ( topic_user . last_read_post_number ) . to eq ( first_post . post_number )
expect ( topic_user . highest_seen_post_number ) . to eq ( first_post . post_number )
2013-07-22 13:06:53 +08:00
user2 = Fabricate ( :coding_horror )
2015-01-10 00:34:37 +08:00
expect ( user2 . user_stat . topic_reply_count ) . to eq ( 0 )
2013-10-04 11:28:49 +08:00
2015-01-10 00:34:37 +08:00
expect ( first_post . user . user_stat . reload . topic_reply_count ) . to eq ( 0 )
2013-04-05 12:29:46 +08:00
PostCreator . new ( user2 , topic_id : first_post . topic_id , raw : " this is my test post 123 " ) . create
2013-10-04 11:28:49 +08:00
2015-01-10 00:34:37 +08:00
expect ( first_post . user . user_stat . reload . topic_reply_count ) . to eq ( 0 )
2013-10-04 11:28:49 +08:00
2015-01-10 00:34:37 +08:00
expect ( user2 . user_stat . reload . topic_reply_count ) . to eq ( 1 )
2013-04-05 12:29:46 +08:00
end
2014-03-19 01:40:40 +08:00
it 'sets topic excerpt if first post, but not second post' do
first_post = creator . create
topic = first_post . topic . reload
2015-01-10 00:34:37 +08:00
expect ( topic . excerpt ) . to be_present
2014-03-19 01:40:40 +08:00
expect {
PostCreator . new ( first_post . user , topic_id : first_post . topic_id , raw : " this is the second post " ) . create
topic . reload
} . to_not change { topic . excerpt }
end
2014-10-11 00:21:44 +08:00
2015-08-03 12:29:04 +08:00
it 'creates post stats' do
Draft . set ( user , 'new_topic' , 0 , " test " )
Draft . set ( user , 'new_topic' , 0 , " test1 " )
begin
PostCreator . track_post_stats = true
post = creator . create
expect ( post . post_stat . typing_duration_msecs ) . to eq ( 0 )
expect ( post . post_stat . drafts_saved ) . to eq ( 2 )
ensure
PostCreator . track_post_stats = false
end
end
2016-12-10 02:28:12 +08:00
it 'creates a post with featured link' do
2016-12-05 20:31:43 +08:00
SiteSetting . topic_featured_link_enabled = true
2016-12-10 04:46:26 +08:00
SiteSetting . min_first_post_length = 100
2017-04-15 12:11:02 +08:00
SiteSetting . queue_jobs = true
2016-12-05 20:31:43 +08:00
post = creator_with_featured_link . create
2016-12-10 02:28:12 +08:00
expect ( post . topic . featured_link ) . to eq ( 'http://www.discourse.org' )
2016-12-10 04:46:26 +08:00
expect ( post . valid? ) . to eq ( true )
2016-12-05 20:31:43 +08:00
end
2014-10-11 00:21:44 +08:00
describe " topic's auto close " do
2017-04-03 17:28:41 +08:00
before do
SiteSetting . queue_jobs = true
end
2014-10-11 00:21:44 +08:00
it " doesn't update topic's auto close when it's not based on last post " do
2017-03-22 11:12:02 +08:00
Timecop . freeze do
2017-05-12 06:23:18 +08:00
topic = Fabricate ( :topic ) . set_or_create_timer ( TopicTimer . types [ :close ] , 12 )
2014-10-11 00:21:44 +08:00
2017-03-22 11:12:02 +08:00
PostCreator . new ( topic . user , topic_id : topic . id , raw : " this is a second post " ) . create
topic . reload
2014-10-11 00:21:44 +08:00
2017-05-12 06:23:18 +08:00
topic_status_update = TopicTimer . last
2017-03-22 11:12:02 +08:00
expect ( topic_status_update . execute_at ) . to be_within ( 1 . second ) . of ( Time . zone . now + 12 . hours )
expect ( topic_status_update . created_at ) . to be_within ( 1 . second ) . of ( Time . zone . now )
end
2014-10-11 00:21:44 +08:00
end
it " updates topic's auto close date when it's based on last post " do
2017-03-22 11:12:02 +08:00
Timecop . freeze do
topic = Fabricate ( :topic ,
2017-05-12 06:23:18 +08:00
topic_timers : [ Fabricate ( :topic_timer ,
2017-03-22 11:12:02 +08:00
based_on_last_post : true ,
execute_at : Time . zone . now - 12 . hours ,
created_at : Time . zone . now - 24 . hours
) ]
)
Fabricate ( :post , topic : topic )
2014-10-11 00:21:44 +08:00
2017-03-22 11:12:02 +08:00
PostCreator . new ( topic . user , topic_id : topic . id , raw : " this is a second post " ) . create
2017-05-12 06:23:18 +08:00
topic_status_update = TopicTimer . last
2017-03-22 11:12:02 +08:00
expect ( topic_status_update . execute_at ) . to be_within ( 1 . second ) . of ( Time . zone . now + 12 . hours )
expect ( topic_status_update . created_at ) . to be_within ( 1 . second ) . of ( Time . zone . now )
end
2014-10-11 00:21:44 +08:00
end
end
2016-05-05 02:02:47 +08:00
context " tags " do
let ( :tag_names ) { [ 'art' , 'science' , 'dance' ] }
let ( :creator_with_tags ) { PostCreator . new ( user , basic_topic_params . merge ( tags : tag_names ) ) }
context " tagging disabled " do
before do
SiteSetting . tagging_enabled = false
end
it " doesn't create tags " do
expect { @post = creator_with_tags . create } . to change { Tag . count } . by ( 0 )
expect ( @post . topic . tags . size ) . to eq ( 0 )
end
end
context " tagging enabled " do
before do
SiteSetting . tagging_enabled = true
end
context " can create tags " do
before do
SiteSetting . min_trust_to_create_tag = 0
SiteSetting . min_trust_level_to_tag_topics = 0
end
it " can create all tags if none exist " do
expect { @post = creator_with_tags . create } . to change { Tag . count } . by ( tag_names . size )
expect ( @post . topic . tags . map ( & :name ) . sort ) . to eq ( tag_names . sort )
end
it " creates missing tags if some exist " do
existing_tag1 = Fabricate ( :tag , name : tag_names [ 0 ] )
existing_tag1 = Fabricate ( :tag , name : tag_names [ 1 ] )
expect { @post = creator_with_tags . create } . to change { Tag . count } . by ( tag_names . size - 2 )
expect ( @post . topic . tags . map ( & :name ) . sort ) . to eq ( tag_names . sort )
end
end
context " cannot create tags " do
before do
SiteSetting . min_trust_to_create_tag = 4
SiteSetting . min_trust_level_to_tag_topics = 0
end
it " only uses existing tags " do
existing_tag1 = Fabricate ( :tag , name : tag_names [ 1 ] )
expect { @post = creator_with_tags . create } . to change { Tag . count } . by ( 0 )
expect ( @post . topic . tags . map ( & :name ) ) . to eq ( [ existing_tag1 . name ] )
end
end
end
end
2013-02-26 00:42:20 +08:00
end
2013-02-06 03:16:51 +08:00
2013-05-08 02:25:41 +08:00
context 'when auto-close param is given' do
2013-11-29 00:06:04 +08:00
it 'ensures the user can auto-close the topic, but ignores auto-close param silently' do
2013-05-08 02:25:41 +08:00
Guardian . any_instance . stubs ( :can_moderate? ) . returns ( false )
2017-03-22 11:12:02 +08:00
expect {
PostCreator . new ( user , basic_topic_params . merge ( auto_close_time : 2 ) ) . create!
2017-05-12 06:23:18 +08:00
} . to_not change { TopicTimer . count }
2013-05-08 02:25:41 +08:00
end
end
2015-09-25 23:28:41 +08:00
end
context 'whisper' do
let! ( :topic ) { Fabricate ( :topic , user : user ) }
2016-12-02 14:03:31 +08:00
it 'whispers do not mess up the public view' do
first = PostCreator . new ( user ,
topic_id : topic . id ,
raw : 'this is the first post' ) . create
2015-09-25 23:28:41 +08:00
whisper = PostCreator . new ( user ,
topic_id : topic . id ,
reply_to_post_number : 1 ,
post_type : Post . types [ :whisper ] ,
raw : 'this is a whispered reply' ) . create
expect ( whisper ) . to be_present
expect ( whisper . post_type ) . to eq ( Post . types [ :whisper ] )
2016-12-02 14:03:31 +08:00
2015-09-25 23:28:41 +08:00
whisper_reply = PostCreator . new ( user ,
topic_id : topic . id ,
reply_to_post_number : whisper . post_number ,
post_type : Post . types [ :regular ] ,
raw : 'replying to a whisper this time' ) . create
expect ( whisper_reply ) . to be_present
expect ( whisper_reply . post_type ) . to eq ( Post . types [ :whisper ] )
2016-12-02 14:03:31 +08:00
first . reload
# does not leak into the OP
expect ( first . reply_count ) . to eq ( 0 )
topic . reload
# cause whispers should not muck up that number
expect ( topic . highest_post_number ) . to eq ( 1 )
expect ( topic . reply_count ) . to eq ( 0 )
expect ( topic . posts_count ) . to eq ( 1 )
expect ( topic . highest_staff_post_number ) . to eq ( 3 )
topic . update_columns ( highest_staff_post_number : 0 , highest_post_number : 0 , posts_count : 0 , last_posted_at : 1 . year . ago )
Topic . reset_highest ( topic . id )
topic . reload
expect ( topic . highest_post_number ) . to eq ( 1 )
expect ( topic . posts_count ) . to eq ( 1 )
expect ( topic . last_posted_at ) . to eq ( first . created_at )
expect ( topic . highest_staff_post_number ) . to eq ( 3 )
2015-09-25 23:28:41 +08:00
end
2013-02-06 03:16:51 +08:00
end
2013-03-19 01:55:34 +08:00
context 'uniqueness' do
let! ( :topic ) { Fabricate ( :topic , user : user ) }
let ( :basic_topic_params ) { { raw : 'test reply' , topic_id : topic . id , reply_to_post_number : 4 } }
let ( :creator ) { PostCreator . new ( user , basic_topic_params ) }
context " disabled " do
before do
2014-07-14 13:59:58 +08:00
SiteSetting . unique_posts_mins = 0
2013-03-19 01:55:34 +08:00
creator . create
end
it " returns true for another post with the same content " do
new_creator = PostCreator . new ( user , basic_topic_params )
2015-01-10 00:34:37 +08:00
expect ( new_creator . create ) . to be_present
2013-03-19 01:55:34 +08:00
end
end
context 'enabled' do
let ( :new_post_creator ) { PostCreator . new ( user , basic_topic_params ) }
before do
2014-07-14 13:59:58 +08:00
SiteSetting . unique_posts_mins = 10
end
it " fails for dupe post accross topic " do
2016-02-03 15:50:05 +08:00
first = create_post ( raw : " this is a test #{ SecureRandom . hex } " )
second = create_post ( raw : " this is a test #{ SecureRandom . hex } " )
2014-07-14 13:59:58 +08:00
dupe = " hello 123 test #{ SecureRandom . hex } "
2016-02-03 15:50:05 +08:00
response_1 = PostCreator . create ( first . user , raw : dupe , topic_id : first . topic_id )
response_2 = PostCreator . create ( first . user , raw : dupe , topic_id : second . topic_id )
2014-07-14 13:59:58 +08:00
2015-01-10 00:34:37 +08:00
expect ( response_1 . errors . count ) . to eq ( 0 )
expect ( response_2 . errors . count ) . to eq ( 1 )
2013-03-19 01:55:34 +08:00
end
it " returns blank for another post with the same content " do
2014-07-14 13:59:58 +08:00
creator . create
2013-03-19 01:55:34 +08:00
new_post_creator . create
2015-01-10 00:34:37 +08:00
expect ( new_post_creator . errors ) . to be_present
2013-03-19 01:55:34 +08:00
end
it " returns a post for admins " do
2014-07-14 13:59:58 +08:00
creator . create
2013-03-19 01:55:34 +08:00
user . admin = true
new_post_creator . create
2015-01-10 00:34:37 +08:00
expect ( new_post_creator . errors ) . to be_blank
2013-03-19 01:55:34 +08:00
end
it " returns a post for moderators " do
2014-07-14 13:59:58 +08:00
creator . create
2013-03-20 12:05:19 +08:00
user . moderator = true
2013-03-19 01:55:34 +08:00
new_post_creator . create
2015-01-10 00:34:37 +08:00
expect ( new_post_creator . errors ) . to be_blank
2013-03-19 01:55:34 +08:00
end
end
end
2013-05-11 04:58:23 +08:00
context " host spam " do
let! ( :topic ) { Fabricate ( :topic , user : user ) }
let ( :basic_topic_params ) { { raw : 'test reply' , topic_id : topic . id , reply_to_post_number : 4 } }
let ( :creator ) { PostCreator . new ( user , basic_topic_params ) }
before do
Post . any_instance . expects ( :has_host_spam? ) . returns ( true )
end
it " does not create the post " do
2013-06-11 01:17:09 +08:00
GroupMessage . stubs ( :create )
2015-08-11 14:01:28 +08:00
_post = creator . create
2015-03-27 04:57:50 +08:00
2015-01-10 00:34:37 +08:00
expect ( creator . errors ) . to be_present
expect ( creator . spam? ) . to eq ( true )
2013-05-11 04:58:23 +08:00
end
2013-06-11 01:17:09 +08:00
it " sends a message to moderators " do
GroupMessage . expects ( :create ) . with do | group_name , msg_type , params |
group_name == Group [ :moderators ] . name and msg_type == :spam_post_blocked and params [ :user ] . id == user . id
end
creator . create
end
2013-05-11 04:58:23 +08:00
end
2013-04-17 15:33:34 +08:00
# more integration testing ... maximise our testing
2013-02-06 03:16:51 +08:00
context 'existing topic' do
2016-07-15 11:36:06 +08:00
let ( :topic ) { Fabricate ( :topic , user : user ) }
2013-02-06 03:16:51 +08:00
let ( :creator ) { PostCreator . new ( user , raw : 'test reply' , topic_id : topic . id , reply_to_post_number : 4 ) }
it 'ensures the user can create the post' do
Guardian . any_instance . expects ( :can_create? ) . with ( Post , topic ) . returns ( false )
2015-03-16 03:14:45 +08:00
post = creator . create
expect ( post ) . to be_blank
expect ( creator . errors . count ) . to eq 1
expect ( creator . errors . messages [ :base ] [ 0 ] ) . to match I18n . t ( :topic_not_found )
2013-02-06 03:16:51 +08:00
end
context 'success' do
2013-04-17 15:33:34 +08:00
it 'create correctly' do
post = creator . create
2015-01-10 00:34:37 +08:00
expect ( Post . count ) . to eq ( 1 )
expect ( Topic . count ) . to eq ( 1 )
expect ( post . reply_to_post_number ) . to eq ( 4 )
2013-02-06 03:16:51 +08:00
end
end
end
2015-03-16 03:14:45 +08:00
context 'closed topic' do
let! ( :topic ) { Fabricate ( :topic , user : user , closed : true ) }
let ( :creator ) { PostCreator . new ( user , raw : 'test reply' , topic_id : topic . id , reply_to_post_number : 4 ) }
it 'responds with an error message' do
post = creator . create
expect ( post ) . to be_blank
expect ( creator . errors . count ) . to eq 1
expect ( creator . errors . messages [ :base ] [ 0 ] ) . to match I18n . t ( :topic_not_found )
end
end
context 'missing topic' do
let! ( :topic ) { Fabricate ( :topic , user : user , deleted_at : 5 . minutes . ago ) }
let ( :creator ) { PostCreator . new ( user , raw : 'test reply' , topic_id : topic . id , reply_to_post_number : 4 ) }
it 'responds with an error message' do
post = creator . create
expect ( post ) . to be_blank
expect ( creator . errors . count ) . to eq 1
expect ( creator . errors . messages [ :base ] [ 0 ] ) . to match I18n . t ( :topic_not_found )
end
end
2013-06-21 23:36:33 +08:00
context " cooking options " do
let ( :raw ) { " this is my awesome message body hello world " }
it " passes the cooking options through correctly " do
creator = PostCreator . new ( user ,
title : 'hi there welcome to my topic' ,
raw : raw ,
cooking_options : { traditional_markdown_linebreaks : true } )
2016-04-13 04:09:29 +08:00
Post . any_instance . expects ( :cook ) . with ( raw , has_key ( :traditional_markdown_linebreaks ) ) . returns ( raw )
2013-06-21 23:36:33 +08:00
creator . create
end
end
2013-04-17 15:33:34 +08:00
# integration test ... minimise db work
2013-02-06 03:16:51 +08:00
context 'private message' do
let ( :target_user1 ) { Fabricate ( :coding_horror ) }
let ( :target_user2 ) { Fabricate ( :moderator ) }
2013-04-17 15:33:34 +08:00
let ( :unrelated ) { Fabricate ( :user ) }
2015-03-23 14:21:58 +08:00
let ( :post ) do
PostCreator . create ( user , title : 'hi there welcome to my topic' ,
2013-04-17 15:33:34 +08:00
raw : " this is my awesome message @ #{ unrelated . username_lower } " ,
archetype : Archetype . private_message ,
2015-03-23 14:21:58 +08:00
target_usernames : [ target_user1 . username , target_user2 . username ] . join ( ',' ) ,
2014-01-24 19:57:48 +08:00
category : 1 )
2013-04-17 15:33:34 +08:00
end
2013-02-06 03:16:51 +08:00
2013-04-17 15:33:34 +08:00
it 'acts correctly' do
2014-09-08 23:11:56 +08:00
# It's not a warning
2017-04-15 12:11:02 +08:00
expect ( post . topic . user_warning ) . to be_blank
2014-09-08 23:11:56 +08:00
2015-01-10 00:34:37 +08:00
expect ( post . topic . archetype ) . to eq ( Archetype . private_message )
expect ( post . topic . subtype ) . to eq ( TopicSubtype . user_to_user )
expect ( post . topic . topic_allowed_users . count ) . to eq ( 3 )
2013-02-06 03:16:51 +08:00
2014-01-24 19:57:48 +08:00
# PMs can't have a category
2015-01-10 00:34:37 +08:00
expect ( post . topic . category ) . to eq ( nil )
2014-01-24 19:57:48 +08:00
2013-04-17 15:33:34 +08:00
# does not notify an unrelated user
2015-01-10 00:34:37 +08:00
expect ( unrelated . notifications . count ) . to eq ( 0 )
expect ( post . topic . subtype ) . to eq ( TopicSubtype . user_to_user )
2013-09-06 12:07:23 +08:00
2016-01-24 13:39:01 +08:00
# PMs do not increase post count or topic count
expect ( post . user . user_stat . post_count ) . to eq ( 0 )
expect ( post . user . user_stat . topic_count ) . to eq ( 0 )
2015-12-23 08:09:17 +08:00
# archive this message and ensure archive is cleared for all users on reply
UserArchivedMessage . create ( user_id : target_user2 . id , topic_id : post . topic_id )
2014-05-13 03:26:36 +08:00
# if an admin replies they should be added to the allowed user list
admin = Fabricate ( :admin )
PostCreator . create ( admin , raw : 'hi there welcome topic, I am a mod' ,
2013-09-06 12:07:23 +08:00
topic_id : post . topic_id )
post . topic . reload
2015-01-10 00:34:37 +08:00
expect ( post . topic . topic_allowed_users . where ( user_id : admin . id ) . count ) . to eq ( 1 )
2015-12-23 08:09:17 +08:00
expect ( UserArchivedMessage . where ( user_id : target_user2 . id , topic_id : post . topic_id ) . count ) . to eq ( 0 )
2016-01-12 10:57:45 +08:00
# if another admin replies and is already member of the group, don't add them to topic_allowed_users
group = Fabricate ( :group )
post . topic . topic_allowed_groups . create! ( group : group )
admin2 = Fabricate ( :admin )
group . add ( admin2 )
PostCreator . create ( admin2 , raw : 'I am also an admin, and a mod' , topic_id : post . topic_id )
expect ( post . topic . topic_allowed_users . where ( user_id : admin2 . id ) . count ) . to eq ( 0 )
2013-02-06 03:16:51 +08:00
end
end
2014-09-08 23:11:56 +08:00
context " warnings " do
let ( :target_user1 ) { Fabricate ( :coding_horror ) }
let ( :target_user2 ) { Fabricate ( :moderator ) }
let ( :base_args ) do
{ title : 'you need a warning buddy!' ,
raw : " you did something bad and I'm telling you about it! " ,
is_warning : true ,
target_usernames : target_user1 . username ,
category : 1 }
end
it " works as expected " do
# Invalid archetype
creator = PostCreator . new ( user , base_args )
creator . create
2015-01-10 00:34:37 +08:00
expect ( creator . errors ) . to be_present
2014-09-08 23:11:56 +08:00
# Too many users
creator = PostCreator . new ( user , base_args . merge ( archetype : Archetype . private_message ,
target_usernames : [ target_user1 . username , target_user2 . username ] . join ( ',' ) ) )
creator . create
2015-01-10 00:34:37 +08:00
expect ( creator . errors ) . to be_present
2014-09-08 23:11:56 +08:00
# Success
creator = PostCreator . new ( user , base_args . merge ( archetype : Archetype . private_message ) )
post = creator . create
2015-01-10 00:34:37 +08:00
expect ( creator . errors ) . to be_blank
2014-09-08 23:11:56 +08:00
topic = post . topic
2015-01-10 00:34:37 +08:00
expect ( topic ) . to be_present
2017-04-15 12:11:02 +08:00
expect ( topic . user_warning ) . to be_present
2015-01-10 00:34:37 +08:00
expect ( topic . subtype ) . to eq ( TopicSubtype . moderator_warning )
2017-04-15 12:11:02 +08:00
expect ( topic . user_warning . user ) . to eq ( target_user1 )
expect ( topic . user_warning . created_by ) . to eq ( user )
expect ( target_user1 . user_warnings . count ) . to eq ( 1 )
2014-09-08 23:11:56 +08:00
end
end
2016-04-12 11:29:48 +08:00
context 'auto closing' do
it 'closes private messages that have more than N posts' do
SiteSetting . auto_close_messages_post_count = 2
admin = Fabricate ( :admin )
post1 = create_post ( archetype : Archetype . private_message ,
target_usernames : [ admin . username ] )
_post2 = create_post ( user : post1 . user , topic_id : post1 . topic_id )
post1 . topic . reload
expect ( post1 . topic . closed ) . to eq ( true )
end
it 'closes topics that have more than N posts' do
SiteSetting . auto_close_topics_post_count = 2
post1 = create_post
_post2 = create_post ( user : post1 . user , topic_id : post1 . topic_id )
post1 . topic . reload
2016-12-02 14:03:31 +08:00
expect ( post1 . topic . posts_count ) . to eq ( 3 )
2016-04-12 11:29:48 +08:00
expect ( post1 . topic . closed ) . to eq ( true )
end
end
2013-05-02 13:15:17 +08:00
context 'private message to group' do
let ( :target_user1 ) { Fabricate ( :coding_horror ) }
let ( :target_user2 ) { Fabricate ( :moderator ) }
let ( :group ) do
g = Fabricate . build ( :group )
g . add ( target_user1 )
g . add ( target_user2 )
g . save
g
end
let ( :unrelated ) { Fabricate ( :user ) }
let ( :post ) do
2015-03-23 14:21:58 +08:00
PostCreator . create ( user , title : 'hi there welcome to my topic' ,
2013-05-02 13:15:17 +08:00
raw : " this is my awesome message @ #{ unrelated . username_lower } " ,
archetype : Archetype . private_message ,
2015-03-23 14:21:58 +08:00
target_group_names : group . name )
2013-05-02 13:15:17 +08:00
end
2015-12-02 12:49:43 +08:00
it 'can post to a group correctly' do
2015-01-10 00:34:37 +08:00
expect ( post . topic . archetype ) . to eq ( Archetype . private_message )
expect ( post . topic . topic_allowed_users . count ) . to eq ( 1 )
expect ( post . topic . topic_allowed_groups . count ) . to eq ( 1 )
2013-05-02 13:15:17 +08:00
# does not notify an unrelated user
2015-01-10 00:34:37 +08:00
expect ( unrelated . notifications . count ) . to eq ( 0 )
expect ( post . topic . subtype ) . to eq ( TopicSubtype . user_to_user )
2015-04-21 01:34:57 +08:00
2015-01-10 00:34:37 +08:00
expect ( target_user1 . notifications . count ) . to eq ( 1 )
expect ( target_user2 . notifications . count ) . to eq ( 1 )
2013-05-02 13:15:17 +08:00
end
end
2013-05-19 03:24:29 +08:00
context 'setting created_at' do
created_at = 1 . week . ago
let ( :topic ) do
PostCreator . create ( user ,
raw : 'This is very interesting test post content' ,
title : 'This is a very interesting test post title' ,
created_at : created_at )
end
let ( :post ) do
PostCreator . create ( user ,
raw : 'This is very interesting test post content' ,
topic_id : Topic . last ,
created_at : created_at )
end
it 'acts correctly' do
2015-01-10 00:34:37 +08:00
expect ( topic . created_at ) . to be_within ( 10 . seconds ) . of ( created_at )
expect ( post . created_at ) . to be_within ( 10 . seconds ) . of ( created_at )
2013-05-19 03:24:29 +08:00
end
end
2013-07-02 10:22:56 +08:00
context 'disable validations' do
it 'can save a post' do
creator = PostCreator . new ( user , raw : 'q' , title : 'q' , skip_validations : true )
2014-03-07 16:00:09 +08:00
creator . create
2015-03-27 04:57:50 +08:00
expect ( creator . errors ) . to be_blank
2013-07-02 10:22:56 +08:00
end
end
2013-12-11 02:47:07 +08:00
describe " word_count " do
it " has a word count " do
2016-01-11 18:16:23 +08:00
creator = PostCreator . new ( user , title : 'some inspired poetry for a rainy day' , raw : 'mary had a little lamb, little lamb, little lamb. mary had a little lamb. Здравствуйте' )
2013-12-11 02:47:07 +08:00
post = creator . create
2016-01-11 18:16:23 +08:00
expect ( post . word_count ) . to eq ( 15 )
2013-12-11 02:47:07 +08:00
post . topic . reload
2016-01-11 18:16:23 +08:00
expect ( post . topic . word_count ) . to eq ( 15 )
2013-12-11 02:47:07 +08:00
end
end
2014-04-04 02:42:26 +08:00
describe " embed_url " do
let ( :embed_url ) { " http://eviltrout.com/stupid-url " }
it " creates the topic_embed record " do
creator = PostCreator . new ( user ,
embed_url : embed_url ,
title : 'Reviews of Science Ovens' ,
raw : 'Did you know that you can use microwaves to cook your dinner? Science!' )
2014-06-04 09:41:42 +08:00
creator . create
2015-06-16 00:08:55 +08:00
expect ( creator . errors ) . to be_blank
2015-01-10 00:34:37 +08:00
expect ( TopicEmbed . where ( embed_url : embed_url ) . exists? ) . to eq ( true )
2015-06-16 00:08:55 +08:00
# If we try to create another topic with the embed url, should fail
creator = PostCreator . new ( user ,
embed_url : embed_url ,
title : 'More Reviews of Science Ovens' ,
raw : 'As if anyone ever wanted to learn more about them!' )
result = creator . create
expect ( result ) . to be_present
expect ( creator . errors ) . to be_present
2014-04-04 02:42:26 +08:00
end
end
2014-06-04 09:41:42 +08:00
describe " read credit for creator " do
it " should give credit to creator " do
post = create_post
2015-01-10 00:34:37 +08:00
expect ( PostTiming . find_by ( topic_id : post . topic_id ,
2014-06-04 09:41:42 +08:00
post_number : post . post_number ,
2015-01-10 00:34:37 +08:00
user_id : post . user_id ) . msecs ) . to be > 0
2014-06-04 09:41:42 +08:00
2015-01-10 00:34:37 +08:00
expect ( TopicUser . find_by ( topic_id : post . topic_id ,
user_id : post . user_id ) . last_read_post_number ) . to eq ( 1 )
2014-06-04 09:41:42 +08:00
end
end
2014-07-31 11:15:16 +08:00
describe " suspended users " do
it " does not allow suspended users to create topics " do
user = Fabricate ( :user , suspended_at : 1 . month . ago , suspended_till : 1 . month . from_now )
creator = PostCreator . new ( user , { title : " my test title 123 " , raw : " I should not be allowed to post " } )
creator . create
2015-01-10 00:34:37 +08:00
expect ( creator . errors . count ) . to be > 0
2014-07-31 11:15:16 +08:00
end
end
2014-09-02 07:18:06 +08:00
it " doesn't strip starting whitespaces " do
2015-03-27 04:57:50 +08:00
pc = PostCreator . new ( user , { title : " testing whitespace stripping " , raw : " <-- whitespaces --> " } )
post = pc . create
2015-01-10 00:34:37 +08:00
expect ( post . raw ) . to eq ( " <-- whitespaces --> " )
2014-09-02 07:18:06 +08:00
end
2015-04-01 00:58:56 +08:00
context " events " do
before do
@posts_created = 0
@topics_created = 0
@increase_posts = - > ( post , opts , user ) { @posts_created += 1 }
@increase_topics = - > ( topic , opts , user ) { @topics_created += 1 }
DiscourseEvent . on ( :post_created , & @increase_posts )
DiscourseEvent . on ( :topic_created , & @increase_topics )
end
after do
DiscourseEvent . off ( :post_created , & @increase_posts )
DiscourseEvent . off ( :topic_created , & @increase_topics )
end
it " fires boths event when creating a topic " do
pc = PostCreator . new ( user , raw : 'this is the new content for my topic' , title : 'this is my new topic title' )
2015-08-11 14:01:28 +08:00
_post = pc . create
2015-04-01 00:58:56 +08:00
expect ( @posts_created ) . to eq ( 1 )
expect ( @topics_created ) . to eq ( 1 )
end
it " fires only the post event when creating a post " do
pc = PostCreator . new ( user , topic_id : topic . id , raw : 'this is the new content for my post' )
2015-08-11 14:01:28 +08:00
_post = pc . create
2015-04-01 00:58:56 +08:00
expect ( @posts_created ) . to eq ( 1 )
expect ( @topics_created ) . to eq ( 0 )
end
end
2015-11-19 05:24:46 +08:00
context " staged users " do
let ( :staged ) { Fabricate ( :staged ) }
it " automatically watches all messages it participates in " do
post = PostCreator . create ( staged ,
title : " this is the title of a topic created by a staged user " ,
raw : " this is the content of a topic created by a staged user ;) "
)
topic_user = TopicUser . find_by ( user_id : staged . id , topic_id : post . topic_id )
expect ( topic_user . notification_level ) . to eq ( TopicUser . notification_levels [ :watching ] )
expect ( topic_user . notifications_reason_id ) . to eq ( TopicUser . notification_reasons [ :auto_watch ] )
end
2016-07-15 11:36:06 +08:00
end
2015-11-19 05:24:46 +08:00
2016-10-01 00:36:43 +08:00
context " topic tracking " do
it " automatically watches topic based on preference " do
user . user_option . notification_level_when_replying = 3
admin = Fabricate ( :admin )
topic = PostCreator . create ( admin ,
title : " this is the title of a topic created by an admin for watching notification " ,
raw : " this is the content of a topic created by an admin for keeping a watching notification state on a topic ;) "
)
post = PostCreator . create ( user ,
topic_id : topic . topic_id ,
raw : " this is a reply to set the tracking state to watching ;) "
)
topic_user = TopicUser . find_by ( user_id : user . id , topic_id : post . topic_id )
expect ( topic_user . notification_level ) . to eq ( TopicUser . notification_levels [ :watching ] )
end
it " topic notification level remains tracking based on preference " do
user . user_option . notification_level_when_replying = 2
admin = Fabricate ( :admin )
topic = PostCreator . create ( admin ,
title : " this is the title of a topic created by an admin for tracking notification " ,
raw : " this is the content of a topic created by an admin for keeping a tracking notification state on a topic ;) "
)
post = PostCreator . create ( user ,
topic_id : topic . topic_id ,
raw : " this is a reply to set the tracking state to tracking ;) "
)
topic_user = TopicUser . find_by ( user_id : user . id , topic_id : post . topic_id )
expect ( topic_user . notification_level ) . to eq ( TopicUser . notification_levels [ :tracking ] )
end
2017-04-21 10:33:10 +08:00
it " topic notification level is normal based on preference " do
user . user_option . notification_level_when_replying = 1
admin = Fabricate ( :admin )
topic = PostCreator . create ( admin ,
title : " this is the title of a topic created by an admin for tracking notification " ,
raw : " this is the content of a topic created by an admin for keeping a tracking notification state on a topic ;) "
)
post = PostCreator . create ( user ,
topic_id : topic . topic_id ,
raw : " this is a reply to set the tracking state to normal ;) "
)
topic_user = TopicUser . find_by ( user_id : user . id , topic_id : post . topic_id )
expect ( topic_user . notification_level ) . to eq ( TopicUser . notification_levels [ :regular ] )
end
2016-10-01 00:36:43 +08:00
end
2016-07-15 11:36:06 +08:00
describe '#create!' do
it " should return the post if it was successfully created " do
title = " This is a valid title "
raw = " This is a really awesome post "
post_creator = PostCreator . new ( user , title : title , raw : raw )
post = post_creator . create
expect ( post ) . to eq ( Post . last )
expect ( post . topic . title ) . to eq ( title )
expect ( post . raw ) . to eq ( raw )
end
it " should raise an error when post fails to be created " do
post_creator = PostCreator . new ( user , title : '' , raw : '' )
expect { post_creator . create! } . to raise_error ( ActiveRecord :: RecordNotSaved )
end
2015-11-19 05:24:46 +08:00
end
2017-01-04 03:51:35 +08:00
context " private message to a muted user " do
let ( :muted_me ) { Fabricate ( :evil_trout ) }
it 'should fail' do
updater = UserUpdater . new ( muted_me , muted_me )
updater . update_muted_users ( " #{ user . username } " )
pc = PostCreator . new (
user ,
title : 'this message is to someone who muted me!' ,
raw : " you will have to see this even if you muted me! " ,
archetype : Archetype . private_message ,
target_usernames : " #{ muted_me . username } "
)
expect ( pc ) . not_to be_valid
expect ( pc . errors ) . to be_present
end
let ( :staff_user ) { Fabricate ( :admin ) }
it 'succeeds if the user is staff' do
updater = UserUpdater . new ( muted_me , muted_me )
updater . update_muted_users ( " #{ staff_user . username } " )
pc = PostCreator . new (
staff_user ,
title : 'this message is to someone who muted me!' ,
raw : " you will have to see this even if you muted me! " ,
archetype : Archetype . private_message ,
target_usernames : " #{ muted_me . username } "
)
expect ( pc ) . to be_valid
expect ( pc . errors ) . to be_blank
end
end
2013-02-06 03:16:51 +08:00
end