diff --git a/app/controllers/idv/in_person/address_search_controller.rb b/app/controllers/idv/in_person/address_search_controller.rb new file mode 100644 index 00000000000..f1bc0151f2f --- /dev/null +++ b/app/controllers/idv/in_person/address_search_controller.rb @@ -0,0 +1,31 @@ +module Idv + module InPerson + class AddressSearchController < ApplicationController + include RenderConditionConcern + + check_or_render_not_found -> { IdentityConfig.store.arcgis_search_enabled } + + def index + render json: addresses + end + + protected + + def addresses + suggestion = geocoder.suggest(permitted_params[:address]).first + return [] unless suggestion + geocoder.find_address_candidates(suggestion.magic_key).slice(0, 1) + rescue Faraday::ConnectionFailed + [] + end + + def geocoder + @geocoder ||= ArcgisApi::Geocoder.new + end + + def permitted_params + params.permit(:address) + end + end + end +end diff --git a/config/application.yml.default b/config/application.yml.default index c673ada06ce..e3c5993bcc3 100644 --- a/config/application.yml.default +++ b/config/application.yml.default @@ -44,6 +44,7 @@ address_identity_proofing_supported_country_codes: '["AS", "GU", "MP", "PR", "US arcgis_api_root_url: 'https://gis.gsa.gov' arcgis_api_username: '' arcgis_api_password: '' +arcgis_search_enabled: false asset_host: '' async_wait_timeout_seconds: 60 async_stale_job_timeout_seconds: 300 diff --git a/config/routes.rb b/config/routes.rb index e5544dc37bd..af2f5ef6310 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -350,6 +350,7 @@ as: :in_person_ready_to_verify get '/in_person/usps_locations' => 'in_person/usps_locations#index' put '/in_person/usps_locations' => 'in_person/usps_locations#update' + post '/in_person/addresses' => 'in_person/address_search#index' get '/in_person/:step' => 'in_person#show', as: :in_person_step put '/in_person/:step' => 'in_person#update' diff --git a/lib/identity_config.rb b/lib/identity_config.rb index 17652ad527b..bf599877041 100644 --- a/lib/identity_config.rb +++ b/lib/identity_config.rb @@ -108,6 +108,7 @@ def self.build_store(config_map) config.add(:arcgis_api_root_url, type: :string) config.add(:arcgis_api_username, type: :string) config.add(:arcgis_api_password, type: :string) + config.add(:arcgis_search_enabled, type: :boolean) config.add(:aws_http_retry_limit, type: :integer) config.add(:aws_http_retry_max_delay, type: :integer) config.add(:aws_http_timeout, type: :integer) diff --git a/spec/controllers/idv/in_person/address_search_controller_spec.rb b/spec/controllers/idv/in_person/address_search_controller_spec.rb new file mode 100644 index 00000000000..5c6e51aa85f --- /dev/null +++ b/spec/controllers/idv/in_person/address_search_controller_spec.rb @@ -0,0 +1,86 @@ +require 'rails_helper' + +describe Idv::InPerson::AddressSearchController do + include IdvHelper + + let(:user) { create(:user) } + let(:sp) { nil } + let(:arcgis_search_enabled) { true } + + before do + stub_analytics + stub_sign_in(user) if user + allow(IdentityConfig.store).to receive(:arcgis_search_enabled). + and_return(arcgis_search_enabled) + allow(controller).to receive(:current_sp).and_return(sp) + end + + describe '#index' do + let(:geocoder) { double('Geocoder') } + let(:suggestions) do + [ + OpenStruct.new({ magic_key: 'a' }), + ] + end + + let(:addresses) do + [ + { name: 'Address 1' }, + { name: 'Address 2' }, + { name: 'Address 3' }, + { name: 'Address 4' }, + ] + end + subject(:response) { get :index } + + before do + allow(controller).to receive(:geocoder).and_return(geocoder) + allow(geocoder).to receive(:find_address_candidates).and_return(addresses) + allow(geocoder).to receive(:suggest).and_return(suggestions) + end + + context 'with successful fetch' do + it 'gets successful response' do + response = get :index + json = response.body + addresses = JSON.parse(json) + expect(addresses.length).to eq 1 + end + + context 'with no suggestions' do + let(:suggestions) do + [] + end + + it 'returns empty array' do + response = get :index + json = response.body + addresses = JSON.parse(json) + expect(addresses.length).to eq 0 + end + end + end + + context 'with unsuccessful fetch' do + before do + exception = Faraday::ConnectionFailed.new('error') + allow(geocoder).to receive(:suggest).and_raise(exception) + end + + it 'gets an empty pilot response' do + response = get :index + json = response.body + addresses = JSON.parse(json) + expect(addresses.length).to eq 0 + end + end + + context 'with feature disabled' do + let(:arcgis_search_enabled) { false } + + it 'renders 404' do + expect(response.status).to eq(404) + end + end + end +end