Our original interface to vote in a poll had a few issues: * Since there was no button to send the form, it wasn't clear that selecting an option would automatically store it in the database. * The interface was almost identical for single-choice questions and multiple-choice questions, which made it hard to know which type of question we were answering. * Adding other type of questions, like open answers, was hard since we would have to add a different submit button for each answer. So we're now using radio buttons for single-choice questions and checkboxes for multiple-choice questions, which are the native controls designed for these purposes, and a button to send the whole form. Since we don't have a database table for poll ballots like we have for budget ballots, we're adding a new `Poll::WebVote` model to manage poll ballots. We're using WebVote instead of Ballot or Vote because they could be mistaken with other vote classes. Note that browsers don't allow removing answers with radio buttons, so once somebody has voted in a single-choice question, they can't remove the vote unless they manually edit their HTML. This is the same behavior we had before commit7df0e9a96. As mentioned inc2010f975, we're now adding the `ChangeByZero` rubocop rule, since we've removed the test that used `and change`.
106 lines
3.7 KiB
Ruby
106 lines
3.7 KiB
Ruby
require "rails_helper"
|
|
|
|
describe Poll::Answer do
|
|
describe "validations" do
|
|
let(:answer) { build(:poll_answer) }
|
|
|
|
it "is valid" do
|
|
expect(answer).to be_valid
|
|
end
|
|
|
|
it "is not valid wihout a question" do
|
|
answer.question = nil
|
|
expect(answer).not_to be_valid
|
|
end
|
|
|
|
it "is not valid without an author" do
|
|
answer.author = nil
|
|
expect(answer).not_to be_valid
|
|
end
|
|
|
|
it "is not valid without an author when multiple answers are allowed" do
|
|
answer.author = nil
|
|
answer.question = create(:poll_question_multiple)
|
|
|
|
expect(answer).not_to be_valid
|
|
end
|
|
|
|
it "is not valid without an answer" do
|
|
answer.answer = nil
|
|
expect(answer).not_to be_valid
|
|
end
|
|
|
|
it "is not valid if there's already an answer to that question" do
|
|
author = create(:user)
|
|
question = create(:poll_question, :yes_no)
|
|
|
|
create(:poll_answer, author: author, question: question)
|
|
|
|
answer = build(:poll_answer, author: author, question: question)
|
|
|
|
expect(answer).not_to be_valid
|
|
end
|
|
|
|
it "is not valid when user already reached multiple answers question max votes" do
|
|
author = create(:user)
|
|
question = create(:poll_question_multiple, :abc, max_votes: 2)
|
|
create(:poll_answer, author: author, question: question, answer: "Answer A")
|
|
create(:poll_answer, author: author, question: question, answer: "Answer B")
|
|
answer = build(:poll_answer, author: author, question: question, answer: "Answer C")
|
|
|
|
expect(answer).not_to be_valid
|
|
end
|
|
|
|
it "is not valid when there are two identical answers" do
|
|
author = create(:user)
|
|
question = create(:poll_question_multiple, :abc)
|
|
option = question.question_options.first
|
|
|
|
create(:poll_answer, author: author, question: question, option: option, answer: "Answer A")
|
|
|
|
answer = build(:poll_answer, author: author, question: question, option: option, answer: "Answer A")
|
|
|
|
expect(answer).not_to be_valid
|
|
expect { answer.save(validate: false) }.to raise_error ActiveRecord::RecordNotUnique
|
|
end
|
|
|
|
it "is not valid when there are two answers with the same option and different answer" do
|
|
author = create(:user)
|
|
question = create(:poll_question_multiple, :abc)
|
|
option = question.question_options.first
|
|
|
|
create(:poll_answer, author: author, question: question, option: option, answer: "Answer A")
|
|
|
|
answer = build(:poll_answer, author: author, question: question, option: option, answer: "Answer B")
|
|
|
|
expect(answer).not_to be_valid
|
|
expect { answer.save(validate: false) }.to raise_error ActiveRecord::RecordNotUnique
|
|
end
|
|
|
|
it "is valid when there are two identical answers and the option is nil" do
|
|
author = create(:user)
|
|
question = create(:poll_question_multiple, :abc)
|
|
|
|
create(:poll_answer, author: author, question: question, option: nil, answer: "Answer A")
|
|
|
|
answer = build(:poll_answer, author: author, question: question, option: nil, answer: "Answer A")
|
|
|
|
expect(answer).to be_valid
|
|
expect { answer.save }.not_to raise_error
|
|
end
|
|
|
|
it "is valid for answers included in the Poll::Question's question_options list" do
|
|
question = create(:poll_question)
|
|
create(:poll_question_option, title: "One", question: question)
|
|
create(:poll_question_option, title: "Two", question: question)
|
|
create(:poll_question_option, title: "Three", question: question)
|
|
|
|
expect(build(:poll_answer, question: question, answer: "One")).to be_valid
|
|
expect(build(:poll_answer, question: question, answer: "Two")).to be_valid
|
|
expect(build(:poll_answer, question: question, answer: "Three")).to be_valid
|
|
|
|
expect(build(:poll_answer, question: question, answer: "Four")).not_to be_valid
|
|
end
|
|
end
|
|
end
|