blob: ebf3243999d34c2c22ea261104abe3425b23696d [file] [log] [blame]
Andrew Stadler7143d962009-06-25 00:02:29 -07001/*
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
Marc Blankf3ff0ba2011-05-19 14:14:14 -070019import android.accounts.AccountManager;
20import android.accounts.AuthenticatorException;
21import android.accounts.OperationCanceledException;
Andrew Stadlerddc871d2009-06-29 23:08:40 -070022import android.content.ContentResolver;
Andrew Stadler7143d962009-06-25 00:02:29 -070023import android.content.ContentUris;
Andrew Stadlerddc871d2009-06-29 23:08:40 -070024import android.content.ContentValues;
Andrew Stadler7143d962009-06-25 00:02:29 -070025import android.content.Context;
Ben Komalo32bed4b2011-08-23 18:02:11 -070026import android.content.ContextWrapper;
Andrew Stadler7143d962009-06-25 00:02:29 -070027import android.database.Cursor;
Makoto Onuki574854b2010-07-30 13:53:59 -070028import android.database.sqlite.SQLiteDatabase;
Andrew Stadler7143d962009-06-25 00:02:29 -070029import android.net.Uri;
Andrew Stadler4a8c70c2009-08-18 12:14:15 -070030import android.os.Bundle;
Marc Blank976f9292009-07-15 15:08:53 -070031import android.os.Environment;
Andrew Stadler4a8c70c2009-08-18 12:14:15 -070032import android.os.Parcel;
Makoto Onukie37881a2010-03-02 13:03:27 -080033import android.test.MoreAsserts;
Andrew Stadler7143d962009-06-25 00:02:29 -070034import android.test.ProviderTestCase2;
Ben Komalo52e66112011-07-13 15:16:55 -070035import android.test.suitebuilder.annotation.LargeTest;
36import android.test.suitebuilder.annotation.MediumTest;
37import android.test.suitebuilder.annotation.SmallTest;
Andrew Stadler7143d962009-06-25 00:02:29 -070038
Ben Komalo32bed4b2011-08-23 18:02:11 -070039import com.android.email.provider.EmailProvider.AttachmentService;
Marc Blank6e418aa2011-06-18 18:03:11 -070040import com.android.emailcommon.AccountManagerTypes;
41import com.android.emailcommon.provider.Account;
42import com.android.emailcommon.provider.EmailContent;
43import com.android.emailcommon.provider.EmailContent.AccountColumns;
44import com.android.emailcommon.provider.EmailContent.Attachment;
45import com.android.emailcommon.provider.EmailContent.AttachmentColumns;
46import com.android.emailcommon.provider.EmailContent.Body;
47import com.android.emailcommon.provider.EmailContent.BodyColumns;
48import com.android.emailcommon.provider.EmailContent.MailboxColumns;
49import com.android.emailcommon.provider.EmailContent.Message;
50import com.android.emailcommon.provider.EmailContent.MessageColumns;
Marc Blank2bdf7ee2011-06-30 16:03:36 -070051import com.android.emailcommon.provider.EmailContent.PolicyColumns;
Marc Blank6e418aa2011-06-18 18:03:11 -070052import com.android.emailcommon.provider.HostAuth;
53import com.android.emailcommon.provider.Mailbox;
54import com.android.emailcommon.provider.Policy;
Marc Blank6e418aa2011-06-18 18:03:11 -070055import com.android.emailcommon.utility.TextUtilities;
56import com.android.emailcommon.utility.Utility;
57
Marc Blank758a5322009-07-30 11:41:31 -070058import java.io.File;
59import java.io.IOException;
60import java.util.ArrayList;
61
Andrew Stadler7143d962009-06-25 00:02:29 -070062/**
63 * Tests of the Email provider.
Marc Blank758a5322009-07-30 11:41:31 -070064 *
Andrew Stadler7143d962009-06-25 00:02:29 -070065 * You can run this entire test case with:
66 * runtest -c com.android.email.provider.ProviderTests email
Makoto Onuki261d6c32010-09-14 16:28:50 -070067 *
68 * TODO: Add tests for cursor notification mechanism. (setNotificationUri and notifyChange)
69 * We can't test the entire notification mechanism with a mock content resolver, because which URI
70 * to notify when notifyChange() is called is in the actual content resolver.
71 * Implementing the same mechanism in a mock one is pointless. Instead what we could do is check
72 * what notification URI each cursor has, and with which URI is notified when
73 * inserting/updating/deleting. (The former require a new method from AbstractCursor)
Andrew Stadler7143d962009-06-25 00:02:29 -070074 */
Ben Komalo52e66112011-07-13 15:16:55 -070075@LargeTest
Andrew Stadler7143d962009-06-25 00:02:29 -070076public class ProviderTests extends ProviderTestCase2<EmailProvider> {
Marc Blank758a5322009-07-30 11:41:31 -070077
Makoto Onuki9d5aaea2010-12-02 16:33:49 -080078 private EmailProvider mProvider;
79 private Context mMockContext;
Andrew Stadler7143d962009-06-25 00:02:29 -070080
81 public ProviderTests() {
Marc Blank31d9acb2011-02-11 15:05:17 -080082 super(EmailProvider.class, EmailContent.AUTHORITY);
Andrew Stadler7143d962009-06-25 00:02:29 -070083 }
Marc Blank758a5322009-07-30 11:41:31 -070084
Ben Komalo32bed4b2011-08-23 18:02:11 -070085 // TODO: move this out to a common place. There are other places that have similar mocks.
86 /**
87 * Private context wrapper used to add back getPackageName() for these tests.
88 */
89 private static class MockContext2 extends ContextWrapper {
90
91 private final Context mRealContext;
92
93 public MockContext2(Context mockContext, Context realContext) {
94 super(mockContext);
95 mRealContext = realContext;
96 }
97
98 @Override
99 public Context getApplicationContext() {
100 return this;
101 }
102
103 @Override
104 public String getPackageName() {
105 return mRealContext.getPackageName();
106 }
107
108 @Override
109 public Object getSystemService(String name) {
110 return mRealContext.getSystemService(name);
111 }
112 }
113
114 private static final AttachmentService MOCK_ATTACHMENT_SERVICE = new AttachmentService() {
115 @Override
116 public void attachmentChanged(Context context, long id, int flags) {
117 // Noop. Don't download attachments.
118 }
119 };
120
Andrew Stadler7143d962009-06-25 00:02:29 -0700121 @Override
122 public void setUp() throws Exception {
123 super.setUp();
Ben Komalo32bed4b2011-08-23 18:02:11 -0700124 mMockContext = new MockContext2(getMockContext(), getContext());
Makoto Onuki9d5aaea2010-12-02 16:33:49 -0800125 mProvider = getProvider();
Ben Komalo32bed4b2011-08-23 18:02:11 -0700126 mProvider.injectAttachmentService(MOCK_ATTACHMENT_SERVICE);
Marc Blank349055a2010-11-17 09:47:36 -0800127 // Invalidate all caches, since we reset the database for each test
Marc Blank6e418aa2011-06-18 18:03:11 -0700128 ContentCache.invalidateAllCaches();
Andrew Stadler7143d962009-06-25 00:02:29 -0700129 }
130
131 @Override
132 public void tearDown() throws Exception {
133 super.tearDown();
Ben Komalo32bed4b2011-08-23 18:02:11 -0700134 mProvider.injectAttachmentService(null);
Andrew Stadler7143d962009-06-25 00:02:29 -0700135 }
136
137 /**
Andrew Stadler0d008892009-09-22 18:31:10 -0700138 * TODO: Database upgrade tests
139 */
140
Todd Kennedy22208772011-04-22 15:45:11 -0700141 //////////////////////////////////////////////////////////
142 ////// Utility methods
143 //////////////////////////////////////////////////////////
144
145 /** Sets the message count of all mailboxes to {@code -1}. */
146 private void setMinusOneToMessageCounts() {
147 ContentValues values = new ContentValues();
148 values.put(MailboxColumns.MESSAGE_COUNT, -1);
149
150 // EmailProvider.update() doesn't allow updating messageCount, so directly use the DB.
151 SQLiteDatabase db = getProvider().getDatabase(mMockContext);
152 db.update(Mailbox.TABLE_NAME, values, null, null);
153 }
154
155 /** Returns the number of messages in a mailbox. */
156 private int getMessageCount(long mailboxId) {
157 return Utility.getFirstRowInt(mMockContext,
158 ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailboxId),
159 new String[] {MailboxColumns.MESSAGE_COUNT}, null, null, null, 0);
160 }
161
162 /** Creates a new message. */
163 private static Message createMessage(Context c, Mailbox b, boolean starred, boolean read,
164 int flagLoaded) {
165 Message message = ProviderTestUtils.setupMessage(
166 "1", b.mAccountKey, b.mId, true, false, c, starred, read);
167 message.mFlagLoaded = flagLoaded;
168 message.save(c);
169 return message;
170 }
171
172 //////////////////////////////////////////////////////////
173 ////// The tests
174 //////////////////////////////////////////////////////////
175
Andrew Stadler0d008892009-09-22 18:31:10 -0700176 /**
Andrew Stadler7143d962009-06-25 00:02:29 -0700177 * Test simple account save/retrieve
178 */
Ben Komalo52e66112011-07-13 15:16:55 -0700179 @SmallTest
Andrew Stadler7143d962009-06-25 00:02:29 -0700180 public void testAccountSave() {
Andrew Stadler28448e72009-07-06 10:49:38 -0700181 Account account1 = ProviderTestUtils.setupAccount("account-save", true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -0700182 long account1Id = account1.mId;
Marc Blank758a5322009-07-30 11:41:31 -0700183
Marc Blankf5418f12011-06-13 15:32:27 -0700184 Account account2 = Account.restoreAccountWithId(mMockContext, account1Id);
Marc Blank758a5322009-07-30 11:41:31 -0700185
Andrew Stadler28448e72009-07-06 10:49:38 -0700186 ProviderTestUtils.assertAccountEqual("testAccountSave", account1, account2);
Andrew Stadler7143d962009-06-25 00:02:29 -0700187 }
satok41f775b2009-07-22 09:58:08 +0900188
Andrew Stadler4a8c70c2009-08-18 12:14:15 -0700189 /**
Andrew Stadlerda8836a2009-09-15 14:10:12 -0700190 * Test simple account save/retrieve with predefined hostauth records
191 */
Ben Komalo52e66112011-07-13 15:16:55 -0700192 @SmallTest
Andrew Stadlerda8836a2009-09-15 14:10:12 -0700193 public void testAccountSaveHostAuth() {
194 Account account1 = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext);
195 // add hostauth data, which should be saved the first time
196 account1.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-hostauth-recv", -1, false,
197 mMockContext);
198 account1.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-hostauth-send", -1, false,
199 mMockContext);
200 account1.save(mMockContext);
201 long account1Id = account1.mId;
202
203 // Confirm account reads back correctly
Marc Blankf5418f12011-06-13 15:32:27 -0700204 Account account1get = Account.restoreAccountWithId(mMockContext, account1Id);
Andrew Stadlerda8836a2009-09-15 14:10:12 -0700205 ProviderTestUtils.assertAccountEqual("testAccountSave", account1, account1get);
206
207 // Confirm hostauth fields can be accessed & read back correctly
Ben Komalo12b82d92011-05-19 15:18:12 -0700208 HostAuth hostAuth1get = HostAuth.restoreHostAuthWithId(mMockContext,
Andrew Stadlerda8836a2009-09-15 14:10:12 -0700209 account1get.mHostAuthKeyRecv);
210 ProviderTestUtils.assertHostAuthEqual("testAccountSaveHostAuth-recv",
211 account1.mHostAuthRecv, hostAuth1get);
Ben Komalo12b82d92011-05-19 15:18:12 -0700212 HostAuth hostAuth2get = HostAuth.restoreHostAuthWithId(mMockContext,
Andrew Stadlerda8836a2009-09-15 14:10:12 -0700213 account1get.mHostAuthKeySend);
214 ProviderTestUtils.assertHostAuthEqual("testAccountSaveHostAuth-send",
215 account1.mHostAuthSend, hostAuth2get);
216 }
217
Todd Kennedy040ddf62011-02-04 09:29:13 -0800218 public void testAccountGetHostAuthSend() {
219 Account account = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext);
220 account.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-hostauth-send", -1, false,
221 mMockContext);
222 account.save(mMockContext);
223 HostAuth authGet;
224 HostAuth authTest;
225
226 authTest = account.mHostAuthSend;
227 assertNotNull(authTest);
228 assertTrue(account.mHostAuthKeySend != 0);
229
230 // HostAuth is not changed
231 authGet = account.getOrCreateHostAuthSend(mMockContext);
232 assertTrue(authGet == authTest); // return the same object
233
234 // New HostAuth; based upon mHostAuthKeyRecv
Ben Komalo12b82d92011-05-19 15:18:12 -0700235 authTest = HostAuth.restoreHostAuthWithId(mMockContext,
Todd Kennedy040ddf62011-02-04 09:29:13 -0800236 account.mHostAuthKeySend);
237 account.mHostAuthSend = null;
238 authGet = account.getOrCreateHostAuthSend(mMockContext);
239 assertNotNull(authGet);
240 assertNotNull(account.mHostAuthSend);
241 ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthSend-1", authTest, authGet);
242
243 // New HostAuth; completely empty
Ben Komalo12b82d92011-05-19 15:18:12 -0700244 authTest = new HostAuth();
Todd Kennedy040ddf62011-02-04 09:29:13 -0800245 account.mHostAuthSend = null;
246 account.mHostAuthKeySend = 0;
247 authGet = account.getOrCreateHostAuthSend(mMockContext);
248 assertNotNull(authGet);
249 assertNotNull(account.mHostAuthSend);
250 ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthSendv-2", authTest, authGet);
251 }
252
253 public void testAccountGetHostAuthRecv() {
254 Account account = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext);
255 account.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-hostauth-recv", -1, false,
256 mMockContext);
257 account.save(mMockContext);
258 HostAuth authGet;
259 HostAuth authTest;
260
261 authTest = account.mHostAuthRecv;
262 assertNotNull(authTest);
263 assertTrue(account.mHostAuthKeyRecv != 0);
264
265 // HostAuth is not changed
266 authGet = account.getOrCreateHostAuthRecv(mMockContext);
267 assertTrue(authGet == authTest); // return the same object
268
269 // New HostAuth; based upon mHostAuthKeyRecv
Ben Komalo12b82d92011-05-19 15:18:12 -0700270 authTest = HostAuth.restoreHostAuthWithId(mMockContext,
Todd Kennedy040ddf62011-02-04 09:29:13 -0800271 account.mHostAuthKeyRecv);
272 account.mHostAuthRecv = null;
273 authGet = account.getOrCreateHostAuthRecv(mMockContext);
274 assertNotNull(authGet);
275 assertNotNull(account.mHostAuthRecv);
276 ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthRecv-1", authTest, authGet);
277
278 // New HostAuth; completely empty
Ben Komalo12b82d92011-05-19 15:18:12 -0700279 authTest = new HostAuth();
Todd Kennedy040ddf62011-02-04 09:29:13 -0800280 account.mHostAuthRecv = null;
281 account.mHostAuthKeyRecv = 0;
282 authGet = account.getOrCreateHostAuthRecv(mMockContext);
283 assertNotNull(authGet);
284 assertNotNull(account.mHostAuthRecv);
285 ProviderTestUtils.assertHostAuthEqual("testAccountGetHostAuthRecv-2", authTest, authGet);
286 }
287
Andrew Stadlerda8836a2009-09-15 14:10:12 -0700288 /**
Todd Kennedy040ddf62011-02-04 09:29:13 -0800289 * Simple test of account parceling. The rather torturous path is to ensure that the
Andrew Stadler4a8c70c2009-08-18 12:14:15 -0700290 * account is really flattened all the way down to a parcel and back.
291 */
292 public void testAccountParcel() {
293 Account account1 = ProviderTestUtils.setupAccount("parcel", false, mMockContext);
294 Bundle b = new Bundle();
295 b.putParcelable("account", account1);
296 Parcel p = Parcel.obtain();
297 b.writeToParcel(p, 0);
298 p.setDataPosition(0); // rewind it for reading
299 Bundle b2 = new Bundle(Account.class.getClassLoader());
300 b2.readFromParcel(p);
301 Account account2 = (Account) b2.getParcelable("account");
302 p.recycle();
303
304 ProviderTestUtils.assertAccountEqual("testAccountParcel", account1, account2);
305 }
306
Makoto Onukie37881a2010-03-02 13:03:27 -0800307 /**
308 * Test for {@link Account#getShortcutSafeUri()} and
Todd Kennedy040ddf62011-02-04 09:29:13 -0800309 * {@link Account#getAccountIdFromShortcutSafeUri}.
Makoto Onukie37881a2010-03-02 13:03:27 -0800310 */
311 public void testAccountShortcutSafeUri() {
312 final Account account1 = ProviderTestUtils.setupAccount("account-1", true, mMockContext);
313 final Account account2 = ProviderTestUtils.setupAccount("account-2", true, mMockContext);
314 final long account1Id = account1.mId;
315 final long account2Id = account2.mId;
316
317 final Uri uri1 = account1.getShortcutSafeUri();
318 final Uri uri2 = account2.getShortcutSafeUri();
319
320 // Check the path part of the URIs.
321 MoreAsserts.assertEquals(new String[] {"account", account1.mCompatibilityUuid},
322 uri1.getPathSegments().toArray());
323 MoreAsserts.assertEquals(new String[] {"account", account2.mCompatibilityUuid},
324 uri2.getPathSegments().toArray());
325
326 assertEquals(account1Id, Account.getAccountIdFromShortcutSafeUri(mMockContext, uri1));
327 assertEquals(account2Id, Account.getAccountIdFromShortcutSafeUri(mMockContext, uri2));
328
329 // Test for the Eclair(2.0-2.1) style URI.
330 assertEquals(account1Id, Account.getAccountIdFromShortcutSafeUri(mMockContext,
331 getEclairStyleShortcutUri(account1)));
332 assertEquals(account2Id, Account.getAccountIdFromShortcutSafeUri(mMockContext,
333 getEclairStyleShortcutUri(account2)));
334 }
335
336 private static Uri getEclairStyleShortcutUri(Account account) {
337 // We used _id instead of UUID only on Eclair(2.0-2.1).
338 return Account.CONTENT_URI.buildUpon().appendEncodedPath("" + account.mId).build();
339 }
340
Marc Blank8d8f86e2010-06-25 11:28:07 -0700341 public void testGetProtocol() {
342 Account account1 = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext);
343 // add hostauth data, with protocol
Todd Kennedyfe68c0e2011-02-17 10:27:31 -0800344 account1.mHostAuthRecv = ProviderTestUtils.setupHostAuth("eas", "account-hostauth-recv",
Marc Blank8d8f86e2010-06-25 11:28:07 -0700345 false, mMockContext);
346 // Note that getProtocol uses the receive host auth, so the protocol here shouldn't matter
347 // to the test result
Todd Kennedyfe68c0e2011-02-17 10:27:31 -0800348 account1.mHostAuthSend = ProviderTestUtils.setupHostAuth("foo", "account-hostauth-send",
Marc Blank8d8f86e2010-06-25 11:28:07 -0700349 false, mMockContext);
350 account1.save(mMockContext);
Makoto Onuki25144e22010-08-26 15:08:19 -0700351 assertEquals("eas", Account.getProtocol(mMockContext, account1.mId));
352 assertEquals("eas", account1.getProtocol(mMockContext));
Marc Blank8d8f86e2010-06-25 11:28:07 -0700353 Account account2 = ProviderTestUtils.setupAccount("account-nohostauth", false,
354 mMockContext);
355 account2.save(mMockContext);
356 // Make sure that we return null when there's no host auth
357 assertNull(Account.getProtocol(mMockContext, account2.mId));
358 assertNull(account2.getProtocol(mMockContext));
359 // And when there's no account
360 assertNull(Account.getProtocol(mMockContext, 0));
361 }
362
Makoto Onuki652be6f2010-03-02 17:49:47 -0800363 public void testAccountIsValidId() {
364 final Account account1 = ProviderTestUtils.setupAccount("account-1", true, mMockContext);
365 final Account account2 = ProviderTestUtils.setupAccount("account-2", true, mMockContext);
366
367 assertTrue(Account.isValidId(mMockContext, account1.mId));
368 assertTrue(Account.isValidId(mMockContext, account2.mId));
369
370 assertFalse(Account.isValidId(mMockContext, 1234567)); // Some random ID
Makoto Onukic133e6f2010-03-05 15:04:11 -0800371 assertFalse(Account.isValidId(mMockContext, -1));
372 assertFalse(Account.isValidId(mMockContext, -500));
Makoto Onuki652be6f2010-03-02 17:49:47 -0800373 }
374
satok41f775b2009-07-22 09:58:08 +0900375 private final static String[] MAILBOX_UNREAD_COUNT_PROJECTION = new String [] {
376 MailboxColumns.UNREAD_COUNT
377 };
378 private final static int MAILBOX_UNREAD_COUNT_COLMUN = 0;
379
380 /**
381 * Get the value of the unread count in the mailbox of the account.
382 * This can be different from the actual number of unread messages in that mailbox.
satok41f775b2009-07-22 09:58:08 +0900383 */
384 private int getUnreadCount(long mailboxId) {
385 String text = null;
386 Cursor c = null;
387 try {
388 c = mMockContext.getContentResolver().query(
389 Mailbox.CONTENT_URI,
390 MAILBOX_UNREAD_COUNT_PROJECTION,
391 EmailContent.RECORD_ID + "=?",
392 new String[] { String.valueOf(mailboxId) },
393 null);
394 c.moveToFirst();
395 text = c.getString(MAILBOX_UNREAD_COUNT_COLMUN);
396 } finally {
397 c.close();
398 }
399 return Integer.valueOf(text);
400 }
401
Andrew Stadler41192182009-07-16 16:03:40 -0700402 private static String[] expectedAttachmentNames =
Marc Blank976f9292009-07-15 15:08:53 -0700403 new String[] {"attachment1.doc", "attachment2.xls", "attachment3"};
404 // The lengths need to be kept in ascending order
Andrew Stadler41192182009-07-16 16:03:40 -0700405 private static long[] expectedAttachmentSizes = new long[] {31415L, 97701L, 151213L};
Marc Blank976f9292009-07-15 15:08:53 -0700406
Mihai Predafb7974f2009-08-03 15:05:50 +0200407 /*
408 * Returns null if the message has no body.
409 */
410 private Body loadBodyForMessageId(long messageId) {
411 Cursor c = null;
412 try {
413 c = mMockContext.getContentResolver().query(
414 EmailContent.Body.CONTENT_URI,
415 EmailContent.Body.CONTENT_PROJECTION,
416 EmailContent.Body.MESSAGE_KEY + "=?",
417 new String[] {String.valueOf(messageId)},
418 null);
419 int numBodies = c.getCount();
420 assertTrue("at most one body", numBodies < 2);
421 return c.moveToFirst() ? EmailContent.getContent(c, Body.class) : null;
422 } finally {
423 c.close();
424 }
425 }
426
Andrew Stadler7143d962009-06-25 00:02:29 -0700427 /**
428 * Test simple message save/retrieve
Marc Blank758a5322009-07-30 11:41:31 -0700429 *
Andrew Stadler7143d962009-06-25 00:02:29 -0700430 * TODO: serverId vs. serverIntId
431 */
Ben Komalo52e66112011-07-13 15:16:55 -0700432 @MediumTest
Andrew Stadler7143d962009-06-25 00:02:29 -0700433 public void testMessageSave() {
Andrew Stadler28448e72009-07-06 10:49:38 -0700434 Account account1 = ProviderTestUtils.setupAccount("message-save", true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -0700435 long account1Id = account1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -0700436 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -0700437 long box1Id = box1.mId;
438
439 // Test a simple message (saved with no body)
Andrew Stadler28448e72009-07-06 10:49:38 -0700440 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
441 true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -0700442 long message1Id = message1.mId;
443 Message message1get = EmailContent.Message.restoreMessageWithId(mMockContext, message1Id);
Andrew Stadler28448e72009-07-06 10:49:38 -0700444 ProviderTestUtils.assertMessageEqual("testMessageSave", message1, message1get);
Andrew Stadler7143d962009-06-25 00:02:29 -0700445
446 // Test a message saved with a body
447 // Note that it will read back w/o the text & html so we must extract those
Andrew Stadler28448e72009-07-06 10:49:38 -0700448 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
449 true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -0700450 long message2Id = message2.mId;
451 String text2 = message2.mText;
452 String html2 = message2.mHtml;
Andrew Stadler936babc2009-09-01 23:19:12 -0700453 String textReply2 = message2.mTextReply;
454 String htmlReply2 = message2.mHtmlReply;
Andrew Stadler6c219422009-09-10 11:52:36 -0700455 long sourceKey2 = message2.mSourceKey;
Marc Blank5fc57ec2009-09-22 18:38:28 -0700456 String introText2 = message2.mIntroText;
Andrew Stadler7143d962009-06-25 00:02:29 -0700457 message2.mText = null;
458 message2.mHtml = null;
Andrew Stadler936babc2009-09-01 23:19:12 -0700459 message2.mTextReply = null;
460 message2.mHtmlReply = null;
Marc Blanke2569832009-09-07 16:03:02 -0700461 message2.mSourceKey = 0;
Marc Blank5fc57ec2009-09-22 18:38:28 -0700462 message2.mIntroText = null;
Andrew Stadler7143d962009-06-25 00:02:29 -0700463 Message message2get = EmailContent.Message.restoreMessageWithId(mMockContext, message2Id);
Andrew Stadler28448e72009-07-06 10:49:38 -0700464 ProviderTestUtils.assertMessageEqual("testMessageSave", message2, message2get);
Marc Blank758a5322009-07-30 11:41:31 -0700465
Andrew Stadler7143d962009-06-25 00:02:29 -0700466 // Now see if there's a body saved with the right stuff
Mihai Predafb7974f2009-08-03 15:05:50 +0200467 Body body2 = loadBodyForMessageId(message2Id);
468 assertEquals("body text", text2, body2.mTextContent);
469 assertEquals("body html", html2, body2.mHtmlContent);
Andrew Stadler936babc2009-09-01 23:19:12 -0700470 assertEquals("reply text", textReply2, body2.mTextReply);
471 assertEquals("reply html", htmlReply2, body2.mHtmlReply);
Andrew Stadler6c219422009-09-10 11:52:36 -0700472 assertEquals("source key", sourceKey2, body2.mSourceKey);
Marc Blank5fc57ec2009-09-22 18:38:28 -0700473 assertEquals("intro text", introText2, body2.mIntroText);
Ben Komalo32bed4b2011-08-23 18:02:11 -0700474 }
475
476 @MediumTest
477 public void testMessageWithAttachment() {
478 Account account1 = ProviderTestUtils.setupAccount("message-save", true, mMockContext);
479 long account1Id = account1.mId;
480 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
481 long box1Id = box1.mId;
Marc Blank976f9292009-07-15 15:08:53 -0700482
Andrew Stadler41192182009-07-16 16:03:40 -0700483 // Message with attachments and body
Marc Blank976f9292009-07-15 15:08:53 -0700484 Message message3 = ProviderTestUtils.setupMessage("message3", account1Id, box1Id, true,
485 false, mMockContext);
486 ArrayList<Attachment> atts = new ArrayList<Attachment>();
487 for (int i = 0; i < 3; i++) {
Andrew Stadler41192182009-07-16 16:03:40 -0700488 atts.add(ProviderTestUtils.setupAttachment(
489 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i],
490 false, mMockContext));
Marc Blank976f9292009-07-15 15:08:53 -0700491 }
492 message3.mAttachments = atts;
Andrew Stadler9e2c6bd2009-07-22 15:13:30 -0700493 message3.save(mMockContext);
Marc Blank976f9292009-07-15 15:08:53 -0700494 long message3Id = message3.mId;
495
496 // Now check the attachments; there should be three and they should match name and size
Mihai Predafb7974f2009-08-03 15:05:50 +0200497 Cursor c = null;
Marc Blank976f9292009-07-15 15:08:53 -0700498 try {
499 // Note that there is NO guarantee of the order of returned records in the general case,
500 // so we specifically ask for ordering by size. The expectedAttachmentSizes array must
501 // be kept sorted by size (ascending) for this test to work properly
502 c = mMockContext.getContentResolver().query(
503 Attachment.CONTENT_URI,
504 Attachment.CONTENT_PROJECTION,
505 Attachment.MESSAGE_KEY + "=?",
506 new String[] {
507 String.valueOf(message3Id)
508 },
509 Attachment.SIZE);
510 int numAtts = c.getCount();
511 assertEquals(3, numAtts);
512 int i = 0;
513 while (c.moveToNext()) {
Andrew Stadler41192182009-07-16 16:03:40 -0700514 Attachment actual = EmailContent.getContent(c, Attachment.class);
515 ProviderTestUtils.assertAttachmentEqual("save-message3", atts.get(i), actual);
516 i++;
517 }
518 } finally {
519 c.close();
520 }
Ben Komalo32bed4b2011-08-23 18:02:11 -0700521 }
522
523
524 @MediumTest
525 public void testMessageSaveWithJustAttachments() {
526 Account account1 = ProviderTestUtils.setupAccount("message-save", true, mMockContext);
527 long account1Id = account1.mId;
528 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
529 long box1Id = box1.mId;
530 Cursor c = null;
Andrew Stadler41192182009-07-16 16:03:40 -0700531
532 // Message with attachments but no body
533 Message message4 = ProviderTestUtils.setupMessage("message4", account1Id, box1Id, false,
534 false, mMockContext);
Ben Komalo32bed4b2011-08-23 18:02:11 -0700535 ArrayList<Attachment> atts = new ArrayList<Attachment>();
Andrew Stadler41192182009-07-16 16:03:40 -0700536 for (int i = 0; i < 3; i++) {
537 atts.add(ProviderTestUtils.setupAttachment(
538 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i],
539 false, mMockContext));
540 }
541 message4.mAttachments = atts;
Andrew Stadler9e2c6bd2009-07-22 15:13:30 -0700542 message4.save(mMockContext);
Andrew Stadler41192182009-07-16 16:03:40 -0700543 long message4Id = message4.mId;
544
545 // Now check the attachments; there should be three and they should match name and size
546 c = null;
satok41f775b2009-07-22 09:58:08 +0900547
Andrew Stadler41192182009-07-16 16:03:40 -0700548 try {
549 // Note that there is NO guarantee of the order of returned records in the general case,
550 // so we specifically ask for ordering by size. The expectedAttachmentSizes array must
551 // be kept sorted by size (ascending) for this test to work properly
552 c = mMockContext.getContentResolver().query(
553 Attachment.CONTENT_URI,
554 Attachment.CONTENT_PROJECTION,
555 Attachment.MESSAGE_KEY + "=?",
556 new String[] {
557 String.valueOf(message4Id)
558 },
559 Attachment.SIZE);
560 int numAtts = c.getCount();
561 assertEquals(3, numAtts);
562 int i = 0;
563 while (c.moveToNext()) {
564 Attachment actual = EmailContent.getContent(c, Attachment.class);
565 ProviderTestUtils.assertAttachmentEqual("save-message4", atts.get(i), actual);
Marc Blank976f9292009-07-15 15:08:53 -0700566 i++;
567 }
568 } finally {
569 c.close();
Andrew Stadler7143d962009-06-25 00:02:29 -0700570 }
Mihai Preda44144d02009-08-18 18:55:59 +0200571
572 // test EmailContent.restoreAttachmentsWitdMessageId()
573 Attachment[] attachments =
574 Attachment.restoreAttachmentsWithMessageId(mMockContext, message4Id);
575 int size = attachments.length;
576 assertEquals(3, size);
577 for (int i = 0; i < size; ++i) {
578 ProviderTestUtils.assertAttachmentEqual("save-message4", atts.get(i), attachments[i]);
579 }
Andrew Stadler7143d962009-06-25 00:02:29 -0700580 }
Marc Blank758a5322009-07-30 11:41:31 -0700581
Andrew Stadler7143d962009-06-25 00:02:29 -0700582 /**
Marc Blanke7b9e4a2010-09-01 19:06:15 -0700583 * Test that saving a message creates the proper snippet for that message
584 */
585 public void testMessageSaveAddsSnippet() {
586 Account account = ProviderTestUtils.setupAccount("message-snippet", true, mMockContext);
587 Mailbox box = ProviderTestUtils.setupMailbox("box1", account.mId, true, mMockContext);
588
589 // Create a message without a body, unsaved
590 Message message = ProviderTestUtils.setupMessage("message", account.mId, box.mId, false,
591 false, mMockContext);
592 message.mText = "This is some text";
593 message.mHtml = "<html>This is some text</html>";
594 message.save(mMockContext);
595 Message restoredMessage = Message.restoreMessageWithId(mMockContext, message.mId);
596 // We should have the plain text as the snippet
Marc Blank76f61472011-03-26 19:19:35 -0700597 assertEquals(restoredMessage.mSnippet,
598 TextUtilities.makeSnippetFromPlainText(message.mText));
Marc Blanke7b9e4a2010-09-01 19:06:15 -0700599
600 // Start again
601 message = ProviderTestUtils.setupMessage("message", account.mId, box.mId, false,
602 false, mMockContext);
603 message.mText = null;
604 message.mHtml = "<html>This is some text</html>";
605 message.save(mMockContext);
606 restoredMessage = Message.restoreMessageWithId(mMockContext, message.mId);
607 // We should have the plain text as the snippet
Marc Blank76f61472011-03-26 19:19:35 -0700608 assertEquals(restoredMessage.mSnippet,
609 TextUtilities.makeSnippetFromHtmlText(message.mHtml));
Marc Blanke7b9e4a2010-09-01 19:06:15 -0700610 }
611
612 /**
Andrew Stadler7143d962009-06-25 00:02:29 -0700613 * TODO: update account
614 */
Marc Blank758a5322009-07-30 11:41:31 -0700615
Andrew Stadler7143d962009-06-25 00:02:29 -0700616 /**
617 * TODO: update mailbox
618 */
Marc Blank758a5322009-07-30 11:41:31 -0700619
Andrew Stadler7143d962009-06-25 00:02:29 -0700620 /**
621 * TODO: update message
622 */
Marc Blank758a5322009-07-30 11:41:31 -0700623
Andrew Stadler7143d962009-06-25 00:02:29 -0700624 /**
625 * Test delete account
626 * TODO: hostauth
627 */
628 public void testAccountDelete() {
Andrew Stadler28448e72009-07-06 10:49:38 -0700629 Account account1 = ProviderTestUtils.setupAccount("account-delete-1", true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -0700630 long account1Id = account1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -0700631 Account account2 = ProviderTestUtils.setupAccount("account-delete-2", true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -0700632 long account2Id = account2.mId;
633
634 // make sure there are two accounts
635 int numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null);
636 assertEquals(2, numBoxes);
637
638 // now delete one of them
639 Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id);
640 mMockContext.getContentResolver().delete(uri, null, null);
641
642 // make sure there's only one account now
643 numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null);
644 assertEquals(1, numBoxes);
645
646 // now delete the other one
647 uri = ContentUris.withAppendedId(Account.CONTENT_URI, account2Id);
648 mMockContext.getContentResolver().delete(uri, null, null);
649
650 // make sure there are no accounts now
651 numBoxes = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null);
652 assertEquals(0, numBoxes);
653 }
Marc Blank758a5322009-07-30 11:41:31 -0700654
Andrew Stadler7143d962009-06-25 00:02:29 -0700655 /**
Mihai Preda9627d012009-08-12 12:51:26 +0200656 * Test for Body.lookupBodyIdWithMessageId()
657 * Verifies that:
658 * - for a message without body, -1 is returned.
659 * - for a mesage with body, the id matches the one from loadBodyForMessageId.
660 */
661 public void testLookupBodyIdWithMessageId() {
662 final ContentResolver resolver = mMockContext.getContentResolver();
663 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext);
664 long account1Id = account1.mId;
665 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
666 long box1Id = box1.mId;
667
668 // 1. create message with no body, check that returned bodyId is -1
669 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
670 true, mMockContext);
671 long message1Id = message1.mId;
Makoto Onukibcf32322010-07-27 12:52:46 -0700672 long bodyId1 = Body.lookupBodyIdWithMessageId(mMockContext, message1Id);
Mihai Preda9627d012009-08-12 12:51:26 +0200673 assertEquals(bodyId1, -1);
674
675 // 2. create message with body, check that returned bodyId is correct
676 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
677 true, mMockContext);
678 long message2Id = message2.mId;
Makoto Onukibcf32322010-07-27 12:52:46 -0700679 long bodyId2 = Body.lookupBodyIdWithMessageId(mMockContext, message2Id);
Mihai Preda9627d012009-08-12 12:51:26 +0200680 Body body = loadBodyForMessageId(message2Id);
681 assertNotNull(body);
682 assertEquals(body.mId, bodyId2);
683 }
684
685 /**
686 * Test for Body.updateBodyWithMessageId().
687 * 1. - create message without body,
688 * - update its body (set TEXT_CONTENT)
689 * - check correct updated body is read back
690 *
691 * 2. - create message with body,
692 * - update body (set TEXT_CONTENT)
693 * - check correct updated body is read back
694 */
695 public void testUpdateBodyWithMessageId() {
696 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext);
697 long account1Id = account1.mId;
698 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
699 long box1Id = box1.mId;
700
701 final String textContent = "foobar some odd text";
Andrew Stadler936babc2009-09-01 23:19:12 -0700702 final String htmlContent = "and some html";
703 final String textReply = "plain text reply";
704 final String htmlReply = "or the html reply";
Marc Blank5fc57ec2009-09-22 18:38:28 -0700705 final String introText = "fred wrote:";
Mihai Preda9627d012009-08-12 12:51:26 +0200706
707 ContentValues values = new ContentValues();
708 values.put(BodyColumns.TEXT_CONTENT, textContent);
Andrew Stadler936babc2009-09-01 23:19:12 -0700709 values.put(BodyColumns.HTML_CONTENT, htmlContent);
710 values.put(BodyColumns.TEXT_REPLY, textReply);
711 values.put(BodyColumns.HTML_REPLY, htmlReply);
Marc Blanke2569832009-09-07 16:03:02 -0700712 values.put(BodyColumns.SOURCE_MESSAGE_KEY, 17);
Marc Blank5fc57ec2009-09-22 18:38:28 -0700713 values.put(BodyColumns.INTRO_TEXT, introText);
Mihai Preda9627d012009-08-12 12:51:26 +0200714
715 // 1
716 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
717 true, mMockContext);
718 long message1Id = message1.mId;
719 Body body1 = loadBodyForMessageId(message1Id);
720 assertNull(body1);
721 Body.updateBodyWithMessageId(mMockContext, message1Id, values);
722 body1 = loadBodyForMessageId(message1Id);
723 assertNotNull(body1);
724 assertEquals(body1.mTextContent, textContent);
Andrew Stadler936babc2009-09-01 23:19:12 -0700725 assertEquals(body1.mHtmlContent, htmlContent);
726 assertEquals(body1.mTextReply, textReply);
727 assertEquals(body1.mHtmlReply, htmlReply);
Marc Blanke2569832009-09-07 16:03:02 -0700728 assertEquals(body1.mSourceKey, 17);
Marc Blank5fc57ec2009-09-22 18:38:28 -0700729 assertEquals(body1.mIntroText, introText);
Mihai Preda9627d012009-08-12 12:51:26 +0200730
731 // 2
732 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
733 true, mMockContext);
734 long message2Id = message2.mId;
735 Body body2 = loadBodyForMessageId(message2Id);
736 assertNotNull(body2);
737 assertTrue(!body2.mTextContent.equals(textContent));
738 Body.updateBodyWithMessageId(mMockContext, message2Id, values);
739 body2 = loadBodyForMessageId(message1Id);
740 assertNotNull(body2);
741 assertEquals(body2.mTextContent, textContent);
Andrew Stadler936babc2009-09-01 23:19:12 -0700742 assertEquals(body2.mHtmlContent, htmlContent);
743 assertEquals(body2.mTextReply, textReply);
744 assertEquals(body2.mHtmlReply, htmlReply);
Marc Blanke2569832009-09-07 16:03:02 -0700745 assertEquals(body2.mSourceKey, 17);
Marc Blank5fc57ec2009-09-22 18:38:28 -0700746 assertEquals(body2.mIntroText, introText);
Mihai Preda9627d012009-08-12 12:51:26 +0200747 }
748
749 /**
Andrew Stadlerc41c47f2009-09-25 14:54:32 -0700750 * Test body retrieve methods
751 */
752 public void testBodyRetrieve() {
753 // No account needed
754 // No mailbox needed
755 Message message1 = ProviderTestUtils.setupMessage("bodyretrieve", 1, 1, true,
756 true, mMockContext);
757 long messageId = message1.mId;
758
759 assertEquals(message1.mText,
760 Body.restoreBodyTextWithMessageId(mMockContext, messageId));
761 assertEquals(message1.mHtml,
762 Body.restoreBodyHtmlWithMessageId(mMockContext, messageId));
763 assertEquals(message1.mTextReply,
764 Body.restoreReplyTextWithMessageId(mMockContext, messageId));
765 assertEquals(message1.mHtmlReply,
766 Body.restoreReplyHtmlWithMessageId(mMockContext, messageId));
767 assertEquals(message1.mIntroText,
768 Body.restoreIntroTextWithMessageId(mMockContext, messageId));
Mihai Preda1575e782010-02-15 14:56:40 +0100769 assertEquals(message1.mSourceKey,
770 Body.restoreBodySourceKey(mMockContext, messageId));
Andrew Stadlerc41c47f2009-09-25 14:54:32 -0700771 }
772
773 /**
Mihai Predafb7974f2009-08-03 15:05:50 +0200774 * Test delete body.
775 * 1. create message without body (message id 1)
776 * 2. create message with body (message id 2. The body has _id 1 and messageKey 2).
777 * 3. delete first message.
778 * 4. verify that body for message 2 has not been deleted.
779 * 5. delete message 2, verify body is deleted.
780 */
781 public void testDeleteBody() {
782 final ContentResolver resolver = mMockContext.getContentResolver();
783
784 // Create account and mailboxes
785 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext);
786 long account1Id = account1.mId;
787 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
788 long box1Id = box1.mId;
789
790 // 1. create message without body
791 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
792 true, mMockContext);
793 long message1Id = message1.mId;
794
795 // 2. create message with body
796 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
797 true, mMockContext);
798 long message2Id = message2.mId;
799 // verify body is there
800 assertNotNull(loadBodyForMessageId(message2Id));
801
802 // 3. delete first message
803 resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message1Id), null, null);
Marc Blankc0c9c332009-08-19 19:07:29 -0700804
Mihai Predafb7974f2009-08-03 15:05:50 +0200805 // 4. verify body for second message wasn't deleted
806 assertNotNull(loadBodyForMessageId(message2Id));
807
808 // 5. delete second message, check its body is deleted
809 resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message2Id), null, null);
810 assertNull(loadBodyForMessageId(message2Id));
811 }
812
813 /**
814 * Test delete orphan bodies.
815 * 1. create message without body (message id 1)
816 * 2. create message with body (message id 2. Body has _id 1 and messageKey 2).
817 * 3. delete first message.
818 * 4. delete some other mailbox -- this triggers delete orphan bodies.
819 * 5. verify that body for message 2 has not been deleted.
820 */
821 public void testDeleteOrphanBodies() {
822 final ContentResolver resolver = mMockContext.getContentResolver();
823
Marc Blankef832992009-10-13 16:25:00 -0700824 // Create account and two mailboxes
Mihai Predafb7974f2009-08-03 15:05:50 +0200825 Account account1 = ProviderTestUtils.setupAccount("orphaned body", true, mMockContext);
826 long account1Id = account1.mId;
827 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
828 long box1Id = box1.mId;
829 Mailbox box2 = ProviderTestUtils.setupMailbox("box2", account1Id, true, mMockContext);
830 long box2Id = box2.mId;
831
832 // 1. create message without body
833 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
834 true, mMockContext);
835 long message1Id = message1.mId;
836
837 // 2. create message with body
838 Message message2 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
839 true, mMockContext);
840 long message2Id = message2.mId;
841 //verify body is there
Mihai Predafb7974f2009-08-03 15:05:50 +0200842 assertNotNull(loadBodyForMessageId(message2Id));
843
844 // 3. delete first message
845 resolver.delete(ContentUris.withAppendedId(Message.CONTENT_URI, message1Id), null, null);
846
847 // 4. delete some mailbox (because it triggers "delete orphan bodies")
848 resolver.delete(ContentUris.withAppendedId(Mailbox.CONTENT_URI, box2Id), null, null);
849
850 // 5. verify body for second message wasn't deleted during "delete orphan bodies"
851 assertNotNull(loadBodyForMessageId(message2Id));
852 }
853
854 /**
Marc Blank0efe7382010-09-27 18:29:50 -0700855 * Note that we can't use EmailContent.count() here because it uses a projection including
856 * count(*), and count(*) is incompatible with a LIMIT (i.e. the limit would be applied to the
857 * single column returned with count(*), rather than to the query itself)
858 */
859 private int count(Context context, Uri uri, String selection, String[] selectionArgs) {
860 Cursor c = context.getContentResolver().query(uri, EmailContent.ID_PROJECTION, selection,
861 selectionArgs, null);
862 try {
863 return c.getCount();
864 } finally {
865 c.close();
866 }
867 }
868
869 public void testMessageQueryWithLimit() {
870 final Context context = mMockContext;
871
872 // Create account and two mailboxes
873 Account acct = ProviderTestUtils.setupAccount("orphaned body", true, context);
874 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context);
875 Mailbox box2 = ProviderTestUtils.setupMailbox("box2", acct.mId, true, context);
876
877 // Create 4 messages in box1
878 ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, false, true, context);
879 ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, false, true, context);
880 ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, false, true, context);
881 ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, false, true, context);
882
883 // Create 4 messages in box2
884 ProviderTestUtils.setupMessage("message1", acct.mId, box2.mId, false, true, context);
885 ProviderTestUtils.setupMessage("message2", acct.mId, box2.mId, false, true, context);
886 ProviderTestUtils.setupMessage("message3", acct.mId, box2.mId, false, true, context);
887 ProviderTestUtils.setupMessage("message4", acct.mId, box2.mId, false, true, context);
888
889 // Check normal case, special case (limit 1), and arbitrary limits
890 assertEquals(8, count(mMockContext, Message.CONTENT_URI, null, null));
891 assertEquals(1, count(mMockContext, EmailContent.uriWithLimit(Message.CONTENT_URI, 1),
892 null, null));
893 assertEquals(3, count(mMockContext, EmailContent.uriWithLimit(Message.CONTENT_URI, 3),
894 null, null));
895 assertEquals(8, count(mMockContext, EmailContent.uriWithLimit(Message.CONTENT_URI, 100),
896 null, null));
897
898 // Check that it works with selection/selection args
899 String[] args = new String[] {Long.toString(box1.mId)};
900 assertEquals(4, count(mMockContext, Message.CONTENT_URI,
901 MessageColumns.MAILBOX_KEY + "=?", args));
902 assertEquals(1, count(mMockContext,
903 EmailContent.uriWithLimit(Message.CONTENT_URI, 1),
904 MessageColumns.MAILBOX_KEY + "=?", args));
905 }
906
907 /**
Marc Blankef832992009-10-13 16:25:00 -0700908 * Test delete orphan messages
909 * 1. create message without body (message id 1)
910 * 2. create message with body (message id 2. Body has _id 1 and messageKey 2).
911 * 3. delete first message.
912 * 4. delete some other mailbox -- this triggers delete orphan bodies.
913 * 5. verify that body for message 2 has not been deleted.
914 */
915 public void testDeleteOrphanMessages() {
916 final ContentResolver resolver = mMockContext.getContentResolver();
917 final Context context = mMockContext;
918
919 // Create account and two mailboxes
920 Account acct = ProviderTestUtils.setupAccount("orphaned body", true, context);
921 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context);
922 Mailbox box2 = ProviderTestUtils.setupMailbox("box2", acct.mId, true, context);
923
924 // Create 4 messages in box1
925 Message msg1_1 =
926 ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, false, true, context);
927 Message msg1_2 =
928 ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, false, true, context);
929 Message msg1_3 =
930 ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, false, true, context);
931 Message msg1_4 =
932 ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, false, true, context);
933
934 // Create 4 messages in box2
935 Message msg2_1 =
936 ProviderTestUtils.setupMessage("message1", acct.mId, box2.mId, false, true, context);
937 Message msg2_2 =
938 ProviderTestUtils.setupMessage("message2", acct.mId, box2.mId, false, true, context);
939 Message msg2_3 =
940 ProviderTestUtils.setupMessage("message3", acct.mId, box2.mId, false, true, context);
941 Message msg2_4 =
942 ProviderTestUtils.setupMessage("message4", acct.mId, box2.mId, false, true, context);
943
944 // Delete 2 from each mailbox
945 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_1.mId),
946 null, null);
947 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_2.mId),
948 null, null);
949 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_1.mId),
950 null, null);
951 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_2.mId),
952 null, null);
953
954 // There should be 4 items in the deleted item table
955 assertEquals(4, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null));
956
957 // Update 2 from each mailbox
958 ContentValues v = new ContentValues();
959 v.put(MessageColumns.DISPLAY_NAME, "--updated--");
960 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_3.mId),
961 v, null, null);
962 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg1_4.mId),
963 v, null, null);
964 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_3.mId),
965 v, null, null);
966 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, msg2_4.mId),
967 v, null, null);
968
969 // There should be 4 items in the updated item table
970 assertEquals(4, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null));
971
972 // Manually add 2 messages from a "deleted" mailbox to deleted and updated tables
973 // Use a value > 2 for the deleted box id
974 long delBoxId = 10;
975 // Create 4 messages in the "deleted" mailbox
976 Message msgX_A =
977 ProviderTestUtils.setupMessage("messageA", acct.mId, delBoxId, false, false, context);
978 Message msgX_B =
979 ProviderTestUtils.setupMessage("messageB", acct.mId, delBoxId, false, false, context);
980 Message msgX_C =
981 ProviderTestUtils.setupMessage("messageC", acct.mId, delBoxId, false, false, context);
982 Message msgX_D =
983 ProviderTestUtils.setupMessage("messageD", acct.mId, delBoxId, false, false, context);
984
985 ContentValues cv;
986 // We have to assign id's manually because there are no autoincrement id's for these tables
987 // Start with an id that won't exist, since id's in these tables must be unique
988 long msgId = 10;
989 // It's illegal to manually insert these, so we need to catch the exception
990 // NOTE: The insert succeeds, and then throws the exception
991 try {
992 cv = msgX_A.toContentValues();
993 cv.put(EmailContent.RECORD_ID, msgId++);
994 resolver.insert(Message.DELETED_CONTENT_URI, cv);
995 } catch (IllegalArgumentException e) {
996 }
997 try {
998 cv = msgX_B.toContentValues();
999 cv.put(EmailContent.RECORD_ID, msgId++);
1000 resolver.insert(Message.DELETED_CONTENT_URI, cv);
1001 } catch (IllegalArgumentException e) {
1002 }
1003 try {
1004 cv = msgX_C.toContentValues();
1005 cv.put(EmailContent.RECORD_ID, msgId++);
1006 resolver.insert(Message.UPDATED_CONTENT_URI, cv);
1007 } catch (IllegalArgumentException e) {
1008 }
1009 try {
1010 cv = msgX_D.toContentValues();
1011 cv.put(EmailContent.RECORD_ID, msgId++);
1012 resolver.insert(Message.UPDATED_CONTENT_URI, cv);
1013 } catch (IllegalArgumentException e) {
1014 }
1015
1016 // There should be 6 items in the deleted and updated tables
1017 assertEquals(6, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null));
1018 assertEquals(6, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null));
1019
1020 // Delete the orphans
Marc Blank2bdf7ee2011-06-30 16:03:36 -07001021 EmailProvider.deleteMessageOrphans(EmailProvider.getReadableDatabase(context),
Marc Blankef832992009-10-13 16:25:00 -07001022 Message.DELETED_TABLE_NAME);
Marc Blank2bdf7ee2011-06-30 16:03:36 -07001023 EmailProvider.deleteMessageOrphans(EmailProvider.getReadableDatabase(context),
Marc Blankef832992009-10-13 16:25:00 -07001024 Message.UPDATED_TABLE_NAME);
1025
1026 // There should now be 4 messages in each of the deleted and updated tables again
1027 assertEquals(4, EmailContent.count(context, Message.UPDATED_CONTENT_URI, null, null));
1028 assertEquals(4, EmailContent.count(context, Message.DELETED_CONTENT_URI, null, null));
1029 }
1030
1031 /**
Andrew Stadler7143d962009-06-25 00:02:29 -07001032 * Test delete message
1033 * TODO: body
1034 * TODO: attachments
1035 */
1036 public void testMessageDelete() {
Andrew Stadler28448e72009-07-06 10:49:38 -07001037 Account account1 = ProviderTestUtils.setupAccount("message-delete", true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -07001038 long account1Id = account1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001039 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -07001040 long box1Id = box1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001041 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
1042 true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -07001043 long message1Id = message1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001044 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false,
1045 true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -07001046 long message2Id = message2.mId;
1047
1048 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " +
1049 EmailContent.MessageColumns.MAILBOX_KEY + "=?";
1050 String[] selArgs = new String[] { String.valueOf(account1Id), String.valueOf(box1Id) };
1051
1052 // make sure there are two messages
1053 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
1054 assertEquals(2, numMessages);
1055
1056 // now delete one of them
1057 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id);
1058 mMockContext.getContentResolver().delete(uri, null, null);
1059
1060 // make sure there's only one message now
1061 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
1062 assertEquals(1, numMessages);
1063
1064 // now delete the other one
1065 uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id);
1066 mMockContext.getContentResolver().delete(uri, null, null);
1067
1068 // make sure there are no messages now
1069 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
1070 assertEquals(0, numMessages);
1071 }
Marc Blank758a5322009-07-30 11:41:31 -07001072
Andrew Stadler7143d962009-06-25 00:02:29 -07001073 /**
Andrew Stadlerddc871d2009-06-29 23:08:40 -07001074 * Test delete synced message
1075 * TODO: body
1076 * TODO: attachments
1077 */
1078 public void testSyncedMessageDelete() {
Andrew Stadler28448e72009-07-06 10:49:38 -07001079 Account account1 = ProviderTestUtils.setupAccount("synced-message-delete", true,
1080 mMockContext);
Andrew Stadlerddc871d2009-06-29 23:08:40 -07001081 long account1Id = account1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001082 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
Andrew Stadlerddc871d2009-06-29 23:08:40 -07001083 long box1Id = box1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001084 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
1085 true, mMockContext);
Andrew Stadlerddc871d2009-06-29 23:08:40 -07001086 long message1Id = message1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001087 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false,
1088 true, mMockContext);
Andrew Stadlerddc871d2009-06-29 23:08:40 -07001089 long message2Id = message2.mId;
1090
1091 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND "
1092 + EmailContent.MessageColumns.MAILBOX_KEY + "=?";
1093 String[] selArgs = new String[] {
1094 String.valueOf(account1Id), String.valueOf(box1Id)
1095 };
1096
1097 // make sure there are two messages
1098 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
1099 assertEquals(2, numMessages);
1100
1101 // make sure we start with no synced deletions
1102 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
1103 selArgs);
1104 assertEquals(0, numMessages);
1105
1106 // now delete one of them SYNCED
1107 Uri uri = ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message1Id);
1108 mMockContext.getContentResolver().delete(uri, null, null);
1109
1110 // make sure there's only one message now
1111 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
1112 assertEquals(1, numMessages);
1113
1114 // make sure there's one synced deletion now
1115 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
1116 selArgs);
1117 assertEquals(1, numMessages);
1118
1119 // now delete the other one NOT SYNCED
1120 uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id);
1121 mMockContext.getContentResolver().delete(uri, null, null);
1122
1123 // make sure there are no messages now
1124 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
1125 assertEquals(0, numMessages);
1126
1127 // make sure there's still one deletion now
1128 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
1129 selArgs);
1130 assertEquals(1, numMessages);
1131 }
1132
1133 /**
1134 * Test message update
1135 * TODO: body
1136 * TODO: attachments
1137 */
1138 public void testMessageUpdate() {
Andrew Stadler28448e72009-07-06 10:49:38 -07001139 Account account1 = ProviderTestUtils.setupAccount("message-update", true, mMockContext);
Andrew Stadlerddc871d2009-06-29 23:08:40 -07001140 long account1Id = account1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001141 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
Andrew Stadlerddc871d2009-06-29 23:08:40 -07001142 long box1Id = box1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001143 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, false,
1144 true, mMockContext);
Andrew Stadlerddc871d2009-06-29 23:08:40 -07001145 long message1Id = message1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001146 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, false,
1147 true, mMockContext);
Andrew Stadlerddc871d2009-06-29 23:08:40 -07001148 long message2Id = message2.mId;
1149 ContentResolver cr = mMockContext.getContentResolver();
1150
1151 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND "
1152 + EmailContent.MessageColumns.MAILBOX_KEY + "=?";
1153 String[] selArgs = new String[] {
1154 String.valueOf(account1Id), String.valueOf(box1Id)
1155 };
1156
1157 // make sure there are two messages
1158 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
1159 assertEquals(2, numMessages);
1160
1161 // change the first one
1162 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id);
1163 ContentValues cv = new ContentValues();
1164 cv.put(MessageColumns.FROM_LIST, "from-list");
1165 cr.update(uri, cv, null, null);
1166
1167 // make sure there's no updated message
1168 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
1169 selArgs);
1170 assertEquals(0, numMessages);
1171
1172 // get the message back from the provider, make sure the change "stuck"
1173 Message restoredMessage = Message.restoreMessageWithId(mMockContext, message1Id);
1174 assertEquals("from-list", restoredMessage.mFrom);
1175
1176 // change the second one
1177 uri = ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2Id);
1178 cv = new ContentValues();
1179 cv.put(MessageColumns.FROM_LIST, "from-list");
1180 cr.update(uri, cv, null, null);
1181
1182 // make sure there's one updated message
1183 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
1184 selArgs);
1185 assertEquals(1, numMessages);
1186
1187 // get the message back from the provider, make sure the change "stuck",
1188 // as before
1189 restoredMessage = Message.restoreMessageWithId(mMockContext, message2Id);
1190 assertEquals("from-list", restoredMessage.mFrom);
1191
1192 // get the original message back from the provider
1193 Cursor c = cr.query(Message.UPDATED_CONTENT_URI, Message.CONTENT_PROJECTION, null, null,
1194 null);
1195 try {
1196 assertTrue(c.moveToFirst());
1197 Message originalMessage = EmailContent.getContent(c, Message.class);
1198 // make sure this has the original value
1199 assertEquals("from message2", originalMessage.mFrom);
1200 // Should only be one
1201 assertFalse(c.moveToNext());
1202 } finally {
1203 c.close();
1204 }
1205
1206 // delete the second message
1207 cr.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2Id), null, null);
1208
1209 // hey, presto! the change should be gone
1210 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
1211 selArgs);
1212 assertEquals(0, numMessages);
1213
1214 // and there should now be a deleted record
1215 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
1216 selArgs);
1217 assertEquals(1, numMessages);
1218 }
1219
1220 /**
Andrew Stadler7143d962009-06-25 00:02:29 -07001221 * TODO: cascaded delete account
1222 * TODO: hostauth
1223 * TODO: body
1224 * TODO: attachments
1225 * TODO: create other account, mailbox & messages and confirm the right objects were deleted
1226 */
1227 public void testCascadeDeleteAccount() {
Andrew Stadler28448e72009-07-06 10:49:38 -07001228 Account account1 = ProviderTestUtils.setupAccount("account-delete-cascade", true,
1229 mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -07001230 long account1Id = account1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001231 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -07001232 long box1Id = box1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001233 /* Message message1 = */ ProviderTestUtils.setupMessage("message1", account1Id, box1Id,
1234 false, true, mMockContext);
1235 /* Message message2 = */ ProviderTestUtils.setupMessage("message2", account1Id, box1Id,
1236 false, true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -07001237
1238 // make sure there is one account, one mailbox, and two messages
1239 int numAccounts = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null);
1240 assertEquals(1, numAccounts);
1241 int numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, null, null);
1242 assertEquals(1, numBoxes);
1243 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
1244 assertEquals(2, numMessages);
1245
1246 // delete the account
1247 Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id);
1248 mMockContext.getContentResolver().delete(uri, null, null);
1249
1250 // make sure there are no accounts, mailboxes, or messages
1251 numAccounts = EmailContent.count(mMockContext, Account.CONTENT_URI, null, null);
1252 assertEquals(0, numAccounts);
1253 numBoxes = EmailContent.count(mMockContext, Mailbox.CONTENT_URI, null, null);
1254 assertEquals(0, numBoxes);
1255 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
1256 assertEquals(0, numMessages);
1257 }
Marc Blank758a5322009-07-30 11:41:31 -07001258
Andrew Stadler7143d962009-06-25 00:02:29 -07001259 /**
1260 * Test cascaded delete mailbox
1261 * TODO: body
1262 * TODO: attachments
1263 * TODO: create other mailbox & messages and confirm the right objects were deleted
1264 */
1265 public void testCascadeDeleteMailbox() {
Andrew Stadler28448e72009-07-06 10:49:38 -07001266 Account account1 = ProviderTestUtils.setupAccount("mailbox-delete-cascade", true,
1267 mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -07001268 long account1Id = account1.mId;
Andrew Stadler28448e72009-07-06 10:49:38 -07001269 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -07001270 long box1Id = box1.mId;
Marc Blankef832992009-10-13 16:25:00 -07001271 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id,
Andrew Stadler28448e72009-07-06 10:49:38 -07001272 false, true, mMockContext);
Marc Blankef832992009-10-13 16:25:00 -07001273 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id,
Andrew Stadler28448e72009-07-06 10:49:38 -07001274 false, true, mMockContext);
Marc Blankef832992009-10-13 16:25:00 -07001275 Message message3 = ProviderTestUtils.setupMessage("message3", account1Id, box1Id,
1276 false, true, mMockContext);
1277 Message message4 = ProviderTestUtils.setupMessage("message4", account1Id, box1Id,
1278 false, true, mMockContext);
1279 ProviderTestUtils.setupMessage("message5", account1Id, box1Id, false, true, mMockContext);
1280 ProviderTestUtils.setupMessage("message6", account1Id, box1Id, false, true, mMockContext);
Andrew Stadler7143d962009-06-25 00:02:29 -07001281
1282 String selection = EmailContent.MessageColumns.ACCOUNT_KEY + "=? AND " +
1283 EmailContent.MessageColumns.MAILBOX_KEY + "=?";
1284 String[] selArgs = new String[] { String.valueOf(account1Id), String.valueOf(box1Id) };
1285
Marc Blank0e1595c2009-11-18 17:11:33 -08001286 // make sure there are six messages
Andrew Stadler7143d962009-06-25 00:02:29 -07001287 int numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
Marc Blankef832992009-10-13 16:25:00 -07001288 assertEquals(6, numMessages);
1289
1290 ContentValues cv = new ContentValues();
1291 cv.put(Message.SERVER_ID, "SERVER_ID");
1292 ContentResolver resolver = mMockContext.getContentResolver();
1293
1294 // Update two messages
1295 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message1.mId),
1296 cv, null, null);
1297 resolver.update(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message2.mId),
1298 cv, null, null);
1299 // Delete two messages
1300 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message3.mId),
1301 null, null);
1302 resolver.delete(ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, message4.mId),
1303 null, null);
1304
1305 // There should now be two messages in updated/deleted, and 4 in messages
1306 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
1307 assertEquals(4, numMessages);
1308 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
1309 selArgs);
1310 assertEquals(2, numMessages);
1311 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
1312 selArgs);
Andrew Stadler7143d962009-06-25 00:02:29 -07001313 assertEquals(2, numMessages);
Marc Blank758a5322009-07-30 11:41:31 -07001314
Andrew Stadler7143d962009-06-25 00:02:29 -07001315 // now delete the mailbox
1316 Uri uri = ContentUris.withAppendedId(Mailbox.CONTENT_URI, box1Id);
Marc Blankef832992009-10-13 16:25:00 -07001317 resolver.delete(uri, null, null);
Marc Blank758a5322009-07-30 11:41:31 -07001318
Marc Blankef832992009-10-13 16:25:00 -07001319 // there should now be zero messages in all three tables
Andrew Stadler7143d962009-06-25 00:02:29 -07001320 numMessages = EmailContent.count(mMockContext, Message.CONTENT_URI, selection, selArgs);
1321 assertEquals(0, numMessages);
Marc Blankef832992009-10-13 16:25:00 -07001322 numMessages = EmailContent.count(mMockContext, Message.DELETED_CONTENT_URI, selection,
1323 selArgs);
1324 assertEquals(0, numMessages);
1325 numMessages = EmailContent.count(mMockContext, Message.UPDATED_CONTENT_URI, selection,
1326 selArgs);
1327 assertEquals(0, numMessages);
Andrew Stadler7143d962009-06-25 00:02:29 -07001328 }
Marc Blank758a5322009-07-30 11:41:31 -07001329
Andrew Stadler7143d962009-06-25 00:02:29 -07001330 /**
Andrew Stadler6c219422009-09-10 11:52:36 -07001331 * Test cascaded delete message
1332 * Confirms that deleting a message will also delete its body & attachments
Andrew Stadler7143d962009-06-25 00:02:29 -07001333 */
Andrew Stadler6c219422009-09-10 11:52:36 -07001334 public void testCascadeMessageDelete() {
1335 Account account1 = ProviderTestUtils.setupAccount("message-cascade", true, mMockContext);
1336 long account1Id = account1.mId;
1337 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", account1Id, true, mMockContext);
1338 long box1Id = box1.mId;
Makoto Onukibcf32322010-07-27 12:52:46 -07001339
Andrew Stadler6c219422009-09-10 11:52:36 -07001340 // Each message has a body, and also give each 2 attachments
1341 Message message1 = ProviderTestUtils.setupMessage("message1", account1Id, box1Id, true,
1342 false, mMockContext);
1343 ArrayList<Attachment> atts = new ArrayList<Attachment>();
1344 for (int i = 0; i < 2; i++) {
1345 atts.add(ProviderTestUtils.setupAttachment(
1346 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i],
1347 false, mMockContext));
1348 }
1349 message1.mAttachments = atts;
1350 message1.save(mMockContext);
1351 long message1Id = message1.mId;
1352
1353 Message message2 = ProviderTestUtils.setupMessage("message2", account1Id, box1Id, true,
1354 false, mMockContext);
1355 atts = new ArrayList<Attachment>();
1356 for (int i = 0; i < 2; i++) {
1357 atts.add(ProviderTestUtils.setupAttachment(
1358 -1, expectedAttachmentNames[i], expectedAttachmentSizes[i],
1359 false, mMockContext));
1360 }
1361 message2.mAttachments = atts;
1362 message2.save(mMockContext);
1363 long message2Id = message2.mId;
1364
1365 // Set up to test total counts of bodies & attachments for our test messages
1366 String bodySelection = BodyColumns.MESSAGE_KEY + " IN (?,?)";
1367 String attachmentSelection = AttachmentColumns.MESSAGE_KEY + " IN (?,?)";
1368 String[] selArgs = new String[] { String.valueOf(message1Id), String.valueOf(message2Id) };
Makoto Onukibcf32322010-07-27 12:52:46 -07001369
Andrew Stadler6c219422009-09-10 11:52:36 -07001370 // make sure there are two bodies
1371 int numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs);
1372 assertEquals(2, numBodies);
1373
1374 // make sure there are four attachments
1375 int numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI,
1376 attachmentSelection, selArgs);
1377 assertEquals(4, numAttachments);
1378
1379 // now delete one of the messages
1380 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1Id);
1381 mMockContext.getContentResolver().delete(uri, null, null);
1382
1383 // there should be one body and two attachments
1384 numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs);
1385 assertEquals(1, numBodies);
1386
1387 numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI,
1388 attachmentSelection, selArgs);
1389 assertEquals(2, numAttachments);
1390
1391 // now delete the other message
1392 uri = ContentUris.withAppendedId(Message.CONTENT_URI, message2Id);
1393 mMockContext.getContentResolver().delete(uri, null, null);
1394
1395 // make sure there are no bodies or attachments
1396 numBodies = EmailContent.count(mMockContext, Body.CONTENT_URI, bodySelection, selArgs);
1397 assertEquals(0, numBodies);
1398
1399 numAttachments = EmailContent.count(mMockContext, Attachment.CONTENT_URI,
1400 attachmentSelection, selArgs);
1401 assertEquals(0, numAttachments);
1402 }
Andrew Stadler7143d962009-06-25 00:02:29 -07001403
Marc Blank976f9292009-07-15 15:08:53 -07001404 /**
1405 * Test that our unique file name algorithm works as expected. Since this test requires an
1406 * SD card, we check the environment first, and return immediately if none is mounted.
1407 * @throws IOException
1408 */
1409 public void testCreateUniqueFile() throws IOException {
1410 // Delete existing files, if they exist
1411 if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
1412 return;
1413 }
1414 try {
1415 String fileName = "A11achm3n1.doc";
1416 File uniqueFile = Attachment.createUniqueFile(fileName);
1417 assertEquals(fileName, uniqueFile.getName());
1418 if (uniqueFile.createNewFile()) {
1419 uniqueFile = Attachment.createUniqueFile(fileName);
1420 assertEquals("A11achm3n1-2.doc", uniqueFile.getName());
1421 if (uniqueFile.createNewFile()) {
1422 uniqueFile = Attachment.createUniqueFile(fileName);
1423 assertEquals("A11achm3n1-3.doc", uniqueFile.getName());
1424 }
1425 }
1426 fileName = "A11achm3n1";
1427 uniqueFile = Attachment.createUniqueFile(fileName);
1428 assertEquals(fileName, uniqueFile.getName());
1429 if (uniqueFile.createNewFile()) {
1430 uniqueFile = Attachment.createUniqueFile(fileName);
1431 assertEquals("A11achm3n1-2", uniqueFile.getName());
1432 }
1433 } finally {
1434 File directory = Environment.getExternalStorageDirectory();
1435 // These are the files that should be created earlier in the test. Make sure
1436 // they are deleted for the next go-around
1437 String[] fileNames = new String[] {"A11achm3n1.doc", "A11achm3n1-2.doc", "A11achm3n1"};
1438 int length = fileNames.length;
1439 for (int i = 0; i < length; i++) {
1440 File file = new File(directory, fileNames[i]);
1441 if (file.exists()) {
1442 file.delete();
1443 }
1444 }
1445 }
1446 }
Andrew Stadler41192182009-07-16 16:03:40 -07001447
1448 /**
1449 * Test retrieving attachments by message ID (using EmailContent.Attachment.MESSAGE_ID_URI)
1450 */
1451 public void testGetAttachmentByMessageIdUri() {
1452
1453 // Note, we don't strictly need accounts, mailboxes or messages to run this test.
1454 Attachment a1 = ProviderTestUtils.setupAttachment(1, "a1", 100, true, mMockContext);
1455 Attachment a2 = ProviderTestUtils.setupAttachment(1, "a2", 200, true, mMockContext);
Marc Blank758a5322009-07-30 11:41:31 -07001456 ProviderTestUtils.setupAttachment(2, "a3", 300, true, mMockContext);
1457 ProviderTestUtils.setupAttachment(2, "a4", 400, true, mMockContext);
Andrew Stadler41192182009-07-16 16:03:40 -07001458
1459 // Now ask for the attachments of message id=1
1460 // Note: Using the "sort by size" trick to bring them back in expected order
1461 Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, 1);
1462 Cursor c = mMockContext.getContentResolver().query(uri, Attachment.CONTENT_PROJECTION,
1463 null, null, Attachment.SIZE);
1464 assertEquals(2, c.getCount());
1465
1466 try {
1467 c.moveToFirst();
1468 Attachment a1Get = EmailContent.getContent(c, Attachment.class);
1469 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-1", a1, a1Get);
1470 c.moveToNext();
1471 Attachment a2Get = EmailContent.getContent(c, Attachment.class);
1472 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-2", a2, a2Get);
1473 } finally {
1474 c.close();
1475 }
1476 }
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001477
1478 /**
Andrew Stadler6c219422009-09-10 11:52:36 -07001479 * Test deleting attachments by message ID (using EmailContent.Attachment.MESSAGE_ID_URI)
1480 */
1481 public void testDeleteAttachmentByMessageIdUri() {
1482 ContentResolver mockResolver = mMockContext.getContentResolver();
1483
1484 // Note, we don't strictly need accounts, mailboxes or messages to run this test.
1485 ProviderTestUtils.setupAttachment(1, "a1", 100, true, mMockContext);
1486 ProviderTestUtils.setupAttachment(1, "a2", 200, true, mMockContext);
1487 Attachment a3 = ProviderTestUtils.setupAttachment(2, "a3", 300, true, mMockContext);
1488 Attachment a4 = ProviderTestUtils.setupAttachment(2, "a4", 400, true, mMockContext);
1489
1490 // Delete all attachments for message id=1
1491 Uri uri = ContentUris.withAppendedId(Attachment.MESSAGE_ID_URI, 1);
1492 mockResolver.delete(uri, null, null);
1493
1494 // Read back all attachments and confirm that we have the expected remaining attachments
1495 // (the attachments that are set for message id=2). Note order-by size to simplify test.
1496 Cursor c = mockResolver.query(Attachment.CONTENT_URI, Attachment.CONTENT_PROJECTION,
1497 null, null, Attachment.SIZE);
1498 assertEquals(2, c.getCount());
1499
1500 try {
1501 c.moveToFirst();
1502 Attachment a3Get = EmailContent.getContent(c, Attachment.class);
1503 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-3", a3, a3Get);
1504 c.moveToNext();
1505 Attachment a4Get = EmailContent.getContent(c, Attachment.class);
1506 ProviderTestUtils.assertAttachmentEqual("getAttachByUri-4", a4, a4Get);
1507 } finally {
1508 c.close();
1509 }
1510 }
1511
Ben Komalo52e66112011-07-13 15:16:55 -07001512 @SmallTest
Marc Blank63537742011-06-22 15:45:17 -07001513 public void testGetDefaultAccountNoneExplicitlySet() {
1514 Account account1 = ProviderTestUtils.setupAccount("account-default-1", false, mMockContext);
1515 account1.mIsDefault = false;
1516 account1.save(mMockContext);
1517
1518 // We should find account1 as default
1519 long defaultAccountId = Account.getDefaultAccountId(mMockContext);
1520 assertEquals(defaultAccountId, account1.mId);
1521
Ben Komalo52e66112011-07-13 15:16:55 -07001522 Account account2 = ProviderTestUtils.setupAccount("account-default-2", false, mMockContext);
Marc Blank63537742011-06-22 15:45:17 -07001523 account2.mIsDefault = false;
1524 account2.save(mMockContext);
1525
Ben Komalo52e66112011-07-13 15:16:55 -07001526 Account account3 = ProviderTestUtils.setupAccount("account-default-3", false, mMockContext);
1527 account3.mIsDefault = false;
1528 account3.save(mMockContext);
1529
1530 // We should find the earliest one as the default, so that it can be consistent on
1531 // repeated calls.
Marc Blank63537742011-06-22 15:45:17 -07001532 defaultAccountId = Account.getDefaultAccountId(mMockContext);
Ben Komalo52e66112011-07-13 15:16:55 -07001533 assertTrue(defaultAccountId == account1.mId);
Marc Blank63537742011-06-22 15:45:17 -07001534 }
1535
Andrew Stadler6c219422009-09-10 11:52:36 -07001536 /**
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001537 * Tests of default account behavior
Marc Blank758a5322009-07-30 11:41:31 -07001538 *
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001539 * 1. Simple set/get
1540 * 2. Moving default between 3 accounts
1541 * 3. Delete default, make sure another becomes default
1542 */
1543 public void testSetGetDefaultAccount() {
1544 // There should be no default account if there are no accounts
1545 long defaultAccountId = Account.getDefaultAccountId(mMockContext);
Ben Komaloacd985e2011-07-13 16:51:35 -07001546 assertEquals(Account.NO_ACCOUNT, defaultAccountId);
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001547
Ben Komaloacd985e2011-07-13 16:51:35 -07001548 Account account1 = ProviderTestUtils.setupAccount("account-default-1", false, mMockContext);
1549 account1.mIsDefault = false;
1550 account1.save(mMockContext);
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001551 long account1Id = account1.mId;
Ben Komaloacd985e2011-07-13 16:51:35 -07001552 Account account2 = ProviderTestUtils.setupAccount("account-default-2", false, mMockContext);
1553 account2.mIsDefault = false;
1554 account2.save(mMockContext);
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001555 long account2Id = account2.mId;
Ben Komaloacd985e2011-07-13 16:51:35 -07001556 Account account3 = ProviderTestUtils.setupAccount("account-default-3", false, mMockContext);
1557 account3.mIsDefault = false;
1558 account3.save(mMockContext);
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001559 long account3Id = account3.mId;
1560
Ben Komaloacd985e2011-07-13 16:51:35 -07001561 // With three accounts, but none marked default, confirm that the first one is the default.
Andrew Stadler9e2c6bd2009-07-22 15:13:30 -07001562 defaultAccountId = Account.getDefaultAccountId(mMockContext);
Ben Komaloacd985e2011-07-13 16:51:35 -07001563 assertTrue(defaultAccountId == account1Id);
Andrew Stadler9e2c6bd2009-07-22 15:13:30 -07001564
1565 updateIsDefault(account1, true);
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001566 defaultAccountId = Account.getDefaultAccountId(mMockContext);
1567 assertEquals(account1Id, defaultAccountId);
1568
Marc Blank531ae9d2009-07-22 15:55:45 -07001569 updateIsDefault(account2, true);
1570 defaultAccountId = Account.getDefaultAccountId(mMockContext);
1571 assertEquals(account2Id, defaultAccountId);
1572
1573 updateIsDefault(account3, true);
1574 defaultAccountId = Account.getDefaultAccountId(mMockContext);
1575 assertEquals(account3Id, defaultAccountId);
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001576
1577 // Now delete a non-default account and confirm no change
1578 Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, account1Id);
1579 mMockContext.getContentResolver().delete(uri, null, null);
1580
Marc Blank531ae9d2009-07-22 15:55:45 -07001581 defaultAccountId = Account.getDefaultAccountId(mMockContext);
1582 assertEquals(account3Id, defaultAccountId);
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001583
1584 // Now confirm deleting the default account and it switches to another one
1585 uri = ContentUris.withAppendedId(Account.CONTENT_URI, account3Id);
1586 mMockContext.getContentResolver().delete(uri, null, null);
1587
Marc Blank531ae9d2009-07-22 15:55:45 -07001588 defaultAccountId = Account.getDefaultAccountId(mMockContext);
1589 assertEquals(account2Id, defaultAccountId);
Marc Blank758a5322009-07-30 11:41:31 -07001590
Andrew Stadler9e2c6bd2009-07-22 15:13:30 -07001591 // Now delete the final account and confirm there are no default accounts again
1592 uri = ContentUris.withAppendedId(Account.CONTENT_URI, account2Id);
1593 mMockContext.getContentResolver().delete(uri, null, null);
1594
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001595 defaultAccountId = Account.getDefaultAccountId(mMockContext);
Andrew Stadler9e2c6bd2009-07-22 15:13:30 -07001596 assertEquals(-1, defaultAccountId);
Andrew Stadler54c1f2b2009-07-21 16:44:16 -07001597 }
1598
Andrew Stadler9e2c6bd2009-07-22 15:13:30 -07001599 private void updateIsDefault(Account account, boolean newState) {
1600 account.setDefaultAccount(newState);
1601 ContentValues cv = new ContentValues();
1602 cv.put(AccountColumns.IS_DEFAULT, account.mIsDefault);
1603 account.update(mMockContext, cv);
1604 }
Marc Blank758a5322009-07-30 11:41:31 -07001605
1606 public static Message setupUnreadMessage(String name, long accountId, long mailboxId,
1607 boolean addBody, boolean saveIt, Context context) {
1608 Message msg =
1609 ProviderTestUtils.setupMessage(name, accountId, mailboxId, addBody, false, context);
1610 msg.mFlagRead = false;
1611 if (saveIt) {
1612 msg.save(context);
1613 }
1614 return msg;
1615 }
1616
1617 public void testUnreadCountTriggers() {
1618 // Start with one account and three mailboxes
1619 Account account = ProviderTestUtils.setupAccount("triggers", true, mMockContext);
1620 Mailbox boxA = ProviderTestUtils.setupMailbox("boxA", account.mId, true, mMockContext);
1621 Mailbox boxB = ProviderTestUtils.setupMailbox("boxB", account.mId, true, mMockContext);
1622 Mailbox boxC = ProviderTestUtils.setupMailbox("boxC", account.mId, true, mMockContext);
1623
1624 // Make sure there are no unreads
1625 assertEquals(0, getUnreadCount(boxA.mId));
1626 assertEquals(0, getUnreadCount(boxB.mId));
1627 assertEquals(0, getUnreadCount(boxC.mId));
1628
1629 // Create 4 unread messages (only 3 named) in boxA
1630 Message message1 = setupUnreadMessage("message1", account.mId, boxA.mId,
1631 false, true, mMockContext);
1632 Message message2= setupUnreadMessage("message2", account.mId, boxA.mId,
1633 false, true, mMockContext);
1634 Message message3 = setupUnreadMessage("message3", account.mId, boxA.mId,
1635 false, true, mMockContext);
1636 setupUnreadMessage("message4", account.mId, boxC.mId, false, true, mMockContext);
1637
1638 // Make sure the unreads are where we expect them
1639 assertEquals(3, getUnreadCount(boxA.mId));
1640 assertEquals(0, getUnreadCount(boxB.mId));
1641 assertEquals(1, getUnreadCount(boxC.mId));
1642
1643 // After deleting message 1, the count in box A should be decremented (to 2)
1644 ContentResolver cr = mMockContext.getContentResolver();
1645 Uri uri = ContentUris.withAppendedId(Message.CONTENT_URI, message1.mId);
1646 cr.delete(uri, null, null);
1647 assertEquals(2, getUnreadCount(boxA.mId));
1648 assertEquals(0, getUnreadCount(boxB.mId));
1649 assertEquals(1, getUnreadCount(boxC.mId));
1650
1651 // Move message 2 to box B, leaving 1 in box A and 1 in box B
1652 message2.mMailboxKey = boxB.mId;
1653 ContentValues cv = new ContentValues();
1654 cv.put(MessageColumns.MAILBOX_KEY, boxB.mId);
1655 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message2.mId), cv, null, null);
1656 assertEquals(1, getUnreadCount(boxA.mId));
1657 assertEquals(1, getUnreadCount(boxB.mId));
1658 assertEquals(1, getUnreadCount(boxC.mId));
1659
1660 // Mark message 3 (from box A) read, leaving 0 in box A
1661 cv.clear();
1662 cv.put(MessageColumns.FLAG_READ, 1);
1663 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null);
1664 assertEquals(0, getUnreadCount(boxA.mId));
1665 assertEquals(1, getUnreadCount(boxB.mId));
1666 assertEquals(1, getUnreadCount(boxC.mId));
1667
1668 // Move message 3 to box C; should be no change (it's read)
1669 message3.mMailboxKey = boxC.mId;
1670 cv.clear();
1671 cv.put(MessageColumns.MAILBOX_KEY, boxC.mId);
1672 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null);
1673 assertEquals(0, getUnreadCount(boxA.mId));
1674 assertEquals(1, getUnreadCount(boxB.mId));
1675 assertEquals(1, getUnreadCount(boxC.mId));
1676
1677 // Mark message 3 unread; it's now in box C, so that box's count should go up to 3
1678 cv.clear();
1679 cv.put(MessageColumns.FLAG_READ, 0);
1680 cr.update(ContentUris.withAppendedId(Message.CONTENT_URI, message3.mId), cv, null, null);
1681 assertEquals(0, getUnreadCount(boxA.mId));
1682 assertEquals(1, getUnreadCount(boxB.mId));
1683 assertEquals(2, getUnreadCount(boxC.mId));
1684 }
Mihai Preda9627d012009-08-12 12:51:26 +02001685
1686 /**
1687 * Test for EmailProvider.createIndex().
1688 * Check that it returns exacly the same string as the one used previously for index creation.
1689 */
1690 public void testCreateIndex() {
1691 String oldStr = "create index message_" + MessageColumns.TIMESTAMP
1692 + " on " + Message.TABLE_NAME + " (" + MessageColumns.TIMESTAMP + ");";
1693 String newStr = EmailProvider.createIndex(Message.TABLE_NAME, MessageColumns.TIMESTAMP);
1694 assertEquals(newStr, oldStr);
1695 }
Marc Blankc0c9c332009-08-19 19:07:29 -07001696
Marc Blank0e1595c2009-11-18 17:11:33 -08001697 public void testDatabaseCorruptionRecovery() {
1698 final ContentResolver resolver = mMockContext.getContentResolver();
1699 final Context context = mMockContext;
1700
1701 // Create account and two mailboxes
1702 Account acct = ProviderTestUtils.setupAccount("acct1", true, context);
1703 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context);
1704
1705 // Create 4 messages in box1 with bodies
1706 ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, true, true, context);
1707 ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, true, true, context);
1708 ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, true, true, context);
1709 ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, true, true, context);
1710
1711 // Confirm there are four messages
1712 int count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
1713 assertEquals(4, count);
1714 // Confirm there are four bodies
1715 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null);
1716 assertEquals(4, count);
1717
1718 // Find the EmailProvider.db file
1719 File dbFile = mMockContext.getDatabasePath(EmailProvider.DATABASE_NAME);
1720 // The EmailProvider.db database should exist (the provider creates it automatically)
1721 assertTrue(dbFile != null);
1722 assertTrue(dbFile.exists());
1723 // Delete it, and confirm it is gone
1724 assertTrue(dbFile.delete());
1725 assertFalse(dbFile.exists());
1726
1727 // Find the EmailProviderBody.db file
1728 dbFile = mMockContext.getDatabasePath(EmailProvider.BODY_DATABASE_NAME);
1729 // The EmailProviderBody.db database should still exist
1730 assertTrue(dbFile != null);
1731 assertTrue(dbFile.exists());
1732
1733 // URI to uncache the databases
1734 // This simulates the Provider starting up again (otherwise, it will still be pointing to
1735 // the already opened files)
1736 // Note that we only have access to the EmailProvider via the ContentResolver; therefore,
1737 // we cannot directly call into the provider and use a URI for this
1738 resolver.update(EmailProvider.INTEGRITY_CHECK_URI, null, null, null);
1739
1740 // TODO We should check for the deletion of attachment files once this is implemented in
1741 // the provider
Makoto Onukibcf32322010-07-27 12:52:46 -07001742
Marc Blank0e1595c2009-11-18 17:11:33 -08001743 // Explanation for what happens below...
1744 // The next time the database is created by the provider, it will notice that there's
1745 // already a EmailProviderBody.db file. In this case, it will delete that database to
1746 // ensure that both are in sync (and empty)
1747
1748 // Confirm there are no bodies
1749 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null);
1750 assertEquals(0, count);
1751
1752 // Confirm there are no messages
1753 count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
1754 assertEquals(0, count);
1755 }
1756
1757 public void testBodyDatabaseCorruptionRecovery() {
1758 final ContentResolver resolver = mMockContext.getContentResolver();
1759 final Context context = mMockContext;
1760
1761 // Create account and two mailboxes
1762 Account acct = ProviderTestUtils.setupAccount("acct1", true, context);
1763 Mailbox box1 = ProviderTestUtils.setupMailbox("box1", acct.mId, true, context);
1764
1765 // Create 4 messages in box1 with bodies
1766 ProviderTestUtils.setupMessage("message1", acct.mId, box1.mId, true, true, context);
1767 ProviderTestUtils.setupMessage("message2", acct.mId, box1.mId, true, true, context);
1768 ProviderTestUtils.setupMessage("message3", acct.mId, box1.mId, true, true, context);
1769 ProviderTestUtils.setupMessage("message4", acct.mId, box1.mId, true, true, context);
1770
1771 // Confirm there are four messages
1772 int count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
1773 assertEquals(4, count);
1774 // Confirm there are four bodies
1775 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null);
1776 assertEquals(4, count);
1777
1778 // Find the EmailProviderBody.db file
1779 File dbFile = mMockContext.getDatabasePath(EmailProvider.BODY_DATABASE_NAME);
1780 // The EmailProviderBody.db database should exist (the provider creates it automatically)
1781 assertTrue(dbFile != null);
1782 assertTrue(dbFile.exists());
1783 // Delete it, and confirm it is gone
1784 assertTrue(dbFile.delete());
1785 assertFalse(dbFile.exists());
1786
1787 // Find the EmailProvider.db file
1788 dbFile = mMockContext.getDatabasePath(EmailProvider.DATABASE_NAME);
1789 // The EmailProviderBody.db database should still exist
1790 assertTrue(dbFile != null);
1791 assertTrue(dbFile.exists());
1792
1793 // URI to uncache the databases
1794 // This simulates the Provider starting up again (otherwise, it will still be pointing to
1795 // the already opened files)
1796 // Note that we only have access to the EmailProvider via the ContentResolver; therefore,
1797 // we cannot directly call into the provider and use a URI for this
1798 resolver.update(EmailProvider.INTEGRITY_CHECK_URI, null, null, null);
1799
1800 // TODO We should check for the deletion of attachment files once this is implemented in
1801 // the provider
1802
1803 // Explanation for what happens below...
1804 // The next time the body database is created by the provider, it will notice that there's
1805 // already a populated EmailProvider.db file. In this case, it will delete that database to
1806 // ensure that both are in sync (and empty)
1807
1808 // Confirm there are no messages
1809 count = EmailContent.count(mMockContext, Message.CONTENT_URI, null, null);
1810 assertEquals(0, count);
1811
1812 // Confirm there are no bodies
1813 count = EmailContent.count(mMockContext, Body.CONTENT_URI, null, null);
1814 assertEquals(0, count);
1815 }
Marc Blank694257c2010-02-11 18:14:01 -08001816
Makoto Onukibcf32322010-07-27 12:52:46 -07001817 public void testAccountIsSecurityHold() {
1818 final Context context = mMockContext;
1819 Account acct1 = ProviderTestUtils.setupAccount("acct1", true, context);
1820
1821 Account acct2 = ProviderTestUtils.setupAccount("acct2", false, context);
1822 acct2.mFlags |= Account.FLAGS_SECURITY_HOLD;
1823 acct2.save(context);
1824
1825 assertFalse(Account.isSecurityHold(context, acct1.mId));
1826 assertTrue(Account.isSecurityHold(context, acct2.mId));
1827 assertFalse(Account.isSecurityHold(context, 9999999)); // No such account
1828 }
1829
1830 public void testClearAccountHoldFlags() {
1831 Account a1 = ProviderTestUtils.setupAccount("holdflag-1", false, mMockContext);
1832 a1.mFlags = Account.FLAGS_NOTIFY_NEW_MAIL;
Marc Blank6e418aa2011-06-18 18:03:11 -07001833 a1.mPolicy = new Policy();
Makoto Onukibcf32322010-07-27 12:52:46 -07001834 a1.save(mMockContext);
1835 Account a2 = ProviderTestUtils.setupAccount("holdflag-2", false, mMockContext);
1836 a2.mFlags = Account.FLAGS_VIBRATE_ALWAYS | Account.FLAGS_SECURITY_HOLD;
Marc Blank6e418aa2011-06-18 18:03:11 -07001837 a2.mPolicy = new Policy();
Makoto Onukibcf32322010-07-27 12:52:46 -07001838 a2.save(mMockContext);
1839
1840 // bulk clear
1841 Account.clearSecurityHoldOnAllAccounts(mMockContext);
1842
1843 // confirm new values as expected - no hold flags; other flags unmolested
1844 Account a1a = Account.restoreAccountWithId(mMockContext, a1.mId);
1845 assertEquals(Account.FLAGS_NOTIFY_NEW_MAIL, a1a.mFlags);
1846 Account a2a = Account.restoreAccountWithId(mMockContext, a2.mId);
1847 assertEquals(Account.FLAGS_VIBRATE_ALWAYS, a2a.mFlags);
1848 }
Makoto Onuki574854b2010-07-30 13:53:59 -07001849
Makoto Onuki833fe732010-08-02 18:16:13 -07001850 private static Message createMessage(Context c, Mailbox b, boolean starred, boolean read) {
Todd Kennedy543953a2011-01-24 14:11:20 -08001851 return ProviderTestUtils.setupMessage(
1852 "1", b.mAccountKey, b.mId, true, true, c, starred, read);
1853 }
1854
Makoto Onuki5247ab82010-08-23 17:21:53 -07001855 public void testAccountIsEasAccount() {
Makoto Onuki6d8bfa62010-08-09 16:51:40 -07001856 Account account = new Account();
Makoto Onuki25144e22010-08-26 15:08:19 -07001857 // No hostauth
Makoto Onuki5247ab82010-08-23 17:21:53 -07001858 assertFalse(account.isEasAccount(mMockContext));
Makoto Onuki6d8bfa62010-08-09 16:51:40 -07001859
Makoto Onuki25144e22010-08-26 15:08:19 -07001860 checkAccountIsEasAccount(null, false);
1861 checkAccountIsEasAccount("", false);
1862 checkAccountIsEasAccount("x", false);
1863 checkAccountIsEasAccount("eas", true);
1864 }
Makoto Onuki6d8bfa62010-08-09 16:51:40 -07001865
Makoto Onuki25144e22010-08-26 15:08:19 -07001866 private void checkAccountIsEasAccount(String protocol, boolean expected) {
1867 Account account = ProviderTestUtils.setupAccount("account", false, mMockContext);
1868 account.mHostAuthRecv = ProviderTestUtils.setupHostAuth(protocol, "account-hostauth-recv",
Todd Kennedyfe68c0e2011-02-17 10:27:31 -08001869 false, mMockContext);
Makoto Onuki25144e22010-08-26 15:08:19 -07001870 account.save(mMockContext);
1871 assertEquals(expected, account.isEasAccount(mMockContext));
Makoto Onuki6d8bfa62010-08-09 16:51:40 -07001872 }
Marc Blankbca4e6e2010-08-23 21:39:35 -07001873
1874 public void testGetKeyColumnLong() {
1875 final Context c = mMockContext;
1876 Account a = ProviderTestUtils.setupAccount("acct", true, c);
1877 Mailbox b1 = ProviderTestUtils.setupMailbox("box1", a.mId, true, c, Mailbox.TYPE_MAIL);
1878 Mailbox b2 = ProviderTestUtils.setupMailbox("box2", a.mId, true, c, Mailbox.TYPE_MAIL);
1879 Message m1 = createMessage(c, b1, false, false);
1880 Message m2 = createMessage(c, b2, false, false);
1881 assertEquals(a.mId, Message.getKeyColumnLong(c, m1.mId, MessageColumns.ACCOUNT_KEY));
1882 assertEquals(a.mId, Message.getKeyColumnLong(c, m2.mId, MessageColumns.ACCOUNT_KEY));
1883 assertEquals(b1.mId, Message.getKeyColumnLong(c, m1.mId, MessageColumns.MAILBOX_KEY));
1884 assertEquals(b2.mId, Message.getKeyColumnLong(c, m2.mId, MessageColumns.MAILBOX_KEY));
1885 }
1886
Makoto Onukiaef95152010-12-10 13:36:18 -08001887 public void testGetAccountIdForMessageId() {
1888 final Context c = mMockContext;
1889 Account a1 = ProviderTestUtils.setupAccount("acct1", true, c);
1890 Account a2 = ProviderTestUtils.setupAccount("acct2", true, c);
1891 Mailbox b1 = ProviderTestUtils.setupMailbox("box1", a1.mId, true, c, Mailbox.TYPE_MAIL);
1892 Mailbox b2 = ProviderTestUtils.setupMailbox("box2", a2.mId, true, c, Mailbox.TYPE_MAIL);
1893 Message m1 = createMessage(c, b1, false, false);
1894 Message m2 = createMessage(c, b2, false, false);
1895
1896 assertEquals(a1.mId, Account.getAccountIdForMessageId(c, m1.mId));
1897 assertEquals(a2.mId, Account.getAccountIdForMessageId(c, m2.mId));
1898
1899 // message desn't exist
1900 assertEquals(-1, Account.getAccountIdForMessageId(c, 12345));
1901 }
1902
Todd Kennedy200c6bd2011-04-20 16:22:41 -07001903 public void testGetAccountForMessageId() {
1904 final Context c = mMockContext;
1905 Account a = ProviderTestUtils.setupAccount("acct", true, c);
1906 Message m1 = ProviderTestUtils.setupMessage("1", a.mId, 1, true, true, c, false, false);
1907 Message m2 = ProviderTestUtils.setupMessage("1", a.mId, 2, true, true, c, false, false);
1908 ProviderTestUtils.assertAccountEqual("x", a, Account.getAccountForMessageId(c, m1.mId));
1909 ProviderTestUtils.assertAccountEqual("x", a, Account.getAccountForMessageId(c, m2.mId));
1910 }
1911
Makoto Onukie357f582010-08-27 10:25:03 -07001912 public void testGetAccountGetInboxIdTest() {
1913 final Context c = mMockContext;
1914
1915 // Prepare some data with red-herrings.
1916 Account a1 = ProviderTestUtils.setupAccount("acct1", true, c);
1917 Account a2 = ProviderTestUtils.setupAccount("acct2", true, c);
1918 Mailbox b1i = ProviderTestUtils.setupMailbox("b1i", a1.mId, true, c, Mailbox.TYPE_INBOX);
1919 Mailbox b2a = ProviderTestUtils.setupMailbox("b2a", a2.mId, true, c, Mailbox.TYPE_MAIL);
1920 Mailbox b2i = ProviderTestUtils.setupMailbox("b2b", a2.mId, true, c, Mailbox.TYPE_INBOX);
1921
1922 assertEquals(b2i.mId, Account.getInboxId(c, a2.mId));
Makoto Onukid25d87c2010-09-24 14:50:20 -07001923
1924 // No account found.
1925 assertEquals(-1, Account.getInboxId(c, 999999));
Makoto Onukie357f582010-08-27 10:25:03 -07001926 }
1927
Makoto Onuki261d6c32010-09-14 16:28:50 -07001928 /**
1929 * Check if update to {@link Account#RESET_NEW_MESSAGE_COUNT_URI} resets the new message count.
1930 */
1931 public void testResetNewMessageCount() {
1932 final Context c = mMockContext;
1933 final ContentResolver cr = c.getContentResolver();
1934
1935 // Prepare test data
1936 Account a1 = ProviderTestUtils.setupAccount("acct1", false, c);
1937 a1.mNewMessageCount = 1;
1938 a1.save(c);
1939 Account a2 = ProviderTestUtils.setupAccount("acct2", false, c);
1940 a2.mNewMessageCount = 2;
1941 a2.save(c);
1942 Account a3 = ProviderTestUtils.setupAccount("acct3", false, c);
1943 a3.mNewMessageCount = 3;
1944 a3.save(c);
1945 Account a4 = ProviderTestUtils.setupAccount("acct4", false, c);
1946 a4.mNewMessageCount = 4;
1947 a4.save(c);
1948 Account a5 = ProviderTestUtils.setupAccount("acct5", false, c);
1949 a5.mNewMessageCount = 5;
1950 a5.save(c);
1951
1952 // With ID in URI, no selection
1953 cr.update(ContentUris.withAppendedId(Account.RESET_NEW_MESSAGE_COUNT_URI, a1.mId),
1954 null, null, null);
1955 assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
1956 assertEquals(2, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount);
1957 assertEquals(3, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount);
1958 assertEquals(4, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount);
1959 assertEquals(5, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount);
1960
1961 // No ID in URI, with selection
1962 cr.update(Account.RESET_NEW_MESSAGE_COUNT_URI, null,
1963 EmailContent.ID_SELECTION, new String[] {Long.toString(a2.mId)});
1964 assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
1965 assertEquals(0, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount);
1966 assertEquals(3, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount);
1967 assertEquals(4, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount);
1968 assertEquals(5, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount);
1969
1970 // With ID, with selection
1971 cr.update(ContentUris.withAppendedId(Account.RESET_NEW_MESSAGE_COUNT_URI, a3.mId), null,
1972 EmailContent.ID_SELECTION, new String[] {Long.toString(a3.mId)});
1973 assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
1974 assertEquals(0, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount);
1975 assertEquals(0, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount);
1976 assertEquals(4, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount);
1977 assertEquals(5, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount);
1978
1979 // No ID in URI, no selection
1980 cr.update(Account.RESET_NEW_MESSAGE_COUNT_URI, null, null, null);
1981 assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
1982 assertEquals(0, Account.restoreAccountWithId(c, a2.mId).mNewMessageCount);
1983 assertEquals(0, Account.restoreAccountWithId(c, a3.mId).mNewMessageCount);
1984 assertEquals(0, Account.restoreAccountWithId(c, a4.mId).mNewMessageCount);
1985 assertEquals(0, Account.restoreAccountWithId(c, a5.mId).mNewMessageCount);
1986 }
Makoto Onuki899c5b82010-09-26 16:16:21 -07001987
Makoto Onuki9d5aaea2010-12-02 16:33:49 -08001988 /**
1989 * Check if update on ACCOUNT_ID_ADD_TO_FIELD updates the cache properly.
1990 */
1991 public void testUpdateCacheAccountIdAddToField() {
1992 final Context c = mMockContext;
1993 Account a1 = ProviderTestUtils.setupAccount("a1", true, c);
1994
1995 int start = Account.restoreAccountWithId(c, a1.mId).mNewMessageCount;
1996
1997 // +1 to NEW_MESSAGE_COUNT
1998 ContentValues cv = new ContentValues();
1999 cv.put(EmailContent.FIELD_COLUMN_NAME, AccountColumns.NEW_MESSAGE_COUNT);
2000 cv.put(EmailContent.ADD_COLUMN_NAME, 1);
2001 mProvider.update(ContentUris.withAppendedId(Account.ADD_TO_FIELD_URI, a1.mId), cv,
2002 null, null);
2003
2004 // Check
2005 assertEquals(start + 1, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
2006 }
2007
2008 /**
2009 * Check if update on ACCOUNT_RESET_NEW_COUNT updates the cache properly.
2010 */
2011 public void testUpdateCacheAccountResetNewCount() {
2012 final Context c = mMockContext;
2013 Account a1 = ProviderTestUtils.setupAccount("a1", true, c);
2014
2015 // precondition
2016 assertTrue(Account.restoreAccountWithId(c, a1.mId).mNewMessageCount > 0);
2017
2018 // Reset
2019 mProvider.update(Account.RESET_NEW_MESSAGE_COUNT_URI, null, null, null);
2020
2021 // Check
2022 assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
2023 }
2024
2025 /**
2026 * Check if update on ACCOUNT_RESET_NEW_COUNT_ID updates the cache properly.
2027 */
2028 public void testUpdateCacheAccountResetNewCountId() {
2029 final Context c = mMockContext;
2030 Account a1 = ProviderTestUtils.setupAccount("a1", true, c);
2031
2032 // precondition
2033 assertTrue(Account.restoreAccountWithId(c, a1.mId).mNewMessageCount > 0);
2034
2035 // Reset
2036 mProvider.update(ContentUris.withAppendedId(Account.RESET_NEW_MESSAGE_COUNT_URI, a1.mId),
2037 null, null, null);
2038
2039 // Check
2040 assertEquals(0, Account.restoreAccountWithId(c, a1.mId).mNewMessageCount);
2041 }
2042
2043 /**
Marc Blankd306ba32010-12-30 14:55:27 -08002044 * Check that we're handling illegal uri's properly (by throwing an exception unless it's a
2045 * query for an id of -1, in which case we return a zero-length cursor)
2046 */
2047 public void testIllegalUri() {
2048 final ContentResolver cr = mMockContext.getContentResolver();
2049
2050 ContentValues cv = new ContentValues();
2051 Uri uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/fooble");
2052 try {
2053 cr.insert(uri, cv);
2054 fail("Insert should have thrown exception");
2055 } catch (IllegalArgumentException e) {
2056 }
2057 try {
2058 cr.update(uri, cv, null, null);
2059 fail("Update should have thrown exception");
2060 } catch (IllegalArgumentException e) {
2061 }
2062 try {
2063 cr.delete(uri, null, null);
2064 fail("Delete should have thrown exception");
2065 } catch (IllegalArgumentException e) {
2066 }
2067 try {
2068 cr.query(uri, EmailContent.ID_PROJECTION, null, null, null);
2069 fail("Query should have thrown exception");
2070 } catch (IllegalArgumentException e) {
2071 }
2072 uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/mailbox/fred");
2073 try {
2074 cr.query(uri, EmailContent.ID_PROJECTION, null, null, null);
2075 fail("Query should have thrown exception");
2076 } catch (IllegalArgumentException e) {
2077 }
2078 uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/mailbox/-1");
2079 Cursor c = cr.query(uri, EmailContent.ID_PROJECTION, null, null, null);
2080 assertNotNull(c);
2081 assertEquals(0, c.getCount());
2082 c.close();
2083 }
Todd Kennedy22208772011-04-22 15:45:11 -07002084
2085 /**
2086 * Verify {@link EmailProvider#recalculateMessageCount(android.database.sqlite.SQLiteDatabase)}
2087 */
2088 public void testRecalculateMessageCounts() {
2089 final Context c = mMockContext;
2090
2091 // Create accounts
2092 Account a1 = ProviderTestUtils.setupAccount("holdflag-1", true, c);
2093 Account a2 = ProviderTestUtils.setupAccount("holdflag-2", true, c);
2094
2095 // Create mailboxes for each account
2096 Mailbox b1 = ProviderTestUtils.setupMailbox("box1", a1.mId, true, c, Mailbox.TYPE_INBOX);
2097 Mailbox b2 = ProviderTestUtils.setupMailbox("box2", a1.mId, true, c, Mailbox.TYPE_OUTBOX);
2098 Mailbox b3 = ProviderTestUtils.setupMailbox("box3", a2.mId, true, c, Mailbox.TYPE_INBOX);
2099 Mailbox b4 = ProviderTestUtils.setupMailbox("box4", a2.mId, true, c, Mailbox.TYPE_OUTBOX);
2100 Mailbox bt = ProviderTestUtils.setupMailbox("boxT", a2.mId, true, c, Mailbox.TYPE_TRASH);
2101
2102 // Create some messages
2103 // b1 (account 1, inbox): 1 message, including 1 starred
2104 Message m11 = createMessage(c, b1, true, false, Message.FLAG_LOADED_COMPLETE);
2105
2106 // b2 (account 1, outbox): 2 message, including 1 starred
2107 Message m21 = createMessage(c, b2, false, false, Message.FLAG_LOADED_COMPLETE);
2108 Message m22 = createMessage(c, b2, true, true, Message.FLAG_LOADED_COMPLETE);
2109
2110 // b3 (account 2, inbox): 3 message, including 1 starred
2111 Message m31 = createMessage(c, b3, false, false, Message.FLAG_LOADED_COMPLETE);
2112 Message m32 = createMessage(c, b3, false, false, Message.FLAG_LOADED_COMPLETE);
2113 Message m33 = createMessage(c, b3, true, true, Message.FLAG_LOADED_COMPLETE);
2114
2115 // b4 (account 2, outbox) has no messages.
2116
2117 // bt (account 2, trash) has 3 messages, including 2 starred
2118 Message mt1 = createMessage(c, bt, true, false, Message.FLAG_LOADED_COMPLETE);
2119 Message mt2 = createMessage(c, bt, true, false, Message.FLAG_LOADED_COMPLETE);
2120 Message mt3 = createMessage(c, bt, false, false, Message.FLAG_LOADED_COMPLETE);
2121
2122 // Verifiy initial message counts
2123 assertEquals(1, getMessageCount(b1.mId));
2124 assertEquals(2, getMessageCount(b2.mId));
2125 assertEquals(3, getMessageCount(b3.mId));
2126 assertEquals(0, getMessageCount(b4.mId));
2127 assertEquals(3, getMessageCount(bt.mId));
2128
2129 // Whew. The setup is done; now let's actually get to the test
2130
2131 // First, invalidate the message counts.
2132 setMinusOneToMessageCounts();
2133 assertEquals(-1, getMessageCount(b1.mId));
2134 assertEquals(-1, getMessageCount(b2.mId));
2135 assertEquals(-1, getMessageCount(b3.mId));
2136 assertEquals(-1, getMessageCount(b4.mId));
2137 assertEquals(-1, getMessageCount(bt.mId));
2138
2139 // Batch update.
2140 SQLiteDatabase db = getProvider().getDatabase(mMockContext);
2141 EmailProvider.recalculateMessageCount(db);
2142
2143 // Check message counts are valid again
2144 assertEquals(1, getMessageCount(b1.mId));
2145 assertEquals(2, getMessageCount(b2.mId));
2146 assertEquals(3, getMessageCount(b3.mId));
2147 assertEquals(0, getMessageCount(b4.mId));
2148 assertEquals(3, getMessageCount(bt.mId));
2149 }
2150
2151 /** Creates an account */
2152 private Account createAccount(Context c, String name, HostAuth recvAuth, HostAuth sendAuth) {
2153 Account account = ProviderTestUtils.setupAccount(name, false, c);
2154 if (recvAuth != null) {
2155 account.mHostAuthKeyRecv = recvAuth.mId;
2156 if (sendAuth == null) {
2157 account.mHostAuthKeySend = recvAuth.mId;
2158 }
2159 }
2160 if (sendAuth != null) {
2161 account.mHostAuthKeySend = sendAuth.mId;
2162 }
2163 account.save(c);
2164 return account;
2165 }
2166
2167 /** Creates a mailbox; redefine as we need version 17 mailbox values */
2168 private Mailbox createMailbox(Context c, String displayName, String serverId, long parentKey,
2169 long accountId) {
2170 Mailbox box = new Mailbox();
2171
2172 box.mDisplayName = displayName;
2173 box.mServerId = serverId;
2174 box.mParentKey = parentKey;
2175 box.mAccountKey = accountId;
2176 // Don't care about the fields below ... set them for giggles
2177 box.mType = Mailbox.TYPE_MAIL;
2178 box.mDelimiter = '/';
2179 box.mSyncKey = "sync-key";
2180 box.mSyncLookback = 2;
Marc Blankf5418f12011-06-13 15:32:27 -07002181 box.mSyncInterval = Account.CHECK_INTERVAL_NEVER;
Todd Kennedy22208772011-04-22 15:45:11 -07002182 box.mSyncTime = 3;
2183 box.mFlagVisible = true;
2184 box.mFlags = 5;
2185 box.mVisibleLimit = 6;
2186 box.save(c);
2187 return box;
2188 }
2189
2190 /**
2191 * Asserts equality between two mailboxes. We define this as we don't have implementations
2192 * for Mailbox#equals().
2193 */
2194 private void assertEquals(Mailbox expected, Mailbox actual) {
2195 if (expected == null && actual == null) return;
2196 assertTrue(expected != null && actual != null);
2197 assertEqualsExceptServerId(expected, actual, expected.mServerId);
2198 }
2199
2200 /**
2201 * Asserts equality between the two mailboxes EXCEPT for the server id. The given server
2202 * ID is the expected value.
2203 */
2204 private void assertEqualsExceptServerId(Mailbox expected, Mailbox actual, String serverId) {
2205 if (expected == null && actual == null) return;
2206
2207 assertTrue(expected != null && actual != null);
2208 assertEquals(expected.mDisplayName, actual.mDisplayName);
2209 assertEquals(serverId, actual.mServerId);
2210 assertEquals(expected.mParentKey, actual.mParentKey);
2211 assertEquals(expected.mAccountKey, actual.mAccountKey);
2212 }
2213
2214 /** Verifies updating the DB from v17 to v18 works as expected */
2215 public void testUpgradeFromVersion17ToVersion18() {
2216 final Context c = mMockContext;
2217 // Create accounts
Marc Blank6e418aa2011-06-18 18:03:11 -07002218 Account a1 = createAccount(c, "exchange",
Todd Kennedy22208772011-04-22 15:45:11 -07002219 ProviderTestUtils.setupHostAuth("eas", "exchange.host.com", true, c),
2220 null);
2221 Account a2 = createAccount(c, "imap",
2222 ProviderTestUtils.setupHostAuth("imap", "imap.host.com", true, c),
2223 ProviderTestUtils.setupHostAuth("smtp", "smtp.host.com", true, c));
2224 Account a3 = createAccount(c, "pop3",
2225 ProviderTestUtils.setupHostAuth("pop3", "imap.host.com", true, c),
2226 ProviderTestUtils.setupHostAuth("smtp", "smtp.host.com", true, c));
2227
2228 // Create mailboxes; some w/ valid parent IDs, others without
2229 Mailbox b11 = createMailbox(c, "box1", "12", 0L, a1.mId);
2230 Mailbox b12 = createMailbox(c, "box2", "67", -1L, a1.mId);
2231 Mailbox b13 = createMailbox(c, "box3", "18", b12.mId, a1.mId);
2232
2233 Mailbox b21 = createMailbox(c, "box4", null, 0L, a2.mId);
2234 Mailbox b22 = createMailbox(c, "box4/foo/bar", "will-be-replaced", 0L, a2.mId);
2235 Mailbox b23 = createMailbox(c, "box5", null, -1L, a2.mId);
2236 Mailbox b24 = createMailbox(c, "box6", "box5/box6", b23.mId, a2.mId);
2237
2238 Mailbox b31 = createMailbox(c, "box7", "12", 0L, a3.mId);
2239 Mailbox b32 = createMailbox(c, "box8/foo/bar", "will-be-replaced", 0L, a3.mId);
2240 Mailbox b33 = createMailbox(c, "box9", "box9", -1L, a3.mId);
2241 Mailbox b34 = createMailbox(c, "boxA", "box9/boxA", b33.mId, a3.mId);
2242
2243 // Sanity check the mailboxes that were just added
2244 Mailbox testMailbox;
2245 testMailbox = Mailbox.restoreMailboxWithId(c, b11.mId);
2246 assertEquals(b11, testMailbox);
2247 testMailbox = Mailbox.restoreMailboxWithId(c, b12.mId);
2248 assertEquals(b12, testMailbox);
2249 testMailbox = Mailbox.restoreMailboxWithId(c, b13.mId);
2250 assertEquals(b13, testMailbox);
2251 testMailbox = Mailbox.restoreMailboxWithId(c, b21.mId);
2252 assertEqualsExceptServerId(b21, testMailbox, null);
2253 testMailbox = Mailbox.restoreMailboxWithId(c, b22.mId);
2254 assertEqualsExceptServerId(b22, testMailbox, "will-be-replaced");
2255 testMailbox = Mailbox.restoreMailboxWithId(c, b23.mId);
2256 assertEquals(b23, testMailbox);
2257 testMailbox = Mailbox.restoreMailboxWithId(c, b24.mId);
2258 assertEquals(b24, testMailbox);
2259 testMailbox = Mailbox.restoreMailboxWithId(c, b31.mId);
2260 assertEqualsExceptServerId(b31, testMailbox, "12");
2261 testMailbox = Mailbox.restoreMailboxWithId(c, b32.mId);
2262 assertEqualsExceptServerId(b32, testMailbox, "will-be-replaced");
2263 testMailbox = Mailbox.restoreMailboxWithId(c, b33.mId);
2264 assertEquals(b33, testMailbox);
2265 testMailbox = Mailbox.restoreMailboxWithId(c, b34.mId);
2266 assertEquals(b34, testMailbox);
2267
2268 SQLiteDatabase db = getProvider().getDatabase(mMockContext);
2269 EmailProvider.upgradeFromVersion17ToVersion18(db);
2270
2271 // Verify that only IMAP/POP3 mailboxes w/ a parent key of '0' are changed
2272 // Exchange mailboxes; none should be changed
2273 testMailbox = Mailbox.restoreMailboxWithId(c, b11.mId);
2274 assertEquals(b11, testMailbox);
2275 testMailbox = Mailbox.restoreMailboxWithId(c, b12.mId);
2276 assertEquals(b12, testMailbox);
2277 testMailbox = Mailbox.restoreMailboxWithId(c, b13.mId);
2278 assertEquals(b13, testMailbox);
2279
2280 // IMAP mailboxes; only mailboxes w/ a parent id of '0' are changed
2281 testMailbox = Mailbox.restoreMailboxWithId(c, b21.mId);
2282 assertEqualsExceptServerId(b21, testMailbox, "box4");
2283 testMailbox = Mailbox.restoreMailboxWithId(c, b22.mId);
2284 assertEqualsExceptServerId(b22, testMailbox, "box4/foo/bar");
2285 testMailbox = Mailbox.restoreMailboxWithId(c, b23.mId);
2286 assertEquals(b23, testMailbox);
2287 testMailbox = Mailbox.restoreMailboxWithId(c, b24.mId);
2288 assertEquals(b24, testMailbox);
2289
2290 // POP3 mailboxes; only mailboxes w/ a parent id of '0' are changed
2291 testMailbox = Mailbox.restoreMailboxWithId(c, b31.mId);
2292 assertEqualsExceptServerId(b31, testMailbox, "box7");
2293 testMailbox = Mailbox.restoreMailboxWithId(c, b32.mId);
2294 assertEqualsExceptServerId(b32, testMailbox, "box8/foo/bar");
2295 testMailbox = Mailbox.restoreMailboxWithId(c, b33.mId);
2296 assertEquals(b33, testMailbox);
2297 testMailbox = Mailbox.restoreMailboxWithId(c, b34.mId);
2298 assertEquals(b34, testMailbox);
2299 }
Makoto Onuki4c4e4c32011-05-13 14:09:22 -07002300
Marc Blankf3ff0ba2011-05-19 14:14:14 -07002301 /**
2302 * Determine whether a list of AccountManager accounts includes a given EmailProvider account
2303 * @param amAccountList a list of AccountManager accounts
2304 * @param account an EmailProvider account
2305 * @param context the caller's context (our test provider's context)
2306 * @return whether or not the EmailProvider account is represented in AccountManager
2307 */
2308 private boolean amAccountListHasAccount(android.accounts.Account[] amAccountList,
2309 Account account, Context context) {
Ben Komalo32bed4b2011-08-23 18:02:11 -07002310 String email = account.mEmailAddress;
Marc Blankf3ff0ba2011-05-19 14:14:14 -07002311 for (android.accounts.Account amAccount: amAccountList) {
Ben Komalo32bed4b2011-08-23 18:02:11 -07002312 if (amAccount.name.equals(email)) {
Marc Blankf3ff0ba2011-05-19 14:14:14 -07002313 return true;
2314 }
2315 }
2316 return false;
2317 }
2318
Marc Blank6e418aa2011-06-18 18:03:11 -07002319 public void testAutoCacheNewContent() {
2320 Account account = ProviderTestUtils.setupAccount("account-hostauth", false, mMockContext);
2321 // add hostauth data, which should be saved the first time
2322 account.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-hostauth-recv", -1, false,
2323 mMockContext);
2324 account.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-hostauth-send", -1, false,
2325 mMockContext);
2326 account.save(mMockContext);
2327 assertTrue(mProvider.isCached(Account.CONTENT_URI, account.mId));
2328 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, account.mHostAuthRecv.mId));
2329 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, account.mHostAuthSend.mId));
2330 }
2331
2332 /** Creates a mailbox; redefine as we need version 17 mailbox values */
2333 private Mailbox createTypeMailbox(Context c, long accountId, int type) {
2334 Mailbox box = new Mailbox();
2335
2336 box.mDisplayName = "foo";
2337 box.mServerId = "1:1";
2338 box.mParentKey = 0;
2339 box.mAccountKey = accountId;
2340 // Don't care about the fields below ... set them for giggles
2341 box.mType = type;
2342 box.save(c);
2343 return box;
2344 }
2345
2346 public void testAutoCacheInvalidate() {
2347 // Create 3 accounts with hostauth and 3 mailboxes each (2 of which are pre-cached)
2348 Account a = ProviderTestUtils.setupAccount("account1", false, mMockContext);
2349 a.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-recv", -1, false,
2350 mMockContext);
2351 a.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-send", -1, false,
2352 mMockContext);
2353 a.save(mMockContext);
2354 Mailbox a1 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_INBOX);
2355 Mailbox a2 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_MAIL);
2356 Mailbox a3 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_DRAFTS);
2357 Account b = ProviderTestUtils.setupAccount("account2", false, mMockContext);
2358 b.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-recv", -1, false,
2359 mMockContext);
2360 b.mHostAuthSend = ProviderTestUtils.setupHostAuth("accoun-send", -1, false,
2361 mMockContext);
2362 b.save(mMockContext);
2363 Mailbox b1 = createTypeMailbox(mMockContext, b.mId, Mailbox.TYPE_OUTBOX);
2364 Mailbox b2 = createTypeMailbox(mMockContext, b.mId, Mailbox.TYPE_MAIL);
2365 Mailbox b3 = createTypeMailbox(mMockContext, b.mId, Mailbox.TYPE_SENT);
2366 Account c = ProviderTestUtils.setupAccount("account3", false, mMockContext);
2367 c.mHostAuthRecv = ProviderTestUtils.setupHostAuth("account-recv", -1, false,
2368 mMockContext);
2369 c.mHostAuthSend = ProviderTestUtils.setupHostAuth("account-send", -1, false,
2370 mMockContext);
2371 c.save(mMockContext);
2372 Mailbox c1 = createTypeMailbox(mMockContext, c.mId, Mailbox.TYPE_SEARCH);
2373 Mailbox c2 = createTypeMailbox(mMockContext, c.mId, Mailbox.TYPE_MAIL);
2374 Mailbox c3 = createTypeMailbox(mMockContext, c.mId, Mailbox.TYPE_TRASH);
2375
2376 // Confirm expected cache state
2377 assertTrue(mProvider.isCached(Account.CONTENT_URI, a.mId));
2378 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, a.mHostAuthRecv.mId));
2379 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, a.mHostAuthSend.mId));
2380 assertTrue(mProvider.isCached(Account.CONTENT_URI, b.mId));
2381 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, b.mHostAuthRecv.mId));
2382 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, b.mHostAuthSend.mId));
2383 assertTrue(mProvider.isCached(Account.CONTENT_URI, c.mId));
2384 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, c.mHostAuthRecv.mId));
2385 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, c.mHostAuthSend.mId));
2386
2387 assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, a1.mId));
2388 assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, a2.mId));
2389 assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, a3.mId));
2390 assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, b1.mId));
2391 assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, b2.mId));
2392 assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, b3.mId));
2393 assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, c1.mId));
2394 assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, c2.mId));
2395 assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, c3.mId));
2396
2397 // Delete account b
2398 EmailContent.delete(mMockContext, Account.CONTENT_URI, b.mId);
2399
2400 // Confirm cache state
2401 assertTrue(mProvider.isCached(Account.CONTENT_URI, a.mId));
2402 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, a.mHostAuthRecv.mId));
2403 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, a.mHostAuthSend.mId));
2404 assertFalse(mProvider.isCached(Account.CONTENT_URI, b.mId));
2405 assertFalse(mProvider.isCached(HostAuth.CONTENT_URI, b.mHostAuthRecv.mId));
2406 assertFalse(mProvider.isCached(HostAuth.CONTENT_URI, b.mHostAuthSend.mId));
2407 assertTrue(mProvider.isCached(Account.CONTENT_URI, c.mId));
2408 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, c.mHostAuthRecv.mId));
2409 assertTrue(mProvider.isCached(HostAuth.CONTENT_URI, c.mHostAuthSend.mId));
2410
2411 assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, a1.mId));
2412 assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, a2.mId));
2413 assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, a3.mId));
2414 assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, b1.mId));
2415 assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, b2.mId));
2416 assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, b3.mId));
2417 assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, c1.mId));
2418 assertFalse(mProvider.isCached(Mailbox.CONTENT_URI, c2.mId));
2419 assertTrue(mProvider.isCached(Mailbox.CONTENT_URI, c3.mId));
2420 }
2421
Marc Blankf3ff0ba2011-05-19 14:14:14 -07002422 /**
2423 * Remove a single pop/imap account from the AccountManager
2424 * @param accountManager our AccountManager
2425 * @param name the name of the test account to remove
2426 */
2427 private void removeAccountManagerAccount(AccountManager accountManager, String name) {
2428 try {
2429 accountManager.removeAccount(
2430 new android.accounts.Account(name, AccountManagerTypes.TYPE_POP_IMAP),
2431 null, null).getResult();
2432 } catch (OperationCanceledException e) {
2433 } catch (AuthenticatorException e) {
2434 } catch (IOException e) {
2435 }
2436 }
2437
2438 /**
2439 * Remove all test accounts from the AccountManager
2440 * @param accountManager the AccountManager
2441 */
2442 private void cleanupTestAccountManagerAccounts(AccountManager accountManager) {
2443 android.accounts.Account[] amAccountList =
2444 accountManager.getAccountsByType(AccountManagerTypes.TYPE_POP_IMAP);
2445 for (android.accounts.Account account: amAccountList) {
2446 if (account.name.startsWith(AccountReconciler.ACCOUNT_MANAGER_ACCOUNT_TEST_PREFIX)) {
2447 removeAccountManagerAccount(accountManager, account.name);
2448 }
2449 }
2450 }
2451
2452 /** Verifies updating the DB from v21 to v22 works as expected */
2453 public void testUpgradeFromVersion21ToVersion22() {
2454 String imapTestLogin =
2455 AccountReconciler.ACCOUNT_MANAGER_ACCOUNT_TEST_PREFIX + "imap.host.com";
2456 String pop3TestLogin =
2457 AccountReconciler.ACCOUNT_MANAGER_ACCOUNT_TEST_PREFIX + "pop3.host.com";
2458 AccountManager accountManager = AccountManager.get(mContext);
2459
2460 // Create provider accounts (one of each type)
2461 Account a1 = createAccount(mMockContext, "exchange",
2462 ProviderTestUtils.setupHostAuth("eas", "exchange.host.com", true, mMockContext),
2463 null);
2464 HostAuth h2 =
2465 ProviderTestUtils.setupHostAuth("imap", "imap.host.com", false, mMockContext);
2466 h2.mLogin = imapTestLogin;
2467 h2.save(mMockContext);
2468 Account a2 = createAccount(mMockContext, "imap", h2,
2469 ProviderTestUtils.setupHostAuth("smtp", "smtp.host.com", true, mMockContext));
2470 HostAuth h3 =
2471 ProviderTestUtils.setupHostAuth("pop3", "pop3.host.com", false, mMockContext);
2472 h3.mLogin = pop3TestLogin;
2473 h3.save(mMockContext);
2474 Account a3 = createAccount(mMockContext, "pop3", h3,
2475 ProviderTestUtils.setupHostAuth("smtp", "smtp.host.com", true, mMockContext));
2476
2477 // Get the current list of AccountManager accounts (we have to use the real context here),
2478 // whereas we use the mock context for EmailProvider (this is because the mock context
2479 // doesn't implement AccountManager hooks)
2480 android.accounts.Account[] amAccountList =
2481 accountManager.getAccountsByType(AccountManagerTypes.TYPE_POP_IMAP);
2482 // There shouldn't be AccountManager accounts for these
2483 assertFalse(amAccountListHasAccount(amAccountList, a1, mMockContext));
2484 assertFalse(amAccountListHasAccount(amAccountList, a2, mMockContext));
2485 assertFalse(amAccountListHasAccount(amAccountList, a3, mMockContext));
2486
2487 amAccountList = null;
2488 try {
2489 // Upgrade the database
2490 SQLiteDatabase db = getProvider().getDatabase(mMockContext);
2491 EmailProvider.upgradeFromVersion21ToVersion22(db, getContext());
2492
2493 // The pop3 and imap account should now be in account manager
2494 amAccountList = accountManager.getAccountsByType(AccountManagerTypes.TYPE_POP_IMAP);
2495 assertFalse(amAccountListHasAccount(amAccountList, a1, mMockContext));
2496 assertTrue(amAccountListHasAccount(amAccountList, a2, mMockContext));
2497 assertTrue(amAccountListHasAccount(amAccountList, a3, mMockContext));
2498 } finally {
2499 cleanupTestAccountManagerAccounts(accountManager);
2500 }
2501 }
Marc Blank2bdf7ee2011-06-30 16:03:36 -07002502
2503 public void testCleanupOrphans() {
2504 EmailProvider ep = getProvider();
2505 SQLiteDatabase db = ep.getDatabase(mMockContext);
2506
2507 Account a = ProviderTestUtils.setupAccount("account1", true, mMockContext);
2508 // Mailbox a1 and a3 won't have a valid account
2509 Mailbox a1 = createTypeMailbox(mMockContext, -1, Mailbox.TYPE_INBOX);
2510 Mailbox a2 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_MAIL);
2511 Mailbox a3 = createTypeMailbox(mMockContext, -1, Mailbox.TYPE_DRAFTS);
2512 Mailbox a4 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_SENT);
2513 Mailbox a5 = createTypeMailbox(mMockContext, a.mId, Mailbox.TYPE_TRASH);
2514 // Mailbox ax isn't even saved; use an obviously invalid id
2515 Mailbox ax = new Mailbox();
2516 ax.mId = 69105;
2517
2518 // Message mt2 is an orphan, as is mt4
2519 Message m1 = createMessage(mMockContext, a1, true, false, Message.FLAG_LOADED_COMPLETE);
2520 Message m2 = createMessage(mMockContext, a2, true, false, Message.FLAG_LOADED_COMPLETE);
2521 Message m3 = createMessage(mMockContext, a3, true, false, Message.FLAG_LOADED_COMPLETE);
2522 Message m4 = createMessage(mMockContext, a4, true, false, Message.FLAG_LOADED_COMPLETE);
2523 Message m5 = createMessage(mMockContext, a5, true, false, Message.FLAG_LOADED_COMPLETE);
2524 Message mx = createMessage(mMockContext, ax, true, false, Message.FLAG_LOADED_COMPLETE);
2525
2526 // Two orphan policies
2527 Policy p1 = new Policy();
2528 p1.save(mMockContext);
2529 Policy p2 = new Policy();
2530 p2.save(mMockContext);
2531 Policy p3 = new Policy();
2532 Policy.setAccountPolicy(mMockContext, a.mId, p3, "0");
2533
2534 // We don't want anything cached or the tests below won't work. Note that
2535 // deleteUnlinked is only called by EmailProvider when the caches are empty
2536 ContentCache.invalidateAllCaches();
2537 // Delete orphaned mailboxes/messages/policies
2538 ep.deleteUnlinked(db, Mailbox.TABLE_NAME, MailboxColumns.ACCOUNT_KEY, AccountColumns.ID,
2539 Account.TABLE_NAME);
2540 ep.deleteUnlinked(db, Message.TABLE_NAME, MessageColumns.ACCOUNT_KEY, AccountColumns.ID,
2541 Account.TABLE_NAME);
2542 ep.deleteUnlinked(db, Policy.TABLE_NAME, PolicyColumns.ID, AccountColumns.POLICY_KEY,
2543 Account.TABLE_NAME);
2544
2545 // Make sure the orphaned mailboxes are gone
2546 assertNull(Mailbox.restoreMailboxWithId(mMockContext, a1.mId));
2547 assertNotNull(Mailbox.restoreMailboxWithId(mMockContext, a2.mId));
2548 assertNull(Mailbox.restoreMailboxWithId(mMockContext, a3.mId));
2549 assertNotNull(Mailbox.restoreMailboxWithId(mMockContext, a4.mId));
2550 assertNotNull(Mailbox.restoreMailboxWithId(mMockContext, a5.mId));
2551 assertNull(Mailbox.restoreMailboxWithId(mMockContext, ax.mId));
2552
2553 // Make sure orphaned messages are gone
2554 assertNull(Message.restoreMessageWithId(mMockContext, m1.mId));
2555 assertNotNull(Message.restoreMessageWithId(mMockContext, m2.mId));
2556 assertNull(Message.restoreMessageWithId(mMockContext, m3.mId));
2557 assertNotNull(Message.restoreMessageWithId(mMockContext, m4.mId));
2558 assertNotNull(Message.restoreMessageWithId(mMockContext, m5.mId));
2559 assertNull(Message.restoreMessageWithId(mMockContext, mx.mId));
2560
2561 // Make sure orphaned policies are gone
2562 assertNull(Policy.restorePolicyWithId(mMockContext, p1.mId));
2563 assertNull(Policy.restorePolicyWithId(mMockContext, p2.mId));
2564 a = Account.restoreAccountWithId(mMockContext, a.mId);
2565 assertNotNull(Policy.restorePolicyWithId(mMockContext, a.mPolicyKey));
2566 }
Andrew Stadler7143d962009-06-25 00:02:29 -07002567}