mirror of
https://github.com/discourse/discourse.git
synced 2026-08-06 13:08:40 +08:00
This creates an explicit "default homepage" setting, because right now
the experience of changing the homepage via the "top menu" setting isn't
very intuitive. This will also make it easier to support new homepage
options in the future that don't necessarily need to exist within "top
menu."
The setting is empty by default, and when empty it falls back to "First
item in top menu" — using the current functionality as a fallback means
we don't need a migration.
The options in the list are the core top menu choices plus anything
registered via `Discourse.filters.push(:filter)`. Registered filters are
an existing pattern that come with all the prerequisites to function as
a homepage (server & client routes, and a topic list).
So for example, how the "votes" option is produced
plugins/discourse-topic-voting/plugin.rb
```ruby
Discourse.filters.push(:votes)
Discourse.anonymous_filters.push(:votes)
```
anonymous_filters is optional, if there's no anonymous equivalent of a
given option, we fall back to the first anon-viewable top menu item
(there's always at least one)
lib/discourse_topic_voting/topic_query_extension.rb
```ruby
def list_votes
create_list(:votes, unordered: true) do |topics|
topics.joins(
"LEFT JOIN topic_voting_topic_vote_count dvtvc ON dvtvc.topic_id = topics.id",
).order("COALESCE(dvtvc.votes_count,'0')::integer DESC, topics.bumped_at DESC")
end
end
```
config/locales/client.en.yml
```yaml
js:
filters:
votes:
title: "Votes"
help: "topics with the all time most votes"
```
<img width="600" alt="image"
src="https://github.com/user-attachments/assets/6b580e92-1b58-477c-81ab-6ceacc020672"
/>
This also adds a persistent "Default" option to the Default Home Page
user preference, which was previously only visible when a custom
homepage is set by a theme.
A future enhancement could add a plugin API for registering non-filter
homepage options (e.g. a chat channel)
Some related fixes along for the ride:
* select-kit treated a blank value as "clear selection", so it could not
be selected or displayed... this allows "First item in top menu" as an
alias for being unset
* the admin combo-box couldn't detect when the first choice's value was
blank, and submitted the whole object
* topic lists advertised RSS feeds that don't exist for registered
filters (this was happening with /votes)
733 lines
26 KiB
Ruby
Vendored
733 lines
26 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
RSpec.describe SiteSerializer do
|
|
let(:guardian) { Guardian.new }
|
|
let(:category) { Fabricate(:category) }
|
|
|
|
after { Site.clear_cache }
|
|
|
|
describe "category_types" do
|
|
it "is included on each serialized category in the site payload" do
|
|
category
|
|
Site.clear_cache
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
c = serialized[:categories].find { |entry| entry[:id] == category.id }
|
|
expect(c).to have_key(:category_types)
|
|
end
|
|
end
|
|
|
|
describe "#homepage_choices" do
|
|
it "exposes the eligible homepage choices" do
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:homepage_choices]).to eq(TopMenu.homepage_choices)
|
|
end
|
|
end
|
|
|
|
describe "#user_tips" do
|
|
it "is included if enable_user_tips" do
|
|
SiteSetting.enable_user_tips = true
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:user_tips]).to eq(User.user_tips)
|
|
end
|
|
|
|
it "is not included if enable_user_tips is disabled" do
|
|
SiteSetting.enable_user_tips = false
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:user_tips]).to eq(nil)
|
|
end
|
|
end
|
|
|
|
describe "#access_control" do
|
|
let(:target_class) do
|
|
Class.new(ActiveRecord::Base) do
|
|
include AclTarget
|
|
|
|
self.table_name = "posts"
|
|
|
|
def self.name
|
|
"SiteSerializerSpecTarget"
|
|
end
|
|
|
|
def self.mandatory_acl
|
|
[{ type: :group, id: Group::AUTO_GROUPS[:admins], permission: "manage" }]
|
|
end
|
|
|
|
def self.banned_acl
|
|
[{ type: :group, id: Group::AUTO_GROUPS[:anonymous_users], permission: "edit" }]
|
|
end
|
|
end
|
|
end
|
|
|
|
after { DiscoursePluginRegistry.reset_register!(:acl_target_classes) }
|
|
|
|
it "includes mandatory ACLs by target class" do
|
|
target_class
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized.dig(:access_control, :mandatory_acl)).to include(
|
|
"SiteSerializerSpecTarget" => [
|
|
{ type: :group, id: Group::AUTO_GROUPS[:admins], permission: "manage" },
|
|
],
|
|
)
|
|
end
|
|
|
|
it "includes banned ACLs by target class" do
|
|
target_class
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized.dig(:access_control, :banned_acl)).to include(
|
|
"SiteSerializerSpecTarget" => [
|
|
{ type: :group, id: Group::AUTO_GROUPS[:anonymous_users], permission: "edit" },
|
|
],
|
|
)
|
|
end
|
|
|
|
it "includes plugin-registered target classes" do
|
|
Object.const_set(:SiteSerializerSpecTarget, target_class)
|
|
AclTarget.loaded_target_classes.delete(target_class)
|
|
DiscoursePluginRegistry.register_acl_target_class(
|
|
"SiteSerializerSpecTarget",
|
|
Plugin::Instance.new,
|
|
)
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized.dig(:access_control, :mandatory_acl)).to include(
|
|
"SiteSerializerSpecTarget" => [
|
|
{ type: :group, id: Group::AUTO_GROUPS[:admins], permission: "manage" },
|
|
],
|
|
)
|
|
ensure
|
|
Object.send(:remove_const, :SiteSerializerSpecTarget) if defined?(SiteSerializerSpecTarget)
|
|
end
|
|
end
|
|
|
|
it "includes category custom fields only if its preloaded" do
|
|
category.custom_fields["enable_marketplace"] = true
|
|
category.save_custom_fields
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
c1 = serialized[:categories].find { |c| c[:id] == category.id }
|
|
|
|
expect(c1[:custom_fields]).to eq(nil)
|
|
|
|
Site.preloaded_category_custom_fields << "enable_marketplace"
|
|
Site.clear_cache
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
c1 = serialized[:categories].find { |c| c[:id] == category.id }
|
|
|
|
expect(c1[:custom_fields]["enable_marketplace"]).to eq("t")
|
|
ensure
|
|
Site.reset_preloaded_category_custom_fields
|
|
end
|
|
|
|
it "includes category tags" do
|
|
tag = Fabricate(:tag)
|
|
tag_group = Fabricate(:tag_group)
|
|
tag_group_2 = Fabricate(:tag_group)
|
|
|
|
category.tags << tag
|
|
category.tag_groups << tag_group
|
|
category.update!(
|
|
category_required_tag_groups: [
|
|
CategoryRequiredTagGroup.new(tag_group: tag_group_2, min_count: 1),
|
|
],
|
|
)
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
c1 = serialized[:categories].find { |c| c[:id] == category.id }
|
|
|
|
expect(c1[:allowed_tags]).to contain_exactly({ id: tag.id, name: tag.name, slug: tag.slug })
|
|
expect(c1[:allowed_tag_groups]).to contain_exactly(tag_group.name)
|
|
expect(c1[:required_tag_groups]).to eq([{ name: tag_group_2.name, min_count: 1 }])
|
|
end
|
|
|
|
it "doesn't explode when category_required_tag_group is missing" do
|
|
tag = Fabricate(:tag)
|
|
tag_group = Fabricate(:tag_group)
|
|
crtg = CategoryRequiredTagGroup.new(tag_group: tag_group, min_count: 1)
|
|
category.update!(category_required_tag_groups: [crtg])
|
|
|
|
tag_group.delete # Bypassing hooks like this should never happen in the app
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
c1 = serialized[:categories].find { |c| c[:id] == category.id }
|
|
|
|
expect(c1[:required_tag_groups]).to eq([{ name: nil, min_count: 1 }])
|
|
end
|
|
|
|
it "returns correct notification level for categories" do
|
|
SiteSetting.mute_all_categories_by_default = true
|
|
SiteSetting.default_categories_normal = category.id.to_s
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
categories = serialized[:categories]
|
|
expect(categories[0][:notification_level]).to eq(0)
|
|
expect(categories[-1][:notification_level]).to eq(1)
|
|
end
|
|
|
|
it "includes user-selectable color schemes" do
|
|
dark_scheme =
|
|
ColorScheme.create_from_base(
|
|
name: "AnotherDarkScheme",
|
|
base_scheme_id: ColorScheme::NAMES_TO_ID_MAP["Dark"],
|
|
)
|
|
dark_scheme.user_selectable = true
|
|
dark_scheme.save!
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:user_color_schemes].count).to eq(1)
|
|
expect(serialized[:user_color_schemes][0][:is_dark]).to eq(true)
|
|
end
|
|
|
|
describe "only_theme_color_schemes modifier" do
|
|
fab!(:theme)
|
|
fab!(:color_scheme) { Fabricate(:color_scheme, theme_id: theme.id, user_selectable: false) }
|
|
|
|
before do
|
|
theme.update!(user_selectable: true)
|
|
theme.theme_modifier_set.update!(only_theme_color_schemes: true)
|
|
end
|
|
|
|
it "includes theme color schemes in user_color_schemes when modifier is active" do
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
scheme_ids = serialized[:user_color_schemes].map { |s| s[:id] }
|
|
expect(scheme_ids).to include(color_scheme.id)
|
|
end
|
|
|
|
it "includes only_theme_color_schemes flag in user_themes" do
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
theme_data = serialized[:user_themes].find { |t| t["theme_id"] == theme.id }
|
|
expect(theme_data["only_theme_color_schemes"]).to eq(true)
|
|
end
|
|
end
|
|
|
|
it "includes default dark mode scheme" do
|
|
scheme = ColorScheme.last
|
|
Theme.find_default.update!(dark_color_scheme_id: scheme.id)
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
default_dark_scheme = expect(serialized[:default_dark_color_scheme][:name]).to eq(scheme.name)
|
|
|
|
Theme.find_default.update!(dark_color_scheme_id: nil)
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:default_dark_color_scheme]).to eq(nil)
|
|
end
|
|
|
|
it "does not include shared_drafts_category_id if the category is Uncategorized" do
|
|
admin = Fabricate(:admin)
|
|
admin_guardian = Guardian.new(admin)
|
|
|
|
SiteSetting.shared_drafts_category = SiteSetting.uncategorized_category_id
|
|
|
|
serialized =
|
|
described_class.new(Site.new(admin_guardian), scope: admin_guardian, root: false).as_json
|
|
expect(serialized[:shared_drafts_category_id]).to eq(nil)
|
|
end
|
|
|
|
context "with lazy loaded categories enabled" do
|
|
fab!(:user)
|
|
fab!(:category)
|
|
fab!(:sidebar) { Fabricate(:category_sidebar_section_link, linkable: category, user: user) }
|
|
|
|
before { SiteSetting.lazy_load_categories_groups = "#{Group::AUTO_GROUPS[:logged_in_users]}" }
|
|
|
|
it "includes categories for anonymous users" do
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized[:categories].map { |category| category[:id] }).to include(category.id)
|
|
end
|
|
|
|
it "includes preloaded categories for logged in users" do
|
|
guardian = Guardian.new(user)
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized[:categories].map { |c| c[:id] }).to contain_exactly(category.id)
|
|
end
|
|
end
|
|
|
|
describe "#anonymous_default_navigation_menu_tags" do
|
|
fab!(:user)
|
|
fab!(:tag) { Fabricate(:tag, name: "dev", description: "some description") }
|
|
fab!(:tag2) { Fabricate(:tag, name: "random") }
|
|
fab!(:hidden_tag) { Fabricate(:tag, name: "secret") }
|
|
|
|
fab!(:staff_tag_group) do
|
|
Fabricate(:tag_group, permissions: { "staff" => 1 }, tag_names: [hidden_tag.name])
|
|
end
|
|
|
|
before do
|
|
SiteSetting.navigation_menu = "sidebar"
|
|
SiteSetting.tagging_enabled = true
|
|
SiteSetting.default_navigation_menu_tags = "#{tag.name}|#{tag2.name}|#{hidden_tag.name}"
|
|
end
|
|
|
|
it "is not included in the serialised object when tagging is not enabled" do
|
|
SiteSetting.tagging_enabled = false
|
|
guardian = Guardian.new(user)
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:anonymous_default_navigation_menu_tags]).to eq(nil)
|
|
end
|
|
|
|
it "is not included in the serialised object when user is not anonymous" do
|
|
guardian = Guardian.new(user)
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:anonymous_default_navigation_menu_tags]).to eq(nil)
|
|
end
|
|
|
|
it "is not included in the serialisd object when default sidebar tags have not been configured" do
|
|
SiteSetting.default_navigation_menu_tags = ""
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:anonymous_default_navigation_menu_tags]).to eq(nil)
|
|
end
|
|
|
|
it "includes only tags user can see in the serialised object when user is anonymous" do
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized[:anonymous_default_navigation_menu_tags]).to eq(
|
|
[
|
|
{
|
|
id: tag.id,
|
|
name: "dev",
|
|
slug: tag.slug,
|
|
description: "some description",
|
|
pm_only: false,
|
|
},
|
|
{
|
|
id: tag2.id,
|
|
name: "random",
|
|
slug: tag2.slug,
|
|
description: tag2.description,
|
|
pm_only: false,
|
|
},
|
|
],
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "#anonymous_sidebar_sections" do
|
|
fab!(:user)
|
|
fab!(:public_sidebar_section) do
|
|
Fabricate(:sidebar_section, title: "Public section", public: true)
|
|
end
|
|
fab!(:private_sidebar_section) do
|
|
Fabricate(:sidebar_section, title: "Private section", user: user, public: false)
|
|
end
|
|
|
|
it "is not included in the serialised object when user is not anonymous" do
|
|
guardian = Guardian.new(user)
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized).not_to have_key(:anonymous_sidebar_sections)
|
|
end
|
|
|
|
it "includes only public sidebar sections serialised object when user is anonymous" do
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:anonymous_sidebar_sections].map { |section| section[:title] }).to eq(
|
|
["Community", "Public section"],
|
|
)
|
|
end
|
|
|
|
it "eager loads sidebar_urls" do
|
|
public_section_link =
|
|
Fabricate(:custom_sidebar_section_link, user: user, sidebar_section: public_sidebar_section)
|
|
# warmup
|
|
described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
initial_count =
|
|
track_sql_queries do
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized[:anonymous_sidebar_sections].count).to eq(2)
|
|
|
|
expect(
|
|
serialized[:anonymous_sidebar_sections].last[:links].map { |link| link[:id] },
|
|
).to eq([public_section_link.linkable.id])
|
|
end.count
|
|
|
|
public_section_link_2 =
|
|
Fabricate(:custom_sidebar_section_link, user: user, sidebar_section: public_sidebar_section)
|
|
public_section_link_3 =
|
|
Fabricate(:custom_sidebar_section_link, user: user, sidebar_section: public_sidebar_section)
|
|
|
|
final_count =
|
|
track_sql_queries do
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized[:anonymous_sidebar_sections].count).to eq(2)
|
|
|
|
expect(
|
|
serialized[:anonymous_sidebar_sections].last[:links].map { |link| link[:id] },
|
|
).to eq(
|
|
[
|
|
public_section_link.linkable.id,
|
|
public_section_link_2.linkable.id,
|
|
public_section_link_3.linkable.id,
|
|
],
|
|
)
|
|
end.count
|
|
expect(final_count).to eq(initial_count)
|
|
end
|
|
end
|
|
|
|
describe "#top_tags" do
|
|
fab!(:tag)
|
|
|
|
describe "when tagging is not enabled" do
|
|
before { SiteSetting.tagging_enabled = false }
|
|
|
|
it "is not included in the serialised object" do
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized[:top_tags]).to eq(nil)
|
|
end
|
|
end
|
|
|
|
describe "when tagging is enabled" do
|
|
fab!(:tag2, :tag)
|
|
fab!(:tag3, :tag)
|
|
|
|
before { SiteSetting.tagging_enabled = true }
|
|
|
|
it "is not included in the serialised object when there are no tags" do
|
|
tag.destroy!
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized[:top_tags]).to eq([])
|
|
end
|
|
|
|
it "is included in the serialised object containing the top tags" do
|
|
tag2 = Fabricate(:tag)
|
|
tag2 = Fabricate(:tag)
|
|
|
|
SiteSetting.max_tags_in_filter_list = 1
|
|
|
|
CategoryTagStat.create!(
|
|
category_id: SiteSetting.uncategorized_category_id,
|
|
tag_id: tag2.id,
|
|
topic_count: 2,
|
|
)
|
|
CategoryTagStat.create!(
|
|
category_id: SiteSetting.uncategorized_category_id,
|
|
tag_id: tag.id,
|
|
topic_count: 1,
|
|
)
|
|
CategoryTagStat.create!(
|
|
category_id: SiteSetting.uncategorized_category_id,
|
|
tag_id: tag3.id,
|
|
topic_count: 5,
|
|
)
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized[:top_tags]).to eq(
|
|
[
|
|
{ id: tag3.id, name: tag3.name, slug: tag3.slug },
|
|
{ id: tag2.id, name: tag2.name, slug: tag2.slug },
|
|
],
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#navigation_menu_site_top_tags" do
|
|
fab!(:tag1) do
|
|
Fabricate(:tag, name: "tag 1").tap { |tag| Fabricate.times(2, :topic, tags: [tag]) }
|
|
end
|
|
|
|
fab!(:tag2) do
|
|
Fabricate(:tag, name: "tag 2").tap { |tag| Fabricate.times(1, :topic, tags: [tag]) }
|
|
end
|
|
|
|
fab!(:tag3) do
|
|
Fabricate(:tag, name: "tag 3").tap { |tag| Fabricate.times(3, :topic, tags: [tag]) }
|
|
end
|
|
|
|
fab!(:hidden_tag) do
|
|
Fabricate(:tag, name: "tag 4").tap { |tag| Fabricate.times(4, :topic, tags: [tag]) }
|
|
end
|
|
|
|
fab!(:staff_tag_group) do
|
|
Fabricate(:tag_group, permissions: { "staff" => 1 }, tag_names: [hidden_tag.name])
|
|
end
|
|
|
|
it "should return the site's top tags as the default tags for sidebar" do
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized[:navigation_menu_site_top_tags]).to eq(
|
|
[
|
|
{
|
|
id: tag3.id,
|
|
name: tag3.name,
|
|
slug: tag3.slug_for_url,
|
|
description: tag3.description,
|
|
pm_only: false,
|
|
},
|
|
{
|
|
id: tag1.id,
|
|
name: tag1.name,
|
|
slug: tag1.slug_for_url,
|
|
description: tag1.description,
|
|
pm_only: false,
|
|
},
|
|
{
|
|
id: tag2.id,
|
|
name: tag2.name,
|
|
slug: tag2.slug_for_url,
|
|
description: tag2.description,
|
|
pm_only: false,
|
|
},
|
|
],
|
|
)
|
|
end
|
|
|
|
it "should not be serialized if `tagging_enabled` site setting is set to false" do
|
|
SiteSetting.set(:tagging_enabled, false)
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized[:navigation_menu_site_top_tags]).to eq(nil)
|
|
end
|
|
|
|
it "should use slug_for_url for tags with empty slugs" do
|
|
numeric_tag =
|
|
Fabricate(:tag, name: "1").tap { |tag| Fabricate.times(10, :topic, tags: [tag]) }
|
|
|
|
expect(numeric_tag.slug).to eq("")
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
numeric_entry =
|
|
serialized[:navigation_menu_site_top_tags].find { |t| t[:id] == numeric_tag.id }
|
|
|
|
expect(numeric_entry[:slug]).to eq("#{numeric_tag.id}-tag")
|
|
end
|
|
|
|
it "should return an empty array if site has no top tags" do
|
|
Tag.delete_all
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
|
|
expect(serialized[:navigation_menu_site_top_tags]).to eq([])
|
|
end
|
|
end
|
|
|
|
describe "#whispers_allowed_groups_names" do
|
|
fab!(:admin)
|
|
fab!(:allowed_user, :user)
|
|
fab!(:not_allowed_user, :user)
|
|
fab!(:group1) { Fabricate(:group, name: "whisperers1", users: [allowed_user]) }
|
|
fab!(:group2) { Fabricate(:group, name: "whisperers2", users: [allowed_user]) }
|
|
|
|
it "returns correct group names for created groups" do
|
|
admin_guardian = Guardian.new(admin)
|
|
SiteSetting.whispers_allowed_groups = "#{group1.id}|#{group2.id}"
|
|
|
|
serialized =
|
|
described_class.new(Site.new(admin_guardian), scope: admin_guardian, root: false).as_json
|
|
expect(serialized[:whispers_allowed_groups_names]).to contain_exactly(
|
|
"whisperers1",
|
|
"whisperers2",
|
|
)
|
|
end
|
|
|
|
it "returns correct group names for automatic groups" do
|
|
admin_guardian = Guardian.new(admin)
|
|
SiteSetting.whispers_allowed_groups =
|
|
"#{Group::AUTO_GROUPS[:staff]}|#{Group::AUTO_GROUPS[:trust_level_4]}"
|
|
|
|
serialized =
|
|
described_class.new(Site.new(admin_guardian), scope: admin_guardian, root: false).as_json
|
|
expect(serialized[:whispers_allowed_groups_names]).to contain_exactly(
|
|
"trust_level_4",
|
|
"staff",
|
|
)
|
|
end
|
|
|
|
it "returns group names when user is allowed to whisper" do
|
|
user_guardian = Guardian.new(allowed_user)
|
|
SiteSetting.whispers_allowed_groups = "#{group1.id}|#{group2.id}"
|
|
|
|
serialized =
|
|
described_class.new(Site.new(user_guardian), scope: user_guardian, root: false).as_json
|
|
expect(serialized[:whispers_allowed_groups_names]).to contain_exactly(
|
|
"whisperers1",
|
|
"whisperers2",
|
|
)
|
|
end
|
|
|
|
it "returns nil when user is not allowed to whisper" do
|
|
user_guardian = Guardian.new(not_allowed_user)
|
|
SiteSetting.whispers_allowed_groups =
|
|
"#{Group::AUTO_GROUPS[:staff]}|#{Group::AUTO_GROUPS[:trust_level_4]}"
|
|
|
|
serialized =
|
|
described_class.new(Site.new(user_guardian), scope: user_guardian, root: false).as_json
|
|
expect(serialized[:whispers_allowed_groups_names]).to eq(nil)
|
|
end
|
|
end
|
|
|
|
describe "#full_name_required_for_signup" do
|
|
let(:site_json) do
|
|
described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
end
|
|
|
|
it "is false when full_name_requirement setting is optional_at_signup" do
|
|
SiteSetting.full_name_requirement = "optional_at_signup"
|
|
expect(site_json[:full_name_required_for_signup]).to eq(false)
|
|
end
|
|
|
|
it "is false when full_name_requirement setting is hidden_at_signup" do
|
|
SiteSetting.full_name_requirement = "hidden_at_signup"
|
|
SiteSetting.enable_names = true
|
|
expect(site_json[:full_name_required_for_signup]).to eq(false)
|
|
end
|
|
|
|
it "is true when full_name_requirement setting is required_at_signup and enable_names is true" do
|
|
SiteSetting.full_name_requirement = "required_at_signup"
|
|
SiteSetting.enable_names = true
|
|
expect(site_json[:full_name_required_for_signup]).to eq(true)
|
|
end
|
|
end
|
|
|
|
describe "#full_name_visible_in_signup" do
|
|
let(:site_json) do
|
|
described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
end
|
|
|
|
it "is false when full_name_requirement is hidden_at_signup" do
|
|
SiteSetting.full_name_requirement = "hidden_at_signup"
|
|
expect(site_json[:full_name_visible_in_signup]).to eq(false)
|
|
end
|
|
|
|
it "is true when enable_names setting is true and full_name_requirement is optional_at_signup" do
|
|
SiteSetting.full_name_requirement = "optional_at_signup"
|
|
expect(site_json[:full_name_visible_in_signup]).to eq(true)
|
|
end
|
|
|
|
it "is true when enable_names setting is true and full_name_requirement is required_at_signup" do
|
|
SiteSetting.full_name_requirement = "required_at_signup"
|
|
expect(site_json[:full_name_visible_in_signup]).to eq(true)
|
|
end
|
|
|
|
it "is false when enable_names setting is true and full_name_requirement is hidden_at_signup" do
|
|
SiteSetting.full_name_requirement = "hidden_at_signup"
|
|
expect(site_json[:full_name_visible_in_signup]).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe "#email_configured" do
|
|
it "returns true when smtp_address is set" do
|
|
global_setting :smtp_address, "smtp.example.com"
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:email_configured]).to eq(true)
|
|
end
|
|
|
|
it "returns false when smtp_address is blank" do
|
|
global_setting :smtp_address, ""
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:email_configured]).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe "#groups" do
|
|
fab!(:group)
|
|
fab!(:admin)
|
|
|
|
it "serializes the automatic field of each group" do
|
|
serialized_groups =
|
|
described_class.new(Site.new(admin.guardian), scope: admin.guardian, root: false).as_json[
|
|
:groups
|
|
]
|
|
|
|
expect(serialized_groups.find { |g| g["name"] == "trust_level_1" }["automatic"]).to eq(true)
|
|
expect(serialized_groups.find { |g| g["name"] == group.name }["automatic"]).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe "#admin_config_login_routes" do
|
|
fab!(:admin)
|
|
fab!(:user)
|
|
|
|
before { DiscoursePluginRegistry.admin_config_login_routes << "plugin_login_route" }
|
|
|
|
after { DiscoursePluginRegistry.admin_config_login_routes.delete("plugin_login_route") }
|
|
|
|
it "is included for admin users" do
|
|
admin_guardian = Guardian.new(admin)
|
|
serialized =
|
|
described_class.new(Site.new(admin_guardian), scope: admin_guardian, root: false).as_json
|
|
expect(serialized[:admin_config_login_routes]).to include("plugin_login_route")
|
|
end
|
|
|
|
it "is not included for anonymous users" do
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized).not_to have_key(:admin_config_login_routes)
|
|
end
|
|
|
|
it "is not included for non-admin users" do
|
|
user_guardian = Guardian.new(user)
|
|
serialized =
|
|
described_class.new(Site.new(user_guardian), scope: user_guardian, root: false).as_json
|
|
expect(serialized).not_to have_key(:admin_config_login_routes)
|
|
end
|
|
end
|
|
|
|
describe "#upcoming_changes_with_css" do
|
|
it "returns upcoming changes with body_class: true" do
|
|
mock_upcoming_change_metadata(
|
|
{
|
|
enable_upload_debug_mode: {
|
|
impact: "other,developers",
|
|
status: :beta,
|
|
impact_type: "other",
|
|
impact_role: "developers",
|
|
body_class: true,
|
|
},
|
|
enable_user_tips: {
|
|
impact: "feature,all_members",
|
|
status: :alpha,
|
|
impact_type: "feature",
|
|
impact_role: "all_members",
|
|
body_class: false,
|
|
},
|
|
},
|
|
)
|
|
|
|
serialized = described_class.new(Site.new(guardian), scope: guardian, root: false).as_json
|
|
expect(serialized[:upcoming_changes_with_css]).to include(:enable_upload_debug_mode)
|
|
expect(serialized[:upcoming_changes_with_css]).not_to include(:enable_user_tips)
|
|
end
|
|
end
|
|
|
|
describe "#permanent_upcoming_change_names" do
|
|
before do
|
|
UpcomingChanges.stubs(:permanent_upcoming_change_names).returns(%w[enable_permanent_feature])
|
|
end
|
|
|
|
it "returns the permanent change names for staff" do
|
|
admin = Fabricate(:admin)
|
|
admin_guardian = Guardian.new(admin)
|
|
serialized =
|
|
described_class.new(Site.new(admin_guardian), scope: admin_guardian, root: false).as_json
|
|
expect(serialized[:permanent_upcoming_change_names]).to eq(%w[enable_permanent_feature])
|
|
end
|
|
|
|
it "is not included for non-staff users" do
|
|
user = Fabricate(:user)
|
|
user_guardian = Guardian.new(user)
|
|
serialized =
|
|
described_class.new(Site.new(user_guardian), scope: user_guardian, root: false).as_json
|
|
expect(serialized).not_to have_key(:permanent_upcoming_change_names)
|
|
end
|
|
end
|
|
end
|