@@ -165,5 +165,126 @@ final class IdentityExecutorTests: XCTestCase {
165
165
XCTAssertTrue ( invalidatedCallbackWasCalled)
166
166
}
167
167
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
+ }
168
246
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
+ }
169
290
}
0 commit comments