FIX: TopicQuery for NULL `category.topic_id` (#20664)
Our schema allows `category.topic_id` to be NULL. Null values shouldn't actually happen in production, but it is very common in tests because `Fabricate(:category)` skips creating the definition topic to improve performance. Before this commit, a NULL category.topic_id would cause all subcategory topics to be excluded from a TopicQuery result. This is because, in postgres, `NULL <> anything` is falsy. Instead, we can use `IS DISTINCT FROM`, which will return true when NULL is compared to a non-NULL value.
This commit is contained in:
parent
0a5b078ac7
commit
964f37476d
|
@ -692,7 +692,10 @@ class TopicQuery
|
|||
result = result.where("topics.category_id IN (?)", Category.subcategory_ids(category_id))
|
||||
if !SiteSetting.show_category_definitions_in_topic_lists
|
||||
result =
|
||||
result.where("categories.topic_id <> topics.id OR topics.category_id = ?", category_id)
|
||||
result.where(
|
||||
"categories.topic_id IS DISTINCT FROM topics.id OR topics.category_id = ?",
|
||||
category_id,
|
||||
)
|
||||
end
|
||||
end
|
||||
result = result.references(:categories)
|
||||
|
|
|
@ -1909,4 +1909,31 @@ RSpec.describe TopicQuery do
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "show_category_definitions_in_topic_lists setting" do
|
||||
fab!(:category) { Fabricate(:category_with_definition) }
|
||||
fab!(:subcategory) { Fabricate(:category_with_definition, parent_category: category) }
|
||||
fab!(:subcategory_regular_topic) { Fabricate(:topic, category: subcategory) }
|
||||
|
||||
it "excludes subcategory definition topics by default" do
|
||||
expect(
|
||||
TopicQuery.new(nil, category: category.id).list_latest.topics.map(&:id),
|
||||
).to contain_exactly(category.topic_id, subcategory_regular_topic.id)
|
||||
end
|
||||
|
||||
it "works when topic_id is null" do
|
||||
subcategory.topic.destroy!
|
||||
subcategory.update!(topic_id: nil)
|
||||
expect(
|
||||
TopicQuery.new(nil, category: category.id).list_latest.topics.map(&:id),
|
||||
).to contain_exactly(category.topic_id, subcategory_regular_topic.id)
|
||||
end
|
||||
|
||||
it "includes subcategory definition when setting enabled" do
|
||||
SiteSetting.show_category_definitions_in_topic_lists = true
|
||||
expect(
|
||||
TopicQuery.new(nil, category: category.id).list_latest.topics.map(&:id),
|
||||
).to contain_exactly(category.topic_id, subcategory.topic_id, subcategory_regular_topic.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -131,10 +131,17 @@ RSpec.describe CategoriesController do
|
|||
category_list = response.parsed_body["category_list"]
|
||||
|
||||
category_response = category_list["categories"].find { |c| c["id"] == category.id }
|
||||
expect(category_response["topics"].map { |c| c["id"] }).to contain_exactly(topic1.id)
|
||||
expect(category_response["topics"].map { |c| c["id"] }).to contain_exactly(
|
||||
topic1.id,
|
||||
topic2.id,
|
||||
topic3.id,
|
||||
)
|
||||
|
||||
subcategory_response = category_response["subcategory_list"][0]
|
||||
expect(subcategory_response["topics"].map { |c| c["id"] }).to contain_exactly(topic2.id)
|
||||
expect(subcategory_response["topics"].map { |c| c["id"] }).to contain_exactly(
|
||||
topic2.id,
|
||||
topic3.id,
|
||||
)
|
||||
|
||||
subsubcategory_response = subcategory_response["subcategory_list"][0]
|
||||
expect(subsubcategory_response["topics"].map { |c| c["id"] }).to contain_exactly(topic3.id)
|
||||
|
|
Loading…
Reference in New Issue