2019-04-30 08:27:42 +08:00
# frozen_string_literal: true
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
2019-05-07 11:12:20 +08:00
fab! ( :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
2019-05-07 11:12:20 +08:00
fab! ( :category ) { Fabricate ( :category , user : user ) }
2017-07-28 09:20:09 +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 ) }
2017-07-28 09:20:09 +08:00
let ( :creator_with_category ) { PostCreator . new ( user , basic_topic_params . merge ( category : category . id ) ) }
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
2017-07-28 09:20:09 +08:00
post = PostCreator . create ( user , basic_topic_params . merge ( category : cat . id ) )
2016-12-18 21:38:55 +08:00
expect ( post . wiki ) . to eq ( true )
end
2018-07-05 17:07:46 +08:00
it " can be created with a hidden reason " do
hri = Post . hidden_reasons [ :flag_threshold_reached ]
post = PostCreator . create ( user , basic_topic_params . merge ( hidden_reason_id : hri ) )
expect ( post . hidden ) . to eq ( true )
expect ( post . hidden_at ) . to be_present
expect ( post . hidden_reason_id ) . to eq ( hri )
expect ( post . topic . visible ) . to eq ( false )
end
2013-07-08 10:44:55 +08:00
it " ensures the user can create the topic " do
2017-07-28 09:20:09 +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
2019-05-25 21:53:03 +08:00
it " can be created with custom fields " do
post = PostCreator . create ( user , basic_topic_params . merge ( topic_opts : { custom_fields : { hello : " world " } } ) )
expect ( post . topic . custom_fields ) . to eq ( " hello " = > " world " )
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
2018-07-05 17:07:46 +08:00
it " is not hidden " do
p = creator . create
expect ( p . hidden ) . to eq ( false )
expect ( p . hidden_at ) . not_to be_present
expect ( p . hidden_reason_id ) . to eq ( nil )
expect ( p . topic . visible ) . to eq ( true )
end
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
2017-06-01 15:19:43 +08:00
events = DiscourseEvent . track_events { creator . create }
expect ( events . map { | event | event [ :event_name ] } ) . to include (
:before_create_post ,
:validate_post ,
:topic_created ,
:post_created ,
:after_validate_topic ,
:before_create_topic ,
:after_trigger_post_process ,
:markdown_context ,
:topic_notification_level_changed ,
)
2015-04-24 01:33:29 +08:00
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 )
2017-07-28 09:20:09 +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
2019-01-04 01:03:01 +08:00
UserActionManager . enable
2016-12-22 12:03:40 +08:00
2013-05-16 13:03:03 +08:00
admin = Fabricate ( :admin )
cat = Fabricate ( :category )
2017-07-28 09:20:09 +08:00
cat . set_permissions ( admins : :full )
2013-05-16 13:03:03 +08:00
cat . save
created_post = 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
2019-10-31 06:01:26 +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
2020-03-11 05:13:17 +08:00
messages . filter! { | m | m . channel != " /distributed_hash " }
channels = messages . map { | m | m . channel } . sort
2014-06-25 08:55:50 +08:00
# 2 for topic, one to notify of new topic another for tracking state
2020-03-11 05:13:17 +08:00
expect ( channels ) . to eq (
[
" /new " ,
" /u/ #{ admin . username } " ,
" /u/ #{ admin . username } " ,
" /unread/ #{ admin . id } " ,
" /unread/ #{ admin . id } " ,
" /latest " ,
" /latest " ,
" /topic/ #{ created_post . topic_id } " ,
" /topic/ #{ created_post . topic_id } "
] . sort
)
2013-06-03 15:07:44 +08:00
2020-03-11 05:13:17 +08:00
admin_ids = [ Group [ :admins ] . id ]
2017-07-28 09:20:09 +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
2019-01-04 01:03:01 +08:00
UserActionManager . enable
2016-12-22 12:03:40 +08:00
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
2017-07-28 09:20:09 +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
2017-07-28 09:20:09 +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
2017-07-28 09:20:09 +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-07-28 09:20:09 +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
2019-05-01 21:44:45 +08:00
expect ( messages . filter { | m | m . channel != " /distributed_hash " } . 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
creator . create
2018-09-06 09:58:01 +08:00
post = Post . last
post_id = post . id
topic_id = post . topic_id
process_post_args = Jobs :: ProcessPost . jobs . first [ " args " ] . first
expect ( process_post_args [ " post_id " ] ) . to eq ( post_id )
feature_topic_users_args = Jobs :: FeatureTopicUsers . jobs . first [ " args " ] . first
expect ( feature_topic_users_args [ " topic_id " ] ) . to eq ( topic_id )
post_alert_args = Jobs :: PostAlert . jobs . first [ " args " ] . first
expect ( post_alert_args [ " post_id " ] ) . to eq ( post_id )
notify_mailing_list_subscribers_args =
Jobs :: NotifyMailingListSubscribers . jobs . first [ " args " ] . first
expect ( notify_mailing_list_subscribers_args [ " post_id " ] ) . to eq ( post_id )
2013-03-19 01:55:34 +08:00
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 ) )
2020-01-23 10:01:10 +08:00
Jobs . expects ( :enqueue ) . with ( :update_topic_upload_security , has_key ( :topic_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 ) )
2020-01-23 10:01:10 +08:00
Jobs . expects ( :enqueue ) . with ( :update_topic_upload_security , has_key ( :topic_id ) )
2013-03-19 01:55:34 +08:00
Jobs . expects ( :enqueue ) . with ( :process_post , has_key ( :image_sizes ) )
2017-07-28 09:20:09 +08:00
creator . opts [ :image_sizes ] = { 'http://an.image.host/image.jpg' = > { 'width' = > 17 , 'height' = > 31 } }
2013-03-19 01:55:34 +08:00
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
2018-12-04 12:13:34 +08:00
it 'supports custom excerpts' do
raw = << ~ MD
< div class = 'excerpt' >
I am
a custom excerpt
< / div>
testing
MD
post = create_post ( raw : raw )
expect ( post . excerpt ) . to eq ( " I am \n a custom excerpt " )
end
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
2017-11-21 21:59:55 +08:00
it " updates topic stats " do
first_post = creator . create
topic = first_post . topic . reload
2020-03-11 05:13:17 +08:00
expect ( topic . last_posted_at ) . to eq_time ( first_post . created_at )
2017-11-21 21:59:55 +08:00
expect ( topic . last_post_user_id ) . to eq ( first_post . user_id )
expect ( topic . word_count ) . to eq ( 4 )
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
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
2017-06-12 15:41:39 +08:00
it 'allows notification email to be skipped' do
user_2 = Fabricate ( :user )
creator = PostCreator . new ( user ,
title : 'hi there welcome to my topic' ,
raw : " this is my awesome message @ #{ user_2 . username_lower } " ,
archetype : Archetype . private_message ,
target_usernames : [ user_2 . username ] ,
post_alert_options : { skip_send_email : true }
)
NotificationEmailer . expects ( :process_notification ) . never
creator . create
end
2014-10-11 00:21:44 +08:00
describe " topic's auto close " do
it " doesn't update topic's auto close when it's not based on last post " do
2017-07-24 21:17:42 +08:00
freeze_time
2014-10-11 00:21:44 +08:00
2017-07-24 21:17:42 +08:00
topic = Fabricate ( :topic ) . set_or_create_timer ( TopicTimer . types [ :close ] , 12 )
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-07-24 21:17:42 +08:00
topic_status_update = TopicTimer . last
2020-03-11 05:13:17 +08:00
expect ( topic_status_update . execute_at ) . to eq_time ( 12 . hours . from_now )
expect ( topic_status_update . created_at ) . to eq_time ( Time . zone . now )
2014-10-11 00:21:44 +08:00
end
2018-04-23 13:32:08 +08:00
describe " topic's auto close based on last post " do
2019-05-07 11:12:20 +08:00
fab! ( :topic_timer ) do
2018-04-23 13:32:08 +08:00
Fabricate ( :topic_timer ,
based_on_last_post : true ,
execute_at : Time . zone . now - 12 . hours ,
created_at : Time . zone . now - 24 . hours
)
end
2017-03-22 11:12:02 +08:00
2018-04-23 13:32:08 +08:00
let ( :topic ) { topic_timer . topic }
2014-10-11 00:21:44 +08:00
2019-05-07 11:12:20 +08:00
fab! ( :post ) do
Fabricate ( :post , topic : topic_timer . topic )
2018-04-23 13:32:08 +08:00
end
2017-03-22 11:12:02 +08:00
2018-04-23 13:32:08 +08:00
it " updates topic's auto close date " do
freeze_time
post
PostCreator . new (
topic . user ,
topic_id : topic . id ,
raw : " this is a second post "
) . create
topic_timer . reload
2019-03-28 14:28:01 +08:00
expect ( topic_timer . execute_at ) . to eq_time ( Time . zone . now + 12 . hours )
expect ( topic_timer . created_at ) . to eq_time ( Time . zone . now )
2018-04-23 13:32:08 +08:00
end
describe " when auto_close_topics_post_count has been reached " do
before do
SiteSetting . auto_close_topics_post_count = 2
end
it " closes the topic and deletes the topic timer " do
freeze_time
post
PostCreator . new (
topic . user ,
topic_id : topic . id ,
raw : " this is a second post "
) . create
2014-10-11 00:21:44 +08:00
2018-04-23 13:32:08 +08:00
topic . reload
expect ( topic . posts . last . raw ) . to eq ( I18n . t (
'topic_statuses.autoclosed_topic_max_posts' ,
count : SiteSetting . auto_close_topics_post_count
) )
expect ( topic . closed ) . to eq ( true )
2019-03-28 14:28:01 +08:00
expect ( topic_timer . reload . deleted_at ) . to eq_time ( Time . zone . now )
2018-04-23 13:32:08 +08:00
end
end
end
2014-10-11 00:21:44 +08:00
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
2017-07-28 09:20:09 +08:00
expect { @post = creator_with_tags . create } . to change { Tag . count } . by ( tag_names . size )
2016-05-05 02:02:47 +08:00
expect ( @post . topic . tags . map ( & :name ) . sort ) . to eq ( tag_names . sort )
end
it " creates missing tags if some exist " do
2019-10-31 06:01:26 +08:00
_existing_tag1 = Fabricate ( :tag , name : tag_names [ 0 ] )
_existing_tag1 = Fabricate ( :tag , name : tag_names [ 1 ] )
2017-07-28 09:20:09 +08:00
expect { @post = creator_with_tags . create } . to change { Tag . count } . by ( tag_names . size - 2 )
2016-05-05 02:02:47 +08:00
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
2019-05-07 11:12:20 +08:00
fab! ( :topic ) { Fabricate ( :topic , user : user ) }
2015-09-25 23:28:41 +08:00
2016-12-02 14:03:31 +08:00
it 'whispers do not mess up the public view' do
2020-02-29 15:30:08 +08:00
# turns out this can fail on leap years if we don't do this
freeze_time DateTime . parse ( '2010-01-01 12:00' )
2019-10-31 06:01:26 +08:00
first = PostCreator . new (
user ,
2017-11-03 04:08:42 +08:00
topic_id : topic . id ,
2019-10-31 06:01:26 +08:00
raw : 'this is the first post'
) . create
freeze_time 1 . year . from_now
2017-11-03 04:08:42 +08:00
user_stat = user . user_stat
2016-12-02 14:03:31 +08:00
2015-09-25 23:28:41 +08:00
whisper = PostCreator . new ( user ,
2017-11-03 04:08:42 +08:00
topic_id : topic . id ,
reply_to_post_number : 1 ,
post_type : Post . types [ :whisper ] ,
raw : 'this is a whispered reply' ) . create
# don't count whispers in user stats
2017-11-10 07:05:53 +08:00
expect ( user_stat . reload . post_count ) . to eq ( 0 )
2015-09-25 23:28:41 +08:00
expect ( whisper ) . to be_present
expect ( whisper . post_type ) . to eq ( Post . types [ :whisper ] )
whisper_reply = PostCreator . new ( user ,
2017-11-03 04:08:42 +08:00
topic_id : topic . id ,
reply_to_post_number : whisper . post_number ,
post_type : Post . types [ :regular ] ,
raw : 'replying to a whisper this time' ) . create
2015-09-25 23:28:41 +08:00
expect ( whisper_reply ) . to be_present
expect ( whisper_reply . post_type ) . to eq ( Post . types [ :whisper ] )
2016-12-02 14:03:31 +08:00
2017-11-10 07:05:53 +08:00
expect ( user_stat . reload . post_count ) . to eq ( 0 )
2017-11-03 04:08:42 +08:00
2019-10-31 06:01:26 +08:00
user . reload
expect ( user . last_posted_at ) . to eq_time ( 1 . year . ago )
2017-05-26 03:07:12 +08:00
# date is not precise enough in db
whisper_reply . reload
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 )
2020-03-11 05:13:17 +08:00
expect ( topic . last_posted_at ) . to eq_time ( first . created_at )
2017-11-21 21:59:55 +08:00
expect ( topic . last_post_user_id ) . to eq ( first . user_id )
expect ( topic . word_count ) . to eq ( 5 )
2016-12-02 14:03:31 +08:00
2017-11-03 04:08:42 +08:00
topic . update_columns (
highest_staff_post_number : 0 ,
highest_post_number : 0 ,
posts_count : 0 ,
last_posted_at : 1 . year . ago
)
2016-12-02 14:03:31 +08:00
Topic . reset_highest ( topic . id )
topic . reload
expect ( topic . highest_post_number ) . to eq ( 1 )
expect ( topic . posts_count ) . to eq ( 1 )
2020-03-11 05:13:17 +08:00
expect ( topic . last_posted_at ) . to eq_time ( first . created_at )
2016-12-02 14:03:31 +08:00
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
2019-05-07 11:12:20 +08:00
fab! ( :topic ) { Fabricate ( :topic , user : user ) }
2017-07-28 09:20:09 +08:00
let ( :basic_topic_params ) { { raw : 'test reply' , topic_id : topic . id , reply_to_post_number : 4 } }
2013-03-19 01:55:34 +08:00
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
2019-01-08 15:02:51 +08:00
post = new_post_creator . create
expect ( post . errors [ :raw ] ) . to include ( I18n . t ( :just_posted_that ) )
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
2019-05-07 11:12:20 +08:00
fab! ( :topic ) { Fabricate ( :topic , user : user ) }
2017-07-28 09:20:09 +08:00
let ( :basic_topic_params ) { { raw : 'test reply' , topic_id : topic . id , reply_to_post_number : 4 } }
2013-05-11 04:58:23 +08:00
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 |
2017-07-28 09:20:09 +08:00
group_name == ( Group [ :moderators ] . name ) && msg_type == ( :spam_post_blocked ) && params [ :user ] . id == ( user . id )
2013-06-11 01:17:09 +08:00
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
2019-05-07 11:12:20 +08:00
fab! ( :topic ) { Fabricate ( :topic , user : user , title : 'topic title with 25 chars' ) }
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
2017-11-21 21:59:55 +08:00
context " topic stats " do
before do
PostCreator . new (
Fabricate ( :coding_horror ) ,
raw : 'first post in topic' ,
topic_id : topic . id ,
created_at : Time . zone . now - 24 . hours
) . create
end
it " updates topic stats " do
post = creator . create
topic . reload
2020-03-11 05:13:17 +08:00
expect ( topic . last_posted_at ) . to eq_time ( post . created_at )
2017-11-21 21:59:55 +08:00
expect ( topic . last_post_user_id ) . to eq ( post . user_id )
expect ( topic . word_count ) . to eq ( 6 )
end
it " updates topic stats even when topic fails validation " do
topic . update_columns ( title : 'below 15 chars' )
post = creator . create
topic . reload
2020-03-11 05:13:17 +08:00
expect ( topic . last_posted_at ) . to eq_time ( post . created_at )
2017-11-21 21:59:55 +08:00
expect ( topic . last_post_user_id ) . to eq ( post . user_id )
expect ( topic . word_count ) . to eq ( 6 )
end
end
2013-02-06 03:16:51 +08:00
end
2015-03-16 03:14:45 +08:00
context 'closed topic' do
2019-05-07 11:12:20 +08:00
fab! ( :topic ) { Fabricate ( :topic , user : user , closed : true ) }
2015-03-16 03:14:45 +08:00
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
2019-05-07 11:12:20 +08:00
let ( :topic ) { Fabricate ( :topic , user : user , deleted_at : 5 . minutes . ago ) }
2015-03-16 03:14:45 +08:00
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 ) }
2019-05-07 11:12:20 +08:00
fab! ( :target_user2 ) { Fabricate ( :moderator ) }
fab! ( :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
2019-10-31 06:01:26 +08:00
freeze_time
user . update_columns ( last_posted_at : 1 . year . ago )
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 )
2019-10-31 06:01:26 +08:00
user . reload
expect ( user . last_posted_at ) . to eq_time ( 1 . year . ago )
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' ,
2017-07-28 09:20:09 +08:00
topic_id : post . topic_id )
2013-09-06 12:07:23 +08:00
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
2019-03-08 16:49:34 +08:00
it 'does not increase posts count for small actions' do
topic = Fabricate ( :private_message_topic , user : Fabricate ( :user ) )
Fabricate ( :post , topic : topic )
1 . upto ( 3 ) do | i |
user = Fabricate ( :user )
topic . invite ( topic . user , user . username )
topic . reload
expect ( topic . posts_count ) . to eq ( 1 )
expect ( topic . posts . where ( post_type : Post . types [ :small_action ] ) . count ) . to eq ( i )
end
Fabricate ( :post , topic : topic )
Topic . reset_highest ( topic . id )
expect ( topic . reload . posts_count ) . to eq ( 2 )
Fabricate ( :post , topic : topic )
Topic . reset_all_highest!
expect ( topic . reload . posts_count ) . to eq ( 3 )
end
2013-02-06 03:16:51 +08:00
end
2014-09-08 23:11:56 +08:00
context " warnings " do
let ( :target_user1 ) { Fabricate ( :coding_horror ) }
2019-05-07 11:12:20 +08:00
fab! ( :target_user2 ) { Fabricate ( :moderator ) }
2014-09-08 23:11:56 +08:00
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 ] )
2018-04-23 13:32:08 +08:00
expect do
create_post ( user : post1 . user , topic_id : post1 . topic_id )
end . to change { Post . count } . by ( 2 )
2016-04-12 11:29:48 +08:00
post1 . topic . reload
2018-04-23 13:32:08 +08:00
expect ( post1 . topic . posts . last . raw ) . to eq ( I18n . t (
'topic_statuses.autoclosed_message_max_posts' ,
count : SiteSetting . auto_close_messages_post_count
) )
2016-04-12 11:29:48 +08:00
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
2018-04-23 13:32:08 +08:00
expect do
create_post ( user : post1 . user , topic_id : post1 . topic_id )
end . to change { Post . count } . by ( 2 )
2016-04-12 11:29:48 +08:00
post1 . topic . reload
2016-12-02 14:03:31 +08:00
2018-04-23 13:32:08 +08:00
expect ( post1 . topic . posts . last . raw ) . to eq ( I18n . t (
'topic_statuses.autoclosed_topic_max_posts' ,
count : SiteSetting . auto_close_topics_post_count
) )
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 ) }
2019-05-07 11:12:20 +08:00
fab! ( :target_user2 ) { Fabricate ( :moderator ) }
2013-05-02 13:15:17 +08:00
let ( :group ) do
2017-12-14 10:53:21 +08:00
g = Fabricate . build ( :group , messageable_level : Group :: ALIAS_LEVELS [ :everyone ] )
2013-05-02 13:15:17 +08:00
g . add ( target_user1 )
g . add ( target_user2 )
g . save
g
end
2019-05-07 11:12:20 +08:00
fab! ( :unrelated ) { Fabricate ( :user ) }
2013-05-02 13:15:17 +08:00
let ( :post ) do
2017-12-14 10:53:21 +08:00
PostCreator . create! ( user ,
title : 'hi there welcome to my topic' ,
raw : " this is my awesome message @ #{ unrelated . username_lower } " ,
archetype : Archetype . private_message ,
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
2019-03-14 22:47:38 +08:00
Jobs . run_immediately!
2018-05-31 15:53:49 +08:00
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
2020-03-10 00:38:13 +08:00
it 'supports Time instances' do
freeze_time
2013-05-19 03:24:29 +08:00
2020-03-10 00:38:13 +08:00
post1 = PostCreator . create ( user ,
raw : 'This is very interesting test post content' ,
title : 'This is a very interesting test post title' ,
created_at : 1 . week . ago
)
topic = post1 . topic
post2 = PostCreator . create ( user ,
raw : 'This is very interesting test post content' ,
topic_id : topic ,
created_at : 1 . week . ago
)
2020-03-11 05:13:17 +08:00
expect ( post1 . created_at ) . to eq_time ( 1 . week . ago )
expect ( post2 . created_at ) . to eq_time ( 1 . week . ago )
expect ( topic . created_at ) . to eq_time ( 1 . week . ago )
2013-05-19 03:24:29 +08:00
end
2020-03-10 00:38:13 +08:00
it 'supports strings' do
freeze_time
time = Time . zone . parse ( '2019-09-02' )
post1 = PostCreator . create ( user ,
raw : 'This is very interesting test post content' ,
title : 'This is a very interesting test post title' ,
created_at : '2019-09-02'
)
topic = post1 . topic
post2 = PostCreator . create ( user ,
raw : 'This is very interesting test post content' ,
topic_id : topic ,
created_at : '2019-09-02 00:00:00 UTC'
)
2020-03-11 05:13:17 +08:00
expect ( post1 . created_at ) . to eq_time ( time )
expect ( post2 . created_at ) . to eq_time ( time )
expect ( topic . created_at ) . to eq_time ( time )
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 ,
2017-07-28 09:20:09 +08:00
post_number : post . post_number ,
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 ,
2017-07-28 09:20:09 +08:00
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 )
2017-07-28 09:20:09 +08:00
creator = PostCreator . new ( user , title : " my test title 123 " , raw : " I should not be allowed to post " )
2014-07-31 11:15:16 +08:00
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
2017-07-28 09:20:09 +08:00
pc = PostCreator . new ( user , title : " testing whitespace stripping " , raw : " <-- whitespaces --> " )
2015-03-27 04:57:50 +08:00
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
2019-05-07 11:12:20 +08:00
fab! ( :staged ) { Fabricate ( :staged ) }
2015-11-19 05:24:46 +08:00
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
2018-08-23 12:36:49 +08:00
it " user preferences for notification level when replying doesn't affect PMs " do
user . user_option . update! ( notification_level_when_replying : 1 )
admin = Fabricate ( :admin )
pm = Fabricate ( :private_message_topic , user : admin )
pm . invite ( admin , user . username )
PostCreator . create (
user ,
topic_id : pm . id ,
raw : " this is a test reply 123 123 ;) "
)
topic_user = TopicUser . find_by ( user_id : user . id , topic_id : pm . id )
expect ( topic_user . notification_level ) . to eq ( 3 )
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
2019-03-16 00:58:43 +08:00
it " does not generate an alert for empty posts " do
Jobs . run_immediately!
user2 = Fabricate ( :user )
topic = Fabricate ( :private_message_topic ,
topic_allowed_users : [
Fabricate . build ( :topic_allowed_user , user : user ) ,
Fabricate . build ( :topic_allowed_user , user : user2 )
] ,
)
Fabricate ( :topic_user ,
topic : topic ,
user : user2 ,
notification_level : TopicUser . notification_levels [ :watching ]
)
expect {
PostCreator . create! ( user , raw : " " , topic_id : topic . id , skip_validations : true )
} . to change { user2 . notifications . count } . by ( 0 )
expect {
PostCreator . create! ( user , raw : " hello world " , topic_id : topic . id , skip_validations : true )
} . to change { user2 . notifications . count } . by ( 1 )
end
2015-11-19 05:24:46 +08:00
end
2017-10-06 15:56:58 +08:00
context 'private message to a user that has disabled private messages' do
2019-05-07 11:12:20 +08:00
fab! ( :another_user ) { Fabricate ( :user ) }
2017-10-06 15:56:58 +08:00
before do
another_user . user_option . update! ( allow_private_messages : false )
end
it 'should not be valid' do
post_creator = 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 : " #{ another_user . username } "
)
expect ( post_creator ) . to_not be_valid
expect ( post_creator . errors . full_messages ) . to include ( I18n . t (
" not_accepting_pms " , username : another_user . username
) )
end
end
2017-01-04 03:51:35 +08:00
context " private message to a muted user " do
2019-05-07 11:12:20 +08:00
fab! ( :muted_me ) { Fabricate ( :evil_trout ) }
fab! ( :another_user ) { Fabricate ( :user ) }
2017-01-04 03:51:35 +08:00
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 ,
2018-11-29 03:47:45 +08:00
target_usernames : " #{ muted_me . username } , #{ another_user . username } "
2017-01-04 03:51:35 +08:00
)
2018-11-29 03:47:45 +08:00
2017-01-04 03:51:35 +08:00
expect ( pc ) . not_to be_valid
2018-11-29 03:47:45 +08:00
expect ( pc . errors . full_messages ) . to contain_exactly (
I18n . t ( :not_accepting_pms , username : muted_me . username )
)
2017-01-04 03:51:35 +08:00
end
2019-05-07 11:12:20 +08:00
fab! ( :staff_user ) { Fabricate ( :admin ) }
2017-01-04 03:51:35 +08:00
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
2017-07-06 01:09:45 +08:00
2019-03-21 19:15:34 +08:00
context " private message to an ignored user " do
2019-05-07 11:12:20 +08:00
fab! ( :ignorer ) { Fabricate ( :evil_trout ) }
fab! ( :another_user ) { Fabricate ( :user ) }
2019-03-21 19:15:34 +08:00
context " when post author is ignored " do
let! ( :ignored_user ) { Fabricate ( :ignored_user , user : ignorer , ignored_user : user ) }
it 'should fail' do
pc = PostCreator . new (
user ,
title : 'this message is to someone who ignored me!' ,
raw : " you will have to see this even if you ignored me! " ,
archetype : Archetype . private_message ,
target_usernames : " #{ ignorer . username } , #{ another_user . username } "
)
expect ( pc ) . not_to be_valid
expect ( pc . errors . full_messages ) . to contain_exactly (
I18n . t ( :not_accepting_pms , username : ignorer . username )
)
end
end
context " when post author is admin who is ignored " do
2019-05-07 11:12:20 +08:00
fab! ( :staff_user ) { Fabricate ( :admin ) }
fab! ( :ignored_user ) { Fabricate ( :ignored_user , user : ignorer , ignored_user : staff_user ) }
2019-03-21 19:15:34 +08:00
it 'succeeds if the user is staff' do
pc = PostCreator . new (
staff_user ,
title : 'this message is to someone who ignored me!' ,
raw : " you will have to see this even if you ignored me! " ,
archetype : Archetype . private_message ,
target_usernames : " #{ ignorer . username } "
)
expect ( pc ) . to be_valid
expect ( pc . errors ) . to be_blank
end
end
end
2017-07-06 01:09:45 +08:00
context " private message recipients limit (max_allowed_message_recipients) reached " do
2019-05-07 11:12:20 +08:00
fab! ( :target_user1 ) { Fabricate ( :coding_horror ) }
fab! ( :target_user2 ) { Fabricate ( :evil_trout ) }
fab! ( :target_user3 ) { Fabricate ( :walter_white ) }
2017-07-06 01:09:45 +08:00
before do
SiteSetting . max_allowed_message_recipients = 2
end
context " for normal user " do
it 'fails when sending message to multiple recipients' do
pc = PostCreator . new (
user ,
title : 'this message is for multiple recipients!' ,
raw : " Lorem ipsum dolor sit amet, id elitr praesent mea, ut ius facilis fierent. " ,
archetype : Archetype . private_message ,
target_usernames : [ target_user1 . username , target_user2 . username , target_user3 . username ] . join ( ',' )
)
expect ( pc ) . not_to be_valid
expect ( pc . errors ) . to be_present
end
it 'succeeds when sending message to multiple recipients if skip_validations is true' do
pc = PostCreator . new (
user ,
title : 'this message is for multiple recipients!' ,
raw : " Lorem ipsum dolor sit amet, id elitr praesent mea, ut ius facilis fierent. " ,
archetype : Archetype . private_message ,
target_usernames : [ target_user1 . username , target_user2 . username , target_user3 . username ] . join ( ',' ) ,
skip_validations : true
)
expect ( pc ) . to be_valid
expect ( pc . errors ) . to be_blank
end
end
context " always succeeds if the user is staff " do
2019-05-07 11:12:20 +08:00
fab! ( :staff_user ) { Fabricate ( :admin ) }
2017-07-06 01:09:45 +08:00
it 'when sending message to multiple recipients' do
pc = PostCreator . new (
staff_user ,
title : 'this message is for multiple recipients!' ,
raw : " Lorem ipsum dolor sit amet, id elitr praesent mea, ut ius facilis fierent. " ,
archetype : Archetype . private_message ,
target_usernames : [ target_user1 . username , target_user2 . username , target_user3 . username ] . join ( ',' )
)
expect ( pc ) . to be_valid
expect ( pc . errors ) . to be_blank
end
end
end
2019-03-08 16:48:35 +08:00
context " # create_post_notice " do
2019-05-07 11:12:20 +08:00
fab! ( :user ) { Fabricate ( :user ) }
fab! ( :staged ) { Fabricate ( :staged ) }
fab! ( :anonymous ) { Fabricate ( :anonymous ) }
2019-03-08 16:48:35 +08:00
2019-03-11 17:19:58 +08:00
it " generates post notices for new users " do
2019-04-19 22:53:58 +08:00
post = PostCreator . create! ( user , title : " one of my first topics " , raw : " one of my first posts " )
2019-11-25 20:32:19 +08:00
expect ( post . custom_fields [ Post :: NOTICE_TYPE ] ) . to eq ( Post . notices [ :new_user ] )
2019-04-19 22:53:58 +08:00
post = PostCreator . create! ( user , title : " another one of my first topics " , raw : " another one of my first posts " )
2019-11-25 20:32:19 +08:00
expect ( post . custom_fields [ Post :: NOTICE_TYPE ] ) . to eq ( nil )
2019-03-11 17:19:58 +08:00
end
2019-03-08 16:48:35 +08:00
2019-03-11 17:19:58 +08:00
it " generates post notices for returning users " do
2019-03-08 16:48:35 +08:00
SiteSetting . returning_users_days = 30
2019-03-11 17:19:58 +08:00
old_post = Fabricate ( :post , user : user , created_at : 31 . days . ago )
2020-01-15 18:40:19 +08:00
2019-04-19 22:53:58 +08:00
post = PostCreator . create! ( user , title : " this is a returning topic " , raw : " this is a post " )
2019-11-25 20:32:19 +08:00
expect ( post . custom_fields [ Post :: NOTICE_TYPE ] ) . to eq ( Post . notices [ :returning_user ] )
expect ( post . custom_fields [ Post :: NOTICE_ARGS ] ) . to eq ( old_post . created_at . iso8601 )
2019-03-08 16:48:35 +08:00
2019-04-19 22:53:58 +08:00
post = PostCreator . create! ( user , title : " this is another topic " , raw : " this is my another post " )
2019-11-25 20:32:19 +08:00
expect ( post . custom_fields [ Post :: NOTICE_TYPE ] ) . to eq ( nil )
expect ( post . custom_fields [ Post :: NOTICE_ARGS ] ) . to eq ( nil )
2019-03-08 16:48:35 +08:00
end
2019-03-11 17:19:58 +08:00
2019-04-19 22:53:58 +08:00
it " does not generate for non-human, staged or anonymous users " do
SiteSetting . allow_anonymous_posting = true
[ anonymous , Discourse . system_user , staged ] . each do | user |
2019-03-11 17:19:58 +08:00
expect ( user . posts . size ) . to eq ( 0 )
2019-04-19 22:53:58 +08:00
post = PostCreator . create! ( user , title : " #{ user . username } 's first topic " , raw : " #{ user . name } 's first post " )
2019-11-25 20:32:19 +08:00
expect ( post . custom_fields [ Post :: NOTICE_TYPE ] ) . to eq ( nil )
expect ( post . custom_fields [ Post :: NOTICE_ARGS ] ) . to eq ( nil )
2019-03-11 17:19:58 +08:00
end
end
2019-03-08 16:48:35 +08:00
end
2019-11-18 09:25:42 +08:00
context " secure media uploads " do
fab! ( :image_upload ) { Fabricate ( :upload , secure : true ) }
fab! ( :user2 ) { Fabricate ( :user ) }
fab! ( :public_topic ) { Fabricate ( :topic ) }
before do
SiteSetting . enable_s3_uploads = true
SiteSetting . authorized_extensions = " png|jpg|gif|mp4 "
SiteSetting . s3_upload_bucket = " s3-upload-bucket "
SiteSetting . s3_access_key_id = " some key "
SiteSetting . s3_secret_access_key = " some secret key "
2019-12-11 22:13:17 +08:00
SiteSetting . s3_region = " us-east-1 "
2019-11-18 09:25:42 +08:00
SiteSetting . secure_media = true
2019-12-12 03:26:52 +08:00
stub_request ( :head , " https:// #{ SiteSetting . s3_upload_bucket } .s3.amazonaws.com/ " )
2019-11-18 09:25:42 +08:00
stub_request (
:put ,
2019-12-12 03:26:52 +08:00
" https:// #{ SiteSetting . s3_upload_bucket } .s3.amazonaws.com/original/1X/ #{ image_upload . sha1 } . #{ image_upload . extension } ?acl "
2019-11-18 09:25:42 +08:00
)
end
2020-01-16 11:50:27 +08:00
it " links post uploads " do
2020-02-29 15:30:08 +08:00
_public_post = PostCreator . create (
2019-11-18 09:25:42 +08:00
user ,
topic_id : public_topic . id ,
raw : " A public post with an image. \n ![]( #{ image_upload . short_path } ) "
)
2019-11-21 22:13:33 +08:00
end
2019-11-18 09:25:42 +08:00
end
2013-02-06 03:16:51 +08:00
end