From 276b1a8809ab04033e0d40c6d8a97ac209023685 Mon Sep 17 00:00:00 2001 From: jinliu9508 Date: Tue, 20 Jan 2026 01:27:12 -0500 Subject: [PATCH 1/2] fix: SDK stuck when login with restricted external ID --- .../operations/impl/executors/LoginUserOperationExecutor.kt | 2 ++ .../user/internal/operations/LoginUserOperationExecutorTests.kt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt index 46968b3e71..b9c39902e1 100644 --- a/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt +++ b/OneSignalSDK/onesignal/core/src/main/java/com/onesignal/user/internal/operations/impl/executors/LoginUserOperationExecutor.kt @@ -237,6 +237,8 @@ internal class LoginUserOperationExecutor( ExecutionResponse(ExecutionResult.FAIL_RETRY, retryAfterSeconds = ex.retryAfterSeconds) NetworkUtils.ResponseStatusType.UNAUTHORIZED -> ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED, retryAfterSeconds = ex.retryAfterSeconds) + NetworkUtils.ResponseStatusType.INVALID -> + ExecutionResponse(ExecutionResult.FAIL_NORETRY) else -> ExecutionResponse(ExecutionResult.FAIL_PAUSE_OPREPO) } diff --git a/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/operations/LoginUserOperationExecutorTests.kt b/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/operations/LoginUserOperationExecutorTests.kt index d80dc5531a..307a66544e 100644 --- a/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/operations/LoginUserOperationExecutorTests.kt +++ b/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/operations/LoginUserOperationExecutorTests.kt @@ -159,7 +159,7 @@ class LoginUserOperationExecutorTests : FunSpec({ val response = loginUserOperationExecutor.execute(operations) // Then - response.result shouldBe ExecutionResult.FAIL_PAUSE_OPREPO + response.result shouldBe ExecutionResult.FAIL_NORETRY coVerify(exactly = 1) { mockUserBackendService.createUser(appId, mapOf(), any(), any()) } } From 34ed43e602174b5457cc03e7ada8e3cf90af038b Mon Sep 17 00:00:00 2001 From: jinliu9508 Date: Tue, 20 Jan 2026 11:43:49 -0500 Subject: [PATCH 2/2] Update test with backend error 400 --- .../LoginUserOperationExecutorTests.kt | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/operations/LoginUserOperationExecutorTests.kt b/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/operations/LoginUserOperationExecutorTests.kt index 307a66544e..ec49d8bad4 100644 --- a/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/operations/LoginUserOperationExecutorTests.kt +++ b/OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/operations/LoginUserOperationExecutorTests.kt @@ -136,7 +136,7 @@ class LoginUserOperationExecutorTests : FunSpec({ coVerify(exactly = 1) { mockUserBackendService.createUser(appId, mapOf(), any(), any()) } } - test("login anonymous user fails with no retry when backend error condition exists") { + test("login anonymous user fails with no retry when hit with backend error 404") { // Given val mockUserBackendService = mockk() coEvery { mockUserBackendService.createUser(any(), any(), any(), any()) } throws BackendException(404, "NOT FOUND") @@ -158,6 +158,33 @@ class LoginUserOperationExecutorTests : FunSpec({ // When val response = loginUserOperationExecutor.execute(operations) + // Then + response.result shouldBe ExecutionResult.FAIL_PAUSE_OPREPO + coVerify(exactly = 1) { mockUserBackendService.createUser(appId, mapOf(), any(), any()) } + } + + test("login anonymous user fails with no retry when hit with backend error 400") { + // Given + val mockUserBackendService = mockk() + coEvery { mockUserBackendService.createUser(any(), any(), any(), any()) } throws BackendException(400, "INVALID") + + val mockIdentityOperationExecutor = mockk() + + val mockIdentityModelStore = MockHelper.identityModelStore() + val mockPropertiesModelStore = MockHelper.propertiesModelStore() + val mockSubscriptionsModelStore = mockk() + + val loginUserOperationExecutor = + LoginUserOperationExecutor(mockIdentityOperationExecutor, AndroidMockHelper.applicationService(), MockHelper.deviceService(), mockUserBackendService, mockIdentityModelStore, mockPropertiesModelStore, mockSubscriptionsModelStore, MockHelper.configModelStore(), MockHelper.languageContext()) + val operations = + listOf( + LoginUserOperation(appId, localOneSignalId, null, null), + createSubscriptionOperation, + ) + + // When + val response = loginUserOperationExecutor.execute(operations) + // Then response.result shouldBe ExecutionResult.FAIL_NORETRY coVerify(exactly = 1) { mockUserBackendService.createUser(appId, mapOf(), any(), any()) }