mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 15:06:26 +08:00
DEV: endpoint to reset community community-section (#21664)
In upcoming PRs, admins will be able to edit the Community section. We need an endpoint which allows resetting it to the default state.
This commit is contained in:
parent
984a616204
commit
7ead8de232
|
@ -50,6 +50,18 @@ class SidebarSectionsController < ApplicationController
|
|||
render json: failed_json, status: 403
|
||||
end
|
||||
|
||||
def reset
|
||||
sidebar_section = SidebarSection.find_by(id: params[:id])
|
||||
raise Discourse::InvalidParameters if !sidebar_section
|
||||
@guardian.ensure_can_edit!(sidebar_section)
|
||||
|
||||
case sidebar_section.section_type
|
||||
when "community"
|
||||
sidebar_section.reset_community!
|
||||
end
|
||||
render_serialized(sidebar_section.reload, SidebarSectionSerializer)
|
||||
end
|
||||
|
||||
def reorder
|
||||
sidebar_section = SidebarSection.find_by(id: reorder_params["sidebar_section_id"])
|
||||
@guardian.ensure_can_edit!(sidebar_section)
|
||||
|
|
|
@ -26,6 +26,33 @@ class SidebarSection < ActiveRecord::Base
|
|||
scope :public_sections, -> { where("public") }
|
||||
enum :section_type, { community: 0 }, scopes: false, suffix: true
|
||||
|
||||
def reset_community!
|
||||
ActiveRecord::Base.transaction do
|
||||
self.update!(title: "Community")
|
||||
self.sidebar_section_links.destroy_all
|
||||
community_urls =
|
||||
SidebarUrl::COMMUNITY_SECTION_LINKS.map do |url_data|
|
||||
"('#{url_data[:name]}', '#{url_data[:path]}', '#{url_data[:icon]}', '#{url_data[:segment]}', false, now(), now())"
|
||||
end
|
||||
|
||||
result = DB.query <<~SQL
|
||||
INSERT INTO sidebar_urls(name, value, icon, segment, external, created_at, updated_at)
|
||||
VALUES #{community_urls.join(",")}
|
||||
RETURNING sidebar_urls.id
|
||||
SQL
|
||||
|
||||
sidebar_section_links =
|
||||
result.map.with_index do |url, index|
|
||||
"(-1, #{url.id}, 'SidebarUrl', #{self.id}, #{index}, now(), now())"
|
||||
end
|
||||
|
||||
DB.query <<~SQL
|
||||
INSERT INTO sidebar_section_links(user_id, linkable_id, linkable_type, sidebar_section_id, position, created_at, updated_at)
|
||||
VALUES #{sidebar_section_links.join(",")}
|
||||
SQL
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_system_user_for_public_section
|
||||
|
|
|
@ -1,20 +1,47 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SidebarUrl < ActiveRecord::Base
|
||||
enum :segment, { primary: 0, secondary: 1 }, scopes: false, suffix: true
|
||||
|
||||
FULL_RELOAD_LINKS_REGEX = [%r{\A/my/[a-z_\-/]+\z}, %r{\A/safe-mode\z}]
|
||||
MAX_ICON_LENGTH = 40
|
||||
MAX_NAME_LENGTH = 80
|
||||
MAX_VALUE_LENGTH = 200
|
||||
COMMUNITY_SECTION_LINKS = [
|
||||
{ name: "Everything", path: "/latest", icon: "layer-group", segment: "primary" },
|
||||
{ name: "My Posts", path: "/my/activity", icon: "user", segment: "primary" },
|
||||
{ name: "Review", path: "/review", icon: "flag", segment: "primary" },
|
||||
{ name: "Admin", path: "/admin", icon: "wrench", segment: "primary" },
|
||||
{ name: "Users", path: "/u", icon: "users", segment: "secondary" },
|
||||
{ name: "About", path: "/about", icon: "info-circle", segment: "secondary" },
|
||||
{ name: "FAQ", path: "/faq", icon: "question-circle", segment: "secondary" },
|
||||
{ name: "Groups", path: "/g", icon: "user-friends", segment: "secondary" },
|
||||
{ name: "Badges", path: "/badges", icon: "certificate", segment: "secondary" },
|
||||
{
|
||||
name: "Everything",
|
||||
path: "/latest",
|
||||
icon: "layer-group",
|
||||
segment: SidebarUrl.segments["primary"],
|
||||
},
|
||||
{
|
||||
name: "My Posts",
|
||||
path: "/my/activity",
|
||||
icon: "user",
|
||||
segment: SidebarUrl.segments["primary"],
|
||||
},
|
||||
{ name: "Review", path: "/review", icon: "flag", segment: SidebarUrl.segments["primary"] },
|
||||
{ name: "Admin", path: "/admin", icon: "wrench", segment: SidebarUrl.segments["primary"] },
|
||||
{ name: "Users", path: "/u", icon: "users", segment: SidebarUrl.segments["secondary"] },
|
||||
{
|
||||
name: "About",
|
||||
path: "/about",
|
||||
icon: "info-circle",
|
||||
segment: SidebarUrl.segments["secondary"],
|
||||
},
|
||||
{
|
||||
name: "FAQ",
|
||||
path: "/faq",
|
||||
icon: "question-circle",
|
||||
segment: SidebarUrl.segments["secondary"],
|
||||
},
|
||||
{ name: "Groups", path: "/g", icon: "user-friends", segment: SidebarUrl.segments["secondary"] },
|
||||
{
|
||||
name: "Badges",
|
||||
path: "/badges",
|
||||
icon: "certificate",
|
||||
segment: SidebarUrl.segments["secondary"],
|
||||
},
|
||||
]
|
||||
|
||||
validates :icon, presence: true, length: { maximum: MAX_ICON_LENGTH }
|
||||
|
@ -25,8 +52,6 @@ class SidebarUrl < ActiveRecord::Base
|
|||
|
||||
before_validation :remove_internal_hostname, :set_external
|
||||
|
||||
enum :segment, { primary: 0, secondary: 1 }, scopes: false, suffix: true
|
||||
|
||||
def path_validator
|
||||
return true if !external?
|
||||
raise ActionController::RoutingError.new("Not Found") if value !~ Discourse::Utils::URI_REGEXP
|
||||
|
|
|
@ -1594,6 +1594,7 @@ Discourse::Application.routes.draw do
|
|||
|
||||
resources :sidebar_sections, only: %i[index create update destroy]
|
||||
post "/sidebar_sections/reorder" => "sidebar_sections#reorder"
|
||||
put "/sidebar_sections/reset/:id" => "sidebar_sections#reset"
|
||||
|
||||
get "*url", to: "permalinks#show", constraints: PermalinkConstraint.new
|
||||
end
|
||||
|
|
|
@ -2,16 +2,17 @@
|
|||
|
||||
module SidebarGuardian
|
||||
def can_create_public_sidebar_section?
|
||||
@user.staff?
|
||||
@user.admin?
|
||||
end
|
||||
|
||||
def can_edit_sidebar_section?(sidebar_section)
|
||||
return @user.staff? if sidebar_section.public?
|
||||
return @user.admin? if sidebar_section.public?
|
||||
return @user.admin? if sidebar_section.section_type
|
||||
is_my_own?(sidebar_section)
|
||||
end
|
||||
|
||||
def can_delete_sidebar_section?(sidebar_section)
|
||||
return @user.staff? if sidebar_section.public?
|
||||
return @user.admin? if sidebar_section.public?
|
||||
is_my_own?(sidebar_section)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,10 +3,25 @@
|
|||
RSpec.describe SidebarSection do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:sidebar_section) { Fabricate(:sidebar_section, user: user) }
|
||||
let(:community_section) do
|
||||
SidebarSection.find_by(section_type: SidebarSection.section_types[:community])
|
||||
end
|
||||
|
||||
it "uses system user for public sections" do
|
||||
expect(sidebar_section.user_id).to eq(user.id)
|
||||
sidebar_section.update!(public: true)
|
||||
expect(sidebar_section.user_id).to eq(Discourse.system_user.id)
|
||||
end
|
||||
|
||||
it "resets Community section to the default state" do
|
||||
community_section.update!(title: "test")
|
||||
community_section.sidebar_section_links.first.linkable.update!(name: "everything edited")
|
||||
community_section.sidebar_section_links.last.destroy!
|
||||
|
||||
community_section.reset_community!
|
||||
expect(community_section.reload.title).to eq("Community")
|
||||
expect(community_section.sidebar_section_links.all.map { |link| link.linkable.name }).to eq(
|
||||
["Everything", "My Posts", "Review", "Admin", "Users", "About", "FAQ", "Groups", "Badges"],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
RSpec.describe SidebarSectionsController do
|
||||
fab!(:user) { Fabricate(:user) }
|
||||
fab!(:admin) { Fabricate(:admin) }
|
||||
fab!(:moderator) { Fabricate(:moderator) }
|
||||
|
||||
describe "#index" do
|
||||
fab!(:sidebar_section) { Fabricate(:sidebar_section, title: "private section", user: user) }
|
||||
|
@ -100,6 +101,20 @@ RSpec.describe SidebarSectionsController do
|
|||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "does not allow moderator to create public section" do
|
||||
sign_in(moderator)
|
||||
post "/sidebar_sections.json",
|
||||
params: {
|
||||
title: "custom section",
|
||||
public: true,
|
||||
links: [
|
||||
{ icon: "link", name: "categories", value: "/categories" },
|
||||
{ icon: "address-book", name: "tags", value: "/tags" },
|
||||
],
|
||||
}
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "allows admin to create public section" do
|
||||
sign_in(admin)
|
||||
post "/sidebar_sections.json",
|
||||
|
@ -334,5 +349,43 @@ RSpec.describe SidebarSectionsController do
|
|||
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "doesn't allow moderator to delete public sidebar section" do
|
||||
sign_in(moderator)
|
||||
sidebar_section.update!(public: true)
|
||||
delete "/sidebar_sections/#{sidebar_section.id}.json"
|
||||
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#reset" do
|
||||
let(:community_section) do
|
||||
SidebarSection.find_by(section_type: SidebarSection.section_types[:community])
|
||||
end
|
||||
let(:everything_link) { community_section.sidebar_section_links.first }
|
||||
|
||||
it "doesn't allow user to reset community section" do
|
||||
sign_in(user)
|
||||
SidebarSection.any_instance.expects(:reset_community!).never
|
||||
put "/sidebar_sections/reset/#{community_section.id}.json"
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "doesn't allow staff to reset community section" do
|
||||
sign_in(moderator)
|
||||
SidebarSection.any_instance.expects(:reset_community!).never
|
||||
put "/sidebar_sections/reset/#{community_section.id}.json"
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "allows admins to reset community section to default" do
|
||||
sign_in(admin)
|
||||
SidebarSection.any_instance.expects(:reset_community!).once
|
||||
put "/sidebar_sections/reset/#{community_section.id}.json"
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.parsed_body["sidebar_section"]["id"]).to eq(community_section.id)
|
||||
expect(response.parsed_body["sidebar_section"]["title"]).to eq(community_section.title)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user