@@ -23,7 +23,9 @@ import io.mockk.slot
23
23
import io.mockk.spyk
24
24
import io.mockk.verify
25
25
import kotlinx.coroutines.delay
26
+ import kotlinx.coroutines.launch
26
27
import kotlinx.coroutines.withTimeoutOrNull
28
+ import kotlinx.coroutines.yield
27
29
28
30
// Mocks used by every test in this file
29
31
private class Mocks {
@@ -485,6 +487,54 @@ class OperationRepoTests : FunSpec({
485
487
executor.execute(withArg { it[0] shouldBe secondOp })
486
488
}
487
489
}
490
+
491
+ // This is to account for the case where we create a User or Subscription
492
+ // and attempt to immediately access it (via GET or PATCH). A delay is
493
+ // needed as the backend may incorrectly 404 otherwise, due to a small
494
+ // delay in it's server replication.
495
+ // A cold down period like this also helps improve batching as well.
496
+ test("execution of an operation with translation IDs delays follow up operations") {
497
+ // Given
498
+ val mocks = Mocks ()
499
+ mocks.configModelStore.model.opRepoPostCreateDelay = 100
500
+ val operation1 = mockOperation(groupComparisonType = GroupComparisonType .NONE )
501
+ val operation2 = mockOperation(groupComparisonType = GroupComparisonType .NONE , applyToRecordId = "id2")
502
+ val operation3 = mockOperation(groupComparisonType = GroupComparisonType .NONE )
503
+ coEvery {
504
+ mocks.executor.execute(listOf(operation1))
505
+ } returns ExecutionResponse (ExecutionResult .SUCCESS , mapOf("local-id1" to "id2"))
506
+
507
+ // When
508
+ mocks.operationRepo.start()
509
+ mocks.operationRepo.enqueue(operation1)
510
+ val job = launch { mocks.operationRepo.enqueueAndWait(operation2) }.also { yield () }
511
+ mocks.operationRepo.enqueue(operation3)
512
+ job.join()
513
+
514
+ // Then
515
+ coVerifyOrder {
516
+ mocks.executor.execute(
517
+ withArg {
518
+ it.count() shouldBe 1
519
+ it[0] shouldBe operation1
520
+ },
521
+ )
522
+ operation2.translateIds(mapOf("local-id1" to "id2"))
523
+ mocks.executor.execute(
524
+ withArg {
525
+ it.count() shouldBe 1
526
+ it[0] shouldBe operation3
527
+ },
528
+ )
529
+ // Ensure operation2 runs after operation3 as it has to wait for the create delay
530
+ mocks.executor.execute(
531
+ withArg {
532
+ it.count() shouldBe 1
533
+ it[0] shouldBe operation2
534
+ },
535
+ )
536
+ }
537
+ }
488
538
}) {
489
539
companion object {
490
540
private fun mockOperation (
@@ -495,6 +545,7 @@ class OperationRepoTests : FunSpec({
495
545
createComparisonKey : String = "create-key",
496
546
modifyComparisonKey : String = "modify-key",
497
547
operationIdSlot : CapturingSlot <String >? = null,
548
+ applyToRecordId : String = "",
498
549
): Operation {
499
550
val operation = mockk<Operation >()
500
551
val opIdSlot = operationIdSlot ? : slot()
0 commit comments