Merge pull request #2125 from LauraConcepcion/feature/generalize_postal_code_verification

Redefine postal code verification methods to use setting config parameter
This commit is contained in:
Javi Martín
2021-12-17 17:26:57 +01:00
committed by GitHub
10 changed files with 214 additions and 69 deletions

View File

@@ -1,26 +0,0 @@
require_dependency Rails.root.join("app", "models", "verification", "residence").to_s
class Verification::Residence
validate :local_postal_code
validate :local_residence
def local_postal_code
errors.add(:postal_code, I18n.t("verification.residence.new.error_not_allowed_postal_code")) unless valid_postal_code?
end
def local_residence
return if errors.any?
unless residency_valid?
errors.add(:local_residence, false)
store_failed_attempt
Lock.increase_tries(user)
end
end
private
def valid_postal_code?
postal_code =~ /^280/
end
end

View File

@@ -177,6 +177,7 @@ class Setting < ApplicationRecord
"machine_learning.comments_summary": false,
"machine_learning.related_content": false,
"machine_learning.tags": false,
"postal_codes": "",
"remote_census.general.endpoint": "",
"remote_census.request.method_name": "",
"remote_census.request.structure": "",

View File

@@ -5,18 +5,18 @@ class Verification::Residence
attr_accessor :user, :document_number, :document_type, :date_of_birth, :postal_code, :terms_of_service
before_validation :retrieve_census_data
validates :document_number, presence: true
validates :document_type, presence: true
validates :date_of_birth, presence: true
validates :postal_code, presence: true
validates :terms_of_service, acceptance: { allow_nil: false }
validates :postal_code, length: { is: 5 }
validate :allowed_age
validate :document_number_uniqueness
validate :local_postal_code
validate :local_residence
def initialize(attrs = {})
self.date_of_birth = parse_date("date_of_birth", attrs)
attrs = remove_date("date_of_birth", attrs)
@@ -66,26 +66,52 @@ class Verification::Residence
end
def district_code
@census_data.district_code
census_data.district_code
end
def gender
@census_data.gender
census_data.gender
end
def local_postal_code
errors.add(:postal_code, I18n.t("verification.residence.new.error_not_allowed_postal_code")) unless valid_postal_code?
end
def local_residence
return if errors.any?
unless residency_valid?
errors.add(:local_residence, false)
store_failed_attempt
Lock.increase_tries(user)
end
end
private
def retrieve_census_data
@census_data = CensusCaller.new.call(document_type, document_number, date_of_birth, postal_code)
def census_data
@census_data ||= CensusCaller.new.call(document_type, document_number, date_of_birth, postal_code)
end
def residency_valid?
@census_data.valid? &&
@census_data.postal_code == postal_code &&
@census_data.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
self.document_number = document_number.gsub(/[^a-z0-9]+/i, "").upcase if document_number.present?
end
def valid_postal_code?
return true if Setting["postal_codes"].blank?
Setting["postal_codes"].split(",").any? do |code_or_range|
if code_or_range.include?(":")
Range.new(*code_or_range.split(":").map(&:strip)).include?(postal_code&.strip)
else
/\A#{code_or_range.strip}\Z/.match?(postal_code&.strip)
end
end
end
end

View File

@@ -60,6 +60,8 @@ en:
meta_keywords_description: 'Keywords <meta name="keywords">, used to improve SEO'
min_age_to_participate: Minimum age needed to participate
min_age_to_participate_description: "Users over this age can participate in all processes where a user verified account is needed"
postal_codes: "Postal Codes"
postal_codes_description: "A comma-separated list of valid postal codes; you can also introduce ranges separated with a colon. Example: 00001:00010,00024,AB3 45FG,00031:00035 will allow postal codes between 00001 and 00010, the postal code 00024, the postal code AB3 45FG, and postal codes between 00031 and 00035. If you leave it blank, all postal codes will be valid."
proposals:
successful_proposal_id: Successful proposal
successful_proposal_id_description: This proposal is used as a reference for a successful proposal in supports number and will be displayed in the dashboard graph.

View File

@@ -55,7 +55,7 @@ en:
residence_card: Residence card
spanish_id: DNI
error_not_allowed_age: You don't have the required age to participate
error_not_allowed_postal_code: In order to be verified, you must be registered.
error_not_allowed_postal_code: Citizens from this postal code cannot participate
error_verifying_census: The Census was unable to verify your information. Please confirm that your census details are correct by calling to City Council or visit one Citizen Support Office.
form_errors: prevented the verification of your residence
postal_code_note: To verify your account you must be registered

View File

@@ -60,6 +60,8 @@ es:
meta_keywords_description: 'Palabras clave <meta name="keywords">, utilizadas para mejorar el SEO'
min_age_to_participate: Edad mínima para participar
min_age_to_participate_description: "Los usuarios mayores de esta edad podrán participar en todos los procesos donde se necesite una cuenta verificada"
postal_codes: "Códigos Postales"
postal_codes_description: "Una lista de códigos postales válidos separados por comas; también puedes usar rangos utilizando \":\". Ejemplo: 00001:00010,00024,AB3 45FG,00031:00035 permitirá códigos postales entre 00001 y 00010, el 00024, el AB3 45FG, y códigos postales entre 00031 y 00035. Si dejas esta opción en blanco, cualquier código postal será válido."
proposals:
successful_proposal_id: Propuesta exitosa
successful_proposal_id_description: Esta propuesta se utiliza como referencia de una propuesta exitosa en número de apoyos y se mostrará en el gráfico del panel de control

View File

@@ -55,7 +55,7 @@ es:
residence_card: Tarjeta de residencia
spanish_id: DNI
error_not_allowed_age: No tienes la edad mínima para participar
error_not_allowed_postal_code: Para verificarte debes estar empadronado.
error_not_allowed_postal_code: Los ciudadanos residentes en este código postal no pueden participar
error_verifying_census: El Padrón no pudo verificar tu información. Por favor, confirma que tus datos de empadronamiento sean correctos llamando al Ayuntamiento o visitando una Oficina de Atención al Ciudadano.
form_errors: evitaron verificar tu residencia
postal_code_note: Para verificar tus datos debes estar empadronado

View File

@@ -1,29 +0,0 @@
require "rails_helper"
describe Verification::Residence do
let(:residence) { build(:verification_residence, document_number: "12345678Z") }
describe "verification" do
describe "postal code" do
it "is valid with postal codes starting with 280" do
residence.postal_code = "28012"
residence.valid?
expect(residence.errors[:postal_code]).to be_empty
residence.postal_code = "28023"
residence.valid?
expect(residence.errors[:postal_code]).to be_empty
end
it "is not valid with postal codes not starting with 280" do
residence.postal_code = "12345"
residence.valid?
expect(residence.errors[:postal_code].size).to eq(1)
residence.postal_code = "13280"
residence.valid?
expect(residence.errors[:postal_code]).to eq ["In order to be verified, you must be registered."]
end
end
end
end

View File

@@ -46,6 +46,174 @@ describe Verification::Residence do
residence.terms_of_service = nil
expect(residence).not_to be_valid
end
describe "postal code" do
before do
Setting["postal_codes"] = "28001:28100,28200,28303-455"
census_data = double(valid?: true, district_code: "", gender: "")
allow(census_data).to receive(:postal_code) { residence.postal_code }
allow(census_data).to receive(:date_of_birth) { residence.date_of_birth }
allow(residence).to receive(:census_data).and_return(census_data)
end
it "is not valid when it's nil" do
residence.postal_code = nil
expect(residence).not_to be_valid
end
it "is valid with postal codes included in settings" do
residence.postal_code = "28012"
expect(residence).to be_valid
residence.postal_code = "28001"
expect(residence).to be_valid
residence.postal_code = "28100"
expect(residence).to be_valid
residence.postal_code = "28200"
expect(residence).to be_valid
residence.postal_code = "28303-455"
expect(residence).to be_valid
end
it "uses string ranges and not integer ranges" do
Setting["postal_codes"] = "0000-9999"
residence.postal_code = "02004"
expect(residence).not_to be_valid
end
it "accepts postal codes of any length" do
Setting["postal_codes"] = "AB1 3NE,815C,38000"
residence.postal_code = "AB1 3NE"
expect(residence).to be_valid
residence.postal_code = "815C"
expect(residence).to be_valid
residence.postal_code = "38000"
expect(residence).to be_valid
residence.postal_code = "815"
expect(residence).not_to be_valid
end
it "does not ignore spaces inside the postal code" do
Setting["postal_codes"] = "00001,000 05,00011"
residence.postal_code = "000 05"
expect(residence).to be_valid
residence.postal_code = "00005"
expect(residence).not_to be_valid
end
it "ignores trailing spaces in both the setting and the postal codes" do
Setting["postal_codes"] = " 00001,00002: 00005, 00011 "
residence.postal_code = " 00003 "
expect(residence).to be_valid
residence.postal_code = "00011 "
expect(residence).to be_valid
end
it "allows regular expressions" do
Setting["postal_codes"] = "007,[A-Za-z]{2}-[0-9]{3},86"
residence.postal_code = "007"
expect(residence).to be_valid
residence.postal_code = "86"
expect(residence).to be_valid
residence.postal_code = "AB-123"
expect(residence).to be_valid
residence.postal_code = "zz-789"
expect(residence).to be_valid
residence.postal_code = "006"
expect(residence).not_to be_valid
residence.postal_code = "87"
expect(residence).not_to be_valid
residence.postal_code = "AB-12"
expect(residence).not_to be_valid
residence.postal_code = "AB-1234"
expect(residence).not_to be_valid
residence.postal_code = "A-123"
expect(residence).not_to be_valid
residence.postal_code = "ABC-123"
expect(residence).not_to be_valid
residence.postal_code = "ABC-12"
expect(residence).not_to be_valid
residence.postal_code = "AB-A12"
expect(residence).not_to be_valid
residence.postal_code = "12A-12"
expect(residence).not_to be_valid
residence.postal_code = "123-12"
expect(residence).not_to be_valid
residence.postal_code = "ABC-A1"
expect(residence).not_to be_valid
residence.postal_code = "AB-123\n123"
expect(residence).not_to be_valid
end
it "is not valid with postal codes not included in settings" do
residence.postal_code = "12345"
expect(residence).not_to be_valid
residence.postal_code = "28000"
expect(residence).not_to be_valid
residence.postal_code = "28303-454"
expect(residence).not_to be_valid
residence.postal_code = "28303"
expect(residence).not_to be_valid
residence.postal_code = "28101"
expect(residence).not_to be_valid
expect(residence.errors.count).to eq 1
expect(residence.errors[:postal_code]).to eq ["Citizens from this postal code cannot participate"]
end
it "allows any postal code when the setting is blank" do
Setting["postal_codes"] = nil
residence.postal_code = "randomthing"
expect(residence).to be_valid
Setting["postal_codes"] = ""
residence.postal_code = "ABC123"
expect(residence).to be_valid
Setting["postal_codes"] = " "
residence.postal_code = "555-5"
expect(residence).to be_valid
end
end
end
describe "new" do

View File

@@ -91,6 +91,7 @@ describe "Residence" do
end
scenario "Error on postal code not in census" do
Setting["postal_codes"] = "00001:99999"
user = create(:user)
login_as(user)
@@ -102,12 +103,12 @@ describe "Residence" do
select "1997", from: "residence_date_of_birth_1i"
select "January", from: "residence_date_of_birth_2i"
select "1", from: "residence_date_of_birth_3i"
fill_in "residence_postal_code", with: "12345"
fill_in "residence_postal_code", with: "00000"
check "residence_terms_of_service"
click_button "Verify residence"
expect(page).to have_content "In order to be verified, you must be registered"
expect(page).to have_content "Citizens from this postal code cannot participate"
end
scenario "Error on census" do