Create new RemoteCensusAPI
Create a new RemoteCensusAPI with the same functionality as
the old CensusAPI.
In the new RemoteCensusAPI both the request and the
processing of the response are made according to the
parameters defined in the "Remote Census Configuration"
page.
Same as old Census API we only consider document_type and
document_number on API request.
* request(document_type, document_number))
On "Remote Census Configuration" we allow to define request
structure on Setting["remote_census.request.structure"]
The information text of this field on "Remote Census Configuration" is:
> The "static" values of this request should be filled.
> Values related to Document Type, Document Number, Date of Birth and
Postal Code should be nil value.
An Example with the expected value for this field:
"{ request:
{
codigo_institucion: 1,
codigo_portal: 1,
codigo_usuario: 1,
documento: nil,
tipo_documento: nil,
codigo_idioma: '102',
nivel: '3'
}
}"
Where 'codigo_institucion', 'codigo_portal', 'codigo_usuario' and
'nivel' are "static" and filled in with their expected static values.
On the other hand 'documento' and 'tipo_documento' are fields
related with 'document_type','document_number' and filled in with
nil value.
On 'request' method we fill in thats 'nil values' with their
correct argument value. We can fill_in correctly because on
"Remote Census Configuration" we allow to define request path for
'document_type','document_number'
Setting["remote_census.request.document_type"]
Setting["remote_census.request.document_number"]
An Example with the expected values:
Setting["remote_census.request.document_type"] = "request.tipo_documento"
Setting["remote_census.request.document_number"] = "request.documento"
With this information with 'fill_in(structure, path_value, value)'
method, we can update structure with correct argument ('document_type',
'document_number', 'date_of_birth' and 'postal_code') value.
An Example of fill_in(structure, path_value, value) where:
structure = "{ request:
{
codigo_institucion: 1,
codigo_portal: 1,
codigo_usuario: 1,
documento: nil,
tipo_documento: nil,
codigo_idioma: '102',
nivel: '3'
}
}"
path_value = "request.documento"
value = "12345678X"
The result expected is:
{ request:
{
codigo_institucion: 1,
codigo_portal: 1,
codigo_usuario: 1,
documento: "12345678X",
tipo_documento: nil,
codigo_idioma: '102',
nivel: '3'
}
}
This commit is contained in:
152
lib/remote_census_api.rb
Normal file
152
lib/remote_census_api.rb
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
include DocumentParser
|
||||||
|
class RemoteCensusApi
|
||||||
|
|
||||||
|
def call(document_type, document_number)
|
||||||
|
response = nil
|
||||||
|
get_document_number_variants(document_type, document_number).each do |variant|
|
||||||
|
response = Response.new(get_response_body(document_type, variant))
|
||||||
|
return response if response.valid?
|
||||||
|
end
|
||||||
|
response
|
||||||
|
end
|
||||||
|
|
||||||
|
class Response
|
||||||
|
def initialize(body)
|
||||||
|
@body = body
|
||||||
|
end
|
||||||
|
|
||||||
|
def extract_value(path_value)
|
||||||
|
path = parse_path(path_value)
|
||||||
|
return nil unless path.present?
|
||||||
|
@body.dig(*path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def valid?
|
||||||
|
path_value = Setting["remote_census.response.valid"]
|
||||||
|
extract_value(path_value).present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def date_of_birth
|
||||||
|
path_value = Setting["remote_census.response.date_of_birth"]
|
||||||
|
str = extract_value(path_value)
|
||||||
|
return nil unless str.present?
|
||||||
|
day, month, year = str.match(/(\d\d?)\D(\d\d?)\D(\d\d\d?\d?)/)[1..3]
|
||||||
|
return nil unless day.present? && month.present? && year.present?
|
||||||
|
Time.zone.local(year.to_i, month.to_i, day.to_i).to_date
|
||||||
|
end
|
||||||
|
|
||||||
|
def postal_code
|
||||||
|
path_value = Setting["remote_census.response.postal_code"]
|
||||||
|
extract_value(path_value)
|
||||||
|
end
|
||||||
|
|
||||||
|
def district_code
|
||||||
|
path_value = Setting["remote_census.response.district"]
|
||||||
|
extract_value(path_value)
|
||||||
|
end
|
||||||
|
|
||||||
|
def gender
|
||||||
|
path_value = Setting["remote_census.response.gender"]
|
||||||
|
|
||||||
|
case extract_value(path_value)
|
||||||
|
when "Varón"
|
||||||
|
"male"
|
||||||
|
when "Mujer"
|
||||||
|
"female"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def name
|
||||||
|
path_value_name = Setting["remote_census.response.name"]
|
||||||
|
path_value_surname = Setting["remote_census.response.surname"]
|
||||||
|
|
||||||
|
"#{extract_value(path_value_name)} #{extract_value(path_value_surname)}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_path(path_value)
|
||||||
|
path_value.split(".").map{ |section| section.to_sym } if path_value.present?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def get_response_body(document_type, document_number)
|
||||||
|
if end_point_available?
|
||||||
|
client.call(Setting["remote_census.request.method_name"].to_sym, message: request(document_type, document_number)).body
|
||||||
|
else
|
||||||
|
stubbed_response(document_type, document_number)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def client
|
||||||
|
@client = Savon.client(wsdl: Setting["remote_census.general.endpoint"])
|
||||||
|
end
|
||||||
|
|
||||||
|
def request(document_type, document_number)
|
||||||
|
structure = eval(Setting["remote_census.request.structure"])
|
||||||
|
|
||||||
|
fill_in(structure, Setting["remote_census.request.document_type"], document_type)
|
||||||
|
fill_in(structure, Setting["remote_census.request.document_number"], document_number)
|
||||||
|
|
||||||
|
structure
|
||||||
|
end
|
||||||
|
|
||||||
|
def fill_in(structure, path_value, value)
|
||||||
|
path = parse_path(path_value)
|
||||||
|
|
||||||
|
update_value(structure, path, value) if path.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_path(path_value)
|
||||||
|
path_value.split(".").map{ |section| section.to_sym } if path_value.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_value(structure, path, value)
|
||||||
|
*path, final_key = path
|
||||||
|
to_set = path.empty? ? structure : structure.dig(*path)
|
||||||
|
|
||||||
|
return unless to_set
|
||||||
|
to_set[final_key] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
def end_point_available?
|
||||||
|
Rails.env.staging? || Rails.env.preproduction? || Rails.env.production?
|
||||||
|
end
|
||||||
|
|
||||||
|
def stubbed_response(document_type, document_number)
|
||||||
|
if (document_number == "12345678Z" || document_number == "12345678Y") && document_type == "1"
|
||||||
|
stubbed_valid_response
|
||||||
|
else
|
||||||
|
stubbed_invalid_response
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def stubbed_valid_response
|
||||||
|
{
|
||||||
|
get_habita_datos_response: {
|
||||||
|
get_habita_datos_return: {
|
||||||
|
datos_habitante: {
|
||||||
|
item: {
|
||||||
|
fecha_nacimiento_string: "31-12-1980",
|
||||||
|
identificador_documento: "12345678Z",
|
||||||
|
descripcion_sexo: "Varón",
|
||||||
|
nombre: "José",
|
||||||
|
apellido1: "García"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
datos_vivienda: {
|
||||||
|
item: {
|
||||||
|
codigo_postal: "28013",
|
||||||
|
codigo_distrito: "01"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def stubbed_invalid_response
|
||||||
|
{get_habita_datos_response: {get_habita_datos_return: {datos_habitante: {}, datos_vivienda: {}}}}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -42,6 +42,35 @@ describe CensusCaller do
|
|||||||
|
|
||||||
expect(response).to eq(census_api_response)
|
expect(response).to eq(census_api_response)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "returns data from Remote Census API if it's available and valid" do
|
||||||
|
Setting["feature.remote_census"] = true
|
||||||
|
access_user_data = "get_habita_datos_response.get_habita_datos_return.datos_habitante.item"
|
||||||
|
access_residence_data = "get_habita_datos_response.get_habita_datos_return.datos_vivienda.item"
|
||||||
|
Setting["remote_census.response.date_of_birth"] = "#{access_user_data}.fecha_nacimiento_string"
|
||||||
|
Setting["remote_census.response.postal_code"] = "#{access_residence_data}.codigo_postal"
|
||||||
|
Setting["remote_census.response.valid"] = access_user_data
|
||||||
|
|
||||||
|
remote_census_api_response = RemoteCensusApi::Response.new(get_habita_datos_response: {
|
||||||
|
get_habita_datos_return: {
|
||||||
|
datos_habitante: { item: { fecha_nacimiento_string: "1-1-1980" } }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
local_census_response = LocalCensus::Response.new(create(:local_census_record))
|
||||||
|
|
||||||
|
expect_any_instance_of(RemoteCensusApi).to receive(:call).and_return(remote_census_api_response)
|
||||||
|
allow_any_instance_of(LocalCensus).to receive(:call).and_return(local_census_response)
|
||||||
|
|
||||||
|
allow(RemoteCensusApi).to receive(:call).with(1, "12345678A")
|
||||||
|
allow(LocalCensus).to receive(:call).with(1, "12345678A")
|
||||||
|
|
||||||
|
response = api.call(1, "12345678A")
|
||||||
|
|
||||||
|
expect(response).to eq(remote_census_api_response)
|
||||||
|
|
||||||
|
Setting["feature.remote_census"] = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
51
spec/lib/remote_census_api_spec.rb
Normal file
51
spec/lib/remote_census_api_spec.rb
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe RemoteCensusApi do
|
||||||
|
let(:api) { described_class.new }
|
||||||
|
|
||||||
|
describe "#call" do
|
||||||
|
let(:invalid_body) { {get_habita_datos_response: {get_habita_datos_return: {datos_habitante: {}}}} }
|
||||||
|
let(:valid_body) do
|
||||||
|
{
|
||||||
|
get_habita_datos_response: {
|
||||||
|
get_habita_datos_return: {
|
||||||
|
datos_habitante: {
|
||||||
|
item: {
|
||||||
|
fecha_nacimiento_string: "1-1-1980"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
access_user_data = "get_habita_datos_response.get_habita_datos_return.datos_habitante.item"
|
||||||
|
access_residence_data = "get_habita_datos_response.get_habita_datos_return.datos_vivienda.item"
|
||||||
|
Setting["remote_census.response.date_of_birth"] = "#{access_user_data}.fecha_nacimiento_string"
|
||||||
|
Setting["remote_census.response.postal_code"] = "#{access_residence_data}.codigo_postal"
|
||||||
|
Setting["remote_census.response.valid"] = access_user_data
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the response for the first valid variant" do
|
||||||
|
allow(api).to receive(:get_response_body).with(1, "00123456").and_return(invalid_body)
|
||||||
|
allow(api).to receive(:get_response_body).with(1, "123456").and_return(invalid_body)
|
||||||
|
allow(api).to receive(:get_response_body).with(1, "0123456").and_return(valid_body)
|
||||||
|
|
||||||
|
response = api.call(1, "123456")
|
||||||
|
|
||||||
|
expect(response).to be_valid
|
||||||
|
expect(response.date_of_birth).to eq(Date.new(1980, 1, 1))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the last failed response" do
|
||||||
|
allow(api).to receive(:get_response_body).with(1, "00123456").and_return(invalid_body)
|
||||||
|
allow(api).to receive(:get_response_body).with(1, "123456").and_return(invalid_body)
|
||||||
|
allow(api).to receive(:get_response_body).with(1, "0123456").and_return(invalid_body)
|
||||||
|
response = api.call(1, "123456")
|
||||||
|
|
||||||
|
expect(response).not_to be_valid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user