1
1
import type { Mock } from 'jest-mock' ;
2
+ import type { OnyxEntry } from 'react-native-onyx' ;
2
3
import MockedOnyx from 'react-native-onyx' ;
4
+ import * as App from '@libs/actions/App' ;
3
5
import CONST from '@src/CONST' ;
4
6
import OnyxUpdateManager from '@src/libs/actions/OnyxUpdateManager' ;
5
7
import * as PersistedRequests from '@src/libs/actions/PersistedRequests' ;
@@ -12,6 +14,7 @@ import * as MainQueue from '@src/libs/Network/MainQueue';
12
14
import * as NetworkStore from '@src/libs/Network/NetworkStore' ;
13
15
import NetworkConnection from '@src/libs/NetworkConnection' ;
14
16
import ONYXKEYS from '@src/ONYXKEYS' ;
17
+ import type { Session as OnyxSession } from '@src/types/onyx' ;
15
18
import type ReactNativeOnyxMock from '../../__mocks__/react-native-onyx' ;
16
19
import * as TestHelper from '../utils/TestHelper' ;
17
20
import waitForBatchedUpdates from '../utils/waitForBatchedUpdates' ;
@@ -50,7 +53,7 @@ afterEach(() => {
50
53
} ) ;
51
54
52
55
describe ( 'NetworkTests' , ( ) => {
53
- test ( 'failing to reauthenticate while offline should not log out user' , ( ) => {
56
+ test ( 'failing to reauthenticate should not log out user' , ( ) => {
54
57
// Given a test user login and account ID
55
58
const TEST_USER_LOGIN = '[email protected] ' ;
56
59
const TEST_USER_ACCOUNT_ID = 1 ;
@@ -130,6 +133,80 @@ describe('NetworkTests', () => {
130
133
} ) ;
131
134
} ) ;
132
135
136
+ test ( 'failing to reauthenticate while offline should not log out user' , async ( ) => {
137
+ const TEST_USER_LOGIN = '[email protected] ' ;
138
+ const TEST_USER_ACCOUNT_ID = 1 ;
139
+
140
+ let session : OnyxEntry < OnyxSession > ;
141
+ Onyx . connect ( {
142
+ key : ONYXKEYS . SESSION ,
143
+ callback : ( val ) => ( session = val ) ,
144
+ } ) ;
145
+
146
+ Onyx . connect ( {
147
+ key : ONYXKEYS . NETWORK ,
148
+ } ) ;
149
+
150
+ await TestHelper . signInWithTestUser ( TEST_USER_ACCOUNT_ID , TEST_USER_LOGIN ) ;
151
+ await waitForBatchedUpdates ( ) ;
152
+
153
+ expect ( session ?. authToken ) . not . toBeUndefined ( ) ;
154
+
155
+ // Turn off the network
156
+ await Onyx . set ( ONYXKEYS . NETWORK , { isOffline : true } ) ;
157
+
158
+ const mockedXhr = jest . fn ( ) ;
159
+ mockedXhr
160
+ // Call ReconnectApp with an expired token
161
+ . mockImplementationOnce ( ( ) =>
162
+ Promise . resolve ( {
163
+ jsonCode : CONST . JSON_CODE . NOT_AUTHENTICATED ,
164
+ } ) ,
165
+ )
166
+ // Call Authenticate
167
+ . mockImplementationOnce ( ( ) =>
168
+ Promise . resolve ( {
169
+ jsonCode : CONST . JSON_CODE . SUCCESS ,
170
+ authToken : 'newAuthToken' ,
171
+ } ) ,
172
+ )
173
+ // Call ReconnectApp again, it should connect with a new token
174
+ . mockImplementationOnce ( ( ) =>
175
+ Promise . resolve ( {
176
+ jsonCode : CONST . JSON_CODE . SUCCESS ,
177
+ } ) ,
178
+ ) ;
179
+
180
+ HttpUtils . xhr = mockedXhr ;
181
+
182
+ // Initiate the requests
183
+ App . confirmReadyToOpenApp ( ) ;
184
+ App . reconnectApp ( ) ;
185
+ await waitForBatchedUpdates ( ) ;
186
+
187
+ // Turn the network back online
188
+ await Onyx . set ( ONYXKEYS . NETWORK , { isOffline : false } ) ;
189
+
190
+ // Filter requests results by request name
191
+ const reconnectResults = ( HttpUtils . xhr as Mock ) . mock . results . filter ( ( _ , index ) => ( HttpUtils . xhr as Mock ) ?. mock ?. calls ?. at ( index ) ?. [ 0 ] === 'ReconnectApp' ) ;
192
+ const authenticateResults = ( HttpUtils . xhr as Mock ) . mock . results . filter ( ( _ , index ) => ( HttpUtils . xhr as Mock ) ?. mock ?. calls ?. at ( index ) ?. [ 0 ] === 'Authenticate' ) ;
193
+
194
+ // Get the response code of Authenticate call
195
+ const authenticateResponse = await ( authenticateResults ?. at ( 0 ) ?. value as Promise < { jsonCode : string } > ) ;
196
+
197
+ // Get the response code of the second Reconnect call
198
+ const reconnectResponse = await ( reconnectResults ?. at ( 1 ) ?. value as Promise < { jsonCode : string } > ) ;
199
+
200
+ // Authenticate request should return 200
201
+ expect ( authenticateResponse . jsonCode ) . toBe ( CONST . JSON_CODE . SUCCESS ) ;
202
+
203
+ // The second ReconnectApp should return 200
204
+ expect ( reconnectResponse . jsonCode ) . toBe ( CONST . JSON_CODE . SUCCESS ) ;
205
+
206
+ // check if the user is still logged in
207
+ expect ( session ?. authToken ) . not . toBeUndefined ( ) ;
208
+ } ) ;
209
+
133
210
test ( 'consecutive API calls eventually succeed when authToken is expired' , ( ) => {
134
211
// Given a test user login and account ID
135
212
const TEST_USER_LOGIN = '[email protected] ' ;
0 commit comments