0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-11 02:59:07 +08:00
discourse/plugins/discourse-assign/spec/requests/users_controller_spec.rb
Alan Guo Xiang Tan 7ce1992ec1
FIX: Serialize only a bookmark target's active assignment (#41397)
This PR makes a bookmark's "Assigned to …" badge reflect only the
current, active assignment of the exact item that was bookmarked.

In discourse-assign, a topic or an individual post can be assigned to a
user or group, and bookmark lists show a badge for it. Previously,
`BookmarkQuery.on_preload` loaded every assignment belonging to a
bookmarked topic — without filtering on `active`, and keyed by
`topic_id` regardless of `target_type`. Bookmarks kept showing "Assigned
to …" after an assignment was deactivated (for example by
`unassign_on_close`), and when a topic carried both a direct assignment
and post-level assignments, whichever row loaded last won, so a bookmark
could show an assignee that was never assigned the bookmarked item at
all. Post bookmarks had a second problem: the
`UserBookmarkBaseSerializer` extension read the topic's assignment for
them, so a bookmark on an assigned post never showed that post's own
assignee.
2026-07-06 06:34:22 +08:00

167 lines
5.8 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe UsersController do
fab!(:admin)
fab!(:assignee) { Fabricate(:user, username: "assigneduser") }
before do
SiteSetting.assign_enabled = true
SiteSetting.assign_allowed_on_groups = Group::AUTO_GROUPS[:staff].to_s
sign_in(admin)
end
describe "#bookmarks" do
fab!(:topic) { Fabricate(:read_topic, current_user: admin) }
context "when a bookmarked topic has an active assignment" do
fab!(:bookmark) { Fabricate(:bookmark, user: admin, bookmarkable: topic) }
fab!(:assignment) { Fabricate(:topic_assignment, topic: topic, assigned_to: assignee) }
it "includes the user assigned to the topic" do
get "/u/#{admin.username}/bookmarks.json"
expect(response.status).to eq(200)
expect(
response.parsed_body.dig("user_bookmark_list", "bookmarks", 0, "assigned_to_user", "id"),
).to eq(assignee.id)
end
end
context "when a bookmarked topic's assignment is inactive" do
fab!(:bookmark) { Fabricate(:bookmark, user: admin, bookmarkable: topic) }
fab!(:assignment) do
Fabricate(:topic_assignment, topic: topic, assigned_to: assignee, active: false)
end
it "does not include an assigned user" do
get "/u/#{admin.username}/bookmarks.json"
expect(response.status).to eq(200)
expect(response.parsed_body.dig("user_bookmark_list", "bookmarks", 0)).not_to have_key(
"assigned_to_user",
)
end
end
context "when only a post in the bookmarked topic is assigned" do
fab!(:bookmark) { Fabricate(:bookmark, user: admin, bookmarkable: topic) }
fab!(:assignment) do
Fabricate(:post_assignment, post: topic.first_post, assigned_to: assignee)
end
it "does not include an assigned user" do
get "/u/#{admin.username}/bookmarks.json"
expect(response.status).to eq(200)
expect(response.parsed_body.dig("user_bookmark_list", "bookmarks", 0)).not_to have_key(
"assigned_to_user",
)
end
end
context "when a bookmarked post has an active assignment" do
fab!(:bookmark) { Fabricate(:bookmark, user: admin, bookmarkable: topic.first_post) }
fab!(:assignment) do
Fabricate(:post_assignment, post: topic.first_post, assigned_to: assignee)
end
it "includes the user assigned to the post" do
get "/u/#{admin.username}/bookmarks.json"
expect(response.status).to eq(200)
expect(
response.parsed_body.dig("user_bookmark_list", "bookmarks", 0, "assigned_to_user", "id"),
).to eq(assignee.id)
end
end
context "when a bookmarked post's assignment is inactive" do
fab!(:bookmark) { Fabricate(:bookmark, user: admin, bookmarkable: topic.first_post) }
fab!(:assignment) do
Fabricate(:post_assignment, post: topic.first_post, assigned_to: assignee, active: false)
end
it "does not include an assigned user" do
get "/u/#{admin.username}/bookmarks.json"
expect(response.status).to eq(200)
expect(response.parsed_body.dig("user_bookmark_list", "bookmarks", 0)).not_to have_key(
"assigned_to_user",
)
end
end
context "when only the topic of a bookmarked post is assigned" do
fab!(:bookmark) { Fabricate(:bookmark, user: admin, bookmarkable: topic.first_post) }
fab!(:assignment) { Fabricate(:topic_assignment, topic: topic, assigned_to: assignee) }
it "does not include an assigned user" do
get "/u/#{admin.username}/bookmarks.json"
expect(response.status).to eq(200)
expect(response.parsed_body.dig("user_bookmark_list", "bookmarks", 0)).not_to have_key(
"assigned_to_user",
)
end
end
context "when a different post in the bookmarked post's topic is assigned" do
fab!(:other_post) { Fabricate(:post, topic: topic) }
fab!(:bookmark) { Fabricate(:bookmark, user: admin, bookmarkable: topic.first_post) }
fab!(:assignment) { Fabricate(:post_assignment, post: other_post, assigned_to: assignee) }
it "does not include an assigned user" do
get "/u/#{admin.username}/bookmarks.json"
expect(response.status).to eq(200)
expect(response.parsed_body.dig("user_bookmark_list", "bookmarks", 0)).not_to have_key(
"assigned_to_user",
)
end
end
context "when a bookmarked post and its topic are both assigned" do
fab!(:topic_assignee) { Fabricate(:user, username: "topicassignee") }
fab!(:bookmark) { Fabricate(:bookmark, user: admin, bookmarkable: topic.first_post) }
fab!(:topic_assignment) do
Fabricate(:topic_assignment, topic: topic, assigned_to: topic_assignee)
end
fab!(:post_assignment) do
Fabricate(:post_assignment, post: topic.first_post, assigned_to: assignee)
end
it "includes the user assigned to the post" do
get "/u/#{admin.username}/bookmarks.json"
expect(response.status).to eq(200)
expect(
response.parsed_body.dig("user_bookmark_list", "bookmarks", 0, "assigned_to_user", "id"),
).to eq(assignee.id)
end
end
end
describe "#user_menu_bookmarks" do
context "when a bookmarked topic's assignment is inactive" do
fab!(:topic) { Fabricate(:read_topic, current_user: admin) }
fab!(:bookmark) { Fabricate(:bookmark, user: admin, bookmarkable: topic) }
fab!(:assignment) do
Fabricate(:topic_assignment, topic: topic, assigned_to: assignee, active: false)
end
it "does not include an assigned user" do
get "/u/#{admin.username}/user-menu-bookmarks"
expect(response.status).to eq(200)
expect(response.parsed_body.dig("bookmarks", 0)).not_to have_key("assigned_to_user")
end
end
end
end