2019-04-30 08:27:42 +08:00
# frozen_string_literal: true
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
2022-07-28 10:27:38 +08:00
RSpec . describe PostCreator do
2019-05-07 11:12:20 +08:00
fab! ( :user ) { Fabricate ( :user ) }
2021-12-23 01:09:43 +08:00
fab! ( :admin ) { Fabricate ( :admin ) }
2021-12-16 01:41:14 +08:00
fab! ( :coding_horror ) { Fabricate ( :coding_horror ) }
fab! ( :evil_trout ) { Fabricate ( :evil_trout ) }
2016-07-15 11:36:06 +08:00
let ( :topic ) { Fabricate ( :topic , user : user ) }
2013-02-06 03:16:51 +08:00
2022-07-28 00:14:14 +08:00
describe " new topic " do
2019-05-07 11:12:20 +08:00
fab! ( :category ) { Fabricate ( :category , user : user ) }
2022-02-09 16:37:38 +08:00
let ( :basic_topic_params ) { { title : " hello world topic " , raw : " my name is fred " , archetype_id : 1 , advance_draft : true } }
2013-07-08 10:44:55 +08:00
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
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 )
2022-02-11 09:00:58 +08:00
expect ( post . user . topic_count ) . to eq ( 0 )
expect ( post . user . post_count ) . to eq ( 0 )
2018-07-05 17:07:46 +08:00
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
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
2022-07-28 00:14:14 +08:00
context " with reply to post number " do
2015-09-23 01:32:19 +08:00
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
2022-07-28 00:14:14 +08:00
context " with invalid title " do
2013-06-08 00:36:37 +08:00
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
2022-07-28 00:14:14 +08:00
context " with invalid raw " do
2013-10-23 09:14:31 +08:00
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
2022-07-28 00:14:14 +08:00
context " with 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
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
2021-01-12 04:58:27 +08:00
it 'enqueues job to generate messages' do
p = creator . create
expect ( job_enqueued? ( job : :post_update_topic_tracking_state , args : { post_id : p . id } ) ) . to eq ( true )
end
2013-05-16 13:03:03 +08:00
2021-01-12 04:58:27 +08:00
it " generates the correct messages for a secure topic " do
Jobs . run_immediately!
2019-01-04 01:03:01 +08:00
UserActionManager . enable
2016-12-22 12:03:40 +08:00
2021-08-11 11:01:13 +08:00
admin = Fabricate ( :user )
admin . grant_admin!
FIX: Issues with incorrect unread and private message topic tracking state (#16474)
This commit fixes two issues at play. The first was introduced
in f6c852b (or maybe not introduced
but rather revealed). When a user posted a new message in a topic,
they received the unread topic tracking state MessageBus message,
and the Unread (X) indicator was incremented by one, because with the
aforementioned perf commit we "guess" the correct last read post
for the user, because we no longer calculate individual users' read
status there. This meant that every time a user posted in a topic
they tracked, the unread indicator was incremented. To get around
this, we can just exclude the user who created the post from the
target users of the unread state message.
The second issue was related to the private message topic tracking
state, and was somewhat similar. Whenever a user created a new private
message, the New (X) indicator was incremented, and could not be
cleared until the page was refreshed. To solve this, we just don't
update the topic state for the user when the new_topic tracking state
message comes through if the user who created the topic is the
same as the current user.
cf. https://meta.discourse.org/t/bottom-of-topic-shows-there-is-1-unread-remaining-when-there-are-actually-0-unread-topics-remaining/220817
2022-04-19 09:37:01 +08:00
other_admin = Fabricate ( :user )
other_admin . grant_admin!
2013-05-16 13:03:03 +08:00
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
FIX: Issues with incorrect unread and private message topic tracking state (#16474)
This commit fixes two issues at play. The first was introduced
in f6c852b (or maybe not introduced
but rather revealed). When a user posted a new message in a topic,
they received the unread topic tracking state MessageBus message,
and the Unread (X) indicator was incremented by one, because with the
aforementioned perf commit we "guess" the correct last read post
for the user, because we no longer calculate individual users' read
status there. This meant that every time a user posted in a topic
they tracked, the unread indicator was incremented. To get around
this, we can just exclude the user who created the post from the
target users of the unread state message.
The second issue was related to the private message topic tracking
state, and was somewhat similar. Whenever a user created a new private
message, the New (X) indicator was incremented, and could not be
cleared until the page was refreshed. To solve this, we just don't
update the topic state for the user when the new_topic tracking state
message comes through if the user who created the topic is the
same as the current user.
cf. https://meta.discourse.org/t/bottom-of-topic-shows-there-is-1-unread-remaining-when-there-are-actually-0-unread-topics-remaining/220817
2022-04-19 09:37:01 +08:00
other_user_tracking_topic = nil
2013-05-16 13:03:03 +08:00
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
FIX: Issues with incorrect unread and private message topic tracking state (#16474)
This commit fixes two issues at play. The first was introduced
in f6c852b (or maybe not introduced
but rather revealed). When a user posted a new message in a topic,
they received the unread topic tracking state MessageBus message,
and the Unread (X) indicator was incremented by one, because with the
aforementioned perf commit we "guess" the correct last read post
for the user, because we no longer calculate individual users' read
status there. This meant that every time a user posted in a topic
they tracked, the unread indicator was incremented. To get around
this, we can just exclude the user who created the post from the
target users of the unread state message.
The second issue was related to the private message topic tracking
state, and was somewhat similar. Whenever a user created a new private
message, the New (X) indicator was incremented, and could not be
cleared until the page was refreshed. To solve this, we just don't
update the topic state for the user when the new_topic tracking state
message comes through if the user who created the topic is the
same as the current user.
cf. https://meta.discourse.org/t/bottom-of-topic-shows-there-is-1-unread-remaining-when-there-are-actually-0-unread-topics-remaining/220817
2022-04-19 09:37:01 +08:00
Fabricate ( :topic_user_tracking , topic : created_post . topic , user : other_admin )
2022-02-09 16:37:38 +08:00
_reply = PostCreator . new ( admin , raw : " this is my test reply 123 testing " , topic_id : created_post . topic_id , advance_draft : true ) . 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
2022-06-28 05:21:05 +08:00
# 3 for topic, one to notify of new topic, one for topic stats and another for tracking state
2020-03-11 05:13:17 +08:00
expect ( channels ) . to eq (
[
" /new " ,
" /u/ #{ admin . username } " ,
" /u/ #{ admin . username } " ,
2022-02-22 23:27:46 +08:00
" /unread " ,
2020-03-11 05:13:17 +08:00
" /unread/ #{ admin . id } " ,
" /latest " ,
" /latest " ,
" /topic/ #{ created_post . topic_id } " ,
2021-07-29 22:06:11 +08:00
" /topic/ #{ created_post . topic_id } " ,
2022-06-28 05:21:05 +08:00
" /topic/ #{ created_post . topic_id } " ,
2022-06-17 12:24:15 +08:00
" /user-drafts/ #{ admin . id } " ,
" /user-drafts/ #{ admin . id } " ,
" /user-drafts/ #{ admin . id } " ,
2020-03-11 05:13:17 +08:00
] . sort
)
2013-06-03 15:07:44 +08:00
2020-03-11 05:13:17 +08:00
admin_ids = [ Group [ :admins ] . id ]
FIX: Issues with incorrect unread and private message topic tracking state (#16474)
This commit fixes two issues at play. The first was introduced
in f6c852b (or maybe not introduced
but rather revealed). When a user posted a new message in a topic,
they received the unread topic tracking state MessageBus message,
and the Unread (X) indicator was incremented by one, because with the
aforementioned perf commit we "guess" the correct last read post
for the user, because we no longer calculate individual users' read
status there. This meant that every time a user posted in a topic
they tracked, the unread indicator was incremented. To get around
this, we can just exclude the user who created the post from the
target users of the unread state message.
The second issue was related to the private message topic tracking
state, and was somewhat similar. Whenever a user created a new private
message, the New (X) indicator was incremented, and could not be
cleared until the page was refreshed. To solve this, we just don't
update the topic state for the user when the new_topic tracking state
message comes through if the user who created the topic is the
same as the current user.
cf. https://meta.discourse.org/t/bottom-of-topic-shows-there-is-1-unread-remaining-when-there-are-actually-0-unread-topics-remaining/220817
2022-04-19 09:37:01 +08:00
expect ( messages . any? { | m | m . group_ids != admin_ids && ( ! m . user_ids . include? ( other_admin . id ) && ! m . user_ids . include? ( 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
2021-01-12 04:58:27 +08:00
Jobs . run_immediately!
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
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
2022-06-17 12:24:15 +08:00
draft_count = messages . find { | m | m . channel == " /user-drafts/ #{ p . user_id } " }
2021-08-04 18:30:37 +08:00
expect ( draft_count ) . not_to eq ( nil )
2022-06-28 05:21:05 +08:00
topics_stats = messages . find { | m | m . channel == " /topic/ #{ p . topic . id } " && m . data [ :type ] == :stats }
expect ( topics_stats ) . to eq ( nil )
2021-08-04 18:30:37 +08:00
expect ( messages . filter { | m | m . channel != " /distributed_hash " } . length ) . to eq ( 7 )
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
creator . opts [ :invalidate_oneboxes ] = true
creator . create
2020-07-24 17:16:52 +08:00
expect ( job_enqueued? ( job : :process_post , args : { invalidate_oneboxes : true } ) ) . to eq ( true )
2013-03-19 01:55:34 +08:00
end
it 'passes the image_sizes along to the job if present' do
2020-07-24 17:16:52 +08:00
image_sizes = { 'http://an.image.host/image.jpg' = > { 'width' = > 17 , 'height' = > 31 } }
creator . opts [ :image_sizes ] = image_sizes
2013-03-19 01:55:34 +08:00
creator . create
2020-07-24 17:16:52 +08:00
expect ( job_enqueued? ( job : :process_post , args : { image_sizes : image_sizes } ) ) . to eq ( true )
2013-03-19 01:55:34 +08:00
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
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
2020-05-12 11:13:18 +08:00
Draft . set ( user , Draft :: NEW_TOPIC , 0 , " test " )
Draft . set ( user , Draft :: NEW_TOPIC , 0 , " test1 " )
2021-07-29 22:06:11 +08:00
expect ( user . user_stat . draft_count ) . to eq ( 1 )
2015-08-03 12:29:04 +08:00
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 )
2021-07-29 22:06:11 +08:00
expect ( user . reload . user_stat . draft_count ) . to eq ( 0 )
2015-08-03 12:29:04 +08:00
ensure
PostCreator . track_post_stats = false
end
end
2022-02-09 16:37:38 +08:00
it 'clears the draft if advanced_draft is true' do
creator = PostCreator . new ( user , basic_topic_params . merge ( advance_draft : true ) )
Draft . set ( user , Draft :: NEW_TOPIC , 0 , 'test' )
expect ( Draft . where ( user : user ) . size ) . to eq ( 1 )
expect { creator . create } . to change { Draft . count } . by ( - 1 )
end
it 'does not clear the draft if advanced_draft is false' do
creator = PostCreator . new ( user , basic_topic_params . merge ( advance_draft : false ) )
Draft . set ( user , Draft :: NEW_TOPIC , 0 , 'test' )
expect ( Draft . where ( user : user ) . size ) . to eq ( 1 )
2022-07-19 22:03:03 +08:00
expect { creator . create } . not_to change { Draft . count }
2022-02-09 16:37:38 +08:00
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 ,
2020-03-20 00:15:05 +08:00
created_at : Time . zone . now - 24 . hours ,
2021-02-05 08:12:56 +08:00
duration_minutes : 12 * 60
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
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
2020-08-17 22:40:47 +08:00
it " uses the system locale for the message " do
post
I18n . with_locale ( :fr ) do
PostCreator . new (
topic . user ,
topic_id : topic . id ,
raw : " this is a second post "
) . create
end
topic . reload
expect ( topic . posts . last . raw ) . to eq ( I18n . t (
'topic_statuses.autoclosed_topic_max_posts' ,
count : SiteSetting . auto_close_topics_post_count ,
locale : :en
) )
end
2020-11-02 14:48:48 +08:00
describe " auto_close_topics_create_linked_topic is enabled " do
before do
SiteSetting . auto_close_topics_create_linked_topic = true
end
it " enqueues a job to create a new linked topic " do
freeze_time
post
post_2 = PostCreator . new (
topic . user ,
topic_id : topic . id ,
raw : " this is a second post "
) . create
topic . reload
expect ( topic . closed ) . to eq ( true )
expect ( topic_timer . reload . deleted_at ) . to eq_time ( Time . zone . now )
expect ( job_enqueued? ( job : :create_linked_topic , args : { post_id : post_2 . id } ) ) . to eq ( true )
end
end
2018-04-23 13:32:08 +08:00
end
end
2014-10-11 00:21:44 +08:00
end
2022-07-28 00:14:14 +08:00
context " with tags " do
2016-05-05 02:02:47 +08:00
let ( :tag_names ) { [ 'art' , 'science' , 'dance' ] }
let ( :creator_with_tags ) { PostCreator . new ( user , basic_topic_params . merge ( tags : tag_names ) ) }
2022-07-28 00:14:14 +08:00
context " with tagging disabled " do
2016-05-05 02:02:47 +08:00
before do
SiteSetting . tagging_enabled = false
end
it " doesn't create tags " do
2022-07-19 22:03:03 +08:00
expect { @post = creator_with_tags . create } . not_to change { Tag . count }
2020-08-11 06:14:15 +08:00
expect ( @post . topic & . tags & . size ) . to eq ( nil )
2016-05-05 02:02:47 +08:00
end
end
2022-07-28 00:14:14 +08:00
context " with tagging enabled " do
2016-05-05 02:02:47 +08:00
before do
SiteSetting . tagging_enabled = true
end
2022-07-28 00:14:14 +08:00
context " when can create tags " do
2016-05-05 02:02:47 +08:00
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
2019-10-31 06:01:26 +08:00
_existing_tag1 = Fabricate ( :tag , name : tag_names [ 0 ] )
_existing_tag1 = Fabricate ( :tag , name : tag_names [ 1 ] )
2016-05-05 02:02:47 +08:00
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
2022-07-28 00:14:14 +08:00
context " when cannot create tags " do
2016-05-05 02:02:47 +08:00
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 ] )
2022-07-19 22:03:03 +08:00
expect { @post = creator_with_tags . create } . not_to change { Tag . count }
2016-05-05 02:02:47 +08:00
expect ( @post . topic . tags . map ( & :name ) ) . to eq ( [ existing_tag1 . name ] )
end
end
2021-04-23 21:55:34 +08:00
2022-07-28 00:14:14 +08:00
context " when automatically tagging first posts " do
2021-04-23 21:55:34 +08:00
before do
SiteSetting . min_trust_to_create_tag = 0
SiteSetting . min_trust_level_to_tag_topics = 0
2022-06-28 03:16:33 +08:00
Fabricate ( :tag , name : 'greetings' )
Fabricate ( :tag , name : 'hey' )
Fabricate ( :tag , name : 'about-art' )
Fabricate ( :tag , name : 'about-artists' )
2021-04-23 21:55:34 +08:00
end
context " without regular expressions " do
2021-06-18 23:54:06 +08:00
it " works with many tags " do
2022-06-28 03:16:33 +08:00
Fabricate ( :watched_word , action : WatchedWord . actions [ :tag ] , word : " HELLO " , replacement : " greetings,hey " )
2021-04-23 21:55:34 +08:00
2021-05-14 21:52:10 +08:00
@post = creator . create
expect ( @post . topic . tags . map ( & :name ) ) . to match_array ( [ 'greetings' , 'hey' ] )
2021-04-23 21:55:34 +08:00
end
2021-06-18 23:54:06 +08:00
it " works with overlapping words " do
Fabricate ( :watched_word , action : WatchedWord . actions [ :tag ] , word : " art " , replacement : " about-art " )
Fabricate ( :watched_word , action : WatchedWord . actions [ :tag ] , word : " artist* " , replacement : " about-artists " )
post = PostCreator . new ( user , title : " hello world topic " , raw : " this is topic abour artists " , archetype_id : 1 ) . create
expect ( post . topic . tags . map ( & :name ) ) . to match_array ( [ 'about-artists' ] )
end
2021-04-23 21:55:34 +08:00
it " does not treat as regular expressions " do
2022-06-28 03:16:33 +08:00
Fabricate ( :watched_word , action : WatchedWord . actions [ :tag ] , word : " he(llo|y) " , replacement : " greetings,hey " )
2021-04-23 21:55:34 +08:00
@post = creator_with_tags . create
expect ( @post . topic . tags . map ( & :name ) ) . to match_array ( tag_names )
end
end
context " with regular expressions " do
it " works " do
SiteSetting . watched_words_regular_expressions = true
2022-06-28 03:16:33 +08:00
Fabricate ( :watched_word , action : WatchedWord . actions [ :tag ] , word : " he(llo|y) " , replacement : " greetings,hey " )
2021-04-23 21:55:34 +08:00
@post = creator_with_tags . create
expect ( @post . topic . tags . map ( & :name ) ) . to match_array ( tag_names + [ 'greetings' , 'hey' ] )
end
end
end
2016-05-05 02:02:47 +08:00
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
2022-07-28 00:14:14 +08:00
describe '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
2022-07-28 00:14:14 +08:00
describe 'silent' do
2020-12-03 07:43:19 +08:00
fab! ( :topic ) { Fabricate ( :topic , user : user ) }
it 'silent do not mess up the public view' do
freeze_time DateTime . parse ( '2010-01-01 12:00' )
first = PostCreator . new (
user ,
topic_id : topic . id ,
raw : 'this is the first post'
) . create
freeze_time 1 . year . from_now
PostCreator . new ( user ,
topic_id : topic . id ,
reply_to_post_number : 1 ,
silent : true ,
post_type : Post . types [ :regular ] ,
raw : 'this is a whispered reply' ) . create
topic . reload
# silent post should not muck up that number
expect ( topic . last_posted_at ) . to eq_time ( first . created_at )
expect ( topic . last_post_user_id ) . to eq ( first . user_id )
expect ( topic . word_count ) . to eq ( 5 )
end
end
2022-07-28 00:14:14 +08:00
describe 'uniqueness' do
2019-05-07 11:12:20 +08:00
fab! ( :topic ) { Fabricate ( :topic , user : user ) }
2013-03-19 01:55:34 +08:00
let ( :basic_topic_params ) { { raw : 'test reply' , topic_id : topic . id , reply_to_post_number : 4 } }
let ( :creator ) { PostCreator . new ( user , basic_topic_params ) }
2022-07-28 00:14:14 +08:00
context " when disabled " do
2013-03-19 01:55:34 +08:00
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
2022-07-28 00:14:14 +08:00
context 'when enabled' do
2013-03-19 01:55:34 +08:00
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
2021-05-21 09:43:47 +08:00
it " fails for dupe post across 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
2022-07-28 00:14:14 +08:00
describe " host spam " do
2019-05-07 11:12:20 +08:00
fab! ( :topic ) { Fabricate ( :topic , user : user ) }
2013-05-11 04:58:23 +08:00
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 ) && msg_type == ( :spam_post_blocked ) && params [ :user ] . id == ( user . id )
end
creator . create
end
2021-04-21 19:41:36 +08:00
it 'does not create a reviewable post if the review_every_post setting is enabled' do
SiteSetting . review_every_post = true
GroupMessage . stubs ( :create )
2022-07-19 22:03:03 +08:00
expect { creator . create } . not_to change ( ReviewablePost , :count )
2021-04-21 19:41:36 +08:00
end
2013-05-11 04:58:23 +08:00
end
2013-04-17 15:33:34 +08:00
# more integration testing ... maximise our testing
2022-07-28 00:14:14 +08:00
describe '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
2022-07-28 00:14:14 +08:00
context 'with 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
2020-07-21 08:00:39 +08:00
context " when the user has bookmarks with auto_delete_preference on_owner_reply " do
before do
2022-05-23 08:07:15 +08:00
Fabricate ( :bookmark , user : user , bookmarkable : Fabricate ( :post , topic : topic ) , auto_delete_preference : Bookmark . auto_delete_preferences [ :on_owner_reply ] )
Fabricate ( :bookmark , user : user , bookmarkable : Fabricate ( :post , topic : topic ) , auto_delete_preference : Bookmark . auto_delete_preferences [ :on_owner_reply ] )
2020-07-29 07:43:32 +08:00
TopicUser . create! ( topic : topic , user : user , bookmarked : true )
end
it " deletes the bookmarks, but not the ones without an auto_delete_preference " do
2022-05-23 08:07:15 +08:00
Fabricate ( :bookmark , bookmarkable : Fabricate ( :post , topic : topic ) , user : user )
2020-07-21 08:00:39 +08:00
Fabricate ( :bookmark , user : user )
creator . create
expect ( Bookmark . where ( user : user ) . count ) . to eq ( 2 )
2020-07-29 07:43:32 +08:00
expect ( TopicUser . find_by ( topic : topic , user : user ) . bookmarked ) . to eq ( true )
end
context " when there are no bookmarks left in the topic " do
it " sets TopicUser.bookmarked to false " do
creator . create
expect ( TopicUser . find_by ( topic : topic , user : user ) . bookmarked ) . to eq ( false )
end
2020-07-21 08:00:39 +08:00
end
end
2022-07-28 00:14:14 +08:00
context " with topic stats " do
2017-11-21 21:59:55 +08:00
before do
PostCreator . new (
2021-12-16 01:41:14 +08:00
coding_horror ,
2017-11-21 21:59:55 +08:00
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
2022-06-28 05:21:05 +08:00
it " publishes updates to topic stats " do
reply_timestamp = 1 . day . from_now . round
# tests if messages of type :stats are published and the relevant data is fetched from the topic
messages = MessageBus . track_publish ( " /topic/ #{ topic . id } " ) do
PostCreator . new (
evil_trout ,
raw : 'other post in topic' ,
topic_id : topic . id ,
created_at : reply_timestamp
) . create
end
stats_message = messages . select { | msg | msg . data [ :type ] == :stats } . first
expect ( stats_message ) . to be_present
expect ( stats_message . data [ :posts_count ] ) . to eq ( 2 )
expect ( stats_message . data [ :last_posted_at ] ) . to eq ( reply_timestamp . as_json )
expect ( stats_message . data [ :last_poster ] ) . to eq ( BasicUserSerializer . new ( evil_trout , root : false ) . as_json )
end
2017-11-21 21:59:55 +08:00
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
2020-10-17 03:24:38 +08:00
context 'when the topic is in slow mode' do
before do
one_day = 86400
topic . update! ( slow_mode_seconds : one_day )
end
it 'fails if the user recently posted in this topic' do
TopicUser . create! ( user : user , topic : topic , last_posted_at : 10 . minutes . ago )
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 ( :slow_mode_enabled )
end
it 'creates the topic if the user last post is older than the slow mode interval' do
TopicUser . create! ( user : user , topic : topic , last_posted_at : 5 . days . ago )
post = creator . create
expect ( post ) . to be_present
expect ( creator . errors . count ) . to be_zero
end
2020-10-29 03:47:50 +08:00
it 'creates the topic if the user is a staff member' do
post_creator = PostCreator . new ( admin , raw : 'test reply' , topic_id : topic . id , reply_to_post_number : 4 )
TopicUser . create! ( user : admin , topic : topic , last_posted_at : 10 . minutes . ago )
post = post_creator . create
expect ( post ) . to be_present
expect ( post_creator . errors . count ) . to be_zero
end
2020-10-17 03:24:38 +08:00
end
2013-02-06 03:16:51 +08:00
end
2022-07-28 00:14:14 +08:00
describe '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
2022-07-28 00:14:14 +08:00
describe '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
2022-07-28 00:14:14 +08:00
describe " cooking options " do
2013-06-21 23:36:33 +08:00
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
2022-07-28 00:14:14 +08:00
describe 'private message' do
2021-12-16 01:41:14 +08:00
let ( :target_user1 ) { coding_horror }
2019-05-07 11:12:20 +08:00
fab! ( :target_user2 ) { Fabricate ( :moderator ) }
2021-07-23 11:35:01 +08:00
fab! ( :unrelated_user ) { Fabricate ( :user ) }
2015-03-23 14:21:58 +08:00
let ( :post ) do
2021-07-23 16:01:51 +08:00
PostCreator . create! ( user ,
title : 'hi there welcome to my topic' ,
raw : " this is my awesome message @ #{ unrelated_user . username_lower } " ,
archetype : Archetype . private_message ,
target_usernames : [ target_user1 . username , target_user2 . username ] . join ( ',' ) ,
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
2021-07-23 11:35:01 +08:00
expect ( unrelated_user . notifications . count ) . to eq ( 0 )
2015-01-10 00:34:37 +08:00
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
2021-07-23 16:01:51 +08:00
PostCreator . create! ( admin ,
raw : 'hi there welcome topic, I am a mod' ,
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 )
2021-07-23 11:35:01 +08:00
PostCreator . create! ( admin2 , raw : 'I am also an admin, and a mod' , topic_id : post . topic_id )
2016-01-12 10:57:45 +08:00
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
2021-07-23 11:35:01 +08:00
it 'does not add whisperers to allowed users of the topic' do
SiteSetting . enable_whispers = true
unrelated_user . update! ( admin : true )
PostCreator . create! (
unrelated_user ,
raw : " This is a whisper that I am testing " ,
topic_id : post . topic_id ,
post_type : Post . types [ :whisper ]
)
expect ( post . topic . topic_allowed_users . map ( & :user_id ) ) . to contain_exactly (
target_user1 . id , target_user2 . id , user . id
)
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
2022-07-28 00:14:14 +08:00
describe " warnings " do
2021-12-16 01:41:14 +08:00
let ( :target_user1 ) { 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
2022-07-28 00:14:14 +08:00
describe 'auto closing' do
2016-04-12 11:29:48 +08:00
it 'closes private messages that have more than N posts' do
SiteSetting . auto_close_messages_post_count = 2
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
2022-07-28 00:14:14 +08:00
describe 'private message to group' do
2021-12-16 01:41:14 +08:00
let ( :target_user1 ) { 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 )
2021-09-10 09:20:50 +08:00
GroupArchivedMessage . create! ( group : group , topic : post . topic )
message = MessageBus . track_publish (
PrivateMessageTopicTrackingState . group_channel ( group . id )
) do
PostCreator . create! ( user ,
raw : " this is a reply to the group message " ,
topic_id : post . topic_id
)
end . first
expect ( message . data [ " message_type " ] ) . to eq (
PrivateMessageTopicTrackingState :: GROUP_ARCHIVE_MESSAGE_TYPE
)
expect ( message . data [ " payload " ] [ " acting_user_id " ] ) . to eq ( user . id )
expect ( GroupArchivedMessage . exists? ( group : group , topic : post . topic ) )
. to eq ( false )
2013-05-02 13:15:17 +08:00
end
end
2013-05-19 03:24:29 +08:00
2022-07-28 00:14:14 +08:00
describe '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
2022-07-28 00:14:14 +08:00
describe 'disable validations' do
2013-07-02 10:22:56 +08:00
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
2022-07-28 00:14:14 +08:00
describe " events " do
2015-04-01 00:58:56 +08:00
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
2021-05-21 09:43:47 +08:00
it " fires both event when creating a topic " do
2015-04-01 00:58:56 +08:00
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
2022-07-28 00:14:14 +08:00
describe " 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
2022-07-28 00:14:14 +08:00
describe " topic tracking " do
2016-10-01 00:36:43 +08:00
it " automatically watches topic based on preference " do
user . user_option . notification_level_when_replying = 3
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
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
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 )
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
2020-10-17 03:24:38 +08:00
it 'sets the last_posted_at timestamp to track the last time the user posted' do
topic = Fabricate ( :topic )
PostCreator . create (
user ,
topic_id : topic . id ,
raw : " this is a test reply 123 123 ;) "
)
topic_user = TopicUser . find_by ( user_id : user . id , topic_id : topic . id )
expect ( topic_user . last_posted_at ) . to be_present
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 )
2022-07-19 22:03:03 +08:00
} . not_to change { user2 . notifications . count }
2019-03-16 00:58:43 +08:00
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
2022-07-28 00:14:14 +08:00
describe 'private message to a user that has disabled private messages' do
2020-06-18 02:26:14 +08:00
fab! ( :another_user ) { Fabricate ( :user , username : 'HelloWorld' ) }
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
2020-06-18 02:26:14 +08:00
it 'should not be valid if the name is downcased' 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 . downcase } "
)
expect ( post_creator ) . to_not be_valid
end
2017-10-06 15:56:58 +08:00
end
2022-07-28 00:14:14 +08:00
describe " private message to a muted user " do
2021-12-16 01:41:14 +08:00
fab! ( :muted_me ) { evil_trout }
2019-05-07 11:12:20 +08:00
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
2022-07-28 00:14:14 +08:00
describe " private message to an ignored user " do
2021-12-16 01:41:14 +08:00
fab! ( :ignorer ) { evil_trout }
2019-05-07 11:12:20 +08:00
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
2022-07-28 00:14:14 +08:00
describe " private message to user in allow list " do
2021-12-16 01:41:14 +08:00
fab! ( :sender ) { evil_trout }
2020-07-21 05:23:49 +08:00
fab! ( :allowed_user ) { Fabricate ( :user ) }
context " when post author is allowed " do
let! ( :allowed_pm_user ) { Fabricate ( :allowed_pm_user , user : allowed_user , allowed_pm_user : sender ) }
it 'should succeed' do
allowed_user . user_option . update! ( enable_allowed_pm_users : true )
pc = PostCreator . new (
sender ,
title : 'this message is to someone who is in my allow list!' ,
raw : " you will have to see this because I'm in your allow list! " ,
archetype : Archetype . private_message ,
target_usernames : " #{ allowed_user . username } "
)
expect ( pc ) . to be_valid
expect ( pc . errors ) . to be_blank
end
end
context " when personal messages are disabled " do
let! ( :allowed_pm_user ) { Fabricate ( :allowed_pm_user , user : allowed_user , allowed_pm_user : sender ) }
it 'should fail' do
allowed_user . user_option . update! ( allow_private_messages : false )
allowed_user . user_option . update! ( enable_allowed_pm_users : true )
pc = PostCreator . new (
sender ,
title : 'this message is to someone who is in my allow list!' ,
raw : " you will have to see this because I'm in your allow list! " ,
archetype : Archetype . private_message ,
target_usernames : " #{ allowed_user . username } "
)
expect ( pc ) . not_to be_valid
expect ( pc . errors . full_messages ) . to contain_exactly (
I18n . t ( :not_accepting_pms , username : allowed_user . username )
)
end
end
end
2022-07-28 00:14:14 +08:00
describe " private message to user not in allow list " do
2021-12-16 01:41:14 +08:00
fab! ( :sender ) { evil_trout }
2020-07-21 05:23:49 +08:00
fab! ( :allowed_user ) { Fabricate ( :user ) }
fab! ( :not_allowed_user ) { Fabricate ( :user ) }
context " when post author is not allowed " do
let! ( :allowed_pm_user ) { Fabricate ( :allowed_pm_user , user : not_allowed_user , allowed_pm_user : allowed_user ) }
it 'should fail' do
not_allowed_user . user_option . update! ( enable_allowed_pm_users : true )
pc = PostCreator . new (
sender ,
title : 'this message is to someone who is not in my allowed list!' ,
raw : " you will have to see this even if you don't want message from me! " ,
archetype : Archetype . private_message ,
target_usernames : " #{ not_allowed_user . username } "
)
expect ( pc ) . not_to be_valid
expect ( pc . errors . full_messages ) . to contain_exactly (
I18n . t ( :not_accepting_pms , username : not_allowed_user . username )
)
end
it 'should succeed when not enabled' do
not_allowed_user . user_option . update! ( enable_allowed_pm_users : false )
pc = PostCreator . new (
sender ,
title : 'this message is to someone who is not in my allowed list!' ,
raw : " you will have to see this even if you don't want message from me! " ,
archetype : Archetype . private_message ,
target_usernames : " #{ not_allowed_user . username } "
)
expect ( pc ) . to be_valid
expect ( pc . errors ) . to be_blank
end
end
end
2022-07-28 00:14:14 +08:00
describe " private message when post author is admin who is not in allow list " do
2020-07-21 05:23:49 +08:00
fab! ( :staff_user ) { Fabricate ( :admin ) }
fab! ( :allowed_user ) { Fabricate ( :user ) }
fab! ( :not_allowed_user ) { Fabricate ( :user ) }
fab! ( :allowed_pm_user ) { Fabricate ( :allowed_pm_user , user : staff_user , allowed_pm_user : allowed_user ) }
it 'succeeds if the user is staff' do
pc = PostCreator . new (
staff_user ,
title : 'this message is to someone who did not allow me!' ,
raw : " you will have to see this even if you did not allow me! " ,
archetype : Archetype . private_message ,
target_usernames : " #{ not_allowed_user . username } "
)
expect ( pc ) . to be_valid
expect ( pc . errors ) . to be_blank
end
end
2022-07-28 00:14:14 +08:00
describe " private message to multiple users and one is not allowed " do
2021-12-16 01:41:14 +08:00
fab! ( :sender ) { evil_trout }
2020-07-21 05:23:49 +08:00
fab! ( :allowed_user ) { Fabricate ( :user ) }
fab! ( :not_allowed_user ) { Fabricate ( :user ) }
context " when post author is not allowed " do
let! ( :allowed_pm_user ) { Fabricate ( :allowed_pm_user , user : allowed_user , allowed_pm_user : sender ) }
it 'should fail' do
allowed_user . user_option . update! ( enable_allowed_pm_users : true )
not_allowed_user . user_option . update! ( enable_allowed_pm_users : true )
pc = PostCreator . new (
sender ,
title : 'this message is to someone who is not in my allowed list!' ,
raw : " you will have to see this even if you don't want message from me! " ,
archetype : Archetype . private_message ,
target_usernames : " #{ allowed_user . username } , #{ not_allowed_user . username } "
)
expect ( pc ) . not_to be_valid
expect ( pc . errors . full_messages ) . to contain_exactly (
I18n . t ( :not_accepting_pms , username : not_allowed_user . username )
)
end
end
end
2022-07-28 00:14:14 +08:00
describe " private message recipients limit (max_allowed_message_recipients) reached " do
2021-12-16 01:41:14 +08:00
fab! ( :target_user1 ) { coding_horror }
fab! ( :target_user2 ) { evil_trout }
2019-05-07 11:12:20 +08:00
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
2022-07-28 00:14:14 +08:00
context " 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
2022-07-28 00:14:14 +08:00
it 'succeeds when sending message to multiple recipients' do
2017-07-06 01:09:45 +08:00
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
2022-07-27 18:21:10 +08:00
describe " # 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 " )
2020-11-11 20:49:53 +08:00
expect ( post . custom_fields [ Post :: NOTICE ] ) . to eq ( " type " = > 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 " )
2020-11-11 20:49:53 +08:00
expect ( post . custom_fields [ Post :: NOTICE ] ) . 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 " )
2020-11-11 20:49:53 +08:00
expect ( post . custom_fields [ Post :: NOTICE ] ) . to eq ( " type " = > Post . notices [ :returning_user ] , " last_posted_at " = > 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 " )
2020-11-11 20:49:53 +08:00
expect ( post . custom_fields [ Post :: NOTICE ] ) . 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 " )
2020-11-11 20:49:53 +08:00
expect ( post . custom_fields [ Post :: NOTICE ] ) . 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
2022-07-28 00:14:14 +08:00
describe " secure media uploads " do
2019-11-18 09:25:42 +08:00
fab! ( :image_upload ) { Fabricate ( :upload , secure : true ) }
fab! ( :user2 ) { Fabricate ( :user ) }
fab! ( :public_topic ) { Fabricate ( :topic ) }
before do
2020-09-14 19:32:25 +08:00
setup_s3
2019-11-18 09:25:42 +08:00
SiteSetting . authorized_extensions = " png|jpg|gif|mp4 "
SiteSetting . secure_media = true
2020-09-14 19:32:25 +08:00
stub_upload ( image_upload )
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
2021-04-21 19:41:36 +08:00
2022-07-28 00:14:14 +08:00
describe 'queue for review' do
2021-04-21 19:41:36 +08:00
before { SiteSetting . review_every_post = true }
it 'created a reviewable post after creating the post' do
title = " This is a valid title "
raw = " This is a really awesome post "
post_creator = PostCreator . new ( user , title : title , raw : raw )
expect { post_creator . create } . to change ( ReviewablePost , :count ) . by ( 1 )
end
it 'does not create a reviewable post if the post is not valid' do
post_creator = PostCreator . new ( user , title : '' , raw : '' )
2022-07-19 22:03:03 +08:00
expect { post_creator . create } . not_to change ( ReviewablePost , :count )
2021-04-21 19:41:36 +08:00
end
end
2013-02-06 03:16:51 +08:00
end