diff --git a/app/controllers/idv/address_controller.rb b/app/controllers/idv/address_controller.rb index 0b114849364..21c5d98139f 100644 --- a/app/controllers/idv/address_controller.rb +++ b/app/controllers/idv/address_controller.rb @@ -11,12 +11,14 @@ class AddressController < ApplicationController def new analytics.idv_address_visit - @presenter = AddressPresenter.new(pii: idv_session.pii_from_doc) + @address_form = Idv::AddressForm.new(idv_session.pii_from_doc) + @presenter = AddressPresenter.new end def update clear_future_steps! - form_result = idv_form.submit(profile_params) + @address_form = Idv::AddressForm.new(idv_session.pii_from_doc) + form_result = @address_form.submit(profile_params) analytics.idv_address_submitted(**form_result.to_h) capture_address_edited(form_result) if form_result.success? @@ -44,14 +46,19 @@ def idv_form end def success - profile_params.each do |key, value| - idv_session.pii_from_doc[key] = value - end + idv_session.pii_from_doc = idv_session.pii_from_doc.merge( + address1: @address_form.address1, + address2: @address_form.address2, + city: @address_form.city, + state: @address_form.state, + zipcode: @address_form.zipcode, + ) redirect_to idv_verify_info_url end def failure - redirect_to idv_address_url + @presenter = AddressPresenter.new + render :new end def profile_params diff --git a/app/forms/idv/address_form.rb b/app/forms/idv/address_form.rb index 904fe0341b6..4fc800782c9 100644 --- a/app/forms/idv/address_form.rb +++ b/app/forms/idv/address_form.rb @@ -10,11 +10,11 @@ class AddressForm attr_accessor(*ATTRIBUTES) def self.model_name - ActiveModel::Name.new(self, nil, 'Address') + ActiveModel::Name.new(self, nil, 'IdvForm') end def initialize(pii) - @pii = pii + set_ivars_with_pii(pii) @address_edited = false end @@ -33,13 +33,21 @@ def submit(params) private + def set_ivars_with_pii(pii) + pii = pii.symbolize_keys + @address1 = pii[:address1] + @address2 = pii[:address2] + @city = pii[:city] + @state = pii[:state] + @zipcode = pii[:zipcode] + end + def consume_params(params) - params.each do |key, value| - raise_invalid_address_parameter_error(key) unless ATTRIBUTES.include?(key.to_sym) - send(:"#{key}=", value) - if send(key) != @pii[key] && (send(key).present? || @pii[key].present?) + ATTRIBUTES.each do |attribute_name| + if send(attribute_name).to_s != params[attribute_name].to_s @address_edited = true end + send(:"#{attribute_name}=", params[attribute_name].to_s) end end diff --git a/app/presenters/idv/address_presenter.rb b/app/presenters/idv/address_presenter.rb index 26ca19b177d..b7c9bd17ac7 100644 --- a/app/presenters/idv/address_presenter.rb +++ b/app/presenters/idv/address_presenter.rb @@ -2,14 +2,6 @@ module Idv class AddressPresenter - def initialize(pii:) - @pii = pii - end - - def pii - @pii - end - def address_line1_hint "#{I18n.t('forms.example')} 150 Calle A Apt 3" end diff --git a/app/views/idv/address/new.html.erb b/app/views/idv/address/new.html.erb index 80358753a39..29a301e8552 100644 --- a/app/views/idv/address/new.html.erb +++ b/app/views/idv/address/new.html.erb @@ -21,7 +21,7 @@ %> <%= simple_form_for( - :idv_form, + @address_form, url: idv_address_path, method: 'POST', html: { autocomplete: 'off', class: 'margin-top-5' }, @@ -35,7 +35,6 @@ hint_html: { class: @presenter.hint_class }, required: true, maxlength: 255, - input_html: { value: @presenter.pii['address1'] }, ) %> <%= render ValidatedFieldComponent.new( form: f, @@ -45,7 +44,6 @@ hint_html: { class: @presenter.hint_class }, required: false, maxlength: 255, - input_html: { value: @presenter.pii['address2'] }, ) %> <%= render ValidatedFieldComponent.new( form: f, @@ -55,7 +53,6 @@ hint_html: { class: @presenter.hint_class }, required: true, maxlength: 255, - input_html: { value: @presenter.pii['city'] }, ) %> <%= render ValidatedFieldComponent.new( form: f, @@ -63,7 +60,6 @@ collection: us_states_territories, label: t('idv.form.state'), required: true, - selected: @presenter.pii['state'], ) %>
<%# using :tel for mobile numeric keypad %> @@ -76,7 +72,7 @@ hint_html: { class: @presenter.hint_class }, required: true, pattern: '(\d{5}([\-]\d{4})?)', - input_html: { value: @presenter.pii['zipcode'], class: 'zipcode' }, + input_html: { class: 'zipcode' }, error_messages: { patternMismatch: t('idv.errors.pattern_mismatch.zipcode'), }, diff --git a/spec/controllers/idv/address_controller_spec.rb b/spec/controllers/idv/address_controller_spec.rb index 1f4f2025213..ace2bc39578 100644 --- a/spec/controllers/idv/address_controller_spec.rb +++ b/spec/controllers/idv/address_controller_spec.rb @@ -97,5 +97,18 @@ error_details: nil }, ) end + + context 'with invalid params' do + render_views + + it 'renders errors if they occur' do + params[:idv_form][:zipcode] = 'this is invalid' + + put :update, params: params + + expect(response).to render_template(:new) + expect(response.body).to include(t('idv.errors.pattern_mismatch.zipcode')) + end + end end end diff --git a/spec/forms/idv/address_form_spec.rb b/spec/forms/idv/address_form_spec.rb new file mode 100644 index 00000000000..e8287f6b073 --- /dev/null +++ b/spec/forms/idv/address_form_spec.rb @@ -0,0 +1,78 @@ +require 'rails_helper' + +RSpec.describe Idv::AddressForm do + let(:pii) do + { + first_name: 'Test', + last_name: 'McTesterson', + address1: '123 Main St', + address2: nil, + city: 'Testertown', + state: 'TX', + zipcode: '11111', + } + end + + let(:params) do + { + address1: '456 Other St', + address2: 'Apt 1', + city: 'McTestville', + state: 'IL', + zipcode: '22222', + } + end + + it 'is initialized with values from the hash in the initializer' do + address_form = Idv::AddressForm.new(pii) + expect(address_form.address1).to eq('123 Main St') + expect(address_form.address2).to eq(nil) + expect(address_form.city).to eq('Testertown') + expect(address_form.state).to eq('TX') + expect(address_form.zipcode).to eq('11111') + end + + describe '#submit' do + context 'with valid params' do + it 'returns a successful result' do + result = Idv::AddressForm.new(pii).submit(params) + + expect(result.success?).to eq(true) + expect(result.extra[:address_edited]).to eq(true) + end + end + + context 'with a malformed param' do + it 'returns an error result' do + params[:zipcode] = 'this is not a valid zipcde' + + result = Idv::AddressForm.new(pii).submit(params) + + expect(result.success?).to eq(false) + expect(result.errors[:zipcode]).to be_present + end + end + + context 'with a missing params' do + it 'returns an error result' do + params.delete(:zipcode) + + result = Idv::AddressForm.new(pii).submit(params) + + expect(result.success?).to eq(false) + expect(result.errors[:zipcode]).to be_present + end + end + + context 'the user submits the same address that is in the pii' do + it 'does not set `address_edited` to true' do + params = pii.slice(:address1, :address2, :city, :state, :zipcode) + + result = Idv::AddressForm.new(pii).submit(params) + + expect(result.success?).to eq(true) + expect(result.extra[:address_edited]).to eq(false) + end + end + end +end diff --git a/spec/views/idv/address/new.html.erb_spec.rb b/spec/views/idv/address/new.html.erb_spec.rb index 82d6f818c1c..2e2b7e0912f 100644 --- a/spec/views/idv/address/new.html.erb_spec.rb +++ b/spec/views/idv/address/new.html.erb_spec.rb @@ -4,7 +4,8 @@ let(:parsed_page) { Nokogiri::HTML.parse(rendered) } before do - assign(:presenter, Idv::AddressPresenter.new(pii: {})) + assign(:presenter, Idv::AddressPresenter.new) + assign(:address_form, Idv::AddressForm.new({})) render end