Skip to content

Commit

Permalink
Remove DOB and SSN from veteran_representatives (#16369)
Browse files Browse the repository at this point in the history
* remove dob and ssn from veteran_representatives

* rubocop formatting

* rubocop formatting

* add data back to personal_information_log_schema

* move migration to another PR

* reset schema to master

* reset schema to master

* add ignored columns to vet rep

* remove ignore_columns
  • Loading branch information
stevenjcumming authored Apr 17, 2024
1 parent 88ec761 commit 3bc601f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 84 deletions.
58 changes: 11 additions & 47 deletions modules/veteran/app/models/veteran/service/representative.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ class Representative < ApplicationRecord
BASE_URL = 'https://www.va.gov/ogc/apps/accreditation/'

self.primary_key = :representative_id
has_kms_key
has_encrypted :dob, :ssn, key: :kms_key, **lockbox_options

scope :attorneys, -> { where(user_types: ['attorney']) }
scope :veteran_service_officers, -> { where(user_types: ['veteran_service_officer']) }
Expand All @@ -24,62 +22,28 @@ class Representative < ApplicationRecord
# Find all representatives that matches the provided search criteria
# @param first_name: [String] First name to search for, ignoring case
# @param last_name: [String] Last name to search for, ignoring case
# @param ssn: nil [String] SSN to search for
# @param dob: nil [String] Date of birth to search for
# @param middle_initial: nil [String] Middle initial to search for
# @param poa_code: nil [String] filter to reps working this POA code
#
# @return [Array(Veteran::Service::Representative)] All representatives found using the submitted search criteria
def self.all_for_user(first_name:, last_name:, ssn: nil, dob: nil, middle_initial: nil, poa_code: nil) # rubocop:disable Metrics/ParameterLists
reps = where('lower(first_name) = ? AND lower(last_name) = ?', first_name.downcase, last_name.downcase)
reps = reps.where('? = ANY(poa_codes)', poa_code) if poa_code

reps.select do |rep|
matching_ssn(rep, ssn) &&
matching_date_of_birth(rep, dob) &&
matching_middle_initial(rep, middle_initial)
end
def self.all_for_user(first_name:, last_name:, middle_initial: nil, poa_code: nil)
representatives = where('lower(first_name) = ? AND lower(last_name) = ?', first_name.downcase,
last_name.downcase)
representatives = representatives.where('? = ANY(poa_codes)', poa_code) if poa_code
representatives.select { |rep| matching_middle_initial(rep, middle_initial) }
end

#
# Find first representative that matches the provided search criteria
# @param first_name: [String] First name to search for, ignoring case
# @param last_name: [String] Last name to search for, ignoring case
# @param ssn: nil [String] SSN to search for
# @param dob: nil [String] Date of birth to search for
#
# @return [Veteran::Service::Representative] First representative record found using the submitted search criteria
def self.for_user(first_name:, last_name:, ssn: nil, dob: nil)
reps = all_for_user(first_name:, last_name:, ssn:, dob:)
return nil if reps.blank?

reps.first
end

#
# Determine if representative ssn matches submitted ssn search query
# @note Assumes that the consumer did not submit an ssn value if the value is blank
# @param rep [Veteran::Service::Representative] Representative to match soon with
# @param ssn [String] Submitted ssn to match against representative
#
# @return [Boolean] True if matches, false if not
def self.matching_ssn(rep, ssn)
return true if ssn.blank?

rep.ssn.present? && rep.ssn == ssn
end

#
# Determine if representative dob matches submitted birth_date search query
# @note Assumes that the consumer did not submit a birth_date value if the value is blank
# @param rep [Veteran::Service::Representative] Representative to match soon with
# @param birth_date [String] Submitted birth_date to match against representative
#
# @return [Boolean] True if matches, false if not
def self.matching_date_of_birth(rep, birth_date)
return true if birth_date.blank?
def self.for_user(first_name:, last_name:)
representatives = all_for_user(first_name:, last_name:)
return nil if representatives.blank?

rep.dob.present? && rep.dob == birth_date
representatives.first
end

#
Expand All @@ -89,10 +53,10 @@ def self.matching_date_of_birth(rep, birth_date)
# @param middle_initial [String] Submitted middle_initial to match against representative
#
# @return [Boolean] True if matches, false if not
def self.matching_middle_initial(rep, middle_initial)
def self.matching_middle_initial(representative, middle_initial)
return true if middle_initial.blank?

rep.middle_initial.present? && rep.middle_initial == middle_initial
representative.middle_initial.present? && representative.middle_initial == middle_initial
end

#
Expand Down
55 changes: 18 additions & 37 deletions modules/veteran/spec/models/veteran/service/representative_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,50 +25,31 @@ def basic_attributes
end

describe 'finding by identity' do
let(:rep) do
let(:representative) do
FactoryBot.create(:representative,
basic_attributes.merge!(ssn: identity.ssn, dob: identity.birth_date))
basic_attributes)
end

before do
identity
rep
representative
end

describe 'finding by all fields' do
it 'finds a user by name, ssn, and dob' do
describe 'finding by the name' do
it 'finds a user' do
expect(Veteran::Service::Representative.for_user(
first_name: identity.first_name,
last_name: identity.last_name,
dob: identity.birth_date,
ssn: identity.ssn
).id).to eq(rep.id)
last_name: identity.last_name
).id).to eq(representative.id)
end

it 'finds right user when 2 with the same name exist' do
FactoryBot.create(:representative,
basic_attributes.merge!(ssn: '123-45-6789', dob: '1929-10-01'))
expect(Veteran::Service::Representative.for_user(
first_name: identity.first_name,
last_name: identity.last_name,
dob: identity.birth_date,
ssn: identity.ssn
).id).to eq(rep.id)
end
end

describe 'finding by the name only' do
it 'finds a user by name fields' do
rep = FactoryBot.create(:representative, first_name: 'Bob', last_name: 'Smith')
identity = FactoryBot.create(:user_identity, first_name: rep.first_name, last_name: rep.last_name)
Veteran::Service::Representative.for_user(
first_name: identity.first_name,
last_name: identity.last_name
)
basic_attributes)
expect(Veteran::Service::Representative.for_user(
first_name: identity.first_name,
last_name: identity.last_name
).id).to eq(rep.id)
).id).to eq(representative.id)
end
end
end
Expand Down Expand Up @@ -118,26 +99,26 @@ def basic_attributes
describe '#set_full_name' do
context 'creating a new representative' do
it 'sets the full_name attribute as first_name + last_name' do
rep = described_class.new(representative_id: 'abc', poa_codes: ['123'], first_name: 'Joe',
last_name: 'Smith')
representative = described_class.new(representative_id: 'abc', poa_codes: ['123'], first_name: 'Joe',
last_name: 'Smith')

expect(rep.full_name).to be_nil
expect(representative.full_name).to be_nil

rep.save!
representative.save!

expect(rep.reload.full_name).to eq('Joe Smith')
expect(representative.reload.full_name).to eq('Joe Smith')
end
end

context 'updating an existing representative' do
it 'sets the full_name attribute as first_name + last_name' do
rep = create(:representative, first_name: 'Joe', last_name: 'Smith')
representative = create(:representative, first_name: 'Joe', last_name: 'Smith')

expect(rep.full_name).to eq('Joe Smith')
expect(representative.full_name).to eq('Joe Smith')

rep.update(first_name: 'Bob')
representative.update(first_name: 'Bob')

expect(rep.reload.full_name).to eq('Bob Smith')
expect(representative.reload.full_name).to eq('Bob Smith')
end
end
end
Expand Down

0 comments on commit 3bc601f

Please sign in to comment.