kopia lustrzana https://github.com/ryukoposting/Signal-Android
843 wiersze
21 KiB
Kotlin
843 wiersze
21 KiB
Kotlin
package org.thoughtcrime.securesms.database
|
|
|
|
import androidx.core.content.contentValuesOf
|
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
import org.junit.Assert.assertEquals
|
|
import org.junit.Before
|
|
import org.junit.Rule
|
|
import org.junit.Test
|
|
import org.junit.runner.RunWith
|
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
|
import org.thoughtcrime.securesms.testing.SignalDatabaseRule
|
|
import org.thoughtcrime.securesms.util.Util
|
|
import org.whispersystems.signalservice.api.push.ACI
|
|
import org.whispersystems.signalservice.api.push.PNI
|
|
import org.whispersystems.signalservice.api.push.ServiceId
|
|
import java.lang.AssertionError
|
|
import java.lang.IllegalStateException
|
|
import java.util.UUID
|
|
|
|
@RunWith(AndroidJUnit4::class)
|
|
class RecipientTableTest_processPnpTupleToChangeSet {
|
|
|
|
@Rule
|
|
@JvmField
|
|
val databaseRule = SignalDatabaseRule(deleteAllThreadsOnEachRun = false)
|
|
|
|
private lateinit var db: RecipientTable
|
|
|
|
@Before
|
|
fun setup() {
|
|
db = SignalDatabase.recipients
|
|
}
|
|
|
|
@Test
|
|
fun noMatch_e164Only() {
|
|
val changeSet = db.processPnpTupleToChangeSet(E164_A, null, null, pniVerified = false)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpInsert(E164_A, null, null)
|
|
),
|
|
changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun noMatch_e164AndPni() {
|
|
val changeSet = db.processPnpTupleToChangeSet(E164_A, PNI_A, null, pniVerified = false)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpInsert(E164_A, PNI_A, null)
|
|
),
|
|
changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun noMatch_aciOnly() {
|
|
val changeSet = db.processPnpTupleToChangeSet(null, null, ACI_A, pniVerified = false)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpInsert(null, null, ACI_A)
|
|
),
|
|
changeSet
|
|
)
|
|
}
|
|
|
|
@Test(expected = IllegalStateException::class)
|
|
fun noMatch_noData() {
|
|
db.processPnpTupleToChangeSet(null, null, null, pniVerified = false)
|
|
}
|
|
|
|
@Test
|
|
fun noMatch_allFields() {
|
|
val changeSet = db.processPnpTupleToChangeSet(E164_A, PNI_A, ACI_A, pniVerified = false)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpInsert(E164_A, PNI_A, ACI_A)
|
|
),
|
|
changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun fullMatch() {
|
|
val result = applyAndAssert(
|
|
Input(E164_A, PNI_A, ACI_A),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun onlyE164Matches() {
|
|
val result = applyAndAssert(
|
|
Input(E164_A, null, null),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetPni(result.id, PNI_A),
|
|
PnpOperation.SetAci(result.id, ACI_A)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun onlyE164Matches_pniChanges_noAciProvided_existingPniSession() {
|
|
val result = applyAndAssert(
|
|
Input(E164_A, PNI_B, null, pniSession = true),
|
|
Update(E164_A, PNI_A, null),
|
|
Output(E164_A, PNI_A, null)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetPni(result.id, PNI_A),
|
|
PnpOperation.SessionSwitchoverInsert(result.id)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun onlyE164Matches_pniChanges_noAciProvided_noPniSession() {
|
|
val result = applyAndAssert(
|
|
Input(E164_A, PNI_B, null),
|
|
Update(E164_A, PNI_A, null),
|
|
Output(E164_A, PNI_A, null)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetPni(result.id, PNI_A)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun e164AndPniMatches_noExistingSession() {
|
|
val result = applyAndAssert(
|
|
Input(E164_A, PNI_A, null),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetAci(result.id, ACI_A)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun e164AndPniMatches_existingPniSession() {
|
|
val result = applyAndAssert(
|
|
Input(E164_A, PNI_A, null, pniSession = true),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetAci(result.id, ACI_A),
|
|
PnpOperation.SessionSwitchoverInsert(result.id)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun e164AndAciMatches() {
|
|
val result = applyAndAssert(
|
|
Input(E164_A, null, ACI_A),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetPni(result.id, PNI_A)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun onlyPniMatches_noExistingSession() {
|
|
val result = applyAndAssert(
|
|
Input(null, PNI_A, null),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetE164(result.id, E164_A),
|
|
PnpOperation.SetAci(result.id, ACI_A)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun onlyPniMatches_existingPniSession() {
|
|
val result = applyAndAssert(
|
|
Input(null, PNI_A, null, pniSession = true),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetE164(result.id, E164_A),
|
|
PnpOperation.SetAci(result.id, ACI_A),
|
|
PnpOperation.SessionSwitchoverInsert(result.id)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun onlyPniMatches_existingPniSession_changeNumber() {
|
|
val result = applyAndAssert(
|
|
Input(E164_B, PNI_A, null, pniSession = true),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetE164(result.id, E164_A),
|
|
PnpOperation.SetAci(result.id, ACI_A),
|
|
PnpOperation.ChangeNumberInsert(
|
|
recipientId = result.id,
|
|
oldE164 = E164_B,
|
|
newE164 = E164_A
|
|
),
|
|
PnpOperation.SessionSwitchoverInsert(result.id)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun pniAndAciMatches() {
|
|
val result = applyAndAssert(
|
|
Input(null, PNI_A, ACI_A),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetE164(result.id, E164_A),
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun pniAndAciMatches_changeNumber() {
|
|
val result = applyAndAssert(
|
|
Input(E164_B, PNI_A, ACI_A),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetE164(result.id, E164_A),
|
|
PnpOperation.ChangeNumberInsert(
|
|
recipientId = result.id,
|
|
oldE164 = E164_B,
|
|
newE164 = E164_A
|
|
)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun onlyAciMatches() {
|
|
val result = applyAndAssert(
|
|
Input(null, null, ACI_A),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetE164(result.id, E164_A),
|
|
PnpOperation.SetPni(result.id, PNI_A)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun onlyAciMatches_changeNumber() {
|
|
val result = applyAndAssert(
|
|
Input(E164_B, null, ACI_A),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.id),
|
|
operations = listOf(
|
|
PnpOperation.SetE164(result.id, E164_A),
|
|
PnpOperation.SetPni(result.id, PNI_A),
|
|
PnpOperation.ChangeNumberInsert(
|
|
recipientId = result.id,
|
|
oldE164 = E164_B,
|
|
newE164 = E164_A
|
|
)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164Only_pniOnly_aciOnly() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_A, null, null),
|
|
Input(null, PNI_A, null),
|
|
Input(null, null, ACI_A)
|
|
),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.thirdId),
|
|
operations = listOf(
|
|
PnpOperation.Merge(
|
|
primaryId = result.firstId,
|
|
secondaryId = result.secondId
|
|
),
|
|
PnpOperation.Merge(
|
|
primaryId = result.thirdId,
|
|
secondaryId = result.firstId
|
|
)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164Only_pniOnly_noAciProvided() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_A, null, null),
|
|
Input(null, PNI_A, null),
|
|
),
|
|
Update(E164_A, PNI_A, null),
|
|
Output(E164_A, PNI_A, null)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.firstId),
|
|
operations = listOf(
|
|
PnpOperation.Merge(
|
|
primaryId = result.firstId,
|
|
secondaryId = result.secondId
|
|
)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164Only_pniOnly_aciProvidedButNoAciRecord() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_A, null, null),
|
|
Input(null, PNI_A, null),
|
|
),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.firstId),
|
|
operations = listOf(
|
|
PnpOperation.Merge(
|
|
primaryId = result.firstId,
|
|
secondaryId = result.secondId
|
|
),
|
|
PnpOperation.SetAci(
|
|
recipientId = result.firstId,
|
|
aci = ACI_A
|
|
)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164Only_pniAndE164_noAciProvided() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_A, null, null),
|
|
Input(E164_B, PNI_A, null),
|
|
),
|
|
Update(E164_A, PNI_A, null),
|
|
Output(E164_A, PNI_A, null)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.firstId),
|
|
operations = listOf(
|
|
PnpOperation.RemovePni(result.secondId),
|
|
PnpOperation.SetPni(
|
|
recipientId = result.firstId,
|
|
pni = PNI_A
|
|
),
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164AndPni_pniOnly_noAciProvided() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_A, PNI_B, null),
|
|
Input(null, PNI_A, null),
|
|
),
|
|
Update(E164_A, PNI_A, null),
|
|
Output(E164_A, PNI_A, null)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.firstId),
|
|
operations = listOf(
|
|
PnpOperation.RemovePni(result.firstId),
|
|
PnpOperation.Merge(
|
|
primaryId = result.firstId,
|
|
secondaryId = result.secondId
|
|
),
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164AndPni_e164AndPni_noAciProvided_noSessions() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_A, PNI_B, null),
|
|
Input(E164_B, PNI_A, null),
|
|
),
|
|
Update(E164_A, PNI_A, null),
|
|
Output(E164_A, PNI_A, null)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.firstId),
|
|
operations = listOf(
|
|
PnpOperation.RemovePni(result.secondId),
|
|
PnpOperation.SetPni(result.firstId, PNI_A)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164AndPni_e164AndPni_noAciProvided_sessionsExist() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_A, PNI_B, null, pniSession = true),
|
|
Input(E164_B, PNI_A, null, pniSession = true),
|
|
),
|
|
Update(E164_A, PNI_A, null),
|
|
Output(E164_A, PNI_A, null)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.firstId),
|
|
operations = listOf(
|
|
PnpOperation.RemovePni(result.secondId),
|
|
PnpOperation.SetPni(result.firstId, PNI_A),
|
|
PnpOperation.SessionSwitchoverInsert(result.secondId),
|
|
PnpOperation.SessionSwitchoverInsert(result.firstId)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164AndPni_aciOnly() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_A, PNI_A, null),
|
|
Input(null, null, ACI_A),
|
|
),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.secondId),
|
|
operations = listOf(
|
|
PnpOperation.Merge(
|
|
primaryId = result.secondId,
|
|
secondaryId = result.firstId
|
|
),
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164AndPni_aciOnly_e164RecordHasSeparateE164() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_B, PNI_A, null),
|
|
Input(null, null, ACI_A),
|
|
),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.secondId),
|
|
operations = listOf(
|
|
PnpOperation.RemovePni(result.firstId),
|
|
PnpOperation.SetPni(
|
|
recipientId = result.secondId,
|
|
pni = PNI_A,
|
|
),
|
|
PnpOperation.SetE164(
|
|
recipientId = result.secondId,
|
|
e164 = E164_A,
|
|
)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164AndPni_aciOnly_e164RecordHasSeparateE164_changeNumber() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_B, PNI_A, null),
|
|
Input(E164_C, null, ACI_A),
|
|
),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.secondId),
|
|
operations = listOf(
|
|
PnpOperation.RemovePni(result.firstId),
|
|
PnpOperation.SetPni(
|
|
recipientId = result.secondId,
|
|
pni = PNI_A,
|
|
),
|
|
PnpOperation.SetE164(
|
|
recipientId = result.secondId,
|
|
e164 = E164_A,
|
|
),
|
|
PnpOperation.ChangeNumberInsert(
|
|
recipientId = result.secondId,
|
|
oldE164 = E164_C,
|
|
newE164 = E164_A
|
|
)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164AndPni_e164AndPniAndAci_changeNumber() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_A, PNI_A, null),
|
|
Input(E164_B, PNI_B, ACI_A),
|
|
),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.secondId),
|
|
operations = listOf(
|
|
PnpOperation.RemovePni(result.secondId),
|
|
PnpOperation.RemoveE164(result.secondId),
|
|
PnpOperation.Merge(
|
|
primaryId = result.secondId,
|
|
secondaryId = result.firstId
|
|
),
|
|
PnpOperation.ChangeNumberInsert(
|
|
recipientId = result.secondId,
|
|
oldE164 = E164_B,
|
|
newE164 = E164_A
|
|
)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
@Test
|
|
fun merge_e164AndPni_e164Aci_changeNumber() {
|
|
val result = applyAndAssert(
|
|
listOf(
|
|
Input(E164_A, PNI_A, null),
|
|
Input(E164_B, null, ACI_A),
|
|
),
|
|
Update(E164_A, PNI_A, ACI_A),
|
|
Output(E164_A, PNI_A, ACI_A)
|
|
)
|
|
|
|
assertEquals(
|
|
PnpChangeSet(
|
|
id = PnpIdResolver.PnpNoopId(result.secondId),
|
|
operations = listOf(
|
|
PnpOperation.RemoveE164(result.secondId),
|
|
PnpOperation.Merge(
|
|
primaryId = result.secondId,
|
|
secondaryId = result.firstId
|
|
),
|
|
PnpOperation.ChangeNumberInsert(
|
|
recipientId = result.secondId,
|
|
oldE164 = E164_B,
|
|
newE164 = E164_A
|
|
)
|
|
)
|
|
),
|
|
result.changeSet
|
|
)
|
|
}
|
|
|
|
private fun insert(e164: String?, pni: PNI?, aci: ACI?): RecipientId {
|
|
val id: Long = SignalDatabase.rawDatabase.insert(
|
|
RecipientTable.TABLE_NAME,
|
|
null,
|
|
contentValuesOf(
|
|
RecipientTable.PHONE to e164,
|
|
RecipientTable.SERVICE_ID to (aci ?: pni)?.toString(),
|
|
RecipientTable.PNI_COLUMN to pni?.toString(),
|
|
RecipientTable.REGISTERED to RecipientTable.RegisteredState.REGISTERED.id
|
|
)
|
|
)
|
|
|
|
return RecipientId.from(id)
|
|
}
|
|
|
|
private fun insertMockSessionFor(account: ServiceId, address: ServiceId) {
|
|
SignalDatabase.rawDatabase.insert(
|
|
SessionTable.TABLE_NAME, null,
|
|
contentValuesOf(
|
|
SessionTable.ACCOUNT_ID to account.toString(),
|
|
SessionTable.ADDRESS to address.toString(),
|
|
SessionTable.DEVICE to 1,
|
|
SessionTable.RECORD to Util.getSecretBytes(32)
|
|
)
|
|
)
|
|
}
|
|
|
|
data class Input(val e164: String?, val pni: PNI?, val aci: ACI?, val pniSession: Boolean = false, val aciSession: Boolean = false)
|
|
data class Update(val e164: String?, val pni: PNI?, val aci: ACI?, val pniVerified: Boolean = false)
|
|
data class Output(val e164: String?, val pni: PNI?, val aci: ACI?)
|
|
data class PnpMatchResult(val ids: List<RecipientId>, val changeSet: PnpChangeSet) {
|
|
val id
|
|
get() = if (ids.size == 1) {
|
|
ids[0]
|
|
} else {
|
|
throw IllegalStateException("There are multiple IDs, but you assumed 1!")
|
|
}
|
|
|
|
val firstId
|
|
get() = ids[0]
|
|
|
|
val secondId
|
|
get() = ids[1]
|
|
|
|
val thirdId
|
|
get() = ids[2]
|
|
}
|
|
|
|
private fun applyAndAssert(input: Input, update: Update, output: Output): PnpMatchResult {
|
|
return applyAndAssert(listOf(input), update, output)
|
|
}
|
|
|
|
/**
|
|
* Helper method that will call insert your recipients, call [RecipientTable.processPnpTupleToChangeSet] with your params,
|
|
* and then verify your output matches what you expect.
|
|
*
|
|
* It results the inserted ID's and changeset for additional verification.
|
|
*
|
|
* But basically this is here to make the tests more readable. It gives you a clear list of:
|
|
* - input
|
|
* - update
|
|
* - output
|
|
*
|
|
* that you can spot check easily.
|
|
*
|
|
* Important: The output will only include records that contain fields from the input. That means
|
|
* for:
|
|
*
|
|
* Input: E164_B, PNI_A, null
|
|
* Update: E164_A, PNI_A, null
|
|
*
|
|
* You will get:
|
|
* Output: E164_A, PNI_A, null
|
|
*
|
|
* Even though there was an update that will also result in the row (E164_B, null, null)
|
|
*/
|
|
private fun applyAndAssert(input: List<Input>, update: Update, output: Output): PnpMatchResult {
|
|
val ids = input.map { insert(it.e164, it.pni, it.aci) }
|
|
|
|
input
|
|
.filter { it.pniSession }
|
|
.forEach { insertMockSessionFor(databaseRule.localAci, it.pni!!) }
|
|
|
|
input
|
|
.filter { it.aciSession }
|
|
.forEach { insertMockSessionFor(databaseRule.localAci, it.aci!!) }
|
|
|
|
val byE164 = update.e164?.let { db.getByE164(it).orElse(null) }
|
|
val byPniSid = update.pni?.let { db.getByServiceId(it).orElse(null) }
|
|
val byAciSid = update.aci?.let { db.getByServiceId(it).orElse(null) }
|
|
|
|
val data = PnpDataSet(
|
|
e164 = update.e164,
|
|
pni = update.pni,
|
|
aci = update.aci,
|
|
byE164 = byE164,
|
|
byPniSid = byPniSid,
|
|
byPniOnly = update.pni?.let { db.getByPni(it).orElse(null) },
|
|
byAciSid = byAciSid,
|
|
e164Record = byE164?.let { db.getRecord(it) },
|
|
pniSidRecord = byPniSid?.let { db.getRecord(it) },
|
|
aciSidRecord = byAciSid?.let { db.getRecord(it) }
|
|
)
|
|
val changeSet = db.processPnpTupleToChangeSet(update.e164, update.pni, update.aci, pniVerified = update.pniVerified)
|
|
|
|
val finalData = data.perform(changeSet.operations)
|
|
|
|
val finalRecords = setOfNotNull(finalData.e164Record, finalData.pniSidRecord, finalData.aciSidRecord)
|
|
assertEquals("There's still multiple records in the resulting record set! $finalRecords", 1, finalRecords.size)
|
|
|
|
finalRecords.firstOrNull { record -> record.e164 == output.e164 && record.pni == output.pni && record.serviceId == (output.aci ?: output.pni) }
|
|
?: throw AssertionError("Expected output was not found in the result set! Expected: $output")
|
|
|
|
return PnpMatchResult(
|
|
ids = ids,
|
|
changeSet = changeSet
|
|
)
|
|
}
|
|
|
|
companion object {
|
|
val ACI_A = ACI.from(UUID.fromString("3436efbe-5a76-47fa-a98a-7e72c948a82e"))
|
|
val ACI_B = ACI.from(UUID.fromString("8de7f691-0b60-4a68-9cd9-ed2f8453f9ed"))
|
|
|
|
val PNI_A = PNI.from(UUID.fromString("154b8d92-c960-4f6c-8385-671ad2ffb999"))
|
|
val PNI_B = PNI.from(UUID.fromString("ba92b1fb-cd55-40bf-adda-c35a85375533"))
|
|
|
|
const val E164_A = "+12221234567"
|
|
const val E164_B = "+13331234567"
|
|
const val E164_C = "+14441234567"
|
|
}
|
|
}
|