diff --git a/k9mail/src/main/java/com/fsck/k9/preferences/SettingsImporter.java b/k9mail/src/main/java/com/fsck/k9/preferences/SettingsImporter.java index 0b825578b..031b5041d 100644 --- a/k9mail/src/main/java/com/fsck/k9/preferences/SettingsImporter.java +++ b/k9mail/src/main/java/com/fsck/k9/preferences/SettingsImporter.java @@ -16,6 +16,7 @@ import org.xmlpull.v1.XmlPullParserFactory; import android.content.Context; import android.content.SharedPreferences; +import android.support.annotation.VisibleForTesting; import android.util.Log; import com.fsck.k9.Account; @@ -661,8 +662,9 @@ public class SettingsImporter { editor.putString(key, value); } - private static Imported parseSettings(InputStream inputStream, boolean globalSettings, - List accountUuids, boolean overview) + @VisibleForTesting + static Imported parseSettings(InputStream inputStream, boolean globalSettings, + List accountUuids, boolean overview) throws SettingsImportExportException { if (!overview && accountUuids == null) { @@ -1138,7 +1140,8 @@ public class SettingsImporter { } } - private static class Imported { + @VisibleForTesting + static class Imported { public int contentVersion; public ImportedSettings globalSettings; public Map accounts; @@ -1148,7 +1151,8 @@ public class SettingsImporter { public Map settings = new HashMap(); } - private static class ImportedAccount { + @VisibleForTesting + static class ImportedAccount { public String uuid; public String name; public ImportedServer incoming; @@ -1158,7 +1162,8 @@ public class SettingsImporter { public List folders; } - private static class ImportedServer { + @VisibleForTesting + static class ImportedServer { public String type; public String host; public String port; @@ -1170,7 +1175,8 @@ public class SettingsImporter { public ImportedSettings extras; } - private static class ImportedIdentity { + @VisibleForTesting + static class ImportedIdentity { public String name; public String email; public String description; diff --git a/k9mail/src/test/java/com/fsck/k9/preferences/SettingsExporterTest.java b/k9mail/src/test/java/com/fsck/k9/preferences/SettingsExporterTest.java new file mode 100644 index 000000000..3451d42d4 --- /dev/null +++ b/k9mail/src/test/java/com/fsck/k9/preferences/SettingsExporterTest.java @@ -0,0 +1,74 @@ +package com.fsck.k9.preferences; + +import org.jdom2.Document; +import org.jdom2.input.SAXBuilder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.Collections; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +@RunWith(RobolectricTestRunner.class) +@Config(manifest = "src/main/AndroidManifest.xml", sdk = 21) +public class SettingsExporterTest { + + @Test + public void exportPreferences_producesXML() throws Exception { + Document document = exportPreferences(false, Collections.emptySet()); + + assertEquals("k9settings", document.getRootElement().getName()); + } + + @Test + public void exportPreferences_setsVersionTo43() throws Exception { + Document document = exportPreferences(false, Collections.emptySet()); + + assertEquals("43", document.getRootElement().getAttributeValue("version")); + } + + @Test + public void exportPreferences_setsFormatTo1() throws Exception { + Document document = exportPreferences(false, Collections.emptySet()); + + assertEquals("1", document.getRootElement().getAttributeValue("format")); + } + + @Test + public void exportPreferences_exportsGlobalSettingsWhenRequested() throws Exception { + Document document = exportPreferences(true, Collections.emptySet()); + + assertNotNull(document.getRootElement().getChild("global")); + } + + @Test + public void exportPreferences_ignoresGlobalSettingsWhenRequested() throws Exception { + Document document = exportPreferences(false, Collections.emptySet()); + + assertNull(document.getRootElement().getChild("global")); + } + + private Document exportPreferences(boolean globalSettings, Set accounts) throws Exception { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + SettingsExporter.exportPreferences(RuntimeEnvironment.application, outputStream, + globalSettings, accounts); + Document document = parseXML(outputStream.toByteArray()); + outputStream.close(); + return document; + } + + private Document parseXML(byte[] xml) throws Exception { + SAXBuilder builder = new SAXBuilder(); + InputStream stream = new ByteArrayInputStream(xml); + return builder.build(stream); + } +} diff --git a/k9mail/src/test/java/com/fsck/k9/preferences/SettingsImporterTest.java b/k9mail/src/test/java/com/fsck/k9/preferences/SettingsImporterTest.java new file mode 100644 index 000000000..c22f92dd9 --- /dev/null +++ b/k9mail/src/test/java/com/fsck/k9/preferences/SettingsImporterTest.java @@ -0,0 +1,167 @@ +package com.fsck.k9.preferences; + +import com.fsck.k9.Account; +import com.fsck.k9.Preferences; +import com.fsck.k9.mail.AuthType; + +import org.apache.tools.ant.filters.StringInputStream; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +@SuppressWarnings("unchecked") +@RunWith(RobolectricTestRunner.class) +@Config(manifest = "src/main/AndroidManifest.xml", sdk = 21) +public class SettingsImporterTest { + + @Before + public void before() { + deletePreExistingAccounts(); + } + + private void deletePreExistingAccounts() { + Preferences preferences = Preferences.getPreferences(RuntimeEnvironment.application); + Collection availableAccounts = + preferences.getAvailableAccounts(); + for(Account account: availableAccounts) { + preferences.deleteAccount(account); + } + } + + @Test(expected = SettingsImportExportException.class) + public void importSettings_throwsExceptionOnBlankFile() throws SettingsImportExportException { + InputStream inputStream = new StringInputStream(""); + List accountUuids = new ArrayList<>(); + + SettingsImporter.importSettings(RuntimeEnvironment.application, inputStream, true, accountUuids, true); + } + + @Test(expected = SettingsImportExportException.class) + public void importSettings_throwsExceptionOnMissingFormat() throws SettingsImportExportException { + InputStream inputStream = new StringInputStream(""); + List accountUuids = new ArrayList<>(); + + SettingsImporter.importSettings(RuntimeEnvironment.application, inputStream, true, accountUuids, true); + } + + @Test(expected = SettingsImportExportException.class) + public void importSettings_throwsExceptionOnInvalidFormat() throws SettingsImportExportException { + InputStream inputStream = new StringInputStream(""); + List accountUuids = new ArrayList<>(); + + SettingsImporter.importSettings(RuntimeEnvironment.application, inputStream, true, accountUuids, true); + } + + @Test(expected = SettingsImportExportException.class) + public void importSettings_throwsExceptionOnNonPositiveFormat() throws SettingsImportExportException { + InputStream inputStream = new StringInputStream(""); + List accountUuids = new ArrayList<>(); + + SettingsImporter.importSettings(RuntimeEnvironment.application, inputStream, true, accountUuids, true); + } + + @Test(expected = SettingsImportExportException.class) + public void importSettings_throwsExceptionOnMissingVersion() throws SettingsImportExportException { + InputStream inputStream = new StringInputStream(""); + List accountUuids = new ArrayList<>(); + + SettingsImporter.importSettings(RuntimeEnvironment.application, inputStream, true, accountUuids, true); + } + + @Test(expected = SettingsImportExportException.class) + public void importSettings_throwsExceptionOnInvalidVersion() throws SettingsImportExportException { + InputStream inputStream = new StringInputStream(""); + List accountUuids = new ArrayList<>(); + + SettingsImporter.importSettings(RuntimeEnvironment.application, inputStream, true, accountUuids, true); + } + + @Test(expected = SettingsImportExportException.class) + public void importSettings_throwsExceptionOnNonPositiveVersion() throws SettingsImportExportException { + InputStream inputStream = new StringInputStream(""); + List accountUuids = new ArrayList<>(); + + SettingsImporter.importSettings(RuntimeEnvironment.application, inputStream, true, accountUuids, true); + } + + @Test + public void parseSettings_account() throws SettingsImportExportException { + String validUUID = UUID.randomUUID().toString(); + InputStream inputStream = new StringInputStream("" + + "Account"); + List accountUuids = new ArrayList<>(); + accountUuids.add("1"); + + SettingsImporter.Imported results = SettingsImporter.parseSettings(inputStream, true, accountUuids, true); + + assertEquals(1, results.accounts.size()); + assertEquals("Account", results.accounts.get(validUUID).name); + assertEquals(validUUID, results.accounts.get(validUUID).uuid); + } + + @Test + public void parseSettings_account_cram_md5() throws SettingsImportExportException { + + String validUUID = UUID.randomUUID().toString(); + InputStream inputStream = new StringInputStream("" + + "Account" + + "CRAM_MD5" + + ""); + List accountUuids = new ArrayList<>(); + accountUuids.add(validUUID); + + SettingsImporter.Imported results = SettingsImporter.parseSettings(inputStream, true, accountUuids, false); + + assertEquals("Account", results.accounts.get(validUUID).name); + assertEquals(validUUID, results.accounts.get(validUUID).uuid); + assertEquals(AuthType.CRAM_MD5, results.accounts.get(validUUID).incoming.authenticationType); + } + + @Test + public void importSettings_disablesAccountsNeedingPasswords() throws SettingsImportExportException { + String validUUID = UUID.randomUUID().toString(); + InputStream inputStream = new StringInputStream("" + + "Account" + + "" + + "SSL_TLS_REQUIRED" + + "user@gmail.com" + + "CRAM_MD5" + + "googlemail.com" + + "" + + "" + + "SSL_TLS_REQUIRED" + + "user@googlemail.com" + + "CRAM_MD5" + + "googlemail.com" + + "" + + "b" + + "user@gmail.com" + + ""); + List accountUuids = new ArrayList<>(); + accountUuids.add(validUUID); + + SettingsImporter.ImportResults results = SettingsImporter.importSettings( + RuntimeEnvironment.application, inputStream, true, accountUuids, false); + + assertEquals(0, results.errorneousAccounts.size()); + assertEquals(1, results.importedAccounts.size()); + assertEquals("Account", results.importedAccounts.get(0).imported.name); + assertEquals(validUUID, results.importedAccounts.get(0).imported.uuid); + + assertFalse(Preferences.getPreferences(RuntimeEnvironment.application) + .getAccount(validUUID).isEnabled()); + } + +}