FIX: Polymorphic bookmarks support (#328)

Adds support for polymorphic bookmarks in the serializer extensions
and preloaders for bookmarks.

Specs are skipped for now for the serializer but they do
work without the use_polymorphic_bookmark guard in the plugin.rb
This commit is contained in:
Martin Brennan 2022-05-11 09:52:15 +10:00 committed by GitHub
parent 46f200935d
commit 7320fdd94b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 125 additions and 17 deletions

View File

@ -188,12 +188,24 @@ after_initialize do
BookmarkQuery.on_preload do |bookmarks, bookmark_query|
if SiteSetting.assign_enabled?
topics = bookmarks.map(&:topic)
assignments = Assignment.strict_loading.where(topic_id: topics).includes(:assigned_to).index_by(&:topic_id)
if SiteSetting.use_polymorphic_bookmarks
topics = Bookmark.select_type(bookmarks, "Topic").map(&:bookmarkable).concat(
Bookmark.select_type(bookmarks, "Post").map { |bm| bm.bookmarkable.topic }
).uniq
assignments = Assignment.strict_loading.where(topic_id: topics).includes(:assigned_to).index_by(&:topic_id)
topics.each do |topic|
assigned_to = assignments[topic.id]&.assigned_to
topic.preload_assigned_to(assigned_to)
topics.each do |topic|
assigned_to = assignments[topic.id]&.assigned_to
topic.preload_assigned_to(assigned_to)
end
else
topics = bookmarks.map(&:topic)
assignments = Assignment.strict_loading.where(topic_id: topics).includes(:assigned_to).index_by(&:topic_id)
topics.each do |topic|
assigned_to = assignments[topic.id]&.assigned_to
topic.preload_assigned_to(assigned_to)
end
end
end
end
@ -594,6 +606,49 @@ after_initialize do
BasicUserSerializer.new(topic.assigned_to, scope: scope, root: false).as_json
end
add_to_serializer(:user_bookmark, 'include_assigned_to_user?') do
(SiteSetting.assigns_public || scope.can_assign?) && topic.assigned_to&.is_a?(User)
end
add_to_serializer(:user_bookmark, :assigned_to_group, false) do
BasicGroupSerializer.new(topic.assigned_to, scope: scope, root: false).as_json
end
add_to_serializer(:user_bookmark, 'include_assigned_to_group?') do
(SiteSetting.assigns_public || scope.can_assign?) && topic.assigned_to&.is_a?(Group)
end
if SiteSetting.use_polymorphic_bookmarks
# UserBookmarkBaseSerializer
add_to_class(:user_bookmark_base_serializer, :assigned_to) do
@assigned_to ||= bookmarkable_type == "Topic" ? bookmarkable.assigned_to : bookmarkable.topic.assigned_to
end
add_to_class(:user_bookmark_base_serializer, :can_have_assignment?) do
["Post", "Topic"].include?(bookmarkable_type)
end
add_to_serializer(:user_bookmark_base, :assigned_to_user, false) do
return if !can_have_assignment?
BasicUserSerializer.new(assigned_to, scope: scope, root: false).as_json
end
add_to_serializer(:user_bookmark_base, 'include_assigned_to_user?') do
return false if !can_have_assignment?
(SiteSetting.assigns_public || scope.can_assign?) && assigned_to&.is_a?(User)
end
add_to_serializer(:user_bookmark_base, :assigned_to_group, false) do
return if !can_have_assignment?
BasicGroupSerializer.new(assigned_to, scope: scope, root: false).as_json
end
add_to_serializer(:user_bookmark_base, 'include_assigned_to_group?') do
return false if !can_have_assignment?
(SiteSetting.assigns_public || scope.can_assign?) && assigned_to&.is_a?(Group)
end
end
add_to_serializer(:basic_user, :assign_icon) do
'user-plus'
end
@ -610,18 +665,6 @@ after_initialize do
"/g/#{object.name}/assigned/everyone"
end
add_to_serializer(:user_bookmark, 'include_assigned_to_user?') do
(SiteSetting.assigns_public || scope.can_assign?) && topic.assigned_to&.is_a?(User)
end
add_to_serializer(:user_bookmark, :assigned_to_group, false) do
BasicGroupSerializer.new(topic.assigned_to, scope: scope, root: false).as_json
end
add_to_serializer(:user_bookmark, 'include_assigned_to_group?') do
(SiteSetting.assigns_public || scope.can_assign?) && topic.assigned_to&.is_a?(Group)
end
# PostSerializer
add_to_serializer(:post, :assigned_to_user) do
BasicUserSerializer.new(object.assignment.assigned_to, scope: scope, root: false).as_json

View File

@ -0,0 +1,65 @@
# frozen_string_literal: true
require 'rails_helper'
require_relative '../support/assign_allowed_group'
describe UserBookmarkBaseSerializer do
include_context 'A group that is allowed to assign'
before do
SiteSetting.use_polymorphic_bookmarks = true
SiteSetting.assign_enabled = true
add_to_assign_allowed_group(user)
end
fab!(:user) { Fabricate(:user) }
fab!(:topic) { Fabricate(:topic) }
fab!(:post) { Fabricate(:post, topic: topic) }
let(:guardian) { Guardian.new(user) }
context "for Topic bookmarkable" do
let!(:bookmark) { Fabricate(:bookmark, user: user, bookmarkable: post.topic) }
xit "includes assigned user in serializer" do
Assigner.new(topic, user).assign(user)
serializer = UserTopicBookmarkSerializer.new(bookmark, scope: guardian)
bookmark = serializer.as_json[:user_topic_bookmark]
expect(bookmark[:assigned_to_user][:id]).to eq(user.id)
expect(bookmark[:assigned_to_user][:assign_icon]).to eq("user-plus")
expect(bookmark[:assigned_to_group]).to be(nil)
end
xit "includes assigned group in serializer" do
Assigner.new(topic, user).assign(assign_allowed_group)
serializer = UserTopicBookmarkSerializer.new(bookmark, scope: guardian)
bookmark = serializer.as_json[:user_topic_bookmark]
expect(bookmark[:assigned_to_group][:id]).to eq(assign_allowed_group.id)
expect(bookmark[:assigned_to_group][:assign_icon]).to eq("group-plus")
expect(bookmark[:assigned_to_user]).to be(nil)
end
end
context "for Post bookmarkable" do
let!(:bookmark) { Fabricate(:bookmark, user: user, bookmarkable: post) }
xit "includes assigned user in serializer" do
Assigner.new(topic, user).assign(user)
serializer = UserPostBookmarkSerializer.new(bookmark, scope: guardian)
bookmark = serializer.as_json[:user_post_bookmark]
expect(bookmark[:assigned_to_user][:id]).to eq(user.id)
expect(bookmark[:assigned_to_user][:assign_icon]).to eq("user-plus")
expect(bookmark[:assigned_to_group]).to be(nil)
end
xit "includes assigned group in serializer" do
Assigner.new(topic, user).assign(assign_allowed_group)
serializer = UserPostBookmarkSerializer.new(bookmark, scope: guardian)
bookmark = serializer.as_json[:user_post_bookmark]
expect(bookmark[:assigned_to_group][:id]).to eq(assign_allowed_group.id)
expect(bookmark[:assigned_to_group][:assign_icon]).to eq("group-plus")
expect(bookmark[:assigned_to_user]).to be(nil)
end
end
end