Skip to content

Commit ac83f9e

Browse files
Use mhv_user_account cached response or nil on User (#20216)
1 parent 91f74de commit ac83f9e

File tree

7 files changed

+162
-55
lines changed

7 files changed

+162
-55
lines changed

app/models/user.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def mhv_correlation_id
160160
end
161161

162162
def mhv_user_account
163-
@mhv_user_account ||= MHV::UserAccount::Creator.new(user_verification:).perform
163+
@mhv_user_account ||= MHV::UserAccount::Creator.new(user_verification:, from_cache_only: true).perform
164164
rescue => e
165165
log_mhv_user_account_error(e.message)
166166
nil

app/services/mhv/user_account/creator.rb

+11-5
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
module MHV
66
module UserAccount
77
class Creator
8-
attr_reader :user_verification, :break_cache
8+
attr_reader :user_verification, :break_cache, :from_cache_only
99

10-
def initialize(user_verification:, break_cache: false)
10+
def initialize(user_verification:, break_cache: false, from_cache_only: false)
1111
@user_verification = user_verification
1212
@break_cache = break_cache
13+
@from_cache_only = from_cache_only
1314
end
1415

1516
def perform
@@ -30,16 +31,17 @@ def perform
3031
private
3132

3233
def create_mhv_user_account!
34+
return nil if mhv_account_creation_response.nil? && from_cache_only
35+
3336
account = MHVUserAccount.new(mhv_account_creation_response)
3437
account.validate!
3538
MPIData.find(icn)&.destroy
3639
account
3740
end
3841

3942
def mhv_account_creation_response
40-
tou_occurred_at = current_tou_agreement.created_at
41-
42-
mhv_client.create_account(icn:, email:, tou_occurred_at:, break_cache:)
43+
@mhv_account_creation_response ||= mhv_client.create_account(icn:, email:, tou_occurred_at:, break_cache:,
44+
from_cache_only:)
4345
end
4446

4547
def icn
@@ -58,6 +60,10 @@ def user_account
5860
@user_account ||= user_verification.user_account
5961
end
6062

63+
def tou_occurred_at
64+
current_tou_agreement.created_at
65+
end
66+
6167
def mhv_client
6268
MHV::AccountCreation::Service.new
6369
end

lib/mhv/account_creation/service.rb

+14-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ module AccountCreation
77
class Service < Common::Client::Base
88
configuration Configuration
99

10-
def create_account(icn:, email:, tou_occurred_at:, break_cache: false)
10+
def create_account(icn:, email:, tou_occurred_at:, break_cache: false, from_cache_only: false)
11+
return find_cached_response(icn) if from_cache_only
12+
1113
params = build_create_account_params(icn:, email:, tou_occurred_at:)
1214

1315
create_account_with_cache(icn:, force: break_cache, expires_in: 1.day) do
@@ -23,6 +25,17 @@ def create_account(icn:, email:, tou_occurred_at:, break_cache: false)
2325

2426
private
2527

28+
def find_cached_response(icn)
29+
account = Rails.cache.read("#{config.service_name}_#{icn}")
30+
31+
if account.present?
32+
log_payload = { icn:, account:, from_cache: true, from_cache_only: true }
33+
Rails.logger.info("#{config.logging_prefix} create_account success", log_payload)
34+
end
35+
36+
account
37+
end
38+
2639
def create_account_with_cache(icn:, force:, expires_in:, &request)
2740
cache_hit = true
2841
start = nil

spec/controllers/v0/user/mhv_user_accounts_controller_spec.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050
expect(mhv_client).to have_received(:create_account).with(icn:,
5151
email: user_credential_email.credential_email,
5252
tou_occurred_at: terms_of_use_agreement.created_at,
53-
break_cache: true)
53+
break_cache: true,
54+
from_cache_only: false)
5455
end
5556
end
5657

spec/lib/mhv/account_creation/service_spec.rb

+52-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
describe MHV::AccountCreation::Service do
77
describe '#create_account' do
8-
subject { described_class.new.create_account(icn:, email:, tou_occurred_at:, break_cache:) }
8+
subject { described_class.new.create_account(icn:, email:, tou_occurred_at:, break_cache:, from_cache_only:) }
99

1010
let(:icn) { '10101V964144' }
1111
let(:email) { '[email protected]' }
@@ -16,9 +16,20 @@
1616
let(:account_creation_base_url) { 'https://apigw-intb.aws.myhealth.va.gov' }
1717
let(:account_creation_path) { 'v1/usermgmt/account-service/account' }
1818
let(:break_cache) { false }
19+
let(:from_cache_only) { false }
1920
let(:start_time) { Time.zone.now }
2021
let(:end_time) { start_time + 10.seconds }
2122

23+
let(:user_profile_id) { '12345678' }
24+
let(:premium) { true }
25+
let(:champ_va) { true }
26+
let(:patient) { true }
27+
let(:sm_account_created) { true }
28+
let(:message) { 'Existing MHV Account Found for ICN' }
29+
let(:expected_response_body) do
30+
{ user_profile_id:, premium:, champ_va:, patient:, sm_account_created:, message: }
31+
end
32+
2233
before do
2334
allow(Rails.logger).to receive(:info)
2435
allow(Rails.logger).to receive(:error)
@@ -47,22 +58,53 @@
4758
end
4859
end
4960

61+
context 'when from_cache_only is true' do
62+
let(:from_cache_only) { true }
63+
let(:expected_cache_key) { "mhv_account_creation_#{icn}" }
64+
65+
context 'when the account is in the cache' do
66+
before do
67+
allow(Rails.cache).to receive(:read).with(expected_cache_key).and_return(expected_response_body)
68+
end
69+
70+
it 'returns the cached response' do
71+
expect(subject).to eq(expected_response_body)
72+
end
73+
74+
it 'does not make a request to the account creation service' do
75+
subject
76+
expect(a_request(:post, "#{account_creation_base_url}/#{account_creation_path}")).not_to have_been_made
77+
expect(Rails.logger).not_to have_received(:info).with("#{log_prefix} create_account request",
78+
anything)
79+
end
80+
end
81+
82+
context 'when the account is not in the cache' do
83+
before do
84+
allow(Rails.cache).to receive(:read).with(expected_cache_key).and_return(nil)
85+
end
86+
87+
it 'returns nil' do
88+
expect(subject).to be_nil
89+
end
90+
91+
it 'does not make a request to the account creation service' do
92+
subject
93+
expect(a_request(:post, "#{account_creation_base_url}/#{account_creation_path}")).not_to have_been_made
94+
expect(Rails.logger).not_to have_received(:info).with("#{log_prefix} create_account request",
95+
anything)
96+
end
97+
end
98+
end
99+
50100
context 'when the response is successful' do
51101
let(:successful_response_cassette) { 'mhv/account_creation/account_creation_service_200_found' }
52102
let(:expected_log_message) { "#{log_prefix} create_account success" }
53103
let(:expected_log_payload) do
54104
{ icn:, account: expected_response_body, from_cache: expected_from_cache_log,
55105
duration_ms: expected_duration }.compact
56106
end
57-
let(:user_profile_id) { '12345678' }
58-
let(:premium) { true }
59-
let(:champ_va) { true }
60-
let(:patient) { true }
61-
let(:sm_account_created) { true }
62-
let(:message) { 'Existing MHV Account Found for ICN' }
63-
let(:expected_response_body) do
64-
{ user_profile_id:, premium:, champ_va:, patient:, sm_account_created:, message: }
65-
end
107+
66108
let(:expected_duration) { 10_000.0 }
67109

68110
shared_examples 'a successful external request' do

spec/models/user_spec.rb

+44-33
Original file line numberDiff line numberDiff line change
@@ -1399,6 +1399,7 @@
13991399
describe '#mhv_user_account' do
14001400
let(:user) { build(:user, :loa3) }
14011401
let(:icn) { user.icn }
1402+
let(:expected_cache_key) { "mhv_account_creation_#{icn}" }
14021403

14031404
let!(:user_verification) do
14041405
create(:idme_user_verification, idme_uuid: user.idme_uuid, user_credential_email:, user_account:)
@@ -1423,55 +1424,65 @@
14231424
before do
14241425
allow(Rails.logger).to receive(:info)
14251426
allow(MHV::AccountCreation::Service).to receive(:new).and_return(mhv_client)
1426-
allow(mhv_client).to receive(:create_account).and_return(mhv_response)
1427+
allow(Rails.cache).to receive(:read).with(expected_cache_key).and_return(mhv_response)
14271428
end
14281429

1429-
context 'when the user has all required attributes' do
1430-
it 'returns a MHVUserAccount with the expected attributes' do
1431-
mhv_user_account = user.mhv_user_account
1430+
context 'when the mhv response is cached' do
1431+
context 'when the user has all required attributes' do
1432+
it 'returns a MHVUserAccount with the expected attributes' do
1433+
mhv_user_account = user.mhv_user_account
14321434

1433-
expect(mhv_user_account).to be_a(MHVUserAccount)
1434-
expect(mhv_user_account.attributes).to eq(mhv_response.with_indifferent_access)
1435+
expect(mhv_user_account).to be_a(MHVUserAccount)
1436+
expect(mhv_user_account.attributes).to eq(mhv_response.with_indifferent_access)
1437+
end
14351438
end
1436-
end
14371439

1438-
context 'when there is an error creating the account' do
1439-
shared_examples 'mhv_user_account error' do
1440-
let(:expected_log_message) { '[User] mhv_user_account error' }
1441-
let(:expected_log_payload) { { error_message: /#{expected_error_message}/, icn: user.icn } }
1440+
context 'when there is an error creating the account' do
1441+
shared_examples 'mhv_user_account error' do
1442+
let(:expected_log_message) { '[User] mhv_user_account error' }
1443+
let(:expected_log_payload) { { error_message: /#{expected_error_message}/, icn: user.icn } }
14421444

1443-
it 'logs and returns nil' do
1444-
expect(user.mhv_user_account).to be_nil
1445-
expect(Rails.logger).to have_received(:info).with(expected_log_message, expected_log_payload)
1445+
it 'logs and returns nil' do
1446+
expect(user.mhv_user_account).to be_nil
1447+
expect(Rails.logger).to have_received(:info).with(expected_log_message, expected_log_payload)
1448+
end
14461449
end
1447-
end
14481450

1449-
context 'when the user does not have a terms_of_use_agreement' do
1450-
let(:terms_of_use_agreement) { nil }
1451-
let(:expected_error_message) { 'Current terms of use agreement must be present' }
1451+
context 'when the user does not have a terms_of_use_agreement' do
1452+
let(:terms_of_use_agreement) { nil }
1453+
let(:expected_error_message) { 'Current terms of use agreement must be present' }
14521454

1453-
it_behaves_like 'mhv_user_account error'
1454-
end
1455+
it_behaves_like 'mhv_user_account error'
1456+
end
14551457

1456-
context 'when the user has not accepted the terms of use' do
1457-
let(:terms_of_use_response) { 'declined' }
1458-
let(:expected_error_message) { "Current terms of use agreement must be 'accepted'" }
1458+
context 'when the user has not accepted the terms of use' do
1459+
let(:terms_of_use_response) { 'declined' }
1460+
let(:expected_error_message) { "Current terms of use agreement must be 'accepted'" }
14591461

1460-
it_behaves_like 'mhv_user_account error'
1461-
end
1462+
it_behaves_like 'mhv_user_account error'
1463+
end
1464+
1465+
context 'when the user does not have a user_credential_email' do
1466+
let(:user_credential_email) { nil }
1467+
let(:expected_error_message) { 'Email must be present' }
1468+
1469+
it_behaves_like 'mhv_user_account error'
1470+
end
14621471

1463-
context 'when the user does not have a user_credential_email' do
1464-
let(:user_credential_email) { nil }
1465-
let(:expected_error_message) { 'Email must be present' }
1472+
context 'when the user does not have an icn' do
1473+
let(:icn) { nil }
1474+
let(:expected_error_message) { 'ICN must be present' }
14661475

1467-
it_behaves_like 'mhv_user_account error'
1476+
it_behaves_like 'mhv_user_account error'
1477+
end
14681478
end
1479+
end
14691480

1470-
context 'when the user does not have an icn' do
1471-
let(:icn) { nil }
1472-
let(:expected_error_message) { 'ICN must be present' }
1481+
context 'when the mhv response is not cached' do
1482+
let(:mhv_response) { nil }
14731483

1474-
it_behaves_like 'mhv_user_account error'
1484+
it 'returns nil' do
1485+
expect(user.mhv_user_account).to be_nil
14751486
end
14761487
end
14771488
end

spec/services/mhv/user_account/creator_spec.rb

+38-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
require 'mhv/account_creation/service'
55

66
RSpec.describe MHV::UserAccount::Creator do
7-
subject { described_class.new(user_verification:, break_cache:) }
7+
subject { described_class.new(user_verification:, break_cache:, from_cache_only:) }
88

99
let(:user_account) { create(:user_account, icn:) }
1010
let(:user_verification) { create(:user_verification, user_account:, user_credential_email:) }
@@ -14,6 +14,7 @@
1414
let(:email) { '[email protected]' }
1515
let(:tou_occurred_at) { terms_of_use_agreement&.created_at }
1616
let(:break_cache) { false }
17+
let(:from_cache_only) { false }
1718
let(:mhv_client) { instance_double(MHV::AccountCreation::Service) }
1819
let(:mhv_response_body) do
1920
{
@@ -30,7 +31,7 @@
3031

3132
allow(MHV::AccountCreation::Service).to receive(:new).and_return(mhv_client)
3233
allow(mhv_client).to receive(:create_account)
33-
.with(icn:, email:, tou_occurred_at:, break_cache:)
34+
.with(icn:, email:, tou_occurred_at:, break_cache:, from_cache_only:)
3435
.and_return(mhv_response_body)
3536
end
3637

@@ -80,7 +81,8 @@
8081
context 'when break_cache is false' do
8182
it 'calls MHV::AccountCreation::Service#create_account with break_cache: false' do
8283
subject.perform
83-
expect(mhv_client).to have_received(:create_account).with(icn:, email:, tou_occurred_at:, break_cache: false)
84+
expect(mhv_client).to have_received(:create_account).with(icn:, email:, tou_occurred_at:, break_cache: false,
85+
from_cache_only:)
8486
end
8587
end
8688

@@ -89,7 +91,39 @@
8991

9092
it 'calls MHV::AccountCreation::Service#create_account with break_cache: true' do
9193
subject.perform
92-
expect(mhv_client).to have_received(:create_account).with(icn:, email:, tou_occurred_at:, break_cache: true)
94+
expect(mhv_client).to have_received(:create_account).with(icn:, email:, tou_occurred_at:, break_cache: true,
95+
from_cache_only:)
96+
end
97+
end
98+
99+
context 'when from_cache_only is true' do
100+
let(:from_cache_only) { true }
101+
let(:expected_cache_key) { "mhv_account_creation_#{icn}" }
102+
103+
before do
104+
allow(Rails.cache).to receive(:read).with(expected_cache_key).and_return(mhv_response_body)
105+
end
106+
107+
it 'calls MHV::AccountCreation::Service#create_account with from_cache_only: true' do
108+
subject.perform
109+
expect(mhv_client).to have_received(:create_account).with(icn:, email:, tou_occurred_at:, break_cache:,
110+
from_cache_only: true)
111+
end
112+
113+
context 'when the response is cached' do
114+
it 'returns the cached response' do
115+
mhv_user_account = subject.perform
116+
expect(mhv_user_account).to be_a(MHVUserAccount)
117+
expect(mhv_user_account).to be_valid
118+
end
119+
end
120+
121+
context 'when the response is not cached' do
122+
let(:mhv_response_body) { nil }
123+
124+
it 'returns nil' do
125+
expect(subject.perform).to be_nil
126+
end
93127
end
94128
end
95129
end

0 commit comments

Comments
 (0)