Merge pull request #1752 from MariaCheca/1725-census_local_copy_user_verification
Allow users to verify their account against a local copy of the Census
This commit is contained in:
6
app/models/local_census_record.rb
Normal file
6
app/models/local_census_record.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
class LocalCensusRecord < ActiveRecord::Base
|
||||
validates :document_number, presence: true
|
||||
validates :document_type, presence: true
|
||||
validates :date_of_birth, presence: true
|
||||
validates :postal_code, presence: true
|
||||
end
|
||||
@@ -4,7 +4,7 @@ class Officing::Residence
|
||||
|
||||
attr_accessor :user, :officer, :document_number, :document_type, :year_of_birth
|
||||
|
||||
before_validation :call_census_api
|
||||
before_validation :retrieve_census_data
|
||||
|
||||
validates :document_number, presence: true
|
||||
validates :document_type, presence: true
|
||||
@@ -101,8 +101,8 @@ class Officing::Residence
|
||||
|
||||
private
|
||||
|
||||
def call_census_api
|
||||
@census_api_response = CensusApi.new.call(document_type, document_number)
|
||||
def retrieve_census_data
|
||||
@census_api_response = CensusCaller.new.call(document_type, document_number)
|
||||
end
|
||||
|
||||
def residency_valid?
|
||||
|
||||
@@ -35,7 +35,7 @@ class Poll
|
||||
end
|
||||
|
||||
def census_api_response
|
||||
@census_api_response ||= CensusApi.new.call(document_type, document_number)
|
||||
@census_api_response ||= CensusCaller.new.call(document_type, document_number)
|
||||
end
|
||||
|
||||
def fill_stats_fields
|
||||
|
||||
@@ -69,7 +69,7 @@ class Signature < ActiveRecord::Base
|
||||
|
||||
def in_census?
|
||||
document_types.detect do |document_type|
|
||||
response = CensusApi.new.call(document_type, document_number)
|
||||
response = CensusCaller.new.call(document_type, document_number)
|
||||
if response.valid?
|
||||
@census_api_response = response
|
||||
true
|
||||
@@ -94,4 +94,4 @@ class Signature < ActiveRecord::Base
|
||||
%w(1 2 3 4)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,7 +18,7 @@ class Verification::Management::Document
|
||||
end
|
||||
|
||||
def in_census?
|
||||
response = CensusApi.new.call(document_type, document_number)
|
||||
response = CensusCaller.new.call(document_type, document_number)
|
||||
response.valid? && valid_age?(response)
|
||||
end
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ class Verification::Residence
|
||||
|
||||
attr_accessor :user, :document_number, :document_type, :date_of_birth, :postal_code, :terms_of_service
|
||||
|
||||
before_validation :call_census_api
|
||||
before_validation :retrieve_census_data
|
||||
|
||||
validates :document_number, presence: true
|
||||
validates :document_type, presence: true
|
||||
@@ -61,23 +61,23 @@ class Verification::Residence
|
||||
end
|
||||
|
||||
def district_code
|
||||
@census_api_response.district_code
|
||||
@census_data.district_code
|
||||
end
|
||||
|
||||
def gender
|
||||
@census_api_response.gender
|
||||
@census_data.gender
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def call_census_api
|
||||
@census_api_response = CensusApi.new.call(document_type, document_number)
|
||||
def retrieve_census_data
|
||||
@census_data = CensusCaller.new.call(document_type, document_number)
|
||||
end
|
||||
|
||||
def residency_valid?
|
||||
@census_api_response.valid? &&
|
||||
@census_api_response.postal_code == postal_code &&
|
||||
@census_api_response.date_of_birth == date_of_birth
|
||||
@census_data.valid? &&
|
||||
@census_data.postal_code == postal_code &&
|
||||
@census_data.date_of_birth == date_of_birth
|
||||
end
|
||||
|
||||
def clean_document_number
|
||||
|
||||
15
db/migrate/20170708174932_create_local_census_records.rb
Normal file
15
db/migrate/20170708174932_create_local_census_records.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
class CreateLocalCensusRecords < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :local_census_records do |t|
|
||||
t.string :document_number, null: false
|
||||
t.string :document_type, null: false
|
||||
t.date :date_of_birth, null: false
|
||||
t.string :postal_code, null: false
|
||||
t.integer :user_id
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
|
||||
add_foreign_key :local_census_records, :users, column: :user_id
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class RemoveLocalCensusRecordUserId < ActiveRecord::Migration
|
||||
def change
|
||||
remove_column :local_census_records, :user_id
|
||||
end
|
||||
end
|
||||
11
db/schema.rb
11
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: 20170708225159) do
|
||||
ActiveRecord::Schema.define(version: 20170713110317) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -484,6 +484,15 @@ ActiveRecord::Schema.define(version: 20170708225159) do
|
||||
add_index "legislation_questions", ["hidden_at"], name: "index_legislation_questions_on_hidden_at", using: :btree
|
||||
add_index "legislation_questions", ["legislation_process_id"], name: "index_legislation_questions_on_legislation_process_id", using: :btree
|
||||
|
||||
create_table "local_census_records", force: :cascade do |t|
|
||||
t.string "document_number", null: false
|
||||
t.string "document_type", null: false
|
||||
t.date "date_of_birth", null: false
|
||||
t.string "postal_code", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "locks", force: :cascade do |t|
|
||||
t.integer "user_id"
|
||||
t.integer "tries", default: 0
|
||||
|
||||
9
lib/census_caller.rb
Normal file
9
lib/census_caller.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
class CensusCaller
|
||||
|
||||
def call(document_type, document_number)
|
||||
response = CensusApi.new.call(document_type, document_number)
|
||||
response = LocalCensus.new.call(document_type, document_number) unless response.valid?
|
||||
|
||||
response
|
||||
end
|
||||
end
|
||||
66
lib/local_census.rb
Normal file
66
lib/local_census.rb
Normal file
@@ -0,0 +1,66 @@
|
||||
include DocumentParser
|
||||
class LocalCensus
|
||||
|
||||
def call(document_type, document_number)
|
||||
record = nil
|
||||
get_document_number_variants(document_type, document_number).each do |variant|
|
||||
record = Response.new(get_record(document_type, variant))
|
||||
return record if record.valid?
|
||||
end
|
||||
record
|
||||
end
|
||||
|
||||
class Response
|
||||
def initialize(body)
|
||||
@body = body
|
||||
end
|
||||
|
||||
def valid?
|
||||
@body.present? ? !@body.attributes.values.include?("" || nil) : false
|
||||
end
|
||||
|
||||
def date_of_birth
|
||||
@body.date_of_birth
|
||||
end
|
||||
|
||||
def postal_code
|
||||
@body.postal_code
|
||||
end
|
||||
|
||||
def district_code
|
||||
@body.district_code rescue nil
|
||||
end
|
||||
|
||||
def gender
|
||||
case @body.gender
|
||||
when "Varón"
|
||||
"male"
|
||||
when "Mujer"
|
||||
"female"
|
||||
end
|
||||
rescue NoMethodError
|
||||
nil
|
||||
end
|
||||
|
||||
def name
|
||||
"#{@body.nombre} #{@body.apellido1}" rescue nil
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def data
|
||||
@body.attributes
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_record(document_type, document_number)
|
||||
LocalCensusRecord.find_by(document_type: document_type, document_number: document_number)
|
||||
end
|
||||
|
||||
def is_dni?(document_type)
|
||||
document_type.to_s == "1"
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,4 +1,11 @@
|
||||
FactoryGirl.define do
|
||||
factory :local_census_record, class: 'LocalCensusRecord' do
|
||||
document_number '12345678A'
|
||||
document_type 1
|
||||
date_of_birth Date.new(1970, 1, 31)
|
||||
postal_code '28002'
|
||||
end
|
||||
|
||||
sequence(:document_number) { |n| "#{n.to_s.rjust(8, '0')}X" }
|
||||
|
||||
factory :user do
|
||||
|
||||
38
spec/lib/census_caller_spec.rb
Normal file
38
spec/lib/census_caller_spec.rb
Normal file
@@ -0,0 +1,38 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe CensusCaller do
|
||||
let(:api) { described_class.new }
|
||||
|
||||
describe '#call' do
|
||||
it "returns data from local_census_records if census API is not available" do
|
||||
census_api_response = CensusApi::Response.new({:get_habita_datos_response=>{:get_habita_datos_return=>{:datos_habitante=>{}, :datos_vivienda=>{}}}})
|
||||
local_census_response = LocalCensus::Response.new(create(:local_census_record))
|
||||
|
||||
CensusApi.any_instance.stub(:call).and_return(census_api_response)
|
||||
LocalCensus.any_instance.stub(:call).and_return(local_census_response)
|
||||
|
||||
allow(CensusApi).to receive(:call).with(1, "12345678A")
|
||||
allow(LocalCensus).to receive(:call).with(1, "12345678A")
|
||||
|
||||
response = api.call(1, "12345678A")
|
||||
|
||||
expect(response).to eq(local_census_response)
|
||||
end
|
||||
|
||||
it "returns data from census API if it's available and valid" do
|
||||
census_api_response = CensusApi::Response.new({get_habita_datos_response: {get_habita_datos_return: {datos_habitante: {item: {fecha_nacimiento_string: "1-1-1980"}}}}})
|
||||
local_census_response = LocalCensus::Response.new(create(:local_census_record))
|
||||
|
||||
CensusApi.any_instance.stub(:call).and_return(census_api_response)
|
||||
LocalCensus.any_instance.stub(:call).and_return(local_census_response)
|
||||
|
||||
allow(CensusApi).to receive(:call).with(1, "12345678A")
|
||||
allow(LocalCensus).to receive(:call).with(1, "12345678A")
|
||||
|
||||
response = api.call(1, "12345678A")
|
||||
|
||||
expect(response).to eq(census_api_response)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
55
spec/lib/local_census_spec.rb
Normal file
55
spec/lib/local_census_spec.rb
Normal file
@@ -0,0 +1,55 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe LocalCensus do
|
||||
let(:api) { described_class.new }
|
||||
|
||||
describe '#get_document_number_variants' do
|
||||
it "trims and cleans up entry" do
|
||||
expect(api.get_document_number_variants(2, ' 1 2@ 34')).to eq(['1234'])
|
||||
end
|
||||
|
||||
it "returns only one try for passports & residence cards" do
|
||||
expect(api.get_document_number_variants(2, '1234')).to eq(['1234'])
|
||||
expect(api.get_document_number_variants(3, '1234')).to eq(['1234'])
|
||||
end
|
||||
|
||||
it 'takes only the last 8 digits for dnis and resicence cards' do
|
||||
expect(api.get_document_number_variants(1, '543212345678')).to eq(['12345678'])
|
||||
end
|
||||
|
||||
it 'tries all the dni variants padding with zeroes' do
|
||||
expect(api.get_document_number_variants(1, '0123456')).to eq(['123456', '0123456', '00123456'])
|
||||
expect(api.get_document_number_variants(1, '00123456')).to eq(['123456', '0123456', '00123456'])
|
||||
end
|
||||
|
||||
it 'adds upper and lowercase letter when the letter is present' do
|
||||
expect(api.get_document_number_variants(1, '1234567A')).to eq(['1234567', '01234567', '1234567a', '1234567A', '01234567a', '01234567A'])
|
||||
end
|
||||
end
|
||||
|
||||
describe '#call' do
|
||||
let(:invalid_body) { nil }
|
||||
let(:valid_body) { create(:local_census_record) }
|
||||
|
||||
it "returns the response for the first valid variant" do
|
||||
allow(api).to receive(:get_record).with(1, "00123456").and_return(invalid_body)
|
||||
allow(api).to receive(:get_record).with(1, "123456").and_return(invalid_body)
|
||||
expect(api).to receive(:get_record).with(1, "0123456").and_return(valid_body)
|
||||
|
||||
response = api.call(1, "123456")
|
||||
|
||||
expect(response).to be_valid
|
||||
expect(response.date_of_birth).to eq(Date.new(1970, 1, 31))
|
||||
end
|
||||
|
||||
it "returns the last failed response" do
|
||||
expect(api).to receive(:get_record).with(1, "00123456").and_return(invalid_body)
|
||||
expect(api).to receive(:get_record).with(1, "123456").and_return(invalid_body)
|
||||
expect(api).to receive(:get_record).with(1, "0123456").and_return(invalid_body)
|
||||
response = api.call(1, "123456")
|
||||
|
||||
expect(response).to_not be_valid
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user