@@ -3,7 +3,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
33import waitForBatchedUpdates from '../utils/waitForBatchedUpdates' ;
44
55const mockSetAuthenticationData = jest . fn ( ) ;
6- const mockSetAttribute = jest . fn ( ) ;
6+ const mockSetAttribute = jest . fn < void , unknown [ ] > ( ) ;
77
88jest . mock ( '@libs/FraudProtection/GroupIBSdkBridge' , ( ) => ( {
99 init : jest . fn ( ) ,
@@ -12,15 +12,26 @@ jest.mock('@libs/FraudProtection/GroupIBSdkBridge', () => ({
1212 setAuthenticationData : mockSetAuthenticationData ,
1313} ) ) ;
1414
15- // Load the module once. Onyx connections are registered at module scope.
15+ // Captured snapshot of the setAttribute calls made by FraudProtection's initial sweep when it loads with an
16+ // already-authenticated session in Onyx. Captured in beforeAll so the restored-session assertions can read it
17+ // after beforeEach clears the live mock state for the rest of the tests.
18+ let initialSweepSetAttributeCalls : unknown [ ] [ ] = [ ] ;
1619
17- require ( '@libs/FraudProtection' ) ;
20+ beforeAll ( async ( ) => {
21+ Onyx . init ( { keys : ONYXKEYS } ) ;
1822
19- beforeAll ( ( ) =>
20- Onyx . init ( {
21- keys : ONYXKEYS ,
22- } ) ,
23- ) ;
23+ // Pre-populate Onyx with a restored session BEFORE loading FraudProtection so the module's initial session
24+ // callback observes an existing authToken without first observing a signed-out state — the "session restored
25+ // from disk on app boot" scenario.
26+ await Onyx . merge ( ONYXKEYS . ACCOUNT , { primaryLogin : 'restored@expensify.com' , requiresTwoFactorAuth : false , validated : true } ) ;
27+ await Onyx . merge ( ONYXKEYS . SESSION , { authToken : 'restoredToken' , accountID : 99 , authMethod : 'google' } ) ;
28+ await waitForBatchedUpdates ( ) ;
29+
30+ require ( '@libs/FraudProtection' ) ;
31+ await waitForBatchedUpdates ( ) ;
32+
33+ initialSweepSetAttributeCalls = mockSetAttribute . mock . calls . slice ( ) ;
34+ } ) ;
2435
2536beforeEach ( async ( ) => {
2637 await Onyx . clear ( ) ;
@@ -171,4 +182,19 @@ describe('FraudProtection', () => {
171182
172183 expect ( mockSetAttribute ) . toHaveBeenCalledWith ( 'mfa' , '2fa_disabled' , false , true ) ;
173184 } ) ;
185+
186+ it ( 'should forward session.authMethod as the authentication attribute on a fresh sign-in' , async ( ) => {
187+ await Onyx . merge ( ONYXKEYS . ACCOUNT , { primaryLogin : 'user@expensify.com' , requiresTwoFactorAuth : false , validated : true } ) ;
188+ await Onyx . merge ( ONYXKEYS . SESSION , { authToken : 'token123' , accountID : 12345 , authMethod : 'shortLivedAuthToken' } ) ;
189+ await waitForBatchedUpdates ( ) ;
190+
191+ expect ( mockSetAttribute ) . toHaveBeenCalledWith ( 'authentication' , 'shortLivedAuthToken' , false , true ) ;
192+ } ) ;
193+
194+ it ( 'should report authentication=infiniteSession when an authenticated session is restored on app boot' , ( ) => {
195+ // Asserts against the snapshot captured in beforeAll. Even though the restored session stores
196+ // authMethod='google', the freshly-loaded module overrides it with infiniteSession because no
197+ // signed-out state was observed during this lifetime.
198+ expect ( initialSweepSetAttributeCalls ) . toContainEqual ( [ 'authentication' , 'infiniteSession' , false , true ] ) ;
199+ } ) ;
174200} ) ;
0 commit comments