diff --git a/app/models/contact/ident.rb b/app/models/contact/ident.rb index 5cd26f17b..fdbaa0e9f 100644 --- a/app/models/contact/ident.rb +++ b/app/models/contact/ident.rb @@ -5,8 +5,11 @@ class Contact::Ident attr_accessor :type attr_accessor :country_code - validates :code, presence: true, code: true + validates :code, presence: true + validates :code, national_id: true, if: :national_id? + validates :code, reg_no: true, if: :reg_no? validates :code, iso8601: { date_only: true }, if: :birthday? + validates :type, presence: true, inclusion: { in: proc { types } } validates :country_code, presence: true, iso31661_alpha2: true validate :mismatched diff --git a/app/validators/contact/ident/code_validator.rb b/app/validators/contact/ident/code_validator.rb deleted file mode 100644 index 255867a75..000000000 --- a/app/validators/contact/ident/code_validator.rb +++ /dev/null @@ -1,30 +0,0 @@ -class Contact::Ident::CodeValidator < ActiveModel::EachValidator - def validate_each(record, attribute, value) - return unless record.country_code == 'EE' - - if record.national_id? && !valid_national_id_ee?(value) - record.errors.add(attribute, - :invalid_national_id, - country: record.country) - end - - if record.reg_no? - validator = ActiveModel::Validations:: - FormatValidator.new(with: reg_no_ee_format, - attributes: attribute, - message: :invalid_reg_no, - country: record.country) - validator.validate(record) - end - end - - private - - def reg_no_ee_format - /\A[0-9]{8}\z/ - end - - def valid_national_id_ee?(ident) - Isikukood.new(ident).valid? - end -end diff --git a/app/validators/contact/ident/national_id_validator.rb b/app/validators/contact/ident/national_id_validator.rb new file mode 100644 index 000000000..89746169f --- /dev/null +++ b/app/validators/contact/ident/national_id_validator.rb @@ -0,0 +1,22 @@ +class Contact::Ident::NationalIDValidator < ActiveModel::EachValidator + def self.country_specific_validations + { + Country.new('EE') => proc { |code| Isikukood.new(code).valid? }, + } + end + + def validate_each(record, attribute, value) + validation = validation_for(record.country) + + return unless validation + + valid = validation.call(value) + record.errors.add(attribute, :invalid_national_id, country: record.country) unless valid + end + + private + + def validation_for(country) + self.class.country_specific_validations[country] + end +end diff --git a/app/validators/contact/ident/reg_no_validator.rb b/app/validators/contact/ident/reg_no_validator.rb new file mode 100644 index 000000000..611d13301 --- /dev/null +++ b/app/validators/contact/ident/reg_no_validator.rb @@ -0,0 +1,21 @@ +class Contact::Ident::RegNoValidator < ActiveModel::EachValidator + def self.country_specific_formats + { + Country.new('EE') => /\A[0-9]{8}\z/, + } + end + + def validate_each(record, attribute, value) + format = format_for(record.country) + + return unless format + + record.errors.add(attribute, :invalid_reg_no, country: record.country) unless value =~ format + end + + private + + def format_for(country) + self.class.country_specific_formats[country] + end +end diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index b4eccb451..18f593685 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -12,4 +12,5 @@ ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.acronym 'DNS' + inflect.acronym 'ID' end diff --git a/spec/requests/epp/contact/create/ident_spec.rb b/spec/requests/epp/contact/create/ident_spec.rb index b0a7254d8..e02fc9c52 100644 --- a/spec/requests/epp/contact/create/ident_spec.rb +++ b/spec/requests/epp/contact/create/ident_spec.rb @@ -88,7 +88,7 @@ RSpec.describe 'EPP contact:create' do end end - context 'when code is invalid' do + context 'when code is not valid national id' do let(:request_xml) { <<-XML @@ -104,7 +104,7 @@ RSpec.describe 'EPP contact:create' do - invalid + invalid @@ -112,6 +112,15 @@ RSpec.describe 'EPP contact:create' do XML } + before do + country_specific_validations = { + Country.new('DE') => proc { false }, + } + + allow(Contact::Ident::NationalIDValidator).to receive(:country_specific_validations) + .and_return(country_specific_validations) + end + it 'does not create a contact' do expect { request }.to_not change { Contact.count } end @@ -119,11 +128,54 @@ RSpec.describe 'EPP contact:create' do specify do request - message = 'Ident code does not conform to national identification number format of Estonia' + message = 'Ident code does not conform to national identification number format of Germany' expect(epp_response).to have_result(:param_syntax_error, message) end end + context 'when code is not valid registration number' do + let(:request_xml) { <<-XML + + + + + + + test + + +1.2 + test@test.com + + + + + invalid + + + + + XML + } + + before do + country_specific_formats = { + Country.new('DE') => /\Avalid\z/, + } + + allow(Contact::Ident::RegNoValidator).to receive(:country_specific_formats).and_return(country_specific_formats) + end + + it 'does not create a contact' do + expect { request }.to_not change { Contact.count } + end + + specify do + request + expect(epp_response).to have_result(:param_syntax_error, + 'Ident code does not conform to registration number format of Germany') + end + end + context 'when country code is absent' do let(:request_xml) { <<-XML