@@ -1,2 +1,4 @@
|
||||
class Poll < ActiveRecord::Base
|
||||
has_many :booths
|
||||
has_many :voters, through: :booths, class_name: "Poll::Voter"
|
||||
end
|
||||
6
app/models/poll/booth.rb
Normal file
6
app/models/poll/booth.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class Poll
|
||||
class Booth < ActiveRecord::Base
|
||||
belongs_to :poll
|
||||
has_many :voters
|
||||
end
|
||||
end
|
||||
30
app/models/poll/voter.rb
Normal file
30
app/models/poll/voter.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
class Poll
|
||||
class Voter < ActiveRecord::Base
|
||||
belongs_to :booth
|
||||
delegate :poll, to: :booth
|
||||
|
||||
validate :in_census
|
||||
validate :has_not_voted
|
||||
|
||||
def in_census
|
||||
errors.add(:document_number, :not_in_census) unless census_api_response.valid?
|
||||
end
|
||||
|
||||
def has_not_voted
|
||||
errors.add(:document_number, :has_voted, name: name) if has_voted?
|
||||
end
|
||||
|
||||
def census_api_response
|
||||
@census ||= CensusApi.new.call(document_type, document_number)
|
||||
end
|
||||
|
||||
def has_voted?
|
||||
poll.voters.where(document_number: document_number, document_type: document_type).exists?
|
||||
end
|
||||
|
||||
def name
|
||||
@census.name
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -82,6 +82,11 @@ en:
|
||||
attributes:
|
||||
max_per_day:
|
||||
invalid: "You have reached the maximum number of private messages per day"
|
||||
poll/voter:
|
||||
attributes:
|
||||
document_number:
|
||||
not_in_census: "Document not in census"
|
||||
has_voted: "%{name} has already voted"
|
||||
proposal:
|
||||
attributes:
|
||||
tag_list:
|
||||
|
||||
@@ -82,6 +82,11 @@ es:
|
||||
attributes:
|
||||
max_per_day:
|
||||
invalid: "Has llegado al número máximo de mensajes privados por día"
|
||||
poll/voter:
|
||||
attributes:
|
||||
document_number:
|
||||
not_in_census: "Este documento no aparece en el censo"
|
||||
has_voted: "%{name} ya ha votado"
|
||||
proposal:
|
||||
attributes:
|
||||
tag_list:
|
||||
|
||||
9
db/migrate/20160914172016_create_poll_voters.rb
Normal file
9
db/migrate/20160914172016_create_poll_voters.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class CreatePollVoters < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :poll_voters do |t|
|
||||
t.integer :booth_id
|
||||
t.string :document_number
|
||||
t.string :document_type
|
||||
end
|
||||
end
|
||||
end
|
||||
8
db/migrate/20160914172535_create_poll_booths.rb
Normal file
8
db/migrate/20160914172535_create_poll_booths.rb
Normal file
@@ -0,0 +1,8 @@
|
||||
class CreatePollBooths < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :poll_booths do |t|
|
||||
t.string :name
|
||||
t.integer :poll_id
|
||||
end
|
||||
end
|
||||
end
|
||||
13
db/schema.rb
13
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: 20160914110039) do
|
||||
ActiveRecord::Schema.define(version: 20160914172535) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -270,6 +270,17 @@ ActiveRecord::Schema.define(version: 20160914110039) do
|
||||
|
||||
add_index "organizations", ["user_id"], name: "index_organizations_on_user_id", using: :btree
|
||||
|
||||
create_table "poll_booths", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.integer "poll_id"
|
||||
end
|
||||
|
||||
create_table "poll_voters", force: :cascade do |t|
|
||||
t.integer "booth_id"
|
||||
t.string "document_number"
|
||||
t.string "document_type"
|
||||
end
|
||||
|
||||
create_table "poll_officers", force: :cascade do |t|
|
||||
t.integer "user_id"
|
||||
end
|
||||
|
||||
@@ -61,6 +61,10 @@ class CensusApi
|
||||
end
|
||||
end
|
||||
|
||||
def name
|
||||
"#{data[:datos_habitante][:item][:nombre]} #{data[:datos_habitante][:item][:apellido1]}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def data
|
||||
@@ -74,7 +78,7 @@ class CensusApi
|
||||
if end_point_available?
|
||||
client.call(:get_habita_datos, message: request(document_type, document_number)).body
|
||||
else
|
||||
stubbed_response_body
|
||||
stubbed_response(document_type, document_number)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -97,8 +101,20 @@ class CensusApi
|
||||
Rails.env.staging? || Rails.env.preproduction? || Rails.env.production?
|
||||
end
|
||||
|
||||
def stubbed_response_body
|
||||
{get_habita_datos_response: {get_habita_datos_return: {hay_errores: false, datos_habitante: { item: {fecha_nacimiento_string: "31-12-1980", identificador_documento: "12345678Z", descripcion_sexo: "Varón" }}, datos_vivienda: {item: {codigo_postal: "28013", codigo_distrito: "01"}}}}}
|
||||
def stubbed_response(document_type, document_number)
|
||||
if document_number == "12345678Z" && document_type == "1"
|
||||
stubbed_valid_response
|
||||
else
|
||||
stubbed_invalid_response
|
||||
end
|
||||
end
|
||||
|
||||
def stubbed_valid_response
|
||||
{get_habita_datos_response: {get_habita_datos_return: {datos_habitante: { item: {fecha_nacimiento_string: "31-12-1980", identificador_documento: "12345678Z", descripcion_sexo: "Varón", nombre: "José", apellido1: "García" }}, datos_vivienda: {item: {codigo_postal: "28013", codigo_distrito: "01"}}}}}
|
||||
end
|
||||
|
||||
def stubbed_invalid_response
|
||||
{get_habita_datos_response: {get_habita_datos_return: {datos_habitante: {}, datos_vivienda: {}}}}
|
||||
end
|
||||
|
||||
def is_dni?(document_type)
|
||||
|
||||
@@ -259,10 +259,33 @@ FactoryGirl.define do
|
||||
user
|
||||
end
|
||||
|
||||
factory :poll do
|
||||
sequence(:name) { |n| "Poll #{n}" }
|
||||
end
|
||||
|
||||
factory :poll_officer, class: 'Poll::Officer' do
|
||||
user
|
||||
end
|
||||
|
||||
factory :poll_booth, class: 'Poll::Booth' do
|
||||
sequence(:name) { |n| "Booth #{n}" }
|
||||
poll
|
||||
end
|
||||
|
||||
factory :poll_voter, class: 'Poll::Voter' do
|
||||
association :booth, factory: :budget_booth
|
||||
|
||||
trait :valid_document do
|
||||
document_type "1"
|
||||
document_number "12345678Z"
|
||||
end
|
||||
|
||||
trait :invalid_document do
|
||||
document_type "1"
|
||||
document_number "99999999A"
|
||||
end
|
||||
end
|
||||
|
||||
factory :organization do
|
||||
user
|
||||
responsible_name "Johnny Utah"
|
||||
|
||||
@@ -47,7 +47,7 @@ feature 'DocumentVerifications' do
|
||||
scenario 'Verifying a user which does exists in the census but not in the db redirects allows sending an email' do
|
||||
|
||||
visit management_document_verifications_path
|
||||
fill_in 'document_verification_document_number', with: '1234'
|
||||
fill_in 'document_verification_document_number', with: '12345678Z'
|
||||
click_button 'Check'
|
||||
|
||||
expect(page).to have_content "Please introduce the email used on the account"
|
||||
@@ -66,7 +66,7 @@ feature 'DocumentVerifications' do
|
||||
expect_any_instance_of(Verification::Management::Document).to receive(:under_sixteen?).and_return(true)
|
||||
|
||||
visit management_document_verifications_path
|
||||
fill_in 'document_verification_document_number', with: '1234'
|
||||
fill_in 'document_verification_document_number', with: '12345678Z'
|
||||
click_button 'Check'
|
||||
|
||||
expect(page).to have_content "You must be over 16 to verify your account."
|
||||
|
||||
@@ -8,7 +8,7 @@ feature 'EmailVerifications' do
|
||||
user = create(:user)
|
||||
|
||||
visit management_document_verifications_path
|
||||
fill_in 'document_verification_document_number', with: '1234'
|
||||
fill_in 'document_verification_document_number', with: '12345678Z'
|
||||
click_button 'Check'
|
||||
|
||||
expect(page).to have_content "Please introduce the email used on the account"
|
||||
@@ -30,7 +30,7 @@ feature 'EmailVerifications' do
|
||||
expect(page).to_not have_link "Verify my account"
|
||||
expect(page).to have_content "Account verified"
|
||||
|
||||
expect(user.reload.document_number).to eq('1234')
|
||||
expect(user.reload.document_number).to eq('12345678Z')
|
||||
expect(user).to be_level_three_verified
|
||||
end
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ feature 'Managed User' do
|
||||
user = create(:user)
|
||||
|
||||
visit management_document_verifications_path
|
||||
fill_in 'document_verification_document_number', with: '1234'
|
||||
fill_in 'document_verification_document_number', with: '12345678Z'
|
||||
click_button 'Check'
|
||||
|
||||
within(".account-info") do
|
||||
@@ -88,7 +88,7 @@ feature 'Managed User' do
|
||||
login_as_manager
|
||||
|
||||
visit management_document_verifications_path
|
||||
fill_in 'document_verification_document_number', with: '1234'
|
||||
fill_in 'document_verification_document_number', with: '12345678Z'
|
||||
click_button 'Check'
|
||||
|
||||
expect(page).to have_content "Please introduce the email used on the account"
|
||||
|
||||
@@ -9,7 +9,7 @@ feature 'Users' do
|
||||
scenario 'Create a level 3 user from scratch' do
|
||||
|
||||
visit management_document_verifications_path
|
||||
fill_in 'document_verification_document_number', with: '1234'
|
||||
fill_in 'document_verification_document_number', with: '12345678Z'
|
||||
click_button 'Check'
|
||||
|
||||
expect(page).to have_content "Please introduce the email used on the account"
|
||||
@@ -45,10 +45,10 @@ feature 'Users' do
|
||||
end
|
||||
|
||||
scenario 'Delete a level 2 user account from document verification page', :js do
|
||||
level_2_user = create(:user, :level_two, document_number: 13579)
|
||||
level_2_user = create(:user, :level_two, document_number: "12345678Z")
|
||||
|
||||
visit management_document_verifications_path
|
||||
fill_in 'document_verification_document_number', with: '13579'
|
||||
fill_in 'document_verification_document_number', with: '12345678Z'
|
||||
click_button 'Check'
|
||||
|
||||
expect(page).to_not have_content "This user account is already verified."
|
||||
@@ -62,7 +62,7 @@ feature 'Users' do
|
||||
expect(level_2_user.reload.erase_reason).to eq "Deleted by manager: manager_user_#{Manager.last.user_id}"
|
||||
|
||||
visit management_document_verifications_path
|
||||
fill_in 'document_verification_document_number', with: '13579'
|
||||
fill_in 'document_verification_document_number', with: '12345678Z'
|
||||
click_button 'Check'
|
||||
|
||||
expect(page).to have_content "no user account associated to it"
|
||||
|
||||
47
spec/models/poll/voter_spec.rb
Normal file
47
spec/models/poll/voter_spec.rb
Normal file
@@ -0,0 +1,47 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe :voter do
|
||||
|
||||
let(:poll) { create(:poll) }
|
||||
let(:booth) { create(:poll_booth, poll: poll) }
|
||||
|
||||
describe "validations" do
|
||||
|
||||
it "should be valid if in census and has not voted" do
|
||||
voter = build(:poll_voter, :valid_document, booth: booth)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
voter1 = create(:poll_voter, :valid_document, booth: booth1)
|
||||
voter2 = build(:poll_voter, :valid_document, booth: booth2)
|
||||
|
||||
expect(voter2).to_not be_valid
|
||||
expect(voter2.errors.messages[:document_number]).to eq(["José García has already voted"])
|
||||
end
|
||||
|
||||
xit "should not be valid if the user has voted via web" do
|
||||
pending "Implementation for voting via web"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user