/posts/:id/events: list is_resolved correctly for appeals.

/posts/:id/events incorrectly lists appeals as always being resolved.
This is because events UNION together appeals and flags, which doesn't
quite work because for appeals is_resolved is a method, not an
attribute. is_resolved was hardcoded to true so it'd work in the UNION.

This changes PostEvent to be a wrapper object around PostFlag /
PostAppeal, instead of a UNION. PostEvent delegates everything to the
inner flag/appeals object, so that is_resolved works correctly.

Also, this incidentally fixes a problem with /posts/:id/event.xml not
serializing correctly.
This commit is contained in:
evazion
2017-03-19 20:45:51 -05:00
parent d22d655d43
commit 5ba1df5502
2 changed files with 47 additions and 38 deletions

View File

@@ -1,44 +1,36 @@
class PostEvent
class Instance
attr_reader :creator_id, :reason, :is_resolved, :created_at, :type
include ActiveModel::Model
include ActiveModel::Serializers::JSON
include ActiveModel::Serializers::Xml
def initialize(row)
@creator_id = row["creator_id"].to_i
@reason = row["reason"]
@is_resolved = (row["is_resolved"] == "t")
@created_at = row["created_at"].to_time
@type = row["type"]
end
def creator
User.find(creator_id)
end
def type_name
if appeal?
"appeal"
else
"flag"
end
end
def appeal?
type == "a"
end
def flag?
type == "f"
end
end
QUERY = <<-EOS
(SELECT post_flags.creator_id, post_flags.reason, post_flags.is_resolved, post_flags.created_at, 'f' as type FROM post_flags WHERE post_flags.post_id = ?)
UNION
(SELECT post_appeals.creator_id, post_appeals.reason, 't' AS is_resolved, post_appeals.created_at, 'a' as type FROM post_appeals WHERE post_appeals.post_id = ?)
ORDER BY created_at
EOS
attr_accessor :event
delegate :creator_id, :reason, :is_resolved, :created_at, to: :event
def self.find_for_post(post_id)
ActiveRecord::Base.select_all_sql(QUERY, post_id, post_id).map {|x| Instance.new(x)}
post = Post.find(post_id)
(post.appeals + post.flags).sort_by(&:created_at).reverse.map { |e| new(event: e) }
end
def type_name
case event
when PostFlag
"flag"
when PostAppeal
"appeal"
end
end
def type
type_name.first
end
def attributes
{
"creator_id": nil,
"created_at": nil,
"reason": nil,
"is_resolved": nil,
"type": nil,
}
end
end

View File

@@ -26,4 +26,21 @@ class PostEventsControllerTest < ActionController::TestCase
assert_response :ok
end
end
context "GET /posts/:post_id/events.xml" do
setup do
get :index, {:post_id => @post.id, :format => :xml}, {:user_id => CurrentUser.user.id}
@xml = Hash.from_xml(response.body)
@appeal = @xml["post_events"].find { |e| e["type"] == "a" }
end
should "render" do
assert_not_nil(@appeal)
end
should "return is_resolved correctly" do
assert_equal(false, @appeal["is_resolved"])
end
end
end