Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 35 additions & 19 deletions app/forms/idv/inherited_proofing/va/form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,45 @@ def namespaced_model_name

# Returns the field names based on the validators we've set up.
def field_names
@field_names ||= validators.filter_map do |validator|
validator.attributes.first
end&.flatten&.uniq&.sort
@field_names ||= fields.keys
end

def fields
@fields ||= {
first_name: { required: true },
last_name: { required: true },
phone: { required: false },
birth_date: { required: true },
ssn: { required: true },
address_street: { required: true },
address_street2: { required: false },
address_city: { required: false },
address_state: { required: false },
address_country: { required: false },
address_zip: { required: true },
}
end

def required_fields
@required_fields ||= fields.filter_map do |field_name, options|
field_name if options[:required]
end
end

def optional_fields
@optional_fields ||= fields.filter_map do |field_name, options|
field_name unless options[:required]
end
end
end

private_class_method :namespaced_model_name
private_class_method :namespaced_model_name, :required_fields, :optional_fields

attr_reader :payload_hash

validate :validate_field_names

validates :first_name, presence: true, length: { maximum: 255 }
validates :last_name, presence: true, length: { maximum: 255 }
validates :phone, length: { maximum: 11 }
validates :birth_date, presence: true
validates :ssn, presence: true
validates :address_street, presence: true, length: { maximum: 255 }
validates :address_street2, length: { maximum: 255 }
validates :address_city, length: { maximum: 255 }
validates :address_state, length: { maximum: 2 }
validates :address_country, length: { maximum: 255 }
validates :address_zip, presence: true
validates_format_of :address_zip, with: /\A\d{5}(-?\d{4})?\z/,
message: I18n.t('idv.errors.pattern_mismatch.zipcode'),
allow_blank: false
required_fields.each { |required_field| validates(required_field, presence: true) }

# This must be performed after our validators are defined.
attr_accessor(*self.field_names)
Expand Down Expand Up @@ -72,6 +85,9 @@ def submit
# Populates our field data from the payload hash.
def populate_field_data
payload_field_info.each do |field_name, field_info|
# Ignore fields we're not interested in.
next unless respond_to? field_name

value = payload_hash.dig(
*[field_info[:namespace],
field_info[:field_name]].flatten.compact,
Expand All @@ -84,7 +100,7 @@ def populate_field_data
def validate_field_names
self.class.field_names.each do |field_name|
next if payload_field_info.key? field_name
errors.add(field_name, 'field is missing', type: missing_required_field)
errors.add(field_name, 'field is missing', type: :missing_required_field)
end
end

Expand Down
97 changes: 91 additions & 6 deletions spec/forms/idv/inherited_proofing/va/form_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,17 +88,102 @@
end

describe '#validate' do
context 'with a valid payload' do
it 'returns true'
context 'with valid payload data' do
it 'returns true' do
expect(subject.validate).to eq true
end
end

context 'with an invalid payload' do
context 'with invalid payload data' do
context 'when the payload has missing fields' do
it 'returns false'
let(:payload_hash) do
{
xfirst_name: 'Henry',
xlast_name: 'Ford',
xphone: '12222222222',
xbirth_date: '2000-01-01',
xssn: '111223333',
xaddress: {
xstreet: '1234 Model Street',
xstreet2: 'Suite A',
xcity: 'Detroit',
xstate: 'MI',
xcountry: 'United States',
xzip: '12345',
},
}
end

let(:expected_error_messages) do
[
# Required field presence
'First name field is missing',
'Last name field is missing',
'Phone field is missing',
'Birth date field is missing',
'Ssn field is missing',
'Address street field is missing',
'Address street2 field is missing',
'Address city field is missing',
'Address state field is missing',
'Address country field is missing',
'Address zip field is missing',
]
end

it 'returns false' do
expect(subject.validate).to eq false
end

it 'adds the correct error messages for missing fields' do
subject.validate
expect(
expected_error_messages.all? do |error_message|
subject.errors.full_messages.include? error_message
end,
).to eq true
end
end

context 'when the payload has invalid field data' do
it 'returns false'
context 'when the payload has missing required field data' do
let(:payload_hash) do
{
first_name: nil,
last_name: '',
phone: nil,
birth_date: '',
ssn: nil,
address: {
street: '',
street2: nil,
city: '',
state: nil,
country: '',
zip: nil,
},
}
end

let(:expected_error_messages) do
[
# Required field data presence
'First name Please fill in this field.',
'Last name Please fill in this field.',
'Birth date Please fill in this field.',
'Ssn Please fill in this field.',
'Address street Please fill in this field.',
'Address zip Please fill in this field.',
]
end

it 'returns false' do
expect(subject.validate).to eq false
end

it 'adds the correct error messages for required fields that are missing data' do
subject.validate
expect(subject.errors.full_messages).to match_array expected_error_messages
end
end
end
end
Expand Down