discourse/plugins/poll/spec/lib/polls_updater_spec.rb
Sam Saffron 3c1fa3910f DEV: track the correct channel in specs
These tests are erratically failing due to distributed cache messages that
can land between tests

Ensure we are only looking for the correct messages
2019-05-20 18:27:09 +10:00

223 lines
5.3 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
describe DiscoursePoll::PollsUpdater do
def update(post, polls)
DiscoursePoll::PollsUpdater.update(post, polls)
end
let(:user) { Fabricate(:user) }
let(:post) {
Fabricate(:post, raw: <<~RAW)
[poll]
* 1
* 2
[/poll]
RAW
}
let(:post_with_3_options) {
Fabricate(:post, raw: <<~RAW)
[poll]
- a
- b
- c
[/poll]
RAW
}
let(:post_with_some_attributes) {
Fabricate(:post, raw: <<~RAW)
[poll close=#{1.week.from_now.to_formatted_s(:iso8601)} results=on_close]
- A
- B
- C
[/poll]
RAW
}
let(:polls) {
DiscoursePoll::PollsValidator.new(post).validate_polls
}
let(:polls_with_3_options) {
DiscoursePoll::PollsValidator.new(post_with_3_options).validate_polls
}
let(:polls_with_some_attributes) {
DiscoursePoll::PollsValidator.new(post_with_some_attributes).validate_polls
}
describe "update" do
it "does nothing when there are no changes" do
message = MessageBus.track_publish("/polls/#{post.topic_id}") do
update(post, polls)
end.first
expect(message).to be(nil)
end
describe "when editing" do
let(:raw) do
<<~RAW
This is a new poll with three options.
[poll type=multiple results=always min=1 max=2]
* first
* second
* third
[/poll]
RAW
end
let(:post) { Fabricate(:post, raw: raw) }
it "works if poll is closed and unmodified" do
DiscoursePoll::Poll.vote(post.id, "poll", ["e55de753c08b93d04d677ce05e942d3c"], post.user)
DiscoursePoll::Poll.toggle_status(post.id, "poll", "closed", post.user)
freeze_time (SiteSetting.poll_edit_window_mins + 1).minutes.from_now
update(post, DiscoursePoll::PollsValidator.new(post).validate_polls)
expect(post.errors[:base].size).to equal(0)
end
end
describe "deletes polls" do
it "that were removed" do
update(post, {})
post.reload
expect(Poll.where(post: post).exists?).to eq(false)
expect(post.custom_fields[DiscoursePoll::HAS_POLLS]).to eq(nil)
end
end
describe "creates polls" do
it "that were added" do
post = Fabricate(:post)
expect(Poll.find_by(post: post)).to_not be
message = MessageBus.track_publish("/polls/#{post.topic_id}") do
update(post, polls)
end.first
poll = Poll.find_by(post: post)
expect(poll).to be
expect(poll.poll_options.size).to eq(2)
expect(poll.post.custom_fields[DiscoursePoll::HAS_POLLS]).to eq(true)
expect(message.data[:post_id]).to eq(post.id)
expect(message.data[:polls][0][:name]).to eq(poll.name)
end
end
describe "updates polls" do
describe "when there are no votes" do
it "at any time" do
post # create the post
freeze_time 1.month.from_now
message = MessageBus.track_publish("/polls/#{post.topic_id}") do
update(post, polls_with_some_attributes)
end.first
poll = Poll.find_by(post: post)
expect(poll).to be
expect(poll.poll_options.size).to eq(3)
expect(poll.poll_votes.size).to eq(0)
expect(poll.on_close?).to eq(true)
expect(poll.close_at).to be
expect(poll.post.custom_fields[DiscoursePoll::HAS_POLLS]).to eq(true)
expect(message.data[:post_id]).to eq(post.id)
expect(message.data[:polls][0][:name]).to eq(poll.name)
end
end
describe "when there are votes" do
before do
expect {
DiscoursePoll::Poll.vote(post.id, "poll", [polls["poll"]["options"][0]["id"]], user)
}.to change { PollVote.count }.by(1)
end
describe "inside the edit window" do
it "and deletes the votes" do
message = MessageBus.track_publish("/polls/#{post.topic_id}") do
update(post, polls_with_some_attributes)
end.first
poll = Poll.find_by(post: post)
expect(poll).to be
expect(poll.poll_options.size).to eq(3)
expect(poll.poll_votes.size).to eq(0)
expect(poll.on_close?).to eq(true)
expect(poll.close_at).to be
expect(poll.post.custom_fields[DiscoursePoll::HAS_POLLS]).to eq(true)
expect(message.data[:post_id]).to eq(post.id)
expect(message.data[:polls][0][:name]).to eq(poll.name)
end
end
describe "outside the edit window" do
it "throws an error" do
edit_window = SiteSetting.poll_edit_window_mins
freeze_time (edit_window + 1).minutes.from_now
update(post, polls_with_some_attributes)
poll = Poll.find_by(post: post)
expect(poll).to be
expect(poll.poll_options.size).to eq(2)
expect(poll.poll_votes.size).to eq(1)
expect(poll.on_close?).to eq(false)
expect(poll.close_at).to_not be
expect(post.errors[:base]).to include(
I18n.t(
"poll.edit_window_expired.cannot_edit_default_poll_with_votes",
minutes: edit_window
)
)
end
end
end
end
end
end