mirror of
https://github.com/discourse/discourse.git
synced 2024-12-19 07:03:47 +08:00
FIX: Discard empty bundles for reviewables (#30121)
Followup c7e471d35a
It is currently possible to add a bundle (which is a collection
of actions used for a dropdown on the client) for a reviewable
via actions.add_bundle and then never add any actions to it.
This causes the client to explode, as seen in the referenced
commit, because of the way our store expects to resolve objects
referenced by ID that are passed down by the serializer, which
then causes Ember to have an unrecoverable render error.
Fixing this on the serializer level is not really possible because
of all the ActiveModel::Serializer magic that serializes
objects by ID reference when doing things like has_many.
`Reviewable#actions_for` is a better place to do this anyway,
because this is the main location where the bundles and actions
are built for every action via the serializer.
This commit is contained in:
parent
dd0b4e26a7
commit
8a89a77248
|
@ -270,8 +270,15 @@ class Reviewable < ActiveRecord::Base
|
||||||
|
|
||||||
def actions_for(guardian, args = nil)
|
def actions_for(guardian, args = nil)
|
||||||
args ||= {}
|
args ||= {}
|
||||||
|
built_actions =
|
||||||
Actions.new(self, guardian).tap { |actions| build_actions(actions, guardian, args) }
|
Actions.new(self, guardian).tap { |actions| build_actions(actions, guardian, args) }
|
||||||
|
|
||||||
|
# Empty bundles can cause big issues on the client side, so we remove them
|
||||||
|
# here. It's not valid anyway to have a bundle with no actions, but you can
|
||||||
|
# add a bundle via actions.add_bundle and then not add any actions to it.
|
||||||
|
built_actions.bundles.reject!(&:empty?)
|
||||||
|
|
||||||
|
built_actions
|
||||||
end
|
end
|
||||||
|
|
||||||
def editable_for(guardian, args = nil)
|
def editable_for(guardian, args = nil)
|
||||||
|
|
|
@ -30,6 +30,10 @@ class Reviewable < ActiveRecord::Base
|
||||||
@label = label
|
@label = label
|
||||||
@actions = []
|
@actions = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def empty?
|
||||||
|
@actions.empty?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Action < Item
|
class Action < Item
|
||||||
|
|
|
@ -621,6 +621,45 @@ RSpec.describe Reviewable, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#actions_for" do
|
||||||
|
fab!(:reviewable) { Fabricate(:reviewable_queued_post) }
|
||||||
|
fab!(:user)
|
||||||
|
|
||||||
|
it "gets the bundles and actions for a reviewable" do
|
||||||
|
actions = reviewable.actions_for(user.guardian)
|
||||||
|
expect(actions.bundles.map(&:id)).to eq(%w[approve_post reject_post revise_and_reject_post])
|
||||||
|
expect(actions.bundles.find { |b| b.id == "approve_post" }.actions.map(&:id)).to eq(
|
||||||
|
["approve_post"],
|
||||||
|
)
|
||||||
|
expect(actions.bundles.find { |b| b.id == "reject_post" }.actions.map(&:id)).to eq(
|
||||||
|
["reject_post"],
|
||||||
|
)
|
||||||
|
expect(actions.bundles.find { |b| b.id == "revise_and_reject_post" }.actions.map(&:id)).to eq(
|
||||||
|
["revise_and_reject_post"],
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "handling empty bundles" do
|
||||||
|
class ReviewableTestRecord < Reviewable
|
||||||
|
def build_actions(actions, guardian, args)
|
||||||
|
actions.add(:approve_post) do |action|
|
||||||
|
action.icon = "check"
|
||||||
|
action.label = "reviewables.actions.approve_post.title"
|
||||||
|
end
|
||||||
|
actions.add_bundle("empty_bundle", icon: "xmark", label: "Empty Bundle")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "does not return empty bundles with no actions" do
|
||||||
|
actions = ReviewableTestRecord.new.actions_for(user.guardian)
|
||||||
|
expect(actions.bundles.map(&:id)).to eq(%w[approve_post])
|
||||||
|
expect(actions.bundles.find { |b| b.id == "approve_post" }.actions.map(&:id)).to eq(
|
||||||
|
["approve_post"],
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "default actions" do
|
describe "default actions" do
|
||||||
let(:reviewable) { Reviewable.new }
|
let(:reviewable) { Reviewable.new }
|
||||||
let(:actions) { Reviewable::Actions.new(reviewable, Guardian.new) }
|
let(:actions) { Reviewable::Actions.new(reviewable, Guardian.new) }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user