require "rails_helper" describe Poll::Voter do describe "validations" do let(:poll) { create(:poll) } let(:booth) { create(:poll_booth) } let(:booth_assignment) { create(:poll_booth_assignment, poll: poll, booth: booth) } let(:voter) { create(:poll_voter) } let(:user) { create(:user, :level_two) } it "is valid" do expect(voter).to be_valid end it "is not valid without a user" do voter.user = nil expect(voter).not_to be_valid end it "is not valid without a poll" do voter.poll = nil expect(voter).not_to be_valid end it "is valid if has not voted" do voter = build(:poll_voter, :valid_document) expect(voter).to be_valid end it "is not valid if the user has already voted in the same poll or booth_assignment" do create(:poll_voter, user: user, poll: poll) voter = build(:poll_voter, user: user, poll: poll) expect { voter.save }.to raise_error ActiveRecord::RecordNotUnique end it "is not valid if the user has already voted in the same poll/booth" do create(:poll_voter, user: user, poll: poll, booth_assignment: booth_assignment) voter = build(:poll_voter, user: user, poll: poll, booth_assignment: booth_assignment) expect { voter.save }.to raise_error ActiveRecord::RecordNotUnique end it "is not valid if the user has already voted in different booth in the same poll" do create(:poll_voter, :from_booth, user: user, poll: poll, booth: create(:poll_booth)) voter = build(:poll_voter, :from_booth, user: user, poll: poll, booth: booth) expect { voter.save }.to raise_error ActiveRecord::RecordNotUnique end it "is valid if the user has already voted in the same booth in different poll" do create(:poll_voter, :from_booth, user: user, booth: booth, poll: create(:poll)) voter = build(:poll_voter, :from_booth, user: user, booth: booth, poll: poll) expect(voter).to be_valid end it "is not valid if the user has voted via web" do answer = create(:poll_answer) create(:poll_voter, :from_web, user: answer.author, poll: answer.poll) voter = build(:poll_voter, poll: answer.question.poll, user: answer.author) expect { voter.save }.to raise_error ActiveRecord::RecordNotUnique end context "Skip verification is enabled" do before do Setting["feature.user.skip_verification"] = true user.update!(document_number: nil, document_type: nil) end it "is not valid if the user has already voted in the same poll" do create(:poll_voter, user: user, poll: poll) voter = build(:poll_voter, user: user, poll: poll) expect { voter.save }.to raise_error ActiveRecord::RecordNotUnique end it "is valid if other users have voted in the same poll" do another_user = create(:user, :level_two, document_number: nil, document_type: nil) create(:poll_voter, user: another_user, poll: poll) voter = build(:poll_voter, user: user, poll: poll) expect(voter).to be_valid end end context "origin" do it "is not valid without an origin" do voter.origin = nil expect(voter).not_to be_valid end it "is not valid without a valid origin" do voter.origin = "invalid_origin" expect(voter).not_to be_valid end it "is valid with a booth origin" do voter.origin = "booth" voter.officer_assignment = create(:poll_officer_assignment) expect(voter).to be_valid end it "is valid with a web origin" do voter.origin = "web" expect(voter).to be_valid end it "dynamically validates the valid origins" do stub_const("#{Poll::Voter}::VALID_ORIGINS", %w[custom]) expect(build(:poll_voter, origin: "custom")).to be_valid expect(build(:poll_voter, origin: "web")).not_to be_valid end end context "assignments" do it "is not valid without a booth_assignment_id when origin is booth" do voter.origin = "booth" voter.booth_assignment_id = nil expect(voter).not_to be_valid end it "is not valid without an officer_assignment_id when origin is booth" do voter.origin = "booth" voter.officer_assignment_id = nil expect(voter).not_to be_valid end it "is valid without assignments when origin is web" do voter.origin = "web" voter.booth_assignment_id = nil voter.officer_assignment_id = nil expect(voter).to be_valid end end describe ".create_or_find_by!" do it "finds the voter when it already exists instead of failing the validation" do existing_voter = Poll::Voter.create_with(origin: "web") .create_or_find_by!(user: voter.user, poll: voter.poll) expect(existing_voter).to eq voter end end end describe "scopes" do describe "#web" do it "returns voters with a web origin" do voter = create(:poll_voter, :from_web) expect(Poll::Voter.web).to eq [voter] end it "does not return voters with a booth origin" do create(:poll_voter, :from_booth) expect(Poll::Voter.web).to be_empty end end describe "#booth" do it "returns voters with a booth origin" do voter = create(:poll_voter, :from_booth) expect(Poll::Voter.booth).to eq [voter] end it "does not return voters with a web origin" do create(:poll_voter, :from_web) expect(Poll::Voter.booth).to be_empty end end end describe "save" do it "sets demographic info" do geozone = create(:geozone) user = create(:user, :level_two, geozone: geozone, date_of_birth: 30.years.ago, gender: "female") voter = build(:poll_voter, user: user) voter.save! expect(voter.geozone).to eq(geozone) expect(voter.age).to eq(30) expect(voter.gender).to eq("female") end it "sets user info" do user = create(:user, document_number: "1234A", document_type: "1") voter = build(:poll_voter, user: user) voter.save! expect(voter.document_number).to eq("1234A") expect(voter.document_type).to eq("1") end it "sets user info with skip verification enabled" do Setting["feature.user.skip_verification"] = true user = create(:user) voter = build(:poll_voter, user: user) expect { voter.save! }.not_to raise_exception end end end