mirror of
https://github.com/discourse/discourse.git
synced 2026-08-09 21:45:25 +08:00
Add `ensure_can_see_group` to places where we needed it before returning the group metadata. Also added `.visible_groups(@guardian.user).members_visible_groups(@guardian.user)` to guard `advanced_filter` search --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
599 lines
20 KiB
Ruby
Vendored
599 lines
20 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
require_relative "../support/assign_allowed_group"
|
|
|
|
describe ListController do
|
|
before do
|
|
SiteSetting.personal_message_enabled_groups = Group::AUTO_GROUPS[:trust_level_0]
|
|
SiteSetting.assign_enabled = true
|
|
end
|
|
|
|
fab!(:user, :active_user)
|
|
fab!(:user2, :user)
|
|
let(:admin) { Fabricate(:admin) }
|
|
let(:post) { Fabricate(:post) }
|
|
|
|
describe "only allow users from allowed groups" do
|
|
include_context "with group that is allowed to assign"
|
|
|
|
it "filters requests where current_user is not member of an allowed group" do
|
|
sign_in(user)
|
|
SiteSetting.assign_allowed_on_groups = ""
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json"
|
|
expect(response.status).to eq(403)
|
|
|
|
get "/topics/messages-assigned/#{user.username_lower}.json"
|
|
expect(response.status).to eq(403)
|
|
end
|
|
|
|
it "filters requests from users who can only assign in scoped categories" do
|
|
SiteSetting.assign_allowed_on_groups = ""
|
|
category = Fabricate(:category)
|
|
scoped_group = Fabricate(:group, assignable_level: Group::ALIAS_LEVELS[:everyone])
|
|
scoped_user = Fabricate(:user, groups: [scoped_group])
|
|
allow_group_to_assign_in_category(category, scoped_group)
|
|
|
|
sign_in(scoped_user)
|
|
|
|
get "/topics/group-topics-assigned/#{scoped_group.name}.json"
|
|
expect(response.status).to eq(403)
|
|
|
|
get "/topics/messages-assigned/#{scoped_user.username_lower}.json"
|
|
expect(response.status).to eq(403)
|
|
end
|
|
|
|
it "as an anon user" do
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json"
|
|
expect(response.status).to eq(403)
|
|
|
|
get "/topics/messages-assigned/#{user.username_lower}.json"
|
|
expect(response.status).to eq(403)
|
|
end
|
|
|
|
it "as an admin user" do
|
|
sign_in(admin)
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json"
|
|
expect(response.status).to eq(200)
|
|
|
|
get "/topics/messages-assigned/#{user.username_lower}.json"
|
|
expect(response.status).to eq(200)
|
|
end
|
|
end
|
|
|
|
describe "#group_topics_assigned" do
|
|
include_context "with group that is allowed to assign"
|
|
|
|
fab!(:post1, :post)
|
|
fab!(:post2, :post)
|
|
fab!(:post3, :post)
|
|
fab!(:topic) { post3.topic }
|
|
fab!(:topic1) { post1.topic }
|
|
fab!(:topic2) { post2.topic }
|
|
|
|
before do
|
|
add_to_assign_allowed_group(user)
|
|
|
|
Assigner.new(topic1, user).assign(user)
|
|
Assigner.new(topic2, user).assign(user2)
|
|
|
|
sign_in(user)
|
|
end
|
|
|
|
it "returns 403 for a group hidden from the acting user" do
|
|
hidden_group =
|
|
Fabricate(
|
|
:group,
|
|
visibility_level: Group.visibility_levels[:staff],
|
|
assignable_level: Group::ALIAS_LEVELS[:everyone],
|
|
)
|
|
|
|
get "/g/#{hidden_group.name}.json"
|
|
expect(response.status).to eq(404)
|
|
|
|
get "/topics/group-topics-assigned/#{hidden_group.name}.json"
|
|
expect(response.status).to eq(403)
|
|
end
|
|
|
|
it "returns user-assigned-topics-list of users in the assigned_allowed_group and doesn't include deleted topic" do
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json"
|
|
expect(
|
|
JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["assigned_to_user"]["id"] },
|
|
).to match_array([user.id])
|
|
end
|
|
|
|
it "returns user-assigned-topics-list of users in the assigned_allowed_group and doesn't include inactive topics" do
|
|
Assignment.where(assigned_to: user, target: topic1).update_all(active: false)
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json"
|
|
expect(response.parsed_body["topic_list"]["topics"]).to be_empty
|
|
end
|
|
|
|
it "returns empty user-assigned-topics-list for users not in the assigned_allowed_group" do
|
|
ids = []
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json"
|
|
JSON.parse(response.body)["topic_list"]["topics"].each do |t|
|
|
ids.push(t["assigned_to_user"]["id"]) if t["assigned_to_user"]["id"] == user2.id
|
|
end
|
|
expect(ids).to be_empty
|
|
end
|
|
|
|
it "returns the correct more_topics_url with a unicode group name" do
|
|
SiteSetting.unicode_usernames = true
|
|
|
|
unicode_group =
|
|
Fabricate(:group, name: "管理员", assignable_level: Group::ALIAS_LEVELS[:everyone])
|
|
unicode_group.add(user)
|
|
SiteSetting.assign_allowed_on_groups += "|#{unicode_group.id}"
|
|
|
|
stub_const(TopicQuery, "DEFAULT_PER_PAGE_COUNT", 1) do
|
|
get "/topics/group-topics-assigned/#{UrlHelper.encode_component(unicode_group.name)}.json"
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(response.parsed_body["topic_list"]["more_topics_url"]).to eq(
|
|
"/topics/group-topics-assigned/%E7%AE%A1%E7%90%86%E5%91%98?page=1",
|
|
)
|
|
end
|
|
end
|
|
|
|
it "doesn't return deleted topics" do
|
|
sign_in(admin)
|
|
|
|
Assigner.new(topic, user).assign(user)
|
|
|
|
delete "/t/#{topic.id}.json"
|
|
|
|
topic.reload
|
|
|
|
id = 0
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json"
|
|
|
|
JSON.parse(response.body)["topic_list"]["topics"].each do |t|
|
|
id = t.id if t["id"] == topic.id
|
|
end
|
|
|
|
expect(id).to eq(0)
|
|
end
|
|
end
|
|
|
|
describe "#sorting messages_assigned and group_topics_assigned" do
|
|
include_context "with group that is allowed to assign"
|
|
|
|
fab!(:post1, :post)
|
|
fab!(:post2, :post)
|
|
fab!(:post3, :post)
|
|
fab!(:topic1) { post1.topic }
|
|
fab!(:topic2) { post2.topic }
|
|
fab!(:topic3) { post3.topic }
|
|
|
|
before do
|
|
add_to_assign_allowed_group(user)
|
|
add_to_assign_allowed_group(user2)
|
|
|
|
Assigner.new(post1.topic, user).assign(user)
|
|
Assigner.new(post2.topic, user).assign(user2)
|
|
Assigner.new(post3.topic, user).assign(user)
|
|
|
|
sign_in(user)
|
|
end
|
|
|
|
it "group_topics_assigned returns sorted topicsList" do
|
|
topic1.bumped_at = Time.now
|
|
topic2.bumped_at = 1.day.ago
|
|
topic3.bumped_at = 3.days.ago
|
|
|
|
topic1.views = 3
|
|
topic2.views = 5
|
|
topic3.views = 1
|
|
|
|
topic1.posts_count = 3
|
|
topic2.posts_count = 1
|
|
topic3.posts_count = 5
|
|
|
|
topic1.save!
|
|
topic2.save!
|
|
topic3.save!
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json?order=posts"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic2.id, topic1.id, topic3.id],
|
|
)
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json?order=views"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic3.id, topic1.id, topic2.id],
|
|
)
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json?order=activity"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic3.id, topic2.id, topic1.id],
|
|
)
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json?order=posts&ascending=true"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic3.id, topic1.id, topic2.id],
|
|
)
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json?order=views&ascending=true"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic2.id, topic1.id, topic3.id],
|
|
)
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json?order=activity&ascending=true"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic1.id, topic2.id, topic3.id],
|
|
)
|
|
end
|
|
|
|
it "messages_assigned returns sorted topicsList" do
|
|
topic1.bumped_at = Time.now
|
|
topic3.bumped_at = 3.days.ago
|
|
|
|
topic1.views = 3
|
|
topic3.views = 1
|
|
|
|
topic1.posts_count = 3
|
|
topic3.posts_count = 5
|
|
|
|
topic1.reload
|
|
topic3.reload
|
|
|
|
get "/topics/messages-assigned/#{user.username}.json?order=posts"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic1.id, topic3.id],
|
|
)
|
|
|
|
get "/topics/messages-assigned/#{user.username}.json?order=views"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic3.id, topic1.id],
|
|
)
|
|
|
|
get "/topics/messages-assigned/#{user.username}.json?order=activity"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic3.id, topic1.id],
|
|
)
|
|
|
|
get "/topics/messages-assigned/#{user.username}.json?order=posts&ascending=true"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic3.id, topic1.id],
|
|
)
|
|
|
|
get "/topics/messages-assigned/#{user.username}.json?order=views&ascending=true"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic1.id, topic3.id],
|
|
)
|
|
|
|
get "/topics/messages-assigned/#{user.username}.json?order=activity&ascending=true"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic1.id, topic3.id],
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "filtering of topics as per parameter" do
|
|
include_context "with group that is allowed to assign"
|
|
|
|
fab!(:post1, :post)
|
|
fab!(:post2, :post)
|
|
fab!(:post3, :post)
|
|
fab!(:topic1) { post1.topic }
|
|
fab!(:topic2) { post2.topic }
|
|
fab!(:topic3) { post3.topic }
|
|
|
|
before do
|
|
SearchIndexer.enable
|
|
|
|
add_to_assign_allowed_group(user)
|
|
add_to_assign_allowed_group(user2)
|
|
|
|
Assigner.new(post1.topic, user).assign(user)
|
|
Assigner.new(post2.topic, user).assign(user2)
|
|
Assigner.new(post3.topic, user).assign(user)
|
|
|
|
sign_in(user)
|
|
end
|
|
|
|
after { SearchIndexer.disable }
|
|
|
|
it "returns topics as per filter for #group_topics_assigned" do
|
|
topic1.title = "QUnit testing is love"
|
|
topic2.title = "RSpec testing is too fun"
|
|
topic3.title = "Testing is main part of programming"
|
|
|
|
topic1.save!
|
|
topic2.save!
|
|
topic3.save!
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json",
|
|
params: {
|
|
search: "Testing",
|
|
}
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic1.id, topic2.id, topic3.id],
|
|
)
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json",
|
|
params: {
|
|
search: "RSpec",
|
|
}
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic2.id],
|
|
)
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json",
|
|
params: {
|
|
search: "love",
|
|
}
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic1.id],
|
|
)
|
|
end
|
|
|
|
it "returns topics as per filter for #group_topics_assigned" do
|
|
topic1.title = "QUnit testing is love"
|
|
topic2.title = "RSpec testing is too fun"
|
|
topic3.title = "Testing is main part of programming"
|
|
|
|
topic1.save!
|
|
topic2.save!
|
|
topic3.save!
|
|
|
|
get "/topics/messages-assigned/#{user.username}.json", params: { search: "Testing" }
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic1.id, topic3.id],
|
|
)
|
|
|
|
get "/topics/group-topics-assigned/#{get_assigned_allowed_group_name}.json",
|
|
params: {
|
|
search: "love",
|
|
}
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to match_array(
|
|
[topic1.id],
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "#messages_assigned" do
|
|
include_context "with group that is allowed to assign"
|
|
|
|
fab!(:post1, :post)
|
|
fab!(:post2, :post)
|
|
|
|
before do
|
|
add_to_assign_allowed_group(user)
|
|
|
|
Assigner.new(post1.topic, user).assign(user)
|
|
Assigner.new(post2.topic, user).assign(user2)
|
|
|
|
sign_in(user)
|
|
end
|
|
|
|
it "returns user-assigned-topics-list of given user" do
|
|
get "/topics/messages-assigned/#{user.username_lower}.json"
|
|
expect(
|
|
JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["assigned_to_user"]["id"] },
|
|
).to match_array([user.id])
|
|
end
|
|
|
|
it "returns empty user-assigned-topics-list for given user not in the assigned_allowed_group" do
|
|
get "/topics/messages-assigned/#{user2.username_lower}.json"
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"]).to be_empty
|
|
end
|
|
end
|
|
|
|
describe "#private_messages_assigned" do
|
|
fab!(:group) { Fabricate(:group, users: [user]) }
|
|
fab!(:pm) { Fabricate(:topic, archetype: Archetype.private_message, category_id: nil) }
|
|
fab!(:topic) { Fabricate(:topic, user: user) }
|
|
fab!(:pm_post) { Fabricate(:post, topic: pm) }
|
|
fab!(:post) { Fabricate(:post, topic: topic) }
|
|
|
|
before do
|
|
SiteSetting.assign_allowed_on_groups = "#{group.id}"
|
|
Fabricate(:topic_allowed_user, user: user, topic: pm)
|
|
Assigner.new(pm, user).assign(user)
|
|
Assigner.new(topic, user).assign(user)
|
|
end
|
|
|
|
it "returns assigned messages for user" do
|
|
sign_in(user)
|
|
|
|
get "/topics/private-messages-assigned/#{user.username_lower}.json"
|
|
|
|
expect(JSON.parse(response.body)["topic_list"]["topics"].map { |t| t["id"] }).to eq([pm.id])
|
|
end
|
|
end
|
|
|
|
describe "#filter" do
|
|
include_context "with group that is allowed to assign"
|
|
|
|
fab!(:group) { Fabricate(:group, assignable_level: Group::ALIAS_LEVELS[:mods_and_admins]) }
|
|
|
|
fab!(:topic_1, :topic)
|
|
fab!(:topic_2, :topic)
|
|
fab!(:topic_3, :topic)
|
|
|
|
fab!(:post_1) { Fabricate(:post, topic: topic_1) }
|
|
fab!(:post_2) { Fabricate(:post, topic: topic_2) }
|
|
fab!(:post_3) { Fabricate(:post, topic: topic_3) }
|
|
|
|
describe "when user cannot assign" do
|
|
it "ignores the assign filter" do
|
|
add_to_assign_allowed_group(user)
|
|
|
|
Assigner.new(topic_1, user).assign(user)
|
|
|
|
get "/filter", params: { q: "assigned:#{user.username_lower}", format: :json }
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(
|
|
response.parsed_body.dig("topic_list", "topics").map { it["id"] },
|
|
).to contain_exactly(topic_1.id, topic_2.id, topic_3.id)
|
|
end
|
|
end
|
|
|
|
describe "when user can assign" do
|
|
before { sign_in(admin) }
|
|
|
|
it "filters topics by assigned user" do
|
|
add_to_assign_allowed_group(user)
|
|
|
|
Assigner.new(topic_1, admin).assign(user)
|
|
|
|
get "/filter", params: { q: "assigned:#{user.username_lower}", format: :json }
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(
|
|
response.parsed_body.dig("topic_list", "topics").map { it["id"] },
|
|
).to contain_exactly(topic_1.id)
|
|
end
|
|
|
|
it "filters topics by assigned group" do
|
|
Assigner.new(topic_2, admin).assign(group)
|
|
|
|
get "/filter", params: { q: "assigned:#{group.name}", format: :json }
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(
|
|
response.parsed_body.dig("topic_list", "topics").map { it["id"] },
|
|
).to contain_exactly(topic_2.id)
|
|
end
|
|
|
|
it "filters topics by multiple assigned users and groups" do
|
|
add_to_assign_allowed_group(user)
|
|
user2 = Fabricate(:user)
|
|
add_to_assign_allowed_group(user2)
|
|
|
|
# Assign topics to different users and groups
|
|
Assigner.new(topic_1, admin).assign(user)
|
|
Assigner.new(topic_2, admin).assign(group)
|
|
Assigner.new(topic_3, admin).assign(user2)
|
|
|
|
# Test filtering by multiple users and groups (comma-separated)
|
|
get "/filter",
|
|
params: {
|
|
q: "assigned:#{user.username_lower},#{group.name},#{user2.username_lower}",
|
|
format: :json,
|
|
}
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(
|
|
response.parsed_body.dig("topic_list", "topics").map { it["id"] },
|
|
).to contain_exactly(topic_1.id, topic_2.id, topic_3.id)
|
|
end
|
|
|
|
it "filters topics by subset of multiple assigned users and groups" do
|
|
add_to_assign_allowed_group(user)
|
|
user2 = Fabricate(:user)
|
|
add_to_assign_allowed_group(user2)
|
|
|
|
# Assign topics to different users and groups
|
|
Assigner.new(topic_1, admin).assign(user)
|
|
Assigner.new(topic_2, admin).assign(group)
|
|
# topic_3 remains unassigned
|
|
|
|
# Test filtering by specific users only
|
|
get "/filter",
|
|
params: {
|
|
q: "assigned:#{user.username_lower},#{user2.username_lower}",
|
|
format: :json,
|
|
}
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(
|
|
response.parsed_body.dig("topic_list", "topics").map { it["id"] },
|
|
).to contain_exactly(topic_1.id)
|
|
end
|
|
|
|
it "filters topics by assigned:*" do
|
|
add_to_assign_allowed_group(user)
|
|
|
|
Assigner.new(topic_1, admin).assign(user)
|
|
Assigner.new(topic_2, admin).assign(group)
|
|
# topic_3 remains unassigned
|
|
|
|
get "/filter", params: { q: "assigned:*", format: :json }
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(
|
|
response.parsed_body.dig("topic_list", "topics").map { it["id"] },
|
|
).to contain_exactly(topic_1.id, topic_2.id)
|
|
end
|
|
|
|
it "filters topics by assigned:nobody" do
|
|
add_to_assign_allowed_group(user)
|
|
|
|
Assigner.new(topic_1, admin).assign(user)
|
|
Assigner.new(topic_2, admin).assign(group)
|
|
# topic_3 remains unassigned
|
|
|
|
get "/filter", params: { q: "assigned:nobody", format: :json }
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(
|
|
response.parsed_body.dig("topic_list", "topics").map { it["id"] },
|
|
).to contain_exactly(topic_3.id)
|
|
end
|
|
|
|
it "handles empty multi-value assigned filter gracefully" do
|
|
add_to_assign_allowed_group(user)
|
|
|
|
Assigner.new(topic_1, admin).assign(user)
|
|
|
|
# Test with empty values and spaces
|
|
get "/filter", params: { q: "assigned:, ,", format: :json }
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(
|
|
response.parsed_body.dig("topic_list", "topics").map { it["id"] },
|
|
).to contain_exactly(topic_1.id, topic_2.id, topic_3.id)
|
|
end
|
|
|
|
it "handles non-existent users and groups in multi-value filter" do
|
|
add_to_assign_allowed_group(user)
|
|
|
|
Assigner.new(topic_1, admin).assign(user)
|
|
|
|
# Test with mix of existing and non-existing users/groups
|
|
get "/filter",
|
|
params: {
|
|
q: "assigned:#{user.username_lower},nonexistent_user,nonexistent_group",
|
|
format: :json,
|
|
}
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(
|
|
response.parsed_body.dig("topic_list", "topics").map { it["id"] },
|
|
).to contain_exactly(topic_1.id)
|
|
end
|
|
end
|
|
|
|
describe "when user cannot assign" do
|
|
it "ignores the assigned:* filter" do
|
|
add_to_assign_allowed_group(admin)
|
|
|
|
Assigner.new(topic_1, admin).assign(admin)
|
|
|
|
get "/filter", params: { q: "assigned:*", format: :json }
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(
|
|
response.parsed_body.dig("topic_list", "topics").map { it["id"] },
|
|
).to contain_exactly(topic_1.id, topic_2.id, topic_3.id)
|
|
end
|
|
|
|
it "ignores the assigned:nobody filter" do
|
|
add_to_assign_allowed_group(admin)
|
|
|
|
Assigner.new(topic_1, admin).assign(admin)
|
|
|
|
get "/filter", params: { q: "assigned:nobody", format: :json }
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(
|
|
response.parsed_body.dig("topic_list", "topics").map { it["id"] },
|
|
).to contain_exactly(topic_1.id, topic_2.id, topic_3.id)
|
|
end
|
|
end
|
|
end
|
|
end
|