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
|
2023-12-13 11:50:13 +08:00
|
|
|
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
|
2024-03-26 11:41:12 +08:00
|
|
|
fab!(:admin)
|
2023-12-13 11:50:13 +08:00
|
|
|
fab!(:coding_horror) { Fabricate(:coding_horror, refresh_auto_groups: true) }
|
|
|
|
fab!(:evil_trout) { Fabricate(:evil_trout, refresh_auto_groups: true) }
|
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) do
|
|
|
|
{ title: "hello world topic", raw: "my name is fred", archetype_id: 1, advance_draft: true }
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
2013-07-08 10:44:55 +08:00
|
|
|
let(:image_sizes) do
|
|
|
|
{ "http://an.image.host/image.jpg" => { "width" => 111, "height" => 222 } }
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
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) do
|
|
|
|
PostCreator.new(user, basic_topic_params.merge(category: category.id))
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
2013-02-06 03:16:51 +08:00
|
|
|
let(:creator_with_image_sizes) do
|
|
|
|
PostCreator.new(user, basic_topic_params.merge(image_sizes: image_sizes))
|
2016-12-10 02:28:12 +08:00
|
|
|
end
|
|
|
|
let(:creator_with_featured_link) do
|
|
|
|
PostCreator.new(
|
|
|
|
user,
|
|
|
|
title: "featured link topic",
|
|
|
|
archetype_id: 1,
|
|
|
|
featured_link: "http://www.discourse.org",
|
|
|
|
raw: "http://www.discourse.org",
|
|
|
|
)
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
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
|
|
|
|
|
2022-12-01 23:04:05 +08:00
|
|
|
it "creates post with a hidden reason for staff user" do
|
2018-07-05 17:07:46 +08:00
|
|
|
hri = Post.hidden_reasons[:flag_threshold_reached]
|
2022-12-01 23:04:05 +08:00
|
|
|
post = PostCreator.create(admin, basic_topic_params.merge(hidden_reason_id: hri))
|
2018-07-05 17:07:46 +08:00
|
|
|
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
|
|
|
|
|
2022-12-01 23:04:05 +08:00
|
|
|
it "fails to create post with a hidden reason for non-staff user" do
|
|
|
|
hri = Post.hidden_reasons[:flag_threshold_reached]
|
|
|
|
|
|
|
|
expect do
|
|
|
|
post = PostCreator.create(user, basic_topic_params.merge(hidden_reason_id: hri))
|
|
|
|
|
|
|
|
expect(post).to be_nil
|
|
|
|
end.not_to change { Post.count }
|
|
|
|
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" } }),
|
|
|
|
)
|
2023-10-10 11:23:56 +08:00
|
|
|
|
2019-05-25 21:53:03 +08:00
|
|
|
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
|
|
|
|
|
2022-11-22 00:11:29 +08:00
|
|
|
it "before_create_post event signature contains both post and opts" do
|
|
|
|
events = DiscourseEvent.track_events { creator.create }
|
|
|
|
|
|
|
|
expect(events).to include(
|
|
|
|
event_name: :before_create_post,
|
|
|
|
params: [creator.post, creator.opts],
|
|
|
|
)
|
|
|
|
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],
|
2023-01-09 19:18:21 +08:00
|
|
|
),
|
2013-07-08 10:44:55 +08:00
|
|
|
)
|
|
|
|
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
|
|
|
|
|
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? do |m|
|
|
|
|
m.group_ids != admin_ids &&
|
|
|
|
(!m.user_ids.include?(other_admin.id) && !m.user_ids.include?(admin.id))
|
2023-01-09 19:18:21 +08:00
|
|
|
end,
|
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
|
|
|
).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 { p = creator.create }
|
2013-05-16 13:03:03 +08:00
|
|
|
|
2024-03-19 01:05:46 +08:00
|
|
|
expect(messages.find { _1.channel == "/latest" }).not_to eq(nil)
|
|
|
|
expect(messages.find { _1.channel == "/new" }).not_to eq(nil)
|
|
|
|
expect(messages.find { _1.channel == "/unread/#{p.user_id}" }).not_to eq(nil)
|
|
|
|
expect(messages.find { _1.channel == "/user-drafts/#{p.user_id}" }).not_to eq(nil)
|
2014-08-05 11:40:44 +08:00
|
|
|
|
2024-03-19 01:05:46 +08:00
|
|
|
user_action = messages.find { _1.channel == "/u/#{p.user.username}" }
|
|
|
|
expect(user_action).to eq(nil)
|
2021-08-04 18:30:37 +08:00
|
|
|
|
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)
|
|
|
|
|
2024-03-19 01:05:46 +08:00
|
|
|
expect(messages.filter { _1.channel != "/distributed_hash" }.size).to eq(6)
|
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 "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\na 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) { Fabricate(:post, topic: topic_timer.topic) }
|
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 { SiteSetting.auto_close_topics_post_count = 2 }
|
|
|
|
|
|
|
|
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,
|
2023-01-09 19:18:21 +08:00
|
|
|
),
|
2018-04-23 13:32:08 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
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,
|
2023-01-09 19:18:21 +08:00
|
|
|
),
|
2020-08-17 22:40:47 +08:00
|
|
|
)
|
|
|
|
end
|
2020-11-02 14:48:48 +08:00
|
|
|
|
|
|
|
describe "auto_close_topics_create_linked_topic is enabled" do
|
|
|
|
before { SiteSetting.auto_close_topics_create_linked_topic = true }
|
|
|
|
|
|
|
|
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) { %w[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 { SiteSetting.tagging_enabled = false }
|
|
|
|
|
|
|
|
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 { SiteSetting.tagging_enabled = true }
|
|
|
|
|
2022-07-28 00:14:14 +08:00
|
|
|
context "when can create tags" do
|
2016-05-05 02:02:47 +08:00
|
|
|
before do
|
2024-01-05 10:19:43 +08:00
|
|
|
SiteSetting.create_tag_allowed_groups = Group::AUTO_GROUPS[:trust_level_0]
|
2024-01-26 13:25:03 +08:00
|
|
|
SiteSetting.tag_topic_allowed_groups = Group::AUTO_GROUPS[:trust_level_0]
|
2016-05-05 02:02:47 +08:00
|
|
|
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
|
2024-01-05 10:19:43 +08:00
|
|
|
SiteSetting.create_tag_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
|
2024-01-26 13:25:03 +08:00
|
|
|
SiteSetting.tag_topic_allowed_groups = Group::AUTO_GROUPS[:trust_level_0]
|
2016-05-05 02:02:47 +08:00
|
|
|
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
|
2024-01-05 10:19:43 +08:00
|
|
|
SiteSetting.create_tag_allowed_groups = Group::AUTO_GROUPS[:trust_level_0]
|
2024-01-26 13:25:03 +08:00
|
|
|
SiteSetting.tag_topic_allowed_groups = Group::AUTO_GROUPS[:trust_level_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(%w[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",
|
2023-01-09 19:18:21 +08:00
|
|
|
)
|
|
|
|
|
2021-06-18 23:54:06 +08:00
|
|
|
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 + %w[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
|
2024-03-01 08:07:35 +08:00
|
|
|
freeze_time_safe
|
2019-10-31 06:01:26 +08:00
|
|
|
|
|
|
|
first = PostCreator.new(user, topic_id: topic.id, 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,
|
2024-05-17 23:05:49 +08:00
|
|
|
word_count: 0,
|
2017-11-03 04:08:42 +08:00
|
|
|
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)
|
2024-05-17 23:05:49 +08:00
|
|
|
expect(topic.word_count).to eq(5)
|
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
|
2024-03-01 08:07:35 +08:00
|
|
|
freeze_time_safe
|
2020-12-03 07:43:19 +08: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) }
|
|
|
|
|
2014-07-14 13:59:58 +08:00
|
|
|
before { SiteSetting.unique_posts_mins = 10 }
|
|
|
|
|
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 { Post.any_instance.expects(:has_host_spam?).returns(true) }
|
|
|
|
|
|
|
|
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) do
|
|
|
|
PostCreator.new(user, raw: "test reply", topic_id: topic.id, reply_to_post_number: 4)
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
2013-02-06 03:16:51 +08:00
|
|
|
|
|
|
|
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 = 86_400
|
|
|
|
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) do
|
|
|
|
PostCreator.new(user, raw: "test reply", topic_id: topic.id, reply_to_post_number: 4)
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
2015-03-16 03:14:45 +08:00
|
|
|
|
|
|
|
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) do
|
|
|
|
PostCreator.new(user, raw: "test reply", topic_id: topic.id, reply_to_post_number: 4)
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
2015-03-16 03:14:45 +08:00
|
|
|
|
|
|
|
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
|
|
|
|
2023-09-13 13:43:54 +08:00
|
|
|
it "respects min_personal_message_post_length" do
|
|
|
|
SiteSetting.min_personal_message_post_length = 5
|
|
|
|
SiteSetting.min_first_post_length = 20
|
|
|
|
SiteSetting.min_post_length = 25
|
|
|
|
SiteSetting.body_min_entropy = 20
|
2024-01-25 14:28:26 +08:00
|
|
|
user.change_trust_level!(TrustLevel[3])
|
2023-09-13 13:43:54 +08:00
|
|
|
|
|
|
|
expect {
|
|
|
|
PostCreator.create!(
|
|
|
|
user,
|
|
|
|
title: "hi there welcome to my PM",
|
|
|
|
raw: "sorry",
|
|
|
|
archetype: Archetype.private_message,
|
|
|
|
target_usernames: [target_user1.username, target_user2.username].join(","),
|
|
|
|
category: 1,
|
|
|
|
)
|
|
|
|
}.not_to raise_error
|
|
|
|
end
|
|
|
|
|
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
|
2022-12-17 00:42:51 +08:00
|
|
|
SiteSetting.whispers_allowed_groups = "#{Group::AUTO_GROUPS[:staff]}"
|
2021-07-23 11:35:01 +08:00
|
|
|
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
|
|
|
|
|
2022-08-29 18:01:16 +08:00
|
|
|
it "does not add whisperers to allowed users of the topic" do
|
|
|
|
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[:small_action],
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(post.topic.topic_allowed_users.map(&:user_id)).to contain_exactly(
|
|
|
|
target_user1.id,
|
|
|
|
target_user2.id,
|
|
|
|
user.id,
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2024-05-17 23:05:49 +08:00
|
|
|
it "does not increase posts/words count for small actions" do
|
2024-01-25 14:28:26 +08:00
|
|
|
topic = Fabricate(:private_message_topic, user: Fabricate(:user, refresh_auto_groups: true))
|
2019-03-08 16:49:34 +08:00
|
|
|
|
2024-05-17 23:05:49 +08:00
|
|
|
p1 = Fabricate(:post, topic: topic)
|
2019-03-08 16:49:34 +08:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2024-05-17 23:05:49 +08:00
|
|
|
expect(topic.word_count).to eq(0)
|
|
|
|
|
|
|
|
p2 = Fabricate(:post, topic: topic)
|
2019-03-08 16:49:34 +08:00
|
|
|
Topic.reset_highest(topic.id)
|
2024-05-17 23:05:49 +08:00
|
|
|
topic.reload
|
|
|
|
expect(topic.posts_count).to eq(2)
|
|
|
|
expect(topic.word_count).to eq([p1, p2].sum(&:word_count))
|
2019-03-08 16:49:34 +08:00
|
|
|
|
2024-05-17 23:05:49 +08:00
|
|
|
p3 = Fabricate(:post, topic: topic)
|
2019-03-08 16:49:34 +08:00
|
|
|
Topic.reset_all_highest!
|
2024-05-17 23:05:49 +08:00
|
|
|
topic.reload
|
|
|
|
expect(topic.posts_count).to eq(3)
|
|
|
|
expect(topic.word_count).to eq([p1, p2, p3].sum(&:word_count))
|
2019-03-08 16:49:34 +08:00
|
|
|
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(","),
|
2023-01-09 19:18:21 +08:00
|
|
|
),
|
2014-09-08 23:11:56 +08:00
|
|
|
)
|
|
|
|
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,
|
2023-01-09 19:18:21 +08:00
|
|
|
),
|
2018-04-23 13:32:08 +08:00
|
|
|
)
|
|
|
|
|
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,
|
2023-01-09 19:18:21 +08:00
|
|
|
),
|
2018-04-23 13:32:08 +08:00
|
|
|
)
|
|
|
|
|
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
|
2022-10-05 08:50:20 +08:00
|
|
|
fab!(:target_user1) { coding_horror }
|
2019-05-07 11:12:20 +08:00
|
|
|
fab!(:target_user2) { Fabricate(:moderator) }
|
2022-10-05 08:50:20 +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)
|
2023-12-12 22:35:26 +08:00
|
|
|
end
|
2015-06-16 00:08:55 +08:00
|
|
|
|
2023-12-12 22:35:26 +08:00
|
|
|
it "does not create topics with the same embed url" do
|
|
|
|
PostCreator.create(
|
|
|
|
user,
|
|
|
|
embed_url: embed_url,
|
|
|
|
title: "Reviews of Science Ovens",
|
|
|
|
raw: "Did you know that you can use microwaves to cook your dinner? Science!",
|
|
|
|
)
|
2015-06-16 00:08:55 +08:00
|
|
|
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
|
2023-12-12 22:35:26 +08:00
|
|
|
|
|
|
|
it "sets the embed content sha1" do
|
|
|
|
content = "Did you know that you can use microwaves to cook your dinner? Science!"
|
|
|
|
content_sha1 = Digest::SHA1.hexdigest(content)
|
|
|
|
creator =
|
|
|
|
PostCreator.new(
|
|
|
|
user,
|
|
|
|
embed_url: embed_url,
|
|
|
|
embed_content_sha1: content_sha1,
|
|
|
|
title: "Reviews of Science Ovens",
|
|
|
|
raw: content,
|
|
|
|
)
|
|
|
|
creator.create
|
|
|
|
expect(creator.errors).to be_blank
|
|
|
|
expect(TopicEmbed.where(content_sha1: content_sha1).exists?).to eq(true)
|
|
|
|
end
|
2024-03-27 20:57:43 +08:00
|
|
|
|
|
|
|
context "when embed_unlisted is true" do
|
|
|
|
before { SiteSetting.embed_unlisted = true }
|
|
|
|
|
|
|
|
it "unlists the topic" 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!",
|
|
|
|
)
|
|
|
|
post = creator.create
|
|
|
|
expect(creator.errors).to be_blank
|
|
|
|
expect(post.topic).not_to be_visible
|
|
|
|
end
|
|
|
|
end
|
2014-04-04 02:42:26 +08:00
|
|
|
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
|
2023-01-09 19:18:21 +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
|
2023-12-13 11:50:13 +08:00
|
|
|
fab!(:staged) { Fabricate(:staged, refresh_auto_groups: true) }
|
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 { another_user.user_option.update!(allow_private_messages: false) }
|
|
|
|
|
|
|
|
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) do
|
|
|
|
Fabricate(:allowed_pm_user, user: allowed_user, allowed_pm_user: sender)
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
2020-07-21 05:23:49 +08:00
|
|
|
|
|
|
|
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) do
|
|
|
|
Fabricate(:allowed_pm_user, user: allowed_user, allowed_pm_user: sender)
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
2020-07-21 05:23:49 +08:00
|
|
|
|
|
|
|
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) do
|
|
|
|
Fabricate(:allowed_pm_user, user: not_allowed_user, allowed_pm_user: allowed_user)
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
2020-07-21 05:23:49 +08:00
|
|
|
|
|
|
|
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) do
|
|
|
|
Fabricate(:allowed_pm_user, user: staff_user, allowed_pm_user: allowed_user)
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
2020-07-21 05:23:49 +08:00
|
|
|
|
|
|
|
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) do
|
|
|
|
Fabricate(:allowed_pm_user, user: allowed_user, allowed_pm_user: sender)
|
2023-01-09 19:18:21 +08:00
|
|
|
end
|
2020-07-21 05:23:49 +08:00
|
|
|
|
|
|
|
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 { SiteSetting.max_allowed_message_recipients = 2 }
|
|
|
|
|
|
|
|
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
|
2023-12-13 11:50:13 +08:00
|
|
|
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
|
|
|
|
fab!(:staged) { Fabricate(:staged, refresh_auto_groups: true) }
|
|
|
|
fab!(:anonymous) { Fabricate(:anonymous, refresh_auto_groups: true) }
|
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
|
|
|
|
2023-10-19 07:48:01 +08:00
|
|
|
describe "secure 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"
|
2022-09-29 07:24:33 +08:00
|
|
|
SiteSetting.secure_uploads = 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
|
2023-10-19 07:48:01 +08:00
|
|
|
public_post =
|
2020-02-29 15:30:08 +08:00
|
|
|
PostCreator.create(
|
2019-11-18 09:25:42 +08:00
|
|
|
user,
|
|
|
|
topic_id: public_topic.id,
|
2023-10-19 07:48:01 +08:00
|
|
|
raw: "A public post with an image.\n![secure image](#{image_upload.short_path})",
|
2019-11-18 09:25:42 +08:00
|
|
|
)
|
2023-10-19 07:48:01 +08:00
|
|
|
expect(public_post.reload.uploads.map(&:access_control_post_id)).to eq([public_post.id])
|
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
|
2024-07-31 10:45:00 +08:00
|
|
|
|
|
|
|
context "when the review_every_post setting is enabled and category requires topic approval" do
|
|
|
|
fab!(:category)
|
|
|
|
|
|
|
|
before do
|
|
|
|
category.require_topic_approval = true
|
|
|
|
category.save!
|
|
|
|
end
|
|
|
|
|
|
|
|
before { SiteSetting.review_every_post = true }
|
|
|
|
|
|
|
|
it "creates single reviewable item" do
|
|
|
|
manager =
|
|
|
|
NewPostManager.new(
|
|
|
|
user,
|
|
|
|
title: "this is a new title",
|
|
|
|
raw: "this is a new post",
|
|
|
|
category: category.id,
|
|
|
|
)
|
|
|
|
reviewable = manager.perform.reviewable
|
|
|
|
|
|
|
|
expect { reviewable.perform(admin, :approve_post) }.not_to change(ReviewablePost, :count)
|
|
|
|
end
|
|
|
|
end
|
2013-02-06 03:16:51 +08:00
|
|
|
end
|