discourse/spec/lib/topics_bulk_action_spec.rb
Ted Johansson 7e5d2a95ee
DEV: Convert min_trust_level_to_tag_topics to groups ()
We're changing the implementation of trust levels to use groups. Part of this is to have site settings that reference trust levels use groups instead. It converts the min_trust_level_to_tag_topics site setting to tag_topic_allowed_groups.
2024-01-26 13:25:03 +08:00

580 lines
19 KiB
Ruby

# frozen_string_literal: true
RSpec.describe TopicsBulkAction do
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
fab!(:topic) { Fabricate(:topic, user: user) }
describe "#dismiss_topics" do
fab!(:user) { Fabricate(:user, created_at: 1.days.ago, refresh_auto_groups: true) }
fab!(:category)
fab!(:topic2) { Fabricate(:topic, category: category, created_at: 60.minutes.ago) }
fab!(:topic3) { Fabricate(:topic, category: category, created_at: 120.minutes.ago) }
before { topic.destroy! }
it "dismisses private messages" do
pm = Fabricate(:private_message_topic, recipient: user)
TopicsBulkAction.new(user, [pm.id], type: "dismiss_topics").perform!
expect(DismissedTopicUser.exists?(topic: pm)).to eq(true)
end
it "dismisses two topics" do
expect {
TopicsBulkAction.new(user, [Topic.all.pluck(:id)], type: "dismiss_topics").perform!
}.to change { DismissedTopicUser.count }.by(2)
end
it "returns dismissed topic ids" do
expect(
TopicsBulkAction.new(user, [Topic.all.pluck(:id)], type: "dismiss_topics").perform!.sort,
).to match_array([topic2.id, topic3.id])
end
it "respects max_new_topics limit" do
SiteSetting.max_new_topics = 1
expect do
TopicsBulkAction.new(user, [Topic.all.pluck(:id)], type: "dismiss_topics").perform!
end.to change { DismissedTopicUser.count }.by(1)
dismissed_topic_user = DismissedTopicUser.last
expect(dismissed_topic_user.user_id).to eq(user.id)
expect(dismissed_topic_user.topic_id).to eq(topic2.id)
expect(dismissed_topic_user.created_at).not_to be_nil
end
it "respects seen topics" do
Fabricate(:topic_user, user: user, topic: topic2, last_read_post_number: 1)
Fabricate(:topic_user, user: user, topic: topic3, last_read_post_number: 1)
expect do
TopicsBulkAction.new(user, [Topic.all.pluck(:id)], type: "dismiss_topics").perform!
end.not_to change { DismissedTopicUser.count }
end
it "dismisses when topic user without last_read_post_number" do
Fabricate(:topic_user, user: user, topic: topic2, last_read_post_number: nil)
Fabricate(:topic_user, user: user, topic: topic3, last_read_post_number: nil)
expect do
TopicsBulkAction.new(user, [Topic.all.pluck(:id)], type: "dismiss_topics").perform!
end.to change { DismissedTopicUser.count }.by(2)
end
it "respects new_topic_duration_minutes" do
user.user_option.update!(new_topic_duration_minutes: 70)
expect do
TopicsBulkAction.new(user, [Topic.all.pluck(:id)], type: "dismiss_topics").perform!
end.to change { DismissedTopicUser.count }.by(1)
dismissed_topic_user = DismissedTopicUser.last
expect(dismissed_topic_user.user_id).to eq(user.id)
expect(dismissed_topic_user.topic_id).to eq(topic2.id)
expect(dismissed_topic_user.created_at).not_to be_nil
end
it "doesn't dismiss topics the user can't see" do
group = Fabricate(:group)
private_category = Fabricate(:private_category, group: group)
topic2.update!(category_id: private_category.id)
expect do
TopicsBulkAction.new(user, [topic2.id, topic3.id], type: "dismiss_topics").perform!
end.to change { DismissedTopicUser.count }.by(1)
expect(DismissedTopicUser.where(user_id: user.id).pluck(:topic_id)).to eq([topic3.id])
group.add(user)
expect do
TopicsBulkAction.new(user, [topic2.id, topic3.id], type: "dismiss_topics").perform!
end.to change { DismissedTopicUser.count }.by(1)
expect(DismissedTopicUser.where(user_id: user.id).pluck(:topic_id)).to contain_exactly(
topic2.id,
topic3.id,
)
end
end
describe "dismiss_posts" do
it "dismisses posts" do
post1 = create_post
p = create_post(topic_id: post1.topic_id)
create_post(topic_id: post1.topic_id)
PostDestroyer.new(Fabricate(:admin), p).destroy
TopicsBulkAction.new(post1.user, [post1.topic_id], type: "dismiss_posts").perform!
tu = TopicUser.find_by(user_id: post1.user_id, topic_id: post1.topic_id)
expect(tu.last_read_post_number).to eq(3)
end
context "when the user is staff" do
fab!(:user) { Fabricate(:admin) }
context "when the highest_staff_post_number is > highest_post_number for a topic (e.g. whisper is last post)" do
it "dismisses posts" do
SiteSetting.whispers_allowed_groups = "#{Group::AUTO_GROUPS[:staff]}"
post1 = create_post(user: user)
p = create_post(topic_id: post1.topic_id)
create_post(topic_id: post1.topic_id)
whisper =
PostCreator.new(
user,
topic_id: post1.topic.id,
post_type: Post.types[:whisper],
raw: "this is a whispered reply",
).create
TopicsBulkAction.new(user, [post1.topic_id], type: "dismiss_posts").perform!
tu = TopicUser.find_by(user_id: user.id, topic_id: post1.topic_id)
expect(tu.last_read_post_number).to eq(4)
end
end
end
end
describe "invalid operation" do
let(:user) { Fabricate.build(:user) }
it "raises an error with an invalid operation" do
tba = TopicsBulkAction.new(user, [1], type: "rm_root")
expect { tba.perform! }.to raise_error(Discourse::InvalidParameters)
end
end
describe "change_category" do
fab!(:category)
fab!(:fist_post) { Fabricate(:post, topic: topic) }
context "when the user can edit the topic" do
context "with 'create_revision_on_bulk_topic_moves' setting enabled" do
before { SiteSetting.create_revision_on_bulk_topic_moves = true }
it "changes the category, creates a post revision and returns the topic_id" do
old_category_id = topic.category_id
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "change_category",
category_id: category.id,
)
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic.category).to eq(category)
revision = topic.first_post.revisions.last
expect(revision).to be_present
expect(revision.modifications).to eq({ "category_id" => [old_category_id, category.id] })
end
it "doesn't do anything when category stays the same" do
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "change_category",
category_id: topic.category_id,
)
topic_ids = tba.perform!
expect(topic_ids).to be_empty
topic.reload
revision = topic.first_post.revisions.last
expect(revision).to be_nil
end
end
context "with 'create_revision_on_bulk_topic_moves' setting disabled" do
before { SiteSetting.create_revision_on_bulk_topic_moves = false }
it "changes the category, doesn't create a post revision and returns the topic_id" do
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "change_category",
category_id: category.id,
)
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic.category).to eq(category)
revision = topic.first_post.revisions.last
expect(revision).to be_nil
end
it "doesn't do anything when category stays the same" do
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "change_category",
category_id: topic.category_id,
)
topic_ids = tba.perform!
expect(topic_ids).to be_empty
end
end
end
context "when the user can't edit the topic" do
it "doesn't change the category" do
Guardian.any_instance.expects(:can_edit?).returns(false)
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "change_category",
category_id: category.id,
)
topic_ids = tba.perform!
expect(topic_ids).to eq([])
topic.reload
expect(topic.category).not_to eq(category)
end
end
end
describe "destroy_post_timing" do
fab!(:fist_post) { Fabricate(:post, topic: topic) }
before { PostTiming.process_timings(topic.user, topic.id, 10, [[1, 10]]) }
it "delegates to PostTiming.destroy_for" do
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "destroy_post_timing")
topic_ids = nil
expect { topic_ids = tba.perform! }.to change { PostTiming.count }.by(-1)
expect(topic_ids).to contain_exactly(topic.id)
end
end
describe "delete" do
fab!(:topic) { Fabricate(:post).topic }
fab!(:moderator)
it "deletes the topic" do
tba = TopicsBulkAction.new(moderator, [topic.id], type: "delete")
tba.perform!
topic.reload
expect(topic).to be_trashed
end
end
describe "change_notification_level" do
context "when the user can see the topic" do
it "updates the notification level" do
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "change_notification_level",
notification_level_id: 2,
)
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
expect(TopicUser.get(topic, topic.user).notification_level).to eq(2)
end
end
context "when the user can't see the topic" do
it "doesn't change the level" do
Guardian.any_instance.expects(:can_see?).returns(false)
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "change_notification_level",
notification_level_id: 2,
)
topic_ids = tba.perform!
expect(topic_ids).to eq([])
expect(TopicUser.get(topic, topic.user)).to be_blank
end
end
end
describe "close" do
context "when the user can moderate the topic" do
it "closes the topic and returns the topic_id" do
Guardian.any_instance.expects(:can_moderate?).returns(true)
Guardian.any_instance.expects(:can_create?).returns(true)
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "close")
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic).to be_closed
end
end
context "when the user can't edit the topic" do
it "doesn't close the topic" do
Guardian.any_instance.expects(:can_moderate?).returns(false)
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "close")
topic_ids = tba.perform!
expect(topic_ids).to be_blank
topic.reload
expect(topic).not_to be_closed
end
end
end
describe "archive" do
context "when the user can moderate the topic" do
it "archives the topic and returns the topic_id" do
Guardian.any_instance.expects(:can_moderate?).returns(true)
Guardian.any_instance.expects(:can_create?).returns(true)
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "archive")
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic).to be_archived
end
end
context "when the user can't edit the topic" do
it "doesn't archive the topic" do
Guardian.any_instance.expects(:can_moderate?).returns(false)
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "archive")
topic_ids = tba.perform!
expect(topic_ids).to be_blank
topic.reload
expect(topic).not_to be_archived
end
end
end
describe "unlist" do
context "when the user can moderate the topic" do
it "unlists the topic and returns the topic_id" do
Guardian.any_instance.expects(:can_moderate?).returns(true)
Guardian.any_instance.expects(:can_create?).returns(true)
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "unlist")
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic).not_to be_visible
end
end
context "when the user can't edit the topic" do
it "doesn't unlist the topic" do
Guardian.any_instance.expects(:can_moderate?).returns(false)
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "unlist")
topic_ids = tba.perform!
expect(topic_ids).to be_blank
topic.reload
expect(topic).to be_visible
end
end
end
describe "reset_bump_dates" do
context "when the user can update bumped at" do
it "does reset the topic bump date" do
post_created_at = 1.day.ago
create_post(topic_id: topic.id, created_at: post_created_at)
topic.update!(bumped_at: 1.hour.ago)
Guardian.any_instance.expects(:can_update_bumped_at?).returns(true)
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "reset_bump_dates")
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
expect(topic.reload.bumped_at).to eq_time(post_created_at)
end
end
context "when the user can't update bumped at" do
it "doesn't reset the topic bump date" do
create_post(topic_id: topic.id, created_at: 1.day.ago)
bumped_at = 1.hour.ago
topic.update!(bumped_at: bumped_at)
Guardian.any_instance.expects(:can_update_bumped_at?).returns(false)
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "reset_bump_dates")
topic_ids = tba.perform!
expect(topic_ids).to eq([])
expect(topic.reload.bumped_at).to eq_time(bumped_at)
end
end
end
describe "change_tags" do
fab!(:tag1) { Fabricate(:tag) }
fab!(:tag2) { Fabricate(:tag) }
before do
SiteSetting.tagging_enabled = true
SiteSetting.tag_topic_allowed_groups = Group::AUTO_GROUPS[:trust_level_0]
topic.tags = [tag1, tag2]
end
it "can change the tags, and can create new tags" do
SiteSetting.create_tag_allowed_groups = Group::AUTO_GROUPS[:trust_level_0]
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "change_tags",
tags: ["newtag", tag1.name],
)
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic.tags.map(&:name)).to contain_exactly("newtag", tag1.name)
end
it "can change the tags but not create new ones" do
SiteSetting.create_tag_allowed_groups = Group::AUTO_GROUPS[:trust_level_4]
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "change_tags",
tags: ["newtag", tag1.name],
)
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic.tags.map(&:name)).to contain_exactly(tag1.name)
end
it "can remove all tags" do
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "change_tags", tags: [])
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic.tags.size).to eq(0)
end
context "when user can't edit topic" do
before { Guardian.any_instance.expects(:can_edit?).returns(false) }
it "doesn't change the tags" do
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "change_tags",
tags: ["newtag", tag1.name],
)
topic_ids = tba.perform!
expect(topic_ids).to eq([])
topic.reload
expect(topic.tags.map(&:name)).to contain_exactly(tag1.name, tag2.name)
end
end
end
describe "append tags" do
fab!(:tag1) { Fabricate(:tag) }
fab!(:tag2) { Fabricate(:tag) }
fab!(:tag3) { Fabricate(:tag) }
before do
SiteSetting.tagging_enabled = true
SiteSetting.tag_topic_allowed_groups = Group::AUTO_GROUPS[:trust_level_0]
topic.tags = [tag1, tag2]
end
it "can append new or existing tags" do
SiteSetting.create_tag_allowed_groups = Group::AUTO_GROUPS[:trust_level_0]
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "append_tags",
tags: [tag1.name, tag3.name, "newtag"],
)
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic.tags.map(&:name)).to contain_exactly(tag1.name, tag2.name, tag3.name, "newtag")
end
it "can append empty tags" do
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "append_tags", tags: [])
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic.tags.map(&:name)).to contain_exactly(tag1.name, tag2.name)
end
context "when the user can't create new topics" do
before { SiteSetting.create_tag_allowed_groups = Group::AUTO_GROUPS[:trust_level_4] }
it "can append existing tags but doesn't append new tags" do
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "append_tags",
tags: [tag3.name, "newtag"],
)
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic.tags.map(&:name)).to contain_exactly(tag1.name, tag2.name, tag3.name)
end
end
context "when user can't edit topic" do
before { Guardian.any_instance.expects(:can_edit?).returns(false) }
it "doesn't change the tags" do
tba =
TopicsBulkAction.new(
topic.user,
[topic.id],
type: "append_tags",
tags: ["newtag", tag3.name],
)
topic_ids = tba.perform!
expect(topic_ids).to eq([])
topic.reload
expect(topic.tags.map(&:name)).to contain_exactly(tag1.name, tag2.name)
end
end
end
describe "remove_tags" do
fab!(:tag1) { Fabricate(:tag) }
fab!(:tag2) { Fabricate(:tag) }
before do
SiteSetting.tagging_enabled = true
SiteSetting.tag_topic_allowed_groups = Group::AUTO_GROUPS[:trust_level_0]
topic.tags = [tag1, tag2]
end
it "can remove all tags" do
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "remove_tags")
topic_ids = tba.perform!
expect(topic_ids).to eq([topic.id])
topic.reload
expect(topic.tags.size).to eq(0)
end
context "when user can't edit topic" do
before { Guardian.any_instance.expects(:can_edit?).returns(false) }
it "doesn't remove the tags" do
tba = TopicsBulkAction.new(topic.user, [topic.id], type: "remove_tags")
topic_ids = tba.perform!
expect(topic_ids).to eq([])
topic.reload
expect(topic.tags.map(&:name)).to contain_exactly(tag1.name, tag2.name)
end
end
end
end