FEATURE: Create legal topics for set company name (#21620)

Legal topics, such as the Terms of Service and Privacy Policy topics
do not make sense if the entity creating the community is not a company.
These topics will be created and updated only when the company name is
present and deleted when it is not.
This commit is contained in:
Bianca Nenciu
2023-05-24 22:05:36 +02:00
committed by GitHub
parent baa5389a23
commit 61a0ae3755
8 changed files with 186 additions and 57 deletions

View File

@ -18,12 +18,16 @@
"faq" "faq"
}}</LinkTo></li> }}</LinkTo></li>
{{/if}} {{/if}}
{{#if (gt this.siteSettings.tos_topic_id 0)}}
<li class="nav-item-tos"><LinkTo @route="tos">{{i18n <li class="nav-item-tos"><LinkTo @route="tos">{{i18n
"tos" "tos"
}}</LinkTo></li> }}</LinkTo></li>
{{/if}}
{{#if (gt this.siteSettings.privacy_topic_id 0)}}
<li class="nav-item-privacy"><LinkTo @route="privacy">{{i18n <li class="nav-item-privacy"><LinkTo @route="privacy">{{i18n
"privacy" "privacy"
}}</LinkTo></li> }}</LinkTo></li>
{{/if}}
</ul> </ul>
<section class="about description"> <section class="about description">

View File

@ -10,8 +10,12 @@
<li class='nav-item-faq'><a class='<%= @page == 'faq' ? 'active' : '' %>' href='<%=faq_path%>'><%= t 'js.faq' %></a></li> <li class='nav-item-faq'><a class='<%= @page == 'faq' ? 'active' : '' %>' href='<%=faq_path%>'><%= t 'js.faq' %></a></li>
<% end %> <% end %>
<% end %> <% end %>
<% if SiteSetting.tos_topic_id > 0 %>
<li class='nav-item-tos'><a href='<%= tos_path %>' class='<%= @page == 'tos' ? 'active' : '' %>'><%= t 'js.tos' %></a></li> <li class='nav-item-tos'><a href='<%= tos_path %>' class='<%= @page == 'tos' ? 'active' : '' %>'><%= t 'js.tos' %></a></li>
<% end %>
<% if SiteSetting.privacy_topic_id > 0 %>
<li class='nav-item-privacy'><a href='<%= privacy_path %>' class='<%= @page == 'privacy' ? 'active' : '' %>'><%= t 'js.privacy' %></a></li> <li class='nav-item-privacy'><a href='<%= privacy_path %>' class='<%= @page == 'privacy' ? 'active' : '' %>'><%= t 'js.privacy' %></a></li>
<% end %>
</ul> </ul>
<% if staff? %> <% if staff? %>

View File

@ -66,21 +66,23 @@ DiscourseEvent.on(:site_setting_changed) do |name, old_value, new_value|
Emoji.clear_cache && Discourse.request_refresh! if name == :emoji_deny_list Emoji.clear_cache && Discourse.request_refresh! if name == :emoji_deny_list
if (name == :title || name == :site_description) && # Update seeded topics
topic = Topic.find_by(id: SiteSetting.welcome_topic_id) if %i[title site_description].include?(name)
PostRevisor.new(topic.first_post, topic).revise!( topics = SeedData::Topics.with_default_locale
Discourse.system_user, topics.update(site_setting_names: ["welcome_topic_id"], skip_changed: true)
{ elsif %i[company_name contact_email governing_law city_for_disputes].include?(name)
title: I18n.t("discourse_welcome_topic.title", site_title: SiteSetting.title), topics = SeedData::Topics.with_default_locale
raw: %w[tos_topic_id privacy_topic_id].each do |site_setting|
I18n.t( topic_id = SiteSetting.get(site_setting)
"discourse_welcome_topic.body", if topic_id > 0 && Topic.with_deleted.exists?(id: topic_id)
base_path: Discourse.base_path, if SiteSetting.company_name.blank?
site_title: SiteSetting.title, topics.delete(site_setting_names: [site_setting], skip_changed: true)
site_description: SiteSetting.site_description, else
), topics.update(site_setting_names: [site_setting], skip_changed: true)
}, end
skip_revision: true, elsif SiteSetting.company_name.present?
) topics.create(site_setting_names: [site_setting])
end
end
end end
end end

View File

@ -2477,12 +2477,14 @@ uncategorized:
tos_topic_id: tos_topic_id:
default: -1 default: -1
hidden: true hidden: true
client: true
guidelines_topic_id: guidelines_topic_id:
default: -1 default: -1
hidden: true hidden: true
privacy_topic_id: privacy_topic_id:
default: -1 default: -1
hidden: true hidden: true
client: true
welcome_topic_id: welcome_topic_id:
default: -1 default: -1
hidden: true hidden: true

View File

@ -10,18 +10,28 @@ module SeedData
@locale = locale @locale = locale
end end
def create(site_setting_names: nil, include_welcome_topics: true) def create(site_setting_names: nil, include_welcome_topics: true, include_legal_topics: false)
I18n.with_locale(@locale) do I18n.with_locale(@locale) do
topics(site_setting_names, include_welcome_topics).each { |params| create_topic(**params) } topics(
site_setting_names: site_setting_names,
include_welcome_topics: include_welcome_topics,
include_legal_topics: include_legal_topics || SiteSetting.company_name.present?,
).each { |params| create_topic(**params) }
end end
end end
def update(site_setting_names: nil, skip_changed: false) def update(site_setting_names: nil, skip_changed: false)
I18n.with_locale(@locale) do I18n.with_locale(@locale) do
topics(site_setting_names).each do |params| topics(site_setting_names: site_setting_names).each do |params|
params.except!(:category, :after_create) update_topic(**params.except(:category, :after_create), skip_changed: skip_changed)
params[:skip_changed] = skip_changed end
update_topic(**params) end
end
def delete(site_setting_names: nil, skip_changed: false)
I18n.with_locale(@locale) do
topics(site_setting_names: site_setting_names).each do |params|
delete_topic(**params.slice(:site_setting_name), skip_changed: skip_changed)
end end
end end
end end
@ -41,12 +51,14 @@ module SeedData
private private
def topics(site_setting_names = nil, include_welcome_topics = true) def topics(site_setting_names: nil, include_welcome_topics: true, include_legal_topics: true)
staff_category = Category.find_by(id: SiteSetting.staff_category_id) staff_category = Category.find_by(id: SiteSetting.staff_category_id)
topics = [ topics = []
# Terms of Service # Terms of Service
{ if include_legal_topics
topics << {
site_setting_name: "tos_topic_id", site_setting_name: "tos_topic_id",
title: I18n.t("tos_topic.title"), title: I18n.t("tos_topic.title"),
raw: raw:
@ -60,24 +72,28 @@ module SeedData
), ),
category: staff_category, category: staff_category,
static_first_reply: true, static_first_reply: true,
}, }
end
# FAQ/Guidelines # FAQ/Guidelines
{ topics << {
site_setting_name: "guidelines_topic_id", site_setting_name: "guidelines_topic_id",
title: I18n.t("guidelines_topic.title"), title: I18n.t("guidelines_topic.title"),
raw: I18n.t("guidelines_topic.body", base_path: Discourse.base_path), raw: I18n.t("guidelines_topic.body", base_path: Discourse.base_path),
category: staff_category, category: staff_category,
static_first_reply: true, static_first_reply: true,
}, }
# Privacy Policy # Privacy Policy
{ if include_legal_topics
topics << {
site_setting_name: "privacy_topic_id", site_setting_name: "privacy_topic_id",
title: I18n.t("privacy_topic.title"), title: I18n.t("privacy_topic.title"),
raw: I18n.t("privacy_topic.body"), raw: I18n.t("privacy_topic.body"),
category: staff_category, category: staff_category,
static_first_reply: true, static_first_reply: true,
}, }
] end
if include_welcome_topics if include_welcome_topics
# Welcome Topic # Welcome Topic
@ -152,27 +168,42 @@ module SeedData
end end
def update_topic(site_setting_name:, title:, raw:, static_first_reply: false, skip_changed:) def update_topic(site_setting_name:, title:, raw:, static_first_reply: false, skip_changed:)
post = find_post(site_setting_name) post = find_post(site_setting_name, deleted: true)
return if !post return if !post
if !skip_changed || unchanged?(post) if !skip_changed || unchanged?(post)
changes = { title: title, raw: raw } if post.trashed?
post.revise(Discourse.system_user, changes, skip_validations: true) PostDestroyer.new(Discourse.system_user, post).recover
post.reload
end
post.revise(Discourse.system_user, { title: title, raw: raw }, skip_validations: true)
end end
if static_first_reply && (reply = first_reply(post)) && (!skip_changed || unchanged?(reply)) if static_first_reply && (reply = first_reply(post)) && (!skip_changed || unchanged?(reply))
changes = { raw: first_reply_raw(title) } reply.revise(Discourse.system_user, { raw: first_reply_raw(title) }, skip_validations: true)
reply.revise(Discourse.system_user, changes, skip_validations: true)
end end
end end
def find_post(site_setting_name) def delete_topic(site_setting_name:, skip_changed:)
post = find_post(site_setting_name)
return if !post
PostDestroyer.new(Discourse.system_user, post).destroy if !skip_changed || unchanged?(post)
end
def find_post(site_setting_name, deleted: false)
topic_id = SiteSetting.get(site_setting_name) topic_id = SiteSetting.get(site_setting_name)
Post.find_by(topic_id: topic_id, post_number: 1) if topic_id > 0 return if topic_id < 1
posts = Post.where(topic_id: topic_id, post_number: 1)
posts = posts.with_deleted if deleted
posts.first
end end
def unchanged?(post) def unchanged?(post)
post.last_editor_id == Discourse::SYSTEM_USER_ID post.last_editor_id == Discourse::SYSTEM_USER_ID &&
(!post.deleted_by_id || post.deleted_by_id == Discourse::SYSTEM_USER_ID)
end end
def setting_value(site_setting_key) def setting_value(site_setting_key)

View File

@ -17,7 +17,7 @@ desc "ensure the asynchronously-created post_search_data index is present"
task "annotate:ensure_all_indexes" => :environment do |task, args| task "annotate:ensure_all_indexes" => :environment do |task, args|
# One of the indexes on post_search_data is created by a sidekiq job # One of the indexes on post_search_data is created by a sidekiq job
# We need to do some acrobatics to create it on-demand # We need to do some acrobatics to create it on-demand
SeedData::Topics.with_default_locale.create(include_welcome_topics: true) SeedData::Topics.with_default_locale.create
SiteSetting.search_enable_recent_regular_posts_offset_size = 1 SiteSetting.search_enable_recent_regular_posts_offset_size = 1
Jobs::CreateRecentPostSearchIndexes.new.execute([]) Jobs::CreateRecentPostSearchIndexes.new.execute([])
end end

View File

@ -43,4 +43,54 @@ RSpec.describe "Setting changes" do
expect(Reviewable.min_score_for_priority(:low)).not_to eq(new_threshold) expect(Reviewable.min_score_for_priority(:low)).not_to eq(new_threshold)
end end
end end
describe "#title and #site_description" do
before do
general_category = Fabricate(:category, name: "General")
SiteSetting.general_category_id = general_category.id
SeedData::Topics.with_default_locale.create(site_setting_names: ["welcome_topic_id"])
end
it "updates the welcome topic when title changes" do
SiteSetting.title = SecureRandom.alphanumeric
topic = Topic.find(SiteSetting.welcome_topic_id)
expect(topic.title).to include(SiteSetting.title)
expect(topic.first_post.raw).to include(SiteSetting.title)
end
it "updates the welcome topic when site_description changes" do
SiteSetting.site_description = SecureRandom.alphanumeric
topic = Topic.find(SiteSetting.welcome_topic_id)
expect(topic.first_post.raw).to include(SiteSetting.site_description)
end
end
describe "#company_name" do
it "creates the TOS and Privacy topics" do
expect { SiteSetting.company_name = "Company Name" }.to change { Topic.count }.by(
2,
).and change { SiteSetting.tos_topic_id }.and change { SiteSetting.privacy_topic_id }
end
it "creates, updates and deletes the topic" do
# Topic is created
expect { SiteSetting.company_name = "Company Name" }.to change { Topic.count }.by(2)
topic = Topic.find(SiteSetting.tos_topic_id)
first_post = topic.first_post
expect(first_post.raw).to include("Company Name")
# Topic is edited
expect { SiteSetting.company_name = "Other Name" }.not_to change { Topic.count }
expect(first_post.reload.raw).to include("Other Name")
# Topic can be deleted
expect { SiteSetting.company_name = "" }.to change { Topic.count }.by(-2)
# Topic can be recovered and edited
SiteSetting.company_name = "New Name"
expect(first_post.reload.raw).to include("New Name")
end
end
end end

View File

@ -11,7 +11,7 @@ RSpec.describe SeedData::Topics do
end end
def create_topic(name = "welcome_topic_id") def create_topic(name = "welcome_topic_id")
subject.create(site_setting_names: [name]) subject.create(site_setting_names: [name], include_legal_topics: true)
end end
describe "#create" do describe "#create" do
@ -71,6 +71,19 @@ RSpec.describe SeedData::Topics do
expect { create_topic }.to_not change { Topic.count } expect { create_topic }.to_not change { Topic.count }
end end
it "does not create a legal topic if company_name is not set" do
subject.create(site_setting_names: ["tos_topic_id"])
expect(SiteSetting.tos_topic_id).to eq(-1)
end
it "creates a legal topic if company_name is set" do
SiteSetting.company_name = "Company Name"
subject.create(site_setting_names: ["tos_topic_id"])
expect(SiteSetting.tos_topic_id).to_not eq(-1)
end
end end
describe "#update" do describe "#update" do
@ -129,6 +142,29 @@ RSpec.describe SeedData::Topics do
end end
end end
describe "#delete" do
def delete_topic(name = "welcome_topic_id", skip_changed: false)
subject.delete(site_setting_names: [name], skip_changed: skip_changed)
end
it "deletes the topic" do
create_topic
topic = Topic.last
expect { delete_topic }.to change { Topic.count }.by(-1)
end
it "does not delete the topic if changed" do
create_topic
topic = Topic.last
topic.first_post.revise(Fabricate(:admin), raw: "New text of first post.")
expect { delete_topic(skip_changed: true) }.not_to change { Topic.count }
end
end
describe "#reseed_options" do describe "#reseed_options" do
it "returns only existing topics as options" do it "returns only existing topics as options" do
create_topic("guidelines_topic_id") create_topic("guidelines_topic_id")