Skip to content

Commit afa35fe

Browse files
committed
Add and adjust some test units for JWT related change
1 parent 2fe7364 commit afa35fe

File tree

7 files changed

+199
-7
lines changed

7 files changed

+199
-7
lines changed

OneSignalSDK/onesignal/core/src/test/java/com/onesignal/core/internal/operations/OperationRepoTests.kt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ import java.util.UUID
3939
private class Mocks {
4040
val configModelStore = MockHelper.configModelStore()
4141

42+
val identityModelStore =
43+
MockHelper.identityModelStore {
44+
it.jwtToken = ""
45+
it.externalId = "externalId1"
46+
}
47+
4248
val operationModelStore: OperationModelStore =
4349
run {
4450
val operationStoreList = mutableListOf<Operation>()
@@ -68,6 +74,7 @@ private class Mocks {
6874
listOf(executor),
6975
operationModelStore,
7076
configModelStore,
77+
identityModelStore,
7178
Time(),
7279
getNewRecordState(configModelStore),
7380
),
@@ -775,6 +782,48 @@ class OperationRepoTests : FunSpec({
775782
response2 shouldBe true
776783
opRepo.forceExecuteOperations()
777784
}
785+
786+
test("operations that need to be identity verified cannot execute until JWT is provided") {
787+
// Given
788+
val mocks = Mocks()
789+
val waiter = Waiter()
790+
791+
every { mocks.configModelStore.model.useIdentityVerification } returns true // set identity verification on
792+
every { mocks.identityModelStore.model.jwtToken } returns null // jwt is initially unset
793+
every { mocks.operationModelStore.remove(any()) } answers {} andThenAnswer { waiter.wake() }
794+
795+
val operation1 = mockOperation("operationId1")
796+
val operation2 = mockOperation("operationId2")
797+
798+
operation1.setStringProperty("externalId", "externalId1")
799+
operation2.setStringProperty("externalId", "externalId1")
800+
801+
// When
802+
mocks.operationRepo.enqueue(operation1)
803+
mocks.operationRepo.enqueue(operation2)
804+
mocks.operationRepo.start()
805+
806+
waiter.waitForWake()
807+
808+
// Then
809+
coVerifyOrder {
810+
mocks.operationModelStore.add(operation1)
811+
mocks.operationModelStore.add(operation2)
812+
}
813+
814+
//
815+
coVerify(exactly = 0) {
816+
mocks.executor.execute(
817+
withArg {
818+
it.count() shouldBe 2
819+
it[0] shouldBe operation1
820+
it[1] shouldBe operation2
821+
},
822+
)
823+
mocks.operationModelStore.remove("operationId1")
824+
mocks.operationModelStore.remove("operationId2")
825+
}
826+
}
778827
}) {
779828
companion object {
780829
private fun mockOperation(

OneSignalSDK/onesignal/core/src/test/java/com/onesignal/internal/OneSignalImpTests.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.onesignal.internal
22

3+
import android.content.Context
34
import com.onesignal.debug.LogLevel
45
import com.onesignal.debug.internal.logging.Logging
56
import io.kotest.assertions.throwables.shouldThrowUnit
67
import io.kotest.core.spec.style.FunSpec
78
import io.kotest.matchers.shouldBe
9+
import io.mockk.mockk
810

911
class OneSignalImpTests : FunSpec({
1012
beforeAny {
@@ -86,4 +88,16 @@ class OneSignalImpTests : FunSpec({
8688
}
8789
}
8890
}
91+
92+
test("When identity verification is on and no user is created, calling initWithContext will create a new user") {
93+
// Given
94+
val os = OneSignalImp()
95+
val appId = "tempAppId"
96+
val context = mockk<Context>()
97+
98+
// When
99+
os.initWithContext(context, appId)
100+
101+
// TODO
102+
}
89103
})

OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/UserManagerTests.kt

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
11
package com.onesignal.user.internal
22

3+
import com.onesignal.IUserJwtInvalidatedListener
34
import com.onesignal.core.internal.language.ILanguageContext
5+
import com.onesignal.core.internal.operations.ExecutionResponse
6+
import com.onesignal.core.internal.operations.ExecutionResult
7+
import com.onesignal.core.internal.operations.Operation
48
import com.onesignal.mocks.MockHelper
9+
import com.onesignal.user.internal.backend.CreateUserResponse
10+
import com.onesignal.user.internal.backend.IUserBackendService
11+
import com.onesignal.user.internal.backend.IdentityConstants
12+
import com.onesignal.user.internal.backend.PropertiesObject
13+
import com.onesignal.user.internal.operations.LoginUserOperation
14+
import com.onesignal.user.internal.operations.impl.executors.IdentityOperationExecutor
15+
import com.onesignal.user.internal.operations.impl.executors.LoginUserOperationExecutor
516
import com.onesignal.user.internal.subscriptions.ISubscriptionManager
617
import com.onesignal.user.internal.subscriptions.SubscriptionList
18+
import com.onesignal.user.internal.subscriptions.SubscriptionModelStore
719
import io.kotest.core.spec.style.FunSpec
820
import io.kotest.matchers.shouldBe
921
import io.kotest.matchers.shouldNotBe
22+
import io.mockk.coEvery
1023
import io.mockk.every
1124
import io.mockk.just
1225
import io.mockk.mockk
1326
import io.mockk.runs
1427
import io.mockk.slot
28+
import io.mockk.spyk
1529
import io.mockk.verify
1630

1731
class UserManagerTests : FunSpec({
@@ -141,7 +155,8 @@ class UserManagerTests : FunSpec({
141155
it.tags["my-tag-key1"] = "my-tag-value1"
142156
}
143157

144-
val userManager = UserManager(mockSubscriptionManager, MockHelper.identityModelStore(), propertiesModelStore, MockHelper.languageContext())
158+
val userManager =
159+
UserManager(mockSubscriptionManager, MockHelper.identityModelStore(), propertiesModelStore, MockHelper.languageContext())
145160

146161
// When
147162
val tagSnapshot1 = userManager.getTags()
@@ -191,4 +206,58 @@ class UserManagerTests : FunSpec({
191206
verify(exactly = 1) { mockSubscriptionManager.addSmsSubscription("+15558675309") }
192207
verify(exactly = 1) { mockSubscriptionManager.removeSmsSubscription("+15558675309") }
193208
}
209+
210+
test("login user with jwt calls onUserJwtInvalidated() when the jwt is unauthorized") {
211+
// Given
212+
val appId = "appId"
213+
val localOneSignalId = "local-onesignalId"
214+
val remoteOneSignalId = "remote-onesignalId"
215+
216+
// mock components
217+
val mockSubscriptionManager = mockk<ISubscriptionManager>()
218+
val mockIdentityModelStore = MockHelper.identityModelStore()
219+
val mockPropertiesModelStore = MockHelper.propertiesModelStore()
220+
val mockSubscriptionsModelStore = mockk<SubscriptionModelStore>()
221+
val mockLanguageContext = MockHelper.languageContext()
222+
223+
// mock backend service
224+
val mockUserBackendService = mockk<IUserBackendService>()
225+
coEvery { mockUserBackendService.createUser(any(), any(), any(), any()) } returns
226+
CreateUserResponse(mapOf(IdentityConstants.ONESIGNAL_ID to remoteOneSignalId), PropertiesObject(), listOf())
227+
228+
// mock operation for login user
229+
val mockIdentityOperationExecutor = mockk<IdentityOperationExecutor>()
230+
coEvery { mockIdentityOperationExecutor.execute(any()) } returns
231+
ExecutionResponse(ExecutionResult.FAIL_UNAUTHORIZED)
232+
val loginUserOperationExecutor =
233+
LoginUserOperationExecutor(
234+
mockIdentityOperationExecutor,
235+
MockHelper.applicationService(),
236+
MockHelper.deviceService(),
237+
mockUserBackendService,
238+
mockIdentityModelStore,
239+
mockPropertiesModelStore,
240+
mockSubscriptionsModelStore,
241+
MockHelper.configModelStore(),
242+
mockLanguageContext,
243+
)
244+
val operations = listOf<Operation>(LoginUserOperation(appId, localOneSignalId, "externalId", "existingOneSignalId"))
245+
246+
// mock user manager with jwtInvalidatedListener added
247+
val userManager =
248+
UserManager(mockSubscriptionManager, mockIdentityModelStore, mockPropertiesModelStore, mockLanguageContext)
249+
mockIdentityModelStore.subscribe(userManager)
250+
val spyJwtInvalidatedListener = spyk<IUserJwtInvalidatedListener>()
251+
userManager.addUserJwtInvalidatedListener(spyJwtInvalidatedListener)
252+
253+
// When
254+
val response = loginUserOperationExecutor.execute(operations)
255+
256+
// Then
257+
userManager.jwtInvalidatedCallback.hasSubscribers shouldBe true
258+
response.result shouldBe ExecutionResult.FAIL_UNAUTHORIZED
259+
verify(exactly = 1) { mockIdentityModelStore.invalidateJwt() }
260+
// Note: set the default value of useIdentityVerification in OneSignalImp.kt to pass the test
261+
verify(exactly = 1) { spyJwtInvalidatedListener.onUserJwtInvalidated(any()) }
262+
}
194263
})

OneSignalSDK/onesignal/core/src/test/java/com/onesignal/user/internal/migrations/RecoverFromDroppedLoginBugTests.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ private class Mocks {
3636
listOf(),
3737
operationModelStore,
3838
configModelStore,
39+
MockHelper.identityModelStore(),
3940
Time(),
4041
ExecutorMocks.getNewRecordState(configModelStore),
4142
),

0 commit comments

Comments
 (0)