From 45d26f6deee1efef2795ce12b2aa98fda1dee060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Tue, 6 Dec 2016 20:20:18 +0100 Subject: [PATCH] refactors poll::voter now belongs_to booth_assignment instead of to booth --- app/models/poll.rb | 7 ++-- app/models/poll/booth.rb | 1 - app/models/poll/booth_assignment.rb | 1 + app/models/poll/voter.rb | 13 ++++++-- ..._rename_booth_id_to_booth_assignment_id.rb | 10 ++++++ db/schema.rb | 11 ++++--- spec/factories.rb | 4 +-- spec/models/poll/poll_spec.rb | 16 +++++++++ spec/models/poll/voter_spec.rb | 33 ++++++++++++------- 9 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 db/migrate/20161206132126_rename_booth_id_to_booth_assignment_id.rb diff --git a/app/models/poll.rb b/app/models/poll.rb index e06e9af92..ceb10d989 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -1,10 +1,9 @@ class Poll < ActiveRecord::Base has_many :booth_assignments, class_name: "Poll::BoothAssignment" has_many :booths, through: :booth_assignments + has_many :voters, through: :booth_assignments has_many :officer_assignments, through: :booth_assignments has_many :officers, through: :officer_assignments - - has_many :voters, through: :booths, class_name: "Poll::Voter" has_many :questions validates :name, presence: true @@ -35,4 +34,8 @@ class Poll < ActiveRecord::Base return none if user.nil? || user.unverified? current end + + def document_has_voted?(document_number, document_type) + voters.where(document_number: document_number, document_type: document_type).exists? + end end diff --git a/app/models/poll/booth.rb b/app/models/poll/booth.rb index 805686976..24f71c11a 100644 --- a/app/models/poll/booth.rb +++ b/app/models/poll/booth.rb @@ -2,7 +2,6 @@ class Poll class Booth < ActiveRecord::Base has_many :booth_assignments, class_name: "Poll::BoothAssignment" has_many :polls, through: :booth_assignments - has_many :voters validates :name, presence: true, uniqueness: true end diff --git a/app/models/poll/booth_assignment.rb b/app/models/poll/booth_assignment.rb index d9d784179..3c3d3d0d0 100644 --- a/app/models/poll/booth_assignment.rb +++ b/app/models/poll/booth_assignment.rb @@ -5,5 +5,6 @@ class Poll has_many :officer_assignments, class_name: "Poll::OfficerAssignment", dependent: :destroy has_many :officers, through: :officer_assignments + has_many :voters end end diff --git a/app/models/poll/voter.rb b/app/models/poll/voter.rb index a517c3f34..c55bc497c 100644 --- a/app/models/poll/voter.rb +++ b/app/models/poll/voter.rb @@ -1,11 +1,14 @@ class Poll class Voter < ActiveRecord::Base - belongs_to :booth - delegate :poll, to: :booth + belongs_to :booth_assignment + delegate :poll, to: :booth_assignment + validates :booth_assignment, presence: true validate :in_census validate :has_not_voted + before_create :assign_poll + def in_census errors.add(:document_number, :not_in_census) unless census_api_response.valid? end @@ -19,12 +22,16 @@ class Poll end def has_voted? - poll.voters.where(document_number: document_number, document_type: document_type).exists? + poll.document_has_voted?(document_number, document_type) end def name @census.name end + def assign_poll + poll_id = booth_assignment.poll_id + end + end end \ No newline at end of file diff --git a/db/migrate/20161206132126_rename_booth_id_to_booth_assignment_id.rb b/db/migrate/20161206132126_rename_booth_id_to_booth_assignment_id.rb new file mode 100644 index 000000000..a1b59c749 --- /dev/null +++ b/db/migrate/20161206132126_rename_booth_id_to_booth_assignment_id.rb @@ -0,0 +1,10 @@ +class RenameBoothIdToBoothAssignmentId < ActiveRecord::Migration + def change + remove_column :poll_voters, :booth_id, :integer + + add_column :poll_voters, :booth_assignment_id, :integer, null: false + add_column :poll_voters, :poll_id, :integer, null: false + add_column :poll_voters, :created_at, :datetime, null: false + add_column :poll_voters, :updated_at, :datetime, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index ed8e3f151..3337764e6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161206131125) do +ActiveRecord::Schema.define(version: 20161206132126) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -337,9 +337,12 @@ ActiveRecord::Schema.define(version: 20161206131125) do add_index "poll_questions", ["tsv"], name: "index_poll_questions_on_tsv", using: :gin create_table "poll_voters", force: :cascade do |t| - t.integer "booth_id" - t.string "document_number" - t.string "document_type" + t.string "document_number" + t.string "document_type" + t.integer "booth_assignment_id", null: false + t.integer "poll_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "polls", force: :cascade do |t| diff --git a/spec/factories.rb b/spec/factories.rb index 50d466718..27c98415d 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -309,11 +309,11 @@ FactoryGirl.define do factory :poll_officer_assignment, class: 'Poll::OfficerAssignment' do association :officer, factory: :poll_officer - association :booth_assignment, factory: :poll_booth_assignment + association :booth_assignment, factory: :poll_booth_assignment end factory :poll_voter, class: 'Poll::Voter' do - association :booth, factory: :budget_booth + association :booth_assignment, factory: :poll_booth_assignment trait :valid_document do document_type "1" diff --git a/spec/models/poll/poll_spec.rb b/spec/models/poll/poll_spec.rb index 0bb4f3136..cc6f2c530 100644 --- a/spec/models/poll/poll_spec.rb +++ b/spec/models/poll/poll_spec.rb @@ -38,4 +38,20 @@ describe :poll do expect(create(:poll)).to_not be_expired end end + + describe "#document_has_voted?" do + it "returns true if Poll::Voter with document exists" do + booth_assignment = create(:poll_booth_assignment, poll: poll) + voter = create(:poll_voter, :valid_document, booth_assignment: booth_assignment) + + expect(poll.document_has_voted?(voter.document_number, voter.document_type)).to eq(true) + end + + it "returns false if Poll::Voter with document does not exists" do + booth_assignment = create(:poll_booth_assignment) + voter = create(:poll_voter, :valid_document, booth_assignment: booth_assignment) + + expect(poll.document_has_voted?(voter.document_number, voter.document_type)).to eq(false) + end + end end \ No newline at end of file diff --git a/spec/models/poll/voter_spec.rb b/spec/models/poll/voter_spec.rb index de4536243..3a1844f4b 100644 --- a/spec/models/poll/voter_spec.rb +++ b/spec/models/poll/voter_spec.rb @@ -3,42 +3,53 @@ require 'rails_helper' describe :voter do let(:poll) { create(:poll) } - let(:booth) { create(:poll_booth, poll: poll) } + let(:booth) { create(:poll_booth) } + let(:booth_assignment) { create(:poll_booth_assignment, poll: poll, booth: booth) } describe "validations" do it "should be valid if in census and has not voted" do - voter = build(:poll_voter, :valid_document, booth: booth) + voter = build(:poll_voter, :valid_document, booth_assignment: booth_assignment) expect(voter).to be_valid end it "should not be valid if the user is not in the census" do - voter = build(:poll_voter, :invalid_document, booth: booth) + voter = build(:poll_voter, :invalid_document, booth_assignment: booth_assignment) expect(voter).to_not be_valid expect(voter.errors.messages[:document_number]).to eq(["Document not in census"]) end - it "should not be valid if the user has already voted in the same booth" do - voter1 = create(:poll_voter, :valid_document, booth: booth) - voter2 = build(:poll_voter, :valid_document, booth: booth) + it "should not be valid if the user has already voted in the same booth/poll" do + voter1 = create(:poll_voter, :valid_document, booth_assignment: booth_assignment) + voter2 = build(:poll_voter, :valid_document, booth_assignment: booth_assignment) expect(voter2).to_not be_valid expect(voter2.errors.messages[:document_number]).to eq(["José García has already voted"]) end - it "should not be valid if the user has already voted in another booth" do - booth1 = create(:poll_booth, poll: poll) - booth2 = create(:poll_booth, poll: poll) + it "should not be valid if the user has already voted in different booth in the same poll" do + booth_assignment1 = create(:poll_booth_assignment, poll: poll) + booth_assignment2 = create(:poll_booth_assignment, poll: poll) - voter1 = create(:poll_voter, :valid_document, booth: booth1) - voter2 = build(:poll_voter, :valid_document, booth: booth2) + voter1 = create(:poll_voter, :valid_document, booth_assignment: booth_assignment1) + voter2 = build(:poll_voter, :valid_document, booth_assignment: booth_assignment2) expect(voter2).to_not be_valid expect(voter2.errors.messages[:document_number]).to eq(["José García has already voted"]) end + it "should be valid if the user has already voted in the same booth in different poll" do + booth_assignment1 = create(:poll_booth_assignment, booth: booth) + booth_assignment2 = create(:poll_booth_assignment, booth: booth, poll: poll) + + voter1 = create(:poll_voter, :valid_document, booth_assignment: booth_assignment1) + voter2 = build(:poll_voter, :valid_document, booth_assignment: booth_assignment2) + + expect(voter2).to be_valid + end + xit "should not be valid if the user has voted via web" do pending "Implementation for voting via web" end