Skip to content

Commit

Permalink
creates data to seed dev & staging (#16502)
Browse files Browse the repository at this point in the history
  • Loading branch information
binq committed Apr 25, 2024
1 parent c8354ff commit c2cc95b
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 4 deletions.
5 changes: 1 addition & 4 deletions modules/vye/app/models/vye/user_info.rb
Expand Up @@ -27,6 +27,7 @@ class Vye::UserInfo < ApplicationRecord
enum indicator: { chapter1606: 'A', chapter1607: 'E', chapter30: 'B', D: 'D' }

delegate :icn, to: :user_profile, allow_nil: true
delegate :ssn, to: :mpi_profile, allow_nil: true
delegate :pending_documents, to: :user_profile
delegate :verifications, to: :user_profile

Expand All @@ -45,10 +46,6 @@ def verification_required
verifications.empty?
end

def ssn
mpi_profile&.ssn
end

private

def mpi_profile
Expand Down
58 changes: 58 additions & 0 deletions modules/vye/lib/tasks/vye.rake
@@ -1,6 +1,15 @@
# frozen_string_literal: true

namespace :vye do
namespace :feature do
desc 'Enables request_allowed feature flag'
task request_allowed: :environment do |_cmd, _args|
current_state = Flipper.enabled?(:vye_request_allowed)
puts format('Current state vye_request_allowed is: %<current_state>s', current_state:)
Flipper.enable :vye_request_allowed
end
end

namespace :install do
desc 'Installs config into config/settings.local.yml'
task config: :environment do |_cmd, _args|
Expand All @@ -13,4 +22,53 @@ namespace :vye do
local_path.write(engine_dev_path.read, mode: 'a')
end
end

namespace :data do
desc 'Clear VYE data from the database'
task clear: :environment do |_cmd, _args|
Vye::AddressChange.destroy_all
Vye::DirectDepositChange.destroy_all
Vye::Verification.destroy_all
Vye::Award.destroy_all
Vye::UserInfo.destroy_all

Vye::PendingDocument.destroy_all

Vye::UserProfile.destroy_all
end

desc 'Build YAML files to load for development from team sensitive data'
task build: :environment do |_cmd, _args|
source = Pathname('/projects/va.gov-team-sensitive')
target = Rails.root / 'tmp'
handles = nil

build = Vye::StagingData::Build.new(target:) do |paths|
handles =
paths
.transform_values do |value|
(source / value).open
end
end

build.dump
handles.each_value(&:close)
end

desc 'Load development YAML files into the database'
task :load, [:path] => :environment do |_cmd, args|
raise 'load path is required' if args[:path].nil?

root = Pathname(args[:path])
files = root.glob('**/*.yaml')
raise "No files found in #{root}" if files.empty?

files.each do |file|
source = :team_sensitive
data = YAML.safe_load(file.read, permitted_classes: [Date, DateTime, Symbol, Time])
records = data.slice(:profile, :info, :address, :awards, :pending_documents)
Vye::LoadData.new(source:, records:)
end
end
end
end
154 changes: 154 additions & 0 deletions modules/vye/lib/vye/staging_data/build.rb
@@ -0,0 +1,154 @@
# frozen_string_literal: true

module Vye
module StagingData
class Build
MAX_AWARD_COUNT = 4
MAX_PENDING_DOCUMENT_COUNT = 1
PATHS =
{
test_users: 'Administrative/vagov-users/test_users.csv',
mvi_staging_users: 'Administrative/vagov-users/mvi-staging-users.csv'
}.freeze

private_constant :PATHS, :MAX_AWARD_COUNT, :MAX_PENDING_DOCUMENT_COUNT

def dump
@dump if defined?(@dump)

rows.each do |row|
summary = row[:summary]
path = root / format('%s.yaml', summary[:full_name].downcase.gsub(/\s+/, '-'))
path.write(row.to_yaml)
end

@dump = true
end

private

attr_reader :test_users, :mvi_staging_users, :target

def initialize(target:)
yield(PATHS) => {test_users:, mvi_staging_users:}
@test_users = CSV.new(test_users, headers: true).each.to_a
@mvi_staging_users = CSV.new(mvi_staging_users, headers: true).each.to_a
@target = target
end

def cross
return @cross if defined?(@cross)

product =
test_users
.product(mvi_staging_users)
.select do |tu, msu|
tu['ssn'] == msu['ssn']
end

@cross = product.group_by { |x| x.first['ssn'] }.values.pluck(0)
end

def rows
@rows ||=
cross
.map do |tu, msu|
tu = extract_from_tu(tu)
msu = extract_from_msu(msu)

summary = {}.merge(tu).merge(msu)

{
summary:,
profile: fake_user_profile(summary:),
info: fake_user_info(summary:),
address: fake_address_change(summary:),
awards: fake_awards,
pending_documents: fake_pending_documents
}
end
end

def root
return @root if defined?(@root)

timestamp = Time.zone.now.strftime('%Y%m%dT%H%M%S%z')
root = target / format('vye/staging-data-%<timestamp>s', timestamp:)
root.mkpath

@root = root
end

def fake_user_profile(summary:)
FactoryBot.attributes_for(:vye_user_profile).except(:ssn, :icn, :file_number).tap do |record|
record[:ssn] = summary[:ssn]
record[:file_number] = summary[:ssn]
record[:icn] = summary[:icn]
end
end

def fake_user_info(summary:)
FactoryBot.attributes_for(:vye_user_info).except(:full_name).tap do |record|
name = summary[:full_name]
parts = name.split(/\s+/)
initials = parts.pluck(0).join
rest = parts[-1][1..(7 - initials.length)]
stub_nm = [initials, rest].join.upcase

record[:stub_nm] = stub_nm
record[:file_number] = summary[:ssn]
end
end

def fake_address_change(summary:)
FactoryBot.attributes_for(:vye_address_backend).tap do |record|
record[:veteran_name] = summary[:full_name]
end
end

def fake_awards
(1..rand(1..4)).map do
FactoryBot.attributes_for(:vye_award)
end
end

def fake_pending_documents
(0..rand(0..1)).map do
FactoryBot.attributes_for(:vye_pending_document)
end
end

def extract_from_tu(row)
ssn = scrub_ssn(row['ssn'])
idme_uuid = row['idme_uuid']&.strip
email = row['email']&.strip
password = row['password']&.strip
full_name =
row.values_at(
'first_name',
'middle_name',
'last_name'
).compact.map(&:strip).map(&:capitalize).join(' ').strip

{ ssn:, idme_uuid:, email:, password:, full_name: }
end

def extract_from_msu(row)
ssn = scrub_ssn(row['ssn'])
icn = row['icn']&.strip
full_name =
row.values_at(
'first_name',
'middle_name',
'last_name'
).compact.map(&:strip).map(&:capitalize).join(' ').strip

{ ssn:, icn:, full_name: }
end

def scrub_ssn(value)
value&.gsub(/\D/, '')&.strip
end
end
end
end
9 changes: 9 additions & 0 deletions modules/vye/spec/factories/vye/address_changes.rb
Expand Up @@ -9,4 +9,13 @@
zip_code { Faker::Address.zip_code }
origin { Vye::AddressChange.origins['frontend'] }
end

factory :vye_address_backend, class: 'Vye::AddressChange' do
veteran_name { Faker::Name.name }
address1 { Faker::Address.street_address }
city { Faker::Address.city }
state { Faker::Address.state_abbr }
zip_code { Faker::Address.zip_code }
origin { Vye::AddressChange.origins['backend'] }
end
end
44 changes: 44 additions & 0 deletions modules/vye/spec/lib/vye/staging_data/build_spec.rb
@@ -0,0 +1,44 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Vye::StagingData::Build do
describe '#dump' do
let(:target) { double('Pathname (Target)') }

let(:source) { double('Pathname (Source)') }

let(:streams) do
{
test_users: StringIO.new(<<~TEST_USERS),
first_name,middle_name,last_name,gender,birth_date,ssn,phone,email,password,mfa_code,id_types,loa,idme_uuid,logingov_uuid,services,notes
John,A,Doe,M,1932-02-05T00:00:00-08:00,111111111,800-827-1000,user1@email.com,xxx,xxx,"idme,logingov",3,xxx,xxx,"notes",
Jane,B,Smith,M,1933-04-05T00:00:00-08:00,222222222,800-827-1000,user2@email.com,xxx,xxx,"idme,logingov",3,xxx,xxx,"notes",
TEST_USERS
mvi_staging_users: StringIO.new(<<~MVI_STAGING_USERS)
first_name,middle_name,last_name,gender,birth_date,ssn,phone,email,password,icn,edipi,has_data_for, notes
John,A,Doe,M,1932-02-05T00:00:00-08:00,111111111,800-827-1000,user1@email.com,xxx,xxx,xxx,,notes
Jane,B,Smith,M,1933-04-05T00:00:00-08:00,222222222,800-827-1000,user2@email.com,xxx,xxx,xxx,,
MVI_STAGING_USERS
}.freeze
end

let(:staging_data_build) do
Vye::StagingData::Build.new(target:) do |_paths|
streams
end
end

it 'returns an array of rows' do
root = double('Pathname (Root)')
dump_file = double('Pathname (File)')

expect(target).to receive(:/).and_return(root)
expect(root).to receive(:mkpath).with(no_args).and_return(true)
expect(root).to receive(:/).twice.with(any_args).and_return(dump_file)
expect(dump_file).to receive(:write).twice.and_return(true)

staging_data_build.dump
end
end
end
15 changes: 15 additions & 0 deletions modules/vye/spec/serializers/verification_serializer_spec.rb
@@ -0,0 +1,15 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe Vye::VerificationSerializer, type: :serializer do
let(:resource) { build(:vye_verification) } # Assuming you have a factory for verification
let(:serializer) { described_class.new(resource) }
let(:serialization) { ActiveModelSerializers::Adapter.create(serializer, {}) }

it 'includes the expected attributes' do
expect do
serialization.as_json
end.not_to raise_error
end
end

0 comments on commit c2cc95b

Please sign in to comment.