mirror of
https://github.com/oxen-io/session-android.git
synced 2025-08-11 20:37:39 +00:00
Add support for dependency injection, and accompanying tests.
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule;
|
||||
import org.whispersystems.libaxolotl.ecc.Curve;
|
||||
import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
|
||||
import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
|
||||
import org.whispersystems.textsecure.api.TextSecureAccountManager;
|
||||
import org.whispersystems.textsecure.push.SignedPreKeyEntity;
|
||||
import org.whispersystems.textsecure.push.exceptions.PushNetworkException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.ObjectGraph;
|
||||
import dagger.Provides;
|
||||
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class CleanPreKeysJobTest extends AndroidTestCase {
|
||||
|
||||
public void testSignedPreKeyRotationNotRegistered() throws IOException, MasterSecretJob.RequirementNotMetException {
|
||||
TextSecureAccountManager accountManager = mock(TextSecureAccountManager.class);
|
||||
SignedPreKeyStore signedPreKeyStore = mock(SignedPreKeyStore.class);
|
||||
MasterSecret masterSecret = mock(MasterSecret.class);
|
||||
when(accountManager.getSignedPreKey()).thenReturn(null);
|
||||
|
||||
CleanPreKeysJob cleanPreKeysJob = new CleanPreKeysJob(getContext());
|
||||
|
||||
ObjectGraph objectGraph = ObjectGraph.create(new TestModule(accountManager, signedPreKeyStore));
|
||||
objectGraph.inject(cleanPreKeysJob);
|
||||
|
||||
cleanPreKeysJob.onRun(masterSecret);
|
||||
|
||||
verify(accountManager).getSignedPreKey();
|
||||
verifyNoMoreInteractions(signedPreKeyStore);
|
||||
}
|
||||
|
||||
public void testSignedPreKeyEviction() throws Exception {
|
||||
SignedPreKeyStore signedPreKeyStore = mock(SignedPreKeyStore.class);
|
||||
TextSecureAccountManager accountManager = mock(TextSecureAccountManager.class);
|
||||
SignedPreKeyEntity currentSignedPreKeyEntity = mock(SignedPreKeyEntity.class);
|
||||
MasterSecret masterSecret = mock(MasterSecret.class);
|
||||
|
||||
when(currentSignedPreKeyEntity.getKeyId()).thenReturn(3133);
|
||||
when(accountManager.getSignedPreKey()).thenReturn(currentSignedPreKeyEntity);
|
||||
|
||||
final SignedPreKeyRecord currentRecord = new SignedPreKeyRecord(3133, System.currentTimeMillis(), Curve.generateKeyPair(), new byte[64]);
|
||||
|
||||
List<SignedPreKeyRecord> records = new LinkedList<SignedPreKeyRecord>() {{
|
||||
add(new SignedPreKeyRecord(2, 11, Curve.generateKeyPair(), new byte[32]));
|
||||
add(new SignedPreKeyRecord(4, System.currentTimeMillis() - 100, Curve.generateKeyPair(), new byte[64]));
|
||||
add(currentRecord);
|
||||
add(new SignedPreKeyRecord(3, System.currentTimeMillis() - 90, Curve.generateKeyPair(), new byte[64]));
|
||||
add(new SignedPreKeyRecord(1, 10, Curve.generateKeyPair(), new byte[32]));
|
||||
}};
|
||||
|
||||
when(signedPreKeyStore.loadSignedPreKeys()).thenReturn(records);
|
||||
when(signedPreKeyStore.loadSignedPreKey(eq(3133))).thenReturn(currentRecord);
|
||||
|
||||
CleanPreKeysJob cleanPreKeysJob = new CleanPreKeysJob(getContext());
|
||||
|
||||
ObjectGraph objectGraph = ObjectGraph.create(new TestModule(accountManager, signedPreKeyStore));
|
||||
objectGraph.inject(cleanPreKeysJob);
|
||||
|
||||
cleanPreKeysJob.onRun(masterSecret);
|
||||
|
||||
verify(signedPreKeyStore).removeSignedPreKey(eq(1));
|
||||
verify(signedPreKeyStore, times(1)).removeSignedPreKey(anyInt());
|
||||
}
|
||||
|
||||
public void testSignedPreKeyNoEviction() throws Exception {
|
||||
SignedPreKeyStore signedPreKeyStore = mock(SignedPreKeyStore.class);
|
||||
TextSecureAccountManager accountManager = mock(TextSecureAccountManager.class);
|
||||
SignedPreKeyEntity currentSignedPreKeyEntity = mock(SignedPreKeyEntity.class);
|
||||
|
||||
when(currentSignedPreKeyEntity.getKeyId()).thenReturn(3133);
|
||||
when(accountManager.getSignedPreKey()).thenReturn(currentSignedPreKeyEntity);
|
||||
|
||||
final SignedPreKeyRecord currentRecord = new SignedPreKeyRecord(3133, System.currentTimeMillis(), Curve.generateKeyPair(), new byte[64]);
|
||||
|
||||
List<SignedPreKeyRecord> records = new LinkedList<SignedPreKeyRecord>() {{
|
||||
add(currentRecord);
|
||||
}};
|
||||
|
||||
when(signedPreKeyStore.loadSignedPreKeys()).thenReturn(records);
|
||||
when(signedPreKeyStore.loadSignedPreKey(eq(3133))).thenReturn(currentRecord);
|
||||
|
||||
CleanPreKeysJob cleanPreKeysJob = new CleanPreKeysJob(getContext());
|
||||
|
||||
ObjectGraph objectGraph = ObjectGraph.create(new TestModule(accountManager, signedPreKeyStore));
|
||||
objectGraph.inject(cleanPreKeysJob);
|
||||
|
||||
verify(signedPreKeyStore, never()).removeSignedPreKey(anyInt());
|
||||
}
|
||||
|
||||
public void testConnectionError() throws Exception {
|
||||
SignedPreKeyStore signedPreKeyStore = mock(SignedPreKeyStore.class);
|
||||
TextSecureAccountManager accountManager = mock(TextSecureAccountManager.class);
|
||||
MasterSecret masterSecret = mock(MasterSecret.class);
|
||||
|
||||
when(accountManager.getSignedPreKey()).thenThrow(new PushNetworkException("Connectivity error!"));
|
||||
|
||||
CleanPreKeysJob cleanPreKeysJob = new CleanPreKeysJob(getContext());
|
||||
|
||||
ObjectGraph objectGraph = ObjectGraph.create(new TestModule(accountManager, signedPreKeyStore));
|
||||
objectGraph.inject(cleanPreKeysJob);
|
||||
|
||||
try {
|
||||
cleanPreKeysJob.onRun(masterSecret);
|
||||
throw new AssertionError("should have failed!");
|
||||
} catch (IOException e) {
|
||||
assertTrue(cleanPreKeysJob.onShouldRetry(e));
|
||||
}
|
||||
}
|
||||
|
||||
@Module(injects = {CleanPreKeysJob.class})
|
||||
public static class TestModule {
|
||||
private final TextSecureAccountManager accountManager;
|
||||
private final SignedPreKeyStore signedPreKeyStore;
|
||||
|
||||
private TestModule(TextSecureAccountManager accountManager, SignedPreKeyStore signedPreKeyStore) {
|
||||
this.accountManager = accountManager;
|
||||
this.signedPreKeyStore = signedPreKeyStore;
|
||||
}
|
||||
|
||||
@Provides TextSecureAccountManager provideTextSecureAccountManager() {
|
||||
return accountManager;
|
||||
}
|
||||
|
||||
@Provides
|
||||
AxolotlStorageModule.SignedPreKeyStoreFactory provideSignedPreKeyStore() {
|
||||
return new AxolotlStorageModule.SignedPreKeyStoreFactory() {
|
||||
@Override
|
||||
public SignedPreKeyStore create(MasterSecret masterSecret) {
|
||||
return signedPreKeyStore;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,101 @@
|
||||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.whispersystems.textsecure.api.TextSecureMessageSender;
|
||||
import org.whispersystems.textsecure.push.PushAddress;
|
||||
import org.whispersystems.textsecure.push.exceptions.NotFoundException;
|
||||
import org.whispersystems.textsecure.push.exceptions.PushNetworkException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.ObjectGraph;
|
||||
import dagger.Provides;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.thoughtcrime.securesms.dependencies.TextSecureCommunicationModule.TextSecureMessageSenderFactory;
|
||||
|
||||
public class DeliveryReceiptJobTest extends AndroidTestCase {
|
||||
|
||||
public void testDelivery() throws IOException {
|
||||
TextSecureMessageSender textSecureMessageSender = mock(TextSecureMessageSender.class);
|
||||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
DeliveryReceiptJob deliveryReceiptJob = new DeliveryReceiptJob(getContext(),
|
||||
"+14152222222",
|
||||
timestamp, "foo");
|
||||
|
||||
ObjectGraph objectGraph = ObjectGraph.create(new TestModule(textSecureMessageSender));
|
||||
objectGraph.inject(deliveryReceiptJob);
|
||||
|
||||
deliveryReceiptJob.onRun();
|
||||
|
||||
ArgumentCaptor<PushAddress> captor = ArgumentCaptor.forClass(PushAddress.class);
|
||||
verify(textSecureMessageSender).sendDeliveryReceipt(captor.capture(), eq(timestamp));
|
||||
|
||||
assertTrue(captor.getValue().getRelay().equals("foo"));
|
||||
assertTrue(captor.getValue().getNumber().equals("+14152222222"));
|
||||
}
|
||||
|
||||
public void testNetworkError() throws IOException {
|
||||
TextSecureMessageSender textSecureMessageSender = mock(TextSecureMessageSender.class);
|
||||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
Mockito.doThrow(new PushNetworkException("network error"))
|
||||
.when(textSecureMessageSender)
|
||||
.sendDeliveryReceipt(any(PushAddress.class), eq(timestamp));
|
||||
|
||||
|
||||
DeliveryReceiptJob deliveryReceiptJob = new DeliveryReceiptJob(getContext(),
|
||||
"+14152222222",
|
||||
timestamp, "foo");
|
||||
|
||||
ObjectGraph objectGraph = ObjectGraph.create(new TestModule(textSecureMessageSender));
|
||||
objectGraph.inject(deliveryReceiptJob);
|
||||
|
||||
try {
|
||||
deliveryReceiptJob.onRun();
|
||||
throw new AssertionError();
|
||||
} catch (IOException e) {
|
||||
assertTrue(deliveryReceiptJob.onShouldRetry(e));
|
||||
}
|
||||
|
||||
Mockito.doThrow(new NotFoundException("not found"))
|
||||
.when(textSecureMessageSender)
|
||||
.sendDeliveryReceipt(any(PushAddress.class), eq(timestamp));
|
||||
|
||||
try {
|
||||
deliveryReceiptJob.onRun();
|
||||
throw new AssertionError();
|
||||
} catch (IOException e) {
|
||||
assertFalse(deliveryReceiptJob.onShouldRetry(e));
|
||||
}
|
||||
}
|
||||
|
||||
@Module(injects = DeliveryReceiptJob.class)
|
||||
public static class TestModule {
|
||||
|
||||
private final TextSecureMessageSender textSecureMessageSender;
|
||||
|
||||
public TestModule(TextSecureMessageSender textSecureMessageSender) {
|
||||
this.textSecureMessageSender = textSecureMessageSender;
|
||||
}
|
||||
|
||||
@Provides TextSecureMessageSenderFactory provideTextSecureMessageSenderFactory() {
|
||||
return new TextSecureMessageSenderFactory() {
|
||||
@Override
|
||||
public TextSecureMessageSender create(MasterSecret masterSecret) {
|
||||
return textSecureMessageSender;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,92 +0,0 @@
|
||||
package org.thoughtcrime.securesms.service;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
import org.whispersystems.libaxolotl.ecc.Curve;
|
||||
import org.whispersystems.libaxolotl.state.SignedPreKeyRecord;
|
||||
import org.whispersystems.libaxolotl.state.SignedPreKeyStore;
|
||||
import org.whispersystems.textsecure.push.PushServiceSocket;
|
||||
import org.whispersystems.textsecure.push.SignedPreKeyEntity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class PreKeyServiceTest extends AndroidTestCase {
|
||||
|
||||
public void testSignedPreKeyRotationNotRegistered() throws IOException {
|
||||
SignedPreKeyStore signedPreKeyStore = mock(SignedPreKeyStore.class);
|
||||
PushServiceSocket pushServiceSocket = mock(PushServiceSocket.class);
|
||||
|
||||
when(pushServiceSocket.getCurrentSignedPreKey()).thenReturn(null);
|
||||
|
||||
PreKeyService.CleanSignedPreKeysTask cleanTask = new PreKeyService.CleanSignedPreKeysTask(signedPreKeyStore,
|
||||
pushServiceSocket);
|
||||
|
||||
cleanTask.run();
|
||||
|
||||
verify(pushServiceSocket).getCurrentSignedPreKey();
|
||||
verifyNoMoreInteractions(signedPreKeyStore);
|
||||
}
|
||||
|
||||
public void testSignedPreKeyEviction() throws Exception {
|
||||
SignedPreKeyStore signedPreKeyStore = mock(SignedPreKeyStore.class);
|
||||
PushServiceSocket pushServiceSocket = mock(PushServiceSocket.class);
|
||||
SignedPreKeyEntity currentSignedPreKeyEntity = mock(SignedPreKeyEntity.class);
|
||||
|
||||
when(currentSignedPreKeyEntity.getKeyId()).thenReturn(3133);
|
||||
when(pushServiceSocket.getCurrentSignedPreKey()).thenReturn(currentSignedPreKeyEntity);
|
||||
|
||||
final SignedPreKeyRecord currentRecord = new SignedPreKeyRecord(3133, System.currentTimeMillis(), Curve.generateKeyPair(true), new byte[64]);
|
||||
|
||||
List<SignedPreKeyRecord> records = new LinkedList<SignedPreKeyRecord>() {{
|
||||
add(new SignedPreKeyRecord(1, 10, Curve.generateKeyPair(true), new byte[32]));
|
||||
add(new SignedPreKeyRecord(2, 11, Curve.generateKeyPair(true), new byte[32]));
|
||||
add(new SignedPreKeyRecord(3, System.currentTimeMillis() - 90, Curve.generateKeyPair(true), new byte[64]));
|
||||
add(new SignedPreKeyRecord(4, System.currentTimeMillis() - 100, Curve.generateKeyPair(true), new byte[64]));
|
||||
add(currentRecord);
|
||||
}};
|
||||
|
||||
when(signedPreKeyStore.loadSignedPreKeys()).thenReturn(records);
|
||||
when(signedPreKeyStore.loadSignedPreKey(eq(3133))).thenReturn(currentRecord);
|
||||
|
||||
PreKeyService.CleanSignedPreKeysTask cleanTask = new PreKeyService.CleanSignedPreKeysTask(signedPreKeyStore, pushServiceSocket);
|
||||
cleanTask.run();
|
||||
|
||||
verify(signedPreKeyStore).removeSignedPreKey(eq(1));
|
||||
verify(signedPreKeyStore).removeSignedPreKey(eq(2));
|
||||
verify(signedPreKeyStore, times(2)).removeSignedPreKey(anyInt());
|
||||
}
|
||||
|
||||
public void testSignedPreKeyNoEviction() throws Exception {
|
||||
SignedPreKeyStore signedPreKeyStore = mock(SignedPreKeyStore.class);
|
||||
PushServiceSocket pushServiceSocket = mock(PushServiceSocket.class);
|
||||
SignedPreKeyEntity currentSignedPreKeyEntity = mock(SignedPreKeyEntity.class);
|
||||
|
||||
when(currentSignedPreKeyEntity.getKeyId()).thenReturn(3133);
|
||||
when(pushServiceSocket.getCurrentSignedPreKey()).thenReturn(currentSignedPreKeyEntity);
|
||||
|
||||
final SignedPreKeyRecord currentRecord = new SignedPreKeyRecord(3133, System.currentTimeMillis(), Curve.generateKeyPair(true), new byte[64]);
|
||||
|
||||
List<SignedPreKeyRecord> records = new LinkedList<SignedPreKeyRecord>() {{
|
||||
add(currentRecord);
|
||||
}};
|
||||
|
||||
when(signedPreKeyStore.loadSignedPreKeys()).thenReturn(records);
|
||||
when(signedPreKeyStore.loadSignedPreKey(eq(3133))).thenReturn(currentRecord);
|
||||
|
||||
PreKeyService.CleanSignedPreKeysTask cleanTask = new PreKeyService.CleanSignedPreKeysTask(signedPreKeyStore, pushServiceSocket);
|
||||
cleanTask.run();
|
||||
|
||||
verify(signedPreKeyStore, never()).removeSignedPreKey(anyInt());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user