Fixed a few bugs, added logging and removed some old code
Added the ability to copy the sessionId of open group URL from the conversation menu Added additional logging to the BatchMessageReceiveJob to make future debugging easier Removed the OpenGroupMigrator Updated the JobQueue logging to provide more insight Fixed an issue where the database migrations weren't blocking which could result in failing/crashing SQL queries Fixed an issue where the new database file wouldn't be removed if a migration error was thrown Fixed an issue where the new database could exist in an invalid state and the app wouldn't attempt to remigrate Fixed an incorrectly throw exception in the PassphrasePromptActivitypull/1102/head
parent
cf916a5762
commit
0256735135
@ -1,139 +0,0 @@
|
||||
package org.thoughtcrime.securesms.groups
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import org.session.libsession.messaging.open_groups.OpenGroupApi
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsignal.utilities.Hex
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||
|
||||
object OpenGroupMigrator {
|
||||
const val HTTP_PREFIX = "__loki_public_chat_group__!687474703a2f2f"
|
||||
private const val HTTPS_PREFIX = "__loki_public_chat_group__!68747470733a2f2f"
|
||||
const val OPEN_GET_SESSION_TRAILING_DOT_ENCODED = "6f70656e2e67657473657373696f6e2e6f72672e"
|
||||
const val LEGACY_GROUP_ENCODED_ID = "__loki_public_chat_group__!687474703a2f2f3131362e3230332e37302e33332e" // old IP based toByteArray()
|
||||
const val NEW_GROUP_ENCODED_ID = "__loki_public_chat_group__!68747470733a2f2f6f70656e2e67657473657373696f6e2e6f72672e" // new URL based toByteArray()
|
||||
|
||||
data class OpenGroupMapping(val stub: String, val legacyThreadId: Long, val newThreadId: Long?)
|
||||
|
||||
@VisibleForTesting
|
||||
fun Recipient.roomStub(): String? {
|
||||
if (!isOpenGroupRecipient) return null
|
||||
val serialized = address.serialize()
|
||||
if (serialized.startsWith(LEGACY_GROUP_ENCODED_ID)) {
|
||||
return serialized.replace(LEGACY_GROUP_ENCODED_ID,"")
|
||||
} else if (serialized.startsWith(NEW_GROUP_ENCODED_ID)) {
|
||||
return serialized.replace(NEW_GROUP_ENCODED_ID,"")
|
||||
} else if (serialized.startsWith(HTTP_PREFIX + OPEN_GET_SESSION_TRAILING_DOT_ENCODED)) {
|
||||
return serialized.replace(HTTP_PREFIX + OPEN_GET_SESSION_TRAILING_DOT_ENCODED, "")
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
fun getExistingMappings(legacy: List<ThreadRecord>, new: List<ThreadRecord>): List<OpenGroupMapping> {
|
||||
val legacyStubsMapping = legacy.mapNotNull { thread ->
|
||||
val stub = thread.recipient.roomStub()
|
||||
stub?.let { it to thread.threadId }
|
||||
}
|
||||
val newStubsMapping = new.mapNotNull { thread ->
|
||||
val stub = thread.recipient.roomStub()
|
||||
stub?.let { it to thread.threadId }
|
||||
}
|
||||
return legacyStubsMapping.map { (legacyEncodedStub, legacyId) ->
|
||||
// get 'new' open group thread ID if stubs match
|
||||
OpenGroupMapping(
|
||||
legacyEncodedStub,
|
||||
legacyId,
|
||||
newStubsMapping.firstOrNull { (newEncodedStub, _) -> newEncodedStub == legacyEncodedStub }?.second
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun migrate(databaseComponent: DatabaseComponent) {
|
||||
// migrate thread db
|
||||
val threadDb = databaseComponent.threadDatabase()
|
||||
|
||||
val legacyOpenGroups = threadDb.legacyOxenOpenGroups
|
||||
val httpBasedNewGroups = threadDb.httpOxenOpenGroups
|
||||
if (legacyOpenGroups.isEmpty() && httpBasedNewGroups.isEmpty()) return // no need to migrate
|
||||
|
||||
val newOpenGroups = threadDb.httpsOxenOpenGroups
|
||||
val firstStepMigration = getExistingMappings(legacyOpenGroups, newOpenGroups)
|
||||
|
||||
val secondStepMigration = getExistingMappings(httpBasedNewGroups, newOpenGroups)
|
||||
|
||||
val groupDb = databaseComponent.groupDatabase()
|
||||
val lokiApiDb = databaseComponent.lokiAPIDatabase()
|
||||
val smsDb = databaseComponent.smsDatabase()
|
||||
val mmsDb = databaseComponent.mmsDatabase()
|
||||
val lokiMessageDatabase = databaseComponent.lokiMessageDatabase()
|
||||
val lokiThreadDatabase = databaseComponent.lokiThreadDatabase()
|
||||
|
||||
firstStepMigration.forEach { (stub, old, new) ->
|
||||
val legacyEncodedGroupId = LEGACY_GROUP_ENCODED_ID+stub
|
||||
if (new == null) {
|
||||
val newEncodedGroupId = NEW_GROUP_ENCODED_ID+stub
|
||||
// migrate thread and group encoded values
|
||||
threadDb.migrateEncodedGroup(old, newEncodedGroupId)
|
||||
groupDb.migrateEncodedGroup(legacyEncodedGroupId, newEncodedGroupId)
|
||||
// migrate Loki API DB values
|
||||
// decode the hex to bytes, decode byte array to string i.e. "oxen" or "session"
|
||||
val decodedStub = Hex.fromStringCondensed(stub).decodeToString()
|
||||
val legacyLokiServerId = "${OpenGroupApi.legacyDefaultServer}.$decodedStub"
|
||||
val newLokiServerId = "${OpenGroupApi.defaultServer}.$decodedStub"
|
||||
lokiApiDb.migrateLegacyOpenGroup(legacyLokiServerId, newLokiServerId)
|
||||
// migrate loki thread db server info
|
||||
val oldServerInfo = lokiThreadDatabase.getOpenGroupChat(old)
|
||||
val newServerInfo = oldServerInfo!!.copy(server = OpenGroupApi.defaultServer, id = newLokiServerId)
|
||||
lokiThreadDatabase.setOpenGroupChat(newServerInfo, old)
|
||||
} else {
|
||||
// has a legacy and a new one
|
||||
// migrate SMS and MMS tables
|
||||
smsDb.migrateThreadId(old, new)
|
||||
mmsDb.migrateThreadId(old, new)
|
||||
lokiMessageDatabase.migrateThreadId(old, new)
|
||||
// delete group for legacy ID
|
||||
groupDb.delete(legacyEncodedGroupId)
|
||||
// delete thread for legacy ID
|
||||
threadDb.deleteConversation(old)
|
||||
lokiThreadDatabase.removeOpenGroupChat(old)
|
||||
}
|
||||
// maybe migrate jobs here
|
||||
}
|
||||
|
||||
secondStepMigration.forEach { (stub, old, new) ->
|
||||
val legacyEncodedGroupId = HTTP_PREFIX + OPEN_GET_SESSION_TRAILING_DOT_ENCODED + stub
|
||||
if (new == null) {
|
||||
val newEncodedGroupId = NEW_GROUP_ENCODED_ID+stub
|
||||
// migrate thread and group encoded values
|
||||
threadDb.migrateEncodedGroup(old, newEncodedGroupId)
|
||||
groupDb.migrateEncodedGroup(legacyEncodedGroupId, newEncodedGroupId)
|
||||
// migrate Loki API DB values
|
||||
// decode the hex to bytes, decode byte array to string i.e. "oxen" or "session"
|
||||
val decodedStub = Hex.fromStringCondensed(stub).decodeToString()
|
||||
val legacyLokiServerId = "${OpenGroupApi.httpDefaultServer}.$decodedStub"
|
||||
val newLokiServerId = "${OpenGroupApi.defaultServer}.$decodedStub"
|
||||
lokiApiDb.migrateLegacyOpenGroup(legacyLokiServerId, newLokiServerId)
|
||||
// migrate loki thread db server info
|
||||
val oldServerInfo = lokiThreadDatabase.getOpenGroupChat(old)
|
||||
val newServerInfo = oldServerInfo!!.copy(server = OpenGroupApi.defaultServer, id = newLokiServerId)
|
||||
lokiThreadDatabase.setOpenGroupChat(newServerInfo, old)
|
||||
} else {
|
||||
// has a legacy and a new one
|
||||
// migrate SMS and MMS tables
|
||||
smsDb.migrateThreadId(old, new)
|
||||
mmsDb.migrateThreadId(old, new)
|
||||
lokiMessageDatabase.migrateThreadId(old, new)
|
||||
// delete group for legacy ID
|
||||
groupDb.delete(legacyEncodedGroupId)
|
||||
// delete thread for legacy ID
|
||||
threadDb.deleteConversation(old)
|
||||
lokiThreadDatabase.removeOpenGroupChat(old)
|
||||
}
|
||||
// maybe migrate jobs here
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,281 +0,0 @@
|
||||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.KStubbing
|
||||
import org.mockito.kotlin.argumentCaptor
|
||||
import org.mockito.kotlin.doAnswer
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.eq
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.verifyNoMoreInteractions
|
||||
import org.session.libsession.messaging.open_groups.OpenGroup
|
||||
import org.session.libsession.messaging.open_groups.OpenGroupApi
|
||||
import org.session.libsession.utilities.Address
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase
|
||||
import org.thoughtcrime.securesms.database.LokiAPIDatabase
|
||||
import org.thoughtcrime.securesms.database.LokiMessageDatabase
|
||||
import org.thoughtcrime.securesms.database.LokiThreadDatabase
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||
import org.thoughtcrime.securesms.groups.OpenGroupMigrator
|
||||
import org.thoughtcrime.securesms.groups.OpenGroupMigrator.OpenGroupMapping
|
||||
import org.thoughtcrime.securesms.groups.OpenGroupMigrator.roomStub
|
||||
|
||||
class OpenGroupMigrationTests {
|
||||
|
||||
companion object {
|
||||
const val EXAMPLE_LEGACY_ENCODED_OPEN_GROUP = "__loki_public_chat_group__!687474703a2f2f3131362e3230332e37302e33332e6f78656e"
|
||||
const val EXAMPLE_NEW_ENCODED_OPEN_GROUP = "__loki_public_chat_group__!68747470733a2f2f6f70656e2e67657473657373696f6e2e6f72672e6f78656e"
|
||||
const val OXEN_STUB_HEX = "6f78656e"
|
||||
|
||||
const val EXAMPLE_LEGACY_SERVER_ID = "http://116.203.70.33.oxen"
|
||||
const val EXAMPLE_NEW_SERVER_ID = "https://open.getsession.org.oxen"
|
||||
|
||||
const val LEGACY_THREAD_ID = 1L
|
||||
const val NEW_THREAD_ID = 2L
|
||||
}
|
||||
|
||||
private fun legacyOpenGroupRecipient(additionalMocks: ((KStubbing<Recipient>) -> Unit) ? = null) = mock<Recipient> {
|
||||
on { address } doReturn Address.fromSerialized(EXAMPLE_LEGACY_ENCODED_OPEN_GROUP)
|
||||
on { isOpenGroupRecipient } doReturn true
|
||||
additionalMocks?.let { it(this) }
|
||||
}
|
||||
|
||||
private fun newOpenGroupRecipient(additionalMocks: ((KStubbing<Recipient>) -> Unit) ? = null) = mock<Recipient> {
|
||||
on { address } doReturn Address.fromSerialized(EXAMPLE_NEW_ENCODED_OPEN_GROUP)
|
||||
on { isOpenGroupRecipient } doReturn true
|
||||
additionalMocks?.let { it(this) }
|
||||
}
|
||||
|
||||
private fun legacyThreadRecord(additionalRecipientMocks: ((KStubbing<Recipient>) -> Unit) ? = null, additionalThreadMocks: ((KStubbing<ThreadRecord>) -> Unit)? = null) = mock<ThreadRecord> {
|
||||
val returnedRecipient = legacyOpenGroupRecipient(additionalRecipientMocks)
|
||||
on { recipient } doReturn returnedRecipient
|
||||
on { threadId } doReturn LEGACY_THREAD_ID
|
||||
}
|
||||
|
||||
private fun newThreadRecord(additionalRecipientMocks: ((KStubbing<Recipient>) -> Unit)? = null, additionalThreadMocks: ((KStubbing<ThreadRecord>) -> Unit)? = null) = mock<ThreadRecord> {
|
||||
val returnedRecipient = newOpenGroupRecipient(additionalRecipientMocks)
|
||||
on { recipient } doReturn returnedRecipient
|
||||
on { threadId } doReturn NEW_THREAD_ID
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `it should generate the correct room stubs for legacy groups`() {
|
||||
val mockRecipient = legacyOpenGroupRecipient()
|
||||
assertEquals(OXEN_STUB_HEX, mockRecipient.roomStub())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `it should generate the correct room stubs for new groups`() {
|
||||
val mockNewRecipient = newOpenGroupRecipient()
|
||||
assertEquals(OXEN_STUB_HEX, mockNewRecipient.roomStub())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `it should return correct mappings`() {
|
||||
val legacyThread = legacyThreadRecord()
|
||||
val newThread = newThreadRecord()
|
||||
|
||||
val expectedMapping = listOf(
|
||||
OpenGroupMapping(OXEN_STUB_HEX, LEGACY_THREAD_ID, NEW_THREAD_ID)
|
||||
)
|
||||
|
||||
assertTrue(expectedMapping.containsAll(OpenGroupMigrator.getExistingMappings(listOf(legacyThread), listOf(newThread))))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `it should return no mappings if there are no legacy open groups`() {
|
||||
val mappings = OpenGroupMigrator.getExistingMappings(listOf(), listOf())
|
||||
assertTrue(mappings.isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `it should return no mappings if there are only new open groups`() {
|
||||
val newThread = newThreadRecord()
|
||||
val mappings = OpenGroupMigrator.getExistingMappings(emptyList(), listOf(newThread))
|
||||
assertTrue(mappings.isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `it should return null new thread in mappings if there are only legacy open groups`() {
|
||||
val legacyThread = legacyThreadRecord()
|
||||
val mappings = OpenGroupMigrator.getExistingMappings(listOf(legacyThread), emptyList())
|
||||
val expectedMappings = listOf(
|
||||
OpenGroupMapping(OXEN_STUB_HEX, LEGACY_THREAD_ID, null)
|
||||
)
|
||||
assertTrue(expectedMappings.containsAll(mappings))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test migration thread DB calls legacy and returns if no legacy official groups`() {
|
||||
val mockedThreadDb = mock<ThreadDatabase> {
|
||||
on { legacyOxenOpenGroups } doReturn emptyList()
|
||||
}
|
||||
val mockedDbComponent = mock<DatabaseComponent> {
|
||||
on { threadDatabase() } doReturn mockedThreadDb
|
||||
}
|
||||
|
||||
OpenGroupMigrator.migrate(mockedDbComponent)
|
||||
|
||||
verify(mockedDbComponent).threadDatabase()
|
||||
verify(mockedThreadDb).legacyOxenOpenGroups
|
||||
verifyNoMoreInteractions(mockedThreadDb)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `it should migrate on thread, group and loki dbs with correct values for legacy only migration`() {
|
||||
// mock threadDB
|
||||
val capturedThreadId = argumentCaptor<Long>()
|
||||
val capturedNewEncoded = argumentCaptor<String>()
|
||||
val mockedThreadDb = mock<ThreadDatabase> {
|
||||
val legacyThreadRecord = legacyThreadRecord()
|
||||
on { legacyOxenOpenGroups } doReturn listOf(legacyThreadRecord)
|
||||
on { httpsOxenOpenGroups } doReturn emptyList()
|
||||
on { migrateEncodedGroup(capturedThreadId.capture(), capturedNewEncoded.capture()) } doAnswer {}
|
||||
}
|
||||
|
||||
// mock groupDB
|
||||
val capturedGroupLegacyEncoded = argumentCaptor<String>()
|
||||
val capturedGroupNewEncoded = argumentCaptor<String>()
|
||||
val mockedGroupDb = mock<GroupDatabase> {
|
||||
on {
|
||||
migrateEncodedGroup(
|
||||
capturedGroupLegacyEncoded.capture(),
|
||||
capturedGroupNewEncoded.capture()
|
||||
)
|
||||
} doAnswer {}
|
||||
}
|
||||
|
||||
// mock LokiAPIDB
|
||||
val capturedLokiLegacyGroup = argumentCaptor<String>()
|
||||
val capturedLokiNewGroup = argumentCaptor<String>()
|
||||
val mockedLokiApi = mock<LokiAPIDatabase> {
|
||||
on { migrateLegacyOpenGroup(capturedLokiLegacyGroup.capture(), capturedLokiNewGroup.capture()) } doAnswer {}
|
||||
}
|
||||
|
||||
val pubKey = OpenGroupApi.defaultServerPublicKey
|
||||
val room = "oxen"
|
||||
val legacyServer = OpenGroupApi.legacyDefaultServer
|
||||
val newServer = OpenGroupApi.defaultServer
|
||||
|
||||
val lokiThreadOpenGroup = argumentCaptor<OpenGroup>()
|
||||
val mockedLokiThreadDb = mock<LokiThreadDatabase> {
|
||||
on { getOpenGroupChat(eq(LEGACY_THREAD_ID)) } doReturn OpenGroup(legacyServer, room, "Oxen", 0, pubKey)
|
||||
on { setOpenGroupChat(lokiThreadOpenGroup.capture(), eq(LEGACY_THREAD_ID)) } doAnswer {}
|
||||
}
|
||||
|
||||
val mockedDbComponent = mock<DatabaseComponent> {
|
||||
on { threadDatabase() } doReturn mockedThreadDb
|
||||
on { groupDatabase() } doReturn mockedGroupDb
|
||||
on { lokiAPIDatabase() } doReturn mockedLokiApi
|
||||
on { lokiThreadDatabase() } doReturn mockedLokiThreadDb
|
||||
}
|
||||
|
||||
OpenGroupMigrator.migrate(mockedDbComponent)
|
||||
|
||||
// expect threadDB migration to reflect new thread values:
|
||||
// thread ID = 1, encoded ID = new encoded ID
|
||||
assertEquals(LEGACY_THREAD_ID, capturedThreadId.firstValue)
|
||||
assertEquals(EXAMPLE_NEW_ENCODED_OPEN_GROUP, capturedNewEncoded.firstValue)
|
||||
|
||||
// expect groupDB migration to reflect new thread values:
|
||||
// legacy encoded ID, new encoded ID
|
||||
assertEquals(EXAMPLE_LEGACY_ENCODED_OPEN_GROUP, capturedGroupLegacyEncoded.firstValue)
|
||||
assertEquals(EXAMPLE_NEW_ENCODED_OPEN_GROUP, capturedGroupNewEncoded.firstValue)
|
||||
|
||||
// expect Loki API DB migration to reflect new thread values:
|
||||
assertEquals("${OpenGroupApi.legacyDefaultServer}.oxen", capturedLokiLegacyGroup.firstValue)
|
||||
assertEquals("${OpenGroupApi.defaultServer}.oxen", capturedLokiNewGroup.firstValue)
|
||||
|
||||
assertEquals(newServer, lokiThreadOpenGroup.firstValue.server)
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `it should migrate and delete legacy thread with conflicting new and old values`() {
|
||||
|
||||
// mock threadDB
|
||||
val capturedThreadId = argumentCaptor<Long>()
|
||||
val mockedThreadDb = mock<ThreadDatabase> {
|
||||
val legacyThreadRecord = legacyThreadRecord()
|
||||
val newThreadRecord = newThreadRecord()
|
||||
on { legacyOxenOpenGroups } doReturn listOf(legacyThreadRecord)
|
||||
on { httpsOxenOpenGroups } doReturn listOf(newThreadRecord)
|
||||
on { deleteConversation(capturedThreadId.capture()) } doAnswer {}
|
||||
}
|
||||
|
||||
// mock groupDB
|
||||
val capturedGroupLegacyEncoded = argumentCaptor<String>()
|
||||
val mockedGroupDb = mock<GroupDatabase> {
|
||||
on { delete(capturedGroupLegacyEncoded.capture()) } doReturn true
|
||||
}
|
||||
|
||||
// mock LokiAPIDB
|
||||
val capturedLokiLegacyGroup = argumentCaptor<String>()
|
||||
val capturedLokiNewGroup = argumentCaptor<String>()
|
||||
val mockedLokiApi = mock<LokiAPIDatabase> {
|
||||
on { migrateLegacyOpenGroup(capturedLokiLegacyGroup.capture(), capturedLokiNewGroup.capture()) } doAnswer {}
|
||||
}
|
||||
|
||||
// mock messaging dbs
|
||||
val migrateMmsFromThreadId = argumentCaptor<Long>()
|
||||
val migrateMmsToThreadId = argumentCaptor<Long>()
|
||||
|
||||
val mockedMmsDb = mock<MmsDatabase> {
|
||||
on { migrateThreadId(migrateMmsFromThreadId.capture(), migrateMmsToThreadId.capture()) } doAnswer {}
|
||||
}
|
||||
|
||||
val migrateSmsFromThreadId = argumentCaptor<Long>()
|
||||
val migrateSmsToThreadId = argumentCaptor<Long>()
|
||||
val mockedSmsDb = mock<SmsDatabase> {
|
||||
on { migrateThreadId(migrateSmsFromThreadId.capture(), migrateSmsToThreadId.capture()) } doAnswer {}
|
||||
}
|
||||
|
||||
val lokiFromThreadId = argumentCaptor<Long>()
|
||||
val lokiToThreadId = argumentCaptor<Long>()
|
||||
val mockedLokiMessageDatabase = mock<LokiMessageDatabase> {
|
||||
on { migrateThreadId(lokiFromThreadId.capture(), lokiToThreadId.capture()) } doAnswer {}
|
||||
}
|
||||
|
||||
val mockedLokiThreadDb = mock<LokiThreadDatabase> {
|
||||
on { removeOpenGroupChat(eq(LEGACY_THREAD_ID)) } doAnswer {}
|
||||
}
|
||||
|
||||
val mockedDbComponent = mock<DatabaseComponent> {
|
||||
on { threadDatabase() } doReturn mockedThreadDb
|
||||
on { groupDatabase() } doReturn mockedGroupDb
|
||||
on { lokiAPIDatabase() } doReturn mockedLokiApi
|
||||
on { mmsDatabase() } doReturn mockedMmsDb
|
||||
on { smsDatabase() } doReturn mockedSmsDb
|
||||
on { lokiMessageDatabase() } doReturn mockedLokiMessageDatabase
|
||||
on { lokiThreadDatabase() } doReturn mockedLokiThreadDb
|
||||
}
|
||||
|
||||
OpenGroupMigrator.migrate(mockedDbComponent)
|
||||
|
||||
// should delete thread by thread ID
|
||||
assertEquals(LEGACY_THREAD_ID, capturedThreadId.firstValue)
|
||||
|
||||
// should delete group by legacy encoded ID
|
||||
assertEquals(EXAMPLE_LEGACY_ENCODED_OPEN_GROUP, capturedGroupLegacyEncoded.firstValue)
|
||||
|
||||
// should migrate SMS from legacy thread ID to new thread ID
|
||||
assertEquals(LEGACY_THREAD_ID, migrateSmsFromThreadId.firstValue)
|
||||
assertEquals(NEW_THREAD_ID, migrateSmsToThreadId.firstValue)
|
||||
|
||||
// should migrate MMS from legacy thread ID to new thread ID
|
||||
assertEquals(LEGACY_THREAD_ID, migrateMmsFromThreadId.firstValue)
|
||||
assertEquals(NEW_THREAD_ID, migrateMmsToThreadId.firstValue)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue