mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-27 11:42:16 -05:00
Merge branch 'master' into pgp_mime_preparations
Conflicts: k9mail/src/androidTest/java/com/fsck/k9/mailstore/LocalMessageTest.java
This commit is contained in:
commit
23c9398c03
@ -20,11 +20,12 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 17
|
targetSdkVersion 21
|
||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
abortOnError false
|
abortOnError true
|
||||||
|
warningsAsErrors true
|
||||||
lintConfig file("$rootProject.projectDir/config/lint/lint.xml")
|
lintConfig file("$rootProject.projectDir/config/lint/lint.xml")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,14 +555,14 @@ class ImapConnection {
|
|||||||
private static Socket connect(ImapSettings settings, TrustedSocketFactory socketFactory)
|
private static Socket connect(ImapSettings settings, TrustedSocketFactory socketFactory)
|
||||||
throws GeneralSecurityException, MessagingException, IOException {
|
throws GeneralSecurityException, MessagingException, IOException {
|
||||||
// Try all IPv4 and IPv6 addresses of the host
|
// Try all IPv4 and IPv6 addresses of the host
|
||||||
InetAddress[] addresses = InetAddress.getAllByName(settings.getHost());
|
Exception connectException = null;
|
||||||
for (int i = 0; i < addresses.length; i++) {
|
for (InetAddress address : InetAddress.getAllByName(settings.getHost())) {
|
||||||
try {
|
try {
|
||||||
if (K9MailLib.isDebug() && DEBUG_PROTOCOL_IMAP) {
|
if (K9MailLib.isDebug() && DEBUG_PROTOCOL_IMAP) {
|
||||||
Log.d(LOG_TAG, "Connecting to " + settings.getHost() + " as " + addresses[i]);
|
Log.d(LOG_TAG, "Connecting to " + settings.getHost() + " as " + address);
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketAddress socketAddress = new InetSocketAddress(addresses[i], settings.getPort());
|
SocketAddress socketAddress = new InetSocketAddress(address, settings.getPort());
|
||||||
Socket socket;
|
Socket socket;
|
||||||
if (settings.getConnectionSecurity() == ConnectionSecurity.SSL_TLS_REQUIRED) {
|
if (settings.getConnectionSecurity() == ConnectionSecurity.SSL_TLS_REQUIRED) {
|
||||||
socket = socketFactory.createSocket(
|
socket = socketFactory.createSocket(
|
||||||
@ -576,15 +576,12 @@ class ImapConnection {
|
|||||||
socket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);
|
socket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);
|
||||||
// Successfully connected to the server; don't try any other addresses
|
// Successfully connected to the server; don't try any other addresses
|
||||||
return socket;
|
return socket;
|
||||||
} catch (SocketException e) {
|
} catch (IOException e) {
|
||||||
if (i < (addresses.length - 1)) {
|
Log.w(LOG_TAG, "could not connect to "+address, e);
|
||||||
// There are still other addresses for that host to try
|
connectException = e;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
throw new MessagingException("Cannot connect to host", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new MessagingException("Cannot connect to host");
|
throw new MessagingException("Cannot connect to host", connectException);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void adjustDNSCacheTTL() {
|
private void adjustDNSCacheTTL() {
|
||||||
@ -601,10 +598,18 @@ class ImapConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<ImapResponse> receiveCapabilities(List<ImapResponse> responses) {
|
private List<ImapResponse> receiveCapabilities(List<ImapResponse> responses) {
|
||||||
capabilities = ImapResponseParser.parseCapabilities(responses);
|
Set<String> receivedCapabilities = ImapResponseParser.parseCapabilities(responses);
|
||||||
|
/* RFC 3501 6.2.3
|
||||||
|
A server MAY include a CAPABILITY response code in the tagged OK
|
||||||
|
response to a successful LOGIN command in order to send
|
||||||
|
capabilities automatically. It is unnecessary for a client to
|
||||||
|
send a separate CAPABILITY command if it recognizes these
|
||||||
|
automatic capabilities.
|
||||||
|
*/
|
||||||
if (K9MailLib.isDebug()) {
|
if (K9MailLib.isDebug()) {
|
||||||
Log.d(LOG_TAG, "Saving " + capabilities + " capabilities for " + getLogId());
|
Log.d(LOG_TAG, "Saving " + receivedCapabilities + " capabilities for " + getLogId());
|
||||||
}
|
}
|
||||||
|
capabilities.addAll(receivedCapabilities);
|
||||||
return responses;
|
return responses;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
package com.fsck.k9.mail.store.pop3;
|
package com.fsck.k9.mail.store.pop3;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.fsck.k9.mail.*;
|
import com.fsck.k9.mail.*;
|
||||||
@ -278,6 +279,7 @@ public class Pop3Store extends RemoteStore {
|
|||||||
private InputStream mIn;
|
private InputStream mIn;
|
||||||
private OutputStream mOut;
|
private OutputStream mOut;
|
||||||
private Map<String, Pop3Message> mUidToMsgMap = new HashMap<String, Pop3Message>();
|
private Map<String, Pop3Message> mUidToMsgMap = new HashMap<String, Pop3Message>();
|
||||||
|
@SuppressLint("UseSparseArrays")
|
||||||
private Map<Integer, Pop3Message> mMsgNumToMsgMap = new HashMap<Integer, Pop3Message>();
|
private Map<Integer, Pop3Message> mMsgNumToMsgMap = new HashMap<Integer, Pop3Message>();
|
||||||
private Map<String, Integer> mUidToMsgNumMap = new HashMap<String, Integer>();
|
private Map<String, Integer> mUidToMsgNumMap = new HashMap<String, Integer>();
|
||||||
private String mName;
|
private String mName;
|
||||||
|
@ -9,10 +9,8 @@ import com.fsck.k9.mail.ssl.TrustManagerFactory;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLSocket;
|
import javax.net.ssl.SSLSocket;
|
||||||
@ -32,7 +30,7 @@ public class WebDavSocketFactory implements LayeredSocketFactory {
|
|||||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
sslContext.init(null, new TrustManager[] {
|
sslContext.init(null, new TrustManager[] {
|
||||||
TrustManagerFactory.get(host, port)
|
TrustManagerFactory.get(host, port)
|
||||||
}, new SecureRandom());
|
}, null);
|
||||||
mSocketFactory = sslContext.getSocketFactory();
|
mSocketFactory = sslContext.getSocketFactory();
|
||||||
mSchemeSocketFactory = org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory();
|
mSchemeSocketFactory = org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory();
|
||||||
mSchemeSocketFactory.setHostnameVerifier(
|
mSchemeSocketFactory.setHostnameVerifier(
|
||||||
@ -41,7 +39,7 @@ public class WebDavSocketFactory implements LayeredSocketFactory {
|
|||||||
|
|
||||||
public Socket connectSocket(Socket sock, String host, int port,
|
public Socket connectSocket(Socket sock, String host, int port,
|
||||||
InetAddress localAddress, int localPort, HttpParams params)
|
InetAddress localAddress, int localPort, HttpParams params)
|
||||||
throws IOException, UnknownHostException, ConnectTimeoutException {
|
throws IOException, ConnectTimeoutException {
|
||||||
return mSchemeSocketFactory.connectSocket(sock, host, port, localAddress, localPort, params);
|
return mSchemeSocketFactory.connectSocket(sock, host, port, localAddress, localPort, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +55,7 @@ public class WebDavSocketFactory implements LayeredSocketFactory {
|
|||||||
final String host,
|
final String host,
|
||||||
final int port,
|
final int port,
|
||||||
final boolean autoClose
|
final boolean autoClose
|
||||||
) throws IOException, UnknownHostException {
|
) throws IOException {
|
||||||
SSLSocket sslSocket = (SSLSocket) mSocketFactory.createSocket(
|
SSLSocket sslSocket = (SSLSocket) mSocketFactory.createSocket(
|
||||||
socket,
|
socket,
|
||||||
host,
|
host,
|
||||||
|
@ -5,6 +5,9 @@ apply from: '../gradle/plugins/findbugs-android.gradle'
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
|
maven {
|
||||||
|
url "https://oss.sonatype.org/content/repositories/snapshots/"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -21,16 +24,10 @@ dependencies {
|
|||||||
|
|
||||||
androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
|
androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
|
||||||
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
|
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
|
||||||
|
androidTestCompile('com.icegreen:greenmail:1.4.1-SNAPSHOT') {
|
||||||
androidTestCompile("com.icegreen:greenmail:1.3.1b") {
|
exclude group: 'junit'
|
||||||
// Use a better, later version
|
|
||||||
exclude group: "javax.mail"
|
|
||||||
}
|
}
|
||||||
|
androidTestCompile 'com.madgag.spongycastle:pg:1.51.0.0'
|
||||||
// this version avoids some "Ignoring InnerClasses attribute for an anonymous inner class" warnings
|
|
||||||
androidTestCompile "javax.mail:javax.mail-api:1.5.2"
|
|
||||||
|
|
||||||
androidTestCompile "com.madgag.spongycastle:pg:1.51.0.0"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
package com.fsck.k9.activity;
|
|
||||||
|
|
||||||
import android.test.ActivityInstrumentationTestCase2;
|
|
||||||
import com.fsck.k9.activity.Accounts;
|
|
||||||
/**
|
|
||||||
* This is a simple framework for a test of an Application. See
|
|
||||||
* {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on
|
|
||||||
* how to write and extend Application tests.
|
|
||||||
* <p/>
|
|
||||||
* To run this test, you can type:
|
|
||||||
* adb shell am instrument -w \
|
|
||||||
* -e class com.fsck.k9.activity.AccountsTest \
|
|
||||||
* com.fsck.k9.tests/android.test.InstrumentationTestRunner
|
|
||||||
*/
|
|
||||||
public class AccountsTest extends ActivityInstrumentationTestCase2<Accounts> {
|
|
||||||
|
|
||||||
public AccountsTest() {
|
|
||||||
super("com.fsck.k9", Accounts.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,14 +1,23 @@
|
|||||||
package com.fsck.k9.activity;
|
package com.fsck.k9.activity;
|
||||||
|
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
import com.fsck.k9.mail.Flag;
|
import com.fsck.k9.mail.Flag;
|
||||||
import com.fsck.k9.mail.MessagingException;
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import junit.framework.TestCase;
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
public class MessageReferenceTest extends TestCase
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static junit.framework.Assert.assertNotNull;
|
||||||
|
import static junit.framework.Assert.assertNull;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class MessageReferenceTest
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Typically happens during forwards. (You have a reference, but no flag since we don't currently consider FORWARDED a flag.)
|
* Typically happens during forwards. (You have a reference, but no flag since we don't currently consider FORWARDED a flag.)
|
||||||
*/
|
*/
|
||||||
|
@Test
|
||||||
public void testIdentityStringNoFlag()
|
public void testIdentityStringNoFlag()
|
||||||
{
|
{
|
||||||
MessageReference mr = new MessageReference();
|
MessageReference mr = new MessageReference();
|
||||||
@ -22,6 +31,7 @@ public class MessageReferenceTest extends TestCase
|
|||||||
/**
|
/**
|
||||||
* Typically happens during replies.
|
* Typically happens during replies.
|
||||||
*/
|
*/
|
||||||
|
@Test
|
||||||
public void testIdentityString()
|
public void testIdentityString()
|
||||||
{
|
{
|
||||||
MessageReference mr = new MessageReference();
|
MessageReference mr = new MessageReference();
|
||||||
@ -33,6 +43,7 @@ public class MessageReferenceTest extends TestCase
|
|||||||
assertEquals("!:byBoYWkh:Zm9sZGVy:MTAxMDEwMTA=:ANSWERED", mr.toIdentityString());
|
assertEquals("!:byBoYWkh:Zm9sZGVy:MTAxMDEwMTA=:ANSWERED", mr.toIdentityString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testParseIdentityStringNoFlag() throws MessagingException
|
public void testParseIdentityStringNoFlag() throws MessagingException
|
||||||
{
|
{
|
||||||
MessageReference mr = new MessageReference("!:byBoYWkh:Zm9sZGVy:MTAxMDEwMTA=");
|
MessageReference mr = new MessageReference("!:byBoYWkh:Zm9sZGVy:MTAxMDEwMTA=");
|
||||||
@ -42,6 +53,7 @@ public class MessageReferenceTest extends TestCase
|
|||||||
assertNull(mr.flag);
|
assertNull(mr.flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testParseIdentityString() throws MessagingException
|
public void testParseIdentityString() throws MessagingException
|
||||||
{
|
{
|
||||||
MessageReference mr = new MessageReference("!:byBoYWkh:Zm9sZGVy:MTAxMDEwMTA=:ANSWERED");
|
MessageReference mr = new MessageReference("!:byBoYWkh:Zm9sZGVy:MTAxMDEwMTA=:ANSWERED");
|
||||||
@ -51,24 +63,20 @@ public class MessageReferenceTest extends TestCase
|
|||||||
assertEquals(Flag.ANSWERED, mr.flag);
|
assertEquals(Flag.ANSWERED, mr.flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testBadVersion() throws MessagingException
|
public void testBadVersion() throws MessagingException
|
||||||
{
|
{
|
||||||
MessageReference mr = new MessageReference("@:byBoYWkh:Zm9sZGVy:MTAxMDEwMTA=:ANSWERED");
|
MessageReference mr = new MessageReference("@:byBoYWkh:Zm9sZGVy:MTAxMDEwMTA=:ANSWERED");
|
||||||
assertNull(mr.accountUuid);
|
assertNull(mr.accountUuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = MessagingException.class)
|
||||||
public void testNull() throws MessagingException
|
public void testNull() throws MessagingException
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
new MessageReference(null);
|
new MessageReference(null);
|
||||||
assertTrue(false);
|
|
||||||
} catch (MessagingException e)
|
|
||||||
{
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = MessagingException.class)
|
||||||
public void testCorruption() throws MessagingException
|
public void testCorruption() throws MessagingException
|
||||||
{
|
{
|
||||||
MessageReference mr = new MessageReference("!:%^&%^*$&$by&(BYWkh:Zm9%^@sZGVy:MT-35#$AxMDEwMTA=:ANSWERED");
|
MessageReference mr = new MessageReference("!:%^&%^*$&$by&(BYWkh:Zm9%^@sZGVy:MT-35#$AxMDEwMTA=:ANSWERED");
|
||||||
@ -78,13 +86,6 @@ public class MessageReferenceTest extends TestCase
|
|||||||
assertNotNull(mr.uid);
|
assertNotNull(mr.uid);
|
||||||
|
|
||||||
// Corruption in the Flag should throw MessagingException.
|
// Corruption in the Flag should throw MessagingException.
|
||||||
try
|
|
||||||
{
|
|
||||||
new MessageReference("!:%^&%^*$&$by&(BYWkh:Zm9%^@sZGVy:MT-35#$AxMDEwMTA=:ANSWE!RED");
|
new MessageReference("!:%^&%^*$&$by&(BYWkh:Zm9%^@sZGVy:MT-35#$AxMDEwMTA=:ANSWE!RED");
|
||||||
assertTrue(false);
|
|
||||||
} catch (MessagingException e)
|
|
||||||
{
|
|
||||||
assertTrue(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ package com.fsck.k9.endtoend;
|
|||||||
|
|
||||||
import com.fsck.k9.activity.setup.WelcomeMessage;
|
import com.fsck.k9.activity.setup.WelcomeMessage;
|
||||||
import com.fsck.k9.endtoend.pages.WelcomeMessagePage;
|
import com.fsck.k9.endtoend.pages.WelcomeMessagePage;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new IMAP account via the getting started flow.
|
* Creates a new IMAP account via the getting started flow.
|
||||||
@ -12,13 +14,14 @@ public class A000_WelcomeAndSetupAccountIntegrationTest extends AbstractEndToEnd
|
|||||||
super(WelcomeMessage.class, false);
|
super(WelcomeMessage.class, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateAccount() throws Exception {
|
@Test
|
||||||
new AccountSetupFlow(this).setupAccountFromWelcomePage(new WelcomeMessagePage());
|
public void createAccount() throws Exception {
|
||||||
}
|
new AccountSetupFlow().setupAccountFromWelcomePage(new WelcomeMessagePage());
|
||||||
|
|
||||||
public void testCreateSecondAccount() throws Exception {
|
|
||||||
new AccountSetupFlow(this).setupAccountFromWelcomePage(new WelcomeMessagePage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createSecondAccount() throws Exception {
|
||||||
|
new AccountSetupFlow().setupAccountFromWelcomePage(new WelcomeMessagePage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import com.fsck.k9.activity.Accounts;
|
|||||||
import com.fsck.k9.endtoend.framework.AccountForTest;
|
import com.fsck.k9.endtoend.framework.AccountForTest;
|
||||||
import com.fsck.k9.endtoend.framework.ApplicationState;
|
import com.fsck.k9.endtoend.framework.ApplicationState;
|
||||||
import com.fsck.k9.endtoend.pages.AccountsPage;
|
import com.fsck.k9.endtoend.pages.AccountsPage;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and removes accounts.
|
* Creates and removes accounts.
|
||||||
@ -17,14 +19,19 @@ public class A010_AccountIntegrationTest extends AbstractEndToEndTest<Accounts>{
|
|||||||
super(Accounts.class);
|
super(Accounts.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateAccountDirectly() throws Exception {
|
@Test
|
||||||
new AccountSetupFlow(this).setupAccountFromAccountsPage(new AccountsPage());
|
public void createAccountDirectly() throws Exception {
|
||||||
|
new AccountSetupFlow().setupAccountFromAccountsPage(new AccountsPage());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDeleteAccount() {
|
@Test
|
||||||
|
public void deleteAccount() {
|
||||||
AccountsPage accountsPage = new AccountsPage();
|
AccountsPage accountsPage = new AccountsPage();
|
||||||
|
|
||||||
|
// TODO should not have cross-test-dependencies
|
||||||
|
assertFalse("NB: this test is order dependent and requires A000_WelcomeAndSetupAccountIntegrationTest to run first",
|
||||||
|
ApplicationState.getInstance().accounts.isEmpty());
|
||||||
|
|
||||||
AccountForTest accountForTest = ApplicationState.getInstance().accounts.get(0);
|
AccountForTest accountForTest = ApplicationState.getInstance().accounts.get(0);
|
||||||
accountsPage.assertAccountExists(accountForTest.description);
|
accountsPage.assertAccountExists(accountForTest.description);
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.fsck.k9.endtoend;
|
package com.fsck.k9.endtoend;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.espresso.assertion.ViewAssertions;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
import android.test.ActivityInstrumentationTestCase2;
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -8,16 +11,18 @@ import com.fsck.k9.R;
|
|||||||
import com.fsck.k9.endtoend.framework.ApplicationState;
|
import com.fsck.k9.endtoend.framework.ApplicationState;
|
||||||
import com.fsck.k9.endtoend.framework.StubMailServer;
|
import com.fsck.k9.endtoend.framework.StubMailServer;
|
||||||
import com.fsck.k9.endtoend.pages.WelcomeMessagePage;
|
import com.fsck.k9.endtoend.pages.WelcomeMessagePage;
|
||||||
import android.support.test.espresso.assertion.ViewAssertions;
|
|
||||||
|
|
||||||
import junit.framework.AssertionFailedError;
|
import junit.framework.AssertionFailedError;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import static android.support.test.espresso.Espresso.onView;
|
import static android.support.test.espresso.Espresso.onView;
|
||||||
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
public abstract class AbstractEndToEndTest<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
|
public abstract class AbstractEndToEndTest<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
|
||||||
|
|
||||||
private ApplicationState state = ApplicationState.getInstance();
|
|
||||||
private final boolean bypassWelcome;
|
private final boolean bypassWelcome;
|
||||||
|
|
||||||
public AbstractEndToEndTest(Class<T> activityClass) {
|
public AbstractEndToEndTest(Class<T> activityClass) {
|
||||||
@ -29,9 +34,22 @@ public abstract class AbstractEndToEndTest<T extends Activity> extends ActivityI
|
|||||||
this.bypassWelcome = bypassWelcome;
|
this.bypassWelcome = bypassWelcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() {
|
||||||
|
ApplicationState.getInstance().stubMailServer = new StubMailServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void afterClass() {
|
||||||
|
ApplicationState.getInstance().stubMailServer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
|
||||||
|
|
||||||
getActivity();
|
getActivity();
|
||||||
|
|
||||||
if (bypassWelcome) {
|
if (bypassWelcome) {
|
||||||
@ -39,6 +57,12 @@ public abstract class AbstractEndToEndTest<T extends Activity> extends ActivityI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
@Override
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
private void bypassWelcomeScreen() {
|
private void bypassWelcomeScreen() {
|
||||||
try {
|
try {
|
||||||
onView(withId(R.id.welcome_message)).check(ViewAssertions.doesNotExist());
|
onView(withId(R.id.welcome_message)).check(ViewAssertions.doesNotExist());
|
||||||
@ -47,14 +71,12 @@ public abstract class AbstractEndToEndTest<T extends Activity> extends ActivityI
|
|||||||
* The view doesn't NOT exist == the view exists, and needs to be bypassed!
|
* The view doesn't NOT exist == the view exists, and needs to be bypassed!
|
||||||
*/
|
*/
|
||||||
Log.d(getClass().getName(), "Bypassing welcome");
|
Log.d(getClass().getName(), "Bypassing welcome");
|
||||||
new AccountSetupFlow(this).setupAccountFromWelcomePage(new WelcomeMessagePage());
|
new AccountSetupFlow().setupAccountFromWelcomePage(new WelcomeMessagePage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected StubMailServer setupMailServer() {
|
|
||||||
if (null == state.stubMailServer) {
|
public void testEmpty() {
|
||||||
state.stubMailServer = new StubMailServer();
|
// workaround, needs to be empty so that JUnit4 test gets picked up
|
||||||
}
|
|
||||||
return state.stubMailServer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,6 @@ public class AccountSetupFlow {
|
|||||||
|
|
||||||
static final String ACCOUNT_NAME = "sendAndReceiveTestName";
|
static final String ACCOUNT_NAME = "sendAndReceiveTestName";
|
||||||
|
|
||||||
private final AbstractEndToEndTest test;
|
|
||||||
|
|
||||||
public AccountSetupFlow(AbstractEndToEndTest test) {
|
|
||||||
this.test = test;
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountsPage setupAccountFromWelcomePage(WelcomeMessagePage welcomeMessagePage) {
|
public AccountsPage setupAccountFromWelcomePage(WelcomeMessagePage welcomeMessagePage) {
|
||||||
AccountSetupPage accountSetupPage = welcomeMessagePage.clickNext();
|
AccountSetupPage accountSetupPage = welcomeMessagePage.clickNext();
|
||||||
return setupAccountFromSetupNewAccountActivity(accountSetupPage);
|
return setupAccountFromSetupNewAccountActivity(accountSetupPage);
|
||||||
@ -45,7 +39,8 @@ public class AccountSetupFlow {
|
|||||||
|
|
||||||
IncomingServerSettingsPage incoming = accountTypePage.clickImap();
|
IncomingServerSettingsPage incoming = accountTypePage.clickImap();
|
||||||
|
|
||||||
StubMailServer stubMailServer = test.setupMailServer();
|
|
||||||
|
StubMailServer stubMailServer = ApplicationState.getInstance().stubMailServer;
|
||||||
|
|
||||||
OutgoingServerSettingsPage outgoing = setupIncomingServerAndClickNext(incoming, stubMailServer);
|
OutgoingServerSettingsPage outgoing = setupIncomingServerAndClickNext(incoming, stubMailServer);
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package com.fsck.k9.endtoend.framework;
|
package com.fsck.k9.endtoend.framework;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.fsck.k9.K9;
|
||||||
|
import com.icegreen.greenmail.user.GreenMailUser;
|
||||||
import com.icegreen.greenmail.util.GreenMail;
|
import com.icegreen.greenmail.util.GreenMail;
|
||||||
import com.icegreen.greenmail.util.ServerSetup;
|
import com.icegreen.greenmail.util.ServerSetup;
|
||||||
|
|
||||||
@ -18,7 +22,18 @@ public class StubMailServer {
|
|||||||
public StubMailServer() {
|
public StubMailServer() {
|
||||||
|
|
||||||
greenmail = new GreenMail(new ServerSetup[]{IMAP_SERVER_SETUP, SMTP_SERVER_SETUP});
|
greenmail = new GreenMail(new ServerSetup[]{IMAP_SERVER_SETUP, SMTP_SERVER_SETUP});
|
||||||
greenmail.setUser(UserForImap.TEST_USER.emailAddress, UserForImap.TEST_USER.loginUsername, UserForImap.TEST_USER.password);
|
GreenMailUser user = greenmail
|
||||||
|
.setUser(UserForImap.TEST_USER.emailAddress, UserForImap.TEST_USER.loginUsername,
|
||||||
|
UserForImap.TEST_USER.password);
|
||||||
|
|
||||||
|
for (String mailbox : new String[] {"Drafts", "Spam"}) {
|
||||||
|
Log.d(K9.LOG_TAG, "creating mailbox "+mailbox);
|
||||||
|
try {
|
||||||
|
greenmail.getManagers().getImapHostManager().createMailbox(user, mailbox);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
greenmail.start();
|
greenmail.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,5 +52,9 @@ public class StubMailServer {
|
|||||||
public int getImapPort() {
|
public int getImapPort() {
|
||||||
return IMAP_SERVER_SETUP.getPort();
|
return IMAP_SERVER_SETUP.getPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
greenmail.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package com.fsck.k9.endtoend.pages;
|
package com.fsck.k9.endtoend.pages;
|
||||||
|
|
||||||
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
import android.support.test.espresso.NoMatchingViewException;
|
import android.support.test.espresso.NoMatchingViewException;
|
||||||
import android.support.test.espresso.matcher.ViewMatchers;
|
import android.support.test.espresso.matcher.ViewMatchers;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import static android.support.test.espresso.Espresso.onView;
|
import static android.support.test.espresso.Espresso.onView;
|
||||||
import static android.support.test.espresso.action.ViewActions.clearText;
|
import static android.support.test.espresso.action.ViewActions.clearText;
|
||||||
@ -41,6 +43,7 @@ public class AccountSetupNamesPage extends AbstractPage {
|
|||||||
try {
|
try {
|
||||||
onView(ViewMatchers.withText("OK")).perform(click());
|
onView(ViewMatchers.withText("OK")).perform(click());
|
||||||
} catch (NoMatchingViewException ex) {
|
} catch (NoMatchingViewException ex) {
|
||||||
|
Log.w(K9.LOG_TAG, "did not find Changelog OK button - ignored");
|
||||||
// Ignored. Not the best way of doing this, but Espresso rightly makes
|
// Ignored. Not the best way of doing this, but Espresso rightly makes
|
||||||
// conditional flow difficult.
|
// conditional flow difficult.
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,37 @@
|
|||||||
package com.fsck.k9.helper;
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
import java.lang.String;
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
public class FileHelperTest extends TestCase {
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class FileHelperTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSanitize1() {
|
public void testSanitize1() {
|
||||||
checkSanitization(".._bla_", "../bla_");
|
checkSanitization(".._bla_", "../bla_");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSanitize2() {
|
public void testSanitize2() {
|
||||||
checkSanitization("_etc_bla", "/etc/bla");
|
checkSanitization("_etc_bla", "/etc/bla");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSanitize3() {
|
public void testSanitize3() {
|
||||||
checkSanitization("_пPп", "+пPп");
|
checkSanitization("_пPп", "+пPп");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSanitize4() {
|
public void testSanitize4() {
|
||||||
checkSanitization(".東京_!", ".東京?!");
|
checkSanitization(".東京_!", ".東京?!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSanitize5() {
|
public void testSanitize5() {
|
||||||
checkSanitization("Plan 9", "Plan 9");
|
checkSanitization("Plan 9", "Plan 9");
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,24 @@
|
|||||||
package com.fsck.k9.helper;
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
|
|
||||||
public class HtmlConverterTest extends TestCase {
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class HtmlConverterTest {
|
||||||
// Useful if you want to write stuff to a file for debugging in a browser.
|
// Useful if you want to write stuff to a file for debugging in a browser.
|
||||||
private static final boolean WRITE_TO_FILE = Boolean.parseBoolean(System.getProperty("k9.htmlConverterTest.writeToFile", "false"));
|
private static final boolean WRITE_TO_FILE = Boolean.parseBoolean(System.getProperty("k9.htmlConverterTest.writeToFile", "false"));
|
||||||
private static final String OUTPUT_FILE = "C:/temp/parse.html";
|
private static final String OUTPUT_FILE = "C:/temp/parse.html";
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testTextQuoteToHtmlBlockquote() {
|
public void testTextQuoteToHtmlBlockquote() {
|
||||||
String message = "Panama!\r\n" +
|
String message = "Panama!\r\n" +
|
||||||
"\r\n" +
|
"\r\n" +
|
||||||
@ -29,25 +37,30 @@ public class HtmlConverterTest extends TestCase {
|
|||||||
+ "Panama!<br />"
|
+ "Panama!<br />"
|
||||||
+ "<br />"
|
+ "<br />"
|
||||||
+ "Bob Barker <bob@aol.com> wrote:<br />"
|
+ "Bob Barker <bob@aol.com> wrote:<br />"
|
||||||
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">"
|
+
|
||||||
|
"<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">"
|
||||||
+ " a canal<br />"
|
+ " a canal<br />"
|
||||||
+ "<br />"
|
+ "<br />"
|
||||||
+ " Dorothy Jo Gideon <dorothy@aol.com> espoused:<br />"
|
+ " Dorothy Jo Gideon <dorothy@aol.com> espoused:<br />"
|
||||||
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">"
|
+
|
||||||
|
"<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">"
|
||||||
+ "A man, a plan...<br />"
|
+ "A man, a plan...<br />"
|
||||||
+ "</blockquote>"
|
+ "</blockquote>"
|
||||||
+ " Too easy!<br />"
|
+ " Too easy!<br />"
|
||||||
+ "</blockquote>"
|
+ "</blockquote>"
|
||||||
+ "<br />"
|
+ "<br />"
|
||||||
+ "Nice job :)<br />"
|
+ "Nice job :)<br />"
|
||||||
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">"
|
+
|
||||||
+ "<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">"
|
"<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">"
|
||||||
|
+
|
||||||
|
"<blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">"
|
||||||
+ " Guess!"
|
+ " Guess!"
|
||||||
+ "</blockquote>"
|
+ "</blockquote>"
|
||||||
+ "</blockquote>"
|
+ "</blockquote>"
|
||||||
+ "</pre>", result);
|
+ "</pre>", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testTextQuoteToHtmlBlockquoteIndented() {
|
public void testTextQuoteToHtmlBlockquoteIndented() {
|
||||||
String message = "*facepalm*\r\n" +
|
String message = "*facepalm*\r\n" +
|
||||||
"\r\n" +
|
"\r\n" +
|
||||||
@ -73,6 +86,7 @@ public class HtmlConverterTest extends TestCase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testQuoteDepthColor() {
|
public void testQuoteDepthColor() {
|
||||||
assertEquals(HtmlConverter.getQuoteColor(1), HtmlConverter.QUOTE_COLOR_LEVEL_1);
|
assertEquals(HtmlConverter.getQuoteColor(1), HtmlConverter.QUOTE_COLOR_LEVEL_1);
|
||||||
assertEquals(HtmlConverter.getQuoteColor(2), HtmlConverter.QUOTE_COLOR_LEVEL_2);
|
assertEquals(HtmlConverter.getQuoteColor(2), HtmlConverter.QUOTE_COLOR_LEVEL_2);
|
||||||
@ -135,6 +149,7 @@ public class HtmlConverterTest extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testPreserveSpacesAtFirst() {
|
public void testPreserveSpacesAtFirst() {
|
||||||
String message = "foo\r\n"
|
String message = "foo\r\n"
|
||||||
+ " bar\r\n"
|
+ " bar\r\n"
|
||||||
@ -148,6 +163,7 @@ public class HtmlConverterTest extends TestCase {
|
|||||||
+ "</pre>", result);
|
+ "</pre>", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testPreserveSpacesAtFirstForSpecialCharacters() {
|
public void testPreserveSpacesAtFirstForSpecialCharacters() {
|
||||||
String message =
|
String message =
|
||||||
" \r\n"
|
" \r\n"
|
||||||
@ -168,6 +184,7 @@ public class HtmlConverterTest extends TestCase {
|
|||||||
+ "</pre>", result);
|
+ "</pre>", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testLinkifyBitcoinAndHttpUri() {
|
public void testLinkifyBitcoinAndHttpUri() {
|
||||||
String text = "bitcoin:19W6QZkx8SYPG7BBCS7odmWGRxqRph5jFU http://example.com/";
|
String text = "bitcoin:19W6QZkx8SYPG7BBCS7odmWGRxqRph5jFU http://example.com/";
|
||||||
|
|
||||||
|
@ -1,21 +1,31 @@
|
|||||||
package com.fsck.k9.helper;
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.test.AndroidTestCase;
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
import android.text.SpannableString;
|
import android.text.SpannableString;
|
||||||
|
|
||||||
import com.fsck.k9.mail.Address;
|
import com.fsck.k9.mail.Address;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
public class MessageHelperTest extends AndroidTestCase {
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static junit.framework.Assert.assertTrue;
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class MessageHelperTest {
|
||||||
private Contacts contacts;
|
private Contacts contacts;
|
||||||
private Contacts mockContacts;
|
private Contacts mockContacts;
|
||||||
|
|
||||||
@Override
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
Context context = InstrumentationRegistry.getTargetContext();
|
||||||
contacts = new Contacts(getContext());
|
contacts = new Contacts(context);
|
||||||
mockContacts = new Contacts(getContext()) {
|
mockContacts = new Contacts(context) {
|
||||||
@Override public String getNameForAddress(String address) {
|
@Override public String getNameForAddress(String address) {
|
||||||
if ("test@testor.com".equals(address)) {
|
if ("test@testor.com".equals(address)) {
|
||||||
return "Tim Testor";
|
return "Tim Testor";
|
||||||
@ -26,16 +36,19 @@ public class MessageHelperTest extends AndroidTestCase {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testToFriendlyShowsPersonalPartIfItExists() throws Exception {
|
public void testToFriendlyShowsPersonalPartIfItExists() throws Exception {
|
||||||
Address address = new Address("test@testor.com", "Tim Testor");
|
Address address = new Address("test@testor.com", "Tim Testor");
|
||||||
assertEquals("Tim Testor", MessageHelper.toFriendly(address, contacts));
|
assertEquals("Tim Testor", MessageHelper.toFriendly(address, contacts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testToFriendlyShowsEmailPartIfNoPersonalPartExists() throws Exception {
|
public void testToFriendlyShowsEmailPartIfNoPersonalPartExists() throws Exception {
|
||||||
Address address = new Address("test@testor.com");
|
Address address = new Address("test@testor.com");
|
||||||
assertEquals("test@testor.com", MessageHelper.toFriendly(address, contacts));
|
assertEquals("test@testor.com", MessageHelper.toFriendly(address, contacts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testToFriendlyArray() throws Exception {
|
public void testToFriendlyArray() throws Exception {
|
||||||
Address address1 = new Address("test@testor.com", "Tim Testor");
|
Address address1 = new Address("test@testor.com", "Tim Testor");
|
||||||
Address address2 = new Address("foo@bar.com", "Foo Bar");
|
Address address2 = new Address("foo@bar.com", "Foo Bar");
|
||||||
@ -43,11 +56,13 @@ public class MessageHelperTest extends AndroidTestCase {
|
|||||||
assertEquals("Tim Testor,Foo Bar", MessageHelper.toFriendly(addresses, contacts).toString());
|
assertEquals("Tim Testor,Foo Bar", MessageHelper.toFriendly(addresses, contacts).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testToFriendlyWithContactLookup() throws Exception {
|
public void testToFriendlyWithContactLookup() throws Exception {
|
||||||
Address address = new Address("test@testor.com");
|
Address address = new Address("test@testor.com");
|
||||||
assertEquals("Tim Testor", MessageHelper.toFriendly(address, mockContacts).toString());
|
assertEquals("Tim Testor", MessageHelper.toFriendly(address, mockContacts).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testToFriendlyWithChangeContactColor() throws Exception {
|
public void testToFriendlyWithChangeContactColor() throws Exception {
|
||||||
Address address = new Address("test@testor.com");
|
Address address = new Address("test@testor.com");
|
||||||
CharSequence friendly = MessageHelper.toFriendly(address, mockContacts, true, true, Color.RED);
|
CharSequence friendly = MessageHelper.toFriendly(address, mockContacts, true, true, Color.RED);
|
||||||
@ -55,6 +70,7 @@ public class MessageHelperTest extends AndroidTestCase {
|
|||||||
assertEquals("Tim Testor", friendly.toString());
|
assertEquals("Tim Testor", friendly.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testToFriendlyWithoutCorrespondentNames() throws Exception {
|
public void testToFriendlyWithoutCorrespondentNames() throws Exception {
|
||||||
Address address = new Address("test@testor.com", "Tim Testor");
|
Address address = new Address("test@testor.com", "Tim Testor");
|
||||||
CharSequence friendly = MessageHelper.toFriendly(address, mockContacts, false, false, 0);
|
CharSequence friendly = MessageHelper.toFriendly(address, mockContacts, false, false, 0);
|
||||||
|
@ -8,12 +8,8 @@ import java.io.OutputStream;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import com.fsck.k9.mail.internet.MimeMessageHelper;
|
import android.support.test.InstrumentationRegistry;
|
||||||
import org.apache.commons.io.IOUtils;
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
import org.apache.james.mime4j.codec.Base64InputStream;
|
|
||||||
import org.apache.james.mime4j.util.MimeUtil;
|
|
||||||
|
|
||||||
import android.test.AndroidTestCase;
|
|
||||||
|
|
||||||
import com.fsck.k9.mail.Message.RecipientType;
|
import com.fsck.k9.mail.Message.RecipientType;
|
||||||
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
||||||
@ -22,13 +18,23 @@ import com.fsck.k9.mail.internet.CharsetSupport;
|
|||||||
import com.fsck.k9.mail.internet.MimeBodyPart;
|
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||||
import com.fsck.k9.mail.internet.MimeHeader;
|
import com.fsck.k9.mail.internet.MimeHeader;
|
||||||
import com.fsck.k9.mail.internet.MimeMessage;
|
import com.fsck.k9.mail.internet.MimeMessage;
|
||||||
|
import com.fsck.k9.mail.internet.MimeMessageHelper;
|
||||||
import com.fsck.k9.mail.internet.MimeMultipart;
|
import com.fsck.k9.mail.internet.MimeMultipart;
|
||||||
import com.fsck.k9.mail.internet.TextBody;
|
import com.fsck.k9.mail.internet.TextBody;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.james.mime4j.util.MimeUtil;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
public class MessageTest extends AndroidTestCase {
|
import static org.junit.Assert.assertEquals;
|
||||||
@Override
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class MessageTest {
|
||||||
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo"));
|
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Tokyo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,10 +278,7 @@ public class MessageTest extends AndroidTestCase {
|
|||||||
|
|
||||||
private int mMimeBoundary;
|
private int mMimeBoundary;
|
||||||
|
|
||||||
public MessageTest() {
|
@Test
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSetSendDateSetsSentDate() throws Exception {
|
public void testSetSendDateSetsSentDate() throws Exception {
|
||||||
Message message = sampleMessage();
|
Message message = sampleMessage();
|
||||||
final int milliseconds = 0;
|
final int milliseconds = 0;
|
||||||
@ -286,23 +289,26 @@ public class MessageTest extends AndroidTestCase {
|
|||||||
assertEquals(milliseconds, sentDate.getTime());
|
assertEquals(milliseconds, sentDate.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSetSendDateFormatsHeaderCorrectlyWithCurrentTimeZone() throws Exception {
|
public void testSetSendDateFormatsHeaderCorrectlyWithCurrentTimeZone() throws Exception {
|
||||||
Message message = sampleMessage();
|
Message message = sampleMessage();
|
||||||
message.setSentDate(new Date(0), false);
|
message.setSentDate(new Date(0), false);
|
||||||
assertEquals("Thu, 01 Jan 1970 09:00:00 +0900", message.getHeader("Date")[0]);
|
assertEquals("Thu, 01 Jan 1970 09:00:00 +0900", message.getHeader("Date")[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSetSendDateFormatsHeaderCorrectlyWithoutTimeZone() throws Exception {
|
public void testSetSendDateFormatsHeaderCorrectlyWithoutTimeZone() throws Exception {
|
||||||
Message message = sampleMessage();
|
Message message = sampleMessage();
|
||||||
message.setSentDate(new Date(0), true);
|
message.setSentDate(new Date(0), true);
|
||||||
assertEquals("Thu, 01 Jan 1970 00:00:00 +0000", message.getHeader("Date")[0]);
|
assertEquals("Thu, 01 Jan 1970 00:00:00 +0000", message.getHeader("Date")[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testMessage() throws MessagingException, IOException {
|
public void testMessage() throws MessagingException, IOException {
|
||||||
MimeMessage message;
|
MimeMessage message;
|
||||||
ByteArrayOutputStream out;
|
ByteArrayOutputStream out;
|
||||||
|
|
||||||
BinaryTempFileBody.setTempDirectory(getContext().getCacheDir());
|
BinaryTempFileBody.setTempDirectory(InstrumentationRegistry.getTargetContext().getCacheDir());
|
||||||
|
|
||||||
mMimeBoundary = 101;
|
mMimeBoundary = 101;
|
||||||
message = nestedMessage(nestedMessage(sampleMessage()));
|
message = nestedMessage(nestedMessage(sampleMessage()));
|
||||||
|
@ -6,10 +6,13 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import android.test.AndroidTestCase;
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
||||||
import com.fsck.k9.mail.internet.MimeMessage;
|
import com.fsck.k9.mail.internet.MimeMessage;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
import org.spongycastle.openpgp.PGPCompressedData;
|
import org.spongycastle.openpgp.PGPCompressedData;
|
||||||
import org.spongycastle.openpgp.PGPException;
|
import org.spongycastle.openpgp.PGPException;
|
||||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||||
@ -22,8 +25,11 @@ import org.spongycastle.openpgp.bc.BcPGPObjectFactory;
|
|||||||
import org.spongycastle.openpgp.bc.BcPGPPublicKeyRingCollection;
|
import org.spongycastle.openpgp.bc.BcPGPPublicKeyRingCollection;
|
||||||
import org.spongycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
|
import org.spongycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertTrue;
|
||||||
|
|
||||||
public class PgpMimeMessageTest extends AndroidTestCase {
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class PgpMimeMessageTest {
|
||||||
private static final String PUBLIC_KEY = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
|
private static final String PUBLIC_KEY = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
|
||||||
"Version: GnuPG v1\n" +
|
"Version: GnuPG v1\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
@ -150,6 +156,7 @@ public class PgpMimeMessageTest extends AndroidTestCase {
|
|||||||
"-----END PGP PUBLIC KEY BLOCK-----\n";
|
"-----END PGP PUBLIC KEY BLOCK-----\n";
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSignedMessage() throws IOException, MessagingException, PGPException {
|
public void testSignedMessage() throws IOException, MessagingException, PGPException {
|
||||||
String messageSource = "Date: Mon, 08 Dec 2014 17:44:18 +0100\r\n" +
|
String messageSource = "Date: Mon, 08 Dec 2014 17:44:18 +0100\r\n" +
|
||||||
"From: cketti <cketti@googlemail.com>\r\n" +
|
"From: cketti <cketti@googlemail.com>\r\n" +
|
||||||
@ -209,7 +216,7 @@ public class PgpMimeMessageTest extends AndroidTestCase {
|
|||||||
"\r\n" +
|
"\r\n" +
|
||||||
"--24Bem7EnUI1Ipn9jNXuLgsetqa6wOkIxM--\r\n";
|
"--24Bem7EnUI1Ipn9jNXuLgsetqa6wOkIxM--\r\n";
|
||||||
|
|
||||||
BinaryTempFileBody.setTempDirectory(getContext().getCacheDir());
|
BinaryTempFileBody.setTempDirectory(InstrumentationRegistry.getTargetContext().getCacheDir());
|
||||||
|
|
||||||
InputStream messageInputStream = new ByteArrayInputStream(messageSource.getBytes());
|
InputStream messageInputStream = new ByteArrayInputStream(messageSource.getBytes());
|
||||||
MimeMessage message;
|
MimeMessage message;
|
||||||
|
@ -6,14 +6,22 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
||||||
import com.fsck.k9.mail.internet.MimeMessage;
|
import com.fsck.k9.mail.internet.MimeMessage;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
public class ReconstructMessageTest extends AndroidTestCase {
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ReconstructMessageTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testMessage() throws IOException, MessagingException {
|
public void testMessage() throws IOException, MessagingException {
|
||||||
String messageSource =
|
String messageSource =
|
||||||
"From: from@example.com\r\n" +
|
"From: from@example.com\r\n" +
|
||||||
@ -45,7 +53,7 @@ public class ReconstructMessageTest extends AndroidTestCase {
|
|||||||
"------Boundary--\r\n" +
|
"------Boundary--\r\n" +
|
||||||
"Hi, I'm the epilogue";
|
"Hi, I'm the epilogue";
|
||||||
|
|
||||||
BinaryTempFileBody.setTempDirectory(getContext().getCacheDir());
|
BinaryTempFileBody.setTempDirectory(InstrumentationRegistry.getTargetContext().getCacheDir());
|
||||||
|
|
||||||
InputStream messageInputStream = new ByteArrayInputStream(messageSource.getBytes());
|
InputStream messageInputStream = new ByteArrayInputStream(messageSource.getBytes());
|
||||||
MimeMessage message;
|
MimeMessage message;
|
||||||
|
@ -1,18 +1,29 @@
|
|||||||
package com.fsck.k9.mail.ssl;
|
package com.fsck.k9.mail.ssl;
|
||||||
|
|
||||||
import javax.net.ssl.X509TrustManager;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import android.test.AndroidTestCase;
|
|
||||||
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertFalse;
|
||||||
|
import static junit.framework.Assert.assertTrue;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the functionality of {@link TrustManagerFactory}.
|
* Test the functionality of {@link TrustManagerFactory}.
|
||||||
*/
|
*/
|
||||||
public class TrustManagerFactoryTest extends AndroidTestCase {
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class TrustManagerFactoryTest {
|
||||||
public static final String MATCHING_HOST = "k9.example.com";
|
public static final String MATCHING_HOST = "k9.example.com";
|
||||||
public static final String NOT_MATCHING_HOST = "bla.example.com";
|
public static final String NOT_MATCHING_HOST = "bla.example.com";
|
||||||
public static final int PORT1 = 993;
|
public static final int PORT1 = 993;
|
||||||
@ -196,15 +207,16 @@ public class TrustManagerFactoryTest extends AndroidTestCase {
|
|||||||
new ByteArrayInputStream(encodedCert.getBytes()));
|
new ByteArrayInputStream(encodedCert.getBytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
mKeyStoreFile = File.createTempFile("localKeyStore", null, getContext().getCacheDir());
|
mKeyStoreFile = File.createTempFile("localKeyStore", null,
|
||||||
|
InstrumentationRegistry.getTargetContext().getCacheDir());
|
||||||
mKeyStore = LocalKeyStore.getInstance();
|
mKeyStore = LocalKeyStore.getInstance();
|
||||||
mKeyStore.setKeyStoreFile(mKeyStoreFile);
|
mKeyStore.setKeyStoreFile(mKeyStoreFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@After
|
||||||
protected void tearDown() {
|
public void tearDown() {
|
||||||
mKeyStoreFile.delete();
|
mKeyStoreFile.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +232,7 @@ public class TrustManagerFactoryTest extends AndroidTestCase {
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
* if anything goes wrong
|
* if anything goes wrong
|
||||||
*/
|
*/
|
||||||
|
@Test
|
||||||
public void testDifferentCertificatesOnSameServer() throws Exception {
|
public void testDifferentCertificatesOnSameServer() throws Exception {
|
||||||
mKeyStore.addCertificate(NOT_MATCHING_HOST, PORT1, mCert1);
|
mKeyStore.addCertificate(NOT_MATCHING_HOST, PORT1, mCert1);
|
||||||
mKeyStore.addCertificate(NOT_MATCHING_HOST, PORT2, mCert2);
|
mKeyStore.addCertificate(NOT_MATCHING_HOST, PORT2, mCert2);
|
||||||
@ -230,24 +243,28 @@ public class TrustManagerFactoryTest extends AndroidTestCase {
|
|||||||
trustManager1.checkServerTrusted(new X509Certificate[] { mCert1 }, "authType");
|
trustManager1.checkServerTrusted(new X509Certificate[] { mCert1 }, "authType");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSelfSignedCertificateMatchingHost() throws Exception {
|
public void testSelfSignedCertificateMatchingHost() throws Exception {
|
||||||
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mCert1);
|
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mCert1);
|
||||||
X509TrustManager trustManager = TrustManagerFactory.get(MATCHING_HOST, PORT1);
|
X509TrustManager trustManager = TrustManagerFactory.get(MATCHING_HOST, PORT1);
|
||||||
trustManager.checkServerTrusted(new X509Certificate[] { mCert1 }, "authType");
|
trustManager.checkServerTrusted(new X509Certificate[] { mCert1 }, "authType");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSelfSignedCertificateNotMatchingHost() throws Exception {
|
public void testSelfSignedCertificateNotMatchingHost() throws Exception {
|
||||||
mKeyStore.addCertificate(NOT_MATCHING_HOST, PORT1, mCert1);
|
mKeyStore.addCertificate(NOT_MATCHING_HOST, PORT1, mCert1);
|
||||||
X509TrustManager trustManager = TrustManagerFactory.get(NOT_MATCHING_HOST, PORT1);
|
X509TrustManager trustManager = TrustManagerFactory.get(NOT_MATCHING_HOST, PORT1);
|
||||||
trustManager.checkServerTrusted(new X509Certificate[] { mCert1 }, "authType");
|
trustManager.checkServerTrusted(new X509Certificate[] { mCert1 }, "authType");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testWrongCertificate() throws Exception {
|
public void testWrongCertificate() throws Exception {
|
||||||
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mCert1);
|
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mCert1);
|
||||||
X509TrustManager trustManager = TrustManagerFactory.get(MATCHING_HOST, PORT1);
|
X509TrustManager trustManager = TrustManagerFactory.get(MATCHING_HOST, PORT1);
|
||||||
assertCertificateRejection(trustManager, new X509Certificate[] { mCert2 });
|
assertCertificateRejection(trustManager, new X509Certificate[] { mCert2 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testCertificateOfOtherHost() throws Exception {
|
public void testCertificateOfOtherHost() throws Exception {
|
||||||
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mCert1);
|
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mCert1);
|
||||||
mKeyStore.addCertificate(MATCHING_HOST, PORT2, mCert2);
|
mKeyStore.addCertificate(MATCHING_HOST, PORT2, mCert2);
|
||||||
@ -256,11 +273,13 @@ public class TrustManagerFactoryTest extends AndroidTestCase {
|
|||||||
assertCertificateRejection(trustManager, new X509Certificate[] { mCert2 });
|
assertCertificateRejection(trustManager, new X509Certificate[] { mCert2 });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testUntrustedCertificateChain() throws Exception {
|
public void testUntrustedCertificateChain() throws Exception {
|
||||||
X509TrustManager trustManager = TrustManagerFactory.get(MATCHING_HOST, PORT1);
|
X509TrustManager trustManager = TrustManagerFactory.get(MATCHING_HOST, PORT1);
|
||||||
assertCertificateRejection(trustManager, new X509Certificate[] { mCert3, mCaCert });
|
assertCertificateRejection(trustManager, new X509Certificate[] { mCert3, mCaCert });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testLocallyTrustedCertificateChain() throws Exception {
|
public void testLocallyTrustedCertificateChain() throws Exception {
|
||||||
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mCert3);
|
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mCert3);
|
||||||
|
|
||||||
@ -268,6 +287,7 @@ public class TrustManagerFactoryTest extends AndroidTestCase {
|
|||||||
trustManager.checkServerTrusted(new X509Certificate[] { mCert3, mCaCert }, "authType");
|
trustManager.checkServerTrusted(new X509Certificate[] { mCert3, mCaCert }, "authType");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testLocallyTrustedCertificateChainNotMatchingHost() throws Exception {
|
public void testLocallyTrustedCertificateChainNotMatchingHost() throws Exception {
|
||||||
mKeyStore.addCertificate(NOT_MATCHING_HOST, PORT1, mCert3);
|
mKeyStore.addCertificate(NOT_MATCHING_HOST, PORT1, mCert3);
|
||||||
|
|
||||||
@ -275,17 +295,20 @@ public class TrustManagerFactoryTest extends AndroidTestCase {
|
|||||||
trustManager.checkServerTrusted(new X509Certificate[] { mCert3, mCaCert }, "authType");
|
trustManager.checkServerTrusted(new X509Certificate[] { mCert3, mCaCert }, "authType");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testGloballyTrustedCertificateChain() throws Exception {
|
public void testGloballyTrustedCertificateChain() throws Exception {
|
||||||
X509TrustManager trustManager = TrustManagerFactory.get("www.linux.com", PORT1);
|
X509TrustManager trustManager = TrustManagerFactory.get("www.linux.com", PORT1);
|
||||||
X509Certificate[] certificates = new X509Certificate[] { mLinuxComCert, mLinuxComFirstParentCert};
|
X509Certificate[] certificates = new X509Certificate[] { mLinuxComCert, mLinuxComFirstParentCert};
|
||||||
trustManager.checkServerTrusted(certificates, "authType");
|
trustManager.checkServerTrusted(certificates, "authType");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testGloballyTrustedCertificateNotMatchingHost() throws Exception {
|
public void testGloballyTrustedCertificateNotMatchingHost() throws Exception {
|
||||||
X509TrustManager trustManager = TrustManagerFactory.get(NOT_MATCHING_HOST, PORT1);
|
X509TrustManager trustManager = TrustManagerFactory.get(NOT_MATCHING_HOST, PORT1);
|
||||||
assertCertificateRejection(trustManager, new X509Certificate[] { mLinuxComCert, mLinuxComFirstParentCert});
|
assertCertificateRejection(trustManager, new X509Certificate[] { mLinuxComCert, mLinuxComFirstParentCert});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testGloballyTrustedCertificateNotMatchingHostOverride() throws Exception {
|
public void testGloballyTrustedCertificateNotMatchingHostOverride() throws Exception {
|
||||||
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mLinuxComCert);
|
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mLinuxComCert);
|
||||||
|
|
||||||
@ -306,6 +329,7 @@ public class TrustManagerFactoryTest extends AndroidTestCase {
|
|||||||
assertFalse("The certificate should have been rejected but wasn't", certificateValid);
|
assertFalse("The certificate should have been rejected but wasn't", certificateValid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testKeyStoreLoading() throws Exception {
|
public void testKeyStoreLoading() throws Exception {
|
||||||
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mCert1);
|
mKeyStore.addCertificate(MATCHING_HOST, PORT1, mCert1);
|
||||||
mKeyStore.addCertificate(NOT_MATCHING_HOST, PORT2, mCert2);
|
mKeyStore.addCertificate(NOT_MATCHING_HOST, PORT2, mCert2);
|
||||||
|
@ -0,0 +1,204 @@
|
|||||||
|
package com.fsck.k9.mail.store.imap;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import com.fsck.k9.endtoend.framework.StubMailServer;
|
||||||
|
import com.fsck.k9.endtoend.framework.UserForImap;
|
||||||
|
import com.fsck.k9.mail.AuthType;
|
||||||
|
import com.fsck.k9.mail.AuthenticationFailedException;
|
||||||
|
import com.fsck.k9.mail.ConnectionSecurity;
|
||||||
|
import com.fsck.k9.mail.MessagingException;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static junit.framework.Assert.assertFalse;
|
||||||
|
import static junit.framework.Assert.assertNull;
|
||||||
|
import static junit.framework.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ImapConnectionTest {
|
||||||
|
private static final String[] CAPABILITIES = new String[] { "IMAP4REV1", "LITERAL+", "QUOTA" };
|
||||||
|
|
||||||
|
private StubMailServer stubMailServer;
|
||||||
|
private ImapConnection connection;
|
||||||
|
private TestImapSettings settings;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
stubMailServer = new StubMailServer();
|
||||||
|
settings = new TestImapSettings(UserForImap.TEST_USER);
|
||||||
|
connection = new ImapConnection(settings, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
stubMailServer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = MessagingException.class)
|
||||||
|
public void testOpenConnectionWithoutRunningServerThrowsMessagingException() throws Exception {
|
||||||
|
stubMailServer.stop();
|
||||||
|
connection.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = AuthenticationFailedException.class)
|
||||||
|
public void testOpenConnectionWithWrongCredentialsThrowsAuthenticationFailedException() throws Exception {
|
||||||
|
connection = new ImapConnection(new TestImapSettings("wrong", "password"), null, null);
|
||||||
|
connection.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConnectionIsInitiallyClosed() throws Exception {
|
||||||
|
assertFalse(connection.isOpen());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccessfulOpenConnectionTogglesOpenState() throws Exception {
|
||||||
|
connection.open();
|
||||||
|
assertTrue(connection.isOpen());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccessfulOpenAndCloseConnectionTogglesOpenState() throws Exception {
|
||||||
|
connection.open();
|
||||||
|
connection.close();
|
||||||
|
assertFalse(connection.isOpen());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCapabilitiesAreInitiallyEmpty() throws Exception {
|
||||||
|
assertTrue(connection.getCapabilities().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCapabilitiesListGetsParsedCorrectly() throws Exception {
|
||||||
|
connection.open();
|
||||||
|
List<String> capabilities = new ArrayList<String>(connection.getCapabilities());
|
||||||
|
Collections.sort(capabilities);
|
||||||
|
assertArrayEquals(CAPABILITIES, capabilities.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHasCapabilityChecks() throws Exception {
|
||||||
|
connection.open();
|
||||||
|
for (String capability : CAPABILITIES) {
|
||||||
|
assertTrue(connection.hasCapability(capability));
|
||||||
|
}
|
||||||
|
assertFalse(connection.hasCapability("FROBAZIFCATE"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPathPrefixGetsSetCorrectly() throws Exception {
|
||||||
|
connection.open();
|
||||||
|
assertEquals("", settings.getPathPrefix());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPathDelimiterGetsParsedCorrectly() throws Exception {
|
||||||
|
connection.open();
|
||||||
|
assertEquals(".", settings.getPathDelimiter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCombinedPrefixGetsSetCorrectly() throws Exception {
|
||||||
|
connection.open();
|
||||||
|
assertNull(settings.getCombinedPrefix());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestImapSettings implements ImapSettings {
|
||||||
|
private String pathPrefix;
|
||||||
|
private String pathDelimiter;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private String combinedPrefix;
|
||||||
|
|
||||||
|
public TestImapSettings(UserForImap userForImap) {
|
||||||
|
this(userForImap.loginUsername, userForImap.password);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestImapSettings(String username, String password) {
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHost() {
|
||||||
|
return stubMailServer.getImapBindAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPort() {
|
||||||
|
return stubMailServer.getImapPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConnectionSecurity getConnectionSecurity() {
|
||||||
|
return ConnectionSecurity.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthType getAuthType() {
|
||||||
|
return AuthType.PLAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getClientCertificateAlias() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useCompression(int type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPathPrefix() {
|
||||||
|
return pathPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPathPrefix(String prefix) {
|
||||||
|
pathPrefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPathDelimiter() {
|
||||||
|
return pathDelimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPathDelimiter(String delimiter) {
|
||||||
|
pathDelimiter = delimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCombinedPrefix() {
|
||||||
|
return combinedPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCombinedPrefix(String prefix) {
|
||||||
|
combinedPrefix = prefix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,22 +3,30 @@ package com.fsck.k9.mailstore;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import android.test.AndroidTestCase;
|
|
||||||
|
import android.support.test.InstrumentationRegistry;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
import com.fsck.k9.activity.K9ActivityCommon;
|
import com.fsck.k9.activity.K9ActivityCommon;
|
||||||
import com.fsck.k9.mail.Address;
|
import com.fsck.k9.mail.Address;
|
||||||
import com.fsck.k9.mail.MessagingException;
|
|
||||||
import com.fsck.k9.mail.Message.RecipientType;
|
import com.fsck.k9.mail.Message.RecipientType;
|
||||||
|
import com.fsck.k9.mail.MessagingException;
|
||||||
import com.fsck.k9.mail.internet.MimeBodyPart;
|
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||||
import com.fsck.k9.mail.internet.MimeMessage;
|
import com.fsck.k9.mail.internet.MimeMessage;
|
||||||
import com.fsck.k9.mail.internet.MimeMessageHelper;
|
import com.fsck.k9.mail.internet.MimeMessageHelper;
|
||||||
import com.fsck.k9.mail.internet.MimeMultipart;
|
import com.fsck.k9.mail.internet.MimeMultipart;
|
||||||
import com.fsck.k9.mail.internet.TextBody;
|
import com.fsck.k9.mail.internet.TextBody;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import static com.fsck.k9.mailstore.LocalMessageExtractor.extractTextAndAttachments;
|
import static com.fsck.k9.mailstore.LocalMessageExtractor.extractTextAndAttachments;
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
public class LocalMessageExtractorTest extends AndroidTestCase {
|
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class LocalMessageExtractorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSimplePlainTextMessage() throws MessagingException {
|
public void testSimplePlainTextMessage() throws MessagingException {
|
||||||
String bodyText = "K-9 Mail rocks :>";
|
String bodyText = "K-9 Mail rocks :>";
|
||||||
|
|
||||||
@ -30,7 +38,7 @@ public class LocalMessageExtractorTest extends AndroidTestCase {
|
|||||||
MimeMessageHelper.setBody(message, body);
|
MimeMessageHelper.setBody(message, body);
|
||||||
|
|
||||||
// Extract text
|
// Extract text
|
||||||
ViewableContainer container = extractTextAndAttachments(getContext(), message);
|
ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), message);
|
||||||
|
|
||||||
String expectedText = bodyText;
|
String expectedText = bodyText;
|
||||||
String expectedHtml =
|
String expectedHtml =
|
||||||
@ -42,6 +50,7 @@ public class LocalMessageExtractorTest extends AndroidTestCase {
|
|||||||
assertEquals(expectedHtml, container.html);
|
assertEquals(expectedHtml, container.html);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testSimpleHtmlMessage() throws MessagingException {
|
public void testSimpleHtmlMessage() throws MessagingException {
|
||||||
String bodyText = "<strong>K-9 Mail</strong> rocks :>";
|
String bodyText = "<strong>K-9 Mail</strong> rocks :>";
|
||||||
|
|
||||||
@ -54,7 +63,7 @@ public class LocalMessageExtractorTest extends AndroidTestCase {
|
|||||||
MimeMessageHelper.setBody(message, body);
|
MimeMessageHelper.setBody(message, body);
|
||||||
|
|
||||||
// Extract text
|
// Extract text
|
||||||
ViewableContainer container = extractTextAndAttachments(getContext(), message);
|
ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), message);
|
||||||
|
|
||||||
String expectedText = "K-9 Mail rocks :>";
|
String expectedText = "K-9 Mail rocks :>";
|
||||||
String expectedHtml =
|
String expectedHtml =
|
||||||
@ -64,6 +73,7 @@ public class LocalMessageExtractorTest extends AndroidTestCase {
|
|||||||
assertEquals(expectedHtml, container.html);
|
assertEquals(expectedHtml, container.html);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testMultipartPlainTextMessage() throws MessagingException {
|
public void testMultipartPlainTextMessage() throws MessagingException {
|
||||||
String bodyText1 = "text body 1";
|
String bodyText1 = "text body 1";
|
||||||
String bodyText2 = "text body 2";
|
String bodyText2 = "text body 2";
|
||||||
@ -84,7 +94,7 @@ public class LocalMessageExtractorTest extends AndroidTestCase {
|
|||||||
MimeMessageHelper.setBody(message, multipart);
|
MimeMessageHelper.setBody(message, multipart);
|
||||||
|
|
||||||
// Extract text
|
// Extract text
|
||||||
ViewableContainer container = extractTextAndAttachments(getContext(), message);
|
ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), message);
|
||||||
|
|
||||||
String expectedText =
|
String expectedText =
|
||||||
bodyText1 + "\r\n\r\n" +
|
bodyText1 + "\r\n\r\n" +
|
||||||
@ -105,8 +115,9 @@ public class LocalMessageExtractorTest extends AndroidTestCase {
|
|||||||
assertEquals(expectedHtml, container.html);
|
assertEquals(expectedHtml, container.html);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testTextPlusRfc822Message() throws MessagingException {
|
public void testTextPlusRfc822Message() throws MessagingException {
|
||||||
K9ActivityCommon.setLanguage(getContext(), "en");
|
K9ActivityCommon.setLanguage(InstrumentationRegistry.getTargetContext(), "en");
|
||||||
Locale.setDefault(Locale.US);
|
Locale.setDefault(Locale.US);
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("GMT+01:00"));
|
TimeZone.setDefault(TimeZone.getTimeZone("GMT+01:00"));
|
||||||
|
|
||||||
@ -140,7 +151,7 @@ public class LocalMessageExtractorTest extends AndroidTestCase {
|
|||||||
MimeMessageHelper.setBody(message, multipart);
|
MimeMessageHelper.setBody(message, multipart);
|
||||||
|
|
||||||
// Extract text
|
// Extract text
|
||||||
ViewableContainer container = extractTextAndAttachments(getContext(), message);
|
ViewableContainer container = extractTextAndAttachments(InstrumentationRegistry.getTargetContext(), message);
|
||||||
|
|
||||||
String expectedText =
|
String expectedText =
|
||||||
bodyText +
|
bodyText +
|
||||||
|
@ -1894,9 +1894,15 @@ public class Account implements BaseAccount, StoreConfig {
|
|||||||
public void deleteCertificates() {
|
public void deleteCertificates() {
|
||||||
LocalKeyStore localKeyStore = LocalKeyStore.getInstance();
|
LocalKeyStore localKeyStore = LocalKeyStore.getInstance();
|
||||||
|
|
||||||
Uri uri = Uri.parse(getStoreUri());
|
String storeUri = getStoreUri();
|
||||||
|
if (storeUri != null) {
|
||||||
|
Uri uri = Uri.parse(storeUri);
|
||||||
localKeyStore.deleteCertificate(uri.getHost(), uri.getPort());
|
localKeyStore.deleteCertificate(uri.getHost(), uri.getPort());
|
||||||
uri = Uri.parse(getTransportUri());
|
}
|
||||||
|
String transportUri = getTransportUri();
|
||||||
|
if (transportUri != null) {
|
||||||
|
Uri uri = Uri.parse(transportUri);
|
||||||
localKeyStore.deleteCertificate(uri.getHost(), uri.getPort());
|
localKeyStore.deleteCertificate(uri.getHost(), uri.getPort());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -8,13 +8,12 @@ import android.app.FragmentTransaction;
|
|||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Process;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
@ -87,7 +86,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
|
|||||||
setContentView(R.layout.account_setup_check_settings);
|
setContentView(R.layout.account_setup_check_settings);
|
||||||
mMessageView = (TextView)findViewById(R.id.message);
|
mMessageView = (TextView)findViewById(R.id.message);
|
||||||
mProgressBar = (ProgressBar)findViewById(R.id.progress);
|
mProgressBar = (ProgressBar)findViewById(R.id.progress);
|
||||||
((Button)findViewById(R.id.cancel)).setOnClickListener(this);
|
findViewById(R.id.cancel).setOnClickListener(this);
|
||||||
|
|
||||||
setMessage(R.string.account_setup_check_settings_retr_info_msg);
|
setMessage(R.string.account_setup_check_settings_retr_info_msg);
|
||||||
mProgressBar.setIndeterminate(true);
|
mProgressBar.setIndeterminate(true);
|
||||||
@ -96,82 +95,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
|
|||||||
mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
|
mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
|
||||||
mDirection = (CheckDirection) getIntent().getSerializableExtra(EXTRA_CHECK_DIRECTION);
|
mDirection = (CheckDirection) getIntent().getSerializableExtra(EXTRA_CHECK_DIRECTION);
|
||||||
|
|
||||||
new Thread() {
|
new CheckAccountTask(mAccount).execute(mDirection);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
Store store = null;
|
|
||||||
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
|
||||||
try {
|
|
||||||
if (mDestroyed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mCanceled) {
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final MessagingController ctrl = MessagingController.getInstance(getApplication());
|
|
||||||
ctrl.clearCertificateErrorNotifications(AccountSetupCheckSettings.this,
|
|
||||||
mAccount, mDirection);
|
|
||||||
|
|
||||||
if (mDirection == CheckDirection.INCOMING) {
|
|
||||||
store = mAccount.getRemoteStore();
|
|
||||||
|
|
||||||
if (store instanceof WebDavStore) {
|
|
||||||
setMessage(R.string.account_setup_check_settings_authenticate);
|
|
||||||
} else {
|
|
||||||
setMessage(R.string.account_setup_check_settings_check_incoming_msg);
|
|
||||||
}
|
|
||||||
store.checkSettings();
|
|
||||||
|
|
||||||
if (store instanceof WebDavStore) {
|
|
||||||
setMessage(R.string.account_setup_check_settings_fetch);
|
|
||||||
}
|
|
||||||
MessagingController.getInstance(getApplication()).listFoldersSynchronous(mAccount, true, null);
|
|
||||||
MessagingController.getInstance(getApplication()).synchronizeMailbox(mAccount, mAccount.getInboxFolderName(), null, null);
|
|
||||||
}
|
|
||||||
if (mDestroyed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mCanceled) {
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mDirection == CheckDirection.OUTGOING) {
|
|
||||||
if (!(mAccount.getRemoteStore() instanceof WebDavStore)) {
|
|
||||||
setMessage(R.string.account_setup_check_settings_check_outgoing_msg);
|
|
||||||
}
|
|
||||||
Transport transport = Transport.getInstance(K9.app, mAccount);
|
|
||||||
transport.close();
|
|
||||||
transport.open();
|
|
||||||
transport.close();
|
|
||||||
}
|
|
||||||
if (mDestroyed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mCanceled) {
|
|
||||||
finish();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setResult(RESULT_OK);
|
|
||||||
finish();
|
|
||||||
} catch (final AuthenticationFailedException afe) {
|
|
||||||
Log.e(K9.LOG_TAG, "Error while testing settings", afe);
|
|
||||||
showErrorDialog(
|
|
||||||
R.string.account_setup_failed_dlg_auth_message_fmt,
|
|
||||||
afe.getMessage() == null ? "" : afe.getMessage());
|
|
||||||
} catch (final CertificateValidationException cve) {
|
|
||||||
handleCertificateValidationException(cve);
|
|
||||||
} catch (final Throwable t) {
|
|
||||||
Log.e(K9.LOG_TAG, "Error while testing settings", t);
|
|
||||||
showErrorDialog(
|
|
||||||
R.string.account_setup_failed_dlg_server_message_fmt,
|
|
||||||
(t.getMessage() == null ? "" : t.getMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleCertificateValidationException(CertificateValidationException cve) {
|
private void handleCertificateValidationException(CertificateValidationException cve) {
|
||||||
@ -199,15 +123,8 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setMessage(final int resId) {
|
private void setMessage(final int resId) {
|
||||||
mHandler.post(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
if (mDestroyed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mMessageView.setText(getString(resId));
|
mMessageView.setText(getString(resId));
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void acceptKeyDialog(final int msgResId, final CertificateValidationException ex) {
|
private void acceptKeyDialog(final int msgResId, final CertificateValidationException ex) {
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
@ -266,7 +183,7 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
|
|||||||
for (List<?> subjectAlternativeName : subjectAlternativeNames) {
|
for (List<?> subjectAlternativeName : subjectAlternativeNames) {
|
||||||
Integer type = (Integer)subjectAlternativeName.get(0);
|
Integer type = (Integer)subjectAlternativeName.get(0);
|
||||||
Object value = subjectAlternativeName.get(1);
|
Object value = subjectAlternativeName.get(1);
|
||||||
String name = "";
|
String name;
|
||||||
switch (type.intValue()) {
|
switch (type.intValue()) {
|
||||||
case 0:
|
case 0:
|
||||||
Log.w(K9.LOG_TAG, "SubjectAltName of type OtherName not supported.");
|
Log.w(K9.LOG_TAG, "SubjectAltName of type OtherName not supported.");
|
||||||
@ -473,4 +390,89 @@ public class AccountSetupCheckSettings extends K9Activity implements OnClickList
|
|||||||
default: return "";
|
default: return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CheckAccountTask extends AsyncTask<CheckDirection, Integer, Void> {
|
||||||
|
private final Account account;
|
||||||
|
|
||||||
|
CheckAccountTask(Account account) {
|
||||||
|
this.account = account;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(CheckDirection... params) {
|
||||||
|
final CheckDirection direction = params[0];
|
||||||
|
try {
|
||||||
|
if (mDestroyed) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (mCanceled) {
|
||||||
|
finish();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final MessagingController ctrl = MessagingController.getInstance(getApplication());
|
||||||
|
ctrl.clearCertificateErrorNotifications(AccountSetupCheckSettings.this,
|
||||||
|
account, direction);
|
||||||
|
|
||||||
|
if (direction == CheckDirection.INCOMING) {
|
||||||
|
Store store = account.getRemoteStore();
|
||||||
|
if (store instanceof WebDavStore) {
|
||||||
|
publishProgress(R.string.account_setup_check_settings_authenticate);
|
||||||
|
} else {
|
||||||
|
publishProgress(R.string.account_setup_check_settings_check_incoming_msg);
|
||||||
|
}
|
||||||
|
store.checkSettings();
|
||||||
|
|
||||||
|
if (store instanceof WebDavStore) {
|
||||||
|
publishProgress(R.string.account_setup_check_settings_fetch);
|
||||||
|
}
|
||||||
|
MessagingController.getInstance(getApplication()).listFoldersSynchronous(account, true, null);
|
||||||
|
MessagingController.getInstance(getApplication())
|
||||||
|
.synchronizeMailbox(account, account.getInboxFolderName(), null, null);
|
||||||
|
}
|
||||||
|
if (mDestroyed) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (mCanceled) {
|
||||||
|
finish();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (direction == CheckDirection.OUTGOING) {
|
||||||
|
if (!(account.getRemoteStore() instanceof WebDavStore)) {
|
||||||
|
publishProgress(R.string.account_setup_check_settings_check_outgoing_msg);
|
||||||
|
}
|
||||||
|
Transport transport = Transport.getInstance(K9.app, account);
|
||||||
|
transport.close();
|
||||||
|
transport.open();
|
||||||
|
transport.close();
|
||||||
|
}
|
||||||
|
if (mDestroyed) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (mCanceled) {
|
||||||
|
finish();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
setResult(RESULT_OK);
|
||||||
|
finish();
|
||||||
|
} catch (AuthenticationFailedException afe) {
|
||||||
|
Log.e(K9.LOG_TAG, "Error while testing settings", afe);
|
||||||
|
showErrorDialog(
|
||||||
|
R.string.account_setup_failed_dlg_auth_message_fmt,
|
||||||
|
afe.getMessage() == null ? "" : afe.getMessage());
|
||||||
|
} catch (CertificateValidationException cve) {
|
||||||
|
handleCertificateValidationException(cve);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Log.e(K9.LOG_TAG, "Error while testing settings", t);
|
||||||
|
showErrorDialog(
|
||||||
|
R.string.account_setup_failed_dlg_server_message_fmt,
|
||||||
|
(t.getMessage() == null ? "" : t.getMessage()));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onProgressUpdate(Integer... values) {
|
||||||
|
setMessage(values[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
54
k9mail/src/main/java/com/fsck/k9/helper/HtmlSanitizer.java
Normal file
54
k9mail/src/main/java/com/fsck/k9/helper/HtmlSanitizer.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
|
|
||||||
|
import org.htmlcleaner.CleanerProperties;
|
||||||
|
import org.htmlcleaner.HtmlCleaner;
|
||||||
|
import org.htmlcleaner.HtmlSerializer;
|
||||||
|
import org.htmlcleaner.SimpleHtmlSerializer;
|
||||||
|
import org.htmlcleaner.TagNode;
|
||||||
|
|
||||||
|
|
||||||
|
public class HtmlSanitizer {
|
||||||
|
private static final HtmlCleaner HTML_CLEANER;
|
||||||
|
private static final HtmlSerializer HTML_SERIALIZER;
|
||||||
|
|
||||||
|
static {
|
||||||
|
CleanerProperties properties = createCleanerProperties();
|
||||||
|
HTML_CLEANER = new HtmlCleaner(properties);
|
||||||
|
HTML_SERIALIZER = new SimpleHtmlSerializer(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private HtmlSanitizer() {}
|
||||||
|
|
||||||
|
public static String sanitize(String html) {
|
||||||
|
TagNode rootNode = HTML_CLEANER.clean(html);
|
||||||
|
|
||||||
|
removeMetaRefresh(rootNode);
|
||||||
|
|
||||||
|
return HTML_SERIALIZER.getAsString(rootNode, "UTF8");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CleanerProperties createCleanerProperties() {
|
||||||
|
CleanerProperties properties = new CleanerProperties();
|
||||||
|
|
||||||
|
// See http://htmlcleaner.sourceforge.net/parameters.php for descriptions
|
||||||
|
properties.setNamespacesAware(false);
|
||||||
|
properties.setAdvancedXmlEscape(false);
|
||||||
|
properties.setOmitXmlDeclaration(true);
|
||||||
|
properties.setOmitDoctypeDeclaration(false);
|
||||||
|
properties.setTranslateSpecialEntities(false);
|
||||||
|
properties.setRecognizeUnicodeChars(false);
|
||||||
|
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void removeMetaRefresh(TagNode rootNode) {
|
||||||
|
for (TagNode element : rootNode.getElementListByName("meta", true)) {
|
||||||
|
String httpEquiv = element.getAttributeByName("http-equiv");
|
||||||
|
if (httpEquiv != null && httpEquiv.trim().equalsIgnoreCase("refresh")) {
|
||||||
|
element.removeFromTree();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,8 @@ import android.widget.Toast;
|
|||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
import com.fsck.k9.R;
|
import com.fsck.k9.R;
|
||||||
import com.fsck.k9.helper.HtmlConverter;
|
import com.fsck.k9.helper.HtmlConverter;
|
||||||
|
import com.fsck.k9.helper.HtmlSanitizer;
|
||||||
|
|
||||||
|
|
||||||
public class MessageWebView extends RigidWebView {
|
public class MessageWebView extends RigidWebView {
|
||||||
|
|
||||||
@ -123,7 +125,9 @@ public class MessageWebView extends RigidWebView {
|
|||||||
}
|
}
|
||||||
content += HtmlConverter.cssStylePre();
|
content += HtmlConverter.cssStylePre();
|
||||||
content += "</head><body>" + text + "</body></html>";
|
content += "</head><body>" + text + "</body></html>";
|
||||||
loadDataWithBaseURL("http://", content, "text/html", "utf-8", null);
|
|
||||||
|
String sanitizedContent = HtmlSanitizer.sanitize(content);
|
||||||
|
loadDataWithBaseURL("http://", sanitizedContent, "text/html", "utf-8", null);
|
||||||
resumeTimers();
|
resumeTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +129,10 @@
|
|||||||
<incoming uri="imap+ssl+://imap.gmx.com" username="$email" />
|
<incoming uri="imap+ssl+://imap.gmx.com" username="$email" />
|
||||||
<outgoing uri="smtp+ssl+://mail.gmx.com" username="$email" />
|
<outgoing uri="smtp+ssl+://mail.gmx.com" username="$email" />
|
||||||
</provider>
|
</provider>
|
||||||
|
<provider id="zoho.com" label="Zoho Mail" domain="zoho.com">
|
||||||
|
<incoming uri="imap+ssl+://imap.zoho.com" username="$email" />
|
||||||
|
<outgoing uri="smtp+tls+://smtp.zoho.com" username="$email" />
|
||||||
|
</provider>
|
||||||
|
|
||||||
<!-- Yahoo! Mail Variants -->
|
<!-- Yahoo! Mail Variants -->
|
||||||
<provider id="yahoo" label="Yahoo" domain="yahoo.com">
|
<provider id="yahoo" label="Yahoo" domain="yahoo.com">
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
package com.fsck.k9.helper;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
public class HtmlSanitizerTest {
|
||||||
|
@Test
|
||||||
|
public void shouldRemoveMetaRefreshInHead() {
|
||||||
|
String html = "<html>" +
|
||||||
|
"<head><meta http-equiv=\"refresh\" content=\"1; URL=http://example.com/\"></head>" +
|
||||||
|
"<body>Message</body>" +
|
||||||
|
"</html>";
|
||||||
|
assertEquals("<html><head></head><body>Message</body></html>", HtmlSanitizer.sanitize(html));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRemoveMetaRefreshBetweenHeadAndBody() {
|
||||||
|
String html = "<html>" +
|
||||||
|
"<head></head><meta http-equiv=\"refresh\" content=\"1; URL=http://example.com/\">" +
|
||||||
|
"<body>Message</body>" +
|
||||||
|
"</html>";
|
||||||
|
assertEquals("<html><head></head><body>Message</body></html>", HtmlSanitizer.sanitize(html));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRemoveMetaRefreshInBody() {
|
||||||
|
String html = "<html>" +
|
||||||
|
"<head></head>" +
|
||||||
|
"<body><meta http-equiv=\"refresh\" content=\"1; URL=http://example.com/\">Message</body>" +
|
||||||
|
"</html>";
|
||||||
|
assertEquals("<html><head></head><body>Message</body></html>", HtmlSanitizer.sanitize(html));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRemoveMetaRefreshWithUpperCaseAttributeValue() {
|
||||||
|
String html = "<html>" +
|
||||||
|
"<head><meta http-equiv=\"REFRESH\" content=\"1; URL=http://example.com/\"></head>" +
|
||||||
|
"<body>Message</body>" +
|
||||||
|
"</html>";
|
||||||
|
assertEquals("<html><head></head><body>Message</body></html>", HtmlSanitizer.sanitize(html));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRemoveMetaRefreshWithMixedCaseAttributeValue() {
|
||||||
|
String html = "<html>" +
|
||||||
|
"<head><meta http-equiv=\"Refresh\" content=\"1; URL=http://example.com/\"></head>" +
|
||||||
|
"<body>Message</body>" +
|
||||||
|
"</html>";
|
||||||
|
assertEquals("<html><head></head><body>Message</body></html>", HtmlSanitizer.sanitize(html));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRemoveMetaRefreshWithoutQuotesAroundAttributeValue() {
|
||||||
|
String html = "<html>" +
|
||||||
|
"<head><meta http-equiv=refresh content=\"1; URL=http://example.com/\"></head>" +
|
||||||
|
"<body>Message</body>" +
|
||||||
|
"</html>";
|
||||||
|
assertEquals("<html><head></head><body>Message</body></html>", HtmlSanitizer.sanitize(html));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRemoveMetaRefreshWithSpacesInAttributeValue() {
|
||||||
|
String html = "<html>" +
|
||||||
|
"<head><meta http-equiv=\"refresh \" content=\"1; URL=http://example.com/\"></head>" +
|
||||||
|
"<body>Message</body>" +
|
||||||
|
"</html>";
|
||||||
|
assertEquals("<html><head></head><body>Message</body></html>", HtmlSanitizer.sanitize(html));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRemoveMultipleMetaRefreshTags() {
|
||||||
|
String html = "<html>" +
|
||||||
|
"<head><meta http-equiv=\"refresh\" content=\"1; URL=http://example.com/\"></head>" +
|
||||||
|
"<body><meta http-equiv=\"refresh\" content=\"1; URL=http://example.com/\">Message</body>" +
|
||||||
|
"</html>";
|
||||||
|
assertEquals("<html><head></head><body>Message</body></html>", HtmlSanitizer.sanitize(html));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRemoveMetaRefreshButKeepOtherMetaTags() {
|
||||||
|
String html = "<html>" +
|
||||||
|
"<head>" +
|
||||||
|
"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">" +
|
||||||
|
"<meta http-equiv=\"refresh\" content=\"1; URL=http://example.com/\">" +
|
||||||
|
"</head>" +
|
||||||
|
"<body>Message</body>" +
|
||||||
|
"</html>";
|
||||||
|
assertEquals("<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" /></head>" +
|
||||||
|
"<body>Message</body></html>", HtmlSanitizer.sanitize(html));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user