Tusky-App-Android/app/src/test/java/com/keylesspalace/tusky/db/dao/NotificationsDaoTest.kt

235 lines
9.8 KiB
Kotlin

package com.keylesspalace.tusky.db.dao
import androidx.paging.PagingSource
import androidx.room.Room
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import com.keylesspalace.tusky.components.notifications.fakeNotification
import com.keylesspalace.tusky.components.notifications.fakeReport
import com.keylesspalace.tusky.components.notifications.insert
import com.keylesspalace.tusky.components.notifications.toNotificationDataEntity
import com.keylesspalace.tusky.components.notifications.toNotificationEntity
import com.keylesspalace.tusky.components.timeline.Placeholder
import com.keylesspalace.tusky.components.timeline.fakeAccount
import com.keylesspalace.tusky.components.timeline.fakeStatus
import com.keylesspalace.tusky.db.AppDatabase
import com.keylesspalace.tusky.db.Converters
import com.keylesspalace.tusky.di.NetworkModule
import com.keylesspalace.tusky.entity.Notification
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.annotation.Config
@Config(sdk = [28])
@RunWith(AndroidJUnit4::class)
class NotificationsDaoTest {
private lateinit var notificationsDao: NotificationsDao
private lateinit var db: AppDatabase
private val moshi = NetworkModule.providesMoshi()
@Before
fun createDb() {
val context = InstrumentationRegistry.getInstrumentation().targetContext
db = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
.addTypeConverter(Converters(moshi))
.allowMainThreadQueries()
.build()
notificationsDao = db.notificationsDao()
}
@After
fun closeDb() {
db.close()
}
@Test
fun insertAndGetNotification() = runTest {
db.insert(
listOf(
fakeNotification(id = "1"),
fakeNotification(id = "2"),
fakeNotification(id = "3"),
),
tuskyAccountId = 1
)
db.insert(
listOf(fakeNotification(id = "3")),
tuskyAccountId = 2
)
val pagingSource = notificationsDao.getNotifications(tuskyAccountId = 1)
val loadResult = pagingSource.load(PagingSource.LoadParams.Refresh(null, 2, false))
val loadedStatuses = (loadResult as PagingSource.LoadResult.Page).data
assertEquals(
listOf(
fakeNotification(id = "3").toNotificationDataEntity(1),
fakeNotification(id = "2").toNotificationDataEntity(1)
),
loadedStatuses
)
}
@Test
fun deleteRange() = runTest {
val notifications = listOf(
fakeNotification(id = "100"),
fakeNotification(id = "50"),
fakeNotification(id = "15"),
fakeNotification(id = "14"),
fakeNotification(id = "13"),
fakeNotification(id = "12"),
fakeNotification(id = "11"),
fakeNotification(id = "9")
)
db.insert(notifications, 1)
db.insert(listOf(fakeNotification(id = "13")), 2)
assertEquals(3, notificationsDao.deleteRange(1, "12", "14"))
assertEquals(0, notificationsDao.deleteRange(1, "80", "80"))
assertEquals(0, notificationsDao.deleteRange(1, "60", "80"))
assertEquals(0, notificationsDao.deleteRange(1, "5", "8"))
assertEquals(0, notificationsDao.deleteRange(1, "101", "1000"))
assertEquals(1, notificationsDao.deleteRange(1, "50", "50"))
val loadParams: PagingSource.LoadParams<Int> = PagingSource.LoadParams.Refresh(null, 100, false)
val notificationsAccount1 = (notificationsDao.getNotifications(1).load(loadParams) as PagingSource.LoadResult.Page).data
val notificationsAccount2 = (notificationsDao.getNotifications(2).load(loadParams) as PagingSource.LoadResult.Page).data
val remainingNotificationsAccount1 = listOf(
fakeNotification(id = "100").toNotificationDataEntity(1),
fakeNotification(id = "15").toNotificationDataEntity(1),
fakeNotification(id = "11").toNotificationDataEntity(1),
fakeNotification(id = "9").toNotificationDataEntity(1)
)
val remainingNotificationsAccount2 = listOf(
fakeNotification(id = "13").toNotificationDataEntity(2)
)
assertEquals(remainingNotificationsAccount1, notificationsAccount1)
assertEquals(remainingNotificationsAccount2, notificationsAccount2)
}
@Test
fun deleteAllForInstance() = runTest {
val redAccount = fakeNotification(id = "500", account = fakeAccount(id = "500", domain = "mastodon.red"))
val blueAccount = fakeNotification(id = "501", account = fakeAccount(id = "501", domain = "mastodon.blue"))
val redStatus = fakeNotification(id = "502", account = fakeAccount(id = "502", domain = "mastodon.example"), status = fakeStatus(id = "502", domain = "mastodon.red", authorServerId = "502a"))
val blueStatus = fakeNotification(id = "503", account = fakeAccount(id = "503", domain = "mastodon.example"), status = fakeStatus(id = "503", domain = "mastodon.blue", authorServerId = "503a"))
val redStatus2 = fakeNotification(id = "600", account = fakeAccount(id = "600", domain = "mastodon.red"))
db.insert(listOf(redAccount, blueAccount, redStatus, blueStatus), 1)
db.insert(listOf(redStatus2), 2)
notificationsDao.deleteAllFromInstance(1, "mastodon.red")
notificationsDao.deleteAllFromInstance(1, "mastodon.blu") // shouldn't delete anything
notificationsDao.deleteAllFromInstance(1, "mastodon.green") // shouldn't delete anything
val loadParams: PagingSource.LoadParams<Int> = PagingSource.LoadParams.Refresh(null, 100, false)
val notificationsAccount1 = (notificationsDao.getNotifications(1).load(loadParams) as PagingSource.LoadResult.Page).data
val notificationsAccount2 = (notificationsDao.getNotifications(2).load(loadParams) as PagingSource.LoadResult.Page).data
assertEquals(
listOf(
blueStatus.toNotificationDataEntity(1),
blueAccount.toNotificationDataEntity(1)
),
notificationsAccount1
)
assertEquals(listOf(redStatus2.toNotificationDataEntity(2)), notificationsAccount2)
}
@Test
fun `should return null as topId when db is empty`() = runTest {
assertNull(notificationsDao.getTopId(1))
}
@Test
fun `should return correct topId`() = runTest {
db.insert(
listOf(
fakeNotification(id = "100"),
fakeNotification(id = "3"),
fakeNotification(id = "33"),
fakeNotification(id = "8"),
),
tuskyAccountId = 1
)
db.insert(
listOf(
fakeNotification(id = "200"),
fakeNotification(id = "300"),
fakeNotification(id = "1000"),
),
tuskyAccountId = 2
)
assertEquals("100", notificationsDao.getTopId(1))
assertEquals("1000", notificationsDao.getTopId(2))
}
@Test
fun `should return correct top placeholderId`() = runTest {
val notifications = listOf(
fakeNotification(id = "1000"),
fakeNotification(id = "97"),
fakeNotification(id = "90"),
fakeNotification(id = "77")
)
db.insert(notifications)
notificationsDao.insertNotification(Placeholder(id = "99", loading = false).toNotificationEntity(1))
notificationsDao.insertNotification(Placeholder(id = "96", loading = false).toNotificationEntity(1))
notificationsDao.insertNotification(Placeholder(id = "80", loading = false).toNotificationEntity(1))
assertEquals("99", notificationsDao.getTopPlaceholderId(1))
}
@Test
fun `should correctly delete all by user`() = runTest {
val notificationsAccount1 = listOf(
// will be removed because it is a like by account 1
fakeNotification(id = "1", account = fakeAccount(id = "1"), status = fakeStatus(id = "1", authorServerId = "100")),
// will be removed because it references a status by account 1
fakeNotification(id = "2", account = fakeAccount(id = "2"), status = fakeStatus(id = "2", authorServerId = "1")),
// will not be removed because they are admin notifications
fakeNotification(type = Notification.Type.REPORT, id = "3", account = fakeAccount(id = "3"), status = null, report = fakeReport(id = "1", targetAccount = fakeAccount(id = "1"))),
fakeNotification(type = Notification.Type.SIGN_UP, id = "4", account = fakeAccount(id = "1"), status = null, report = fakeReport(id = "1", targetAccount = fakeAccount(id = "4"))),
// will not be removed because it does not reference account 1
fakeNotification(id = "5", account = fakeAccount(id = "5"), status = fakeStatus(id = "5", authorServerId = "100")),
)
db.insert(notificationsAccount1, tuskyAccountId = 1)
db.insert(listOf(fakeNotification(id = "6")), tuskyAccountId = 2)
notificationsDao.removeAllByUser(1, "1")
val loadedNotifications: MutableList<String> = mutableListOf()
val cursor = db.query("SELECT id FROM NotificationEntity ORDER BY id ASC", null)
cursor.moveToFirst()
while (!cursor.isAfterLast) {
val id: String = cursor.getString(cursor.getColumnIndex("id"))
loadedNotifications.add(id)
cursor.moveToNext()
}
cursor.close()
val expectedNotifications = listOf("3", "4", "5", "6")
assertEquals(expectedNotifications, loadedNotifications)
}
}