1
1
package com.onesignal.core.internal.operations
2
2
3
3
import com.onesignal.common.threading.Waiter
4
+ import com.onesignal.common.threading.WaiterWithValue
4
5
import com.onesignal.core.internal.operations.impl.OperationModelStore
5
6
import com.onesignal.core.internal.operations.impl.OperationRepo
6
7
import com.onesignal.core.internal.time.impl.Time
@@ -44,17 +45,16 @@ private class Mocks {
44
45
mockExecutor
45
46
}
46
47
47
- val operationRepo: OperationRepo =
48
- run {
49
- spyk(
50
- OperationRepo (
51
- listOf (executor),
52
- operationModelStore,
53
- configModelStore,
54
- Time (),
55
- ),
56
- )
57
- }
48
+ val operationRepo: OperationRepo by lazy {
49
+ spyk(
50
+ OperationRepo (
51
+ listOf (executor),
52
+ operationModelStore,
53
+ configModelStore,
54
+ Time (),
55
+ ),
56
+ )
57
+ }
58
58
}
59
59
60
60
class OperationRepoTests : FunSpec ({
@@ -136,7 +136,8 @@ class OperationRepoTests : FunSpec({
136
136
test("enqueue operation executes and is removed when executed after retry") {
137
137
// Given
138
138
val mocks = Mocks ()
139
- coEvery { mocks.operationRepo.delayBeforeRetry(any()) } just runs
139
+ val opRepo = mocks.operationRepo
140
+ coEvery { opRepo.delayBeforeRetry(any()) } just runs
140
141
coEvery {
141
142
mocks.executor.execute(any())
142
143
} returns ExecutionResponse (ExecutionResult .FAIL_RETRY ) andThen ExecutionResponse (ExecutionResult .SUCCESS )
@@ -145,8 +146,8 @@ class OperationRepoTests : FunSpec({
145
146
val operation = mockOperation(operationIdSlot = operationIdSlot)
146
147
147
148
// When
148
- mocks.operationRepo .start()
149
- val response = mocks.operationRepo .enqueueAndWait(operation)
149
+ opRepo .start()
150
+ val response = opRepo .enqueueAndWait(operation)
150
151
151
152
// Then
152
153
response shouldBe true
@@ -159,7 +160,7 @@ class OperationRepoTests : FunSpec({
159
160
it[0] shouldBe operation
160
161
},
161
162
)
162
- mocks.operationRepo .delayBeforeRetry(1)
163
+ opRepo .delayBeforeRetry(1)
163
164
mocks.executor.execute(
164
165
withArg {
165
166
it.count() shouldBe 1
@@ -426,6 +427,32 @@ class OperationRepoTests : FunSpec({
426
427
opRepo.executeOperations(any())
427
428
}
428
429
}
430
+
431
+ // Starting operations are operations we didn't process the last time the app was running.
432
+ // We want to ensure we process them, but only after the standard batching delay to be as
433
+ // optional as possible with network calls.
434
+ test("starting OperationModelStore should be processed, following normal delay rules") {
435
+ // Given
436
+ val mocks = Mocks ()
437
+ mocks.configModelStore.model.opRepoExecutionInterval = 100
438
+ every { mocks.operationModelStore.list() } returns listOf(mockOperation())
439
+ val executeOperationsCall = mockExecuteOperations(mocks.operationRepo)
440
+
441
+ // When
442
+ mocks.operationRepo.start()
443
+ val immediateResult =
444
+ withTimeoutOrNull(100) {
445
+ executeOperationsCall.waitForWake()
446
+ }
447
+ val delayedResult =
448
+ withTimeoutOrNull(200) {
449
+ executeOperationsCall.waitForWake()
450
+ }
451
+
452
+ // Then
453
+ immediateResult shouldBe null
454
+ delayedResult shouldBe true
455
+ }
429
456
}) {
430
457
companion object {
431
458
private fun mockOperation (
@@ -454,10 +481,10 @@ class OperationRepoTests : FunSpec({
454
481
455
482
private fun mockOperationNonGroupable () = mockOperation(groupComparisonType = GroupComparisonType .NONE )
456
483
457
- private fun mockExecuteOperations (opRepo : OperationRepo ): Waiter {
458
- val executeWaiter = Waiter ()
484
+ private fun mockExecuteOperations (opRepo : OperationRepo ): WaiterWithValue < Boolean > {
485
+ val executeWaiter = WaiterWithValue < Boolean > ()
459
486
coEvery { opRepo.executeOperations(any()) } coAnswers {
460
- executeWaiter.wake()
487
+ executeWaiter.wake(true )
461
488
delay(10 )
462
489
firstArg<List <OperationRepo .OperationQueueItem >>().forEach { it.waiter?.wake(true ) }
463
490
}
0 commit comments