Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map address validation exceptions to VertexClient::ValidationError #58

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
16 changes: 16 additions & 0 deletions lib/vertex_client/payloads/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ module VertexClient
module Payload
class Base

# https://www.agiis.org/Links/ErrorCodes.htm
ADDRESS_VALIDATION_CODES = %w[
E101 E212 E213 E214 E216 E302 E412 E413 E420 E421 E422 E423 E425 E427 E428 E429 E430 E431
E432 E433 E434 E435 E436 E437 E439 E450 E451 E452 E453 E501 E502 E503 E504 E505 E600 E601
].freeze

attr_reader :params

def initialize(params)
Expand All @@ -16,8 +22,18 @@ def transform
}
end

def map_to_validation_exception!(exception)
return exception unless ADDRESS_VALIDATION_CODES.include?(fault_code(exception.message))

VertexClient::ValidationError.new("Invalid address: #{exception.message}")
end

private

def fault_code(message)
message.match(/fault code=(?<code>\w+),/)&.[](:code)
end

def request_key
:"#{self.class.name.demodulize.underscore}_request"
end
Expand Down
2 changes: 2 additions & 0 deletions lib/vertex_client/resources/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ def config_key

def response
@response ||= connection.request(@payload.transform)
rescue Savon::SOAPFault => e
raise @payload.map_to_validation_exception!(e)
end

def connection
Expand Down
2 changes: 1 addition & 1 deletion lib/vertex_client/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module VertexClient
VERSION = '0.9.1'
VERSION = '0.9.2'
end
41 changes: 38 additions & 3 deletions test/resources/base_test.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
require 'test_helper'

describe VertexClient::Resource::Base do
class VertexClient::Resource::MyTest < VertexClient::Resource::Base
class VertexClient::Resource::MyTest < VertexClient::Resource::Base
ENDPOINT = 'MyEndPoint'.freeze
end
class VertexClient::Payload::MyTest < VertexClient::Payload::Base
class VertexClient::Payload::MyTest < VertexClient::Payload::Base
def validate!
end

Expand All @@ -15,10 +15,12 @@ def body
class VertexClient::Response::MyTest < VertexClient::Response::Base; end;

let(:resource) { VertexClient::Resource::MyTest.new({ test: :ok })}
let(:connection) { resource.send(:connection) }
let(:payload) { resource.instance_variable_get(:@payload) }

describe 'initialize' do
it 'sets @payload with a new instance of payload_type' do
assert_kind_of VertexClient::Payload::MyTest, resource.instance_variable_get(:@payload)
assert_kind_of VertexClient::Payload::MyTest, payload
end
end

Expand All @@ -40,6 +42,39 @@ class VertexClient::Response::MyTest < VertexClient::Response::Base; end;
end
end

describe 'when a soap fault is raised' do
let(:nori) { Nori.new(:strip_namespaces => true, :convert_tags_to => lambda { |tag| tag.snakecase.to_sym }) }
let(:address_fault) { fault_message(<<-ERROR) }
No tax areas were found during the lookup. The address fields are inconsistent for the specified asOfDate. (Street Information=1-252 AR / B- BTRY, Street Information 2=null, Postal Code=UNIT, City=APOAE, Sub Division=null, Main Division=09877-1368, Country=USA, As Of Date=20200419) Failed to cleanse address. (fault code=E412, fault code text=Primary name not found in directory.)
ERROR
let(:fault) { fault_message("The request cannot be processed") }
let(:address_soap_fault) { Savon::SOAPFault.new(HTTPI::Response.new(500, {}, address_fault), nori) }
let(:soap_fault) { Savon::SOAPFault.new(HTTPI::Response.new(500, {}, fault), nori) }

it 'maps to a validation exception for address errors' do
connection.stubs(:request).raises(address_soap_fault)
assert_raises(VertexClient::ValidationError) { resource.result }
end

it 'raises SOAPFault for non validation errors' do
connection.stubs(:request).raises(soap_fault)
assert_raises(Savon::SOAPFault) { resource.result }
end

def fault_message(fault_string)
<<-STRING
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soapenv:Client</faultcode>
<faultstring>#{fault_string}</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
STRING
end
end

describe 'when response is not set' do
before do
resource.stubs(:response).returns(nil)
Expand Down