mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 09:53:44 +08:00
e3b1f5721b
There is a category setting that enforces 1 or more tags must be added to a topic from a specific tag group before creating it. This validation was not being run before the topic was being sent to a review queue for categories that have that setting enabled. There was an existing validation in `TopicCreator` but it was not correct; it was only validating when the tags did _not_ exist and also only happened on `create`. I now run the validation in `TopicCreator.valid?` I also improved the error message shown to the user when they have not added the tags required (showing the tag names from the tag group), and changed the composer tag selector to not show "optional" if there are N tags required from a certain group.
285 lines
11 KiB
Ruby
285 lines
11 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'rails_helper'
|
|
|
|
describe TopicCreator do
|
|
fab!(:user) { Fabricate(:user, trust_level: TrustLevel[2]) }
|
|
fab!(:moderator) { Fabricate(:moderator) }
|
|
fab!(:admin) { Fabricate(:admin) }
|
|
|
|
let(:valid_attrs) { Fabricate.attributes_for(:topic) }
|
|
let(:pm_valid_attrs) { { raw: 'this is a new post', title: 'this is a new title', archetype: Archetype.private_message, target_usernames: moderator.username } }
|
|
|
|
let(:pm_to_email_valid_attrs) do
|
|
{
|
|
raw: 'this is a new email',
|
|
title: 'this is a new subject',
|
|
archetype: Archetype.private_message,
|
|
target_emails: 'moderator@example.com'
|
|
}
|
|
end
|
|
|
|
describe '#create' do
|
|
context 'topic success cases' do
|
|
before do
|
|
TopicCreator.any_instance.expects(:save_topic).returns(true)
|
|
TopicCreator.any_instance.expects(:watch_topic).returns(true)
|
|
SiteSetting.allow_duplicate_topic_titles = true
|
|
end
|
|
|
|
it "should be possible for an admin to create a topic" do
|
|
expect(TopicCreator.create(admin, Guardian.new(admin), valid_attrs)).to be_valid
|
|
end
|
|
|
|
it "should be possible for a moderator to create a topic" do
|
|
expect(TopicCreator.create(moderator, Guardian.new(moderator), valid_attrs)).to be_valid
|
|
end
|
|
|
|
it "supports both meta_data and custom_fields" do
|
|
opts = valid_attrs.merge(
|
|
meta_data: { import_topic_id: "foo" },
|
|
custom_fields: { import_id: "bar" }
|
|
)
|
|
|
|
topic = TopicCreator.create(admin, Guardian.new(admin), opts)
|
|
|
|
expect(topic.custom_fields["import_topic_id"]).to eq("foo")
|
|
expect(topic.custom_fields["import_id"]).to eq("bar")
|
|
end
|
|
|
|
context 'regular user' do
|
|
before { SiteSetting.min_trust_to_create_topic = TrustLevel[0] }
|
|
|
|
it "should be possible for a regular user to create a topic" do
|
|
expect(TopicCreator.create(user, Guardian.new(user), valid_attrs)).to be_valid
|
|
end
|
|
|
|
it "should be possible for a regular user to create a topic with blank auto_close_time" do
|
|
expect(TopicCreator.create(user, Guardian.new(user), valid_attrs.merge(auto_close_time: ''))).to be_valid
|
|
end
|
|
|
|
it "ignores auto_close_time without raising an error" do
|
|
topic = TopicCreator.create(user, Guardian.new(user), valid_attrs.merge(auto_close_time: '24'))
|
|
expect(topic).to be_valid
|
|
expect(topic.public_topic_timer).to eq(nil)
|
|
end
|
|
|
|
it "can create a topic in a category" do
|
|
category = Fabricate(:category, name: "Neil's Blog")
|
|
topic = TopicCreator.create(user, Guardian.new(user), valid_attrs.merge(category: category.id))
|
|
expect(topic).to be_valid
|
|
expect(topic.category).to eq(category)
|
|
end
|
|
|
|
it "ignores participant_count without raising an error" do
|
|
topic = TopicCreator.create(user, Guardian.new(user), valid_attrs.merge(participant_count: 3))
|
|
expect(topic.participant_count).to eq(1)
|
|
end
|
|
|
|
it "accepts participant_count in import mode" do
|
|
topic = TopicCreator.create(user, Guardian.new(user), valid_attrs.merge(import_mode: true, participant_count: 3))
|
|
expect(topic.participant_count).to eq(3)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'tags' do
|
|
fab!(:tag1) { Fabricate(:tag, name: "fun") }
|
|
fab!(:tag2) { Fabricate(:tag, name: "fun2") }
|
|
|
|
before do
|
|
SiteSetting.tagging_enabled = true
|
|
SiteSetting.min_trust_to_create_tag = 0
|
|
SiteSetting.min_trust_level_to_tag_topics = 0
|
|
end
|
|
|
|
context 'regular tags' do
|
|
it "user can add tags to topic" do
|
|
topic = TopicCreator.create(user, Guardian.new(user), valid_attrs.merge(tags: [tag1.name]))
|
|
expect(topic).to be_valid
|
|
expect(topic.tags.length).to eq(1)
|
|
end
|
|
end
|
|
|
|
context 'staff-only tags' do
|
|
before do
|
|
create_staff_only_tags(['alpha'])
|
|
end
|
|
|
|
it "regular users can't add staff-only tags" do
|
|
expect do
|
|
TopicCreator.create(user, Guardian.new(user), valid_attrs.merge(tags: ['alpha']))
|
|
end.to raise_error(ActiveRecord::Rollback)
|
|
end
|
|
|
|
it 'staff can add staff-only tags' do
|
|
topic = TopicCreator.create(admin, Guardian.new(admin), valid_attrs.merge(tags: ['alpha']))
|
|
expect(topic).to be_valid
|
|
expect(topic.tags.length).to eq(1)
|
|
end
|
|
end
|
|
|
|
context 'minimum_required_tags is present' do
|
|
fab!(:category) { Fabricate(:category, name: "beta", minimum_required_tags: 2) }
|
|
|
|
it "fails for regular user if minimum_required_tags is not satisfied" do
|
|
expect(
|
|
TopicCreator.new(user, Guardian.new(user), valid_attrs.merge(category: category.id)).valid?
|
|
).to be_falsy
|
|
end
|
|
|
|
it "lets admin create a topic regardless of minimum_required_tags" do
|
|
topic = TopicCreator.create(admin, Guardian.new(admin), valid_attrs.merge(tags: [tag1.name], category: category.id))
|
|
expect(topic).to be_valid
|
|
expect(topic.tags.length).to eq(1)
|
|
end
|
|
|
|
it "works for regular user if minimum_required_tags is satisfied" do
|
|
topic = TopicCreator.create(user, Guardian.new(user), valid_attrs.merge(tags: [tag1.name, tag2.name], category: category.id))
|
|
expect(topic).to be_valid
|
|
expect(topic.tags.length).to eq(2)
|
|
end
|
|
|
|
it "lets new user create a topic if they don't have sufficient trust level to tag topics" do
|
|
SiteSetting.min_trust_level_to_tag_topics = 1
|
|
new_user = Fabricate(:newuser)
|
|
topic = TopicCreator.create(new_user, Guardian.new(new_user), valid_attrs.merge(category: category.id))
|
|
expect(topic).to be_valid
|
|
end
|
|
end
|
|
|
|
context 'required tag group' do
|
|
fab!(:tag_group) { Fabricate(:tag_group, tags: [tag1]) }
|
|
fab!(:category) { Fabricate(:category, name: "beta", required_tag_group: tag_group, min_tags_from_required_group: 1) }
|
|
|
|
it "when no tags are not present" do
|
|
expect(
|
|
TopicCreator.new(user, Guardian.new(user), valid_attrs.merge(category: category.id)).valid?
|
|
).to be_falsy
|
|
end
|
|
|
|
it "when tags are not part of the tag group" do
|
|
expect(
|
|
TopicCreator.new(user, Guardian.new(user), valid_attrs.merge(category: category.id, tags: ['nope'])).valid?
|
|
).to be_falsy
|
|
end
|
|
|
|
it "when requirement is met" do
|
|
expect(
|
|
TopicCreator.new(user, Guardian.new(user), valid_attrs.merge(category: category.id, tags: [tag1.name, tag2.name])).valid?
|
|
).to be_truthy
|
|
end
|
|
|
|
it "lets staff ignore the restriction" do
|
|
expect(
|
|
TopicCreator.new(user, Guardian.new(admin), valid_attrs.merge(category: category.id)).valid?
|
|
).to be_truthy
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'personal message' do
|
|
|
|
context 'success cases' do
|
|
before do
|
|
TopicCreator.any_instance.expects(:save_topic).returns(true)
|
|
TopicCreator.any_instance.expects(:watch_topic).returns(true)
|
|
SiteSetting.allow_duplicate_topic_titles = true
|
|
SiteSetting.enable_staged_users = true
|
|
end
|
|
|
|
it "should be possible for a regular user to send private message" do
|
|
expect(TopicCreator.create(user, Guardian.new(user), pm_valid_attrs)).to be_valid
|
|
end
|
|
|
|
it "min_trust_to_create_topic setting should not be checked when sending private message" do
|
|
SiteSetting.min_trust_to_create_topic = TrustLevel[4]
|
|
expect(TopicCreator.create(user, Guardian.new(user), pm_valid_attrs)).to be_valid
|
|
end
|
|
|
|
it "enable_personal_messages setting should not be checked when sending private message to staff via flag" do
|
|
SiteSetting.enable_personal_messages = false
|
|
SiteSetting.min_trust_to_send_messages = TrustLevel[4]
|
|
expect(TopicCreator.create(user, Guardian.new(user), pm_valid_attrs.merge(subtype: TopicSubtype.notify_moderators))).to be_valid
|
|
end
|
|
end
|
|
|
|
context 'failure cases' do
|
|
it "should be rollback the changes when email is invalid" do
|
|
SiteSetting.manual_polling_enabled = true
|
|
SiteSetting.reply_by_email_address = "sam+%{reply_key}@sam.com"
|
|
SiteSetting.reply_by_email_enabled = true
|
|
SiteSetting.min_trust_to_send_email_messages = TrustLevel[1]
|
|
attrs = pm_to_email_valid_attrs.dup
|
|
attrs[:target_emails] = "t" * 256
|
|
|
|
expect do
|
|
TopicCreator.create(user, Guardian.new(user), attrs)
|
|
end.to raise_error(ActiveRecord::Rollback)
|
|
end
|
|
|
|
it "min_trust_to_send_messages setting should be checked when sending private message" do
|
|
SiteSetting.min_trust_to_send_messages = TrustLevel[4]
|
|
|
|
expect do
|
|
TopicCreator.create(user, Guardian.new(user), pm_valid_attrs)
|
|
end.to raise_error(ActiveRecord::Rollback)
|
|
end
|
|
end
|
|
|
|
context 'to emails' do
|
|
it 'works for staff' do
|
|
SiteSetting.min_trust_to_send_email_messages = 'staff'
|
|
expect(TopicCreator.create(admin, Guardian.new(admin), pm_to_email_valid_attrs)).to be_valid
|
|
end
|
|
|
|
it 'work for trusted users' do
|
|
SiteSetting.min_trust_to_send_email_messages = 3
|
|
user.update!(trust_level: 3)
|
|
expect(TopicCreator.create(user, Guardian.new(user), pm_to_email_valid_attrs)).to be_valid
|
|
end
|
|
|
|
it 'does not work for non-staff' do
|
|
SiteSetting.min_trust_to_send_email_messages = 'staff'
|
|
expect { TopicCreator.create(user, Guardian.new(user), pm_to_email_valid_attrs) }.to raise_error(ActiveRecord::Rollback)
|
|
end
|
|
|
|
it 'does not work for untrusted users' do
|
|
SiteSetting.min_trust_to_send_email_messages = 3
|
|
user.update!(trust_level: 2)
|
|
expect { TopicCreator.create(user, Guardian.new(user), pm_to_email_valid_attrs) }.to raise_error(ActiveRecord::Rollback)
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'setting timestamps' do
|
|
it 'supports Time instances' do
|
|
freeze_time
|
|
|
|
topic = TopicCreator.create(user, Guardian.new(user), valid_attrs.merge(
|
|
created_at: 1.week.ago,
|
|
pinned_at: 3.days.ago
|
|
))
|
|
|
|
expect(topic.created_at).to eq_time(1.week.ago)
|
|
expect(topic.pinned_at).to eq_time(3.days.ago)
|
|
end
|
|
|
|
it 'supports strings' do
|
|
freeze_time
|
|
|
|
time1 = Time.zone.parse('2019-09-02')
|
|
time2 = Time.zone.parse('2020-03-10 15:17')
|
|
|
|
topic = TopicCreator.create(user, Guardian.new(user), valid_attrs.merge(
|
|
created_at: '2019-09-02',
|
|
pinned_at: '2020-03-10 15:17'
|
|
))
|
|
|
|
expect(topic.created_at).to eq_time(time1)
|
|
expect(topic.pinned_at).to eq_time(time2)
|
|
end
|
|
end
|
|
end
|
|
end
|