FEATURE: Enable the new /about page for everyone (#29390)

This commit removes the feature flag for the new /about page, enabling it for all sites, and removes the code for old the /about page.

Internal topic: t/140413.
This commit is contained in:
Osama Sayegh 2024-10-29 18:40:11 +03:00 committed by GitHub
parent cc447a1ae3
commit 2ffe413b0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 364 additions and 765 deletions

View File

@ -5,6 +5,7 @@
(hash basePath=(base-path))
}}
@hideTabs={{true}}
@learnMoreUrl="https://meta.discourse.org/t/understanding-and-customizing-the-about-page/332161"
>
<:breadcrumbs>
<DBreadcrumbsItem

View File

@ -1,70 +1,9 @@
import Controller from "@ember/controller";
import { alias, gt } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
import I18n from "discourse-i18n";
// TODO(osama): remove all of these methods when the legacy about page is
// removed
const customStats = [];
export function addLegacyStat(name) {
customStats.push(name);
}
export function clearCustomStats() {
customStats.clear();
}
export default class AboutController extends Controller {
@gt("siteSettings.faq_url.length", 0) faqOverridden;
@alias("siteSettings.experimental_rename_faq_to_guidelines")
renameFaqToGuidelines;
@discourseComputed("model.contact_url", "model.contact_email")
contactInfo(url, email) {
if (url) {
return I18n.t("about.contact_info", {
contact_info: `<a href='${url}' target='_blank'>${url}</a>`,
});
} else if (email) {
return I18n.t("about.contact_info", {
contact_info: email,
});
} else {
return null;
}
}
@discourseComputed(
"model.stats.visitors_30_days",
"model.stats.eu_visitors_30_days"
)
statsTableFooter(all, eu) {
return I18n.messageFormat("about.traffic_info_footer_MF", {
total_visitors: all,
eu_visitors: eu,
});
}
@discourseComputed("site.displayed_about_plugin_stat_groups")
statGroups() {
const set = new Set(customStats);
for (const name of this.site.displayed_about_plugin_stat_groups || []) {
set.add(name);
}
return Array.from(set);
}
@discourseComputed(
"model.stats.visitors_7_days",
"model.stats.eu_visitors_7_days",
"siteSettings.display_eu_visitor_stats"
)
displayVisitorStats(visitors, euVisitors, displayEuVisitorStats) {
return (
displayEuVisitorStats &&
typeof euVisitors === "number" &&
typeof visitors === "number"
);
}
}

View File

@ -43,7 +43,6 @@ import { setDesktopScrollAreaHeight } from "discourse/components/topic-timeline/
import { addTopicTitleDecorator } from "discourse/components/topic-title";
import { setNotificationsLimit as setUserMenuNotificationsLimit } from "discourse/components/user-menu/notifications-list";
import { addUserMenuProfileTabItem } from "discourse/components/user-menu/profile-tab-content";
import { addLegacyStat as addLegacyAboutPageStat } from "discourse/controllers/about";
import { addDiscoveryQueryParam } from "discourse/controllers/discovery/list";
import { registerFullPageSearchType } from "discourse/controllers/full-page-search";
import { registerCustomPostMessageCallback as registerCustomPostMessageCallback1 } from "discourse/controllers/topic";
@ -3267,7 +3266,6 @@ class PluginApi {
*/
addAboutPageActivity(name, func) {
addAboutPageActivity(name, func);
addLegacyAboutPageStat(name);
}
/**

View File

@ -40,9 +40,7 @@ export const ADMIN_NAV_MAP = [
links: [
{
name: "admin_about_your_site",
route: "adminSiteSettingsCategory",
routeModels: ["required"],
query: { filter: "" },
route: "adminConfig.about",
label: "admin.community.sidebar_link.about_your_site",
icon: "gear",
},

View File

@ -35,168 +35,7 @@
}}</LinkTo></li>
{{/if}}
</ul>
{{#if this.currentUser.render_experimental_about_page}}
<AboutPage @model={{this.model}} />
{{else}}
<section class="about description">
<h2>{{i18n "about.title" title=this.model.title}}</h2>
<p>{{this.model.description}}</p>
</section>
<PluginOutlet
@name="about-after-description"
@connectorTagName="section"
@outletArgs={{hash model=this.model}}
/>
{{#if this.model.admins}}
<section class="about admins">
<h3>{{d-icon "users"}} {{i18n "about.our_admins"}}</h3>
<div class="users">
<LegacyAboutPageUsers @users={{this.model.admins}} />
</div>
</section>
{{/if}}
<span>
<PluginOutlet
@name="about-after-admins"
@connectorTagName="section"
@outletArgs={{hash model=this.model}}
/>
</span>
{{#if this.model.moderators}}
<section class="about moderators">
<h3>{{d-icon "users"}} {{i18n "about.our_moderators"}}</h3>
<div class="users">
<LegacyAboutPageUsers @users={{this.model.moderators}} />
</div>
</section>
{{/if}}
<span>
<PluginOutlet
@name="about-after-moderators"
@connectorTagName="section"
@outletArgs={{hash model=this.model}}
/>
</span>
{{#if this.model.category_moderators.length}}
{{#each this.model.category_moderators as |cm|}}
<section
class="about category-moderators moderators-{{cm.category.slug}}"
>
<h3>{{category-link cm.category}}{{i18n "about.moderators"}}</h3>
<div class="users">
<LegacyAboutPageUsers @users={{cm.moderators}} />
</div>
<div class="clearfix"></div>
</section>
{{/each}}
{{/if}}
{{#if this.model.can_see_about_stats}}
<section class="about stats">
<h3>{{d-icon "far-chart-bar"}} {{i18n "about.stats"}}</h3>
<table class="table">
<thead>
<tr>
<th>
</th>
<th>{{i18n "about.stat.last_day"}}</th>
<th>{{i18n "about.stat.last_7_days"}}</th>
<th>{{i18n "about.stat.last_30_days"}}</th>
<th>{{i18n "about.stat.all_time"}}</th>
</tr>
</thead>
<tbody>
<tr class="about-topic-count">
<td class="title">{{i18n "about.topic_count"}}</td>
<td>{{number this.model.stats.topics_last_day}}</td>
<td>{{number this.model.stats.topics_7_days}}</td>
<td>{{number this.model.stats.topics_30_days}}</td>
<td>{{number this.model.stats.topics_count}}</td>
</tr>
<tr class="about-post-count">
<td>{{i18n "about.post_count"}}</td>
<td>{{number this.model.stats.posts_last_day}}</td>
<td>{{number this.model.stats.posts_7_days}}</td>
<td>{{number this.model.stats.posts_30_days}}</td>
<td>{{number this.model.stats.posts_count}}</td>
</tr>
<tr class="about-user-count">
<td>{{i18n "about.user_count"}}</td>
<td>{{number this.model.stats.users_last_day}}</td>
<td>{{number this.model.stats.users_7_days}}</td>
<td>{{number this.model.stats.users_30_days}}</td>
<td>{{number this.model.stats.users_count}}</td>
</tr>
<tr class="about-active-user-count">
<td>{{i18n "about.active_user_count"}}</td>
<td>{{number this.model.stats.active_users_last_day}}</td>
<td>{{number this.model.stats.active_users_7_days}}</td>
<td>{{number this.model.stats.active_users_30_days}}</td>
<td>&mdash;</td>
</tr>
{{#if this.displayVisitorStats}}
<tr class="about-visitor-count">
<td>{{i18n "about.visitor_count"}}</td>
<td>{{number this.model.stats.visitors_last_day}}</td>
<td>{{number this.model.stats.visitors_7_days}}</td>
<td>{{number this.model.stats.visitors_30_days}}</td>
<td>&mdash;</td>
</tr>
<tr class="about-eu-visitor-count">
<td>{{i18n "about.eu_visitor_count"}}</td>
<td>{{number this.model.stats.eu_visitors_last_day}}</td>
<td>{{number this.model.stats.eu_visitors_7_days}}</td>
<td>{{number this.model.stats.eu_visitors_30_days}}</td>
<td>&mdash;</td>
</tr>
{{/if}}
<tr class="about-like-count">
<td>{{i18n "about.like_count"}}</td>
<td>{{number this.model.stats.likes_last_day}}</td>
<td>{{number this.model.stats.likes_7_days}}</td>
<td>{{number this.model.stats.likes_30_days}}</td>
<td>{{number this.model.stats.likes_count}}</td>
</tr>
{{#each this.statGroups as |statGroupName|}}
<tr class={{concat "about-" statGroupName "-count"}}>
<td>{{i18n (concat "about." statGroupName "_count")}}</td>
<td>{{number
(get
this.model.stats (concat statGroupName "_last_day")
)
}}</td>
<td>{{number
(get this.model.stats (concat statGroupName "_7_days"))
}}</td>
<td>{{number
(get this.model.stats (concat statGroupName "_30_days"))
}}</td>
<td>{{number
(get this.model.stats (concat statGroupName "_count"))
}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{#if this.displayVisitorStats}}
<p class="about stats-table-footer"><small
>{{this.statsTableFooter}}</small></p>
{{/if}}
</section>
{{/if}}
{{#if this.contactInfo}}
<section class="about contact">
<h3>{{d-icon "envelope"}} {{i18n "about.contact"}}</h3>
<p>{{html-safe this.contactInfo}}</p>
</section>
{{/if}}
{{/if}}
<AboutPage @model={{this.model}} />
</div>
</div>
</section>

View File

@ -1,28 +0,0 @@
import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("About", function () {
test("viewing", async function (assert) {
await visit("/about");
assert.dom(document.body).hasClass("about-page", "has body class");
assert.dom(".about.admins .user-info").exists("has admins");
assert.dom(".about.moderators .user-info").exists("has moderators");
assert
.dom(".about.stats tr.about-topic-count td")
.exists("has topic stats");
assert.dom(".about.stats tr.about-post-count td").exists("has post stats");
assert.dom(".about.stats tr.about-user-count td").exists("has user stats");
assert
.dom(".about.stats tr.about-active-user-count td")
.exists("has active user stats");
assert.dom(".about.stats tr.about-like-count td").exists("has like stats");
assert
.dom(".about.stats tr.about-chat_messages-count td")
.exists("has plugin stats");
assert
.dom(".about.stats tr.about-chat_users-count td")
.doesNotExist("does not show hidden plugin stats");
});
});

View File

@ -108,7 +108,7 @@ acceptance("Admin Sidebar - Sections", function (needs) {
assert.strictEqual(count(".admin-reports-list__report"), 0);
await click(
".sidebar-section-link[data-link-name='admin_about_your_site']"
".sidebar-section-link[data-link-name='admin_login_and_authentication']"
);
await click(".sidebar-section-link[data-link-name='admin_all_reports']");

View File

@ -66,7 +66,7 @@ acceptance("Page Loading Indicator", function (needs) {
assert.strictEqual(currentRouteName(), "about");
assert.dom(SPINNER_SELECTOR).doesNotExist();
assert.dom("#main-outlet section.about").exists();
assert.dom("#main-outlet .about__main-content").exists();
});
test("it works in 'slider' mode", async function (assert) {
@ -98,7 +98,7 @@ acceptance("Page Loading Indicator", function (needs) {
await settled();
assert.strictEqual(currentRouteName(), "about");
assert.dom("#main-outlet section.about").exists();
assert.dom("#main-outlet .about__main-content").exists();
});
test("it only performs one slide during nested loading events", async function (assert) {

View File

@ -724,7 +724,6 @@ export default {
can_revoke: true,
},
],
displayed_about_plugin_stat_groups: ["chat_messages"],
hashtag_configurations: { "topic-composer": ["category", "tag"] },
hashtag_icons: { "category": "folder", "tag": "tag" },
anonymous_sidebar_sections: [

View File

@ -29,7 +29,6 @@ import { resetQuickSearchRandomTips } from "discourse/components/search-menu/res
import { resetOnKeyUpCallbacks } from "discourse/components/search-menu/search-term";
import { resetTopicTitleDecorators } from "discourse/components/topic-title";
import { resetUserMenuProfileTabItems } from "discourse/components/user-menu/profile-tab-content";
import { clearCustomStats as clearLegacyAboutPageStats } from "discourse/controllers/about";
import { resetCustomPostMessageCallbacks } from "discourse/controllers/topic";
import { clearHTMLCache } from "discourse/helpers/custom-html";
import { resetUsernameDecorators } from "discourse/helpers/decorate-username-selector";
@ -252,7 +251,6 @@ export function testCleanup(container, app) {
resetTransformers();
rollbackAllPrepends();
clearAboutPageActivities();
clearLegacyAboutPageStats();
resetWidgetCleanCallbacks();
clearPluginHeaderActionComponents();
}

View File

@ -96,46 +96,3 @@
width: 100%;
}
}
section.about {
margin-bottom: 3em;
.users {
display: grid;
gap: 1em;
grid-template-columns: repeat(auto-fit, minmax(20em, 1fr));
}
h3 {
margin-bottom: 1em;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0 0.35em;
.d-icon {
color: var(--primary-high);
}
.badge-category__wrapper {
font-size: var(--font-0);
align-self: baseline;
}
}
&.stats {
table {
td {
padding: 0.67em;
&:not(:first-child) {
text-align: center;
}
}
}
.stats-table-footer {
max-width: 30em;
}
}
}

View File

@ -1,10 +1,6 @@
# frozen_string_literal: true
class About
def self.displayed_plugin_stat_groups
DiscoursePluginRegistry.stats.select { |stat| stat.show_in_ui }.map { |stat| stat.name }
end
class CategoryMods
include ActiveModel::Serialization
attr_reader :category, :moderators

View File

@ -1,14 +1,13 @@
# frozen_string_literal: true
class Stat
def initialize(name, show_in_ui: false, expose_via_api: false, &block)
def initialize(name, expose_via_api: false, &block)
@name = name
@show_in_ui = show_in_ui
@expose_via_api = expose_via_api
@block = block
end
attr_reader :name, :expose_via_api, :show_in_ui
attr_reader :name, :expose_via_api
def calculate
@block.call.transform_keys { |key| build_key(key) }
@ -41,23 +40,19 @@ class Stat
def self.core_stats
list = [
Stat.new("topics", show_in_ui: true, expose_via_api: true) { Statistics.topics },
Stat.new("posts", show_in_ui: true, expose_via_api: true) { Statistics.posts },
Stat.new("users", show_in_ui: true, expose_via_api: true) { Statistics.users },
Stat.new("active_users", show_in_ui: true, expose_via_api: true) { Statistics.active_users },
Stat.new("likes", show_in_ui: true, expose_via_api: true) { Statistics.likes },
Stat.new("participating_users", show_in_ui: false, expose_via_api: true) do
Statistics.participating_users
end,
Stat.new("topics", expose_via_api: true) { Statistics.topics },
Stat.new("posts", expose_via_api: true) { Statistics.posts },
Stat.new("users", expose_via_api: true) { Statistics.users },
Stat.new("active_users", expose_via_api: true) { Statistics.active_users },
Stat.new("likes", expose_via_api: true) { Statistics.likes },
Stat.new("participating_users", expose_via_api: true) { Statistics.participating_users },
]
if SiteSetting.display_eu_visitor_stats
list.concat(
[
Stat.new("visitors", show_in_ui: true, expose_via_api: true) { Statistics.visitors },
Stat.new("eu_visitors", show_in_ui: true, expose_via_api: true) do
Statistics.eu_visitors
end,
Stat.new("visitors", expose_via_api: true) { Statistics.visitors },
Stat.new("eu_visitors", expose_via_api: true) { Statistics.eu_visitors },
],
)
end

View File

@ -55,18 +55,6 @@ class AboutSerializer < ApplicationSerializer
SiteSetting.contact_email
end
def include_extended_site_description?
render_redesigned_about_page?
end
def include_banner_image?
render_redesigned_about_page?
end
def include_site_creation_date?
render_redesigned_about_page?
end
private
def can_see_about_stats
@ -76,10 +64,4 @@ class AboutSerializer < ApplicationSerializer
def can_see_site_contact_details
scope.can_see_site_contact_details?
end
def render_redesigned_about_page?
return false if scope.anonymous?
scope.user.in_any_groups?(SiteSetting.experimental_redesigned_about_page_groups_map)
end
end

View File

@ -77,7 +77,6 @@ class CurrentUserSerializer < BasicUserSerializer
:can_view_raw_email,
:use_glimmer_topic_list?,
:login_method,
:render_experimental_about_page,
:has_unseen_features
delegate :user_stat, to: :object, private: true
@ -151,10 +150,6 @@ class CurrentUserSerializer < BasicUserSerializer
object.staff?
end
def render_experimental_about_page
object.in_any_groups?(SiteSetting.experimental_redesigned_about_page_groups_map)
end
def can_post_anonymously
SiteSetting.allow_anonymous_posting &&
(is_anonymous || object.in_any_groups?(SiteSetting.anonymous_posting_allowed_groups_map))

View File

@ -39,7 +39,6 @@ class SiteSerializer < ApplicationSerializer
:markdown_additional_options,
:hashtag_configurations,
:hashtag_icons,
:displayed_about_plugin_stat_groups,
:anonymous_default_navigation_menu_tags,
:anonymous_sidebar_sections,
:whispers_allowed_groups_names,
@ -287,10 +286,6 @@ class SiteSerializer < ApplicationSerializer
HashtagAutocompleteService.data_source_icon_map
end
def displayed_about_plugin_stat_groups
About.displayed_plugin_stat_groups
end
SIDEBAR_TOP_TAGS_TO_SHOW = 5
def navigation_menu_site_top_tags

View File

@ -100,15 +100,6 @@
<td><%= stats["likes_7_days"] %></td>
<td><%= stats["likes_30_days"] %></td>
</tr>
<% About.displayed_plugin_stat_groups.each do |stat_group_name| %>
<tr>
<td><%=t "js.about.#{stat_group_name}_count" %></td>
<td><%= stats["#{stat_group_name}_count"] %></td>
<td><%= stats["#{stat_group_name}_last_day"] %></td>
<td><%= stats["#{stat_group_name}_7_days"] %></td>
<td><%= stats["#{stat_group_name}_30_days"] %></td>
</tr>
<% end %>
</table>
</section>

View File

@ -2725,7 +2725,6 @@ en:
experimental_topics_filter: "EXPERIMENTAL: Enables the experimental topics filter route at /filter"
enable_experimental_lightbox: "EXPERIMENTAL: Replace the default image lightbox with the revamped design."
enable_experimental_bookmark_redesign_groups: "EXPERIMENTAL: Show a quick access menu for bookmarks on posts and a new redesigned modal"
experimental_redesigned_about_page_groups: "EXPERIMENTAL: Enable the redesigned /about page for specific groups."
experimental_glimmer_topic_list_groups: "EXPERIMENTAL: Enable the new 'glimmer' topic list implementation. This implementation is under active development, and is not intended for production use. Do not develop themes/plugins against it until the implementation is finalized and announced."
experimental_form_templates: "EXPERIMENTAL: Enable the form templates feature. <b>After enabled,</b> manage the templates at <a href='%{base_path}/admin/customize/form-templates'>Customize / Templates</a>."
admin_sidebar_enabled_groups: "Enable sidebar navigation for the admin UI for the specified groups, which replaces the top-level admin navigation buttons."

View File

@ -2465,10 +2465,6 @@ developer:
default: ""
client: true
hidden: true
experimental_redesigned_about_page_groups:
default: ""
type: group_list
allow_any: false
custom_flags_limit:
default: 50
hidden: true

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
class RemoveExperimentalRedesignedAboutPageGroupsSetting < ActiveRecord::Migration[7.1]
def up
execute(<<~SQL)
DELETE FROM site_settings
WHERE name = 'experimental_redesigned_about_page_groups'
SQL
end
def down
raise IrreversibleMigration.new
end
end

View File

@ -1126,34 +1126,11 @@ class Plugin::Instance
# "chat_messages_30_days": 100,
# "chat_messages_count": 1000,
# }
#
# The show_in_ui option (default false) is used to determine whether the
# group of stats is shown on the site About page in the Site Statistics
# table. Some stats may be needed purely for reporting purposes and thus
# do not need to be shown in the UI to admins/users.
#
# TODO(osama): remove show_in_ui when experimental_redesigned_about_page_groups is removed
def register_stat(
name,
show_in_ui: (
not_using_deprecated_arg = true
false
),
expose_via_api: false,
&block
)
if !not_using_deprecated_arg
Discourse.deprecate(
"`show_in_ui` argument of the `register_stat` API is deprecated. Please use the `addAboutPageActivity` JS API instead if you want your custom stat to be shown on the about page.",
since: "3.4.0.beta2",
drop_from: "3.5.0.beta1",
)
end
def register_stat(name, expose_via_api: false, &block)
# We do not want to register and display the same group multiple times.
return if DiscoursePluginRegistry.stats.any? { |stat| stat.name == name }
stat = Stat.new(name, show_in_ui: show_in_ui, expose_via_api: expose_via_api, &block)
stat = Stat.new(name, expose_via_api: expose_via_api, &block)
DiscoursePluginRegistry.register_stat(stat, self)
end

View File

@ -1,15 +1,10 @@
# frozen_string_literal: true
describe "Chat messages site activity in the about page", type: :system do
fab!(:current_user) { Fabricate(:user) }
fab!(:group) { Fabricate(:group, users: [current_user]) }
let(:about_page) { PageObjects::Pages::About.new }
before do
chat_system_bootstrap
SiteSetting.experimental_redesigned_about_page_groups = group.id.to_s
sign_in(current_user)
Fabricate(:chat_message, created_at: 5.hours.ago)
Fabricate(:chat_message, created_at: 2.days.ago)

View File

@ -928,7 +928,7 @@ TEXT
it "registers an about stat group correctly" do
stats = { :last_day => 1, "7_days" => 10, "30_days" => 100, :count => 1000 }
plugin.register_stat("some_group", show_in_ui: true) { stats }
plugin.register_stat("some_group") { stats }
expect(Stat.all_stats.with_indifferent_access).to match(
hash_including(
some_group_last_day: 1,
@ -939,12 +939,6 @@ TEXT
)
end
it "hides the stat group from the UI by default" do
stats = { :last_day => 1, "7_days" => 10, "30_days" => 100, :count => 1000 }
plugin.register_stat("some_group") { stats }
expect(About.displayed_plugin_stat_groups).to eq([])
end
it "does not allow duplicate named stat groups" do
stats = { :last_day => 1, "7_days" => 10, "30_days" => 100, :count => 1000 }
plugin.register_stat("some_group") { stats }

View File

@ -7,7 +7,7 @@ RSpec.describe About do
def register_stat(name, stats_block)
DiscoursePluginRegistry.register_stat(
Stat.new(name, show_in_ui: true, expose_via_api: true, &stats_block),
Stat.new(name, expose_via_api: true, &stats_block),
stub(enabled?: true),
)
end

View File

@ -1,11 +1,9 @@
# frozen_string_literal: true
describe "About page", type: :system do
fab!(:current_user) { Fabricate(:user) }
fab!(:image_upload)
fab!(:admin) { Fabricate(:admin, last_seen_at: 1.hour.ago) }
fab!(:moderator) { Fabricate(:moderator, last_seen_at: 1.hour.ago) }
fab!(:group) { Fabricate(:group, users: [current_user, admin, moderator]) }
before do
SiteSetting.title = "title for my forum"
@ -22,411 +20,382 @@ describe "About page", type: :system do
SiteSetting.contact_url = "http://some-contact-url.discourse.org"
end
describe "legacy version" do
it "renders successfully for a logged-in user" do
sign_in(current_user)
let(:about_page) { PageObjects::Pages::About.new }
visit("/about")
it "renders successfully" do
about_page.visit
expect(page).to have_css(".about.admins")
expect(page).to have_css(".about.moderators")
expect(page).to have_css(".about.stats")
expect(page).to have_css(".about.contact")
expect(about_page).to have_banner_image(image_upload)
expect(about_page).to have_header_title(SiteSetting.title)
expect(about_page).to have_short_description(SiteSetting.site_description)
expect(about_page).to have_members_count(3, "3")
expect(about_page).to have_admins_count(1, "1")
expect(about_page).to have_moderators_count(1, "1")
end
it "doesn't render banner image when it's not set" do
SiteSetting.about_banner_image = nil
about_page.visit
expect(about_page).to have_no_banner_image
end
describe "displayed site age" do
it "says less than 1 month if the site is less than 1 month old" do
Discourse.stubs(:site_creation_date).returns(1.week.ago)
about_page.visit
expect(about_page).to have_site_created_less_than_1_month_ago
end
it "renders successfully for an anonymous user" do
visit("/about")
it "says how many months old the site is if the site is less than 1 year old" do
Discourse.stubs(:site_creation_date).returns(2.months.ago)
expect(page).to have_css(".about.admins")
expect(page).to have_css(".about.moderators")
expect(page).to have_css(".about.stats")
expect(page).to have_css(".about.contact")
about_page.visit
expect(about_page).to have_site_created_in_months_ago(2)
end
it "says how many years old the site is if the site is more than 1 year old" do
Discourse.stubs(:site_creation_date).returns(5.years.ago)
about_page.visit
expect(about_page).to have_site_created_in_years_ago(5)
end
end
describe "redesigned version" do
let(:about_page) { PageObjects::Pages::About.new }
describe "the site activity section" do
describe "topics" do
before do
Fabricate(:topic, created_at: 2.days.ago)
Fabricate(:topic, created_at: 3.days.ago)
Fabricate(:topic, created_at: 8.days.ago)
end
before do
SiteSetting.experimental_redesigned_about_page_groups = group.id.to_s
sign_in(current_user)
it "shows the count of topics created in the last 7 days" do
about_page.visit
expect(about_page.site_activities.topics).to have_count(2, "2")
expect(about_page.site_activities.topics).to have_7_days_period
end
end
it "renders successfully for a logged in user" do
about_page.visit
describe "posts" do
before do
Fabricate(:post, created_at: 2.days.ago)
Fabricate(:post, created_at: 1.hour.ago)
Fabricate(:post, created_at: 3.hours.ago)
Fabricate(:post, created_at: 23.hours.ago)
end
expect(about_page).to have_banner_image(image_upload)
expect(about_page).to have_header_title(SiteSetting.title)
expect(about_page).to have_short_description(SiteSetting.site_description)
expect(about_page).to have_members_count(4, "4")
expect(about_page).to have_admins_count(1, "1")
expect(about_page).to have_moderators_count(1, "1")
it "shows the count of topics created in the last day" do
about_page.visit
expect(about_page.site_activities.posts).to have_count(3, "3")
expect(about_page.site_activities.posts).to have_1_day_period
end
end
it "doesn't render banner image when it's not set" do
SiteSetting.about_banner_image = nil
describe "visitors" do
context "when the display_eu_visitor_stats setting is disabled" do
before { SiteSetting.display_eu_visitor_stats = false }
it "doesn't show the row" do
about_page.visit
expect(about_page.site_activities).to have_no_activity_item("visitors")
end
end
context "when the display_eu_visitor_stats setting is enabled" do
before { SiteSetting.display_eu_visitor_stats = true }
it "shows the row" do
about_page.visit
expect(about_page.site_activities).to have_activity_item("visitors")
expect(about_page.site_activities.visitors).to have_text(
"0 visitors, about 0 from the EU",
)
end
end
end
describe "active users" do
before do
User.update_all(last_seen_at: 1.month.ago)
Fabricate(:user, last_seen_at: 1.hour.ago)
Fabricate(:user, last_seen_at: 1.day.ago)
Fabricate(:user, last_seen_at: 3.days.ago)
Fabricate(:user, last_seen_at: 6.days.ago)
Fabricate(:user, last_seen_at: 8.days.ago)
end
it "shows the count of active users in the last 7 days" do
about_page.visit
expect(about_page.site_activities.active_users).to have_count(4, "4") # 4 fabricated above
expect(about_page.site_activities.active_users).to have_7_days_period
end
end
describe "sign ups" do
before do
User.update_all(created_at: 1.month.ago)
Fabricate(:user, created_at: 3.hours.ago)
Fabricate(:user, created_at: 3.days.ago)
Fabricate(:user, created_at: 8.days.ago)
end
it "shows the count of signups in the last 7 days" do
about_page.visit
expect(about_page.site_activities.sign_ups).to have_count(2, "2")
expect(about_page.site_activities.sign_ups).to have_7_days_period
end
end
describe "likes" do
before do
UserAction.destroy_all
Fabricate(:user_action, created_at: 1.hour.ago, action_type: UserAction::LIKE)
Fabricate(:user_action, created_at: 1.day.ago, action_type: UserAction::LIKE)
Fabricate(:user_action, created_at: 1.month.ago, action_type: UserAction::LIKE)
Fabricate(:user_action, created_at: 10.years.ago, action_type: UserAction::LIKE)
end
it "shows the count of likes of all time" do
about_page.visit
expect(about_page.site_activities.likes).to have_count(4, "4")
expect(about_page.site_activities.likes).to have_all_time_period
end
end
describe "traffic info footer" do
it "is displayed when the display_eu_visitor_stats setting is true" do
SiteSetting.display_eu_visitor_stats = true
about_page.visit
expect(about_page).to have_traffic_info_footer
end
it "is not displayed when the display_eu_visitor_stats setting is false" do
SiteSetting.display_eu_visitor_stats = false
about_page.visit
expect(about_page).to have_no_traffic_info_footer
end
end
end
describe "our admins section" do
before { User.update_all(last_seen_at: 1.month.ago) }
fab!(:admins) { Fabricate.times(8, :admin) }
it "displays only the 6 most recently seen admins when there are more than 6 admins" do
admins[0].update!(last_seen_at: 4.minutes.ago)
admins[1].update!(last_seen_at: 1.minutes.ago)
admins[2].update!(last_seen_at: 10.minutes.ago)
about_page.visit
expect(about_page).to have_no_banner_image
expect(about_page.admins_list).to have_expand_button
displayed_admins = about_page.admins_list.users
expect(displayed_admins.size).to eq(6)
expect(displayed_admins.map { |u| u[:username] }.first(3)).to eq(
[admins[1].username, admins[0].username, admins[2].username],
)
end
describe "displayed site age" do
it "says less than 1 month if the site is less than 1 month old" do
Discourse.stubs(:site_creation_date).returns(1.week.ago)
it "allows expanding and collapsing the list of admins" do
about_page.visit
about_page.visit
displayed_admins = about_page.admins_list.users
expect(displayed_admins.size).to eq(6)
expect(about_page).to have_site_created_less_than_1_month_ago
end
expect(about_page.admins_list).to be_expandable
it "says how many months old the site is if the site is less than 1 year old" do
Discourse.stubs(:site_creation_date).returns(2.months.ago)
about_page.admins_list.expand
about_page.visit
expect(about_page.admins_list).to be_collapsible
expect(about_page).to have_site_created_in_months_ago(2)
end
displayed_admins = about_page.admins_list.users
expect(displayed_admins.size).to eq(9) # 8 fabricated for this spec group and 1 global
it "says how many years old the site is if the site is more than 1 year old" do
Discourse.stubs(:site_creation_date).returns(5.years.ago)
about_page.admins_list.collapse
about_page.visit
expect(about_page.admins_list).to be_expandable
expect(about_page).to have_site_created_in_years_ago(5)
end
displayed_admins = about_page.admins_list.users
expect(displayed_admins.size).to eq(6)
end
describe "the site activity section" do
describe "topics" do
before do
Fabricate(:topic, created_at: 2.days.ago)
Fabricate(:topic, created_at: 3.days.ago)
Fabricate(:topic, created_at: 8.days.ago)
end
it "doesn't show an expand/collapse button when there are fewer than 6 admins" do
User.where(id: admins.first(4).map(&:id)).destroy_all
it "shows the count of topics created in the last 7 days" do
about_page.visit
expect(about_page.site_activities.topics).to have_count(2, "2")
expect(about_page.site_activities.topics).to have_7_days_period
end
end
about_page.visit
describe "posts" do
before do
Fabricate(:post, created_at: 2.days.ago)
Fabricate(:post, created_at: 1.hour.ago)
Fabricate(:post, created_at: 3.hours.ago)
Fabricate(:post, created_at: 23.hours.ago)
end
it "shows the count of topics created in the last day" do
about_page.visit
expect(about_page.site_activities.posts).to have_count(3, "3")
expect(about_page.site_activities.posts).to have_1_day_period
end
end
describe "visitors" do
context "when the display_eu_visitor_stats setting is disabled" do
before { SiteSetting.display_eu_visitor_stats = false }
it "doesn't show the row" do
about_page.visit
expect(about_page.site_activities).to have_no_activity_item("visitors")
end
end
context "when the display_eu_visitor_stats setting is enabled" do
before { SiteSetting.display_eu_visitor_stats = true }
it "shows the row" do
about_page.visit
expect(about_page.site_activities).to have_activity_item("visitors")
expect(about_page.site_activities.visitors).to have_text(
"1 visitor, about 0 from the EU",
)
end
end
end
describe "active users" do
before do
User.update_all(last_seen_at: 1.month.ago)
Fabricate(:user, last_seen_at: 1.hour.ago)
Fabricate(:user, last_seen_at: 1.day.ago)
Fabricate(:user, last_seen_at: 3.days.ago)
Fabricate(:user, last_seen_at: 6.days.ago)
Fabricate(:user, last_seen_at: 8.days.ago)
end
it "shows the count of active users in the last 7 days" do
about_page.visit
expect(about_page.site_activities.active_users).to have_count(5, "5") # 4 fabricated above + 1 for the current user
expect(about_page.site_activities.active_users).to have_7_days_period
end
end
describe "sign ups" do
before do
User.update_all(created_at: 1.month.ago)
Fabricate(:user, created_at: 3.hours.ago)
Fabricate(:user, created_at: 3.days.ago)
Fabricate(:user, created_at: 8.days.ago)
end
it "shows the count of signups in the last 7 days" do
about_page.visit
expect(about_page.site_activities.sign_ups).to have_count(2, "2")
expect(about_page.site_activities.sign_ups).to have_7_days_period
end
end
describe "likes" do
before do
UserAction.destroy_all
Fabricate(:user_action, created_at: 1.hour.ago, action_type: UserAction::LIKE)
Fabricate(:user_action, created_at: 1.day.ago, action_type: UserAction::LIKE)
Fabricate(:user_action, created_at: 1.month.ago, action_type: UserAction::LIKE)
Fabricate(:user_action, created_at: 10.years.ago, action_type: UserAction::LIKE)
end
it "shows the count of likes of all time" do
about_page.visit
expect(about_page.site_activities.likes).to have_count(4, "4")
expect(about_page.site_activities.likes).to have_all_time_period
end
end
describe "traffic info footer" do
it "is displayed when the display_eu_visitor_stats setting is true" do
SiteSetting.display_eu_visitor_stats = true
about_page.visit
expect(about_page).to have_traffic_info_footer
end
it "is not displayed when the display_eu_visitor_stats setting is false" do
SiteSetting.display_eu_visitor_stats = false
about_page.visit
expect(about_page).to have_no_traffic_info_footer
end
end
displayed_admins = about_page.admins_list.users
expect(displayed_admins.size).to eq(5)
expect(about_page.admins_list).to have_no_expand_button
end
describe "our admins section" do
before { User.update_all(last_seen_at: 1.month.ago) }
it "prioritizes names when prioritize_username_in_ux is false" do
SiteSetting.prioritize_username_in_ux = false
fab!(:admins) { Fabricate.times(8, :admin) }
about_page.visit
it "displays only the 6 most recently seen admins when there are more than 6 admins" do
admins[0].update!(last_seen_at: 4.minutes.ago)
admins[1].update!(last_seen_at: 1.minutes.ago)
admins[2].update!(last_seen_at: 10.minutes.ago)
about_page.visit
expect(about_page.admins_list).to have_expand_button
displayed_admins = about_page.admins_list.users
expect(displayed_admins.size).to eq(6)
expect(displayed_admins.map { |u| u[:username] }.first(3)).to eq(
[admins[1].username, admins[0].username, admins[2].username],
)
end
it "allows expanding and collapsing the list of admins" do
about_page.visit
displayed_admins = about_page.admins_list.users
expect(displayed_admins.size).to eq(6)
expect(about_page.admins_list).to be_expandable
about_page.admins_list.expand
expect(about_page.admins_list).to be_collapsible
displayed_admins = about_page.admins_list.users
expect(displayed_admins.size).to eq(9) # 8 fabricated for this spec group and 1 global
about_page.admins_list.collapse
expect(about_page.admins_list).to be_expandable
displayed_admins = about_page.admins_list.users
expect(displayed_admins.size).to eq(6)
end
it "doesn't show an expand/collapse button when there are fewer than 6 admins" do
User.where(id: admins.first(4).map(&:id)).destroy_all
about_page.visit
displayed_admins = about_page.admins_list.users
expect(displayed_admins.size).to eq(5)
expect(about_page.admins_list).to have_no_expand_button
end
it "prioritizes names when prioritize_username_in_ux is false" do
SiteSetting.prioritize_username_in_ux = false
about_page.visit
displayed_admins = about_page.admins_list.users
admins = User.where(username: displayed_admins.map { |u| u[:username] })
expect(displayed_admins.map { |u| u[:displayed_username] }).to contain_exactly(
*admins.pluck(:name),
)
expect(displayed_admins.map { |u| u[:displayed_name] }).to contain_exactly(
*admins.pluck(:username),
)
end
it "prioritizes usernames when prioritize_username_in_ux is true" do
SiteSetting.prioritize_username_in_ux = true
about_page.visit
displayed_admins = about_page.admins_list.users
admins = User.where(username: displayed_admins.map { |u| u[:username] })
expect(displayed_admins.map { |u| u[:displayed_username] }).to contain_exactly(
*admins.pluck(:username),
)
expect(displayed_admins.map { |u| u[:displayed_name] }).to contain_exactly(
*admins.pluck(:name),
)
end
it "opens the user card when a user is clicked" do
about_page.visit
about_page.admins_list.users.first[:node].click
expect(about_page).to have_css("#user-card")
end
displayed_admins = about_page.admins_list.users
admins = User.where(username: displayed_admins.map { |u| u[:username] })
expect(displayed_admins.map { |u| u[:displayed_username] }).to contain_exactly(
*admins.pluck(:name),
)
expect(displayed_admins.map { |u| u[:displayed_name] }).to contain_exactly(
*admins.pluck(:username),
)
end
describe "our moderators section" do
before { User.update_all(last_seen_at: 1.month.ago) }
it "prioritizes usernames when prioritize_username_in_ux is true" do
SiteSetting.prioritize_username_in_ux = true
fab!(:moderators) { Fabricate.times(9, :moderator) }
about_page.visit
it "displays only the 6 most recently seen moderators when there are more than 6 moderators" do
moderators[5].update!(last_seen_at: 5.hours.ago)
moderators[4].update!(last_seen_at: 2.hours.ago)
moderators[1].update!(last_seen_at: 13.hours.ago)
about_page.visit
expect(about_page.moderators_list).to have_expand_button
displayed_mods = about_page.moderators_list.users
expect(displayed_mods.size).to eq(6)
expect(displayed_mods.map { |u| u[:username] }.first(3)).to eq(
[moderators[4].username, moderators[5].username, moderators[1].username],
)
end
it "allows expanding and collapsing the list of moderators" do
about_page.visit
displayed_mods = about_page.moderators_list.users
expect(displayed_mods.size).to eq(6)
expect(about_page.moderators_list).to be_expandable
about_page.moderators_list.expand
expect(about_page.moderators_list).to be_collapsible
displayed_mods = about_page.moderators_list.users
expect(displayed_mods.size).to eq(10) # 9 fabricated for this spec group and 1 global
about_page.moderators_list.collapse
expect(about_page.moderators_list).to be_expandable
displayed_mods = about_page.moderators_list.users
expect(displayed_mods.size).to eq(6)
end
it "doesn't show an expand/collapse button when there are fewer than 6 moderators" do
User.where(id: moderators.first(4).map(&:id)).destroy_all
about_page.visit
displayed_mods = about_page.moderators_list.users
expect(displayed_mods.size).to eq(6)
expect(about_page.moderators_list).to have_no_expand_button
end
it "prioritizes names when prioritize_username_in_ux is false" do
SiteSetting.prioritize_username_in_ux = false
about_page.visit
displayed_mods = about_page.moderators_list.users
moderators = User.where(username: displayed_mods.map { |u| u[:username] })
expect(displayed_mods.map { |u| u[:displayed_username] }).to contain_exactly(
*moderators.pluck(:name),
)
expect(displayed_mods.map { |u| u[:displayed_name] }).to contain_exactly(
*moderators.pluck(:username),
)
end
it "prioritizes usernames when prioritize_username_in_ux is true" do
SiteSetting.prioritize_username_in_ux = true
about_page.visit
displayed_mods = about_page.moderators_list.users
moderators = User.where(username: displayed_mods.map { |u| u[:username] })
expect(displayed_mods.map { |u| u[:displayed_username] }).to contain_exactly(
*moderators.pluck(:username),
)
expect(displayed_mods.map { |u| u[:displayed_name] }).to contain_exactly(
*moderators.pluck(:name),
)
end
it "opens the user card when a user is clicked" do
about_page.visit
about_page.moderators_list.users.last[:node].click
expect(about_page).to have_css("#user-card")
end
displayed_admins = about_page.admins_list.users
admins = User.where(username: displayed_admins.map { |u| u[:username] })
expect(displayed_admins.map { |u| u[:displayed_username] }).to contain_exactly(
*admins.pluck(:username),
)
expect(displayed_admins.map { |u| u[:displayed_name] }).to contain_exactly(
*admins.pluck(:name),
)
end
describe "the edit link" do
it "appears for admins" do
sign_in(admin)
it "opens the user card when a user is clicked" do
about_page.visit
about_page.visit
expect(about_page).to have_edit_link
about_page.admins_list.users.first[:node].click
expect(about_page).to have_css("#user-card")
end
end
about_page.edit_link.click
describe "our moderators section" do
before { User.update_all(last_seen_at: 1.month.ago) }
try_until_success { expect(current_url).to end_with("/admin/config/about") }
end
fab!(:moderators) { Fabricate.times(9, :moderator) }
it "doesn't appear for moderators" do
sign_in(moderator)
it "displays only the 6 most recently seen moderators when there are more than 6 moderators" do
moderators[5].update!(last_seen_at: 5.hours.ago)
moderators[4].update!(last_seen_at: 2.hours.ago)
moderators[1].update!(last_seen_at: 13.hours.ago)
about_page.visit
expect(about_page).to have_no_edit_link
end
about_page.visit
expect(about_page.moderators_list).to have_expand_button
it "doesn't appear for normal users" do
about_page.visit
expect(about_page).to have_no_edit_link
end
displayed_mods = about_page.moderators_list.users
expect(displayed_mods.size).to eq(6)
expect(displayed_mods.map { |u| u[:username] }.first(3)).to eq(
[moderators[4].username, moderators[5].username, moderators[1].username],
)
end
it "allows expanding and collapsing the list of moderators" do
about_page.visit
displayed_mods = about_page.moderators_list.users
expect(displayed_mods.size).to eq(6)
expect(about_page.moderators_list).to be_expandable
about_page.moderators_list.expand
expect(about_page.moderators_list).to be_collapsible
displayed_mods = about_page.moderators_list.users
expect(displayed_mods.size).to eq(10) # 9 fabricated for this spec group and 1 global
about_page.moderators_list.collapse
expect(about_page.moderators_list).to be_expandable
displayed_mods = about_page.moderators_list.users
expect(displayed_mods.size).to eq(6)
end
it "doesn't show an expand/collapse button when there are fewer than 6 moderators" do
User.where(id: moderators.first(4).map(&:id)).destroy_all
about_page.visit
displayed_mods = about_page.moderators_list.users
expect(displayed_mods.size).to eq(6)
expect(about_page.moderators_list).to have_no_expand_button
end
it "prioritizes names when prioritize_username_in_ux is false" do
SiteSetting.prioritize_username_in_ux = false
about_page.visit
displayed_mods = about_page.moderators_list.users
moderators = User.where(username: displayed_mods.map { |u| u[:username] })
expect(displayed_mods.map { |u| u[:displayed_username] }).to contain_exactly(
*moderators.pluck(:name),
)
expect(displayed_mods.map { |u| u[:displayed_name] }).to contain_exactly(
*moderators.pluck(:username),
)
end
it "prioritizes usernames when prioritize_username_in_ux is true" do
SiteSetting.prioritize_username_in_ux = true
about_page.visit
displayed_mods = about_page.moderators_list.users
moderators = User.where(username: displayed_mods.map { |u| u[:username] })
expect(displayed_mods.map { |u| u[:displayed_username] }).to contain_exactly(
*moderators.pluck(:username),
)
expect(displayed_mods.map { |u| u[:displayed_name] }).to contain_exactly(
*moderators.pluck(:name),
)
end
it "opens the user card when a user is clicked" do
about_page.visit
about_page.moderators_list.users.last[:node].click
expect(about_page).to have_css("#user-card")
end
end
describe "the edit link" do
it "appears for admins" do
sign_in(admin)
about_page.visit
expect(about_page).to have_edit_link
about_page.edit_link.click
try_until_success { expect(current_url).to end_with("/admin/config/about") }
end
it "doesn't appear for moderators" do
sign_in(moderator)
about_page.visit
expect(about_page).to have_no_edit_link
end
it "doesn't appear for normal users" do
about_page.visit
expect(about_page).to have_no_edit_link
end
end
end