196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/*
296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *
496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * you may not use this file except in compliance with the License.
696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * You may obtain a copy of the License at
796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *
896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project *
1096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * See the License for the specific language governing permissions and
1496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * limitations under the License.
1596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */
1696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
1731d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blankpackage com.android.emailcommon.utility;
1896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
1903cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.email.DBTestHelper;
2003cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.email.R;
2103cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.email.TestUtils;
2203cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.email.provider.ProviderTestUtils;
2303cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.emailcommon.provider.Account;
2403cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.emailcommon.provider.EmailContent.Attachment;
2503cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.emailcommon.provider.EmailContent.MailboxColumns;
2603cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.emailcommon.provider.EmailContent.Message;
2703cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.emailcommon.provider.Mailbox;
2803cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport com.android.emailcommon.utility.Utility.NewFileCreator;
2903cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank
304bb52e36b18ab5e2fb9242069611bc0ef6116c09satokimport android.content.Context;
31adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onukiimport android.database.Cursor;
32adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onukiimport android.database.CursorWrapper;
33adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onukiimport android.database.MatrixCursor;
3403cd72805dab0379ed255d151f1c17cc60655fc3Marc Blankimport android.graphics.drawable.Drawable;
35d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onukiimport android.net.Uri;
367f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onukiimport android.os.Environment;
37654cc1f68f81e1f64a8f6242961d0ba507912371Marc Blankimport android.test.AndroidTestCase;
3820225d57609d6a5e482c088fdad60c29212d31a0Makoto Onukiimport android.test.MoreAsserts;
3996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport android.test.suitebuilder.annotation.SmallTest;
40a826d3fb03f29a07ea12e44237b2c02ea1926c74Makoto Onukiimport android.text.SpannableStringBuilder;
41adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onukiimport android.text.TextUtils;
42e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blankimport android.widget.TextView;
4396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
4444b5242edd938450f5e7bc5569852fa5f793da41Makoto Onukiimport java.io.File;
457f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onukiimport java.io.FileNotFoundException;
467f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onukiimport java.io.FileOutputStream;
4744b5242edd938450f5e7bc5569852fa5f793da41Makoto Onukiimport java.io.IOException;
487f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onukiimport java.io.OutputStream;
49767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onukiimport java.util.ArrayList;
50767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onukiimport java.util.Collection;
51dfee3ff278c4f5d9f7b8273c0e6ecab42585213eAndrew Stadlerimport java.util.HashSet;
52dfee3ff278c4f5d9f7b8273c0e6ecab42585213eAndrew Stadlerimport java.util.Set;
5396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
5496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/**
5596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * This is a series of unit tests for the Utility class.  These tests must be locally
5696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * complete - no server(s) required.
579d387ff0bb88ad952b53c956b468dcbcec248752Marc Blank *
589d387ff0bb88ad952b53c956b468dcbcec248752Marc Blank * You can run this entire test case with:
599d387ff0bb88ad952b53c956b468dcbcec248752Marc Blank *   runtest -c com.android.email.UtilityUnitTests email
6096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */
6196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project@SmallTest
62654cc1f68f81e1f64a8f6242961d0ba507912371Marc Blankpublic class UtilityUnitTests extends AndroidTestCase {
6320225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki
64fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki    private static byte[] b(int... array) {
65fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki        return TestUtils.b(array);
66fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki    }
6720225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki
68fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki    public void testToUtf8() {
6920225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki        assertNull(Utility.toUtf8(null));
7020225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki        MoreAsserts.assertEquals(new byte[] {}, Utility.toUtf8(""));
71fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki        MoreAsserts.assertEquals(b('a'), Utility.toUtf8("a"));
72fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki        MoreAsserts.assertEquals(b('A', 'B', 'C'), Utility.toUtf8("ABC"));
73fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki        MoreAsserts.assertEquals(b(0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E),
7420225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki                Utility.toUtf8("\u65E5\u672C\u8A9E"));
7520225d57609d6a5e482c088fdad60c29212d31a0Makoto Onuki    }
7688a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki
77fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki    public void testFromUtf8() {
78fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki        assertNull(Utility.fromUtf8(null));
79fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki        assertEquals("", Utility.fromUtf8(new byte[] {}));
80fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki        assertEquals("a", Utility.fromUtf8(b('a')));
81fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki        assertEquals("ABC", Utility.fromUtf8(b('A', 'B', 'C')));
82fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki        assertEquals("\u65E5\u672C\u8A9E",
83fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki                Utility.fromUtf8(b(0xE6, 0x97, 0xA5, 0xE6, 0x9C, 0xAC, 0xE8, 0xAA, 0x9E)));
84fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki    }
85fe61f358ab67cac2aa454a6dd3ea6bbf876e343cMakoto Onuki
8688a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki    public void testIsFirstUtf8Byte() {
8788a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki        // 1 byte in UTF-8.
8888a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki        checkIsFirstUtf8Byte("0"); // First 2 bits: 00
8988a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki        checkIsFirstUtf8Byte("A"); // First 2 bits: 01
9088a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki
9188a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki        checkIsFirstUtf8Byte("\u00A2"); // 2 bytes in UTF-8.
9288a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki        checkIsFirstUtf8Byte("\u20AC"); // 3 bytes in UTF-8.
9388a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki        checkIsFirstUtf8Byte("\uD852\uDF62"); // 4 bytes in UTF-8.  (surrogate pair)
9488a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki    }
9588a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki
9688a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki    private void checkIsFirstUtf8Byte(String aChar) {
9788a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki        byte[] bytes = Utility.toUtf8(aChar);
9888a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki        assertTrue("0", Utility.isFirstUtf8Byte(bytes[0]));
9988a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki        for (int i = 1; i < bytes.length; i++) {
10088a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki            assertFalse(Integer.toString(i), Utility.isFirstUtf8Byte(bytes[i]));
10188a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki        }
10288a94bca1922615564e70a27bb6ae72bca487c75Makoto Onuki    }
103dfeb1184ebf6c59fc6e617149e03edb73b7e0df7Makoto Onuki
104dfeb1184ebf6c59fc6e617149e03edb73b7e0df7Makoto Onuki    public void testByteToHex() {
105dfeb1184ebf6c59fc6e617149e03edb73b7e0df7Makoto Onuki        for (int i = 0; i <= 0xFF; i++) {
106dfeb1184ebf6c59fc6e617149e03edb73b7e0df7Makoto Onuki            String hex = Utility.byteToHex((byte) i);
107dfeb1184ebf6c59fc6e617149e03edb73b7e0df7Makoto Onuki            assertEquals("val=" + i, 2, hex.length());
108dfeb1184ebf6c59fc6e617149e03edb73b7e0df7Makoto Onuki            assertEquals("val=" + i, i, Integer.parseInt(hex, 16));
109dfeb1184ebf6c59fc6e617149e03edb73b7e0df7Makoto Onuki        }
110dfeb1184ebf6c59fc6e617149e03edb73b7e0df7Makoto Onuki    }
111eba33f8b5a0cc4a28ae5a9d6632df475c4b0a794Marc Blank
112eba33f8b5a0cc4a28ae5a9d6632df475c4b0a794Marc Blank    public void testReplaceBareLfWithCrlf() {
113eba33f8b5a0cc4a28ae5a9d6632df475c4b0a794Marc Blank        assertEquals("", Utility.replaceBareLfWithCrlf(""));
114eba33f8b5a0cc4a28ae5a9d6632df475c4b0a794Marc Blank        assertEquals("", Utility.replaceBareLfWithCrlf("\r"));
115eba33f8b5a0cc4a28ae5a9d6632df475c4b0a794Marc Blank        assertEquals("\r\n", Utility.replaceBareLfWithCrlf("\r\n"));
116eba33f8b5a0cc4a28ae5a9d6632df475c4b0a794Marc Blank        assertEquals("\r\n", Utility.replaceBareLfWithCrlf("\n"));
117eba33f8b5a0cc4a28ae5a9d6632df475c4b0a794Marc Blank        assertEquals("\r\n\r\n\r\n", Utility.replaceBareLfWithCrlf("\n\n\n"));
118eba33f8b5a0cc4a28ae5a9d6632df475c4b0a794Marc Blank        assertEquals("A\r\nB\r\nC\r\nD", Utility.replaceBareLfWithCrlf("A\nB\r\nC\nD"));
119eba33f8b5a0cc4a28ae5a9d6632df475c4b0a794Marc Blank    }
120d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki
121697f98aea5a8344a17ca5e9b0410d484fdce6555Makoto Onuki    public void testGetSmallHash() {
122697f98aea5a8344a17ca5e9b0410d484fdce6555Makoto Onuki        assertEquals("1438642069", Utility.getSmallHash(""));
123697f98aea5a8344a17ca5e9b0410d484fdce6555Makoto Onuki        assertEquals("1354919068", Utility.getSmallHash("abc"));
124697f98aea5a8344a17ca5e9b0410d484fdce6555Makoto Onuki    }
125697f98aea5a8344a17ca5e9b0410d484fdce6555Makoto Onuki
126d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki    public void testGetSmallSha1() {
127d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki        byte[] sha1 = new byte[20];
128d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki
129d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki        // White box test.  Not so great, but to make sure it may detect careless mistakes...
130d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki        assertEquals(0, Utility.getSmallHashFromSha1(sha1));
131d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki
132d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki        for (int i = 0; i < sha1.length; i++) {
133d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki            sha1[i] = (byte) 0xFF;
134d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki        }
135d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki        assertEquals(Integer.MAX_VALUE, Utility.getSmallHashFromSha1(sha1));
136d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki
137d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki        // Boundary check
138d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki        for (int i = 0; i < 16; i++) {
139d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki            sha1[19] = (byte) i;
140d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki            Utility.getSmallHashFromSha1(sha1);
141d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki        }
142d2a0d23380a2751d82f9d1f955a812f94a301e2aMakoto Onuki    }
143128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki
144128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki    public void testCleanUpMimeDate() {
145128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertNull(Utility.cleanUpMimeDate(null));
146128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertEquals("", Utility.cleanUpMimeDate(""));
147128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertEquals("abc", Utility.cleanUpMimeDate("abc"));
148128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertEquals("GMT", Utility.cleanUpMimeDate("GMT"));
149128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertEquals("0000", Utility.cleanUpMimeDate("0000"));
150128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertEquals("-0000", Utility.cleanUpMimeDate("-0000"));
151128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertEquals("+1234", Utility.cleanUpMimeDate("GMT+1234"));
152128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertEquals("-1234", Utility.cleanUpMimeDate("GMT-1234"));
153128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertEquals("gmt-1234", Utility.cleanUpMimeDate("gmt-1234"));
154128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertEquals("GMT-123", Utility.cleanUpMimeDate("GMT-123"));
155128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki
156128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertEquals("Thu, 10 Dec 09 15:08:08 -0700",
157128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki                Utility.cleanUpMimeDate("Thu, 10 Dec 09 15:08:08 GMT-0700"));
158128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki        assertEquals("Thu, 10 Dec 09 15:08:08 -0700",
159128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki                Utility.cleanUpMimeDate("Thu, 10 Dec 09 15:08:08 -0700"));
160128fb393e8ed613c2ce283c0bd51684af2ba444dMakoto Onuki    }
16144b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki
16244b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki    private static class MyNewFileCreator implements NewFileCreator {
16344b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        private final HashSet<String> mExistingFileNames;
16444b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki
16544b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        public MyNewFileCreator(String... fileNames) {
16644b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki            mExistingFileNames = new HashSet<String>();
16744b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki            for (String f : fileNames) {
16844b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki                mExistingFileNames.add(f);
16944b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki            }
17044b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        }
17144b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki
17244b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        @Override public boolean createNewFile(File f) {
17344b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki            return !mExistingFileNames.contains(f.getAbsolutePath());
17444b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        }
17544b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki    }
17644b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki
17744b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki    public void testCreateUniqueFile() throws Exception {
17844b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        final MyNewFileCreator noFiles = new MyNewFileCreator();
17944b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki
18044b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        // Case 1: Files don't exist.
18144b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        checkCreateUniqueFile("/a", noFiles, "/", "a");
18244b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        checkCreateUniqueFile("/a.txt", noFiles, "/", "a.txt");
18344b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki
18444b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        checkCreateUniqueFile("/a/b/a", noFiles, "/a/b", "a");
18544b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        checkCreateUniqueFile("/a/b/a.txt", noFiles, "/a/b", "a.txt");
18644b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki
18744b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        // Case 2: Files exist already.
18844b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        final MyNewFileCreator files = new MyNewFileCreator(
18944b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki                "/a", "/a.txt", "/a/b/a", "/a/b/a.txt",
19044b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki                "/a-2.txt",
19144b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki                "/a/b/a-2", "/a/b/a-3",
19244b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki                "/a/b/a-2.txt", "/a/b/a-3.txt", "/a/b/a-4.txt"
19344b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki                );
19444b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki
19544b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        checkCreateUniqueFile("/a-2", files, "/", "a");
19644b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        checkCreateUniqueFile("/a-3.txt", files, "/", "a.txt");
19744b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki
19844b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        checkCreateUniqueFile("/a/b/a-4", files, "/a/b", "a");
19944b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        checkCreateUniqueFile("/a/b/a-5.txt", files, "/a/b", "a.txt");
20044b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki    }
20144b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki
20244b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki    private void checkCreateUniqueFile(String expectedFileName, NewFileCreator nfc,
20344b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki            String dir, String fileName) throws Exception {
20444b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki        assertEquals(expectedFileName,
20544b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki                Utility.createUniqueFileInternal(nfc, new File(dir), fileName).toString());
20644b5242edd938450f5e7bc5569852fa5f793da41Makoto Onuki    }
2077f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki
2087f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki    /**
2097f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki     * Test that we have the necessary permissions to write to external storage.
2107f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki     */
2117f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki    public void testExternalStoragePermissions() throws FileNotFoundException, IOException {
2127f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki        File file = null;
2137f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki        try {
2147f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki            // If there's no storage available, this test is moot
2157f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki            if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
2167f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki                return;
2177f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki            }
2187f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki            file = Utility.createUniqueFile(Environment.getExternalStorageDirectory(),
2197f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki                    "write-test");
2207f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki            OutputStream out = new FileOutputStream(file);
2217f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki            out.write(1);
2227f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki            out.close();
2237f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki        } finally {
2247f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki            try {
2257f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki                if (file != null) {
2267f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki                    if (file.exists()) {
2277f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki                        file.delete();
2287f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki                    }
2297f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki                }
2307f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki            } catch (Exception e) {
2317f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki                // ignore cleanup error - it still throws the original
2327f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki            }
2337f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki        }
2347f247d1cd316789d2fcab2d1e41fb8af4d7243f8Makoto Onuki    }
235e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank
236e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank    public void testIsPortFieldValid() {
237e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        TextView view = new TextView(getContext());
238e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        // null, empty, negative, and non integer strings aren't valid
239e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        view.setText(null);
240e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        assertFalse(Utility.isPortFieldValid(view));
241e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        view.setText("");
242e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        assertFalse(Utility.isPortFieldValid(view));
243e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        view.setText("-1");
244e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        assertFalse(Utility.isPortFieldValid(view));
245e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        view.setText("1403.75");
246e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        assertFalse(Utility.isPortFieldValid(view));
247e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        view.setText("0");
248e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        assertFalse(Utility.isPortFieldValid(view));
249e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        view.setText("65536");
250e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        assertFalse(Utility.isPortFieldValid(view));
251e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        view.setText("i'm not valid");
252e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        assertFalse(Utility.isPortFieldValid(view));
253e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        // These next values are valid
254e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        view.setText("1");
255e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        assertTrue(Utility.isPortFieldValid(view));
256e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        view.setText("65535");
257e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank        assertTrue(Utility.isPortFieldValid(view));
258e6cc662abc0b5fffe223cda5e980b4f05a4e91ddMarc Blank    }
259bcf32320e2600e96c8a9e997a8903bfc3893b35eMakoto Onuki
260767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki    public void testToPrimitiveLongArray() {
261767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        assertEquals(0, Utility.toPrimitiveLongArray(createLongCollection()).length);
262767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki
263767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        final long[] one = Utility.toPrimitiveLongArray(createLongCollection(1));
264767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        assertEquals(1, one.length);
265767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        assertEquals(1, one[0]);
266767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki
267767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        final long[] two = Utility.toPrimitiveLongArray(createLongCollection(3, 4));
268767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        assertEquals(2, two.length);
269767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        assertEquals(3, two[0]);
270767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        assertEquals(4, two[1]);
271767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki    }
272767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki
2734e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki    public void testToLongSet() {
2744e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki        assertEquals(0, Utility.toLongSet(new long[] {}).size());
2754e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki
2764e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki        final Set<Long> one = Utility.toLongSet(new long[] {1});
2774e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki        assertEquals(1, one.size());
2784e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki        assertTrue(one.contains(1L));
2794e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki
2804e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki        final Set<Long> two = Utility.toLongSet(new long[] {1, 2});
2814e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki        assertEquals(2, two.size());
2824e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki        assertTrue(two.contains(1L));
2834e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki        assertTrue(two.contains(2L));
2844e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki    }
2854e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki
286d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki    public void testGetContentFileName() throws Exception {
287d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        Context providerContext = DBTestHelper.ProviderContextSetupHelper.getProviderContext(
288d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki                mContext);
289d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki
290d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        final long ACCOUNT_ID = 1;
291d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        final long MESSAGE_ID = 10;
292d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki
293d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        Account account = ProviderTestUtils.setupAccount("account", true, providerContext);
294d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        Mailbox mailbox = ProviderTestUtils.setupMailbox("box", account.mId, true, providerContext);
295d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki
296d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        // Set up an attachment.
297d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        Attachment att = ProviderTestUtils.setupAttachment(mailbox.mId, "name", 123, true,
298d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki                providerContext);
299d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        long attachmentId = att.mId;
3008a574694606f0e5d781334d0d426fc379c51f3edMarc Blank        Uri uri = AttachmentUtilities.getAttachmentUri(account.mId, attachmentId);
301d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki
302d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        // Case 1: exists in the provider.
303d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        assertEquals("name", Utility.getContentFileName(providerContext, uri));
304d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki
305d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        // Case 2: doesn't exist in the provider
3068a574694606f0e5d781334d0d426fc379c51f3edMarc Blank        Uri notExistUri = AttachmentUtilities.getAttachmentUri(account.mId, 123456789);
307d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        String lastPathSegment = notExistUri.getLastPathSegment();
308d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki        assertEquals(lastPathSegment, Utility.getContentFileName(providerContext, notExistUri));
309d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki    }
310d1ee5b8fa5fe92df1ded5953a9e3f001b38a1ac7Makoto Onuki
311a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy    private long getLastUpdateKey(Context mockContext, long mailboxId) {
312a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        return Utility.getFirstRowLong(mockContext, Mailbox.CONTENT_URI,
31303cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank                new String[] { MailboxColumns.LAST_SEEN_MESSAGE_KEY }, MailboxColumns.ID + "=?",
314a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                new String[] { Long.toString(mailboxId) }, null, 0, -1L);
315a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy    }
316a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy
317a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy    public void testUpdateLastSeenMessageKey() throws Exception {
318a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Context mockContext = DBTestHelper.ProviderContextSetupHelper.getProviderContext(mContext);
319a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy
320a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        // Setup account & message stuff
321a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Account account1 = ProviderTestUtils.setupAccount("account1", true, mockContext);
322a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Account account2 = ProviderTestUtils.setupAccount("account2", true, mockContext);
323a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Account account3 = ProviderTestUtils.setupAccount("account3", true, mockContext);
324a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Account account4 = ProviderTestUtils.setupAccount("account4", true, mockContext);
325a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Mailbox mailbox1_1 = ProviderTestUtils.setupMailbox("mbox1_1", account1.mId, true,
326a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mockContext, Mailbox.TYPE_INBOX);
327a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Mailbox mailbox1_2 = ProviderTestUtils.setupMailbox("mbox1_2", account1.mId, true,
328a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mockContext, Mailbox.TYPE_MAIL);
329a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Mailbox mailbox1_3 = ProviderTestUtils.setupMailbox("mbox1_3", account1.mId, true,
330a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mockContext, Mailbox.TYPE_DRAFTS);
331a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Mailbox mailbox1_4 = ProviderTestUtils.setupMailbox("mbox1_4", account1.mId, true,
332a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mockContext, Mailbox.TYPE_OUTBOX);
333a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Mailbox mailbox1_5 = ProviderTestUtils.setupMailbox("mbox1_5", account1.mId, true,
334a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mockContext, Mailbox.TYPE_TRASH);
335a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Mailbox mailbox2_1 = ProviderTestUtils.setupMailbox("mbox2_1", account2.mId, true,
336a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mockContext, Mailbox.TYPE_MAIL);
337a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Mailbox mailbox3_1 = ProviderTestUtils.setupMailbox("mbox3_1", account3.mId, true,
338a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mockContext, Mailbox.TYPE_MAIL);
339a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Mailbox mailbox3_2 = ProviderTestUtils.setupMailbox("mbox3_2", account3.mId, true,
340a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mockContext, Mailbox.TYPE_INBOX);
341a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Mailbox mailbox4_1 = ProviderTestUtils.setupMailbox("mbox4_1", account4.mId, true,
342a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mockContext, Mailbox.TYPE_INBOX);
343a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message1_1_1 = ProviderTestUtils.setupMessage("message_1_1_1", account1.mId,
344a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox1_1.mId, false, true, mockContext);
345a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message1_1_2 = ProviderTestUtils.setupMessage("message_1_1_2", account1.mId,
346a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox1_1.mId, false, true, mockContext);
347a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message1_1_3 = ProviderTestUtils.setupMessage("message_1_1_3", account1.mId,
348a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox1_1.mId, false, true, mockContext);
349a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message1_2_1 = ProviderTestUtils.setupMessage("message_1_2_1", account1.mId,
350a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox1_2.mId, false, true, mockContext);
351a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message1_3_1 = ProviderTestUtils.setupMessage("message_1_3_1", account1.mId,
352a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox1_3.mId, false, true, mockContext);
353a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message1_4_1 = ProviderTestUtils.setupMessage("message_1_4_1", account1.mId,
354a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox1_4.mId, false, true, mockContext);
355a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message1_5_1 = ProviderTestUtils.setupMessage("message_1_5_1", account1.mId,
356a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox1_5.mId, false, true, mockContext);
357a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message2_1_1 = ProviderTestUtils.setupMessage("message_2_1_1", account2.mId,
358a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox2_1.mId, false, true, mockContext);
359a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message2_1_2 = ProviderTestUtils.setupMessage("message_2_1_2", account2.mId,
360a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox2_1.mId, false, true, mockContext);
361a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message3_1_1 = ProviderTestUtils.setupMessage("message_3_1_1", account3.mId,
362a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox3_1.mId, false, true, mockContext);
363a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message4_1_1 = ProviderTestUtils.setupMessage("message_4_1_1", account4.mId,
364a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox4_1.mId, false, true, mockContext);
365a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message4_1_2 = ProviderTestUtils.setupMessage("message_4_1_2", account4.mId,
366a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox4_1.mId, false, true, mockContext);
367a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message4_1_3 = ProviderTestUtils.setupMessage("message_4_1_3", account4.mId,
368a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox4_1.mId, false, true, mockContext);
369a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        Message message4_1_4 = ProviderTestUtils.setupMessage("message_4_1_4", account4.mId,
370a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy                mailbox4_1.mId, false, true, mockContext);
371a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy
372a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        // Verify the default case
373a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_1.mId));
374a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_2.mId));
375a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_3.mId));
376a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_4.mId));
377a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_5.mId));
378a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox2_1.mId));
379a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox3_1.mId));
380a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox3_2.mId));
381a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox4_1.mId));
382a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy
383a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        // Test account; only INBOX is modified
38403cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank        Utility.updateLastSeenMessageKey(mockContext, account1.mId).get();
385a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(message1_1_3.mId, getLastUpdateKey(mockContext, mailbox1_1.mId));
386a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_2.mId));
387a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_3.mId));
388a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_4.mId));
389a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_5.mId));
390a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox2_1.mId));
391a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox3_1.mId));
392a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox3_2.mId));
393a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox4_1.mId));
394a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy
395a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        // Missing INBOX
39603cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank        Utility.updateLastSeenMessageKey(mockContext, account2.mId).get();
397a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(message1_1_3.mId, getLastUpdateKey(mockContext, mailbox1_1.mId));
398a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_2.mId));
399a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_3.mId));
400a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_4.mId));
401a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_5.mId));
402a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox2_1.mId));
403a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox3_1.mId));
404a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox3_2.mId));
405a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox4_1.mId));
406a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy
407a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        // No messages in mailbox
40803cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank        Utility.updateLastSeenMessageKey(mockContext, account3.mId).get();
409a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(message1_1_3.mId, getLastUpdateKey(mockContext, mailbox1_1.mId));
410a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_2.mId));
411a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_3.mId));
412a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_4.mId));
413a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_5.mId));
414a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox2_1.mId));
415a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox3_1.mId));
416a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox3_2.mId));
417a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox4_1.mId));
418a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy
419a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        // Test combined accounts
42003cd72805dab0379ed255d151f1c17cc60655fc3Marc Blank        Utility.updateLastSeenMessageKey(mockContext, 0x1000000000000000L).get();
421a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(message1_1_3.mId, getLastUpdateKey(mockContext, mailbox1_1.mId));
422a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_2.mId));
423a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_3.mId));
424a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_4.mId));
425a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox1_5.mId));
426a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox2_1.mId));
427a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox3_1.mId));
428a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(0L, getLastUpdateKey(mockContext, mailbox3_2.mId));
429a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy        assertEquals(message4_1_4.mId, getLastUpdateKey(mockContext, mailbox4_1.mId));
430a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy    }
431a17ee57c7ff7eb3391cc32f700aaa4fed8aa971fTodd Kennedy
4324e033e0ac79d85bc8df8e52bdfc8b1fc9ad29f3eMakoto Onuki    // used by testToPrimitiveLongArray
433767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki    private static Collection<Long> createLongCollection(long... values) {
434767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        ArrayList<Long> ret = new ArrayList<Long>();
435767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        for (long value : values) {
436767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki            ret.add(value);
437767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        }
438767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki        return ret;
439767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki    }
440767f9fe2ebcca7eee20f2a048f33a96ad4bf53daMakoto Onuki
441adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki    public void testDumpCursor() {
442adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        // Just make sure the method won't crash and returns non-empty string.
443adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        final Cursor c1 = new MatrixCursor(new String[] {"col"});
444adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        final Cursor c2 = new CursorWrapper(c1);
445adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki
446adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        // Note it's a subclass of CursorWrapper.
447adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        final Cursor c3 = new CursorWrapper(c2) {
448adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        };
449adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki
450adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        assertFalse(TextUtils.isEmpty(Utility.dumpCursor(c1)));
451adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        assertFalse(TextUtils.isEmpty(Utility.dumpCursor(c2)));
452adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        assertFalse(TextUtils.isEmpty(Utility.dumpCursor(c3)));
453adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        assertFalse(TextUtils.isEmpty(Utility.dumpCursor(null)));
454adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki
455adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        // Test again with closed cursor.
456adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        c1.close();
457adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        assertFalse(TextUtils.isEmpty(Utility.dumpCursor(c1)));
458adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        assertFalse(TextUtils.isEmpty(Utility.dumpCursor(c2)));
459adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        assertFalse(TextUtils.isEmpty(Utility.dumpCursor(c3)));
460adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        assertFalse(TextUtils.isEmpty(Utility.dumpCursor(null)));
461adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki    }
462adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki
463adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki    public void testCloseTraceCursorWrapper() {
464adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        final Cursor org = new MatrixCursor(new String[] {"col"});
465adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        final Utility.CloseTraceCursorWrapper c =
466adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki                Utility.CloseTraceCursorWrapper.alwaysCreateForTest(org);
467adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki
468adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        // Not closed -- no stack trace
469adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        assertNull(Utility.CloseTraceCursorWrapper.getTraceIfAvailable(c));
470adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        Utility.CloseTraceCursorWrapper.log(c); // shouldn't crash
471adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki
472adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        // Close, now stack trace should be available
473adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        c.close();
474adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        assertNotNull(Utility.CloseTraceCursorWrapper.getTraceIfAvailable(c));
475adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        Utility.CloseTraceCursorWrapper.log(c);
476adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki
477adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        // shouldn't crash
478adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki        Utility.CloseTraceCursorWrapper.log(null);
479adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki    }
480adbb6f8bc4df787a8e589d505b3f2e7d9c47cea4Makoto Onuki
481a826d3fb03f29a07ea12e44237b2c02ea1926c74Makoto Onuki    public void testAppendBold() {
482a826d3fb03f29a07ea12e44237b2c02ea1926c74Makoto Onuki        SpannableStringBuilder ssb = new SpannableStringBuilder();
483a826d3fb03f29a07ea12e44237b2c02ea1926c74Makoto Onuki        ssb.append("no");
484a826d3fb03f29a07ea12e44237b2c02ea1926c74Makoto Onuki
485a826d3fb03f29a07ea12e44237b2c02ea1926c74Makoto Onuki        assertEquals(ssb, Utility.appendBold(ssb, "BO"));
486a826d3fb03f29a07ea12e44237b2c02ea1926c74Makoto Onuki
487a826d3fb03f29a07ea12e44237b2c02ea1926c74Makoto Onuki        assertEquals("noBO", ssb.toString());
488a826d3fb03f29a07ea12e44237b2c02ea1926c74Makoto Onuki        // TODO check style -- but how?
489a826d3fb03f29a07ea12e44237b2c02ea1926c74Makoto Onuki    }
490a826d3fb03f29a07ea12e44237b2c02ea1926c74Makoto Onuki
491fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy    public void testAreStringsEqual() {
492fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        String s1;
493fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        String s2;
494fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy
495fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        s1 = new String("Foo");
496fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        s2 = s1;
497fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        assertTrue(Utility.areStringsEqual(s1, s2));
498fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy
499fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        s2 = new String("Foo");
500fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        assertTrue(Utility.areStringsEqual(s1, s2));
501fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy
502fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        s2 = "Bar";
503fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        assertFalse(Utility.areStringsEqual(s1, s2));
504fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy
505fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        s2 = null;
506fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        assertFalse(Utility.areStringsEqual(s1, s2));
507fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy
508fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        s1 = null;
509fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        s2 = "Bar";
510fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        assertFalse(Utility.areStringsEqual(s1, s2));
511fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy
512fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        s1 = null;
513fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        s2 = null;
514fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy        assertTrue(Utility.areStringsEqual(s1, s2));
515fe68c0e7c2672e09076038b36ad24f095633d313Todd Kennedy    }
516ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki
517ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki    public void testIsServerNameValid() {
518ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki        assertTrue(Utility.isServerNameValid("a"));
519ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki        assertTrue(Utility.isServerNameValid("gmail"));
520ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki        assertTrue(Utility.isServerNameValid("gmail.com"));
521ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki        assertTrue(Utility.isServerNameValid("gmail.com.x.y.z"));
522ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki        assertTrue(Utility.isServerNameValid("  gmail.com.x.y.z  "));
523ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki
524ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki        assertFalse(Utility.isServerNameValid(""));
525ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki        assertFalse(Utility.isServerNameValid("$"));
526ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki        assertFalse(Utility.isServerNameValid("  "));
527ce4cce05b2ee5ea2d9629c189a79f7f30778f534Makoto Onuki    }
5288de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki
5298de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki    private static Collection<Long> toColleciton(long... values) {
5308de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki        ArrayList<Long> ret = new ArrayList<Long>();
5318de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki        for (long v : values) {
5328de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki            ret.add(v);
5338de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki        }
5348de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki        return ret;
5358de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki    }
5368de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki
5378de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki    public void testBuildInSelection() {
5388de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki        assertEquals("", Utility.buildInSelection("c", null));
5398de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki        assertEquals("", Utility.buildInSelection("c", toColleciton()));
5408de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki        assertEquals("c in (1)", Utility.buildInSelection("c", toColleciton(1)));
5418de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki        assertEquals("c in (1,2)", Utility.buildInSelection("c", toColleciton(1, 2)));
5428de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki        assertEquals("c in (1,2,-500)", Utility.buildInSelection("c", toColleciton(1, 2, -500)));
5438de5bda81594182757c1aa94a65cfb8c7b360b34Makoto Onuki    }
54496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project}
545