1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.email.provider;
18
19import com.android.emailcommon.internet.Rfc822Output;
20import com.android.emailcommon.provider.Account;
21import com.android.emailcommon.provider.EmailContent;
22import com.android.emailcommon.provider.EmailContent.Attachment;
23import com.android.emailcommon.provider.EmailContent.Body;
24import com.android.emailcommon.provider.EmailContent.Message;
25import com.android.emailcommon.provider.HostAuth;
26import com.android.emailcommon.provider.Mailbox;
27import com.android.emailcommon.utility.Utility;
28
29import android.content.ContentUris;
30import android.content.Context;
31import android.net.Uri;
32import android.test.MoreAsserts;
33
34import java.io.File;
35import java.io.FileOutputStream;
36
37import junit.framework.Assert;
38
39public class ProviderTestUtils extends Assert {
40
41    /**
42     * No constructor - statics only
43     */
44    private ProviderTestUtils() {
45    }
46
47    /**
48     * Create an account for test purposes
49     */
50    public static Account setupAccount(String name, boolean saveIt, Context context) {
51        Account account = new Account();
52
53        account.mDisplayName = name;
54        account.mEmailAddress = name + "@android.com";
55        account.mSyncKey = "sync-key-" + name;
56        account.mSyncLookback = 1;
57        account.mSyncInterval = Account.CHECK_INTERVAL_NEVER;
58        account.mHostAuthKeyRecv = 0;
59        account.mHostAuthKeySend = 0;
60        account.mFlags = 4;
61        account.mSenderName = name;
62        account.mProtocolVersion = "2.5" + name;
63        account.mPolicyKey = 0;
64        account.mSecuritySyncKey = "sec-sync-key-" + name;
65        account.mSignature = "signature-" + name;
66        if (saveIt) {
67            account.save(context);
68        }
69        return account;
70    }
71
72    /**
73     * Lightweight way of deleting an account for testing.
74     */
75    public static void deleteAccount(Context context, long accountId) {
76        context.getContentResolver().delete(ContentUris.withAppendedId(
77                Account.CONTENT_URI, accountId), null, null);
78    }
79
80    /**
81     * Create a hostauth record for test purposes
82     */
83    public static HostAuth setupHostAuth(String name, long accountId, boolean saveIt,
84            Context context) {
85        return setupHostAuth("protocol", name, saveIt, context);
86    }
87
88    /**
89     * Create a hostauth record for test purposes
90     */
91    public static HostAuth setupHostAuth(String protocol, String name, boolean saveIt,
92            Context context) {
93        HostAuth hostAuth = new HostAuth();
94
95        hostAuth.mProtocol = protocol;
96        hostAuth.mAddress = "address-" + name;
97        hostAuth.mPort = 100;
98        hostAuth.mFlags = 200;
99        hostAuth.mLogin = "login-" + name;
100        hostAuth.mPassword = "password-" + name;
101        hostAuth.mDomain = "domain-" + name;
102
103        if (saveIt) {
104            hostAuth.save(context);
105        }
106        return hostAuth;
107    }
108
109    /**
110     * Create a mailbox for test purposes
111     */
112    public static Mailbox setupMailbox(String name, long accountId, boolean saveIt,
113            Context context) {
114        return setupMailbox(name, accountId, saveIt, context, Mailbox.TYPE_MAIL);
115    }
116    public static Mailbox setupMailbox(String name, long accountId, boolean saveIt,
117            Context context, int type) {
118        return setupMailbox(name, accountId, saveIt, context, type, '/');
119    }
120    public static Mailbox setupMailbox(String name, long accountId, boolean saveIt,
121            Context context, int type, char delimiter) {
122        Mailbox box = new Mailbox();
123
124        int delimiterIndex = name.lastIndexOf(delimiter);
125        String displayName = name;
126        if (delimiterIndex > 0) {
127            displayName = name.substring(delimiterIndex + 1);
128        }
129        box.mDisplayName = displayName;
130        box.mServerId = name;
131        box.mParentServerId = "parent-serverid-" + name;
132        box.mParentKey = 4;
133        box.mAccountKey = accountId;
134        box.mType = type;
135        box.mDelimiter = delimiter;
136        box.mSyncKey = "sync-key-" + name;
137        box.mSyncLookback = 2;
138        box.mSyncInterval = Account.CHECK_INTERVAL_NEVER;
139        box.mSyncTime = 3;
140        box.mFlagVisible = true;
141        box.mFlags = 5;
142
143        if (saveIt) {
144            box.save(context);
145        }
146        return box;
147    }
148
149    /**
150     * Create a message for test purposes
151     */
152    public static Message setupMessage(String name, long accountId, long mailboxId,
153            boolean addBody, boolean saveIt, Context context) {
154        // Default starred, read,  (backword compatibility)
155        return setupMessage(name, accountId, mailboxId, addBody, saveIt, context, true, true);
156    }
157
158    /**
159     * Create a message for test purposes
160     */
161    public static Message setupMessage(String name, long accountId, long mailboxId,
162            boolean addBody, boolean saveIt, Context context, boolean starred, boolean read) {
163        Message message = new Message();
164
165        message.mDisplayName = name;
166        message.mTimeStamp = 100 + name.length();
167        message.mSubject = "subject " + name;
168        message.mFlagRead = read;
169        message.mFlagSeen = read;
170        message.mFlagLoaded = Message.FLAG_LOADED_UNLOADED;
171        message.mFlagFavorite = starred;
172        message.mFlagAttachment = true;
173        message.mFlags = 0;
174
175        message.mServerId = "serverid " + name;
176        message.mServerTimeStamp = 300 + name.length();
177        message.mMessageId = "messageid " + name;
178
179        message.mMailboxKey = mailboxId;
180        message.mAccountKey = accountId;
181
182        message.mFrom = "from " + name;
183        message.mTo = "to " + name;
184        message.mCc = "cc " + name;
185        message.mBcc = "bcc " + name;
186        message.mReplyTo = "replyto " + name;
187
188        message.mMeetingInfo = "123" + accountId + mailboxId + name.length();
189
190        if (addBody) {
191            message.mText = "body text " + name;
192            message.mHtml = "body html " + name;
193            message.mSourceKey = 400 + name.length();
194        }
195
196        if (saveIt) {
197            message.save(context);
198        }
199        return message;
200    }
201
202    /**
203     * Create a test body
204     *
205     * @param messageId the message this body belongs to
206     * @param textContent the plain text for the body
207     * @param htmlContent the html text for the body
208     * @param saveIt if true, write the new attachment directly to the DB
209     * @param context use this context
210     */
211    public static Body setupBody(long messageId, String textContent, String htmlContent,
212            boolean saveIt, Context context) {
213        Body body = new Body();
214        body.mMessageKey = messageId;
215        body.mHtmlContent = htmlContent;
216        body.mTextContent = textContent;
217        body.mSourceKey = messageId + 0x1000;
218        if (saveIt) {
219            body.save(context);
220        }
221        return body;
222    }
223
224    /**
225     * Create a test attachment.  A few fields are specified by params, and all other fields
226     * are generated using pseudo-unique values.
227     *
228     * @param messageId the message to attach to
229     * @param fileName the "file" to indicate in the attachment
230     * @param length the "length" of the attachment
231     * @param flags the flags to set in the attachment
232     * @param saveIt if true, write the new attachment directly to the DB
233     * @param context use this context
234     */
235    public static Attachment setupAttachment(long messageId, String fileName, long length,
236            int flags, boolean saveIt, Context context) {
237        Attachment att = new Attachment();
238        att.mSize = length;
239        att.mFileName = fileName;
240        att.mContentId = "contentId " + fileName;
241        att.setContentUri("contentUri " + fileName);
242        att.mMessageKey = messageId;
243        att.mMimeType = "mimeType " + fileName;
244        att.mLocation = "location " + fileName;
245        att.mEncoding = "encoding " + fileName;
246        att.mContent = "content " + fileName;
247        att.mFlags = flags;
248        att.mContentBytes = Utility.toUtf8("content " + fileName);
249        att.mAccountKey = messageId + 0x1000;
250        if (saveIt) {
251            att.save(context);
252        }
253        return att;
254    }
255
256    /**
257     * Create a test attachment with flags = 0 (see above)
258     *
259     * @param messageId the message to attach to
260     * @param fileName the "file" to indicate in the attachment
261     * @param length the "length" of the attachment
262     * @param saveIt if true, write the new attachment directly to the DB
263     * @param context use this context
264     */
265    public static Attachment setupAttachment(long messageId, String fileName, long length,
266            boolean saveIt, Context context) {
267        return setupAttachment(messageId, fileName, length, 0, saveIt, context);
268    }
269
270    private static void assertEmailContentEqual(String caller, EmailContent expect,
271            EmailContent actual) {
272        if (expect == actual) {
273            return;
274        }
275
276        assertEquals(caller + " mId", expect.mId, actual.mId);
277        assertEquals(caller + " mBaseUri", expect.mBaseUri, actual.mBaseUri);
278    }
279
280    /**
281     * Compare two accounts for equality
282     *
283     * TODO: check host auth?
284     */
285    public static void assertAccountEqual(String caller, Account expect, Account actual) {
286        if (expect == actual) {
287            return;
288        }
289
290        assertEmailContentEqual(caller, expect, actual);
291        assertEquals(caller + " mDisplayName", expect.mDisplayName, actual.mDisplayName);
292        assertEquals(caller + " mEmailAddress", expect.mEmailAddress, actual.mEmailAddress);
293        assertEquals(caller + " mSyncKey", expect.mSyncKey, actual.mSyncKey);
294
295        assertEquals(caller + " mSyncLookback", expect.mSyncLookback, actual.mSyncLookback);
296        assertEquals(caller + " mSyncInterval", expect.mSyncInterval, actual.mSyncInterval);
297        assertEquals(caller + " mHostAuthKeyRecv", expect.mHostAuthKeyRecv,
298                actual.mHostAuthKeyRecv);
299        assertEquals(caller + " mHostAuthKeySend", expect.mHostAuthKeySend,
300                actual.mHostAuthKeySend);
301        assertEquals(caller + " mFlags", expect.mFlags, actual.mFlags);
302        assertEquals(caller + " mSenderName", expect.mSenderName, actual.mSenderName);
303        assertEquals(caller + " mProtocolVersion", expect.mProtocolVersion,
304                actual.mProtocolVersion);
305        assertEquals(caller + " mSecuritySyncKey", expect.mSecuritySyncKey,
306                actual.mSecuritySyncKey);
307        assertEquals(caller + " mSignature", expect.mSignature, actual.mSignature);
308        assertEquals(caller + " mPolicyKey", expect.mPolicyKey, actual.mPolicyKey);
309        assertEquals(caller + " mPingDuration", expect.mPingDuration, actual.mPingDuration);
310    }
311
312    /**
313     * Compare two hostauth records for equality
314     */
315    public static void assertHostAuthEqual(String caller, HostAuth expect, HostAuth actual) {
316        assertHostAuthEqual(caller, expect, actual, true);
317    }
318
319    public static void assertHostAuthEqual(String caller, HostAuth expect, HostAuth actual,
320            boolean testEmailContent) {
321        if (expect == actual) {
322            return;
323        }
324
325        if (testEmailContent) {
326            assertEmailContentEqual(caller, expect, actual);
327        }
328        assertEquals(caller + " mProtocol", expect.mProtocol, actual.mProtocol);
329        assertEquals(caller + " mAddress", expect.mAddress, actual.mAddress);
330        assertEquals(caller + " mPort", expect.mPort, actual.mPort);
331        assertEquals(caller + " mFlags", expect.mFlags, actual.mFlags);
332        assertEquals(caller + " mLogin", expect.mLogin, actual.mLogin);
333        assertEquals(caller + " mPassword", expect.mPassword, actual.mPassword);
334        assertEquals(caller + " mDomain", expect.mDomain, actual.mDomain);
335        // This field is dead and is not checked
336//      assertEquals(caller + " mAccountKey", expect.mAccountKey, actual.mAccountKey);
337    }
338
339    /**
340     * Compare two mailboxes for equality
341     */
342    public static void assertMailboxEqual(String caller, Mailbox expect, Mailbox actual) {
343        if (expect == actual) {
344            return;
345        }
346
347        assertEmailContentEqual(caller, expect, actual);
348        assertEquals(caller + " mDisplayName", expect.mDisplayName, actual.mDisplayName);
349        assertEquals(caller + " mServerId", expect.mServerId, actual.mServerId);
350        assertEquals(caller + " mParentServerId", expect.mParentServerId, actual.mParentServerId);
351        assertEquals(caller + " mParentKey", expect.mParentKey, actual.mParentKey);
352        assertEquals(caller + " mAccountKey", expect.mAccountKey, actual.mAccountKey);
353        assertEquals(caller + " mType", expect.mType, actual.mType);
354        assertEquals(caller + " mDelimiter", expect.mDelimiter, actual.mDelimiter);
355        assertEquals(caller + " mSyncKey", expect.mSyncKey, actual.mSyncKey);
356        assertEquals(caller + " mSyncLookback", expect.mSyncLookback, actual.mSyncLookback);
357        assertEquals(caller + " mSyncInterval", expect.mSyncInterval, actual.mSyncInterval);
358        assertEquals(caller + " mSyncTime", expect.mSyncTime, actual.mSyncTime);
359        assertEquals(caller + " mFlagVisible", expect.mFlagVisible, actual.mFlagVisible);
360        assertEquals(caller + " mSyncStatus", expect.mSyncStatus, actual.mSyncStatus);
361        assertEquals(caller + " mLastTouchedTime", expect.mLastTouchedTime, actual.mLastTouchedTime);
362        assertEquals(caller + " mUiSyncStatus", expect.mUiSyncStatus, actual.mUiSyncStatus);
363        assertEquals(caller + " mUiLastSyncResult", expect.mUiLastSyncResult, actual.mUiLastSyncResult);
364        assertEquals(caller + " mTotalCount", expect.mTotalCount, actual.mTotalCount);
365        assertEquals(caller + " mHierarchicalName", expect.mHierarchicalName, actual.mHierarchicalName);
366        assertEquals(caller + " mLastFullSyncTime", expect.mLastFullSyncTime, actual.mLastFullSyncTime);
367    }
368
369    /**
370     * Compare two messages for equality
371     *
372     * TODO: body?
373     * TODO: attachments?
374     */
375    public static void assertMessageEqual(String caller, Message expect, Message actual) {
376        if (expect == actual) {
377            return;
378        }
379
380        assertEmailContentEqual(caller, expect, actual);
381        assertEquals(caller + " mDisplayName", expect.mDisplayName, actual.mDisplayName);
382        assertEquals(caller + " mTimeStamp", expect.mTimeStamp, actual.mTimeStamp);
383        assertEquals(caller + " mSubject", expect.mSubject, actual.mSubject);
384        assertEquals(caller + " mFlagRead = false", expect.mFlagRead, actual.mFlagRead);
385        assertEquals(caller + " mFlagRead = false", expect.mFlagSeen, actual.mFlagSeen);
386        assertEquals(caller + " mFlagLoaded", expect.mFlagLoaded, actual.mFlagLoaded);
387        assertEquals(caller + " mFlagFavorite", expect.mFlagFavorite, actual.mFlagFavorite);
388        assertEquals(caller + " mFlagAttachment", expect.mFlagAttachment, actual.mFlagAttachment);
389        assertEquals(caller + " mFlags", expect.mFlags, actual.mFlags);
390
391        assertEquals(caller + " mServerId", expect.mServerId, actual.mServerId);
392        assertEquals(caller + " mServerTimeStamp", expect.mServerTimeStamp,actual.mServerTimeStamp);
393        assertEquals(caller + " mDraftInfo", expect.mDraftInfo,actual.mDraftInfo);
394        assertEquals(caller + " mMessageId", expect.mMessageId, actual.mMessageId);
395
396        assertEquals(caller + " mMailboxKey", expect.mMailboxKey, actual.mMailboxKey);
397        assertEquals(caller + " mAccountKey", expect.mAccountKey, actual.mAccountKey);
398        assertEquals(caller + " mMainMailboxKey", expect.mMainMailboxKey, actual.mMainMailboxKey);
399
400        assertEquals(caller + " mFrom", expect.mFrom, actual.mFrom);
401        assertEquals(caller + " mTo", expect.mTo, actual.mTo);
402        assertEquals(caller + " mCc", expect.mCc, actual.mCc);
403        assertEquals(caller + " mBcc", expect.mBcc, actual.mBcc);
404        assertEquals(caller + " mReplyTo", expect.mReplyTo, actual.mReplyTo);
405
406        assertEquals(caller + " mMeetingInfo", expect.mMeetingInfo, actual.mMeetingInfo);
407
408        assertEquals(caller + " mSnippet", expect.mSnippet, actual.mSnippet);
409
410        assertEquals(caller + " mProtocolSearchInfo", expect.mProtocolSearchInfo, actual.mProtocolSearchInfo);
411
412        assertEquals(caller + " mThreadTopic", expect.mThreadTopic, actual.mThreadTopic);
413
414        assertEquals(caller + " mSyncData", expect.mSyncData, actual.mSyncData);
415
416        assertEquals(caller + " mSyncData", expect.mServerConversationId, actual.mServerConversationId);
417
418        assertEquals(caller + " mText", expect.mText, actual.mText);
419        assertEquals(caller + " mHtml", expect.mHtml, actual.mHtml);
420        assertEquals(caller + " mSourceKey", expect.mSourceKey, actual.mSourceKey);
421        assertEquals(caller + " mQuotedTextStartPos", expect.mQuotedTextStartPos, actual.mQuotedTextStartPos);
422    }
423
424    /**
425     * Compare to attachments for equality
426     *
427     * TODO: file / content URI mapping?  Compare the actual files?
428     */
429    public static void assertAttachmentEqual(String caller, Attachment expect, Attachment actual) {
430        if (expect == actual) {
431            return;
432        }
433
434        assertEmailContentEqual(caller, expect, actual);
435        assertEquals(caller + " mFileName", expect.mFileName, actual.mFileName);
436        assertEquals(caller + " mMimeType", expect.mMimeType, actual.mMimeType);
437        assertEquals(caller + " mSize", expect.mSize, actual.mSize);
438        assertEquals(caller + " mContentId", expect.mContentId, actual.mContentId);
439        assertEquals(caller + " mContentUri", expect.getContentUri(), actual.getContentUri());
440        assertEquals(caller + " mCachedFileUri", expect.getCachedFileUri(), actual.getCachedFileUri());
441        assertEquals(caller + " mMessageKey", expect.mMessageKey, actual.mMessageKey);
442        assertEquals(caller + " mLocation", expect.mLocation, actual.mLocation);
443        assertEquals(caller + " mEncoding", expect.mEncoding, actual.mEncoding);
444        assertEquals(caller + " mContent", expect.mContent, actual.mContent);
445        assertEquals(caller + " mFlags", expect.mFlags, actual.mFlags);
446        MoreAsserts.assertEquals(caller + " mContentBytes",
447                expect.mContentBytes, actual.mContentBytes);
448        assertEquals(caller + " mAccountKey", expect.mAccountKey, actual.mAccountKey);
449    }
450
451    /**
452     * Create a temporary EML file based on {@code msg} in the directory {@code directory}.
453     */
454    public static Uri createTempEmlFile(Context context, Message msg, File directory)
455            throws Exception {
456        // Write out the message in rfc822 format
457        File outputFile = File.createTempFile("message", "tmp", directory);
458        assertNotNull(outputFile);
459        FileOutputStream outputStream = new FileOutputStream(outputFile);
460        Rfc822Output.writeTo(context, msg, outputStream, true, false, null);
461        outputStream.close();
462
463        return Uri.fromFile(outputFile);
464    }
465}
466