PERF: Respect guardian when calculating topics per page in categories (#37259)

**What is the problem?**

`CategoriesController.topics_per_page` counted all top-level categories
regardless of user permissions. On sites with many restricted
categories, this caused excessive topic fetching for users who could
only see a small number of categories.

**What is the solution?**

Use `Category.secured(guardian)` to only count categories visible to the
current user and add a maximum cap of 100 topics as a safety net.
This commit is contained in:
Alan Guo Xiang Tan
2026-01-22 14:17:36 +08:00
committed by GitHub
parent 8a87e547f5
commit 7d3e965ae5
2 changed files with 33 additions and 4 deletions
@@ -1317,6 +1317,34 @@ RSpec.describe CategoriesController do
expect(parsed_topic).to be_present
end
end
it "only counts categories the user can see when calculating topics per page" do
SiteSetting.categories_topics = 0
restricted_group = Fabricate(:group)
4.times { Fabricate(:private_category, group: restricted_group) }
# anon sees 2 categories (uncategorized + category): 2 * 1.5 = 3, clamped to min 5
get "/categories_and_latest.json"
expect(response.parsed_body["topic_list"]["topics"].size).to eq(5)
# member sees 6 categories (2 + 4 private): 6 * 1.5 = 9
restricted_group.add(user)
sign_in(user)
get "/categories_and_latest.json"
expect(response.parsed_body["topic_list"]["topics"].size).to eq(9)
end
it "enforces maximum cap on topics per page" do
SiteSetting.categories_topics = 0
5.times { Fabricate(:category) }
# 7 categories (uncategorized + category + 5 new): 7 * 1.5 = 10, capped to max 7
stub_const(CategoriesController, :MAX_CATEGORIES_TOPICS, 7) do
sign_in(admin)
get "/categories_and_latest.json"
expect(response.parsed_body["topic_list"]["topics"].size).to eq(7)
end
end
end
describe "#visible_groups" do