@@ -165,5 +165,126 @@ final class IdentityExecutorTests: XCTestCase {
165165 XCTAssertTrue ( invalidatedCallbackWasCalled)
166166 }
167167
168+ func testAddAliasRequests_Retry_OnTokenUpdate( ) {
169+
170+ /* Setup */
171+ let mocks = Mocks ( )
172+ mocks. setAuthRequired ( true )
173+ OneSignalUserManagerImpl . sharedInstance. operationRepo. paused = true
174+
175+ let user = mocks. setUserManagerInternalUser ( externalId: userA_EUID, onesignalId: userA_OSID)
176+ user. identityModel. jwtBearerToken = userA_InvalidJwtToken
177+
178+ // We need to use the user manager's executor because the onJWTUpdated callback won't fire on the mock executor
179+ let executor = OneSignalUserManagerImpl . sharedInstance. identityExecutor!
180+
181+ let aliases = userA_Aliases
182+ MockUserRequests . setUnauthorizedAddAliasFailureResponse ( with: mocks. client, aliases: userA_Aliases)
183+ executor. enqueueDelta ( OSDelta ( name: OS_ADD_ALIAS_DELTA, identityModelId: user. identityModel. modelId, model: user. identityModel, property: " aliases " , value: aliases) )
184+
185+ var invalidatedCallbackWasCalled = false
186+ OneSignalUserManagerImpl . sharedInstance. User. onJwtInvalidated { event in
187+ invalidatedCallbackWasCalled = true
188+ MockUserRequests . setAddAliasesResponse ( with: mocks. client, aliases: aliases)
189+ OneSignalUserManagerImpl . sharedInstance. updateUserJwt ( externalId: userA_EUID, token: userA_ValidJwtToken)
190+ }
191+
192+ /* When */
193+ executor. processDeltaQueue ( inBackground: false )
194+ OneSignalCoreMocks . waitForBackgroundThreads ( seconds: 0.5 )
195+
196+ /* Then */
197+ XCTAssertTrue ( mocks. client. hasExecutedRequestOfType ( OSRequestAddAliases . self) )
198+ XCTAssertTrue ( invalidatedCallbackWasCalled)
199+ XCTAssertEqual ( mocks. client. networkRequestCount, 2 )
200+ }
201+
202+ func testAddAliasRequests_RetryRequests_OnTokenUpdate_ForOnlyUpdatedUser( ) {
203+ /* Setup */
204+ let mocks = Mocks ( )
205+
206+ mocks. setAuthRequired ( true )
207+
208+ let userA = mocks. setUserManagerInternalUser ( externalId: userA_EUID, onesignalId: userA_OSID)
209+ userA. identityModel. jwtBearerToken = userA_InvalidJwtToken
210+
211+ let userB = mocks. setUserManagerInternalUser ( externalId: userB_EUID, onesignalId: userB_OSID)
212+ userB. identityModel. jwtBearerToken = userA_InvalidJwtToken
213+ // We need to use the user manager's executor because the onJWTUpdated callback won't fire on the mock executor
214+ let executor = OneSignalUserManagerImpl . sharedInstance. identityExecutor!
215+
216+ let aliases = userA_Aliases
217+ MockUserRequests . setUnauthorizedAddAliasFailureResponse ( with: mocks. client, aliases: userA_Aliases)
218+
219+ executor. enqueueDelta ( OSDelta ( name: OS_ADD_ALIAS_DELTA, identityModelId: userA. identityModel. modelId, model: userA. identityModel, property: " aliases " , value: aliases) )
220+ executor. enqueueDelta ( OSDelta ( name: OS_ADD_ALIAS_DELTA, identityModelId: userB. identityModel. modelId, model: userB. identityModel, property: " aliases " , value: aliases) )
221+
222+ var invalidatedCallbackWasCalled = false
223+ OneSignalUserManagerImpl . sharedInstance. User. onJwtInvalidated { event in
224+ invalidatedCallbackWasCalled = true
225+ }
226+
227+ /* When */
228+ executor. processDeltaQueue ( inBackground: false )
229+ OneSignalCoreMocks . waitForBackgroundThreads ( seconds: 0.5 )
230+
231+ MockUserRequests . setAddAliasesResponse ( with: mocks. client, aliases: aliases)
232+ OneSignalUserManagerImpl . sharedInstance. updateUserJwt ( externalId: userB_EUID, token: userB_ValidJwtToken)
233+
234+ OneSignalCoreMocks . waitForBackgroundThreads ( seconds: 0.5 )
235+
236+ /* Then */
237+ // The executor should execute this request since identity verification is required and the token was set
238+ XCTAssertTrue ( mocks. client. hasExecutedRequestOfType ( OSRequestAddAliases . self) )
239+ XCTAssertTrue ( invalidatedCallbackWasCalled)
240+ let addAliasRequests = mocks. client. executedRequests. filter { request in
241+ request. isKind ( of: OSRequestAddAliases . self)
242+ }
243+ // It is 4 because setting user B's OneSignal ID counts as an add alias request
244+ XCTAssertEqual ( addAliasRequests. count, 4 )
245+ }
168246
247+ func testRemoveAliasRequests_RetryRequests_OnTokenUpdate_ForOnlyUpdatedUser( ) {
248+ /* Setup */
249+ let mocks = Mocks ( )
250+
251+ mocks. setAuthRequired ( true )
252+
253+ let userA = mocks. setUserManagerInternalUser ( externalId: userA_EUID, onesignalId: userA_OSID)
254+ userA. identityModel. jwtBearerToken = userA_InvalidJwtToken
255+
256+ let userB = mocks. setUserManagerInternalUser ( externalId: userB_EUID, onesignalId: userB_OSID)
257+ userB. identityModel. jwtBearerToken = userA_InvalidJwtToken
258+ // We need to use the user manager's executor because the onJWTUpdated callback won't fire on the mock executor
259+ let executor = OneSignalUserManagerImpl . sharedInstance. identityExecutor!
260+
261+ let aliases = userA_Aliases
262+ MockUserRequests . setUnauthorizedRemoveAliasFailureResponse ( with: mocks. client, aliasLabel: userA_AliasLabel)
263+
264+ executor. enqueueDelta ( OSDelta ( name: OS_REMOVE_ALIAS_DELTA, identityModelId: userA. identityModel. modelId, model: userA. identityModel, property: " aliases " , value: aliases) )
265+ executor. enqueueDelta ( OSDelta ( name: OS_REMOVE_ALIAS_DELTA, identityModelId: userB. identityModel. modelId, model: userB. identityModel, property: " aliases " , value: aliases) )
266+
267+ var invalidatedCallbackWasCalled = false
268+ OneSignalUserManagerImpl . sharedInstance. User. onJwtInvalidated { event in
269+ invalidatedCallbackWasCalled = true
270+ }
271+
272+ /* When */
273+ executor. processDeltaQueue ( inBackground: false )
274+ OneSignalCoreMocks . waitForBackgroundThreads ( seconds: 0.5 )
275+
276+ OneSignalUserManagerImpl . sharedInstance. updateUserJwt ( externalId: userB_EUID, token: userB_ValidJwtToken)
277+
278+ OneSignalCoreMocks . waitForBackgroundThreads ( seconds: 0.5 )
279+
280+ /* Then */
281+ // The executor should execute this request since identity verification is required and the token was set
282+ XCTAssertTrue ( mocks. client. hasExecutedRequestOfType ( OSRequestRemoveAlias . self) )
283+ XCTAssertTrue ( invalidatedCallbackWasCalled)
284+ let removeAliasRequests = mocks. client. executedRequests. filter { request in
285+ request. isKind ( of: OSRequestRemoveAlias . self)
286+ }
287+
288+ XCTAssertEqual ( removeAliasRequests. count, 3 )
289+ }
169290}
0 commit comments