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
40 changes: 40 additions & 0 deletions app/controllers/idv/in_person/public/usps_locations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,34 @@
module Idv
module InPerson
module Public
class UspsLocationsError < StandardError
def initialize
super('Unsupported characters in address field.')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no biggie, but I noticed sometimes there's a pattern to add these error messages as constants. Just wanted to pop that in here as food for thought but non-blocking.

end
end

class UspsLocationsController < ApplicationController
skip_forgery_protection

include IppHelper

rescue_from Faraday::Error,
StandardError,
UspsLocationsError,
Faraday::BadRequestError,
with: :handle_error

def index
candidate = UspsInPersonProofing::Applicant.new(
address: search_params['street_address'],
city: search_params['city'], state: search_params['state'],
zip_code: search_params['zip_code']
)

unless candidate.has_valid_address?
raise UspsLocationsError
end

locations = proofer.request_facilities(candidate, false)

render json: localized_locations(locations).to_json
Expand All @@ -34,6 +53,27 @@ def localized_locations(locations)
end
end

def handle_error(err)
remapped_error = case err
when ActionController::InvalidAuthenticityToken,
Faraday::Error,
UspsLocationsError
:unprocessable_entity
else
:internal_server_error
end

analytics.idv_in_person_locations_request_failure(
api_status_code: Rack::Utils.status_code(remapped_error),
exception_class: err.class,
exception_message: scrub_message(err.message),
response_body_present: err.respond_to?(:response_body) && err.response_body.present?,
response_body: err.respond_to?(:response_body) && scrub_body(err.response_body),
response_status_code: err.respond_to?(:response_status) && err.response_status,
)
render json: {}, status: remapped_error
end

def search_params
params.require(:address).permit(
:street_address,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
RSpec.describe Idv::InPerson::Public::UspsLocationsController do
include Rails.application.routes.url_helpers

before do
stub_analytics
end

describe '#index' do
subject(:action) do
post :index,
Expand All @@ -21,5 +25,59 @@
action
expect(response).to be_ok
end

context 'with a 500 error from USPS' do
let(:server_error) { Faraday::ServerError.new }
let(:proofer) { double('Proofer') }

before do
allow(UspsInPersonProofing::EnrollmentHelper).to receive(:usps_proofer).and_return(proofer)
allow(proofer).to receive(:request_facilities).and_raise(server_error)
end

it 'returns an unprocessible entity client error' do
subject
expect(@analytics).to have_logged_event(
'Request USPS IPP locations: request failed',
api_status_code: 422,
exception_class: server_error.class,
exception_message: server_error.message,
response_body_present:
server_error.response_body.present?,
)

status = response.status
expect(status).to eq 422
end
end

context 'address has unsupported characters' do
let(:locale) { nil }
let(:usps_locations_error) { Idv::InPerson::Public::UspsLocationsError.new }

subject(:response) do
post :index, params: { locale: locale,
address: { street_address: '1600, Pennsylvania Ave',
city: 'Washington',
state: 'DC',
zip_code: '20500' } }
end

it 'returns unprocessable entity' do
subject

expect(@analytics).to have_logged_event(
'Request USPS IPP locations: request failed',
api_status_code: 422,
exception_class: usps_locations_error.class,
exception_message: usps_locations_error.message,
response_body_present: false,
response_body: false,
response_status_code: false,
)

expect(response.status).to eq 422
end
end
end
end