From f4512b2117cf3f1e1d3b9e2ab402c1b3600f864d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Concepci=C3=B3n=20Rodr=C3=ADguez?= Date: Mon, 13 Nov 2017 14:01:37 +0000 Subject: [PATCH 1/9] Redefine postal code verification methods to use setting config parameter --- app/models/custom/verification/residence.rb | 26 ----------- app/models/setting.rb | 1 + app/models/verification/residence.rb | 23 ++++++++++ config/locales/en/settings.yml | 1 + config/locales/es/settings.yml | 1 + .../custom/verification/residence_spec.rb | 29 ------------- spec/models/verification/residence_spec.rb | 43 +++++++++++++++++++ spec/system/verification/residence_spec.rb | 2 +- 8 files changed, 70 insertions(+), 56 deletions(-) delete mode 100644 app/models/custom/verification/residence.rb delete mode 100644 spec/models/custom/verification/residence_spec.rb diff --git a/app/models/custom/verification/residence.rb b/app/models/custom/verification/residence.rb deleted file mode 100644 index 598c71c38..000000000 --- a/app/models/custom/verification/residence.rb +++ /dev/null @@ -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 diff --git a/app/models/setting.rb b/app/models/setting.rb index 7fe170e33..8c813dcc2 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -177,6 +177,7 @@ class Setting < ApplicationRecord "machine_learning.comments_summary": false, "machine_learning.related_content": false, "machine_learning.tags": false, + "postal_codes": "00001-99999", "remote_census.general.endpoint": "", "remote_census.request.method_name": "", "remote_census.request.structure": "", diff --git a/app/models/verification/residence.rb b/app/models/verification/residence.rb index 9ca30b72c..062e191a1 100644 --- a/app/models/verification/residence.rb +++ b/app/models/verification/residence.rb @@ -17,6 +17,9 @@ class Verification::Residence 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) @@ -73,6 +76,20 @@ class Verification::Residence @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 @@ -88,4 +105,10 @@ class Verification::Residence def clean_document_number self.document_number = document_number.gsub(/[^a-z0-9]+/i, "").upcase if document_number.present? end + + def valid_postal_code? + postal_codes = Setting["postal_codes"].gsub("-", "..").split(",") + postal_codes = postal_codes.map { |i| eval(i) }.map { |i| i.is_a?(Range) ? i.to_a : [i] }.flatten + postal_code.to_i.in?(postal_codes) + end end diff --git a/config/locales/en/settings.yml b/config/locales/en/settings.yml index 24679d5a0..d94498cbf 100644 --- a/config/locales/en/settings.yml +++ b/config/locales/en/settings.yml @@ -60,6 +60,7 @@ en: meta_keywords_description: '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" 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. diff --git a/config/locales/es/settings.yml b/config/locales/es/settings.yml index 820aa25f8..d37261848 100644 --- a/config/locales/es/settings.yml +++ b/config/locales/es/settings.yml @@ -60,6 +60,7 @@ es: meta_keywords_description: 'Palabras clave , 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" 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 diff --git a/spec/models/custom/verification/residence_spec.rb b/spec/models/custom/verification/residence_spec.rb deleted file mode 100644 index 493e60b91..000000000 --- a/spec/models/custom/verification/residence_spec.rb +++ /dev/null @@ -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 diff --git a/spec/models/verification/residence_spec.rb b/spec/models/verification/residence_spec.rb index f34becd1f..bc6995f59 100644 --- a/spec/models/verification/residence_spec.rb +++ b/spec/models/verification/residence_spec.rb @@ -46,6 +46,49 @@ describe Verification::Residence do residence.terms_of_service = nil expect(residence).not_to be_valid end + + describe "postal code" do + before { Setting["postal_codes"] = "28001-28100,28200" } + + it "is valid with postal codes included in settings" do + residence.postal_code = "28012" + residence.valid? + + expect(residence.errors[:postal_code]).to be_empty + + residence.postal_code = "28001" + residence.valid? + + expect(residence.errors[:postal_code]).to be_empty + + residence.postal_code = "28100" + residence.valid? + + expect(residence.errors[:postal_code]).to be_empty + + residence.postal_code = "28200" + residence.valid? + + expect(residence.errors[:postal_code]).to be_empty + end + + it "is not valid with postal codes not included in settings" do + residence.postal_code = "12345" + residence.valid? + + expect(residence.errors[:postal_code].size).to eq(1) + + residence.postal_code = "28000" + residence.valid? + + expect(residence.errors[:postal_code].size).to eq(1) + + residence.postal_code = "28101" + residence.valid? + + expect(residence.errors[:postal_code]).to eq ["In order to be verified, you must be registered."] + end + end end describe "new" do diff --git a/spec/system/verification/residence_spec.rb b/spec/system/verification/residence_spec.rb index 7b72e5523..25bdb70df 100644 --- a/spec/system/verification/residence_spec.rb +++ b/spec/system/verification/residence_spec.rb @@ -102,7 +102,7 @@ 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" From 006269a94b325827b5b35ae4b641262d35b34c2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 13 Nov 2021 18:09:00 +0100 Subject: [PATCH 2/9] Simplify tests validating postal codes We weren't using the `be_valid` matcher because we had errors in the census data. Removing the `before_validation` callback and using a method to get the census data instead allows us to stub the `census_data` method in the tests, and so we can use the `be_valid` matcher instead of calling `valid?` manually and then checking for errors. --- app/models/verification/residence.rb | 16 ++++------ spec/models/verification/residence_spec.rb | 37 ++++++++++------------ 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/app/models/verification/residence.rb b/app/models/verification/residence.rb index 062e191a1..935f6bfb0 100644 --- a/app/models/verification/residence.rb +++ b/app/models/verification/residence.rb @@ -5,8 +5,6 @@ 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 @@ -69,11 +67,11 @@ 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 @@ -92,14 +90,14 @@ class Verification::Residence 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 diff --git a/spec/models/verification/residence_spec.rb b/spec/models/verification/residence_spec.rb index bc6995f59..ae4b2b829 100644 --- a/spec/models/verification/residence_spec.rb +++ b/spec/models/verification/residence_spec.rb @@ -48,44 +48,39 @@ describe Verification::Residence do end describe "postal code" do - before { Setting["postal_codes"] = "28001-28100,28200" } + before do + Setting["postal_codes"] = "28001-28100,28200" + + 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 valid with postal codes included in settings" do residence.postal_code = "28012" - residence.valid? - - expect(residence.errors[:postal_code]).to be_empty + expect(residence).to be_valid residence.postal_code = "28001" - residence.valid? - - expect(residence.errors[:postal_code]).to be_empty + expect(residence).to be_valid residence.postal_code = "28100" - residence.valid? - - expect(residence.errors[:postal_code]).to be_empty + expect(residence).to be_valid residence.postal_code = "28200" - residence.valid? - - expect(residence.errors[:postal_code]).to be_empty + expect(residence).to be_valid end it "is not valid with postal codes not included in settings" do residence.postal_code = "12345" - residence.valid? - - expect(residence.errors[:postal_code].size).to eq(1) + expect(residence).not_to be_valid residence.postal_code = "28000" - residence.valid? - - expect(residence.errors[:postal_code].size).to eq(1) + expect(residence).not_to be_valid residence.postal_code = "28101" - residence.valid? - + expect(residence).not_to be_valid + expect(residence.errors.count).to eq 1 expect(residence.errors[:postal_code]).to eq ["In order to be verified, you must be registered."] end end From edc56b1e1fa2cf785c4f5e930a4d70be3006889e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 13 Nov 2021 18:23:57 +0100 Subject: [PATCH 3/9] Avoid using `eval` in postal code validation We were getting a warning by Rubocop because we were using eval with a string defined by administrators, which in theory could be dangerous. --- app/models/verification/residence.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/models/verification/residence.rb b/app/models/verification/residence.rb index 935f6bfb0..39ddf8dd7 100644 --- a/app/models/verification/residence.rb +++ b/app/models/verification/residence.rb @@ -105,8 +105,12 @@ class Verification::Residence end def valid_postal_code? - postal_codes = Setting["postal_codes"].gsub("-", "..").split(",") - postal_codes = postal_codes.map { |i| eval(i) }.map { |i| i.is_a?(Range) ? i.to_a : [i] }.flatten - postal_code.to_i.in?(postal_codes) + Setting["postal_codes"].split(",").any? do |code_or_range| + if code_or_range.include?("-") + Range.new(*code_or_range.split("-").map(&:to_i)).include?(postal_code.to_i) + else + postal_code == code_or_range + end + end end end From b8b433626633c6f83e9b140297889830d3f2a667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 13 Nov 2021 18:56:11 +0100 Subject: [PATCH 4/9] Compare postal codes with strings and not integers We can now get rid of the rule forcing a length of 5 digits, which doesn't apply to all countries. --- app/models/verification/residence.rb | 3 +-- spec/models/verification/residence_spec.rb | 24 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/models/verification/residence.rb b/app/models/verification/residence.rb index 39ddf8dd7..384bbe474 100644 --- a/app/models/verification/residence.rb +++ b/app/models/verification/residence.rb @@ -10,7 +10,6 @@ class Verification::Residence 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 @@ -107,7 +106,7 @@ class Verification::Residence def valid_postal_code? Setting["postal_codes"].split(",").any? do |code_or_range| if code_or_range.include?("-") - Range.new(*code_or_range.split("-").map(&:to_i)).include?(postal_code.to_i) + Range.new(*code_or_range.split("-")).include?(postal_code) else postal_code == code_or_range end diff --git a/spec/models/verification/residence_spec.rb b/spec/models/verification/residence_spec.rb index ae4b2b829..895ea89bf 100644 --- a/spec/models/verification/residence_spec.rb +++ b/spec/models/verification/residence_spec.rb @@ -71,6 +71,30 @@ describe Verification::Residence do 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 "is not valid with postal codes not included in settings" do residence.postal_code = "12345" expect(residence).not_to be_valid From 5cc10cbadff3da89a68c82e193a0afdd8079bdb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sun, 14 Nov 2021 15:44:11 +0100 Subject: [PATCH 5/9] Allow dashes in postal codes In some countries, postal codes are defined with a dash in the middle, so we're using a colon to define ranges instead. We could also use two dots, like in Ruby ranges, but IMHO this would cause typos since people would enter codes separated with three dots or just one dot. --- app/models/setting.rb | 2 +- app/models/verification/residence.rb | 4 ++-- config/locales/en/settings.yml | 1 + config/locales/es/settings.yml | 1 + spec/models/verification/residence_spec.rb | 11 ++++++++++- 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/app/models/setting.rb b/app/models/setting.rb index 8c813dcc2..0488c2d2d 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -177,7 +177,7 @@ class Setting < ApplicationRecord "machine_learning.comments_summary": false, "machine_learning.related_content": false, "machine_learning.tags": false, - "postal_codes": "00001-99999", + "postal_codes": "00001:99999", "remote_census.general.endpoint": "", "remote_census.request.method_name": "", "remote_census.request.structure": "", diff --git a/app/models/verification/residence.rb b/app/models/verification/residence.rb index 384bbe474..d254ccaa6 100644 --- a/app/models/verification/residence.rb +++ b/app/models/verification/residence.rb @@ -105,8 +105,8 @@ class Verification::Residence def valid_postal_code? Setting["postal_codes"].split(",").any? do |code_or_range| - if code_or_range.include?("-") - Range.new(*code_or_range.split("-")).include?(postal_code) + if code_or_range.include?(":") + Range.new(*code_or_range.split(":")).include?(postal_code) else postal_code == code_or_range end diff --git a/config/locales/en/settings.yml b/config/locales/en/settings.yml index d94498cbf..0e8d1218b 100644 --- a/config/locales/en/settings.yml +++ b/config/locales/en/settings.yml @@ -61,6 +61,7 @@ en: 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." 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. diff --git a/config/locales/es/settings.yml b/config/locales/es/settings.yml index d37261848..631ef0603 100644 --- a/config/locales/es/settings.yml +++ b/config/locales/es/settings.yml @@ -61,6 +61,7 @@ es: 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." 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 diff --git a/spec/models/verification/residence_spec.rb b/spec/models/verification/residence_spec.rb index 895ea89bf..cdfee621b 100644 --- a/spec/models/verification/residence_spec.rb +++ b/spec/models/verification/residence_spec.rb @@ -49,7 +49,7 @@ describe Verification::Residence do describe "postal code" do before do - Setting["postal_codes"] = "28001-28100,28200" + 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 } @@ -69,6 +69,9 @@ describe Verification::Residence do 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 @@ -102,6 +105,12 @@ describe Verification::Residence do 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 From 35e0477e0309ee2584dc101df24888e50603a8c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sun, 14 Nov 2021 15:56:55 +0100 Subject: [PATCH 6/9] Ignore trailing spaces in postal codes verification This way both administrators and regular citizens have a certain margin of error when entering the postal codes. --- app/models/verification/residence.rb | 4 ++-- spec/models/verification/residence_spec.rb | 28 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/app/models/verification/residence.rb b/app/models/verification/residence.rb index d254ccaa6..82cc2d046 100644 --- a/app/models/verification/residence.rb +++ b/app/models/verification/residence.rb @@ -106,9 +106,9 @@ class Verification::Residence def valid_postal_code? Setting["postal_codes"].split(",").any? do |code_or_range| if code_or_range.include?(":") - Range.new(*code_or_range.split(":")).include?(postal_code) + Range.new(*code_or_range.split(":").map(&:strip)).include?(postal_code&.strip) else - postal_code == code_or_range + postal_code&.strip == code_or_range.strip end end end diff --git a/spec/models/verification/residence_spec.rb b/spec/models/verification/residence_spec.rb index cdfee621b..7c3e671e3 100644 --- a/spec/models/verification/residence_spec.rb +++ b/spec/models/verification/residence_spec.rb @@ -57,6 +57,12 @@ describe Verification::Residence do 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 @@ -98,6 +104,28 @@ describe Verification::Residence do 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 "is not valid with postal codes not included in settings" do residence.postal_code = "12345" expect(residence).not_to be_valid From c2e95f6b86fa59452e218ae091f620ef55063d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sun, 14 Nov 2021 16:46:05 +0100 Subject: [PATCH 7/9] Allow any postal code by default Due to the way Madrid handled postal code validations (see issue 533), by default we were requiring everyone to validate against the local census *and* to specify valid postal codes. This could be useful in some cases, but in other cases, the census validation will be enough and there'll be no need to manually define the valid postal codes. Besides, some CONSUL installations are used in organizations or political parties where the postal code validation doesn't make sense. --- app/models/setting.rb | 2 +- app/models/verification/residence.rb | 2 ++ config/locales/en/settings.yml | 2 +- config/locales/es/settings.yml | 2 +- spec/models/verification/residence_spec.rb | 17 +++++++++++++++++ spec/system/verification/residence_spec.rb | 1 + 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/app/models/setting.rb b/app/models/setting.rb index 0488c2d2d..a35d8b6c2 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -177,7 +177,7 @@ class Setting < ApplicationRecord "machine_learning.comments_summary": false, "machine_learning.related_content": false, "machine_learning.tags": false, - "postal_codes": "00001:99999", + "postal_codes": "", "remote_census.general.endpoint": "", "remote_census.request.method_name": "", "remote_census.request.structure": "", diff --git a/app/models/verification/residence.rb b/app/models/verification/residence.rb index 82cc2d046..d782fbb6f 100644 --- a/app/models/verification/residence.rb +++ b/app/models/verification/residence.rb @@ -104,6 +104,8 @@ class Verification::Residence 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) diff --git a/config/locales/en/settings.yml b/config/locales/en/settings.yml index 0e8d1218b..fa9287be3 100644 --- a/config/locales/en/settings.yml +++ b/config/locales/en/settings.yml @@ -61,7 +61,7 @@ en: 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." + 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. diff --git a/config/locales/es/settings.yml b/config/locales/es/settings.yml index 631ef0603..146213632 100644 --- a/config/locales/es/settings.yml +++ b/config/locales/es/settings.yml @@ -61,7 +61,7 @@ es: 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." + 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 diff --git a/spec/models/verification/residence_spec.rb b/spec/models/verification/residence_spec.rb index 7c3e671e3..26196c3ce 100644 --- a/spec/models/verification/residence_spec.rb +++ b/spec/models/verification/residence_spec.rb @@ -144,6 +144,23 @@ describe Verification::Residence do expect(residence.errors.count).to eq 1 expect(residence.errors[:postal_code]).to eq ["In order to be verified, you must be registered."] 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 diff --git a/spec/system/verification/residence_spec.rb b/spec/system/verification/residence_spec.rb index 25bdb70df..f2f7e2700 100644 --- a/spec/system/verification/residence_spec.rb +++ b/spec/system/verification/residence_spec.rb @@ -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) From a79bbac894289b68c4db54a8921cb2029b50e45b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 27 Nov 2021 17:45:25 +0100 Subject: [PATCH 8/9] Fix invalid postal code message We were using the word "registered" in English as an equivalent of the Spanish word "empadronado". However, the term "registered" is very confusing because it might be understood as being registered in the CONSUL website. In the message, we're saying "cannot participate" in order to make the message consistent with the message regarding the required age. --- config/locales/en/verification.yml | 2 +- config/locales/es/verification.yml | 2 +- spec/models/verification/residence_spec.rb | 2 +- spec/system/verification/residence_spec.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/locales/en/verification.yml b/config/locales/en/verification.yml index cd0201d63..e1bdb2883 100644 --- a/config/locales/en/verification.yml +++ b/config/locales/en/verification.yml @@ -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 diff --git a/config/locales/es/verification.yml b/config/locales/es/verification.yml index 55123724d..c3191438b 100644 --- a/config/locales/es/verification.yml +++ b/config/locales/es/verification.yml @@ -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 diff --git a/spec/models/verification/residence_spec.rb b/spec/models/verification/residence_spec.rb index 26196c3ce..a33f8aaba 100644 --- a/spec/models/verification/residence_spec.rb +++ b/spec/models/verification/residence_spec.rb @@ -142,7 +142,7 @@ describe Verification::Residence do residence.postal_code = "28101" expect(residence).not_to be_valid expect(residence.errors.count).to eq 1 - expect(residence.errors[:postal_code]).to eq ["In order to be verified, you must be registered."] + 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 diff --git a/spec/system/verification/residence_spec.rb b/spec/system/verification/residence_spec.rb index f2f7e2700..285cd9d71 100644 --- a/spec/system/verification/residence_spec.rb +++ b/spec/system/verification/residence_spec.rb @@ -108,7 +108,7 @@ describe "Residence" do 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 From d6b85a038c36e3b4139364b8cc3a51de6fc5a436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Sat, 27 Nov 2021 18:48:42 +0100 Subject: [PATCH 9/9] Allow regular expressions in postal codes Programmers can take advantage of this feature when defining custom default settings. And, since many CONSUL installations had custom changes in the `custom/verification/residence.rb` model and those changes might use regular expressions, we're making it easier to migrate that code to the new system to define valid postal codes. We aren't documenting this feature in the description in the admin section because most administrators don't know what regular expressions are. Note that, in order to simplify the setting, we already define the `/\A` and `\Z/` characters. So, if the custom code had something like `postal_code =~ /^280/`, the setting would have to be "280*" (without the quotes) or, in order to comply with a length validation, "280[0-9]{2}" (without the quotes). --- app/models/verification/residence.rb | 2 +- spec/models/verification/residence_spec.rb | 52 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/app/models/verification/residence.rb b/app/models/verification/residence.rb index d782fbb6f..539c3ef12 100644 --- a/app/models/verification/residence.rb +++ b/app/models/verification/residence.rb @@ -110,7 +110,7 @@ class Verification::Residence if code_or_range.include?(":") Range.new(*code_or_range.split(":").map(&:strip)).include?(postal_code&.strip) else - postal_code&.strip == code_or_range.strip + /\A#{code_or_range.strip}\Z/.match?(postal_code&.strip) end end end diff --git a/spec/models/verification/residence_spec.rb b/spec/models/verification/residence_spec.rb index a33f8aaba..e9733c7d7 100644 --- a/spec/models/verification/residence_spec.rb +++ b/spec/models/verification/residence_spec.rb @@ -126,6 +126,58 @@ describe Verification::Residence do 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