That fuck shit the fascists are using
at master 157 lines 4.2 kB view raw
1package org.tm.archive.database 2 3import androidx.test.ext.junit.runners.AndroidJUnit4 4import org.junit.Assert.assertEquals 5import org.junit.Assert.assertFalse 6import org.junit.Assert.assertTrue 7import org.junit.Before 8import org.junit.Test 9import org.junit.runner.RunWith 10import org.signal.core.util.concurrent.SignalExecutors 11import org.tm.archive.dependencies.ApplicationDependencies 12import java.util.concurrent.CountDownLatch 13import java.util.concurrent.atomic.AtomicBoolean 14import java.util.concurrent.atomic.AtomicInteger 15 16/** 17 * When writing tests, be very careful to call [DatabaseObserver.flush] before asserting any observer state. Internally, the observer is enqueueing tasks on 18 * an executor, and failing to flush the executor will lead to incorrect/flaky tests. 19 */ 20@RunWith(AndroidJUnit4::class) 21class DatabaseObserverTest { 22 23 private lateinit var db: SQLiteDatabase 24 private lateinit var observer: DatabaseObserver 25 26 @Before 27 fun setup() { 28 db = SignalDatabase.instance!!.signalWritableDatabase 29 observer = ApplicationDependencies.getDatabaseObserver() 30 } 31 32 @Test 33 fun notifyConversationListeners_runsImmediatelyIfNotInTransaction() { 34 val hasRun = AtomicBoolean(false) 35 observer.registerConversationObserver(1) { hasRun.set(true) } 36 observer.notifyConversationListeners(1) 37 observer.flush() 38 assertTrue(hasRun.get()) 39 } 40 41 @Test 42 fun notifyConversationListeners_runsAfterSuccessIfInTransaction() { 43 val hasRun = AtomicBoolean(false) 44 45 db.beginTransaction() 46 47 observer.registerConversationObserver(1) { hasRun.set(true) } 48 observer.notifyConversationListeners(1) 49 observer.flush() 50 assertFalse(hasRun.get()) 51 52 db.setTransactionSuccessful() 53 db.endTransaction() 54 55 observer.flush() 56 57 assertTrue(hasRun.get()) 58 } 59 60 @Test 61 fun notifyConversationListeners_doesNotRunAfterFailedTransaction() { 62 val hasRun = AtomicBoolean(false) 63 64 db.beginTransaction() 65 66 observer.registerConversationObserver(1) { hasRun.set(true) } 67 observer.notifyConversationListeners(1) 68 observer.flush() 69 assertFalse(hasRun.get()) 70 71 db.endTransaction() 72 observer.flush() 73 assertFalse(hasRun.get()) 74 75 // Verifying we still don't run it even after a subsequent success 76 db.beginTransaction() 77 db.setTransactionSuccessful() 78 db.endTransaction() 79 80 observer.flush() 81 82 assertFalse(hasRun.get()) 83 } 84 85 @Test 86 fun notifyConversationListeners_onlyRunAfterAllTransactionsComplete() { 87 val hasRun = AtomicBoolean(false) 88 89 db.beginTransaction() 90 91 observer.registerConversationObserver(1) { hasRun.set(true) } 92 observer.notifyConversationListeners(1) 93 observer.flush() 94 assertFalse(hasRun.get()) 95 96 db.beginTransaction() 97 db.setTransactionSuccessful() 98 db.endTransaction() 99 observer.flush() 100 assertFalse(hasRun.get()) 101 102 db.setTransactionSuccessful() 103 db.endTransaction() 104 105 observer.flush() 106 107 assertTrue(hasRun.get()) 108 } 109 110 @Test 111 fun notifyConversationListeners_runsImmediatelyIfTheTransactionIsOnAnotherThread() { 112 db.beginTransaction() 113 114 val latch = CountDownLatch(1) 115 SignalExecutors.BOUNDED.execute { 116 val hasRun = AtomicBoolean(false) 117 118 observer.registerConversationObserver(1) { hasRun.set(true) } 119 observer.notifyConversationListeners(1) 120 observer.flush() 121 assertTrue(hasRun.get()) 122 123 latch.countDown() 124 } 125 126 latch.await() 127 128 db.setTransactionSuccessful() 129 db.endTransaction() 130 } 131 132 @Test 133 fun notifyConversationListeners_runsAfterSuccessIfInTransaction_ignoreDuplicateNotifications() { 134 val thread1Count = AtomicInteger(0) 135 val thread2Count = AtomicInteger(0) 136 137 db.beginTransaction() 138 139 observer.registerConversationObserver(1) { thread1Count.incrementAndGet() } 140 observer.registerConversationObserver(2) { thread2Count.incrementAndGet() } 141 142 observer.notifyConversationListeners(1) 143 observer.notifyConversationListeners(2) 144 observer.notifyConversationListeners(2) 145 146 observer.flush() 147 assertEquals(0, thread1Count.get()) 148 assertEquals(0, thread2Count.get()) 149 150 db.setTransactionSuccessful() 151 db.endTransaction() 152 153 observer.flush() 154 assertEquals(1, thread1Count.get()) 155 assertEquals(1, thread2Count.get()) 156 } 157}