AttachmentProviderTests.java revision e29189e3eeea9c629777b3deed6ea2be67caa737
1301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler/*
2301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler * Copyright (C) 2009 The Android Open Source Project
3301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler *
4301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler * Licensed under the Apache License, Version 2.0 (the "License");
5301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler * you may not use this file except in compliance with the License.
6301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler * You may obtain a copy of the License at
7301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler *
8301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler *      http://www.apache.org/licenses/LICENSE-2.0
9301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler *
10301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler * Unless required by applicable law or agreed to in writing, software
11301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler * distributed under the License is distributed on an "AS IS" BASIS,
12301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler * See the License for the specific language governing permissions and
14301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler * limitations under the License.
15301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler */
16301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
17301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerpackage com.android.email.provider;
18301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
19301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport com.android.email.R;
20301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport com.android.email.mail.MessagingException;
21301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport com.android.email.mail.store.LocalStore;
22301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport com.android.email.provider.AttachmentProvider.AttachmentProviderColumns;
23301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport com.android.email.provider.EmailContent.Account;
24301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport com.android.email.provider.EmailContent.Attachment;
2571754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadlerimport com.android.email.provider.EmailContent.Mailbox;
2671754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadlerimport com.android.email.provider.EmailContent.Message;
27301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
28301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport android.content.ContentResolver;
29301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport android.content.ContentValues;
30301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport android.content.Context;
31301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport android.content.res.AssetFileDescriptor;
32301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport android.database.Cursor;
33301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport android.database.sqlite.SQLiteDatabase;
34301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport android.graphics.Bitmap;
35301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport android.graphics.BitmapFactory;
36301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport android.net.Uri;
37301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport android.test.ProviderTestCase2;
38301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport android.test.mock.MockContentResolver;
39301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
40301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport java.io.File;
41301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport java.io.FileNotFoundException;
42301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport java.io.FileOutputStream;
43301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerimport java.io.IOException;
44301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
45301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler/**
46301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler * Tests of the Email Attachments provider.
471d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki *
48301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler * You can run this entire test case with:
49301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler *   runtest -c com.android.email.provider.AttachmentProviderTests email
50301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler */
51301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadlerpublic class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvider> {
52301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
53301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /*
54301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * This switch will enable us to transition these tests, and the AttachmentProvider, from the
55301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * "old" LocalStore model to the "new" provider model.  After the transition is complete,
56301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * this flag (and its associated code) can be removed.
57301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
583d25a519abf676f050b546d34401a277aea5de40Andrew Stadler    private final boolean USE_LOCALSTORE = false;
59301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    LocalStore mLocalStore = null;
60301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
61301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    EmailProvider mEmailProvider;
62301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    Context mMockContext;
63301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    ContentResolver mMockResolver;
64301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
65301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    public AttachmentProviderTests() {
66301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        super(AttachmentProvider.class, AttachmentProvider.AUTHORITY);
67301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
68301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
69301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    @Override
70301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    public void setUp() throws Exception {
71301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        super.setUp();
72301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        mMockContext = getMockContext();
73301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        mMockResolver = mMockContext.getContentResolver();
74301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
75301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Spin up an Email provider as well and put it under the same mock test framework
76301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        mEmailProvider = new EmailProvider();
77301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        mEmailProvider.attachInfo(mMockContext, null);
78301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertNotNull(mEmailProvider);
79301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        ((MockContentResolver) mMockResolver)
80301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                .addProvider(EmailProvider.EMAIL_AUTHORITY, mEmailProvider);
81301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
82301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
83301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    @Override
84301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    public void tearDown() throws Exception {
85301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        super.tearDown();
86301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
87301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        if (mLocalStore != null) {
88301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            mLocalStore.delete();
89301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        }
90301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
91301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
92301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /**
93301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * test delete() - should do nothing
94301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * test update() - should do nothing
95301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * test insert() - should do nothing
96301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
97301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    public void testUnimplemented() {
98301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(0, mMockResolver.delete(AttachmentProvider.CONTENT_URI, null, null));
99301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(0, mMockResolver.update(AttachmentProvider.CONTENT_URI, null, null, null));
100301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(null, mMockResolver.insert(AttachmentProvider.CONTENT_URI, null));
101301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
102301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
103301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /**
104301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * test query()
105301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     *  - item found
106301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     *  - item not found
107301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     *  - permuted projection
108301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
109301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    public void testQuery() throws MessagingException {
110301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Account account1 = ProviderTestUtils.setupAccount("attachment-query", false, mMockContext);
111301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        account1.mCompatibilityUuid = "test-UUID";
112301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        account1.save(mMockContext);
113301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        final long message1Id = 1;
114301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        long attachment1Id = 1;
115301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        long attachment2Id = 2;
116301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        long attachment3Id = 3;
117301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
118301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Note:  There is an implicit assumption in this test sequence that the first
119301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // attachment we add will be id=1 and the 2nd will have id=2.  This could fail on
120301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // a legitimate implementation.  Asserts below will catch this and fail the test
121301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // if necessary.
1223d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        Uri attachment1Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id);
1233d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        Uri attachment2Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id);
1243d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        Uri attachment3Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment3Id);
125301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
1263d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        // Test with no attached database - should return null
1273d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        Cursor c = mMockResolver.query(attachment1Uri, (String[])null, null, (String[])null, null);
1283d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        assertNull(c);
129301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
130301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Test with an attached database, but no attachment found - should return null
131301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        setupAttachmentDatabase(account1);
132301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        c = mMockResolver.query(attachment1Uri, (String[])null, null, (String[])null, null);
133301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertNull(c);
134301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
135301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Add a couple of attachment entries.  Note, query() just uses the DB, and does not
136301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // sample the files, so we won't bother creating the files
137301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Attachment newAttachment1 = ProviderTestUtils.setupAttachment(message1Id, "file1", 100,
138301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                false, mMockContext);
139301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        newAttachment1.mContentUri =
1403d25a519abf676f050b546d34401a277aea5de40Andrew Stadler            AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id).toString();
141301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        attachment1Id = addAttachmentToDb(account1, newAttachment1);
142301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("Broken test:  Unexpected id assignment", 1, attachment1Id);
143301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
144301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Attachment newAttachment2 = ProviderTestUtils.setupAttachment(message1Id, "file2", 200,
145301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                false, mMockContext);
146301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        newAttachment2.mContentUri =
1473d25a519abf676f050b546d34401a277aea5de40Andrew Stadler            AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id).toString();
148301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        attachment2Id = addAttachmentToDb(account1, newAttachment2);
149301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("Broken test:  Unexpected id assignment", 2, attachment2Id);
150301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
151301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Attachment newAttachment3 = ProviderTestUtils.setupAttachment(message1Id, "file3", 300,
152301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                false, mMockContext);
153301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        newAttachment3.mContentUri =
1543d25a519abf676f050b546d34401a277aea5de40Andrew Stadler            AttachmentProvider.getAttachmentUri(account1.mId, attachment3Id).toString();
155301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        attachment3Id = addAttachmentToDb(account1, newAttachment3);
156301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("Broken test:  Unexpected id assignment", 3, attachment3Id);
157301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
158301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Return a row with all columns specified
1593d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        attachment2Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id);
160301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        c = mMockResolver.query(
161301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                attachment2Uri,
162301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                new String[] { AttachmentProviderColumns._ID, AttachmentProviderColumns.DATA,
163301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                               AttachmentProviderColumns.DISPLAY_NAME,
164301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                               AttachmentProviderColumns.SIZE },
165301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                null, null, null);
166301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(1, c.getCount());
167301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertTrue(c.moveToFirst());
168301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(attachment2Id, c.getLong(0));                  // id
169301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(attachment2Uri.toString(), c.getString(1));    // content URI
170301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("file2", c.getString(2));                      // display name
171301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(200, c.getInt(3));                             // size
172301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
173301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Return a row with permuted columns
1743d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        attachment3Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment3Id);
175301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        c = mMockResolver.query(
176301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                attachment3Uri,
177301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                new String[] { AttachmentProviderColumns.SIZE,
178301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                               AttachmentProviderColumns.DISPLAY_NAME,
179301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                               AttachmentProviderColumns.DATA, AttachmentProviderColumns._ID },
180301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                null, null, null);
181301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(1, c.getCount());
182301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertTrue(c.moveToFirst());
183301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(attachment3Id, c.getLong(3));                  // id
184301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(attachment3Uri.toString(), c.getString(2));    // content URI
185301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("file3", c.getString(1));                      // display name
186301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(300, c.getInt(0));                             // size
187301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
188301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
189301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /**
190301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * test getType()
191301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     *  - regular file
192301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     *  - thumbnail
193301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
194301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    public void testGetType() throws MessagingException {
195301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Account account1 = ProviderTestUtils.setupAccount("get-type", false, mMockContext);
196301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        account1.mCompatibilityUuid = "test-UUID";
197301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        account1.save(mMockContext);
198301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        final long message1Id = 1;
199301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        long attachment1Id = 1;
200301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        long attachment2Id = 2;
201301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        long attachment3Id = 3;
20280ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        long attachment4Id = 4;
20380ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        long attachment5Id = 5;
20480ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        long attachment6Id = 6;
205301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
2063d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        Uri attachment1Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id);
207301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
208301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Test with no attached database - should return null
209301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        String type = mMockResolver.getType(attachment1Uri);
210301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertNull(type);
211301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
212301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Test with an attached database, but no attachment found - should return null
213301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        setupAttachmentDatabase(account1);
214301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        type = mMockResolver.getType(attachment1Uri);
215301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertNull(type);
216301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
217301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Add a couple of attachment entries.  Note, getType() just uses the DB, and does not
218301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // sample the files, so we won't bother creating the files
219301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Attachment newAttachment2 = ProviderTestUtils.setupAttachment(message1Id, "file2", 100,
220301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                false, mMockContext);
221301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        newAttachment2.mMimeType = "image/jpg";
222301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        attachment2Id = addAttachmentToDb(account1, newAttachment2);
223301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
224301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Attachment newAttachment3 = ProviderTestUtils.setupAttachment(message1Id, "file3", 100,
225301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                false, mMockContext);
2263d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        newAttachment3.mMimeType = "text/plain";
2273d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        attachment3Id = addAttachmentToDb(account1, newAttachment3);
228301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
22980ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        Attachment newAttachment4 = ProviderTestUtils.setupAttachment(message1Id, "file4.doc", 100,
23080ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler                false, mMockContext);
23180ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        newAttachment4.mMimeType = "application/octet-stream";
23280ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        attachment4Id = addAttachmentToDb(account1, newAttachment4);
23380ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler
23480ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        Attachment newAttachment5 = ProviderTestUtils.setupAttachment(message1Id, "file5.xyz", 100,
23580ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler                false, mMockContext);
23680ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        newAttachment5.mMimeType = "application/octet-stream";
23780ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        attachment5Id = addAttachmentToDb(account1, newAttachment5);
23880ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler
23980ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        Attachment newAttachment6 = ProviderTestUtils.setupAttachment(message1Id, "file6", 100,
24080ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler                false, mMockContext);
24180ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        newAttachment6.mMimeType = "";
24280ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        attachment6Id = addAttachmentToDb(account1, newAttachment6);
24380ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler
244301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Check the returned filetypes
2453d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        Uri uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id);
246301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        type = mMockResolver.getType(uri);
247301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("image/jpg", type);
2483d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment3Id);
249301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        type = mMockResolver.getType(uri);
250301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("text/plain", type);
25180ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment4Id);
25280ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        type = mMockResolver.getType(uri);
25380ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("application/msword", type);
25480ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment5Id);
25580ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        type = mMockResolver.getType(uri);
25680ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("application/xyz", type);
25780ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment6Id);
25880ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        type = mMockResolver.getType(uri);
25980ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("application/octet-stream", type);
260301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
261301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Check the returned filetypes for the thumbnails
262a98de7e55e91229c35352b496fad3fbb108a9609Andrew Stadler        uri = AttachmentProvider.getAttachmentThumbnailUri(account1.mId, attachment2Id, 62, 62);
263301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        type = mMockResolver.getType(uri);
264301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("image/png", type);
265a98de7e55e91229c35352b496fad3fbb108a9609Andrew Stadler        uri = AttachmentProvider.getAttachmentThumbnailUri(account1.mId, attachment3Id, 62, 62);
266301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        type = mMockResolver.getType(uri);
267301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("image/png", type);
268301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
269301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
270301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /**
27180ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler     * Test static inferMimeType()
27280ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler     * From the method doc:
2731d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki     * If the file extension is ".eml", return "message/rfc822", which is necessary for the email
2741d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki     * app to open it.
2751d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki     * If the given mime type is non-empty and anything other than "application/octet-stream",
2761d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki     * just return it.  (This is the most common case.)
2771d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki     * If the filename has a recognizable extension and it converts to a mime type, return that.
2781d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki     * If the filename has an unrecognized extension, return "application/extension"
2791d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki     * Otherwise return "application/octet-stream".
28080ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler     */
28180ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler    public void testInferMimeType() {
28280ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        final String DEFAULT = "application/octet-stream";
28380ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        final String FILE_PDF = "myfile.false.pdf";
28480ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        final String FILE_ABC = "myfile.false.abc";
28580ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        final String FILE_NO_EXT = "myfile";
28680ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler
28780ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        // If the given mime type is non-empty and anything other than "application/octet-stream",
28880ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        // just return it.  (This is the most common case.)
28980ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("mime/type", AttachmentProvider.inferMimeType(null, "mime/type"));
29080ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("mime/type", AttachmentProvider.inferMimeType("", "mime/type"));
29180ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("mime/type", AttachmentProvider.inferMimeType(FILE_PDF, "mime/type"));
29280ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler
29380ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        // If the filename has a recognizable extension and it converts to a mime type, return that.
29480ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, null));
29580ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, ""));
29680ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("application/pdf", AttachmentProvider.inferMimeType(FILE_PDF, DEFAULT));
29780ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler
29880ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        // If the filename has an unrecognized extension, return "application/extension"
29980ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, null));
30080ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, ""));
30180ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals("application/abc", AttachmentProvider.inferMimeType(FILE_ABC, DEFAULT));
30280ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler
30380ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        // Otherwise return "application/octet-stream".
30480ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals(DEFAULT, AttachmentProvider.inferMimeType(FILE_NO_EXT, null));
30580ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals(DEFAULT, AttachmentProvider.inferMimeType(FILE_NO_EXT, ""));
30680ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals(DEFAULT, AttachmentProvider.inferMimeType(FILE_NO_EXT, DEFAULT));
30780ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals(DEFAULT, AttachmentProvider.inferMimeType(null, null));
30880ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler        assertEquals(DEFAULT, AttachmentProvider.inferMimeType("", ""));
3091d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki
3101d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki        // Test for eml files.
3111d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki        assertEquals("message/rfc822", AttachmentProvider.inferMimeType("a.eMl", "text/plain"));
3121d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki        assertEquals("message/rfc822", AttachmentProvider.inferMimeType("a.eml", DEFAULT));
31380ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler    }
31480ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler
31580ebde2897dced46a0f24efb7c15a997b660a8feAndrew Stadler    /**
316301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * test openFile()
317301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     *  - regular file
318301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     *  - TODO: variations on the content URI
319301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
320301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    public void testOpenFile() throws MessagingException, IOException {
321301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Account account1 = ProviderTestUtils.setupAccount("open-file", false, mMockContext);
322301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        account1.mCompatibilityUuid = "test-UUID";
323301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        account1.save(mMockContext);
324301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        final long message1Id = 1;
325301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        long attachment1Id = 1;
326301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        long attachment2Id = 2;
327301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
328301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Note:  There is an implicit assumption in this test sequence that the first
329301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // attachment we add will be id=1 and the 2nd will have id=2.  This could fail on
330301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // a legitimate implementation.  Asserts below will catch this and fail the test
331301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // if necessary.
3323d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        Uri file1Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id);
3333d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        Uri file2Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id);
334301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
335301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Test with no attached database - should throw an exception
336301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        AssetFileDescriptor afd;
337301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        try {
338301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            afd = mMockResolver.openAssetFileDescriptor(file1Uri, "r");
339301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            fail("Should throw an exception on a bad URI");
340301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        } catch (FileNotFoundException fnf) {
341301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            // expected
342301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        }
343301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
344301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Test with an attached database, but no attachment found
345301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        setupAttachmentDatabase(account1);
346301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        try {
347301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            afd = mMockResolver.openAssetFileDescriptor(file1Uri, "r");
348301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            fail("Should throw an exception on a missing attachment entry");
349301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        } catch (FileNotFoundException fnf) {
350301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            // expected
351301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        }
352301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
353301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Add an attachment (but no associated file)
354301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Attachment newAttachment = ProviderTestUtils.setupAttachment(message1Id, "file", 100,
355301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                false, mMockContext);
356301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        attachment1Id = addAttachmentToDb(account1, newAttachment);
357301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("Broken test:  Unexpected id assignment", 1, attachment1Id);
358301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
359301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Test with an attached database, attachment entry found, but no attachment found
360301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        try {
361301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            afd = mMockResolver.openAssetFileDescriptor(file1Uri, "r");
362301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            fail("Should throw an exception on a missing attachment file");
363301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        } catch (FileNotFoundException fnf) {
364301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            // expected
365301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        }
366301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
367301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Create an "attachment" by copying an image resource into a file
368301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        /* String fileName = */ createAttachmentFile(account1, attachment2Id);
369301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Attachment newAttachment2 = ProviderTestUtils.setupAttachment(message1Id, "file", 100,
370301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                false, mMockContext);
371301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        newAttachment2.mContentId = null;
372301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        newAttachment2.mContentUri =
3733d25a519abf676f050b546d34401a277aea5de40Andrew Stadler                AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id).toString();
374301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        newAttachment2.mMimeType = "image/png";
375301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        attachment2Id = addAttachmentToDb(account1, newAttachment2);
376301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("Broken test:  Unexpected id assignment", 2, attachment2Id);
377301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
378301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Test with an attached database, attachment entry found - returns a file
379301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        afd = mMockResolver.openAssetFileDescriptor(file2Uri, "r");
380301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertNotNull(afd);
381301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // TODO: Confirm it's the "right" file?
382301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        afd.close();
383301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
384301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
385301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /**
386301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * test openFile()
387301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     *  - thumbnail
388301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * @throws IOException
389301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     *
390301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * TODO:  The thumbnail mode returns null for its failure cases (and in one case, throws
391301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * an SQLiteException).  The ContentResolver contract requires throwing FileNotFoundException
392301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * in all of the non-success cases, and the provider should be fixed for consistency.
393301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
394301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    public void testOpenThumbnail() throws MessagingException, IOException {
395301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Account account1 = ProviderTestUtils.setupAccount("open-thumbnail", false, mMockContext);
396301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        account1.mCompatibilityUuid = "test-UUID";
397301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        account1.save(mMockContext);
398301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        final long message1Id = 1;
399301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        long attachment1Id = 1;
400301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        long attachment2Id = 2;
401301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
402301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Note:  There is an implicit assumption in this test sequence that the first
403301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // attachment we add will be id=1 and the 2nd will have id=2.  This could fail on
404301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // a legitimate implementation.  Asserts below will catch this and fail the test
405301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // if necessary.
406a98de7e55e91229c35352b496fad3fbb108a9609Andrew Stadler        Uri thumb1Uri = AttachmentProvider.getAttachmentThumbnailUri(account1.mId, attachment1Id,
407301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                62, 62);
408a98de7e55e91229c35352b496fad3fbb108a9609Andrew Stadler        Uri thumb2Uri = AttachmentProvider.getAttachmentThumbnailUri(account1.mId, attachment2Id,
409301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                62, 62);
410301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
4113d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        // Test with no attached database - should return null (used to throw SQLiteException)
4123d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        AssetFileDescriptor afd = mMockResolver.openAssetFileDescriptor(thumb1Uri, "r");
4133d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        assertNull(afd);
414301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
415301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Test with an attached database, but no attachment found
416301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        setupAttachmentDatabase(account1);
4173d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        afd = mMockResolver.openAssetFileDescriptor(thumb1Uri, "r");
418301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertNull(afd);
419301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
420301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Add an attachment (but no associated file)
421301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Attachment newAttachment = ProviderTestUtils.setupAttachment(message1Id, "file", 100,
422301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                false, mMockContext);
423301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        attachment1Id = addAttachmentToDb(account1, newAttachment);
424301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("Broken test:  Unexpected id assignment", 1, attachment1Id);
425301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
426301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Test with an attached database, attachment entry found, but no attachment found
427301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        afd = mMockResolver.openAssetFileDescriptor(thumb1Uri, "r");
428301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertNull(afd);
429301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
430301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Create an "attachment" by copying an image resource into a file
431301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        /* String fileName = */ createAttachmentFile(account1, attachment2Id);
432301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Attachment newAttachment2 = ProviderTestUtils.setupAttachment(message1Id, "file", 100,
433301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                false, mMockContext);
434301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        newAttachment2.mContentId = null;
435301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        newAttachment2.mContentUri =
4363d25a519abf676f050b546d34401a277aea5de40Andrew Stadler                AttachmentProvider.getAttachmentUri(account1.mId, attachment2Id).toString();
437301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        newAttachment2.mMimeType = "image/png";
438301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        attachment2Id = addAttachmentToDb(account1, newAttachment2);
439301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals("Broken test:  Unexpected id assignment", 2, attachment2Id);
440301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
441301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // Test with an attached database, attachment entry found - returns a thumbnail
442301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        afd = mMockResolver.openAssetFileDescriptor(thumb2Uri, "r");
443301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertNotNull(afd);
444301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // TODO: Confirm it's the "right" file?
445301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        afd.close();
446301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
447301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
4489ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda    private Uri createAttachment(Account account, long messageId, String contentUriStr) {
4499ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        // Add an attachment entry.
4509ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        Attachment newAttachment = ProviderTestUtils.setupAttachment(messageId, "file", 100,
4519ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda                false, mMockContext);
4529ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        newAttachment.mContentUri = contentUriStr;
4539ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        long attachmentId = addAttachmentToDb(account, newAttachment);
4549ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        Uri attachmentUri = AttachmentProvider.getAttachmentUri(account.mId, attachmentId);
4559ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        return attachmentUri;
4569ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda    }
4579ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda
458301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /**
459301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * test resolveAttachmentIdToContentUri()
4609ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda     *  - without DB
461301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     *  - not in DB
4629ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda     *  - in DB, with not-null contentUri
4639ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda     *  - in DB, with null contentUri
464301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
465301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    public void testResolveAttachmentIdToContentUri() throws MessagingException {
466301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Account account1 = ProviderTestUtils.setupAccount("attachment-query", false, mMockContext);
467301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        account1.mCompatibilityUuid = "test-UUID";
468301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        account1.save(mMockContext);
469301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        final long message1Id = 1;
4709ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        // We use attachmentId == 1 but any other id would do
4719ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        final long attachment1Id = 1;
4729ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        final Uri attachment1Uri = AttachmentProvider.getAttachmentUri(account1.mId, attachment1Id);
473301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
4743d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        // Test with no attached database - should return input
4753d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        Uri result = AttachmentProvider.resolveAttachmentIdToContentUri(
4769ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda                mMockResolver, attachment1Uri);
4773d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        assertEquals(attachment1Uri, result);
478301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
479301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        setupAttachmentDatabase(account1);
4809ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda
4819ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        // Test with an attached database, but no attachment found - should return input
4829ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        // We know that the attachmentId 1 does not exist because there are no attachments
4839ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        // created at this point
4843d25a519abf676f050b546d34401a277aea5de40Andrew Stadler        result = AttachmentProvider.resolveAttachmentIdToContentUri(
485301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                mMockResolver, attachment1Uri);
486301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        assertEquals(attachment1Uri, result);
487301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
4889ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        // Test with existing attachement and contentUri != null
4899ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        // Note, resolveAttachmentIdToContentUri() just uses
490301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        // the DB, and does not sample the files, so we won't bother creating the files
4919ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        {
4929ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda            Uri attachmentUri = createAttachment(account1, message1Id, "file:///path/to/file");
4931d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki            Uri contentUri = AttachmentProvider.resolveAttachmentIdToContentUri(mMockResolver,
4949ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda                    attachmentUri);
4959ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda            // When the attachment is found, return the stored content_uri value
4969ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda            assertEquals("file:///path/to/file", contentUri.toString());
4979ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        }
498301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
4999ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        // Test with existing attachement and contentUri == null
5009ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        {
5019ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda            Uri attachmentUri = createAttachment(account1, message1Id, null);
5021d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki            Uri contentUri = AttachmentProvider.resolveAttachmentIdToContentUri(mMockResolver,
5039ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda                    attachmentUri);
5049ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda            // When contentUri is null should return input
5059ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda            assertEquals(attachmentUri, contentUri);
5069ef6f645f57d869a600113f555389b5d5e368c21Mihai Preda        }
507301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
508301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
509301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /**
5104b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler     * Test the functionality of deleting all attachment files for a given message.
5114b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler     */
5124b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler    public void testDeleteFiles() throws IOException {
5134b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        Account account1 = ProviderTestUtils.setupAccount("attachment-query", false, mMockContext);
5144b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        account1.mCompatibilityUuid = "test-UUID";
5154b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        account1.save(mMockContext);
5164b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        final long message1Id = 1;      // 1 attachment, 1 file
5174b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        final long message2Id = 2;      // 2 attachments, 2 files
5184b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        final long message3Id = 3;      // 1 attachment, missing file
5194b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        final long message4Id = 4;      // no attachments
5204b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler
5214b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        // Add attachment entries for various test messages
5224b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        Attachment newAttachment1 = ProviderTestUtils.setupAttachment(message1Id, "file1", 100,
5234b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler                true, mMockContext);
5244b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        Attachment newAttachment2 = ProviderTestUtils.setupAttachment(message2Id, "file2", 200,
5254b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler                true, mMockContext);
5264b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        Attachment newAttachment3 = ProviderTestUtils.setupAttachment(message2Id, "file3", 100,
5274b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler                true, mMockContext);
5284b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        Attachment newAttachment4 = ProviderTestUtils.setupAttachment(message3Id, "file4", 100,
5294b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler                true, mMockContext);
5304b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler
5314b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        // Create test files
5324b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        createAttachmentFile(account1, newAttachment1.mId);
5334b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        createAttachmentFile(account1, newAttachment2.mId);
5344b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        createAttachmentFile(account1, newAttachment3.mId);
5354b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler
5364b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        // Confirm 3 attachment files found
5374b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        File attachmentsDir = AttachmentProvider.getAttachmentDirectory(mMockContext, account1.mId);
5384b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        assertEquals(3, attachmentsDir.listFiles().length);
5394b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler
5404b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        // Command deletion of some files and check for results
5411d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki
5424b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        // Message 4 has no attachments so no files should be deleted
5434b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        AttachmentProvider.deleteAllAttachmentFiles(mMockContext, account1.mId, message4Id);
5444b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        assertEquals(3, attachmentsDir.listFiles().length);
5454b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler
5464b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        // Message 3 has no attachment files so no files should be deleted
5474b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        AttachmentProvider.deleteAllAttachmentFiles(mMockContext, account1.mId, message3Id);
5484b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        assertEquals(3, attachmentsDir.listFiles().length);
5494b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler
5504b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        // Message 2 has 2 attachment files so this should delete 2 files
5514b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        AttachmentProvider.deleteAllAttachmentFiles(mMockContext, account1.mId, message2Id);
5524b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        assertEquals(1, attachmentsDir.listFiles().length);
5534b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler
5544b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        // Message 1 has 1 attachment file so this should delete the last file
5554b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        AttachmentProvider.deleteAllAttachmentFiles(mMockContext, account1.mId, message1Id);
5564b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler        assertEquals(0, attachmentsDir.listFiles().length);
5574b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler    }
5584b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler
5594b41bae270ea4c49ec8403084db43ee9b37cdda4Andrew Stadler    /**
56071754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler     * Test the functionality of deleting an entire mailbox's attachments.
56171754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler     */
56271754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler    public void testDeleteMailbox() throws IOException {
56371754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        Account account1 = ProviderTestUtils.setupAccount("attach-mbox-del", false, mMockContext);
56471754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        account1.mCompatibilityUuid = "test-UUID";
56571754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        account1.save(mMockContext);
56671754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        long account1Id = account1.mId;
56771754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        Mailbox mailbox1 = ProviderTestUtils.setupMailbox("mbox1", account1Id, true, mMockContext);
56871754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        long mailbox1Id = mailbox1.mId;
56971754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        Mailbox mailbox2 = ProviderTestUtils.setupMailbox("mbox2", account1Id, true, mMockContext);
57071754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        long mailbox2Id = mailbox2.mId;
5711d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki
572e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        // Fill each mailbox with messages & attachments
573e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        populateAccountMailbox(account1, mailbox1Id, 3);
574e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        populateAccountMailbox(account1, mailbox2Id, 1);
57571754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler
57671754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        // Confirm four attachment files found
57771754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        File attachmentsDir = AttachmentProvider.getAttachmentDirectory(mMockContext, account1.mId);
57871754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        assertEquals(4, attachmentsDir.listFiles().length);
57971754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler
58071754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        // Command the deletion of mailbox 1 - we should lose 3 attachment files
58171754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        AttachmentProvider.deleteAllMailboxAttachmentFiles(mMockContext, account1Id, mailbox1Id);
58271754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        assertEquals(1, attachmentsDir.listFiles().length);
58371754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler
58471754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        // Command the deletion of mailbox 2 - we should lose 1 attachment file
58571754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        AttachmentProvider.deleteAllMailboxAttachmentFiles(mMockContext, account1Id, mailbox2Id);
58671754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler        assertEquals(0, attachmentsDir.listFiles().length);
58771754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler    }
5881d0be30871745ef0e623d8bb5e2e433567541623Makoto Onuki
589e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler    /**
590e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler     * Test the functionality of deleting an entire account's attachments.
591e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler     */
592e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler    public void testDeleteAccount() throws IOException {
593e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        Account account1 = ProviderTestUtils.setupAccount("attach-acct-del1", false, mMockContext);
594e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        account1.mCompatibilityUuid = "test-UUID";
595e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        account1.save(mMockContext);
596e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        long account1Id = account1.mId;
597e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        Mailbox mailbox1 = ProviderTestUtils.setupMailbox("mbox1", account1Id, true, mMockContext);
598e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        long mailbox1Id = mailbox1.mId;
599e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        Mailbox mailbox2 = ProviderTestUtils.setupMailbox("mbox2", account1Id, true, mMockContext);
600e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        long mailbox2Id = mailbox2.mId;
601e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler
602e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        // Repeat for account #2
603e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        Account account2 = ProviderTestUtils.setupAccount("attach-acct-del2", false, mMockContext);
604e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        account2.mCompatibilityUuid = "test-UUID-2";
605e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        account2.save(mMockContext);
606e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        long account2Id = account2.mId;
607e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        Mailbox mailbox3 = ProviderTestUtils.setupMailbox("mbox3", account2Id, true, mMockContext);
608e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        long mailbox3Id = mailbox3.mId;
609e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        Mailbox mailbox4 = ProviderTestUtils.setupMailbox("mbox4", account2Id, true, mMockContext);
610e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        long mailbox4Id = mailbox4.mId;
611e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler
612e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        // Fill each mailbox with messages & attachments
613e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        populateAccountMailbox(account1, mailbox1Id, 3);
614e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        populateAccountMailbox(account1, mailbox2Id, 1);
615e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        populateAccountMailbox(account2, mailbox3Id, 5);
616e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        populateAccountMailbox(account2, mailbox4Id, 2);
617e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler
618e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        // Confirm eleven attachment files found
619e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        File directory1 = AttachmentProvider.getAttachmentDirectory(mMockContext, account1.mId);
620e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        assertEquals(4, directory1.listFiles().length);
621e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        File directory2 = AttachmentProvider.getAttachmentDirectory(mMockContext, account2.mId);
622e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        assertEquals(7, directory2.listFiles().length);
623e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler
624e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        // Command the deletion of account 1 - we should lose 4 attachment files
625e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        AttachmentProvider.deleteAllAccountAttachmentFiles(mMockContext, account1Id);
626e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        assertEquals(0, directory1.listFiles().length);
627e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        assertEquals(7, directory2.listFiles().length);
628e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler
629e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        // Command the deletion of account 2 - we should lose 7 attachment file
630e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        AttachmentProvider.deleteAllAccountAttachmentFiles(mMockContext, account2Id);
631e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        assertEquals(0, directory1.listFiles().length);
632e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        assertEquals(0, directory2.listFiles().length);
633e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler    }
634e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler
635e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler    /**
636e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler     * Create a set of attachments for a given test account and mailbox.  Creates the following:
637e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler     *  Two messages per mailbox, one w/attachments, one w/o attachments
638e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler     *  Any number of attachments (on the first message)
639e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler     *  @param account the account to populate
640e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler     *  @param mailboxId the mailbox to populate
641e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler     *  @param numAttachments how many attachments to create
642e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler     */
643e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler    private void populateAccountMailbox(Account account, long mailboxId, int numAttachments)
644e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler            throws IOException {
645e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        long accountId = account.mId;
646e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler
647e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        // two messages per mailbox, one w/attachments, one w/o attachments
648e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        Message message1a = ProviderTestUtils.setupMessage(
649e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler                "msg1a", accountId, mailboxId, false, true, mMockContext);
650e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        /* Message message1b = */ ProviderTestUtils.setupMessage(
651e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler                "msg1b", accountId, mailboxId, false, true, mMockContext);
652e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler
653e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        // Create attachment records & files
654e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        for (int count = 0; count < numAttachments; count++) {
655e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler            Attachment newAttachment = ProviderTestUtils.setupAttachment(message1a.mId,
656e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler                    "file" + count, 100 * count, true, mMockContext);
657e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler            createAttachmentFile(account, newAttachment.mId);
658e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler        }
659e29189e3eeea9c629777b3deed6ea2be67caa737Andy Stadler    }
66071754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler
66171754d3f940fe82e251c274e3e56781e702cfd6fAndrew Stadler    /**
662301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * Create an attachment by copying an image resource into a file.  Uses "real" resources
663301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * to get a real image from Email
664301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
665301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    private String createAttachmentFile(Account forAccount, long id) throws IOException {
666301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        File outFile = getAttachmentFile(forAccount, id);
667301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(),
668301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                R.drawable.ic_email_attachment);
669301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        FileOutputStream out = new FileOutputStream(outFile);
670301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
671301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        out.close();
672301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
673301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        return outFile.getAbsolutePath();
674301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
675301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
676301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /**
677301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * Set up the attachments database.
678301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
679301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    private void setupAttachmentDatabase(Account forAccount) throws MessagingException {
680301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        if (USE_LOCALSTORE) {
681301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            String localStoreUri = "local://localhost/" + dbName(forAccount);
682301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            mLocalStore = (LocalStore) LocalStore.newInstance(localStoreUri, mMockContext, null);
683301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        } else {
6843d25a519abf676f050b546d34401a277aea5de40Andrew Stadler            // Nothing to do - EmailProvider is already available for us
685301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        }
686301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
687301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
688301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /**
689301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * Record an attachment in the attachments database
690301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * @return the id of the attachment just created
691301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
692301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    private long addAttachmentToDb(Account forAccount, Attachment newAttachment) {
693301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        long attachmentId = -1;
694301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        if (USE_LOCALSTORE) {
695301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            ContentValues cv = new ContentValues();
696301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            cv.put("message_id", newAttachment.mMessageKey);
697301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            cv.put("content_uri", newAttachment.mContentUri);
698301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            cv.put("store_data", (String)null);
699301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            cv.put("size", newAttachment.mSize);
700301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            cv.put("name", newAttachment.mFileName);
701301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            cv.put("mime_type", newAttachment.mMimeType);
702301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            cv.put("content_id", newAttachment.mContentId);
703301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
704301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            SQLiteDatabase db = null;
705301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            try {
706301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                db = SQLiteDatabase.openDatabase(dbName(forAccount), null, 0);
707301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                attachmentId = db.insertOrThrow("attachments", "message_id", cv);
708301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            }
709301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            finally {
710301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                if (db != null) {
711301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                    db.close();
712301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                }
713301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            }
714301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        } else {
7153d25a519abf676f050b546d34401a277aea5de40Andrew Stadler            newAttachment.save(mMockContext);
7163d25a519abf676f050b546d34401a277aea5de40Andrew Stadler            attachmentId = newAttachment.mId;
717301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        }
718301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        return attachmentId;
719301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
720301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
721301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /**
722301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * Return the database path+name for a given account
723301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
724301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    private String dbName(Account forAccount) {
725301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        if (USE_LOCALSTORE) {
726301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            return mMockContext.getDatabasePath(forAccount.mCompatibilityUuid + ".db").toString();
727301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        } else {
728301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            throw new java.lang.UnsupportedOperationException();
729301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        }
730301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
731301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler
732301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    /**
733301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     * Map from account, attachment ID to attachment file
734301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler     */
735301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    private File getAttachmentFile(Account forAccount, long id) {
736301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        String idString = Long.toString(id);
737301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        if (USE_LOCALSTORE) {
738301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler            return new File(mMockContext.getDatabasePath(forAccount.mCompatibilityUuid + ".db_att"),
739301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler                    idString);
740301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        } else {
7413d25a519abf676f050b546d34401a277aea5de40Andrew Stadler            File attachmentsDir = mMockContext.getDatabasePath(forAccount.mId + ".db_att");
7423d25a519abf676f050b546d34401a277aea5de40Andrew Stadler            if (!attachmentsDir.exists()) {
7433d25a519abf676f050b546d34401a277aea5de40Andrew Stadler                attachmentsDir.mkdirs();
7443d25a519abf676f050b546d34401a277aea5de40Andrew Stadler            }
7453d25a519abf676f050b546d34401a277aea5de40Andrew Stadler            return new File(attachmentsDir, idString);
746301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler        }
747301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler    }
748301ac18bb7f211b473c4f6fa6ec9bb276bbc6c10Andrew Stadler}
749