Use Dagger Hilt for dependency injection

This gets rid of our own janky dependency injection through the AegisApplication class
This commit is contained in:
Alexander Bakker 2022-02-06 19:00:01 +01:00
parent 927f5f2bd5
commit 71f2b54deb
42 changed files with 1157 additions and 977 deletions

View file

@ -9,15 +9,17 @@ import androidx.test.platform.app.InstrumentationRegistry;
import com.beemdevelopment.aegis.crypto.CryptoUtils;
import com.beemdevelopment.aegis.crypto.SCryptParameters;
import com.beemdevelopment.aegis.otp.OtpInfo;
import com.beemdevelopment.aegis.vault.Vault;
import com.beemdevelopment.aegis.vault.VaultEntry;
import com.beemdevelopment.aegis.vault.VaultFileCredentials;
import com.beemdevelopment.aegis.vault.VaultManager;
import com.beemdevelopment.aegis.vault.VaultManagerException;
import com.beemdevelopment.aegis.vault.VaultRepository;
import com.beemdevelopment.aegis.vault.VaultRepositoryException;
import com.beemdevelopment.aegis.vault.slots.PasswordSlot;
import com.beemdevelopment.aegis.vault.slots.SlotException;
import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Rule;
import java.lang.reflect.InvocationTargetException;
import java.security.InvalidAlgorithmParameterException;
@ -26,28 +28,41 @@ import java.security.NoSuchAlgorithmException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.inject.Inject;
import dagger.hilt.android.testing.HiltAndroidRule;
public abstract class AegisTest {
public static final String VAULT_PASSWORD = "test";
protected AegisApplication getApp() {
return (AegisApplication) InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext();
@Rule
public HiltAndroidRule hiltRule = new HiltAndroidRule(this);
@Inject
protected VaultManager _vaultManager;
@Inject
protected Preferences _prefs;
@Before
public void init() {
hiltRule.inject();
}
protected VaultManager getVault() {
return getApp().getVaultManager();
protected AegisApplicationBase getApp() {
return (AegisApplicationBase) InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext();
}
protected VaultManager initVault() {
protected VaultRepository initVault() {
VaultFileCredentials creds = generateCredentials();
VaultManager vault = getApp().initVaultManager(new Vault(), creds);
VaultRepository vault;
try {
vault.save(false);
} catch (VaultManagerException e) {
vault = _vaultManager.init(creds);
} catch (VaultRepositoryException e) {
throw new RuntimeException(e);
}
getApp().getPreferences().setIntroDone(true);
_prefs.setIntroDone(true);
return vault;
}

View file

@ -0,0 +1,7 @@
package com.beemdevelopment.aegis;
import dagger.hilt.android.testing.CustomTestApplication;
@CustomTestApplication(AegisApplicationBase.class)
public interface AegisTestApplication {
}

View file

@ -1,6 +1,7 @@
package com.beemdevelopment.aegis;
import android.app.Application;
import android.app.Instrumentation;
import android.content.Context;
import android.preference.PreferenceManager;
@ -14,6 +15,12 @@ public class AegisTestRunner extends AndroidJUnitRunner {
BuildConfig.TEST.set(true);
}
@Override
public Application newApplication(ClassLoader cl, String name, Context context)
throws ClassNotFoundException, IllegalAccessException, InstantiationException {
return Instrumentation.newApplication(AegisTestApplication_Application.class, context);
}
@Override
public void callApplicationOnCreate(Application app) {
Context context = app.getApplicationContext();

View file

@ -21,7 +21,10 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import dagger.hilt.android.testing.HiltAndroidTest;
@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
@LargeTest
public class DeepLinkTest extends AegisTest {
@Before
@ -37,7 +40,7 @@ public class DeepLinkTest extends AegisTest {
onView(withId(R.id.action_save)).perform(click());
VaultEntry createdEntry = (VaultEntry) getVault().getEntries().toArray()[0];
VaultEntry createdEntry = (VaultEntry) _vaultManager.getVault().getEntries().toArray()[0];
assertTrue(createdEntry.equivalates(entry));
}

View file

@ -1,20 +1,5 @@
package com.beemdevelopment.aegis;
import androidx.test.espresso.ViewInteraction;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import com.beemdevelopment.aegis.ui.IntroActivity;
import com.beemdevelopment.aegis.vault.VaultManager;
import com.beemdevelopment.aegis.vault.slots.BiometricSlot;
import com.beemdevelopment.aegis.vault.slots.PasswordSlot;
import com.beemdevelopment.aegis.vault.slots.SlotList;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
@ -28,7 +13,25 @@ import static junit.framework.TestCase.assertNull;
import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.Matchers.not;
import androidx.test.espresso.ViewInteraction;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import com.beemdevelopment.aegis.ui.IntroActivity;
import com.beemdevelopment.aegis.vault.VaultRepository;
import com.beemdevelopment.aegis.vault.slots.BiometricSlot;
import com.beemdevelopment.aegis.vault.slots.PasswordSlot;
import com.beemdevelopment.aegis.vault.slots.SlotList;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import dagger.hilt.android.testing.HiltAndroidTest;
@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
@LargeTest
public class IntroTest extends AegisTest {
@Rule
@ -50,9 +53,9 @@ public class IntroTest extends AegisTest {
next.perform(click());
next.perform(click());
VaultManager vault = getVault();
VaultRepository vault = _vaultManager.getVault();
assertFalse(vault.isEncryptionEnabled());
assertNull(getVault().getCredentials());
assertNull(vault.getCredentials());
}
@Test
@ -79,8 +82,8 @@ public class IntroTest extends AegisTest {
next.perform(click());
next.perform(click());
VaultManager vault = getVault();
SlotList slots = getVault().getCredentials().getSlots();
VaultRepository vault = _vaultManager.getVault();
SlotList slots = vault.getCredentials().getSlots();
assertTrue(vault.isEncryptionEnabled());
assertTrue(slots.has(PasswordSlot.class));
assertFalse(slots.has(BiometricSlot.class));

View file

@ -31,7 +31,7 @@ import com.beemdevelopment.aegis.otp.TotpInfo;
import com.beemdevelopment.aegis.otp.YandexInfo;
import com.beemdevelopment.aegis.ui.MainActivity;
import com.beemdevelopment.aegis.vault.VaultEntry;
import com.beemdevelopment.aegis.vault.VaultManager;
import com.beemdevelopment.aegis.vault.VaultRepository;
import com.beemdevelopment.aegis.vault.slots.PasswordSlot;
import org.junit.Rule;
@ -42,7 +42,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import dagger.hilt.android.testing.HiltAndroidTest;
@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
@LargeTest
public class OverallTest extends AegisTest {
private static final String _groupName = "Test";
@ -61,7 +64,7 @@ public class OverallTest extends AegisTest {
next.perform(click());
onView(withId(R.id.btnNext)).perform(click());
VaultManager vault = getVault();
VaultRepository vault = _vaultManager.getVault();
assertTrue(vault.isEncryptionEnabled());
assertTrue(vault.getCredentials().getSlots().has(PasswordSlot.class));
@ -122,7 +125,7 @@ public class OverallTest extends AegisTest {
onView(withText(R.string.lock)).perform(click());
onView(withId(R.id.text_password)).perform(typeText(VAULT_PASSWORD), closeSoftKeyboard());
onView(withId(R.id.button_decrypt)).perform(click());
vault = getVault();
vault = _vaultManager.getVault();
openContextualActionModeOverflowMenu();
onView(withText(R.string.action_settings)).perform(click());

View file

@ -1,25 +1,28 @@
package com.beemdevelopment.aegis;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import android.content.Intent;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.filters.SmallTest;
import androidx.test.rule.ActivityTestRule;
import com.beemdevelopment.aegis.ui.PanicResponderActivity;
import com.beemdevelopment.aegis.vault.VaultManager;
import com.beemdevelopment.aegis.vault.VaultRepository;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import dagger.hilt.android.testing.HiltAndroidTest;
@RunWith(AndroidJUnit4.class)
@LargeTest
@HiltAndroidTest
@SmallTest
public class PanicTriggerTest extends AegisTest {
@Before
public void before() {
@ -28,21 +31,25 @@ public class PanicTriggerTest extends AegisTest {
@Test
public void testPanicTriggerDisabled() {
assertFalse(getApp().getPreferences().isPanicTriggerEnabled());
assertFalse(_prefs.isPanicTriggerEnabled());
launchPanic();
assertFalse(getApp().isVaultLocked());
assertNotNull(getApp().getVaultManager());
assertTrue(VaultManager.fileExists(getApp()));
assertTrue(_vaultManager.isVaultLoaded());
_vaultManager.getVault();
assertFalse(_vaultManager.isVaultFileLoaded());
assertNull(_vaultManager.getVaultFileError());
assertTrue(VaultRepository.fileExists(getApp()));
}
@Test
public void testPanicTriggerEnabled() {
getApp().getPreferences().setIsPanicTriggerEnabled(true);
assertTrue(getApp().getPreferences().isPanicTriggerEnabled());
_prefs.setIsPanicTriggerEnabled(true);
assertTrue(_prefs.isPanicTriggerEnabled());
launchPanic();
assertTrue(getApp().isVaultLocked());
assertNull(getApp().getVaultManager());
assertFalse(VaultManager.fileExists(getApp()));
assertFalse(_vaultManager.isVaultLoaded());
assertThrows(IllegalStateException.class, () -> _vaultManager.getVault());
assertFalse(_vaultManager.isVaultFileLoaded());
assertNull(_vaultManager.getVaultFileError());
assertFalse(VaultRepository.fileExists(getApp()));
}
private void launchPanic() {

View file

@ -1,5 +1,11 @@
package com.beemdevelopment.aegis.vault;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
@ -10,30 +16,28 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import dagger.hilt.android.testing.HiltAndroidTest;
@RunWith(AndroidJUnit4.class)
@HiltAndroidTest
@SmallTest
public class VaultManagerTest extends AegisTest {
public class VaultRepositoryTest extends AegisTest {
@Before
public void before() {
initVault();
}
@Test
public void testToggleEncryption() throws VaultManagerException {
getVault().disableEncryption();
assertFalse(getVault().isEncryptionEnabled());
assertNull(getVault().getCredentials());
public void testToggleEncryption() throws VaultRepositoryException {
VaultRepository vault = _vaultManager.getVault();
_vaultManager.disableEncryption();
assertFalse(vault.isEncryptionEnabled());
assertNull(vault.getCredentials());
VaultFileCredentials creds = generateCredentials();
getVault().enableEncryption(creds);
assertTrue(getVault().isEncryptionEnabled());
assertNotNull(getVault().getCredentials());
assertEquals(getVault().getCredentials().getSlots().findAll(PasswordSlot.class).size(), 1);
_vaultManager.enableEncryption(creds);
assertTrue(vault.isEncryptionEnabled());
assertNotNull(vault.getCredentials());
assertEquals(vault.getCredentials().getSlots().findAll(PasswordSlot.class).size(), 1);
}
}