discourse/spec/serializers/category_serializer_spec.rb
Martin Brennan d41418ec01
DEV: Remove enable_simplified_category_creation old code (#40108)
Now that enable_simplified_category_creation is permanent, we can remove
all the old code in the false condition of this upcoming change.

Since now admins can also add/remove category types in the General tab,
I am also removing the settings connectors for topic voting + solved
plugins, removing more clutter from the Settings tab:
2026-05-27 10:04:46 +10:00

373 lines
12 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe CategorySerializer do
fab!(:user)
fab!(:admin)
fab!(:group)
fab!(:category)
fab!(:category_moderation_group) { Fabricate(:category_moderation_group, category:, group:) }
it "includes the reviewable by group name if enabled" do
SiteSetting.enable_category_group_moderation = true
json = described_class.new(category, scope: Guardian.new, root: false).as_json
expect(json[:moderating_group_ids]).to eq([group.id])
end
it "doesn't include the reviewable by group name if disabled" do
SiteSetting.enable_category_group_moderation = false
json = described_class.new(category, scope: Guardian.new, root: false).as_json
expect(json[:moderating_group_ids]).to be_blank
end
it "includes custom fields" do
json = described_class.new(category, scope: Guardian.new, root: false).as_json
expect(json[:custom_fields]).to be_empty
category.custom_fields["enable_marketplace"] = true
category.save_custom_fields
json = described_class.new(category, scope: Guardian.new, root: false).as_json
expect(json[:custom_fields]).to be_present
end
it "does not include the default notification level when there is no user" do
json = described_class.new(category, scope: Guardian.new, root: false).as_json
expect(json.key?(:notification_level)).to eq(false)
end
describe "user notification level" do
it "includes the user's notification level" do
CategoryUser.set_notification_level_for_category(
user,
NotificationLevels.all[:watching],
category.id,
)
json = described_class.new(category, scope: Guardian.new(user), root: false).as_json
expect(json[:notification_level]).to eq(NotificationLevels.all[:watching])
end
end
describe "#group_permissions" do
fab!(:private_group) do
Fabricate(:group, visibility_level: Group.visibility_levels[:staff], name: "bbb")
end
fab!(:user_group) do
Fabricate(:group, visibility_level: Group.visibility_levels[:members], name: "ccc").tap do |g|
g.add(user)
end
end
before do
group.update!(name: "aaa")
category.set_permissions(
:everyone => :readonly,
group.name => :readonly,
user_group.name => :full,
private_group.name => :full,
)
category.save!
end
it "does not include the attribute for an anon user" do
json = described_class.new(category, scope: Guardian.new, root: false).as_json
expect(json[:group_permissions]).to eq(nil)
end
it "does not include the attribute for a regular user" do
json = described_class.new(category, scope: Guardian.new(user), root: false).as_json
expect(json[:group_permissions]).to eq(nil)
end
it "returns the right category group permissions for a user that can edit the category" do
SiteSetting.moderators_manage_categories = true
user.update!(moderator: true)
json = described_class.new(category, scope: Guardian.new(user), root: false).as_json
expect(json[:group_permissions]).to eq(
[
{
permission_type: CategoryGroup.permission_types[:readonly],
group_name: group.name,
group_id: group.id,
},
{
permission_type: CategoryGroup.permission_types[:full],
group_name: private_group.name,
group_id: private_group.id,
},
{
permission_type: CategoryGroup.permission_types[:full],
group_name: user_group.name,
group_id: user_group.id,
},
{
permission_type: CategoryGroup.permission_types[:readonly],
group_name: "everyone",
group_id: Group::AUTO_GROUPS[:everyone],
},
],
)
end
end
describe "available groups" do
it "not included for a regular user" do
json = described_class.new(category, scope: Guardian.new(user), root: false).as_json
expect(json[:available_groups]).to eq(nil)
end
it "included for an admin" do
json = described_class.new(category, scope: Guardian.new(admin), root: false).as_json
expect(json[:available_groups]).to eq(Group.order(:name).pluck(:name) - ["everyone"])
end
end
describe "name and description" do
fab!(:category_with_localization) do
Fabricate(:category, name: "Original Name", description: "Original Description", locale: "en")
end
before do
CategoryLocalization.create!(
category: category_with_localization,
locale: "ja",
name: "日本語名",
description: "<p>最初の段落</p><p>二番目の段落</p>",
)
end
it "returns untranslated name and description for CategorySerializer" do
json =
described_class.new(
category_with_localization,
scope: Guardian.new(user),
root: false,
).as_json
expect(json[:name]).to eq("Original Name")
expect(json[:description]).to eq("Original Description")
end
it "returns translated attributes for SiteCategorySerializer when enabled" do
SiteSetting.content_localization_enabled = true
user.update!(locale: "ja")
I18n.with_locale("ja") do
json =
SiteCategorySerializer.new(
category_with_localization,
scope: Guardian.new(user),
root: false,
).as_json
expect(json[:name]).to eq("日本語名")
expect(json[:description]).to eq("<p>最初の段落</p><p>二番目の段落</p>")
expect(json[:description_text]).to eq("&lt;p&gt;最初の段落&lt;/p&gt;&lt;p&gt;二番目の段落&lt;/p&gt;")
expect(json[:description_excerpt]).to eq("最初の段落 二番目の段落")
end
end
it "returns untranslated attributes for SiteCategorySerializer when disabled" do
SiteSetting.content_localization_enabled = false
user.update!(locale: "ja")
I18n.with_locale("ja") do
json =
SiteCategorySerializer.new(
category_with_localization,
scope: Guardian.new(user),
root: false,
).as_json
expect(json[:name]).to eq("Original Name")
expect(json[:description]).to eq("Original Description")
expect(json[:description_text]).to eq(category_with_localization.description_text)
expect(json[:description_excerpt]).to eq(category_with_localization.description_excerpt)
end
end
it "returns untranslated name and description for BasicCategorySerializer" do
json =
BasicCategorySerializer.new(
category_with_localization,
scope: Guardian.new(user),
root: false,
).as_json
expect(json[:name]).to eq("Original Name")
expect(json[:description]).to eq("Original Description")
end
end
describe "#topic_posting_review_group_ids" do
it "returns group ids when groups exist" do
category.update!(
topic_posting_review_mode: :everyone_except,
topic_posting_review_group_ids: [group.id],
)
json = described_class.new(category, scope: Guardian.new, root: false).as_json
expect(json[:topic_posting_review_group_ids]).to eq([group.id])
end
it "returns empty array when no groups are associated" do
json = described_class.new(category, scope: Guardian.new, root: false).as_json
expect(json[:topic_posting_review_group_ids]).to eq([])
end
end
describe "#reply_posting_review_group_ids" do
it "returns group ids when groups exist" do
category.update!(
reply_posting_review_mode: :no_one_except,
reply_posting_review_group_ids: [group.id],
)
json = described_class.new(category, scope: Guardian.new, root: false).as_json
expect(json[:reply_posting_review_group_ids]).to eq([group.id])
end
it "returns empty array when no groups are associated" do
json = described_class.new(category, scope: Guardian.new, root: false).as_json
expect(json[:reply_posting_review_group_ids]).to eq([])
end
end
describe "#require_topic_approval" do
it "returns false when topic approval is not required" do
category.require_topic_approval = false
category.save!
json = described_class.new(category, scope: Guardian.new(admin), root: false).as_json
expect(json[:category_setting][:require_topic_approval]).to eq(false)
end
it "returns true when topic approval is required" do
category.require_topic_approval = true
category.save!
json = described_class.new(category, scope: Guardian.new(admin), root: false).as_json
expect(json[:category_setting][:require_topic_approval]).to eq(true)
end
end
describe "#require_reply_approval" do
it "returns false when reply approval is not required" do
category.require_reply_approval = false
category.save!
json = described_class.new(category, scope: Guardian.new(admin), root: false).as_json
expect(json[:category_setting][:require_reply_approval]).to eq(false)
end
it "returns true when reply approval is required" do
category.require_reply_approval = true
category.save!
json = described_class.new(category, scope: Guardian.new(admin), root: false).as_json
expect(json[:category_setting][:require_reply_approval]).to eq(true)
end
end
describe "#category_types" do
it "returns the category types" do
json = described_class.new(category, scope: admin.guardian, root: false).as_json
expect(json[:category_types]).to eq(
{ discussion: Categories::TypeRegistry.all[:discussion].metadata },
)
end
end
describe "#available_category_types" do
class MockCategoryType < ::Categories::Types::Base
type_id :mock_type
class << self
def category_matches?(category)
true
end
def find_matches
Category.none
end
def visible?
false
end
end
end
before { Categories::TypeRegistry.register(MockCategoryType) }
after { Categories::TypeRegistry.reset! }
it "returns the available visible category types" do
json = described_class.new(category, scope: admin.guardian, root: false).as_json
expect(json[:available_category_types]).to eq(
[Categories::TypeRegistry.all[:discussion].metadata],
)
end
end
describe "#category_type_settings" do
let(:type_a) do
Class.new(Categories::Types::Base) do
type_id :test_type_a
def self.category_matches?(_category)
true
end
def self.read_category_settings(_category)
{ foo: "from_a" }
end
end
end
let(:type_b) do
Class.new(Categories::Types::Base) do
type_id :test_type_b
def self.category_matches?(_category)
true
end
def self.read_category_settings(_category)
{ bar: "from_b" }
end
end
end
let(:non_matching_type) do
Class.new(Categories::Types::Base) do
type_id :test_type_off
def self.category_matches?(_category)
false
end
def self.read_category_settings(_category)
{ baz: "should_not_appear" }
end
end
end
before do
Categories::TypeRegistry.stubs(:all).returns(a: type_a, b: type_b, off: non_matching_type)
end
it "merges values from each matching type and skips non-matching types" do
json = described_class.new(category, scope: admin.guardian, root: false).as_json
expect(json[:category_type_settings]).to eq(foo: "from_a", bar: "from_b")
end
end
end