FEATURE: Show votes in an "on voted" poll to the creator
This required properly plumbing the guardian into the serializer. Notably, the default state in the client was not changed - if you haven't voted in the poll, you need to click the button to view the results instead of the results being immediately visible on page load. Implements https://meta.discourse.org/t/-/138108
This commit is contained in:
parent
0d3386d255
commit
330102fd20
|
@ -47,7 +47,11 @@ class Poll < ActiveRecord::Base
|
||||||
|
|
||||||
def can_see_results?(user)
|
def can_see_results?(user)
|
||||||
return !!user&.staff? if staff_only?
|
return !!user&.staff? if staff_only?
|
||||||
!!(always? || (on_vote? && has_voted?(user)) || is_closed?)
|
!!(always? || (on_vote? && (is_me?(user) || has_voted?(user))) || is_closed?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def is_me?(user)
|
||||||
|
user && post.user&.id == user&.id
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_voted?(user)
|
def has_voted?(user)
|
||||||
|
|
|
@ -61,7 +61,7 @@ class PollSerializer < ApplicationSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_preloaded_voters?
|
def include_preloaded_voters?
|
||||||
object.can_see_voters?(scope)
|
object.can_see_voters?(scope.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -678,6 +678,7 @@ createWidget("discourse-poll-buttons", {
|
||||||
const staffOnly = poll.results === "staff_only";
|
const staffOnly = poll.results === "staff_only";
|
||||||
const isStaff = this.currentUser && this.currentUser.staff;
|
const isStaff = this.currentUser && this.currentUser.staff;
|
||||||
const isAdmin = this.currentUser && this.currentUser.admin;
|
const isAdmin = this.currentUser && this.currentUser.admin;
|
||||||
|
const isMe = this.currentUser && post.user_id === this.currentUser.id;
|
||||||
const dataExplorerEnabled = this.siteSettings.data_explorer_enabled;
|
const dataExplorerEnabled = this.siteSettings.data_explorer_enabled;
|
||||||
const hideResultsDisabled = !staffOnly && (closed || topicArchived);
|
const hideResultsDisabled = !staffOnly && (closed || topicArchived);
|
||||||
const exportQueryID = this.siteSettings.poll_export_data_explorer_query_id;
|
const exportQueryID = this.siteSettings.poll_export_data_explorer_query_id;
|
||||||
|
@ -710,7 +711,7 @@ createWidget("discourse-poll-buttons", {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
if (poll.get("results") === "on_vote" && !attrs.hasVoted) {
|
if (poll.get("results") === "on_vote" && !attrs.hasVoted && !isMe) {
|
||||||
contents.push(infoTextHtml(I18n.t("poll.results.vote.title")));
|
contents.push(infoTextHtml(I18n.t("poll.results.vote.title")));
|
||||||
} else if (poll.get("results") === "on_close" && !closed) {
|
} else if (poll.get("results") === "on_close" && !closed) {
|
||||||
contents.push(infoTextHtml(I18n.t("poll.results.closed.title")));
|
contents.push(infoTextHtml(I18n.t("poll.results.closed.title")));
|
||||||
|
|
|
@ -93,7 +93,7 @@ module DiscoursePoll
|
||||||
|
|
||||||
if has_changed
|
if has_changed
|
||||||
polls = ::Poll.includes(poll_options: :poll_votes).where(post: post)
|
polls = ::Poll.includes(poll_options: :poll_votes).where(post: post)
|
||||||
polls = ActiveModel::ArraySerializer.new(polls, each_serializer: PollSerializer, root: false).as_json
|
polls = ActiveModel::ArraySerializer.new(polls, each_serializer: PollSerializer, root: false, scope: Guardian.new(nil)).as_json
|
||||||
post.publish_message!("/polls/#{post.topic_id}", post_id: post.id, polls: polls)
|
post.publish_message!("/polls/#{post.topic_id}", post_id: post.id, polls: polls)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -62,7 +62,8 @@ after_initialize do
|
||||||
end
|
end
|
||||||
|
|
||||||
# user must be allowed to post in topic
|
# user must be allowed to post in topic
|
||||||
if !Guardian.new(user).can_create_post?(post.topic)
|
guardian = Guardian.new(user)
|
||||||
|
if !guardian.can_create_post?(post.topic)
|
||||||
raise StandardError.new I18n.t("poll.user_cant_post_in_topic")
|
raise StandardError.new I18n.t("poll.user_cant_post_in_topic")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -108,7 +109,7 @@ after_initialize do
|
||||||
|
|
||||||
poll.reload
|
poll.reload
|
||||||
|
|
||||||
serialized_poll = PollSerializer.new(poll, root: false).as_json
|
serialized_poll = PollSerializer.new(poll, root: false, scope: guardian).as_json
|
||||||
payload = { post_id: post_id, polls: [serialized_poll] }
|
payload = { post_id: post_id, polls: [serialized_poll] }
|
||||||
|
|
||||||
post.publish_message!("/polls/#{post.topic_id}", payload)
|
post.publish_message!("/polls/#{post.topic_id}", payload)
|
||||||
|
@ -120,6 +121,7 @@ after_initialize do
|
||||||
def toggle_status(post_id, poll_name, status, user, raise_errors = true)
|
def toggle_status(post_id, poll_name, status, user, raise_errors = true)
|
||||||
Poll.transaction do
|
Poll.transaction do
|
||||||
post = Post.find_by(id: post_id)
|
post = Post.find_by(id: post_id)
|
||||||
|
guardian = Guardian.new(user)
|
||||||
|
|
||||||
# post must not be deleted
|
# post must not be deleted
|
||||||
if post.nil? || post.trashed?
|
if post.nil? || post.trashed?
|
||||||
|
@ -149,7 +151,7 @@ after_initialize do
|
||||||
poll.status = status
|
poll.status = status
|
||||||
poll.save!
|
poll.save!
|
||||||
|
|
||||||
serialized_poll = PollSerializer.new(poll, root: false).as_json
|
serialized_poll = PollSerializer.new(poll, root: false, scope: guardian).as_json
|
||||||
payload = { post_id: post_id, polls: [serialized_poll] }
|
payload = { post_id: post_id, polls: [serialized_poll] }
|
||||||
|
|
||||||
post.publish_message!("/polls/#{post.topic_id}", payload)
|
post.publish_message!("/polls/#{post.topic_id}", payload)
|
||||||
|
@ -542,11 +544,12 @@ after_initialize do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
on(:post_created) do |post|
|
on(:post_created) do |post, _opts, user|
|
||||||
|
guardian = Guardian.new(user)
|
||||||
DiscoursePoll::Poll.schedule_jobs(post)
|
DiscoursePoll::Poll.schedule_jobs(post)
|
||||||
|
|
||||||
unless post.is_first_post?
|
unless post.is_first_post?
|
||||||
polls = ActiveModel::ArraySerializer.new(post.polls, each_serializer: PollSerializer, root: false).as_json
|
polls = ActiveModel::ArraySerializer.new(post.polls, each_serializer: PollSerializer, root: false, scope: guardian).as_json
|
||||||
post.publish_message!("/polls/#{post.topic_id}", post_id: post.id, polls: polls)
|
post.publish_message!("/polls/#{post.topic_id}", post_id: post.id, polls: polls)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -594,7 +597,7 @@ after_initialize do
|
||||||
end
|
end
|
||||||
|
|
||||||
add_to_serializer(:post, :polls, false) do
|
add_to_serializer(:post, :polls, false) do
|
||||||
preloaded_polls.map { |p| PollSerializer.new(p, root: false) }
|
preloaded_polls.map { |p| PollSerializer.new(p, root: false, scope: self.scope) }
|
||||||
end
|
end
|
||||||
|
|
||||||
add_to_serializer(:post, :include_polls?) do
|
add_to_serializer(:post, :include_polls?) do
|
||||||
|
|
|
@ -31,10 +31,21 @@ describe ::DiscoursePoll::Poll do
|
||||||
option = poll.poll_options.first
|
option = poll.poll_options.first
|
||||||
|
|
||||||
expect(poll.can_see_results?(user)).to eq(false)
|
expect(poll.can_see_results?(user)).to eq(false)
|
||||||
poll.poll_votes.create!(poll_option_id: option.id , user_id: user.id)
|
poll.poll_votes.create!(poll_option_id: option.id, user_id: user.id)
|
||||||
expect(poll.can_see_results?(user)).to eq(true)
|
expect(poll.can_see_results?(user)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "author can see results when results setting is on_vote" do
|
||||||
|
author = Fabricate(:user)
|
||||||
|
post = Fabricate(:post, user: author, raw: "[poll results=on_vote]\n- A\n- B\n[/poll]")
|
||||||
|
poll = post.polls.first
|
||||||
|
option = poll.poll_options.first
|
||||||
|
|
||||||
|
expect(poll.can_see_results?(author)).to eq(true)
|
||||||
|
poll.poll_votes.create!(poll_option_id: option.id, user_id: author.id)
|
||||||
|
expect(poll.can_see_results?(author)).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
it "everyone can see results when results setting is on_vote and poll is closed" do
|
it "everyone can see results when results setting is on_vote and poll is closed" do
|
||||||
post = Fabricate(:post, raw: "[poll results=on_vote]\n- A\n- B\n[/poll]")
|
post = Fabricate(:post, raw: "[poll results=on_vote]\n- A\n- B\n[/poll]")
|
||||||
user = Fabricate(:user)
|
user = Fabricate(:user)
|
||||||
|
|
Loading…
Reference in New Issue