1 package expo.modules.updates.db 2 3 import android.content.Context 4 import androidx.room.Room 5 import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner 6 import androidx.test.platform.app.InstrumentationRegistry 7 import expo.modules.updates.db.entity.UpdateEntity 8 import expo.modules.updates.db.enums.UpdateStatus 9 import expo.modules.updates.db.entity.AssetEntity 10 import io.mockk.every 11 import io.mockk.spyk 12 import org.json.JSONObject 13 import org.junit.After 14 import org.junit.Assert 15 import org.junit.Before 16 import org.junit.Test 17 import org.junit.runner.RunWith 18 import java.util.* 19 20 @RunWith(AndroidJUnit4ClassRunner::class) 21 class DatabaseIntegrityCheckTest { 22 private lateinit var context: Context 23 private lateinit var db: UpdatesDatabase 24 25 @Before createDbnull26 fun createDb() { 27 context = InstrumentationRegistry.getInstrumentation().targetContext 28 db = Room.inMemoryDatabaseBuilder(context, UpdatesDatabase::class.java).build() 29 } 30 31 @After closeDbnull32 fun closeDb() { 33 db.close() 34 } 35 36 @Test testFilterEmbeddedUpdatesnull37 fun testFilterEmbeddedUpdates() { 38 // We can't run any updates with the status EMBEDDED if they aren't the update that's 39 // currently embedded in the installed app; the integrity check should remove any such updates 40 // from the database entirely. 41 val scopeKey = "testScopeKey" 42 43 val embeddedUpdate1 = UpdateEntity(UUID.randomUUID(), Date(1608667857774L), "1.0", scopeKey, JSONObject("{}")) 44 embeddedUpdate1.status = UpdateStatus.EMBEDDED 45 46 val embeddedUpdate2 = UpdateEntity(UUID.randomUUID(), Date(1608667857775L), "1.0", scopeKey, JSONObject("{}")) 47 embeddedUpdate2.status = UpdateStatus.EMBEDDED 48 49 db.updateDao().insertUpdate(embeddedUpdate1) 50 db.updateDao().insertUpdate(embeddedUpdate2) 51 52 Assert.assertEquals(2, db.updateDao().loadAllUpdates().size.toLong()) 53 54 DatabaseIntegrityCheck().run(db, null, embeddedUpdate2) 55 56 val allUpdates = db.updateDao().loadAllUpdates() 57 Assert.assertEquals(1, allUpdates.size.toLong()) 58 Assert.assertEquals(embeddedUpdate2.id, allUpdates[0].id) 59 60 // cleanup 61 db.updateDao().deleteUpdates(allUpdates) 62 } 63 64 @Test testMissingAssetsnull65 fun testMissingAssets() { 66 val asset1 = AssetEntity("asset1", "png") 67 asset1.relativePath = "asset1.png" 68 69 val scopeKey = "testScopeKey" 70 71 val update1 = UpdateEntity(UUID.randomUUID(), Date(), "1.0", scopeKey, JSONObject("{}")) 72 update1.status = UpdateStatus.READY 73 74 db.updateDao().insertUpdate(update1) 75 db.assetDao().insertAssets(listOf(asset1), update1) 76 77 Assert.assertEquals(1, db.updateDao().loadAllUpdates().size.toLong()) 78 Assert.assertEquals(1, db.assetDao().loadAllAssets().size.toLong()) 79 80 val integrityCheck = spyk(DatabaseIntegrityCheck()) 81 every { integrityCheck.assetExists(any(), any()) } returns false 82 integrityCheck.run(db, context.cacheDir, update1) 83 84 val allUpdates = db.updateDao().loadAllUpdates() 85 val allAssets = db.assetDao().loadAllAssets() 86 Assert.assertEquals(1, allUpdates.size.toLong()) 87 Assert.assertEquals(UpdateStatus.PENDING, allUpdates[0].status) 88 Assert.assertEquals(1, allAssets.size.toLong()) 89 90 // cleanup 91 db.updateDao().deleteUpdates(allUpdates) 92 } 93 94 @Test testNoMissingAssetsnull95 fun testNoMissingAssets() { 96 val asset1 = AssetEntity("asset1", "png") 97 asset1.relativePath = "asset1.png" 98 99 val scopeKey = "testScopeKey" 100 101 val update1 = UpdateEntity(UUID.randomUUID(), Date(), "1.0", scopeKey, JSONObject("{}")) 102 update1.status = UpdateStatus.READY 103 104 db.updateDao().insertUpdate(update1) 105 db.assetDao().insertAssets(listOf(asset1), update1) 106 107 Assert.assertEquals(1, db.updateDao().loadAllUpdates().size.toLong()) 108 Assert.assertEquals(1, db.assetDao().loadAllAssets().size.toLong()) 109 110 val integrityCheck = spyk(DatabaseIntegrityCheck()) 111 every { integrityCheck.assetExists(any(), any()) } returns true 112 integrityCheck.run(db, context.cacheDir, update1) 113 114 val allUpdates = db.updateDao().loadAllUpdates() 115 val allAssets = db.assetDao().loadAllAssets() 116 Assert.assertEquals(1, allUpdates.size.toLong()) 117 Assert.assertEquals(UpdateStatus.READY, allUpdates[0].status) 118 Assert.assertEquals(1, allAssets.size.toLong()) 119 120 // cleanup 121 db.updateDao().deleteUpdates(allUpdates) 122 } 123 } 124