Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrated Notes to room database. #3863

Merged
merged 6 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,19 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.kiwix.kiwixmobile.core.dao.HistoryRoomDao
import org.kiwix.kiwixmobile.core.dao.NotesRoomDao
import org.kiwix.kiwixmobile.core.dao.RecentSearchRoomDao
import org.kiwix.kiwixmobile.core.dao.entities.RecentSearchRoomEntity
import org.kiwix.kiwixmobile.core.data.KiwixRoomDatabase
import org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem
import org.kiwix.kiwixmobile.core.page.notes.adapter.NoteListItem

@RunWith(AndroidJUnit4::class)
class KiwixRoomDatabaseTest {
private lateinit var recentSearchRoomDao: RecentSearchRoomDao
private lateinit var db: KiwixRoomDatabase
private lateinit var historyRoomDao: HistoryRoomDao
private lateinit var notesRoomDao: NotesRoomDao

@Before
fun setUpDatabase() {
Expand Down Expand Up @@ -103,7 +106,7 @@ class KiwixRoomDatabaseTest {

// test inserting into history database
historyRoomDao.saveHistory(historyItem)
var historyList = historyRoomDao.historyRoomEntity().first()
var historyList = historyRoomDao.historyRoomEntity().blockingFirst()
with(historyList.first()) {
assertThat(historyTitle, equalTo(historyItem.title))
assertThat(zimId, equalTo(historyItem.zimId))
Expand All @@ -117,21 +120,64 @@ class KiwixRoomDatabaseTest {

// test deleting the history
historyRoomDao.deleteHistory(listOf(historyItem))
historyList = historyRoomDao.historyRoomEntity().first()
historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertEquals(historyList.size, 0)

// test deleting all history
historyRoomDao.saveHistory(historyItem)
historyRoomDao.saveHistory(
getHistoryItem(databaseId = 2)
)
historyList = historyRoomDao.historyRoomEntity().first()
historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertEquals(historyList.size, 2)
historyRoomDao.deleteAllHistory()
historyList = historyRoomDao.historyRoomEntity().first()
historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertEquals(historyList.size, 0)
}

@Test
fun testNoteRoomDao() = runBlocking {
notesRoomDao = db.notesRoomDao()
// delete all the notes from database to properly run the test cases.
notesRoomDao.deleteNotes(notesRoomDao.notes().blockingFirst() as List<NoteListItem>)
val noteItem = getNoteListItem(
zimUrl = "http://kiwix.app/MainPage",
noteFilePath = "/storage/emulated/0/Download/Notes/Alpine linux/MainPage.txt"
)

// Save and retrieve a notes item
notesRoomDao.saveNote(noteItem)
var notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
with(notesList.first()) {
assertThat(zimId, equalTo(noteItem.zimId))
assertThat(zimUrl, equalTo(noteItem.zimUrl))
assertThat(title, equalTo(noteItem.title))
assertThat(zimFilePath, equalTo(noteItem.zimFilePath))
assertThat(noteFilePath, equalTo(noteItem.noteFilePath))
assertThat(favicon, equalTo(noteItem.favicon))
}
assertEquals(notesList.size, 1)

// test deleting the history
notesRoomDao.deleteNotes(listOf(noteItem))
notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(notesList.size, 0)

// test deleting all notes
notesRoomDao.saveNote(noteItem)
notesRoomDao.saveNote(
getNoteListItem(
title = "Installing",
zimUrl = "http://kiwix.app/Installing"
)
)
notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(notesList.size, 2)
notesRoomDao.deletePages(notesRoomDao.notes().blockingFirst())
notesList = notesRoomDao.notes().blockingFirst() as List<NoteListItem>
assertEquals(notesList.size, 0)
}

companion object {
fun getHistoryItem(
title: String = "Installation",
Expand All @@ -154,5 +200,23 @@ class KiwixRoomDatabaseTest {
dateString = dateString,
timeStamp = timeStamp
)

fun getNoteListItem(
databaseId: Long = 0L,
zimId: String = "1f88ab6f-c265-b-3ff-8f49-b7f4429503800",
title: String = "Alpine Wiki",
zimFilePath: String = "/storage/emulated/0/Download/alpinelinux_en_all_maxi_2023-01.zim",
zimUrl: String,
noteFilePath: String = "/storage/emulated/0/Download/Notes/Alpine linux/AlpineNote.txt"
): NoteListItem = NoteListItem(
databaseId = databaseId,
zimId = zimId,
title = title,
zimFilePath = zimFilePath,
zimUrl = zimUrl,
noteFilePath = noteFilePath,
null,
false
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,14 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.kiwix.kiwixmobile.KiwixRoomDatabaseTest.Companion.getHistoryItem
import org.kiwix.kiwixmobile.KiwixRoomDatabaseTest.Companion.getNoteListItem
import org.kiwix.kiwixmobile.core.dao.entities.HistoryEntity
import org.kiwix.kiwixmobile.core.dao.entities.NotesEntity
import org.kiwix.kiwixmobile.core.dao.entities.RecentSearchEntity
import org.kiwix.kiwixmobile.core.data.KiwixRoomDatabase
import org.kiwix.kiwixmobile.core.data.remote.ObjectBoxToRoomMigrator
import org.kiwix.kiwixmobile.core.di.modules.DatabaseModule
import org.kiwix.kiwixmobile.core.page.notes.adapter.NoteListItem
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil

@RunWith(AndroidJUnit4::class)
Expand Down Expand Up @@ -162,10 +165,12 @@ class ObjectBoxToRoomMigratorTest {
assertTrue("Migration took too long: $migrationTime ms", migrationTime < 20000)
}

private fun <T> clearRoomAndBoxStoreDatabases(box: Box<T>) {
private suspend fun <T> clearRoomAndBoxStoreDatabases(box: Box<T>) {
// delete history for testing other edge cases
kiwixRoomDatabase.recentSearchRoomDao().deleteSearchHistory()
kiwixRoomDatabase.historyRoomDao().deleteAllHistory()
kiwixRoomDatabase.notesRoomDao()
.deletePages(kiwixRoomDatabase.notesRoomDao().notes().blockingFirst())
box.removeAll()
}

Expand All @@ -186,7 +191,7 @@ class ObjectBoxToRoomMigratorTest {
// migrate data into room database
objectBoxToRoomMigrator.migrateHistory(box)
// check if data successfully migrated to room
val actual = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first()
val actual = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
with(actual.first()) {
assertThat(historyTitle, equalTo(historyItem.title))
assertThat(zimId, equalTo(historyItem.zimId))
Expand All @@ -202,15 +207,15 @@ class ObjectBoxToRoomMigratorTest {

// Migrate data from empty ObjectBox database
objectBoxToRoomMigrator.migrateHistory(box)
var actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first()
var actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
assertTrue(actualData.isEmpty())

// Test if data successfully migrated to Room and existing data is preserved
kiwixRoomDatabase.historyRoomDao().saveHistory(historyItem3)
box.put(HistoryEntity(historyItem2))
// Migrate data into Room database
objectBoxToRoomMigrator.migrateHistory(box)
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first()
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
assertEquals(2, actualData.size)
val existingItem =
actualData.find {
Expand All @@ -229,7 +234,7 @@ class ObjectBoxToRoomMigratorTest {
kiwixRoomDatabase.historyRoomDao().saveHistory(historyItem)
box.put(HistoryEntity(historyItem))
objectBoxToRoomMigrator.migrateHistory(box)
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first()
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
assertEquals(1, actualData.size)

clearRoomAndBoxStoreDatabases(box)
Expand All @@ -243,7 +248,7 @@ class ObjectBoxToRoomMigratorTest {
} catch (_: Exception) {
}
// Ensure Room database remains empty or unaffected by the invalid data
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first()
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
assertTrue(actualData.isEmpty())

// Test large data migration for recent searches
Expand All @@ -265,9 +270,118 @@ class ObjectBoxToRoomMigratorTest {
val endTime = System.currentTimeMillis()
val migrationTime = endTime - startTime
// Check if data successfully migrated to Room
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().first()
actualData = kiwixRoomDatabase.historyRoomDao().historyRoomEntity().blockingFirst()
assertEquals(numEntities, actualData.size)
// Assert that the migration completes within a reasonable time frame
assertTrue("Migration took too long: $migrationTime ms", migrationTime < 20000)
}

@Test
fun migrateNotes_shouldInsertDataIntoRoomDatabase() = runBlocking {
val box = boxStore.boxFor(NotesEntity::class.java)
// clear both databases for history to test more edge cases
clearRoomAndBoxStoreDatabases(box)

val noteItem = getNoteListItem(
zimUrl = "http://kiwix.app/MainPage",
noteFilePath = "/storage/emulated/0/Download/Notes/Alpine linux/MainPage.txt"
)

val noteItem1 = getNoteListItem(
databaseId = 1,
title = "Installing",
zimUrl = "http://kiwix.app/Installing",
noteFilePath = "/storage/emulated/0/Download/Notes/Alpine linux/Installing.txt"
)

// insert into object box
box.put(NotesEntity(noteItem))
// migrate data into room database
objectBoxToRoomMigrator.migrateNotes(box)
// check if data successfully migrated to room
var notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
with(notesList.first()) {
assertThat(zimId, equalTo(noteItem.zimId))
assertThat(zimUrl, equalTo(noteItem.zimUrl))
assertThat(title, equalTo(noteItem.title))
assertThat(zimFilePath, equalTo(noteItem.zimFilePath))
assertThat(noteFilePath, equalTo(noteItem.noteFilePath))
assertThat(favicon, equalTo(noteItem.favicon))
}
assertEquals(notesList.size, 1)

clearRoomAndBoxStoreDatabases(box)

// Migrate data from empty ObjectBox database
objectBoxToRoomMigrator.migrateNotes(box)
notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
assertTrue(notesList.isEmpty())

// Test if data successfully migrated to Room and existing data is preserved
kiwixRoomDatabase.notesRoomDao().saveNote(noteItem1)
box.put(NotesEntity(noteItem))
// Migrate data into Room database
objectBoxToRoomMigrator.migrateNotes(box)
notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
assertEquals(noteItem.title, notesList.first().title)
assertEquals(2, notesList.size)
val existingItem =
notesList.find {
it.zimUrl == noteItem.zimUrl && it.title == noteItem.title
}
assertNotNull(existingItem)
val newItem =
notesList.find {
it.zimUrl == noteItem1.zimUrl && it.title == noteItem1.title
}
assertNotNull(newItem)

clearRoomAndBoxStoreDatabases(box)

// Test room will update the already exiting data in the database while migration.
kiwixRoomDatabase.notesRoomDao().saveNote(noteItem1)
box.put(NotesEntity(noteItem1))
// Migrate data into Room database
objectBoxToRoomMigrator.migrateNotes(box)
notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
assertEquals(1, notesList.size)

clearRoomAndBoxStoreDatabases(box)

// Test migration if ObjectBox has null values
try {
lateinit var invalidNotesEntity: NotesEntity
box.put(invalidNotesEntity)
// Migrate data into Room database
objectBoxToRoomMigrator.migrateNotes(box)
} catch (_: Exception) {
}
// Ensure Room database remains empty or unaffected by the invalid data
notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
assertTrue(notesList.isEmpty())

// Test large data migration for recent searches
val numEntities = 5000
// Insert a large number of recent search entities into ObjectBox
for (i in 1..numEntities) {
box.put(
NotesEntity(
getNoteListItem(
title = "Installation$i",
zimUrl = "https://kiwix.app/A/Installation$i"
)
)
)
}
val startTime = System.currentTimeMillis()
// Migrate data into Room database
objectBoxToRoomMigrator.migrateNotes(box)
val endTime = System.currentTimeMillis()
val migrationTime = endTime - startTime
// Check if data successfully migrated to Room
notesList = kiwixRoomDatabase.notesRoomDao().notes().blockingFirst() as List<NoteListItem>
assertEquals(numEntities, notesList.size)
// Assert that the migration completes within a reasonable time frame
assertTrue("Migration took too long: $migrationTime ms", migrationTime < 20000)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import android.content.Context
import androidx.room.Room
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.core.IsEqual.equalTo
Expand Down Expand Up @@ -65,7 +64,7 @@ class HistoryRoomDaoTest {

// Save and retrieve a history item
historyRoomDao.saveHistory(historyItem)
var historyList = historyRoomDao.historyRoomEntity().first()
var historyList = historyRoomDao.historyRoomEntity().blockingFirst()
with(historyList.first()) {
assertThat(historyTitle, equalTo(historyItem.title))
assertThat(zimId, equalTo(historyItem.zimId))
Expand All @@ -79,26 +78,26 @@ class HistoryRoomDaoTest {

// Test to update the same day history for url
historyRoomDao.saveHistory(historyItem)
historyList = historyRoomDao.historyRoomEntity().first()
historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertEquals(historyList.size, 1)

// Delete the saved history item
historyRoomDao.deleteHistory(listOf(historyItem))
historyList = historyRoomDao.historyRoomEntity().first()
historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertEquals(historyList.size, 0)

// Save and delete all history items
historyRoomDao.saveHistory(historyItem)
historyRoomDao.saveHistory(getHistoryItem(databaseId = 2, dateString = "31 May 2024"))
historyRoomDao.deleteAllHistory()
historyList = historyRoomDao.historyRoomEntity().first()
historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertThat(historyList.size, equalTo(0))

// Save history item with empty fields
val emptyHistoryUrl = ""
val emptyTitle = ""
historyRoomDao.saveHistory(getHistoryItem(emptyTitle, emptyHistoryUrl, databaseId = 1))
historyList = historyRoomDao.historyRoomEntity().first()
historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertThat(historyList.size, equalTo(1))
historyRoomDao.deleteAllHistory()

Expand All @@ -118,13 +117,13 @@ class HistoryRoomDaoTest {
val unicodeTitle = "title \u03A3" // Unicode character for Greek capital letter Sigma
val historyItem2 = getHistoryItem(title = unicodeTitle, databaseId = 2)
historyRoomDao.saveHistory(historyItem2)
historyList = historyRoomDao.historyRoomEntity().first()
historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertThat(historyList.first().historyTitle, equalTo("title Σ"))

// Test deletePages function
historyRoomDao.saveHistory(historyItem)
historyRoomDao.deletePages(listOf(historyItem, historyItem2))
historyList = historyRoomDao.historyRoomEntity().first()
historyList = historyRoomDao.historyRoomEntity().blockingFirst()
assertThat(historyList.size, equalTo(0))
}
}
Loading
Loading