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.mIsDefault = true;
62        account.mCompatibilityUuid = "test-uid-" + name;
63        account.mSenderName = name;
64        account.mRingtoneUri = "content://ringtone-" + name;
65        account.mProtocolVersion = "2.5" + name;
66        account.mNewMessageCount = 5 + name.length();
67        account.mPolicyKey = 0;
68        account.mSecuritySyncKey = "sec-sync-key-" + name;
69        account.mSignature = "signature-" + name;
70        if (saveIt) {
71            account.save(context);
72        }
73        return account;
74    }
75
76    /**
77     * Lightweight way of deleting an account for testing.
78     */
79    public static void deleteAccount(Context context, long accountId) {
80        context.getContentResolver().delete(ContentUris.withAppendedId(
81                Account.CONTENT_URI, accountId), null, null);
82    }
83
84    /**
85     * Create a hostauth record for test purposes
86     */
87    public static HostAuth setupHostAuth(String name, long accountId, boolean saveIt,
88            Context context) {
89        return setupHostAuth("protocol", name, saveIt, context);
90    }
91
92    /**
93     * Create a hostauth record for test purposes
94     */
95    public static HostAuth setupHostAuth(String protocol, String name, boolean saveIt,
96            Context context) {
97        HostAuth hostAuth = new HostAuth();
98
99        hostAuth.mProtocol = protocol;
100        hostAuth.mAddress = "address-" + name;
101        hostAuth.mPort = 100;
102        hostAuth.mFlags = 200;
103        hostAuth.mLogin = "login-" + name;
104        hostAuth.mPassword = "password-" + name;
105        hostAuth.mDomain = "domain-" + name;
106
107        if (saveIt) {
108            hostAuth.save(context);
109        }
110        return hostAuth;
111    }
112
113    /**
114     * Create a mailbox for test purposes
115     */
116    public static Mailbox setupMailbox(String name, long accountId, boolean saveIt,
117            Context context) {
118        return setupMailbox(name, accountId, saveIt, context, Mailbox.TYPE_MAIL);
119    }
120    public static Mailbox setupMailbox(String name, long accountId, boolean saveIt,
121            Context context, int type) {
122        return setupMailbox(name, accountId, saveIt, context, type, '/');
123    }
124    public static Mailbox setupMailbox(String name, long accountId, boolean saveIt,
125            Context context, int type, char delimiter) {
126        Mailbox box = new Mailbox();
127
128        int delimiterIndex = name.lastIndexOf(delimiter);
129        String displayName = name;
130        if (delimiterIndex > 0) {
131            displayName = name.substring(delimiterIndex + 1);
132        }
133        box.mDisplayName = displayName;
134        box.mServerId = name;
135        box.mParentServerId = "parent-serverid-" + name;
136        box.mParentKey = 4;
137        box.mAccountKey = accountId;
138        box.mType = type;
139        box.mDelimiter = delimiter;
140        box.mSyncKey = "sync-key-" + name;
141        box.mSyncLookback = 2;
142        box.mSyncInterval = Account.CHECK_INTERVAL_NEVER;
143        box.mSyncTime = 3;
144        box.mFlagVisible = true;
145        box.mFlags = 5;
146        box.mVisibleLimit = 6;
147
148        if (saveIt) {
149            box.save(context);
150        }
151        return box;
152    }
153
154    /**
155     * Create a message for test purposes
156     */
157    public static Message setupMessage(String name, long accountId, long mailboxId,
158            boolean addBody, boolean saveIt, Context context) {
159        // Default starred, read,  (backword compatibility)
160        return setupMessage(name, accountId, mailboxId, addBody, saveIt, context, true, true);
161    }
162
163    /**
164     * Create a message for test purposes
165     */
166    public static Message setupMessage(String name, long accountId, long mailboxId,
167            boolean addBody, boolean saveIt, Context context, boolean starred, boolean read) {
168        Message message = new Message();
169
170        message.mDisplayName = name;
171        message.mTimeStamp = 100 + name.length();
172        message.mSubject = "subject " + name;
173        message.mFlagRead = read;
174        message.mFlagLoaded = Message.FLAG_LOADED_UNLOADED;
175        message.mFlagFavorite = starred;
176        message.mFlagAttachment = true;
177        message.mFlags = 0;
178
179        message.mServerId = "serverid " + name;
180        message.mServerTimeStamp = 300 + name.length();
181        message.mClientId = "clientid " + name;
182        message.mMessageId = "messageid " + name;
183
184        message.mMailboxKey = mailboxId;
185        message.mAccountKey = accountId;
186
187        message.mFrom = "from " + name;
188        message.mTo = "to " + name;
189        message.mCc = "cc " + name;
190        message.mBcc = "bcc " + name;
191        message.mReplyTo = "replyto " + name;
192
193        message.mMeetingInfo = "123" + accountId + mailboxId + name.length();
194
195        if (addBody) {
196            message.mText = "body text " + name;
197            message.mHtml = "body html " + name;
198            message.mTextReply = "reply text " + name;
199            message.mHtmlReply = "reply html " + name;
200            message.mSourceKey = 400 + name.length();
201            message.mIntroText = "intro text " + name;
202        }
203
204        if (saveIt) {
205            message.save(context);
206        }
207        return message;
208    }
209
210    /**
211     * Create a test body
212     *
213     * @param messageId the message this body belongs to
214     * @param textContent the plain text for the body
215     * @param htmlContent the html text for the body
216     * @param saveIt if true, write the new attachment directly to the DB
217     * @param context use this context
218     */
219    public static Body setupBody(long messageId, String textContent, String htmlContent,
220            boolean saveIt, Context context) {
221        Body body = new Body();
222        body.mMessageKey = messageId;
223        body.mTextContent = textContent;
224        body.mHtmlContent = htmlContent;
225        body.mTextReply = "text reply " + messageId;
226        body.mHtmlReply = "html reply " + messageId;
227        body.mSourceKey = messageId + 0x1000;
228        body.mIntroText = "intro text " + messageId;
229        if (saveIt) {
230            body.save(context);
231        }
232        return body;
233    }
234
235    /**
236     * Create a test attachment.  A few fields are specified by params, and all other fields
237     * are generated using pseudo-unique values.
238     *
239     * @param messageId the message to attach to
240     * @param fileName the "file" to indicate in the attachment
241     * @param length the "length" of the attachment
242     * @param flags the flags to set in the attachment
243     * @param saveIt if true, write the new attachment directly to the DB
244     * @param context use this context
245     */
246    public static Attachment setupAttachment(long messageId, String fileName, long length,
247            int flags, boolean saveIt, Context context) {
248        Attachment att = new Attachment();
249        att.mSize = length;
250        att.mFileName = fileName;
251        att.mContentId = "contentId " + fileName;
252        att.mContentUri = "contentUri " + fileName;
253        att.mMessageKey = messageId;
254        att.mMimeType = "mimeType " + fileName;
255        att.mLocation = "location " + fileName;
256        att.mEncoding = "encoding " + fileName;
257        att.mContent = "content " + fileName;
258        att.mFlags = flags;
259        att.mContentBytes = Utility.toUtf8("content " + fileName);
260        att.mAccountKey = messageId + 0x1000;
261        if (saveIt) {
262            att.save(context);
263        }
264        return att;
265    }
266
267    /**
268     * Create a test attachment with flags = 0 (see above)
269     *
270     * @param messageId the message to attach to
271     * @param fileName the "file" to indicate in the attachment
272     * @param length the "length" of the attachment
273     * @param saveIt if true, write the new attachment directly to the DB
274     * @param context use this context
275     */
276    public static Attachment setupAttachment(long messageId, String fileName, long length,
277            boolean saveIt, Context context) {
278        return setupAttachment(messageId, fileName, length, 0, saveIt, context);
279    }
280
281    private static void assertEmailContentEqual(String caller, EmailContent expect,
282            EmailContent actual) {
283        if (expect == actual) {
284            return;
285        }
286
287        assertEquals(caller + " mId", expect.mId, actual.mId);
288        assertEquals(caller + " mBaseUri", expect.mBaseUri, actual.mBaseUri);
289    }
290
291    /**
292     * Compare two accounts for equality
293     *
294     * TODO: check host auth?
295     */
296    public static void assertAccountEqual(String caller, Account expect, Account actual) {
297        if (expect == actual) {
298            return;
299        }
300
301        assertEmailContentEqual(caller, expect, actual);
302        assertEquals(caller + " mDisplayName", expect.mDisplayName, actual.mDisplayName);
303        assertEquals(caller + " mEmailAddress", expect.mEmailAddress, actual.mEmailAddress);
304        assertEquals(caller + " mSyncKey", expect.mSyncKey, actual.mSyncKey);
305
306        assertEquals(caller + " mSyncLookback", expect.mSyncLookback, actual.mSyncLookback);
307        assertEquals(caller + " mSyncInterval", expect.mSyncInterval, actual.mSyncInterval);
308        assertEquals(caller + " mHostAuthKeyRecv", expect.mHostAuthKeyRecv,
309                actual.mHostAuthKeyRecv);
310        assertEquals(caller + " mHostAuthKeySend", expect.mHostAuthKeySend,
311                actual.mHostAuthKeySend);
312        assertEquals(caller + " mFlags", expect.mFlags, actual.mFlags);
313        assertEquals(caller + " mIsDefault", expect.mIsDefault, actual.mIsDefault);
314        assertEquals(caller + " mCompatibilityUuid", expect.mCompatibilityUuid,
315                actual.mCompatibilityUuid);
316        assertEquals(caller + " mSenderName", expect.mSenderName, actual.mSenderName);
317        assertEquals(caller + " mRingtoneUri", expect.mRingtoneUri, actual.mRingtoneUri);
318        assertEquals(caller + " mProtocolVersion", expect.mProtocolVersion,
319                actual.mProtocolVersion);
320        assertEquals(caller + " mNewMessageCount", expect.mNewMessageCount,
321                actual.mNewMessageCount);
322        assertEquals(caller + " mPolicyKey", expect.mPolicyKey, actual.mPolicyKey);
323        assertEquals(caller + " mSecuritySyncKey", expect.mSecuritySyncKey,
324                actual.mSecuritySyncKey);
325        assertEquals(caller + " mSignature", expect.mSignature, actual.mSignature);
326    }
327
328    /**
329     * Compare two hostauth records for equality
330     */
331    public static void assertHostAuthEqual(String caller, HostAuth expect, HostAuth actual) {
332        assertHostAuthEqual(caller, expect, actual, true);
333    }
334
335    public static void assertHostAuthEqual(String caller, HostAuth expect, HostAuth actual,
336            boolean testEmailContent) {
337        if (expect == actual) {
338            return;
339        }
340
341        if (testEmailContent) {
342            assertEmailContentEqual(caller, expect, actual);
343        }
344        assertEquals(caller + " mProtocol", expect.mProtocol, actual.mProtocol);
345        assertEquals(caller + " mAddress", expect.mAddress, actual.mAddress);
346        assertEquals(caller + " mPort", expect.mPort, actual.mPort);
347        assertEquals(caller + " mFlags", expect.mFlags, actual.mFlags);
348        assertEquals(caller + " mLogin", expect.mLogin, actual.mLogin);
349        assertEquals(caller + " mPassword", expect.mPassword, actual.mPassword);
350        assertEquals(caller + " mDomain", expect.mDomain, actual.mDomain);
351        // This field is dead and is not checked
352//      assertEquals(caller + " mAccountKey", expect.mAccountKey, actual.mAccountKey);
353    }
354
355    /**
356     * Compare two mailboxes for equality
357     */
358    public static void assertMailboxEqual(String caller, Mailbox expect, Mailbox actual) {
359        if (expect == actual) {
360            return;
361        }
362
363        assertEmailContentEqual(caller, expect, actual);
364        assertEquals(caller + " mDisplayName", expect.mDisplayName, actual.mDisplayName);
365        assertEquals(caller + " mServerId", expect.mServerId, actual.mServerId);
366        assertEquals(caller + " mParentServerId", expect.mParentServerId, actual.mParentServerId);
367        assertEquals(caller + " mParentKey", expect.mParentKey, actual.mParentKey);
368        assertEquals(caller + " mAccountKey", expect.mAccountKey, actual.mAccountKey);
369        assertEquals(caller + " mType", expect.mType, actual.mType);
370        assertEquals(caller + " mDelimiter", expect.mDelimiter, actual.mDelimiter);
371        assertEquals(caller + " mSyncKey", expect.mSyncKey, actual.mSyncKey);
372        assertEquals(caller + " mSyncLookback", expect.mSyncLookback, actual.mSyncLookback);
373        assertEquals(caller + " mSyncInterval", expect.mSyncInterval, actual.mSyncInterval);
374        assertEquals(caller + " mSyncTime", expect.mSyncTime, actual.mSyncTime);
375        assertEquals(caller + " mFlagVisible", expect.mFlagVisible, actual.mFlagVisible);
376        assertEquals(caller + " mFlags", expect.mFlags, actual.mFlags);
377        assertEquals(caller + " mVisibleLimit", expect.mVisibleLimit, actual.mVisibleLimit);
378    }
379
380    /**
381     * Compare two messages for equality
382     *
383     * TODO: body?
384     * TODO: attachments?
385     */
386    public static void assertMessageEqual(String caller, Message expect, Message actual) {
387        if (expect == actual) {
388            return;
389        }
390
391        assertEmailContentEqual(caller, expect, actual);
392        assertEquals(caller + " mDisplayName", expect.mDisplayName, actual.mDisplayName);
393        assertEquals(caller + " mTimeStamp", expect.mTimeStamp, actual.mTimeStamp);
394        assertEquals(caller + " mSubject", expect.mSubject, actual.mSubject);
395        assertEquals(caller + " mFlagRead = false", expect.mFlagRead, actual.mFlagRead);
396        assertEquals(caller + " mFlagLoaded", expect.mFlagLoaded, actual.mFlagLoaded);
397        assertEquals(caller + " mFlagFavorite", expect.mFlagFavorite, actual.mFlagFavorite);
398        assertEquals(caller + " mFlagAttachment", expect.mFlagAttachment, actual.mFlagAttachment);
399        assertEquals(caller + " mFlags", expect.mFlags, actual.mFlags);
400
401        assertEquals(caller + " mServerId", expect.mServerId, actual.mServerId);
402        assertEquals(caller + " mServerTimeStamp", expect.mServerTimeStamp,actual.mServerTimeStamp);
403        assertEquals(caller + " mClientId", expect.mClientId, actual.mClientId);
404        assertEquals(caller + " mMessageId", expect.mMessageId, actual.mMessageId);
405
406        assertEquals(caller + " mMailboxKey", expect.mMailboxKey, actual.mMailboxKey);
407        assertEquals(caller + " mAccountKey", expect.mAccountKey, actual.mAccountKey);
408
409        assertEquals(caller + " mFrom", expect.mFrom, actual.mFrom);
410        assertEquals(caller + " mTo", expect.mTo, actual.mTo);
411        assertEquals(caller + " mCc", expect.mCc, actual.mCc);
412        assertEquals(caller + " mBcc", expect.mBcc, actual.mBcc);
413        assertEquals(caller + " mReplyTo", expect.mReplyTo, actual.mReplyTo);
414
415        assertEquals(caller + " mMeetingInfo", expect.mMeetingInfo, actual.mMeetingInfo);
416
417        assertEquals(caller + " mSnippet", expect.mSnippet, actual.mSnippet);
418
419        assertEquals(caller + " mText", expect.mText, actual.mText);
420        assertEquals(caller + " mHtml", expect.mHtml, actual.mHtml);
421        assertEquals(caller + " mTextReply", expect.mTextReply, actual.mTextReply);
422        assertEquals(caller + " mHtmlReply", expect.mHtmlReply, actual.mHtmlReply);
423        assertEquals(caller + " mSourceKey", expect.mSourceKey, actual.mSourceKey);
424        assertEquals(caller + " mIntroText", expect.mIntroText, actual.mIntroText);
425    }
426
427    /**
428     * Compare to attachments for equality
429     *
430     * TODO: file / content URI mapping?  Compare the actual files?
431     */
432    public static void assertAttachmentEqual(String caller, Attachment expect, Attachment actual) {
433        if (expect == actual) {
434            return;
435        }
436
437        assertEmailContentEqual(caller, expect, actual);
438        assertEquals(caller + " mSize", expect.mSize, actual.mSize);
439        assertEquals(caller + " mFileName", expect.mFileName, actual.mFileName);
440        assertEquals(caller + " mContentId", expect.mContentId, actual.mContentId);
441        assertEquals(caller + " mContentUri", expect.mContentUri, actual.mContentUri);
442        assertEquals(caller + " mMessageKey", expect.mMessageKey, actual.mMessageKey);
443        assertEquals(caller + " mMimeType", expect.mMimeType, actual.mMimeType);
444        assertEquals(caller + " mLocation", expect.mLocation, actual.mLocation);
445        assertEquals(caller + " mEncoding", expect.mEncoding, actual.mEncoding);
446        assertEquals(caller + " mContent", expect.mContent, actual.mContent);
447        assertEquals(caller + " mFlags", expect.mFlags, actual.mFlags);
448        MoreAsserts.assertEquals(caller + " mContentBytes",
449                expect.mContentBytes, actual.mContentBytes);
450        assertEquals(caller + " mAccountKey", expect.mAccountKey, actual.mAccountKey);
451    }
452
453    /**
454     * Create a temporary EML file based on {@code msg} in the directory {@code directory}.
455     */
456    public static Uri createTempEmlFile(Context context, Message msg, File directory)
457            throws Exception {
458        // Write out the message in rfc822 format
459        File outputFile = File.createTempFile("message", "tmp", directory);
460        assertNotNull(outputFile);
461        FileOutputStream outputStream = new FileOutputStream(outputFile);
462        Rfc822Output.writeTo(context, msg.mId, outputStream, true, false);
463        outputStream.close();
464
465        return Uri.fromFile(outputFile);
466    }
467}
468