mirror of
https://github.com/discourse/discourse.git
synced 2024-12-30 09:06:28 +08:00
499 lines
14 KiB
Ruby
499 lines
14 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe ::DiscoursePoll::PollsController do
|
|
routes { ::DiscoursePoll::Engine.routes }
|
|
|
|
let!(:user) { log_in }
|
|
let(:topic) { Fabricate(:topic) }
|
|
let(:poll) { Fabricate(:post, topic: topic, user: user, raw: "[poll]\n- A\n- B\n[/poll]") }
|
|
let(:multi_poll) do
|
|
Fabricate(
|
|
:post,
|
|
topic: topic,
|
|
user: user,
|
|
raw: "[poll min=1 max=2 type=multiple public=true]\n- A\n- B\n[/poll]",
|
|
)
|
|
end
|
|
let(:public_poll_on_vote) do
|
|
Fabricate(
|
|
:post,
|
|
topic: topic,
|
|
user: user,
|
|
raw: "[poll public=true results=on_vote]\n- A\n- B\n[/poll]",
|
|
)
|
|
end
|
|
let(:public_poll_on_close) do
|
|
Fabricate(
|
|
:post,
|
|
topic: topic,
|
|
user: user,
|
|
raw: "[poll public=true results=on_close]\n- A\n- B\n[/poll]",
|
|
)
|
|
end
|
|
|
|
before { Group.refresh_automatic_groups! }
|
|
|
|
describe "#vote" do
|
|
it "works" do
|
|
channel = "/polls/#{poll.topic_id}"
|
|
|
|
message =
|
|
MessageBus
|
|
.track_publish(channel) do
|
|
put :vote,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
options: ["5c24fc1df56d764b550ceae1b9319125"],
|
|
},
|
|
format: :json
|
|
end
|
|
.first
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
json = response.parsed_body
|
|
expect(json["poll"]["name"]).to eq("poll")
|
|
expect(json["poll"]["voters"]).to eq(1)
|
|
expect(json["vote"]).to eq(["5c24fc1df56d764b550ceae1b9319125"])
|
|
|
|
expect(message.channel).to eq(channel)
|
|
expect(message.user_ids).to eq(nil)
|
|
expect(message.group_ids).to eq(nil)
|
|
end
|
|
|
|
it "works in PM" do
|
|
user2 = Fabricate(:user)
|
|
topic =
|
|
Fabricate(
|
|
:private_message_topic,
|
|
topic_allowed_users: [
|
|
Fabricate.build(:topic_allowed_user, user: user),
|
|
Fabricate.build(:topic_allowed_user, user: user2),
|
|
],
|
|
)
|
|
poll = Fabricate(:post, topic: topic, user: user, raw: "[poll]\n- A\n- B\n[/poll]")
|
|
|
|
channel = "/polls/#{poll.topic_id}"
|
|
|
|
message =
|
|
MessageBus
|
|
.track_publish(channel) do
|
|
put :vote,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
options: ["5c24fc1df56d764b550ceae1b9319125"],
|
|
},
|
|
format: :json
|
|
end
|
|
.first
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
json = response.parsed_body
|
|
expect(json["poll"]["name"]).to eq("poll")
|
|
expect(json["poll"]["voters"]).to eq(1)
|
|
expect(json["vote"]).to eq(["5c24fc1df56d764b550ceae1b9319125"])
|
|
|
|
expect(message.channel).to eq(channel)
|
|
expect(message.user_ids).to contain_exactly(user.id, user2.id)
|
|
expect(message.group_ids).to eq(nil)
|
|
end
|
|
|
|
it "works in secure categories" do
|
|
group = Fabricate(:group)
|
|
group.add_owner(user)
|
|
category = Fabricate(:private_category, group: group)
|
|
topic = Fabricate(:topic, category: category)
|
|
poll = Fabricate(:post, topic: topic, user: user, raw: "[poll]\n- A\n- B\n[/poll]")
|
|
|
|
channel = "/polls/#{poll.topic_id}"
|
|
|
|
message =
|
|
MessageBus
|
|
.track_publish(channel) do
|
|
put :vote,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
options: ["5c24fc1df56d764b550ceae1b9319125"],
|
|
},
|
|
format: :json
|
|
end
|
|
.first
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
json = response.parsed_body
|
|
expect(json["poll"]["name"]).to eq("poll")
|
|
expect(json["poll"]["voters"]).to eq(1)
|
|
expect(json["vote"]).to eq(["5c24fc1df56d764b550ceae1b9319125"])
|
|
|
|
expect(message.channel).to eq(channel)
|
|
expect(message.user_ids).to eq(nil)
|
|
expect(message.group_ids).to contain_exactly(group.id)
|
|
end
|
|
|
|
it "requires at least 1 valid option" do
|
|
put :vote, params: { post_id: poll.id, poll_name: "poll", options: %w[A B] }, format: :json
|
|
|
|
expect(response.status).not_to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["errors"][0]).to eq(I18n.t("poll.requires_at_least_1_valid_option"))
|
|
end
|
|
|
|
it "supports vote changes" do
|
|
put :vote,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
options: ["5c24fc1df56d764b550ceae1b9319125"],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
put :vote,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
options: ["e89dec30bbd9bf50fabf6a05b4324edf"],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["poll"]["voters"]).to eq(1)
|
|
expect(json["poll"]["options"][0]["votes"]).to eq(0)
|
|
expect(json["poll"]["options"][1]["votes"]).to eq(1)
|
|
end
|
|
|
|
it "supports removing votes" do
|
|
put :vote,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
options: ["5c24fc1df56d764b550ceae1b9319125"],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
delete :remove_vote, params: { post_id: poll.id, poll_name: "poll" }, format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["poll"]["voters"]).to eq(0)
|
|
expect(json["poll"]["options"][0]["votes"]).to eq(0)
|
|
expect(json["poll"]["options"][1]["votes"]).to eq(0)
|
|
end
|
|
|
|
it "works on closed topics" do
|
|
topic.update_attribute(:closed, true)
|
|
|
|
put :vote,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
options: ["5c24fc1df56d764b550ceae1b9319125"],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
end
|
|
|
|
it "ensures topic is not archived" do
|
|
topic.update_attribute(:archived, true)
|
|
|
|
put :vote, params: { post_id: poll.id, poll_name: "poll", options: ["A"] }, format: :json
|
|
|
|
expect(response.status).not_to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["errors"][0]).to eq(I18n.t("poll.topic_must_be_open_to_vote"))
|
|
end
|
|
|
|
it "ensures post is not trashed" do
|
|
poll.trash!
|
|
|
|
put :vote, params: { post_id: poll.id, poll_name: "poll", options: ["A"] }, format: :json
|
|
|
|
expect(response.status).not_to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["errors"][0]).to eq(I18n.t("poll.post_is_deleted"))
|
|
end
|
|
|
|
it "ensures user can post in topic" do
|
|
Guardian.any_instance.expects(:can_create_post?).returns(false)
|
|
|
|
put :vote, params: { post_id: poll.id, poll_name: "poll", options: ["A"] }, format: :json
|
|
|
|
expect(response.status).not_to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["errors"][0]).to eq(I18n.t("poll.user_cant_post_in_topic"))
|
|
end
|
|
|
|
it "checks the name of the poll" do
|
|
put :vote, params: { post_id: poll.id, poll_name: "foobar", options: ["A"] }, format: :json
|
|
|
|
expect(response.status).not_to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["errors"][0]).to eq(I18n.t("poll.no_poll_with_this_name", name: "foobar"))
|
|
end
|
|
|
|
it "ensures poll is open" do
|
|
closed_poll = create_post(raw: "[poll status=closed]\n- A\n- B\n[/poll]")
|
|
|
|
put :vote,
|
|
params: {
|
|
post_id: closed_poll.id,
|
|
poll_name: "poll",
|
|
options: ["5c24fc1df56d764b550ceae1b9319125"],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).not_to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["errors"][0]).to eq(I18n.t("poll.poll_must_be_open_to_vote"))
|
|
end
|
|
|
|
it "ensures user has required trust level" do
|
|
poll = create_post(raw: "[poll groups=#{Fabricate(:group).name}]\n- A\n- B\n[/poll]")
|
|
|
|
put :vote,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
options: ["5c24fc1df56d764b550ceae1b9319125"],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).not_to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["errors"][0]).to eq(
|
|
I18n.t("js.poll.results.groups.title", groups: poll.polls.first.groups),
|
|
)
|
|
end
|
|
|
|
it "doesn't discard anonymous votes when someone votes" do
|
|
the_poll = poll.polls.first
|
|
the_poll.update_attribute(:anonymous_voters, 17)
|
|
the_poll.poll_options[0].update_attribute(:anonymous_votes, 11)
|
|
the_poll.poll_options[1].update_attribute(:anonymous_votes, 6)
|
|
|
|
put :vote,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
options: ["5c24fc1df56d764b550ceae1b9319125"],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
json = response.parsed_body
|
|
expect(json["poll"]["voters"]).to eq(18)
|
|
expect(json["poll"]["options"][0]["votes"]).to eq(12)
|
|
expect(json["poll"]["options"][1]["votes"]).to eq(6)
|
|
end
|
|
end
|
|
|
|
describe "#toggle_status" do
|
|
it "works for OP" do
|
|
channel = "/polls/#{poll.topic_id}"
|
|
|
|
message =
|
|
MessageBus
|
|
.track_publish(channel) do
|
|
put :toggle_status,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
status: "closed",
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
end
|
|
.first
|
|
|
|
json = response.parsed_body
|
|
expect(json["poll"]["status"]).to eq("closed")
|
|
expect(message.channel).to eq(channel)
|
|
end
|
|
|
|
it "works for staff" do
|
|
log_in(:moderator)
|
|
|
|
channel = "/polls/#{poll.topic_id}"
|
|
|
|
message =
|
|
MessageBus
|
|
.track_publish(channel) do
|
|
put :toggle_status,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
status: "closed",
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
end
|
|
.first
|
|
|
|
json = response.parsed_body
|
|
expect(json["poll"]["status"]).to eq("closed")
|
|
expect(message.channel).to eq(channel)
|
|
end
|
|
|
|
it "ensures post is not trashed" do
|
|
poll.trash!
|
|
|
|
put :toggle_status,
|
|
params: {
|
|
post_id: poll.id,
|
|
poll_name: "poll",
|
|
status: "closed",
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).not_to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["errors"][0]).to eq(I18n.t("poll.post_is_deleted"))
|
|
end
|
|
end
|
|
|
|
describe "#voters" do
|
|
let(:first) { "5c24fc1df56d764b550ceae1b9319125" }
|
|
let(:second) { "e89dec30bbd9bf50fabf6a05b4324edf" }
|
|
|
|
it "correctly handles offset" do
|
|
user1 = log_in
|
|
|
|
put :vote,
|
|
params: {
|
|
post_id: multi_poll.id,
|
|
poll_name: "poll",
|
|
options: [first],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
user2 = log_in
|
|
|
|
put :vote,
|
|
params: {
|
|
post_id: multi_poll.id,
|
|
poll_name: "poll",
|
|
options: [first],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
user3 = log_in
|
|
|
|
put :vote,
|
|
params: {
|
|
post_id: multi_poll.id,
|
|
poll_name: "poll",
|
|
options: [first, second],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
get :voters, params: { poll_name: "poll", post_id: multi_poll.id, limit: 2 }, format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
json = response.parsed_body
|
|
|
|
# no user3 cause voter_limit is 2
|
|
expect(json["voters"][first].map { |h| h["id"] }).to contain_exactly(user1.id, user2.id)
|
|
expect(json["voters"][second].map { |h| h["id"] }).to contain_exactly(user3.id)
|
|
end
|
|
|
|
it "ensures voters can only be seen after casting a vote" do
|
|
put :vote,
|
|
params: {
|
|
post_id: public_poll_on_vote.id,
|
|
poll_name: "poll",
|
|
options: [first],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
get :voters, params: { poll_name: "poll", post_id: public_poll_on_vote.id }, format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
json = response.parsed_body
|
|
|
|
expect(json["voters"][first].size).to eq(1)
|
|
|
|
_user2 = log_in
|
|
|
|
get :voters, params: { poll_name: "poll", post_id: public_poll_on_vote.id }, format: :json
|
|
|
|
expect(response.status).to eq(400)
|
|
|
|
put :vote,
|
|
params: {
|
|
post_id: public_poll_on_vote.id,
|
|
poll_name: "poll",
|
|
options: [second],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
get :voters, params: { poll_name: "poll", post_id: public_poll_on_vote.id }, format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
json = response.parsed_body
|
|
|
|
expect(json["voters"][first].size).to eq(1)
|
|
expect(json["voters"][second].size).to eq(1)
|
|
end
|
|
|
|
it "ensures voters can only be seen when poll is closed" do
|
|
put :vote,
|
|
params: {
|
|
post_id: public_poll_on_close.id,
|
|
poll_name: "poll",
|
|
options: [first],
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
get :voters, params: { poll_name: "poll", post_id: public_poll_on_close.id }, format: :json
|
|
|
|
expect(response.status).to eq(400)
|
|
|
|
put :toggle_status,
|
|
params: {
|
|
post_id: public_poll_on_close.id,
|
|
poll_name: "poll",
|
|
status: "closed",
|
|
},
|
|
format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
get :voters, params: { poll_name: "poll", post_id: public_poll_on_close.id }, format: :json
|
|
|
|
expect(response.status).to eq(200)
|
|
|
|
json = response.parsed_body
|
|
|
|
expect(json["voters"][first].size).to eq(1)
|
|
end
|
|
end
|
|
end
|