mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-18 02:48:44 +00:00
feat: setup android unit tests for verifying storage behaviours and state of shared configs
This commit is contained in:
parent
2e673901ba
commit
fdff11c535
@ -125,37 +125,35 @@ dependencies {
|
||||
implementation "com.opencsv:opencsv:4.6"
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
testImplementation 'org.assertj:assertj-core:3.11.1'
|
||||
testImplementation "org.mockito:mockito-inline:4.0.0"
|
||||
testImplementation "org.mockito:mockito-inline:4.10.0"
|
||||
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
|
||||
testImplementation 'org.powermock:powermock-api-mockito:1.6.1'
|
||||
testImplementation 'org.powermock:powermock-module-junit4:1.6.1'
|
||||
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.1'
|
||||
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.1'
|
||||
androidTestImplementation "org.mockito:mockito-android:4.10.0"
|
||||
androidTestImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
|
||||
testImplementation "androidx.test:core:$testCoreVersion"
|
||||
testImplementation "androidx.arch.core:core-testing:2.1.0"
|
||||
testImplementation "androidx.arch.core:core-testing:2.2.0"
|
||||
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion"
|
||||
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion"
|
||||
// Core library
|
||||
androidTestImplementation 'androidx.test:core:1.4.0'
|
||||
androidTestImplementation "androidx.test:core:$testCoreVersion"
|
||||
|
||||
// AndroidJUnitRunner and JUnit Rules
|
||||
androidTestImplementation 'androidx.test:runner:1.4.0'
|
||||
androidTestImplementation 'androidx.test:rules:1.4.0'
|
||||
androidTestImplementation 'androidx.test:runner:1.5.2'
|
||||
androidTestImplementation 'androidx.test:rules:1.5.0'
|
||||
|
||||
// Assertions
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.ext:truth:1.4.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.ext:truth:1.5.0'
|
||||
androidTestImplementation 'com.google.truth:truth:1.1.3'
|
||||
|
||||
// Espresso dependencies
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.4.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.4.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-web:3.4.0'
|
||||
androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.4.0'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.4.0'
|
||||
androidTestUtil 'androidx.test:orchestrator:1.4.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.5.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-web:3.5.1'
|
||||
androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.5.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.5.1'
|
||||
androidTestUtil 'androidx.test:orchestrator:1.4.2'
|
||||
|
||||
testImplementation 'org.robolectric:robolectric:4.4'
|
||||
testImplementation 'org.robolectric:shadows-multidex:4.4'
|
||||
|
@ -0,0 +1,81 @@
|
||||
package network.loki.messenger
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import network.loki.messenger.libsession_util.Contacts
|
||||
import network.loki.messenger.libsession_util.util.Contact
|
||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.verify
|
||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsignal.utilities.KeyHelper
|
||||
import org.session.libsignal.utilities.hexEncodedPublicKey
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.crypto.KeyPairUtilities
|
||||
import kotlin.random.Random
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@SmallTest
|
||||
class LibSessionTests {
|
||||
|
||||
private fun randomSeedBytes() = (0 until 16).map { Random.nextInt(UByte.MAX_VALUE.toInt()).toByte() }
|
||||
private fun randomKeyPair() = KeyPairUtilities.generate(randomSeedBytes().toByteArray())
|
||||
private fun randomSessionId() = randomKeyPair().x25519KeyPair.hexEncodedPublicKey
|
||||
|
||||
private fun maybeGetUserInfo(): Pair<ByteArray, String>? {
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as ApplicationContext
|
||||
val prefs = appContext.prefs
|
||||
val localUserPublicKey = prefs.getLocalNumber()
|
||||
val secretKey = with(appContext) {
|
||||
val edKey = KeyPairUtilities.getUserED25519KeyPair(this) ?: return null
|
||||
edKey.secretKey.asBytes
|
||||
}
|
||||
return if (localUserPublicKey == null || secretKey == null) null
|
||||
else secretKey to localUserPublicKey
|
||||
}
|
||||
|
||||
private fun buildContactMessage(contactList: List<Contact>): ByteArray {
|
||||
val (key,_) = maybeGetUserInfo()!!
|
||||
val contacts = Contacts.Companion.newInstance(key)
|
||||
contactList.forEach { contact ->
|
||||
contacts.set(contact)
|
||||
}
|
||||
return contacts.dump()
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setupUser() {
|
||||
val newBytes = randomSeedBytes().toByteArray()
|
||||
val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext
|
||||
val kp = KeyPairUtilities.generate(newBytes)
|
||||
KeyPairUtilities.store(context, kp.seed, kp.ed25519KeyPair, kp.x25519KeyPair)
|
||||
val registrationID = KeyHelper.generateRegistrationId(false)
|
||||
TextSecurePreferences.setLocalRegistrationId(context, registrationID)
|
||||
TextSecurePreferences.setLocalNumber(context, kp.x25519KeyPair.hexEncodedPublicKey)
|
||||
TextSecurePreferences.setRestorationTime(context, 0)
|
||||
TextSecurePreferences.setHasViewedSeed(context, false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun migration_one_to_ones() {
|
||||
val storageSpy = spy(MessagingModuleConfiguration.shared.storage)
|
||||
|
||||
val newContactId = randomSessionId()
|
||||
val singleContact = Contact(
|
||||
id = newContactId,
|
||||
approved = true,
|
||||
expiryMode = ExpiryMode.NONE
|
||||
)
|
||||
val newContactMerge = buildContactMessage(listOf(singleContact))
|
||||
MessagingModuleConfiguration.shared.configFactory.contacts!!.merge("abc123" to newContactMerge)
|
||||
|
||||
verify(storageSpy).addLibSessionContacts(any())
|
||||
}
|
||||
|
||||
}
|
@ -89,7 +89,7 @@ import org.thoughtcrime.securesms.util.SessionMetaProtocol
|
||||
import java.security.MessageDigest
|
||||
import network.loki.messenger.libsession_util.util.Contact as LibSessionContact
|
||||
|
||||
class Storage(context: Context, helper: SQLCipherOpenHelper, private val configFactory: ConfigFactory) : Database(context, helper), StorageProtocol,
|
||||
open class Storage(context: Context, helper: SQLCipherOpenHelper, private val configFactory: ConfigFactory) : Database(context, helper), StorageProtocol,
|
||||
ThreadDatabase.ConversationThreadUpdateListener {
|
||||
|
||||
init {
|
||||
|
@ -17,6 +17,7 @@ import org.session.libsignal.messages.SignalServiceGroup;
|
||||
import org.session.libsignal.utilities.Log;
|
||||
import org.session.libsignal.utilities.guava.Optional;
|
||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.MmsSmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.SmsDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent;
|
||||
@ -37,12 +38,14 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
||||
|
||||
private final SmsDatabase smsDatabase;
|
||||
private final MmsDatabase mmsDatabase;
|
||||
private final MmsSmsDatabase mmsSmsDatabase;
|
||||
private final Context context;
|
||||
|
||||
public ExpiringMessageManager(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.smsDatabase = DatabaseComponent.get(context).smsDatabase();
|
||||
this.mmsDatabase = DatabaseComponent.get(context).mmsDatabase();
|
||||
this.mmsSmsDatabase = DatabaseComponent.get(context).mmsSmsDatabase();
|
||||
|
||||
executor.execute(new LoadTask());
|
||||
executor.execute(new ProcessTask());
|
||||
@ -81,12 +84,11 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
||||
}
|
||||
|
||||
if (message.getId() != null) {
|
||||
DatabaseComponent.get(context).smsDatabase().deleteMessage(message.getId());
|
||||
smsDatabase.deleteMessage(message.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void insertIncomingExpirationTimerMessage(ExpirationTimerUpdate message) {
|
||||
MmsDatabase database = DatabaseComponent.get(context).mmsDatabase();
|
||||
|
||||
String senderPublicKey = message.getSender();
|
||||
Long sentTimestamp = message.getSentTimestamp();
|
||||
@ -126,7 +128,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
||||
Optional.absent(),
|
||||
Optional.absent());
|
||||
//insert the timer update message
|
||||
database.insertSecureDecryptedMessageInbox(mediaMessage, threadId, true);
|
||||
mmsDatabase.insertSecureDecryptedMessageInbox(mediaMessage, threadId, true);
|
||||
|
||||
//set the timer to the conversation
|
||||
MessagingModuleConfiguration.getShared().getStorage().setExpirationTimer(recipient.getAddress().serialize(), duration);
|
||||
@ -137,7 +139,6 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
||||
}
|
||||
|
||||
private void insertOutgoingExpirationTimerMessage(ExpirationTimerUpdate message) {
|
||||
MmsDatabase database = DatabaseComponent.get(context).mmsDatabase();
|
||||
|
||||
Long sentTimestamp = message.getSentTimestamp();
|
||||
String groupId = message.getGroupPublicKey();
|
||||
@ -152,7 +153,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
||||
|
||||
try {
|
||||
OutgoingExpirationUpdateMessage timerUpdateMessage = new OutgoingExpirationUpdateMessage(recipient, sentTimestamp, duration * 1000L, groupId);
|
||||
database.insertSecureDecryptedMessageOutbox(timerUpdateMessage, -1, sentTimestamp, true);
|
||||
mmsDatabase.insertSecureDecryptedMessageOutbox(timerUpdateMessage, -1, sentTimestamp, true);
|
||||
|
||||
if (groupId != null) {
|
||||
// we need the group ID as recipient for setExpireMessages below
|
||||
@ -173,7 +174,7 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
||||
|
||||
@Override
|
||||
public void startAnyExpiration(long timestamp, @NotNull String author) {
|
||||
MessageRecord messageRecord = DatabaseComponent.get(context).mmsSmsDatabase().getMessageFor(timestamp, author);
|
||||
MessageRecord messageRecord = mmsSmsDatabase.getMessageFor(timestamp, author);
|
||||
if (messageRecord != null) {
|
||||
boolean mms = messageRecord.isMms();
|
||||
Recipient recipient = messageRecord.getRecipient();
|
||||
|
@ -21,6 +21,6 @@ preferenceVersion=1.2.0
|
||||
coreVersion=1.8.0
|
||||
|
||||
junitVersion=4.13.2
|
||||
mockitoKotlinVersion=4.0.0
|
||||
testCoreVersion=1.4.0
|
||||
mockitoKotlinVersion=4.1.0
|
||||
testCoreVersion=1.5.0
|
||||
pagingVersion=3.0.0
|
@ -46,10 +46,6 @@ dependencies {
|
||||
testImplementation 'org.assertj:assertj-core:3.11.1'
|
||||
testImplementation "org.mockito:mockito-inline:4.0.0"
|
||||
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
|
||||
testImplementation 'org.powermock:powermock-api-mockito:1.6.1'
|
||||
testImplementation 'org.powermock:powermock-module-junit4:1.6.1'
|
||||
testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.1'
|
||||
testImplementation 'org.powermock:powermock-classloading-xstream:1.6.1'
|
||||
testImplementation "androidx.test:core:$testCoreVersion"
|
||||
testImplementation "androidx.arch.core:core-testing:2.1.0"
|
||||
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion"
|
||||
|
Loading…
x
Reference in New Issue
Block a user