Use Account instead of URI to create transports
There's no need to create a URI just to rip in appart again. Additionally, to support additional changes (i.e. to use Mailbox instead of Folder in the MessageController), we need to store the actual Account. NOTE -- This change only affects IMAP and POP3. SMTP will come in a follow-on CL Change-Id: I400036a17271c99272fd9c603547dcd713b50b9d
This commit is contained in:
parent
ba7652cda0
commit
a50fc99b0c
|
@ -2788,6 +2788,19 @@ public abstract class EmailContent {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the login information. [0] is the username and [1] is the password. If
|
||||
* {@link #FLAG_AUTHENTICATE} is not set, {@code null} is returned.
|
||||
*/
|
||||
public String[] getLogin() {
|
||||
if ((mFlags & FLAG_AUTHENTICATE) != 0) {
|
||||
String trimUser = (mLogin != null) ? mLogin.trim() : "";
|
||||
String password = (mPassword != null) ? mPassword : "";
|
||||
return new String[] { trimUser, password };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the connection values of the auth structure per the given scheme, host and port.
|
||||
*/
|
||||
|
|
|
@ -13,10 +13,15 @@
|
|||
public *** newInstance(android.content.Context, java.lang.String);
|
||||
}
|
||||
|
||||
# TODO remove after converting Sender#instantiateSender() to use Account instead of URI
|
||||
-keepclasseswithmembers class * {
|
||||
public *** newInstance(java.lang.String, android.content.Context, com.android.email.mail.Store$PersistentDataCallbacks);
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
public *** newInstance(com.android.emailcommon.provider.EmailContent$Account, android.content.Context, com.android.email.mail.Store$PersistentDataCallbacks);
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class android.content.SharedPreferences$Editor {
|
||||
*** apply();
|
||||
}
|
||||
|
@ -144,7 +149,7 @@
|
|||
*** setTransport(com.android.email.mail.Transport);
|
||||
}
|
||||
|
||||
-keepclasseswithmembers class com.android.email.mail.store.ImapStore$ImapFolder {
|
||||
-keepclasseswithmembers class com.android.email.mail.store.ImapFolder {
|
||||
*** getMessages(int, int, com.android.emailcommon.mail.Folder$MessageRetrievalListener);
|
||||
*** getMessages(com.android.emailcommon.mail.Folder$MessageRetrievalListener);
|
||||
*** getMessages(java.lang.String[], com.android.emailcommon.mail.Folder$MessageRetrievalListener);
|
||||
|
|
|
@ -1006,7 +1006,7 @@ public class Controller {
|
|||
}
|
||||
|
||||
/**
|
||||
* Delete an account synchronously. Intended to be used only by unit tests.
|
||||
* Delete an account synchronously.
|
||||
*/
|
||||
public void deleteAccountSync(long accountId, Context context) {
|
||||
try {
|
||||
|
@ -1017,12 +1017,13 @@ public class Controller {
|
|||
return; // Already deleted?
|
||||
}
|
||||
|
||||
final String accountUri = account.getStoreUri(context);
|
||||
// Delete Remote store at first.
|
||||
if (!TextUtils.isEmpty(accountUri)) {
|
||||
Store.getInstance(accountUri, context, null).delete();
|
||||
try {
|
||||
// Delete Remote store at first.
|
||||
Store.getInstance(account, context, null).delete();
|
||||
// Remove the Store instance from cache.
|
||||
Store.removeInstance(accountUri);
|
||||
Store.removeInstance(account, context);
|
||||
} catch (MessagingException e) {
|
||||
Log.w(Logging.LOG_TAG, "Failed to delete store", e);
|
||||
}
|
||||
|
||||
Uri uri = ContentUris.withAppendedId(
|
||||
|
|
|
@ -253,7 +253,7 @@ public class MessagingController implements Runnable {
|
|||
// Step 1: Get remote folders, make a list, and add any local folders
|
||||
// that don't already exist.
|
||||
|
||||
Store store = Store.getInstance(account.getStoreUri(mContext), mContext, null);
|
||||
Store store = Store.getInstance(account, mContext, null);
|
||||
|
||||
Folder[] remoteFolders = store.getAllFolders();
|
||||
|
||||
|
@ -383,7 +383,7 @@ public class MessagingController implements Runnable {
|
|||
StoreSynchronizer.SyncResults results;
|
||||
|
||||
// Select generic sync or store-specific sync
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(mContext), mContext, null);
|
||||
Store remoteStore = Store.getInstance(account, mContext, null);
|
||||
StoreSynchronizer customSync = remoteStore.getMessageSynchronizer();
|
||||
if (customSync == null) {
|
||||
results = synchronizeMailboxGeneric(account, folder);
|
||||
|
@ -512,7 +512,7 @@ public class MessagingController implements Runnable {
|
|||
|
||||
// 2. Open the remote folder and create the remote folder if necessary
|
||||
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(mContext), mContext, null);
|
||||
Store remoteStore = Store.getInstance(account, mContext, null);
|
||||
Folder remoteFolder = remoteStore.getFolder(folder.mDisplayName);
|
||||
|
||||
/*
|
||||
|
@ -1130,7 +1130,7 @@ public class MessagingController implements Runnable {
|
|||
|
||||
// Load the remote store if it will be needed
|
||||
if (remoteStore == null && deleteFromTrash) {
|
||||
remoteStore = Store.getInstance(account.getStoreUri(mContext), mContext, null);
|
||||
remoteStore = Store.getInstance(account, mContext, null);
|
||||
}
|
||||
|
||||
// Dispatch here for specific change types
|
||||
|
@ -1202,7 +1202,7 @@ public class MessagingController implements Runnable {
|
|||
// Load the remote store if it will be needed
|
||||
if (remoteStore == null) {
|
||||
remoteStore =
|
||||
Store.getInstance(account.getStoreUri(mContext), mContext, null);
|
||||
Store.getInstance(account, mContext, null);
|
||||
}
|
||||
// Load the mailbox if it will be needed
|
||||
if (mailbox == null) {
|
||||
|
@ -1232,7 +1232,7 @@ public class MessagingController implements Runnable {
|
|||
// Load the remote store if it will be needed
|
||||
if (remoteStore == null) {
|
||||
remoteStore =
|
||||
Store.getInstance(account.getStoreUri(mContext), mContext, null);
|
||||
Store.getInstance(account, mContext, null);
|
||||
}
|
||||
// Load the mailbox if it will be needed
|
||||
if (mailbox == null) {
|
||||
|
@ -1319,7 +1319,7 @@ public class MessagingController implements Runnable {
|
|||
// Load the remote store if it will be needed
|
||||
if (remoteStore == null &&
|
||||
(changeMoveToTrash || changeRead || changeFlagged || changeMailbox)) {
|
||||
remoteStore = Store.getInstance(account.getStoreUri(mContext), mContext, null);
|
||||
remoteStore = Store.getInstance(account, mContext, null);
|
||||
}
|
||||
|
||||
// Dispatch here for specific change types
|
||||
|
@ -1829,7 +1829,7 @@ public class MessagingController implements Runnable {
|
|||
}
|
||||
|
||||
Store remoteStore =
|
||||
Store.getInstance(account.getStoreUri(mContext), mContext, null);
|
||||
Store.getInstance(account, mContext, null);
|
||||
Folder remoteFolder = remoteStore.getFolder(mailbox.mDisplayName);
|
||||
remoteFolder.open(OpenMode.READ_WRITE, null);
|
||||
|
||||
|
@ -1922,7 +1922,7 @@ public class MessagingController implements Runnable {
|
|||
}
|
||||
|
||||
Store remoteStore =
|
||||
Store.getInstance(account.getStoreUri(mContext), mContext, null);
|
||||
Store.getInstance(account, mContext, null);
|
||||
Folder remoteFolder = remoteStore.getFolder(mailbox.mDisplayName);
|
||||
remoteFolder.open(OpenMode.READ_WRITE, null);
|
||||
|
||||
|
@ -2020,7 +2020,7 @@ public class MessagingController implements Runnable {
|
|||
mListeners.sendPendingMessagesStarted(account.mId, -1);
|
||||
|
||||
Sender sender = Sender.getInstance(mContext, account.getSenderUri(mContext));
|
||||
Store remoteStore = Store.getInstance(account.getStoreUri(mContext), mContext, null);
|
||||
Store remoteStore = Store.getInstance(account, mContext, null);
|
||||
boolean requireMoveMessageToSentFolder = remoteStore.requireCopyMessageToSentFolder();
|
||||
ContentValues moveToSentValues = null;
|
||||
if (requireMoveMessageToSentFolder) {
|
||||
|
|
|
@ -390,7 +390,7 @@ public class AccountCheckSettingsFragment extends Fragment {
|
|||
|
||||
final Context mContext;
|
||||
final int mMode;
|
||||
final String mStoreUri;
|
||||
final Account mAccount;
|
||||
final String mStoreHost;
|
||||
final String mSenderUri;
|
||||
final String mCheckEmail;
|
||||
|
@ -404,7 +404,7 @@ public class AccountCheckSettingsFragment extends Fragment {
|
|||
public AccountCheckTask(int mode, Account checkAccount) {
|
||||
mContext = getActivity().getApplicationContext();
|
||||
mMode = mode;
|
||||
mStoreUri = checkAccount.getStoreUri(mContext);
|
||||
mAccount = checkAccount;
|
||||
mStoreHost = checkAccount.mHostAuthRecv.mAddress;
|
||||
mSenderUri = checkAccount.getSenderUri(mContext);
|
||||
mCheckEmail = checkAccount.mEmailAddress;
|
||||
|
@ -422,7 +422,7 @@ public class AccountCheckSettingsFragment extends Fragment {
|
|||
if (isCancelled()) return null;
|
||||
publishProgress(STATE_CHECK_AUTODISCOVER);
|
||||
Log.d(Logging.LOG_TAG, "Begin auto-discover for " + mCheckEmail);
|
||||
Store store = Store.getInstance(mStoreUri, mContext, null);
|
||||
Store store = Store.getInstance(mAccount, mContext, null);
|
||||
Bundle result = store.autoDiscover(mContext, mCheckEmail, mCheckPassword);
|
||||
// Result will be one of:
|
||||
// null: remote exception - proceed to manual setup
|
||||
|
@ -450,7 +450,7 @@ public class AccountCheckSettingsFragment extends Fragment {
|
|||
if (isCancelled()) return null;
|
||||
Log.d(Logging.LOG_TAG, "Begin check of incoming email settings");
|
||||
publishProgress(STATE_CHECK_INCOMING);
|
||||
Store store = Store.getInstance(mStoreUri, mContext, null);
|
||||
Store store = Store.getInstance(mAccount, mContext, null);
|
||||
Bundle bundle = store.checkSettings();
|
||||
int resultCode = MessagingException.UNSPECIFIED_EXCEPTION;
|
||||
if (bundle != null) {
|
||||
|
|
|
@ -613,7 +613,7 @@ public class AccountSettingsXL extends PreferenceActivity {
|
|||
*/
|
||||
public void onIncomingSettings(Account account) {
|
||||
try {
|
||||
Store store = Store.getInstance(account.getStoreUri(this), getApplication(), null);
|
||||
Store store = Store.getInstance(account, getApplication(), null);
|
||||
if (store != null) {
|
||||
Class<? extends android.app.Activity> setting = store.getSettingActivityClass();
|
||||
if (setting != null) {
|
||||
|
|
|
@ -21,12 +21,17 @@ import com.android.email.R;
|
|||
import com.android.emailcommon.Logging;
|
||||
import com.android.emailcommon.mail.Folder;
|
||||
import com.android.emailcommon.mail.MessagingException;
|
||||
import com.android.emailcommon.provider.EmailContent.Account;
|
||||
import com.android.emailcommon.provider.EmailContent.HostAuth;
|
||||
import com.android.emailcommon.utility.Utility;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -59,18 +64,20 @@ public abstract class Store {
|
|||
* should be returned on FetchProfile.Item.BODY_SANE requests.
|
||||
*/
|
||||
public static final int FETCH_BODY_SANE_SUGGESTED_SIZE = (50 * 1024);
|
||||
private static final HashMap<String, Store> sStores = new HashMap<String, Store>();
|
||||
@VisibleForTesting
|
||||
static final HashMap<String, Store> sStores = new HashMap<String, Store>();
|
||||
|
||||
/**
|
||||
* Static named constructor. It should be overrode by extending class.
|
||||
* Because this method will be called through reflection, it can not be protected.
|
||||
*/
|
||||
public static Store newInstance(String uri, Context context, PersistentDataCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
throw new MessagingException("Store.newInstance: Unknown scheme in " + uri);
|
||||
public static Store newInstance(Account account, Context context,
|
||||
PersistentDataCallbacks callbacks) throws MessagingException {
|
||||
throw new MessagingException("Store#newInstance: Unknown scheme in "
|
||||
+ account.mDisplayName);
|
||||
}
|
||||
|
||||
private static Store instantiateStore(String className, String uri, Context context,
|
||||
private static Store instantiateStore(String className, Account account, Context context,
|
||||
PersistentDataCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
Object o = null;
|
||||
|
@ -78,18 +85,19 @@ public abstract class Store {
|
|||
Class<?> c = Class.forName(className);
|
||||
// and invoke "newInstance" class method and instantiate store object.
|
||||
java.lang.reflect.Method m =
|
||||
c.getMethod("newInstance", String.class, Context.class,
|
||||
c.getMethod("newInstance", Account.class, Context.class,
|
||||
PersistentDataCallbacks.class);
|
||||
o = m.invoke(null, uri, context, callbacks);
|
||||
// TODO Do the stores _really need a context? Is there a way to not pass it along?
|
||||
o = m.invoke(null, account, context, callbacks);
|
||||
} catch (Exception e) {
|
||||
Log.d(Logging.LOG_TAG, String.format(
|
||||
"exception %s invoking %s.newInstance.(String, Context) method for %s",
|
||||
e.toString(), className, uri));
|
||||
throw new MessagingException("can not instantiate Store object for " + uri);
|
||||
"exception %s invoking method %s#newInstance(Account, Context) for %s",
|
||||
e.toString(), className, account.mDisplayName));
|
||||
throw new MessagingException("can not instantiate Store for " + account.mDisplayName);
|
||||
}
|
||||
if (!(o instanceof Store)) {
|
||||
throw new MessagingException(
|
||||
uri + ": " + className + " create incompatible object");
|
||||
account.mDisplayName + ": " + className + " create incompatible object");
|
||||
}
|
||||
return (Store) o;
|
||||
}
|
||||
|
@ -149,38 +157,54 @@ public abstract class Store {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get an instance of a mail store. The URI is parsed as a standard URI and
|
||||
* the scheme is used to determine which protocol will be used.
|
||||
*
|
||||
* Although the URI format is somewhat protocol-specific, we use the following
|
||||
* guidelines wherever possible:
|
||||
*
|
||||
* scheme [+ security [+]] :// username : password @ host [ / resource ]
|
||||
*
|
||||
* Typical schemes include imap, pop3, local, eas.
|
||||
* Typical security models include SSL or TLS.
|
||||
* A + after the security identifier indicates "required".
|
||||
* Gets a unique key for the given account.
|
||||
* @throws MessagingException If the account is not setup properly (i.e. there is no address
|
||||
* or login)
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static String getStoreKey(Context context, Account account) throws MessagingException {
|
||||
final StringBuffer key = new StringBuffer();
|
||||
final HostAuth recvAuth = account.getOrCreateHostAuthRecv(context);
|
||||
if (recvAuth.mAddress == null) {
|
||||
throw new MessagingException("Cannot find store for account " + account.mDisplayName);
|
||||
}
|
||||
final String address = recvAuth.mAddress.trim();
|
||||
if (TextUtils.isEmpty(address)) {
|
||||
throw new MessagingException("Cannot find store for account " + account.mDisplayName);
|
||||
}
|
||||
key.append(address);
|
||||
if (recvAuth.mLogin != null) {
|
||||
key.append(recvAuth.mLogin.trim());
|
||||
}
|
||||
return key.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of a mail store for the given account. The account must be valid (i.e. has
|
||||
* at least an incoming server name).
|
||||
*
|
||||
* Username, password, and host are as expected.
|
||||
* Resource is protocol specific. For example, IMAP uses it as the path prefix. EAS uses it
|
||||
* as the domain.
|
||||
*
|
||||
* @param uri The URI of the store.
|
||||
* @param account The account of the store.
|
||||
* @return an initialized store of the appropriate class
|
||||
* @throws MessagingException
|
||||
* @throws MessagingException If the store cannot be obtained or if the account is invalid.
|
||||
*/
|
||||
public synchronized static Store getInstance(String uri, Context context,
|
||||
public synchronized static Store getInstance(Account account, Context context,
|
||||
PersistentDataCallbacks callbacks) throws MessagingException {
|
||||
Store store = sStores.get(uri);
|
||||
String storeKey = getStoreKey(context, account);
|
||||
Store store = sStores.get(storeKey);
|
||||
if (store == null) {
|
||||
context = context.getApplicationContext();
|
||||
StoreInfo info = StoreInfo.getStoreInfo(uri, context);
|
||||
Context appContext = context.getApplicationContext();
|
||||
HostAuth recvAuth = account.getOrCreateHostAuthRecv(context);
|
||||
StoreInfo info = StoreInfo.getStoreInfo(recvAuth.mProtocol, context);
|
||||
if (info != null) {
|
||||
store = instantiateStore(info.mClassName, uri, context, callbacks);
|
||||
store = instantiateStore(info.mClassName, account, appContext, callbacks);
|
||||
}
|
||||
|
||||
if (store != null) {
|
||||
sStores.put(uri, store);
|
||||
sStores.put(storeKey, store);
|
||||
}
|
||||
} else {
|
||||
// update the callbacks, which may have been null at creation time.
|
||||
|
@ -188,21 +212,25 @@ public abstract class Store {
|
|||
}
|
||||
|
||||
if (store == null) {
|
||||
throw new MessagingException("Unable to locate an applicable Store for " + uri);
|
||||
throw new MessagingException("Cannot find store for account " + account.mDisplayName);
|
||||
}
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an instance of a mail store.
|
||||
* Delete the mail store associated with the given account. The account must be valid (i.e. has
|
||||
* at least an incoming server name).
|
||||
*
|
||||
* The store should have been notified already by calling delete(), and the caller should
|
||||
* also take responsibility for deleting the matching LocalStore, etc.
|
||||
* @param storeUri the store to be removed
|
||||
*
|
||||
* @throws MessagingException If the store cannot be removed or if the account is invalid.
|
||||
*/
|
||||
public synchronized static void removeInstance(String storeUri) {
|
||||
sStores.remove(storeUri);
|
||||
public synchronized static void removeInstance(Account account, Context context)
|
||||
throws MessagingException {
|
||||
final String storeKey = getStoreKey(context, account);
|
||||
sStores.remove(storeKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,27 +27,27 @@ import java.net.SocketException;
|
|||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* This interface defines a "transport", which is defined here as being one layer below the
|
||||
* specific wire protocols such as POP3, IMAP, or SMTP.
|
||||
*
|
||||
* This interface defines a "transport", which is defined here as being one layer below the
|
||||
* specific wire protocols such as POP3, IMAP, or SMTP.
|
||||
*
|
||||
* Practically speaking, it provides a definition of the common functionality between them
|
||||
* (dealing with sockets & streams, SSL, logging, and so forth), and provides a seam just below
|
||||
* the individual protocols to enable better testing.
|
||||
*
|
||||
*
|
||||
* The following features are supported and presumed to be common:
|
||||
*
|
||||
*
|
||||
* Interpretation of URI
|
||||
* Support for SSL and TLS wireline security
|
||||
*/
|
||||
public interface Transport {
|
||||
|
||||
|
||||
/**
|
||||
* Connection security options for transport that supports SSL and/or TLS
|
||||
*/
|
||||
public static final int CONNECTION_SECURITY_NONE = 0;
|
||||
public static final int CONNECTION_SECURITY_SSL = 1;
|
||||
public static final int CONNECTION_SECURITY_TLS = 2;
|
||||
|
||||
|
||||
/**
|
||||
* Get a new transport, using an existing one as a model. The new transport is configured as if
|
||||
* setUri() and setSecurity() have been called, but not opened or connected in any way.
|
||||
|
@ -57,27 +57,41 @@ public interface Transport {
|
|||
|
||||
/**
|
||||
* Set the Uri for the connection.
|
||||
*
|
||||
*
|
||||
* @param uri The Uri for the connection
|
||||
* @param defaultPort If the Uri does not include an explicit port, this value will be used.
|
||||
* @deprecated use the individual methods {@link #setHost(String)} and {@link #setPort(int)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void setUri(URI uri, int defaultPort);
|
||||
|
||||
|
||||
/**
|
||||
* @return Returns the host part of the Uri
|
||||
* Sets the host
|
||||
*/
|
||||
public void setHost(String host);
|
||||
|
||||
/**
|
||||
* Sets the port
|
||||
*/
|
||||
public void setPort(int port);
|
||||
|
||||
/**
|
||||
* Returns the host or {@code null} if none was specified.
|
||||
*/
|
||||
public String getHost();
|
||||
|
||||
|
||||
/**
|
||||
* @return Returns the port (either from the Uri or from the default)
|
||||
* Returns the port or {@code 0} if none was specified.
|
||||
*/
|
||||
public int getPort();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the user info parts of the Uri, if any were supplied. Typically, [0] is the user
|
||||
* Returns the user info parts of the Uri, if any were supplied. Typically, [0] is the user
|
||||
* and [1] is the password.
|
||||
* @return Returns the user info parts of the Uri. Null if none were supplied.
|
||||
* @deprecated do not use this method. user info parts should not be stored in the transport.
|
||||
*/
|
||||
@Deprecated
|
||||
public String[] getUserInfoParts();
|
||||
|
||||
/**
|
||||
|
@ -86,17 +100,17 @@ public interface Transport {
|
|||
* @param trustAllCertificates true to allow unverifiable certificates to be used
|
||||
*/
|
||||
public void setSecurity(int connectionSecurity, boolean trustAllCertificates);
|
||||
|
||||
|
||||
/**
|
||||
* @return Returns the desired security mode for this connection.
|
||||
*/
|
||||
public int getSecurity();
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the security mode indicates that SSL is possible
|
||||
*/
|
||||
public boolean canTrySslSecurity();
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the security mode indicates that TLS is possible
|
||||
*/
|
||||
|
@ -118,35 +132,35 @@ public interface Transport {
|
|||
* Attempts to open the connection using the supplied parameters, and using SSL if indicated.
|
||||
*/
|
||||
public void open() throws MessagingException, CertificateValidationException;
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to reopen the connection using TLS.
|
||||
*/
|
||||
public void reopenTls() throws MessagingException;
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the connection is open
|
||||
*/
|
||||
public boolean isOpen();
|
||||
|
||||
|
||||
/**
|
||||
* Closes the connection. Does not send any closure messages, simply closes the socket and the
|
||||
* associated streams. Best effort only. Catches all exceptions and always returns.
|
||||
*
|
||||
* associated streams. Best effort only. Catches all exceptions and always returns.
|
||||
*
|
||||
* MUST NOT throw any exceptions.
|
||||
*/
|
||||
public void close();
|
||||
|
||||
|
||||
/**
|
||||
* @return returns the active input stream
|
||||
*/
|
||||
public InputStream getInputStream();
|
||||
|
||||
|
||||
/**
|
||||
* @return returns the active output stream
|
||||
*/
|
||||
public OutputStream getOutputStream();
|
||||
|
||||
|
||||
/**
|
||||
* Write a single line to the server, and may generate a log entry (if enabled).
|
||||
* @param s The text to send to the server.
|
||||
|
@ -154,7 +168,7 @@ public interface Transport {
|
|||
* please pass a replacement string here (for logging). Most callers simply pass null,
|
||||
*/
|
||||
void writeLine(String s, String sensitiveReplacement) throws IOException;
|
||||
|
||||
|
||||
/**
|
||||
* Reads a single line from the server. Any delimiter characters will not be included in the
|
||||
* result. May generate a log entry, if enabled.
|
||||
|
|
|
@ -37,6 +37,8 @@ import com.android.emailcommon.mail.Flag;
|
|||
import com.android.emailcommon.mail.Folder;
|
||||
import com.android.emailcommon.mail.Message;
|
||||
import com.android.emailcommon.mail.MessagingException;
|
||||
import com.android.emailcommon.provider.EmailContent.Account;
|
||||
import com.android.emailcommon.provider.EmailContent.HostAuth;
|
||||
import com.android.emailcommon.service.EmailServiceProxy;
|
||||
import com.android.emailcommon.utility.Utility;
|
||||
import com.beetstra.jutf7.CharsetProvider;
|
||||
|
@ -51,8 +53,6 @@ import android.util.Log;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.MessageDigest;
|
||||
|
@ -130,66 +130,53 @@ public class ImapStore extends Store {
|
|||
/**
|
||||
* Static named constructor.
|
||||
*/
|
||||
public static Store newInstance(String uri, Context context, PersistentDataCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
return new ImapStore(context, uri);
|
||||
public static Store newInstance(Account account, Context context,
|
||||
PersistentDataCallbacks callbacks) throws MessagingException {
|
||||
return new ImapStore(context, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allowed formats for the Uri:
|
||||
* imap://user:password@server:port
|
||||
* imap+tls+://user:password@server:port
|
||||
* imap+tls+trustallcerts://user:password@server:port
|
||||
* imap+ssl+://user:password@server:port
|
||||
* imap+ssl+trustallcerts://user:password@server:port
|
||||
*
|
||||
* @param uriString the Uri containing information to configure this store
|
||||
* Creates a new store for the given account.
|
||||
*/
|
||||
private ImapStore(Context context, String uriString) throws MessagingException {
|
||||
private ImapStore(Context context, Account account) throws MessagingException {
|
||||
mContext = context;
|
||||
URI uri;
|
||||
try {
|
||||
uri = new URI(uriString);
|
||||
} catch (URISyntaxException use) {
|
||||
throw new MessagingException("Invalid ImapStore URI", use);
|
||||
}
|
||||
|
||||
String scheme = uri.getScheme();
|
||||
if (scheme == null || !scheme.startsWith(STORE_SCHEME_IMAP)) {
|
||||
HostAuth recvAuth = account.getOrCreateHostAuthRecv(context);
|
||||
if (recvAuth == null || !STORE_SCHEME_IMAP.equalsIgnoreCase(recvAuth.mProtocol)) {
|
||||
throw new MessagingException("Unsupported protocol");
|
||||
}
|
||||
// defaults, which can be changed by security modifiers
|
||||
int connectionSecurity = Transport.CONNECTION_SECURITY_NONE;
|
||||
int defaultPort = 143;
|
||||
// check for security modifiers and apply changes
|
||||
if (scheme.contains("+ssl")) {
|
||||
|
||||
// check for security flags and apply changes
|
||||
if ((recvAuth.mFlags & HostAuth.FLAG_SSL) != 0) {
|
||||
connectionSecurity = Transport.CONNECTION_SECURITY_SSL;
|
||||
defaultPort = 993;
|
||||
} else if (scheme.contains("+tls")) {
|
||||
} else if ((recvAuth.mFlags & HostAuth.FLAG_TLS) != 0) {
|
||||
connectionSecurity = Transport.CONNECTION_SECURITY_TLS;
|
||||
}
|
||||
boolean trustCertificates = scheme.contains(STORE_SECURITY_TRUST_CERTIFICATES);
|
||||
|
||||
boolean trustCertificates = ((recvAuth.mFlags & HostAuth.FLAG_TRUST_ALL) != 0);
|
||||
int port = defaultPort;
|
||||
if (recvAuth.mPort != HostAuth.PORT_UNKNOWN) {
|
||||
port = recvAuth.mPort;
|
||||
}
|
||||
mRootTransport = new MailTransport("IMAP");
|
||||
mRootTransport.setUri(uri, defaultPort);
|
||||
mRootTransport.setHost(recvAuth.mAddress);
|
||||
mRootTransport.setPort(port);
|
||||
mRootTransport.setSecurity(connectionSecurity, trustCertificates);
|
||||
|
||||
String[] userInfoParts = mRootTransport.getUserInfoParts();
|
||||
String[] userInfoParts = recvAuth.getLogin();
|
||||
if (userInfoParts != null) {
|
||||
mUsername = userInfoParts[0];
|
||||
if (userInfoParts.length > 1) {
|
||||
mPassword = userInfoParts[1];
|
||||
mPassword = userInfoParts[1];
|
||||
|
||||
// build the LOGIN string once (instead of over-and-over again.)
|
||||
// apply the quoting here around the built-up password
|
||||
mLoginPhrase = ImapConstants.LOGIN + " " + mUsername + " "
|
||||
+ ImapUtility.imapQuoted(mPassword);
|
||||
}
|
||||
}
|
||||
|
||||
if ((uri.getPath() != null) && (uri.getPath().length() > 0)) {
|
||||
mPathPrefix = uri.getPath().substring(1);
|
||||
// build the LOGIN string once (instead of over-and-over again.)
|
||||
// apply the quoting here around the built-up password
|
||||
mLoginPhrase = ImapConstants.LOGIN + " " + mUsername + " "
|
||||
+ ImapUtility.imapQuoted(mPassword);
|
||||
}
|
||||
mPathPrefix = recvAuth.mDomain;
|
||||
}
|
||||
|
||||
/* package */ Collection<ImapConnection> getConnectionPoolForTest() {
|
||||
|
|
|
@ -29,6 +29,8 @@ import com.android.emailcommon.mail.Folder;
|
|||
import com.android.emailcommon.mail.Message;
|
||||
import com.android.emailcommon.mail.MessagingException;
|
||||
import com.android.emailcommon.mail.Folder.OpenMode;
|
||||
import com.android.emailcommon.provider.EmailContent.Account;
|
||||
import com.android.emailcommon.provider.EmailContent.HostAuth;
|
||||
import com.android.emailcommon.service.EmailServiceProxy;
|
||||
import com.android.emailcommon.utility.LoggingInputStream;
|
||||
import com.android.emailcommon.utility.Utility;
|
||||
|
@ -39,8 +41,6 @@ import android.util.Log;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -86,54 +86,45 @@ public class Pop3Store extends Store {
|
|||
/**
|
||||
* Static named constructor.
|
||||
*/
|
||||
public static Store newInstance(String uri, Context context, PersistentDataCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
return new Pop3Store(uri);
|
||||
public static Store newInstance(Account account, Context context,
|
||||
PersistentDataCallbacks callbacks) throws MessagingException {
|
||||
return new Pop3Store(context, account);
|
||||
}
|
||||
|
||||
/**
|
||||
* pop3://user:password@server:port
|
||||
* pop3+tls+://user:password@server:port
|
||||
* pop3+tls+trustallcerts://user:password@server:port
|
||||
* pop3+ssl+://user:password@server:port
|
||||
* pop3+ssl+trustallcerts://user:password@server:port
|
||||
*
|
||||
* @param _uri
|
||||
* Creates a new store for the given account.
|
||||
*/
|
||||
private Pop3Store(String _uri) throws MessagingException {
|
||||
URI uri;
|
||||
try {
|
||||
uri = new URI(_uri);
|
||||
} catch (URISyntaxException use) {
|
||||
throw new MessagingException("Invalid Pop3Store URI", use);
|
||||
}
|
||||
|
||||
String scheme = uri.getScheme();
|
||||
if (scheme == null || !scheme.startsWith(STORE_SCHEME_POP3)) {
|
||||
private Pop3Store(Context context, Account account) throws MessagingException {
|
||||
HostAuth recvAuth = account.getOrCreateHostAuthRecv(context);
|
||||
if (recvAuth == null || !STORE_SCHEME_POP3.equalsIgnoreCase(recvAuth.mProtocol)) {
|
||||
throw new MessagingException("Unsupported protocol");
|
||||
}
|
||||
// defaults, which can be changed by security modifiers
|
||||
int connectionSecurity = Transport.CONNECTION_SECURITY_NONE;
|
||||
int defaultPort = 110;
|
||||
// check for security modifiers and apply changes
|
||||
if (scheme.contains("+ssl")) {
|
||||
|
||||
// check for security flags and apply changes
|
||||
if ((recvAuth.mFlags & HostAuth.FLAG_SSL) != 0) {
|
||||
connectionSecurity = Transport.CONNECTION_SECURITY_SSL;
|
||||
defaultPort = 995;
|
||||
} else if (scheme.contains("+tls")) {
|
||||
} else if ((recvAuth.mFlags & HostAuth.FLAG_TLS) != 0) {
|
||||
connectionSecurity = Transport.CONNECTION_SECURITY_TLS;
|
||||
}
|
||||
boolean trustCertificates = scheme.contains(STORE_SECURITY_TRUST_CERTIFICATES);
|
||||
boolean trustCertificates = ((recvAuth.mFlags & HostAuth.FLAG_TRUST_ALL) != 0);
|
||||
|
||||
int port = defaultPort;
|
||||
if (recvAuth.mPort != HostAuth.PORT_UNKNOWN) {
|
||||
port = recvAuth.mPort;
|
||||
}
|
||||
mTransport = new MailTransport("POP3");
|
||||
mTransport.setUri(uri, defaultPort);
|
||||
mTransport.setHost(recvAuth.mAddress);
|
||||
mTransport.setPort(port);
|
||||
mTransport.setSecurity(connectionSecurity, trustCertificates);
|
||||
|
||||
String[] userInfoParts = mTransport.getUserInfoParts();
|
||||
String[] userInfoParts = recvAuth.getLogin();
|
||||
if (userInfoParts != null) {
|
||||
mUsername = userInfoParts[0];
|
||||
if (userInfoParts.length > 1) {
|
||||
mPassword = userInfoParts[1];
|
||||
}
|
||||
mPassword = userInfoParts[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,7 +138,7 @@ public class Pop3Store extends Store {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Folder getFolder(String name) throws MessagingException {
|
||||
public Folder getFolder(String name) {
|
||||
Folder folder = mFolders.get(name);
|
||||
if (folder == null) {
|
||||
folder = new Pop3Folder(name);
|
||||
|
@ -157,7 +148,7 @@ public class Pop3Store extends Store {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Folder[] getAllFolders() throws MessagingException {
|
||||
public Folder[] getAllFolders() {
|
||||
return new Folder[] {
|
||||
getFolder("INBOX"),
|
||||
};
|
||||
|
@ -314,7 +305,7 @@ public class Pop3Store extends Store {
|
|||
}
|
||||
|
||||
@Override
|
||||
public OpenMode getMode() throws MessagingException {
|
||||
public OpenMode getMode() {
|
||||
return OpenMode.READ_WRITE;
|
||||
}
|
||||
|
||||
|
@ -348,12 +339,12 @@ public class Pop3Store extends Store {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean create(FolderType type) throws MessagingException {
|
||||
public boolean create(FolderType type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() throws MessagingException {
|
||||
public boolean exists() {
|
||||
return mName.equalsIgnoreCase("INBOX");
|
||||
}
|
||||
|
||||
|
@ -363,7 +354,7 @@ public class Pop3Store extends Store {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getUnreadMessageCount() throws MessagingException {
|
||||
public int getUnreadMessageCount() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -608,14 +599,15 @@ public class Pop3Store extends Store {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Message[] getMessages(MessageRetrievalListener listener) throws MessagingException {
|
||||
throw new UnsupportedOperationException("Pop3Folder.getMessage(MessageRetrievalListener)");
|
||||
public Message[] getMessages(MessageRetrievalListener listener) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Pop3Folder.getMessage(MessageRetrievalListener)");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message[] getMessages(String[] uids, MessageRetrievalListener listener)
|
||||
throws MessagingException {
|
||||
throw new UnsupportedOperationException("Pop3Folder.getMessage(MessageRetrievalListener)");
|
||||
public Message[] getMessages(String[] uids, MessageRetrievalListener listener) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Pop3Folder.getMessage(MessageRetrievalListener)");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -805,20 +797,20 @@ public class Pop3Store extends Store {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Flag[] getPermanentFlags() throws MessagingException {
|
||||
public Flag[] getPermanentFlags() {
|
||||
return PERMANENT_FLAGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendMessages(Message[] messages) throws MessagingException {
|
||||
public void appendMessages(Message[] messages) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(boolean recurse) throws MessagingException {
|
||||
public void delete(boolean recurse) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message[] expunge() throws MessagingException {
|
||||
public Message[] expunge() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -847,8 +839,7 @@ public class Pop3Store extends Store {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void copyMessages(Message[] msgs, Folder folder, MessageUpdateCallbacks callbacks)
|
||||
throws MessagingException {
|
||||
public void copyMessages(Message[] msgs, Folder folder, MessageUpdateCallbacks callbacks) {
|
||||
throw new UnsupportedOperationException("copyMessages is not supported in POP3");
|
||||
}
|
||||
|
||||
|
@ -859,7 +850,7 @@ public class Pop3Store extends Store {
|
|||
// (mMessageCount * 58) / (mThroughputKbS * 1024 / 8) * 1000;
|
||||
// }
|
||||
|
||||
private Pop3Capabilities getCapabilities() throws IOException, MessagingException {
|
||||
private Pop3Capabilities getCapabilities() throws IOException {
|
||||
Pop3Capabilities capabilities = new Pop3Capabilities();
|
||||
try {
|
||||
String response = executeSimpleCommand("CAPA");
|
||||
|
@ -945,13 +936,13 @@ public class Pop3Store extends Store {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Message createMessage(String uid) throws MessagingException {
|
||||
public Message createMessage(String uid) {
|
||||
return new Pop3Message(uid, this);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Pop3Message extends MimeMessage {
|
||||
public Pop3Message(String uid, Pop3Folder folder) throws MessagingException {
|
||||
public Pop3Message(String uid, Pop3Folder folder) {
|
||||
mUid = uid;
|
||||
mFolder = folder;
|
||||
mSize = -1;
|
||||
|
|
|
@ -98,6 +98,8 @@ public class MailTransport implements Transport {
|
|||
return newObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void setUri(URI uri, int defaultPort) {
|
||||
mHost = uri.getHost();
|
||||
|
||||
|
@ -109,13 +111,24 @@ public class MailTransport implements Transport {
|
|||
if (uri.getUserInfo() != null) {
|
||||
mUserInfoParts = uri.getUserInfo().split(":", 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String[] getUserInfoParts() {
|
||||
return mUserInfoParts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHost(String host) {
|
||||
mHost = host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPort(int port) {
|
||||
mPort = port;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return mHost;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import javax.net.ssl.SSLException;
|
|||
|
||||
/**
|
||||
* This class handles all of the protocol-level aspects of sending messages via SMTP.
|
||||
* TODO Remove dependence upon URI; there's no reason why we need it here
|
||||
*/
|
||||
public class SmtpSender extends Sender {
|
||||
|
||||
|
@ -65,6 +66,7 @@ public class SmtpSender extends Sender {
|
|||
*
|
||||
* @param uriString the Uri containing information to configure this sender
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private SmtpSender(Context context, String uriString) throws MessagingException {
|
||||
mContext = context;
|
||||
URI uri;
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
package com.android.email.mail;
|
||||
|
||||
import com.android.email.Email;
|
||||
import com.android.email.mail.Store.StoreInfo;
|
||||
import com.android.emailcommon.mail.MessagingException;
|
||||
import com.android.emailcommon.provider.EmailContent.Account;
|
||||
import com.android.emailcommon.provider.EmailContent.HostAuth;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.suitebuilder.annotation.MediumTest;
|
||||
|
@ -27,83 +30,100 @@ import android.test.suitebuilder.annotation.MediumTest;
|
|||
*/
|
||||
@MediumTest
|
||||
public class StoreTests extends AndroidTestCase {
|
||||
public void testGetStoreKey() throws MessagingException {
|
||||
HostAuth testAuth = new HostAuth();
|
||||
Account testAccount = new Account();
|
||||
String testKey;
|
||||
|
||||
/**
|
||||
* Test StoreInfo & Store lookup for POP accounts
|
||||
*/
|
||||
public void testStoreLookupPOP() throws MessagingException {
|
||||
final String storeUri = "pop3://user:password@server.com";
|
||||
Store.StoreInfo info = Store.StoreInfo.getStoreInfo(storeUri, getContext());
|
||||
|
||||
assertNotNull("storeInfo null", info);
|
||||
assertNotNull("scheme null", info.mScheme);
|
||||
assertNotNull("classname null", info.mClassName);
|
||||
assertFalse(info.mPushSupported);
|
||||
assertEquals(Email.VISIBLE_LIMIT_DEFAULT, info.mVisibleLimitDefault);
|
||||
assertEquals(Email.VISIBLE_LIMIT_INCREMENT, info.mVisibleLimitIncrement);
|
||||
|
||||
// This will throw MessagingException if the result would have been null
|
||||
Store store = Store.getInstance(storeUri, getContext(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test StoreInfo & Store lookup for IMAP accounts
|
||||
*/
|
||||
public void testStoreLookupIMAP() throws MessagingException {
|
||||
final String storeUri = "imap://user:password@server.com";
|
||||
Store.StoreInfo info = Store.StoreInfo.getStoreInfo(storeUri, getContext());
|
||||
|
||||
assertNotNull("storeInfo null", info);
|
||||
assertNotNull("scheme null", info.mScheme);
|
||||
assertNotNull("classname null", info.mClassName);
|
||||
assertFalse(info.mPushSupported);
|
||||
assertEquals(Email.VISIBLE_LIMIT_DEFAULT, info.mVisibleLimitDefault);
|
||||
assertEquals(Email.VISIBLE_LIMIT_INCREMENT, info.mVisibleLimitIncrement);
|
||||
|
||||
// This will throw MessagingException if the result would have been null
|
||||
Store store = Store.getInstance(storeUri, getContext(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test StoreInfo & Store lookup for EAS accounts
|
||||
* TODO: EAS store will probably require implementation of Store.PersistentDataCallbacks
|
||||
*/
|
||||
public void testStoreLookupEAS() throws MessagingException {
|
||||
final String storeUri = "eas://user:password@server.com";
|
||||
Store.StoreInfo info = Store.StoreInfo.getStoreInfo(storeUri, getContext());
|
||||
if (info != null) {
|
||||
assertNotNull("scheme null", info.mScheme);
|
||||
assertNotNull("classname null", info.mClassName);
|
||||
assertTrue(info.mPushSupported);
|
||||
assertEquals(-1, info.mVisibleLimitDefault);
|
||||
assertEquals(-1, info.mVisibleLimitIncrement);
|
||||
|
||||
// This will throw MessagingException if the result would have been null
|
||||
Store store = Store.getInstance(storeUri, getContext(), null);
|
||||
} else {
|
||||
try {
|
||||
Store store = Store.getInstance(storeUri, getContext(), null);
|
||||
fail("MessagingException expected when EAS not supported");
|
||||
} catch (MessagingException me) {
|
||||
// expected - fall through
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test StoreInfo & Store lookup for unknown accounts
|
||||
*/
|
||||
public void testStoreLookupUnknown() {
|
||||
final String storeUri = "bogus-scheme://user:password@server.com";
|
||||
Store.StoreInfo info = Store.StoreInfo.getStoreInfo(storeUri, getContext());
|
||||
assertNull(info);
|
||||
// Make sure to set the host auth; otherwise we create entries in the hostauth db
|
||||
testAccount.mHostAuthRecv = testAuth;
|
||||
|
||||
// No address defined; throws an exception
|
||||
try {
|
||||
Store store = Store.getInstance(storeUri, getContext(), null);
|
||||
fail("MessagingException expected from bogus URI scheme");
|
||||
} catch (MessagingException me) {
|
||||
// expected - fall through
|
||||
testKey = Store.getStoreKey(mContext, testAccount);
|
||||
fail("MesasginException not thrown for missing address");
|
||||
} catch (MessagingException expected) {
|
||||
}
|
||||
|
||||
// Empty address defined; throws an exception
|
||||
testAuth.mAddress = " \t ";
|
||||
try {
|
||||
testKey = Store.getStoreKey(mContext, testAccount);
|
||||
fail("MesasginException not thrown for empty address");
|
||||
} catch (MessagingException expected) {
|
||||
}
|
||||
|
||||
// Address defined, no login
|
||||
testAuth.mAddress = "a.valid.address.com";
|
||||
testKey = Store.getStoreKey(mContext, testAccount);
|
||||
assertEquals("a.valid.address.com", testKey);
|
||||
|
||||
// Address & login defined
|
||||
testAuth.mAddress = "address.org";
|
||||
testAuth.mLogin = "auser";
|
||||
testKey = Store.getStoreKey(mContext, testAccount);
|
||||
assertEquals("address.orgauser", testKey);
|
||||
}
|
||||
|
||||
public void testGetStoreInfo() {
|
||||
StoreInfo testInfo;
|
||||
|
||||
// POP3
|
||||
testInfo = Store.StoreInfo.getStoreInfo("pop3", mContext);
|
||||
assertNotNull(testInfo);
|
||||
assertNotNull(testInfo.mScheme);
|
||||
assertNotNull(testInfo.mClassName);
|
||||
assertFalse(testInfo.mPushSupported);
|
||||
assertEquals(Email.VISIBLE_LIMIT_DEFAULT, testInfo.mVisibleLimitDefault);
|
||||
assertEquals(Email.VISIBLE_LIMIT_INCREMENT, testInfo.mVisibleLimitIncrement);
|
||||
|
||||
// IMAP
|
||||
testInfo = Store.StoreInfo.getStoreInfo("imap", mContext);
|
||||
assertNotNull(testInfo);
|
||||
assertNotNull(testInfo.mScheme);
|
||||
assertNotNull(testInfo.mClassName);
|
||||
assertFalse(testInfo.mPushSupported);
|
||||
assertEquals(Email.VISIBLE_LIMIT_DEFAULT, testInfo.mVisibleLimitDefault);
|
||||
assertEquals(Email.VISIBLE_LIMIT_INCREMENT, testInfo.mVisibleLimitIncrement);
|
||||
|
||||
// Unknown
|
||||
testInfo = Store.StoreInfo.getStoreInfo("unknownscheme", mContext);
|
||||
assertNull(testInfo);
|
||||
}
|
||||
|
||||
public void testGetInstance() throws MessagingException {
|
||||
HostAuth testAuth = new HostAuth();
|
||||
Account testAccount = new Account();
|
||||
Store testStore;
|
||||
|
||||
// Make sure to set the host auth; otherwise we create entries in the hostauth db
|
||||
testAccount.mHostAuthRecv = testAuth;
|
||||
|
||||
// POP3
|
||||
testAuth.mAddress = "pop3.google.com";
|
||||
testAuth.mProtocol = "pop3";
|
||||
testStore = Store.getInstance(testAccount, getContext(), null);
|
||||
assertEquals(1, Store.sStores.size());
|
||||
assertSame(testStore, Store.sStores.get("pop3.google.com"));
|
||||
Store.sStores.clear();
|
||||
|
||||
// IMAP
|
||||
testAuth.mAddress = "imap.google.com";
|
||||
testAuth.mProtocol = "imap";
|
||||
testStore = Store.getInstance(testAccount, getContext(), null);
|
||||
assertEquals(1, Store.sStores.size());
|
||||
assertSame(testStore, Store.sStores.get("imap.google.com"));
|
||||
Store.sStores.clear();
|
||||
|
||||
// Unknown
|
||||
testAuth.mAddress = "unknown.google.com";
|
||||
testAuth.mProtocol = "unknown";
|
||||
try {
|
||||
testStore = Store.getInstance(testAccount, getContext(), null);
|
||||
fail("Store#getInstance() should have thrown an exception");
|
||||
} catch (MessagingException expected) {
|
||||
}
|
||||
assertEquals(0, Store.sStores.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,12 +41,15 @@ import com.android.emailcommon.mail.Message;
|
|||
import com.android.emailcommon.mail.Message.RecipientType;
|
||||
import com.android.emailcommon.mail.MessagingException;
|
||||
import com.android.emailcommon.mail.Part;
|
||||
import com.android.emailcommon.provider.EmailContent.Account;
|
||||
import com.android.emailcommon.provider.EmailContent.HostAuth;
|
||||
import com.android.emailcommon.utility.Utility;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.MoreAsserts;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
|
@ -66,7 +69,7 @@ import java.util.regex.Pattern;
|
|||
* TODO test for BYE response in various places?
|
||||
*/
|
||||
@SmallTest
|
||||
public class ImapStoreUnitTests extends AndroidTestCase {
|
||||
public class ImapStoreUnitTests extends InstrumentationTestCase {
|
||||
private final static String[] NO_REPLY = new String[0];
|
||||
|
||||
/**
|
||||
|
@ -85,6 +88,7 @@ public class ImapStoreUnitTests extends AndroidTestCase {
|
|||
/* These values are provided by setUp() */
|
||||
private ImapStore mStore = null;
|
||||
private ImapFolder mFolder = null;
|
||||
private Context mTestContext;
|
||||
|
||||
private int mNextTag;
|
||||
// Fields specific to the CopyMessages tests
|
||||
|
@ -98,11 +102,18 @@ public class ImapStoreUnitTests extends AndroidTestCase {
|
|||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
TempDirectory.setTempDirectory(getContext());
|
||||
mTestContext = getInstrumentation().getContext();
|
||||
// Use the target's (i.e. the Email application) context
|
||||
TempDirectory.setTempDirectory(getInstrumentation().getTargetContext());
|
||||
|
||||
// These are needed so we can get at the inner classes
|
||||
mStore = (ImapStore) ImapStore.newInstance("imap://user:password@server:999",
|
||||
getContext(), null);
|
||||
HostAuth testAuth = new HostAuth();
|
||||
Account testAccount = new Account();
|
||||
|
||||
testAuth.setLogin("user", "password");
|
||||
testAuth.setConnection("imap", "server", 999);
|
||||
testAccount.mHostAuthRecv = testAuth;
|
||||
mStore = (ImapStore) ImapStore.newInstance(testAccount, mTestContext, null);
|
||||
mFolder = (ImapFolder) mStore.getFolder(FOLDER_NAME);
|
||||
mNextTag = 1;
|
||||
}
|
||||
|
@ -194,10 +205,10 @@ public class ImapStoreUnitTests extends AndroidTestCase {
|
|||
// x-android-device-model Model (Optional, so not tested here)
|
||||
// x-android-net-operator Carrier (Unreliable, so not tested here)
|
||||
// AGUID A device+account UID
|
||||
String id = ImapStore.getImapId(getContext(), "user-name", "host-name",
|
||||
String id = ImapStore.getImapId(mTestContext, "user-name", "host-name",
|
||||
CAPABILITY_RESPONSE.flatten());
|
||||
HashMap<String, String> map = tokenizeImapId(id);
|
||||
assertEquals(getContext().getPackageName(), map.get("name"));
|
||||
assertEquals(mTestContext.getPackageName(), map.get("name"));
|
||||
assertEquals("android", map.get("os"));
|
||||
assertNotNull(map.get("os-version"));
|
||||
assertNotNull(map.get("vendor"));
|
||||
|
@ -237,7 +248,7 @@ public class ImapStoreUnitTests extends AndroidTestCase {
|
|||
*/
|
||||
public void testImapIdWithVendorPolicy() {
|
||||
try {
|
||||
MockVendorPolicy.inject(getContext());
|
||||
MockVendorPolicy.inject(mTestContext);
|
||||
|
||||
// Prepare mock result
|
||||
Bundle result = new Bundle();
|
||||
|
@ -245,7 +256,7 @@ public class ImapStoreUnitTests extends AndroidTestCase {
|
|||
MockVendorPolicy.mockResult = result;
|
||||
|
||||
// Invoke
|
||||
String id = ImapStore.getImapId(getContext(), "user-name", "host-name",
|
||||
String id = ImapStore.getImapId(mTestContext, "user-name", "host-name",
|
||||
ImapTestUtils.parseResponse("* CAPABILITY IMAP4rev1 XXX YYY Z").flatten());
|
||||
|
||||
// Check the result
|
||||
|
@ -289,17 +300,37 @@ public class ImapStoreUnitTests extends AndroidTestCase {
|
|||
* Test that IMAP ID uid's are per-username
|
||||
*/
|
||||
public void testImapIdDeviceId() throws MessagingException {
|
||||
ImapStore store1a = (ImapStore) ImapStore.newInstance("imap://user1:password@server:999",
|
||||
getContext(), null);
|
||||
ImapStore store1b = (ImapStore) ImapStore.newInstance("imap://user1:password@server:999",
|
||||
getContext(), null);
|
||||
ImapStore store2 = (ImapStore) ImapStore.newInstance("imap://user2:password@server:999",
|
||||
getContext(), null);
|
||||
HostAuth testAuth;
|
||||
Account testAccount;
|
||||
|
||||
// store 1a
|
||||
testAuth = new HostAuth();
|
||||
testAuth.setLogin("user1", "password");
|
||||
testAuth.setConnection("imap", "server", 999);
|
||||
testAccount = new Account();
|
||||
testAccount.mHostAuthRecv = testAuth;
|
||||
ImapStore testStore1A = (ImapStore) ImapStore.newInstance(testAccount, mTestContext, null);
|
||||
|
||||
// store 1b
|
||||
testAuth = new HostAuth();
|
||||
testAuth.setLogin("user1", "password");
|
||||
testAuth.setConnection("imap", "server", 999);
|
||||
testAccount = new Account();
|
||||
testAccount.mHostAuthRecv = testAuth;
|
||||
ImapStore testStore1B = (ImapStore) ImapStore.newInstance(testAccount, mTestContext, null);
|
||||
|
||||
// store 2
|
||||
testAuth = new HostAuth();
|
||||
testAuth.setLogin("user2", "password");
|
||||
testAuth.setConnection("imap", "server", 999);
|
||||
testAccount = new Account();
|
||||
testAccount.mHostAuthRecv = testAuth;
|
||||
ImapStore testStore2 = (ImapStore) ImapStore.newInstance(testAccount, mTestContext, null);
|
||||
|
||||
String capabilities = CAPABILITY_RESPONSE.flatten();
|
||||
String id1a = ImapStore.getImapId(getContext(), "user1", "host-name", capabilities);
|
||||
String id1b = ImapStore.getImapId(getContext(), "user1", "host-name", capabilities);
|
||||
String id2 = ImapStore.getImapId(getContext(), "user2", "host-name", capabilities);
|
||||
String id1a = ImapStore.getImapId(mTestContext, "user1", "host-name", capabilities);
|
||||
String id1b = ImapStore.getImapId(mTestContext, "user1", "host-name", capabilities);
|
||||
String id2 = ImapStore.getImapId(mTestContext, "user2", "host-name", capabilities);
|
||||
|
||||
String uid1a = tokenizeImapId(id1a).get("AGUID");
|
||||
String uid1b = tokenizeImapId(id1b).get("AGUID");
|
||||
|
@ -412,7 +443,7 @@ public class ImapStoreUnitTests extends AndroidTestCase {
|
|||
public void testImapIdSecureServerNotSent() throws MessagingException {
|
||||
// Note, this is injected into mStore (which we don't use for this test)
|
||||
MockTransport mockTransport = openAndInjectMockTransport();
|
||||
mockTransport.setMockHost("eMail.sEcurEserVer.nEt");
|
||||
mockTransport.setHost("eMail.sEcurEserVer.nEt");
|
||||
|
||||
// Prime the expects pump as if the server wants IMAP ID, but we should not actually expect
|
||||
// to send it, because the login code in the store should never actually send it (to this
|
||||
|
@ -498,7 +529,7 @@ public class ImapStoreUnitTests extends AndroidTestCase {
|
|||
// Create mock transport and inject it into the ImapStore that's already set up
|
||||
MockTransport mockTransport = new MockTransport();
|
||||
mockTransport.setSecurity(connectionSecurity, trustAllCertificates);
|
||||
mockTransport.setMockHost("mock.server.com");
|
||||
mockTransport.setHost("mock.server.com");
|
||||
mStore.setTransport(mockTransport);
|
||||
return mockTransport;
|
||||
}
|
||||
|
|
|
@ -29,8 +29,10 @@ import com.android.emailcommon.mail.Folder.OpenMode;
|
|||
import com.android.emailcommon.mail.Message;
|
||||
import com.android.emailcommon.mail.Message.RecipientType;
|
||||
import com.android.emailcommon.mail.MessagingException;
|
||||
import com.android.emailcommon.provider.EmailContent.Account;
|
||||
import com.android.emailcommon.provider.EmailContent.HostAuth;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
/**
|
||||
|
@ -38,27 +40,33 @@ import android.test.suitebuilder.annotation.SmallTest;
|
|||
* complete - no server(s) required.
|
||||
*/
|
||||
@SmallTest
|
||||
public class Pop3StoreUnitTests extends AndroidTestCase {
|
||||
|
||||
public class Pop3StoreUnitTests extends InstrumentationTestCase {
|
||||
final String UNIQUE_ID_1 = "20080909002219r1800rrjo9e00";
|
||||
|
||||
|
||||
final static int PER_MESSAGE_SIZE = 100;
|
||||
|
||||
|
||||
/* These values are provided by setUp() */
|
||||
private Pop3Store mStore = null;
|
||||
private Pop3Store.Pop3Folder mFolder = null;
|
||||
|
||||
|
||||
/**
|
||||
* Setup code. We generate a lightweight Pop3Store and Pop3Store.Pop3Folder.
|
||||
*/
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
TempDirectory.setTempDirectory(getContext());
|
||||
// Use the target's (i.e. the Email application) context
|
||||
TempDirectory.setTempDirectory(getInstrumentation().getTargetContext());
|
||||
|
||||
// These are needed so we can get at the inner classes
|
||||
mStore = (Pop3Store) Pop3Store.newInstance("pop3://user:password@server:999",
|
||||
getContext(), null);
|
||||
HostAuth testAuth = new HostAuth();
|
||||
Account testAccount = new Account();
|
||||
|
||||
testAuth.setLogin("user", "password");
|
||||
testAuth.setConnection("pop3", "server", 999);
|
||||
testAccount.mHostAuthRecv = testAuth;
|
||||
mStore = (Pop3Store) Pop3Store.newInstance(
|
||||
testAccount, getInstrumentation().getContext(), null);
|
||||
mFolder = (Pop3Store.Pop3Folder) mStore.getFolder("INBOX");
|
||||
}
|
||||
|
||||
|
@ -69,24 +77,24 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
|
||||
// multi-line mode
|
||||
Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
|
||||
|
||||
|
||||
// Test basic in-list UIDL
|
||||
parser.parseMultiLine("101 " + UNIQUE_ID_1);
|
||||
assertEquals(101, parser.mMessageNumber);
|
||||
assertEquals(UNIQUE_ID_1, parser.mUniqueId);
|
||||
assertFalse(parser.mEndOfMessage);
|
||||
assertFalse(parser.mErr);
|
||||
|
||||
|
||||
// Test end-of-list
|
||||
parser.parseMultiLine(".");
|
||||
assertTrue(parser.mEndOfMessage);
|
||||
assertFalse(parser.mErr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test various sunny-day operations of UIDL parser for single-line responses
|
||||
*/
|
||||
public void testUIDLParserSingle() {
|
||||
public void testUIDLParserSingle() {
|
||||
|
||||
// single-line mode
|
||||
Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
|
||||
|
@ -96,12 +104,12 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
assertEquals(101, parser.mMessageNumber);
|
||||
assertEquals(UNIQUE_ID_1, parser.mUniqueId);
|
||||
assertTrue(parser.mEndOfMessage);
|
||||
|
||||
|
||||
// Test single-message ERR response
|
||||
parser.parseSingleLine("-ERR what???");
|
||||
assertTrue(parser.mErr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test various rainy-day operations of the UIDL parser for multi-line responses
|
||||
* TODO other malformed responses
|
||||
|
@ -109,17 +117,17 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
public void testUIDLParserMultiFail() {
|
||||
// multi-line mode
|
||||
Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
|
||||
|
||||
|
||||
// Test with null input
|
||||
boolean result;
|
||||
result = parser.parseMultiLine(null);
|
||||
assertFalse(result);
|
||||
|
||||
|
||||
// Test with empty input
|
||||
result = parser.parseMultiLine("");
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test various rainy-day operations of the UIDL parser for single-line responses
|
||||
* TODO other malformed responses
|
||||
|
@ -127,25 +135,25 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
public void testUIDLParserSingleFail() {
|
||||
// single-line mode
|
||||
Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
|
||||
|
||||
|
||||
// Test with null input
|
||||
boolean result;
|
||||
result = parser.parseSingleLine(null);
|
||||
assertFalse(result);
|
||||
|
||||
|
||||
// Test with empty input
|
||||
result = parser.parseSingleLine("");
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests that variants on the RFC-specified formatting of UIDL work properly.
|
||||
*/
|
||||
public void testUIDLComcastVariant() {
|
||||
|
||||
|
||||
// multi-line mode
|
||||
Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
|
||||
|
||||
|
||||
// Comcast servers send multiple spaces in their darn UIDL strings.
|
||||
parser.parseMultiLine("101 " + UNIQUE_ID_1);
|
||||
assertEquals(101, parser.mMessageNumber);
|
||||
|
@ -153,19 +161,19 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
assertFalse(parser.mEndOfMessage);
|
||||
assertFalse(parser.mErr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Confirms simple non-SSL non-TLS login
|
||||
*/
|
||||
public void testSimpleLogin() throws MessagingException {
|
||||
|
||||
|
||||
MockTransport mockTransport = openAndInjectMockTransport();
|
||||
|
||||
|
||||
// try to open it
|
||||
setupOpenFolder(mockTransport, 0, null);
|
||||
mFolder.open(OpenMode.READ_ONLY, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO: Test with SSL negotiation (faked)
|
||||
* TODO: Test with SSL required but not supported
|
||||
|
@ -173,25 +181,25 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
* TODO: Test with TLS required but not supported
|
||||
* TODO: Test calling getMessageCount(), getMessages(), etc.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Test the operation of checkSettings(), which requires (a) a good open and (b) UIDL support.
|
||||
*/
|
||||
public void testCheckSettings() throws MessagingException {
|
||||
|
||||
MockTransport mockTransport = openAndInjectMockTransport();
|
||||
|
||||
|
||||
// scenario 1: CAPA returns -ERR, so we try UIDL explicitly
|
||||
setupOpenFolder(mockTransport, 0, null);
|
||||
setupUidlSequence(mockTransport, 1);
|
||||
mockTransport.expect("QUIT", "");
|
||||
mStore.checkSettings();
|
||||
|
||||
|
||||
// scenario 2: CAPA indicates UIDL, so we don't try UIDL
|
||||
setupOpenFolder(mockTransport, 0, "UIDL");
|
||||
mockTransport.expect("QUIT", "");
|
||||
mStore.checkSettings();
|
||||
|
||||
|
||||
// scenario 3: CAPA returns -ERR, and UIDL fails
|
||||
try {
|
||||
setupOpenFolder(mockTransport, 0, null);
|
||||
|
@ -238,8 +246,8 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
/**
|
||||
* Test small Store & Folder functions that manage folders & namespace
|
||||
*/
|
||||
public void testStoreFoldersFunctions() throws MessagingException {
|
||||
|
||||
public void testStoreFoldersFunctions() {
|
||||
|
||||
// getPersonalNamespaces() always returns INBOX folder
|
||||
Folder[] folders = mStore.getAllFolders();
|
||||
assertEquals(1, folders.length);
|
||||
|
@ -251,18 +259,18 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
assertEquals("INBOX", folderMixedCaseInbox.getName());
|
||||
Pop3Store.Pop3Folder folderNotInbox = mStore.new Pop3Folder("NOT-INBOX");
|
||||
assertEquals("NOT-INBOX", folderNotInbox.getName());
|
||||
|
||||
|
||||
// exists() true if name is INBOX
|
||||
assertTrue(mFolder.exists());
|
||||
assertTrue(folderMixedCaseInbox.exists());
|
||||
assertFalse(folderNotInbox.exists());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test small Folder functions that don't really do anything in Pop3
|
||||
*/
|
||||
public void testSmallFolderFunctions() throws MessagingException {
|
||||
|
||||
public void testSmallFolderFunctions() {
|
||||
|
||||
// getMode() returns OpenMode.READ_WRITE
|
||||
assertEquals(OpenMode.READ_WRITE, mFolder.getMode());
|
||||
|
||||
|
@ -274,7 +282,7 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
|
||||
// getUnreadMessageCount() always returns -1
|
||||
assertEquals(-1, mFolder.getUnreadMessageCount());
|
||||
|
||||
|
||||
// getMessages(MessageRetrievalListener listener) is unsupported
|
||||
try {
|
||||
mFolder.getMessages(null);
|
||||
|
@ -282,7 +290,7 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
} catch (UnsupportedOperationException e) {
|
||||
// expected - succeed
|
||||
}
|
||||
|
||||
|
||||
// getMessages(String[] uids, MessageRetrievalListener listener) is unsupported
|
||||
try {
|
||||
mFolder.getMessages(null, null);
|
||||
|
@ -290,22 +298,22 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
} catch (UnsupportedOperationException e) {
|
||||
// expected - succeed
|
||||
}
|
||||
|
||||
|
||||
// getPermanentFlags() returns { Flag.DELETED }
|
||||
Flag[] flags = mFolder.getPermanentFlags();
|
||||
assertEquals(1, flags.length);
|
||||
assertEquals(Flag.DELETED, flags[0]);
|
||||
|
||||
|
||||
// appendMessages(Message[] messages) does nothing
|
||||
mFolder.appendMessages(null);
|
||||
|
||||
|
||||
// delete(boolean recurse) does nothing
|
||||
// TODO - it should!
|
||||
mFolder.delete(false);
|
||||
|
||||
|
||||
// expunge() returns null
|
||||
assertNull(mFolder.expunge());
|
||||
|
||||
|
||||
// copyMessages() is unsupported
|
||||
try {
|
||||
mFolder.copyMessages(null, null, null);
|
||||
|
@ -314,14 +322,14 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
// expected - succeed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lightweight test to confirm that POP3 hasn't implemented any folder roles yet.
|
||||
*/
|
||||
public void testNoFolderRolesYet() throws MessagingException {
|
||||
public void testNoFolderRolesYet() {
|
||||
Folder[] remoteFolders = mStore.getAllFolders();
|
||||
for (Folder folder : remoteFolders) {
|
||||
assertEquals(Folder.FolderRole.UNKNOWN, folder.getRole());
|
||||
assertEquals(Folder.FolderRole.UNKNOWN, folder.getRole());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,26 +337,26 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
* Lightweight test to confirm that POP3 isn't requesting structure prefetch.
|
||||
*/
|
||||
public void testNoStructurePrefetch() {
|
||||
assertFalse(mStore.requireStructurePrefetch());
|
||||
assertFalse(mStore.requireStructurePrefetch());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lightweight test to confirm that POP3 is requesting sent-message-upload.
|
||||
*/
|
||||
public void testSentUploadRequested() {
|
||||
assertTrue(mStore.requireCopyMessageToSentFolder());
|
||||
assertTrue(mStore.requireCopyMessageToSentFolder());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the process of opening and indexing a mailbox with one unread message in it.
|
||||
*
|
||||
*
|
||||
* TODO should create an instrumented listener to confirm all expected callbacks. Then use
|
||||
* it everywhere we could have passed a message listener.
|
||||
*/
|
||||
public void testOneUnread() throws MessagingException {
|
||||
|
||||
|
||||
MockTransport mockTransport = openAndInjectMockTransport();
|
||||
|
||||
|
||||
checkOneUnread(mockTransport);
|
||||
}
|
||||
|
||||
|
@ -356,9 +364,9 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
* Test the process of opening and getting message by uid.
|
||||
*/
|
||||
public void testGetMessageByUid() throws MessagingException {
|
||||
|
||||
|
||||
MockTransport mockTransport = openAndInjectMockTransport();
|
||||
|
||||
|
||||
setupOpenFolder(mockTransport, 2, null);
|
||||
mFolder.open(OpenMode.READ_WRITE, null);
|
||||
// check message count
|
||||
|
@ -369,7 +377,7 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
String uid1 = getSingleMessageUID(1);
|
||||
String uid2 = getSingleMessageUID(2);
|
||||
String uid3 = getSingleMessageUID(3);
|
||||
|
||||
|
||||
Message msg1 = mFolder.getMessage(uid1);
|
||||
assertTrue("message with uid1", msg1 != null);
|
||||
|
||||
|
@ -385,11 +393,11 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
* Test the scenario where the transport is "open" but not really (e.g. server closed). Two
|
||||
* things should happen: We should see an intermediate failure that makes sense, and the next
|
||||
* operation should reopen properly.
|
||||
*
|
||||
*
|
||||
* There are multiple versions of this test because we are simulating the steps of
|
||||
* MessagingController.synchronizeMailboxSyncronous() and we will inject the failure a bit
|
||||
* further along in each case, to test various recovery points.
|
||||
*
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the IOExceptionHandler in
|
||||
* Pop3Folder.getMessages(), due to a closure before the UIDL command completes.
|
||||
*/
|
||||
|
@ -428,11 +436,11 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
* Test the scenario where the transport is "open" but not really (e.g. server closed). Two
|
||||
* things should happen: We should see an intermediate failure that makes sense, and the next
|
||||
* operation should reopen properly.
|
||||
*
|
||||
*
|
||||
* There are multiple versions of this test because we are simulating the steps of
|
||||
* MessagingController.synchronizeMailboxSyncronous() and we will inject the failure a bit
|
||||
* further along in each case, to test various recovery points.
|
||||
*
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the IOExceptionHandler in
|
||||
* Pop3Folder.getMessages(), due to non-numeric data in a multi-line UIDL.
|
||||
*/
|
||||
|
@ -470,11 +478,11 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
* Test the scenario where the transport is "open" but not really (e.g. server closed). Two
|
||||
* things should happen: We should see an intermediate failure that makes sense, and the next
|
||||
* operation should reopen properly.
|
||||
*
|
||||
*
|
||||
* There are multiple versions of this test because we are simulating the steps of
|
||||
* MessagingController.synchronizeMailboxSyncronous() and we will inject the failure a bit
|
||||
* further along in each case, to test various recovery points.
|
||||
*
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the IOExceptionHandler in
|
||||
* Pop3Folder.getMessages(), due to non-numeric data in a single-line UIDL.
|
||||
*/
|
||||
|
@ -513,29 +521,29 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
* Test the scenario where the transport is "open" but not really (e.g. server closed). Two
|
||||
* things should happen: We should see an intermediate failure that makes sense, and the next
|
||||
* operation should reopen properly.
|
||||
*
|
||||
* There are multiple versions of this test because we are simulating the steps of
|
||||
*
|
||||
* There are multiple versions of this test because we are simulating the steps of
|
||||
* MessagingController.synchronizeMailboxSyncronous() and we will inject the failure a bit
|
||||
* further along in each case, to test various recovery points.
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the first IOExceptionHandler in
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the first IOExceptionHandler in
|
||||
* Pop3Folder.fetch(), for a failure in the call to indexUids().
|
||||
*/
|
||||
public void testCatchClosed2() throws MessagingException {
|
||||
|
||||
|
||||
MockTransport mockTransport = openAndInjectMockTransport();
|
||||
|
||||
|
||||
openFolderWithMessage(mockTransport);
|
||||
|
||||
|
||||
// index the message(s)
|
||||
setupUidlSequence(mockTransport, 1);
|
||||
Message[] messages = mFolder.getMessages(1, 1, null);
|
||||
assertEquals(1, messages.length);
|
||||
assertEquals(getSingleMessageUID(1), messages[0].getUid());
|
||||
|
||||
assertEquals(getSingleMessageUID(1), messages[0].getUid());
|
||||
|
||||
// cause the next sequence to fail on the readLine() calls
|
||||
mockTransport.closeInputStream();
|
||||
|
||||
|
||||
try {
|
||||
// try the basic fetch of flags & envelope
|
||||
setupListSequence(mockTransport, 1);
|
||||
|
@ -553,36 +561,36 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
// At this point the UI would display connection error, which is fine. Now, the real
|
||||
// test is, can we recover? So I'll just repeat the above steps, without the failure.
|
||||
// NOTE: everything from here down is copied from testOneUnread() and should be consolidated
|
||||
|
||||
|
||||
// confirm that we're closed at this point
|
||||
assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
|
||||
|
||||
|
||||
// and confirm that the next connection will be OK
|
||||
checkOneUnread(mockTransport);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the scenario where the transport is "open" but not really (e.g. server closed). Two
|
||||
* things should happen: We should see an intermediate failure that makes sense, and the next
|
||||
* operation should reopen properly.
|
||||
*
|
||||
*
|
||||
* There are multiple versions of this test because we have to check additional places where
|
||||
* Pop3Store and/or Pop3Folder should be dealing with IOErrors.
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the first IOExceptionHandler in
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the first IOExceptionHandler in
|
||||
* Pop3Folder.fetch(), for a failure in the call to fetchEnvelope().
|
||||
*/
|
||||
public void testCatchClosed2a() throws MessagingException {
|
||||
|
||||
|
||||
MockTransport mockTransport = openAndInjectMockTransport();
|
||||
|
||||
|
||||
openFolderWithMessage(mockTransport);
|
||||
|
||||
|
||||
// index the message(s)
|
||||
setupUidlSequence(mockTransport, 1);
|
||||
Message[] messages = mFolder.getMessages(1, 1, null);
|
||||
assertEquals(1, messages.length);
|
||||
assertEquals(getSingleMessageUID(1), messages[0].getUid());
|
||||
assertEquals(getSingleMessageUID(1), messages[0].getUid());
|
||||
|
||||
// try the basic fetch of flags & envelope, but the LIST command fails
|
||||
setupBrokenListSequence(mockTransport, 1);
|
||||
|
@ -600,37 +608,37 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
// At this point the UI would display connection error, which is fine. Now, the real
|
||||
// test is, can we recover? So I'll just repeat the above steps, without the failure.
|
||||
// NOTE: everything from here down is copied from testOneUnread() and should be consolidated
|
||||
|
||||
|
||||
// confirm that we're closed at this point
|
||||
assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
|
||||
|
||||
|
||||
// and confirm that the next connection will be OK
|
||||
checkOneUnread(mockTransport);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the scenario where the transport is "open" but not really (e.g. server closed). Two
|
||||
* things should happen: We should see an intermediate failure that makes sense, and the next
|
||||
* operation should reopen properly.
|
||||
*
|
||||
* There are multiple versions of this test because we are simulating the steps of
|
||||
*
|
||||
* There are multiple versions of this test because we are simulating the steps of
|
||||
* MessagingController.synchronizeMailboxSyncronous() and we will inject the failure a bit
|
||||
* further along in each case, to test various recovery points.
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the second IOExceptionHandler in
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the second IOExceptionHandler in
|
||||
* Pop3Folder.fetch().
|
||||
*/
|
||||
public void testCatchClosed3() throws MessagingException {
|
||||
|
||||
|
||||
MockTransport mockTransport = openAndInjectMockTransport();
|
||||
|
||||
|
||||
openFolderWithMessage(mockTransport);
|
||||
|
||||
|
||||
// index the message(s)
|
||||
setupUidlSequence(mockTransport, 1);
|
||||
Message[] messages = mFolder.getMessages(1, 1, null);
|
||||
assertEquals(1, messages.length);
|
||||
assertEquals(getSingleMessageUID(1), messages[0].getUid());
|
||||
assertEquals(getSingleMessageUID(1), messages[0].getUid());
|
||||
|
||||
// try the basic fetch of flags & envelope
|
||||
setupListSequence(mockTransport, 1);
|
||||
|
@ -659,37 +667,37 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
// At this point the UI would display connection error, which is fine. Now, the real
|
||||
// test is, can we recover? So I'll just repeat the above steps, without the failure.
|
||||
// NOTE: everything from here down is copied from testOneUnread() and should be consolidated
|
||||
|
||||
|
||||
// confirm that we're closed at this point
|
||||
assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
|
||||
|
||||
|
||||
// and confirm that the next connection will be OK
|
||||
checkOneUnread(mockTransport);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the scenario where the transport is "open" but not really (e.g. server closed). Two
|
||||
* things should happen: We should see an intermediate failure that makes sense, and the next
|
||||
* operation should reopen properly.
|
||||
*
|
||||
*
|
||||
* There are multiple versions of this test because we have to check additional places where
|
||||
* Pop3Store and/or Pop3Folder should be dealing with IOErrors.
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the IOExceptionHandler in
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the IOExceptionHandler in
|
||||
* Pop3Folder.setFlags().
|
||||
*/
|
||||
public void testCatchClosed4() throws MessagingException {
|
||||
|
||||
|
||||
MockTransport mockTransport = openAndInjectMockTransport();
|
||||
|
||||
|
||||
openFolderWithMessage(mockTransport);
|
||||
|
||||
|
||||
// index the message(s)
|
||||
setupUidlSequence(mockTransport, 1);
|
||||
Message[] messages = mFolder.getMessages(1, 1, null);
|
||||
assertEquals(1, messages.length);
|
||||
assertEquals(getSingleMessageUID(1), messages[0].getUid());
|
||||
|
||||
|
||||
// cause the next sequence to fail on the readLine() calls
|
||||
mockTransport.closeInputStream();
|
||||
|
||||
|
@ -706,44 +714,44 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
// At this point the UI would display connection error, which is fine. Now, the real
|
||||
// test is, can we recover? So I'll just repeat the above steps, without the failure.
|
||||
// NOTE: everything from here down is copied from testOneUnread() and should be consolidated
|
||||
|
||||
|
||||
// confirm that we're closed at this point
|
||||
assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
|
||||
|
||||
|
||||
// and confirm that the next connection will be OK
|
||||
checkOneUnread(mockTransport);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the scenario where the transport is "open" but not really (e.g. server closed). Two
|
||||
* things should happen: We should see an intermediate failure that makes sense, and the next
|
||||
* operation should reopen properly.
|
||||
*
|
||||
*
|
||||
* There are multiple versions of this test because we have to check additional places where
|
||||
* Pop3Store and/or Pop3Folder should be dealing with IOErrors.
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the first IOExceptionHandler in
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the first IOExceptionHandler in
|
||||
* Pop3Folder.open().
|
||||
*/
|
||||
public void testCatchClosed5() {
|
||||
// TODO cannot write this test until we can inject stream closures mid-sequence
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the scenario where the transport is "open" but not really (e.g. server closed). Two
|
||||
* things should happen: We should see an intermediate failure that makes sense, and the next
|
||||
* operation should reopen properly.
|
||||
*
|
||||
*
|
||||
* There are multiple versions of this test because we have to check additional places where
|
||||
* Pop3Store and/or Pop3Folder should be dealing with IOErrors.
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the second IOExceptionHandler in
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the second IOExceptionHandler in
|
||||
* Pop3Folder.open() (when it calls STAT and the response is empty of garbagey).
|
||||
*/
|
||||
public void testCatchClosed6a() throws MessagingException {
|
||||
|
||||
|
||||
MockTransport mockTransport = openAndInjectMockTransport();
|
||||
|
||||
|
||||
// like openFolderWithMessage(mockTransport) but with a broken STAT report (empty response)
|
||||
setupOpenFolder(mockTransport, -1, null);
|
||||
try {
|
||||
|
@ -752,48 +760,48 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
} catch(MessagingException me) {
|
||||
// success
|
||||
}
|
||||
|
||||
|
||||
// At this point the UI would display connection error, which is fine. Now, the real
|
||||
// test is, can we recover? So I'll try a new connection, without the failure.
|
||||
|
||||
|
||||
// confirm that we're closed at this point
|
||||
assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
|
||||
|
||||
|
||||
// and confirm that the next connection will be OK
|
||||
checkOneUnread(mockTransport);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test the scenario where the transport is "open" but not really (e.g. server closed). Two
|
||||
* things should happen: We should see an intermediate failure that makes sense, and the next
|
||||
* operation should reopen properly.
|
||||
*
|
||||
*
|
||||
* There are multiple versions of this test because we have to check additional places where
|
||||
* Pop3Store and/or Pop3Folder should be dealing with IOErrors.
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the second IOExceptionHandler in
|
||||
*
|
||||
* This test confirms that Pop3Store needs to call close() in the second IOExceptionHandler in
|
||||
* Pop3Folder.open() (when it calls STAT, and there is no response at all).
|
||||
*/
|
||||
public void testCatchClosed6b() throws MessagingException {
|
||||
public void testCatchClosed6b() {
|
||||
// TODO cannot write this test until we can inject stream closures mid-sequence
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given an initialized mock transport, open it and attempt to "read" one unread message from
|
||||
* Given an initialized mock transport, open it and attempt to "read" one unread message from
|
||||
* it. This can be used as a basic test of functionality and it should be possible to call this
|
||||
* repeatedly (if you close the folder between calls).
|
||||
*
|
||||
*
|
||||
* @param mockTransport the mock transport we're using
|
||||
*/
|
||||
private void checkOneUnread(MockTransport mockTransport) throws MessagingException {
|
||||
openFolderWithMessage(mockTransport);
|
||||
|
||||
|
||||
// index the message(s)
|
||||
setupUidlSequence(mockTransport, 1);
|
||||
Message[] messages = mFolder.getMessages(1, 1, null);
|
||||
assertEquals(1, messages.length);
|
||||
assertEquals(getSingleMessageUID(1), messages[0].getUid());
|
||||
|
||||
|
||||
// try the basic fetch of flags & envelope
|
||||
setupListSequence(mockTransport, 1);
|
||||
FetchProfile fp = new FetchProfile();
|
||||
|
@ -801,8 +809,8 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
fp.add(FetchProfile.Item.ENVELOPE);
|
||||
mFolder.fetch(messages, fp, null);
|
||||
assertEquals(PER_MESSAGE_SIZE, messages[0].getSize());
|
||||
|
||||
// A side effect of how messages work is that if you get fields that are empty,
|
||||
|
||||
// A side effect of how messages work is that if you get fields that are empty,
|
||||
// then empty arrays are written back into the parsed header fields (e.g. mTo, mFrom). The
|
||||
// standard message parser needs to clear these before parsing. Make sure that this
|
||||
// is happening. (This doesn't affect IMAP, which reads the headers directly via
|
||||
|
@ -841,7 +849,7 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
fp.add(FetchProfile.Item.ENVELOPE);
|
||||
mFolder.fetch(messages, fp, null);
|
||||
|
||||
// A side effect of how messages work is that if you get fields that are empty,
|
||||
// A side effect of how messages work is that if you get fields that are empty,
|
||||
// then empty arrays are written back into the parsed header fields (e.g. mTo, mFrom). The
|
||||
// standard message parser needs to clear these before parsing. Make sure that this
|
||||
// is happening. (This doesn't affect IMAP, which reads the headers directly via
|
||||
|
@ -881,30 +889,30 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
mStore.setTransport(mockTransport);
|
||||
return mockTransport;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open a folder that's preloaded with one unread message.
|
||||
*
|
||||
*
|
||||
* @param mockTransport the mock transport we're using
|
||||
*/
|
||||
private void openFolderWithMessage(MockTransport mockTransport) throws MessagingException {
|
||||
// try to open it
|
||||
setupOpenFolder(mockTransport, 1, null);
|
||||
mFolder.open(OpenMode.READ_ONLY, null);
|
||||
|
||||
|
||||
// check message count
|
||||
assertEquals(1, mFolder.getMessageCount());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Look at a fetched message and confirm that it is complete.
|
||||
*
|
||||
*
|
||||
* TODO this needs to be more dynamic, not just hardcoded for empty message #1.
|
||||
*
|
||||
*
|
||||
* @param message the fetched message to be checked
|
||||
* @param msgNum the message number
|
||||
*/
|
||||
private void checkFetchedMessage(Message message, int msgNum, boolean body)
|
||||
private void checkFetchedMessage(Message message, int msgNum, boolean body)
|
||||
throws MessagingException {
|
||||
// check To:
|
||||
Address[] to = message.getRecipients(RecipientType.TO);
|
||||
|
@ -912,14 +920,14 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
assertEquals(1, to.length);
|
||||
assertEquals("Smith@Registry.Org", to[0].getAddress());
|
||||
assertNull(to[0].getPersonal());
|
||||
|
||||
|
||||
// check From:
|
||||
Address[] from = message.getFrom();
|
||||
assertNotNull(from);
|
||||
assertEquals(1, from.length);
|
||||
assertEquals("Jones@Registry.Org", from[0].getAddress());
|
||||
assertNull(from[0].getPersonal());
|
||||
|
||||
|
||||
// check Cc:
|
||||
Address[] cc = message.getRecipients(RecipientType.CC);
|
||||
assertNotNull(cc);
|
||||
|
@ -935,13 +943,13 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
assertNull(replyto[0].getPersonal());
|
||||
|
||||
// TODO date
|
||||
|
||||
|
||||
// TODO check body (if applicable)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper which stuffs the mock with enough strings to satisfy a call to Pop3Folder.open()
|
||||
*
|
||||
*
|
||||
* @param mockTransport the mock transport we're using
|
||||
* @param statCount the number of messages to indicate in the STAT, or -1 for broken STAT
|
||||
* @param capabilities if non-null, comma-separated list of capabilities
|
||||
|
@ -972,7 +980,7 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
* @param numMessages The number of messages to return from UIDL.
|
||||
*/
|
||||
private static void setupUidlSequence(MockTransport transport, int numMessages) {
|
||||
transport.expect("UIDL", "+OK sending UIDL list");
|
||||
transport.expect("UIDL", "+OK sending UIDL list");
|
||||
for (int msgNum = 1; msgNum <= numMessages; ++msgNum) {
|
||||
transport.expect(null, Integer.toString(msgNum) + " " + getSingleMessageUID(msgNum));
|
||||
}
|
||||
|
@ -985,9 +993,9 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
* @param numMessages The number of messages to return from LIST.
|
||||
*/
|
||||
private static void setupListSequence(MockTransport transport, int numMessages) {
|
||||
transport.expect("LIST", "+OK sending scan listing");
|
||||
transport.expect("LIST", "+OK sending scan listing");
|
||||
for (int msgNum = 1; msgNum <= numMessages; ++msgNum) {
|
||||
transport.expect(null, Integer.toString(msgNum) + " " +
|
||||
transport.expect(null, Integer.toString(msgNum) + " " +
|
||||
Integer.toString(PER_MESSAGE_SIZE * msgNum));
|
||||
}
|
||||
transport.expect(null, ".");
|
||||
|
@ -1009,16 +1017,16 @@ public class Pop3StoreUnitTests extends AndroidTestCase {
|
|||
|
||||
/**
|
||||
* Setup a single message to be retrieved.
|
||||
*
|
||||
*
|
||||
* Per RFC822 here is a minimal message header:
|
||||
* Date: 26 Aug 76 1429 EDT
|
||||
* From: Jones@Registry.Org
|
||||
* To: Smith@Registry.Org
|
||||
*
|
||||
*
|
||||
* We'll add the following fields to support additional tests:
|
||||
* Cc: Chris@Registry.Org
|
||||
* Reply-To: Roger@Registry.Org
|
||||
*
|
||||
*
|
||||
* @param transport the mock transport to preload
|
||||
* @param msgNum the message number to expect and return
|
||||
* @param body if true, a non-empty body will be added
|
||||
|
|
|
@ -204,11 +204,8 @@ public class MockTransport implements Transport {
|
|||
mPairs.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a test function (not part of the interface) and is used to set up a result
|
||||
* value for getHost(), if needed for the test.
|
||||
*/
|
||||
public void setMockHost(String host) {
|
||||
@Override
|
||||
public void setHost(String host) {
|
||||
mHost = host;
|
||||
}
|
||||
|
||||
|
@ -239,6 +236,11 @@ public class MockTransport implements Transport {
|
|||
return new MockOutputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPort(int port) {
|
||||
SmtpSenderUnitTests.fail("setPort() not implemented");
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
SmtpSenderUnitTests.fail("getPort() not implemented");
|
||||
return 0;
|
||||
|
@ -248,6 +250,7 @@ public class MockTransport implements Transport {
|
|||
return mConnectionSecurity;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String[] getUserInfoParts() {
|
||||
SmtpSenderUnitTests.fail("getUserInfoParts() not implemented");
|
||||
return null;
|
||||
|
@ -315,6 +318,7 @@ public class MockTransport implements Transport {
|
|||
public void setSoTimeout(int timeoutMilliseconds) /* throws SocketException */ {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setUri(URI uri, int defaultPort) {
|
||||
SmtpSenderUnitTests.assertTrue("Don't call setUri on a mock transport", false);
|
||||
}
|
||||
|
@ -413,4 +417,4 @@ public class MockTransport implements Transport {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue