From 210e2316fbd1255c23528dccfa555ebd4ce88b29 Mon Sep 17 00:00:00 2001 From: Zach Margolis Date: Wed, 7 Feb 2024 15:16:24 -0800 Subject: [PATCH 1/5] wip --- lib/data_pull.rb | 25 +++- .../local/write_cloudwatch_logs.rb | 21 +-- lib/data_requests/local/write_user_events.rb | 33 +++-- lib/data_requests/local/write_user_info.rb | 122 +++++++++++------- lib/tasks/data_requests.rake | 30 ++++- spec/lib/data_pull_spec.rb | 28 ++++ .../local/write_user_info_spec.rb | 74 ++++++++--- 7 files changed, 247 insertions(+), 86 deletions(-) diff --git a/lib/data_pull.rb b/lib/data_pull.rb index dd5b211f565..671efa0c8bb 100644 --- a/lib/data_pull.rb +++ b/lib/data_pull.rb @@ -152,13 +152,36 @@ def run(args:, config:) ActiveRecord::Base.connection.execute('SET statement_timeout = 0') uuids = args - users = uuids.map { |uuid| DataRequests::Deployed::LookupUserByUuid.new(uuid).call }.compact + users, missing_uuids = uuids.map do |uuid| + DataRequests::Deployed::LookupUserByUuid.new(uuid).call || uuid + end.partition { |u| u.is_a?(User) } + shared_device_users = DataRequests::Deployed::LookupSharedDeviceUsers.new(users).call output = shared_device_users.map do |user| DataRequests::Deployed::CreateUserReport.new(user, config.requesting_issuers).call end + if config.include_missing? + output += missing_uuids.map do |uuid| + { + user_id: nil, + login_uuid: nil, + requesting_issuer_uuid: uuid, + email_addresses: [], + mfa_configurations: { + phone_configurations: [], + auth_app_configurations: [], + webauthn_configurations: [], + piv_cac_configurations: [], + backup_code_configurations: [], + }, + user_events: [], + not_found: true, + } + end + end + ScriptBase::Result.new( subtask: 'ig-request', uuids: users.map(&:uuid), diff --git a/lib/data_requests/local/write_cloudwatch_logs.rb b/lib/data_requests/local/write_cloudwatch_logs.rb index c9f5a1939ab..a625c73fdf7 100644 --- a/lib/data_requests/local/write_cloudwatch_logs.rb +++ b/lib/data_requests/local/write_cloudwatch_logs.rb @@ -4,6 +4,7 @@ module DataRequests module Local class WriteCloudwatchLogs HEADERS = %w[ + uuid timestamp event_name success @@ -14,19 +15,22 @@ class WriteCloudwatchLogs user_agent ].freeze - attr_reader :cloudwatch_results, :output_dir + attr_reader :cloudwatch_results, :requesting_issuer_uuid, :csv - def initialize(cloudwatch_results, output_dir) + def initialize(cloudwatch_results:, requesting_issuer_uuid:, csv:, include_header: false) @cloudwatch_results = cloudwatch_results - @output_dir = output_dir + @csv = csv + end + + def include_header? + !!@include_header end def call - CSV.open(File.join(output_dir, 'logs.csv'), 'w') do |csv| - csv << HEADERS - cloudwatch_results.each do |row| - csv << build_row(row) - end + csv << HEADERS if include_header? + + cloudwatch_results.each do |row| + csv << build_row(row) end end @@ -60,6 +64,7 @@ def build_row(row) user_agent = data.dig('properties', 'user_agent') [ + requesting_issuer_uuid, timestamp, event_name, success, diff --git a/lib/data_requests/local/write_user_events.rb b/lib/data_requests/local/write_user_events.rb index 034deaf7e1d..f60fafce969 100644 --- a/lib/data_requests/local/write_user_events.rb +++ b/lib/data_requests/local/write_user_events.rb @@ -3,16 +3,21 @@ module DataRequests module Local class WriteUserEvents - attr_reader :user_report, :output_dir, :requesting_issuer_uuid + attr_reader :user_report, :requesting_issuer_uuid, :csv - def initialize(user_report, output_dir, requesting_issuer_uuid) + def initialize(user_report:, requesting_issuer_uuid:, csv:, include_header: false) @user_report = user_report - @output_dir = output_dir + @csv = csv @requesting_issuer_uuid = requesting_issuer_uuid + @include_header = include_header + end + + def include_header? + !!@include_header end def call - CSV.open(File.join(output_dir, 'events.csv'), 'w') do |csv| + if include_header? csv << %w[ uuid event_name @@ -22,17 +27,17 @@ def call user_agent device_cookie ] + end - user_report[:user_events].each do |row| - csv << [requesting_issuer_uuid] + row.values_at( - :event_name, - :date_time, - :ip, - :disavowed_at, - :user_agent, - :device_cookie, - ) - end + user_report[:user_events].each do |row| + csv << [requesting_issuer_uuid] + row.values_at( + :event_name, + :date_time, + :ip, + :disavowed_at, + :user_agent, + :device_cookie, + ) end end end diff --git a/lib/data_requests/local/write_user_info.rb b/lib/data_requests/local/write_user_info.rb index e1f67b23209..edab2fbd256 100644 --- a/lib/data_requests/local/write_user_info.rb +++ b/lib/data_requests/local/write_user_info.rb @@ -3,86 +3,120 @@ module DataRequests module Local class WriteUserInfo - attr_reader :user_report, :output_dir + attr_reader :user_report, :csv - def initialize(user_report, output_dir) + def initialize(user_report:, csv:, include_header: false) @user_report = user_report - @output_dir = output_dir + @csv = csv + @include_header = include_header + end + + def include_header? + !!@include_header end def call + if include_header? + csv << %w[ + uuid + type + value + created_at + confirmed_at + ] + end + + write_not_found write_emails write_phone_configurations write_auth_app_configurations write_webauthn_configurations write_piv_cac_configurations write_backup_code_configurations - output_file.close end private - def output_file - @output_file ||= begin - output_path = File.join(output_dir, 'user.csv') - File.open(output_path, 'w') - end + def uuid + user_report[:requesting_issuer_uuid] end - def write_rows_to_csv(rows, *columns) - output_file.puts(columns.join(',')) - - return output_file.puts("No data\n\n") if rows.empty? - - rows.each do |row| - output_file.puts CSV.generate_line(row.values_at(*columns)) + def write_not_found + if user_report[:not_found] + csv << [ + uuid, + 'not found', + ] end - output_file.puts("\n") end def write_auth_app_configurations - output_file.puts('Auth app configurations:') - write_rows_to_csv( - user_report[:mfa_configurations][:auth_app_configurations], - :name, :created_at - ) + user_report[:mfa_configurations][:auth_app_configurations].each do |auth_app_config| + csv << [ + uuid, + 'Auth app configuration', + auth_app_config[:name], + auth_app_config[:created_at], + ] + end end def write_backup_code_configurations - output_file.puts('Backup code configurations:') - write_rows_to_csv( - user_report[:mfa_configurations][:backup_code_configurations], - :created_at, :used_at - ) + user_report[:mfa_configurations][:backup_code_configurations].each do |backup_code_config| + csv << [ + uuid, + 'Backup code configuration', + nil, + backup_code_config[:created_at], + backup_code_config[:used_at] + ] + end end def write_emails - output_file.puts('Emails:') - write_rows_to_csv(user_report[:email_addresses], :email, :created_at, :confirmed_at) + user_report[:email_addresses].each do |email| + csv << [ + uuid, + 'Email', + email[:email], + email[:created_at], + email[:confirmed_at], + ] + end end def write_phone_configurations - output_file.puts('Phone configurations:') - write_rows_to_csv( - user_report[:mfa_configurations][:phone_configurations], - :phone, :created_at, :confirmed_at - ) + user_report[:mfa_configurations][:phone_configurations].each do |phone_config| + csv << [ + uuid, + 'Phone configuration', + phone_config[:phone], + phone_config[:created_at], + phone_config[:confirmed_at], + ] + end end def write_piv_cac_configurations - output_file.puts('PIV/CAC configurations:') - write_rows_to_csv( - user_report[:mfa_configurations][:piv_cac_configurations], - :name, :created_at - ) + user_report[:mfa_configurations][:piv_cac_configurations].each do |piv_cac_config| + csv << [ + uuid, + 'PIV/CAC configuration', + piv_cac_config[:name], + piv_cac_config[:created_at], + ] + end end def write_webauthn_configurations - output_file.puts('WebAuthn configurations:') - write_rows_to_csv( - user_report[:mfa_configurations][:webauthn_configurations], - :name, :created_at - ) + user_report[:mfa_configurations][:webauthn_configurations].each do |webauthn_config| + csv << [ + uuid, + 'WebAuthn configuration', + webauthn_config[:name], + webauthn_config[:created_at], + ] + end end end end diff --git a/lib/tasks/data_requests.rake b/lib/tasks/data_requests.rake index e6ec274e126..7e92d4420d4 100644 --- a/lib/tasks/data_requests.rake +++ b/lib/tasks/data_requests.rake @@ -39,25 +39,47 @@ namespace :data_requests do users_report = JSON.parse(File.read(ENV['USERS_REPORT']), symbolize_names: true) output_dir = ENV['OUTPUT_DIR'] - users_report.each do |user_report| + users_csv = CSV.open(File.join(output_dir, 'users.csv'), 'w') + user_events_csv = CSV.open(File.join(output_dir, 'user_events.csv'), 'w') + logs_csv = CSV.open(File.join(output_dir, 'logs.csv'), 'w') + + users_report.each_with_index do |user_report, idx| puts "Processing user: #{user_report[:requesting_issuer_uuid]}" user_output_dir = File.join(output_dir, user_report[:requesting_issuer_uuid]) FileUtils.mkdir_p(user_output_dir) - DataRequests::Local::WriteUserInfo.new(user_report, user_output_dir).call + DataRequests::Local::WriteUserInfo.new( + user_report:, + csv: users_csv, + include_header: idx == 0, + ).call + DataRequests::Local::WriteUserEvents.new( - user_report, user_output_dir, user_report[:requesting_issuer_uuid] + user_report:, + requesting_issuer_uuid: user_report[:requesting_issuer_uuid], + csv: user_events_csv, + include_header: idx == 0, ).call cloudwatch_dates = user_report[:user_events].pluck(:date_time).map do |date_time| Time.zone.parse(date_time).to_date end.uniq + cloudwatch_results = DataRequests::Local::FetchCloudwatchLogs.new( user_report[:login_uuid], cloudwatch_dates, ).call - DataRequests::Local::WriteCloudwatchLogs.new(cloudwatch_results, user_output_dir).call + DataRequests::Local::WriteCloudwatchLogs.new( + cloudwatch_results:, + requesting_issuer_uuid: user_report[:requesting_issuer_uuid], + csv: logs_csv, + include_header: idx == 0, + ).call end + ensure + users_csv&.close + user_events_csv&.close + logs_csv&.close end end diff --git a/spec/lib/data_pull_spec.rb b/spec/lib/data_pull_spec.rb index ec4efaf551e..44d28518014 100644 --- a/spec/lib/data_pull_spec.rb +++ b/spec/lib/data_pull_spec.rb @@ -126,6 +126,34 @@ :user_events, ) end + + context 'with a UUID that is not found' do + let(:uuid) { 'abcdef' } + let(:argv) do + ['ig-request', uuid, '--requesting-issuer', service_provider.issuer] + end + + it 'returns an empty hash for that user' do + data_pull.run + + response = JSON.parse(stdout.string, symbolize_names: true) + expect(response.first).to eq( + user_id: nil, + login_uuid: nil, + requesting_issuer_uuid: uuid, + email_addresses: [], + mfa_configurations: { + phone_configurations: [], + auth_app_configurations: [], + webauthn_configurations: [], + piv_cac_configurations: [], + backup_code_configurations: [], + }, + user_events: [], + not_found: true, + ) + end + end end end diff --git a/spec/lib/data_requests/local/write_user_info_spec.rb b/spec/lib/data_requests/local/write_user_info_spec.rb index 6fca619b720..dc9d03270c9 100644 --- a/spec/lib/data_requests/local/write_user_info_spec.rb +++ b/spec/lib/data_requests/local/write_user_info_spec.rb @@ -3,24 +3,68 @@ RSpec.describe DataRequests::Local::WriteUserInfo do describe '#call' do - it 'writes a file with user information' do - user_report = JSON.parse( + let(:io) { StringIO.new } + let(:csv) { CSV.new(io) } + + subject(:instance) do + DataRequests::Local::WriteUserInfo.new( + user_report:, + csv:, + include_header: true, + ) + end + + let(:user_report) do + JSON.parse( File.read('spec/fixtures/data_request.json'), symbolize_names: true ).first + end + let(:uuid) { user_report[:requesting_issuer_uuid] } + + it 'adds user information to the CSV' do + instance.call + + parsed = CSV.parse(io.string, headers: true) + + email_row = parsed.find { |r| r['type'] == 'Email' } + expect(email_row['uuid']).to eq(uuid) + expect(email_row['value']).to eq('test@example.com') + expect(email_row['created_at']).to be_present + expect(email_row['confirmed_at']).to be_present + + phone_row = parsed.find { |r| r['type'] == 'Phone configuration' } + expect(phone_row['uuid']).to eq(uuid) + expect(phone_row['value']).to eq('+1 555-555-5555') + expect(phone_row['created_at']).to be_present + expect(email_row['confirmed_at']).to be_present + end + + context 'with a not_found user' do + let(:uuid) { SecureRandom.hex } + let(:user_report) do + { + user_id: nil, + login_uuid: nil, + requesting_issuer_uuid: uuid, + email_addresses: [], + mfa_configurations: { + phone_configurations: [], + auth_app_configurations: [], + webauthn_configurations: [], + piv_cac_configurations: [], + backup_code_configurations: [], + }, + user_events: [], + not_found: true, + } + end + + it 'writes a not found row' do + instance.call - Dir.mktmpdir do |dir| - described_class.new(user_report, dir).call - user = File.read(File.join(dir, 'user.csv')) - headings = user.split("\n\n").map do |info_group| - info_group.split("\n").first - end - - expect(headings).to include('Emails:') - expect(headings).to include('Phone configurations:') - expect(headings).to include('Auth app configurations:') - expect(headings).to include('WebAuthn configurations:') - expect(headings).to include('PIV/CAC configurations:') - expect(headings).to include('Backup code configurations:') + parsed = CSV.parse(io.string, headers: true) + expect(parsed.first['uuid']).to eq(uuid) + expect(parsed.first['type']).to eq('not found') end end end From 6f446cc8b4a72071993bb383749e56d8852e84b6 Mon Sep 17 00:00:00 2001 From: Zach Margolis Date: Wed, 7 Feb 2024 16:36:21 -0800 Subject: [PATCH 2/5] Update output format of logs and data for OIG requests (LG-12335) - Before: one directory with 3 files per user - After: 3 files that each contain items by UUID changelog: Internal, Reporting, Update format of OIG export reports --- .../local/write_cloudwatch_logs.rb | 2 ++ .../local/write_cloudwatch_logs_spec.rb | 25 +++++++++------- .../local/write_user_events_spec.rb | 30 +++++++++++++------ 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/lib/data_requests/local/write_cloudwatch_logs.rb b/lib/data_requests/local/write_cloudwatch_logs.rb index a625c73fdf7..9805edd5877 100644 --- a/lib/data_requests/local/write_cloudwatch_logs.rb +++ b/lib/data_requests/local/write_cloudwatch_logs.rb @@ -19,7 +19,9 @@ class WriteCloudwatchLogs def initialize(cloudwatch_results:, requesting_issuer_uuid:, csv:, include_header: false) @cloudwatch_results = cloudwatch_results + @requesting_issuer_uuid = requesting_issuer_uuid @csv = csv + @include_header = include_header end def include_header? diff --git a/spec/lib/data_requests/local/write_cloudwatch_logs_spec.rb b/spec/lib/data_requests/local/write_cloudwatch_logs_spec.rb index eb2de59f2b7..732cb464bb6 100644 --- a/spec/lib/data_requests/local/write_cloudwatch_logs_spec.rb +++ b/spec/lib/data_requests/local/write_cloudwatch_logs_spec.rb @@ -30,23 +30,28 @@ def build_result_row(event_properties = {}) ] end - around do |ex| - Dir.mktmpdir do |dir| - @output_dir = dir - ex.run - end - end + let(:io) { StringIO.new } + let(:csv) { CSV.new(io) } + + let(:requesting_issuer_uuid) { SecureRandom.hex } + let(:include_header) { true } subject(:writer) do - DataRequests::Local::WriteCloudwatchLogs.new(cloudwatch_results, @output_dir) + DataRequests::Local::WriteCloudwatchLogs.new( + cloudwatch_results:, + csv:, + requesting_issuer_uuid:, + include_header: include_header, + ) end describe '#call' do - it 'writes the logs to output_dir/logs.csv' do + it 'writes the logs to the CSV' do writer.call - row = CSV.read(File.join(@output_dir, 'logs.csv'), headers: true).first + row = CSV.parse(io.string, headers: true).first + expect(row['uuid']).to eq(requesting_issuer_uuid) expect(row['timestamp']).to eq(now.iso8601) expect(row['event_name']).to eq('Some Log: Event') expect(row['success']).to eq('true') @@ -83,7 +88,7 @@ def build_result_row(event_properties = {}) it 'unpacks all multi factor ids' do writer.call - csv = CSV.read(File.join(@output_dir, 'logs.csv'), headers: true) + csv = CSV.parse(io.string, headers: true) expect(csv.map { |row| [row['multi_factor_auth_method'], row['multi_factor_id']] }). to eq( diff --git a/spec/lib/data_requests/local/write_user_events_spec.rb b/spec/lib/data_requests/local/write_user_events_spec.rb index 3f5c52a650c..407ce4d554d 100644 --- a/spec/lib/data_requests/local/write_user_events_spec.rb +++ b/spec/lib/data_requests/local/write_user_events_spec.rb @@ -5,18 +5,30 @@ let(:requesting_issuer_uuid) { SecureRandom.uuid } describe '#call' do - it 'writes a file with event information' do - user_report = JSON.parse( + let(:user_report) do + JSON.parse( File.read('spec/fixtures/data_request.json'), symbolize_names: true ).first + end + + let(:io) { StringIO.new } + let(:csv) { CSV.new(io) } + + subject(:writer) do + described_class.new( + user_report:, + requesting_issuer_uuid:, + csv:, + include_header: true, + ) + end + + it 'writes a file with event information' do + writer.call - Dir.mktmpdir do |dir| - described_class.new(user_report, dir, requesting_issuer_uuid).call - events = File.read(File.join(dir, 'events.csv')) - csv = CSV.parse(events, headers: true) - expect(csv.first['uuid']).to eq(requesting_issuer_uuid) - expect(csv.count).to eq(user_report[:user_events].length) - end + parsed = CSV.parse(io.string, headers: true) + expect(parsed.first['uuid']).to eq(requesting_issuer_uuid) + expect(parsed.count).to eq(user_report[:user_events].length) end end end From e0f07f5803347827a8f6520094bd946d6e6d1c9e Mon Sep 17 00:00:00 2001 From: Zach Margolis Date: Wed, 7 Feb 2024 16:46:26 -0800 Subject: [PATCH 3/5] remove no-longer-needed mkdir, add io flushes for easier tail -f watching --- lib/tasks/data_requests.rake | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/tasks/data_requests.rake b/lib/tasks/data_requests.rake index 7e92d4420d4..038af267649 100644 --- a/lib/tasks/data_requests.rake +++ b/lib/tasks/data_requests.rake @@ -45,8 +45,6 @@ namespace :data_requests do users_report.each_with_index do |user_report, idx| puts "Processing user: #{user_report[:requesting_issuer_uuid]}" - user_output_dir = File.join(output_dir, user_report[:requesting_issuer_uuid]) - FileUtils.mkdir_p(user_output_dir) DataRequests::Local::WriteUserInfo.new( user_report:, @@ -76,6 +74,10 @@ namespace :data_requests do csv: logs_csv, include_header: idx == 0, ).call + + users_csv.flush + user_events_csv.flush + logs_csv.flush end ensure users_csv&.close From c521f03d15de9acae9432b1383f360fcb3764318 Mon Sep 17 00:00:00 2001 From: Zach Margolis Date: Thu, 8 Feb 2024 13:37:04 -0800 Subject: [PATCH 4/5] lints --- lib/data_requests/local/write_user_info.rb | 2 +- spec/lib/data_requests/local/write_user_info_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/data_requests/local/write_user_info.rb b/lib/data_requests/local/write_user_info.rb index edab2fbd256..f35a593b6c1 100644 --- a/lib/data_requests/local/write_user_info.rb +++ b/lib/data_requests/local/write_user_info.rb @@ -68,7 +68,7 @@ def write_backup_code_configurations 'Backup code configuration', nil, backup_code_config[:created_at], - backup_code_config[:used_at] + backup_code_config[:used_at], ] end end diff --git a/spec/lib/data_requests/local/write_user_info_spec.rb b/spec/lib/data_requests/local/write_user_info_spec.rb index dc9d03270c9..22a8e704108 100644 --- a/spec/lib/data_requests/local/write_user_info_spec.rb +++ b/spec/lib/data_requests/local/write_user_info_spec.rb @@ -40,7 +40,7 @@ end context 'with a not_found user' do - let(:uuid) { SecureRandom.hex } + let(:uuid) { SecureRandom.hex } let(:user_report) do { user_id: nil, From 346cb15a3e2418e99bfce0ee7cbd20cf0bc8c1d7 Mon Sep 17 00:00:00 2001 From: Zach Margolis Date: Tue, 13 Feb 2024 09:04:21 -0800 Subject: [PATCH 5/5] Add phone_id too per request --- .../deployed/create_mfa_configurations_report.rb | 1 + lib/data_requests/local/write_user_info.rb | 2 ++ spec/fixtures/data_request.json | 1 + .../deployed/create_mfa_configurations_report_spec.rb | 1 + spec/lib/data_requests/local/write_user_info_spec.rb | 4 +++- 5 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/data_requests/deployed/create_mfa_configurations_report.rb b/lib/data_requests/deployed/create_mfa_configurations_report.rb index 58b050f02ab..6a2f97e0b69 100644 --- a/lib/data_requests/deployed/create_mfa_configurations_report.rb +++ b/lib/data_requests/deployed/create_mfa_configurations_report.rb @@ -40,6 +40,7 @@ def backup_code_configurations_report def phone_configurations_report user.phone_configurations.map do |phone_configuration| { + id: phone_configuration.id, phone: phone_configuration.phone, created_at: phone_configuration.created_at, confirmed_at: phone_configuration.confirmed_at, diff --git a/lib/data_requests/local/write_user_info.rb b/lib/data_requests/local/write_user_info.rb index f35a593b6c1..389d0a2d230 100644 --- a/lib/data_requests/local/write_user_info.rb +++ b/lib/data_requests/local/write_user_info.rb @@ -23,6 +23,7 @@ def call value created_at confirmed_at + internal_id ] end @@ -93,6 +94,7 @@ def write_phone_configurations phone_config[:phone], phone_config[:created_at], phone_config[:confirmed_at], + phone_config[:id], ] end end diff --git a/spec/fixtures/data_request.json b/spec/fixtures/data_request.json index a24d8f3614c..71a099d0e2b 100644 --- a/spec/fixtures/data_request.json +++ b/spec/fixtures/data_request.json @@ -13,6 +13,7 @@ "mfa_configurations": { "phone_configurations": [ { + "id": 123456, "phone": "+1 555-555-5555", "created_at": "2021-10-21T14:53:08.803Z", "confirmed_at": "2021-10-21T14:53:08.790Z" diff --git a/spec/lib/data_requests/deployed/create_mfa_configurations_report_spec.rb b/spec/lib/data_requests/deployed/create_mfa_configurations_report_spec.rb index d11712ed2d4..6477d692196 100644 --- a/spec/lib/data_requests/deployed/create_mfa_configurations_report_spec.rb +++ b/spec/lib/data_requests/deployed/create_mfa_configurations_report_spec.rb @@ -10,6 +10,7 @@ result = described_class.new(user).call phone_data = result[:phone_configurations] + expect(phone_data.first[:id]).to eq(phone_configuration.id) expect(phone_data.first[:phone]).to eq(phone_configuration.phone) expect(phone_data.first[:created_at]).to be_within(1.second).of( phone_configuration.created_at, diff --git a/spec/lib/data_requests/local/write_user_info_spec.rb b/spec/lib/data_requests/local/write_user_info_spec.rb index 22a8e704108..13acab62f04 100644 --- a/spec/lib/data_requests/local/write_user_info_spec.rb +++ b/spec/lib/data_requests/local/write_user_info_spec.rb @@ -31,12 +31,14 @@ expect(email_row['value']).to eq('test@example.com') expect(email_row['created_at']).to be_present expect(email_row['confirmed_at']).to be_present + expect(email_row['internal_id']).to be_nil phone_row = parsed.find { |r| r['type'] == 'Phone configuration' } expect(phone_row['uuid']).to eq(uuid) expect(phone_row['value']).to eq('+1 555-555-5555') expect(phone_row['created_at']).to be_present - expect(email_row['confirmed_at']).to be_present + expect(phone_row['confirmed_at']).to be_present + expect(phone_row['internal_id']).to be_present end context 'with a not_found user' do