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
1796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectpackage com.android.email.mail.store;
1896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
19cb1d65c47825dc7a45c7954cd93669296b35305eBen Komaloimport android.content.Context;
20cb1d65c47825dc7a45c7954cd93669296b35305eBen Komaloimport android.test.AndroidTestCase;
21627bc6ed57ee06cc588e64ff959bfd7870b659b6Marc Blankimport android.test.suitebuilder.annotation.SmallTest;
22627bc6ed57ee06cc588e64ff959bfd7870b659b6Marc Blank
23cb1d65c47825dc7a45c7954cd93669296b35305eBen Komaloimport com.android.email.Controller;
24cb1d65c47825dc7a45c7954cd93669296b35305eBen Komaloimport com.android.email.DBTestHelper;
2554ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadlerimport com.android.email.mail.Transport;
2696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport com.android.email.mail.transport.MockTransport;
27cb1d65c47825dc7a45c7954cd93669296b35305eBen Komaloimport com.android.email.provider.ProviderTestUtils;
2831d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blankimport com.android.emailcommon.TempDirectory;
292193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.internet.MimeMessage;
302193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Address;
312193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.FetchProfile;
322193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Flag;
332193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Folder;
342193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Folder.FolderType;
352193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Folder.OpenMode;
3631d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blankimport com.android.emailcommon.mail.Message;
372193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Message.RecipientType;
3831d9acbf0623872f9d4a2b3210b5970854b654c7Marc Blankimport com.android.emailcommon.mail.MessagingException;
39f5418f1f93b02e7fab9f15eb201800b65510998eMarc Blankimport com.android.emailcommon.provider.Account;
4012b82d9374947c9268217f45befe8a74bd9b60d7Ben Komaloimport com.android.emailcommon.provider.HostAuth;
4196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
4296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/**
4396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * This is a series of unit tests for the POP3 Store class.  These tests must be locally
4496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * complete - no server(s) required.
4596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */
4696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project@SmallTest
47cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalopublic class Pop3StoreUnitTests extends AndroidTestCase {
4896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    final String UNIQUE_ID_1 = "20080909002219r1800rrjo9e00";
49a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
5096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    final static int PER_MESSAGE_SIZE = 100;
51a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
5296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /* These values are provided by setUp() */
5396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private Pop3Store mStore = null;
5496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private Pop3Store.Pop3Folder mFolder = null;
55a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
56cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo    private Context mMockContext;
57cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo
5896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
5996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Setup code.  We generate a lightweight Pop3Store and Pop3Store.Pop3Folder.
6096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
6196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    @Override
6296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    protected void setUp() throws Exception {
6396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        super.setUp();
64cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo        mMockContext = DBTestHelper.ProviderContextSetupHelper.getProviderContext(
65cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo                getContext());
66cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo        Controller.getInstance(mMockContext).setProviderContext(mMockContext);
67cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo        Controller.getInstance(mMockContext).markForTest(true);
68cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo
69a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        // Use the target's (i.e. the Email application) context
70cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo        TempDirectory.setTempDirectory(mMockContext);
710a8030562a5235591a5f5364bf5e6855ffa62861Makoto Onuki
7296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // These are needed so we can get at the inner classes
73a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        HostAuth testAuth = new HostAuth();
74cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo        Account testAccount = ProviderTestUtils.setupAccount("acct1", false, mMockContext);
75a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
76a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        testAuth.setLogin("user", "password");
77a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        testAuth.setConnection("pop3", "server", 999);
78a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        testAccount.mHostAuthRecv = testAuth;
79cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo        testAccount.save(mMockContext);
80cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo        mStore = (Pop3Store) Pop3Store.newInstance(testAccount, mMockContext);
8196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mFolder = (Pop3Store.Pop3Folder) mStore.getFolder("INBOX");
8296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
8396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
8496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
8596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test various sunny-day operations of UIDL parser for multi-line responses
8696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
8796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void testUIDLParserMulti() {
8896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
8996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // multi-line mode
9096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
91a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
9296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // Test basic in-list UIDL
9396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        parser.parseMultiLine("101 " + UNIQUE_ID_1);
9496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(101, parser.mMessageNumber);
9596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(UNIQUE_ID_1, parser.mUniqueId);
9696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertFalse(parser.mEndOfMessage);
9796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertFalse(parser.mErr);
98a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
9996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        //  Test end-of-list
10096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        parser.parseMultiLine(".");
10196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertTrue(parser.mEndOfMessage);
10296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertFalse(parser.mErr);
10396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
104a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
10596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
10696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test various sunny-day operations of UIDL parser for single-line responses
10796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
108a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy    public void testUIDLParserSingle() {
10996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
11096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // single-line mode
11196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
11296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
11396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // Test single-message OK response
11496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        parser.parseSingleLine("+OK 101 " + UNIQUE_ID_1);
11596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(101, parser.mMessageNumber);
11696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(UNIQUE_ID_1, parser.mUniqueId);
11796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertTrue(parser.mEndOfMessage);
118a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
11996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // Test single-message ERR response
12096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        parser.parseSingleLine("-ERR what???");
12196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertTrue(parser.mErr);
12296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
123a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
12496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
125b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler     * Test various rainy-day operations of the UIDL parser for multi-line responses
126b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler     * TODO other malformed responses
127b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler     */
128b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler    public void testUIDLParserMultiFail() {
129b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        // multi-line mode
130b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
131a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
132b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        // Test with null input
133b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        boolean result;
134b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        result = parser.parseMultiLine(null);
135b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        assertFalse(result);
136a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
137b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        // Test with empty input
138b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        result = parser.parseMultiLine("");
139b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        assertFalse(result);
140b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler    }
141a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
142b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler    /**
143b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler     * Test various rainy-day operations of the UIDL parser for single-line responses
144b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler     * TODO other malformed responses
145b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler     */
146b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler    public void testUIDLParserSingleFail() {
147b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        // single-line mode
148b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
149a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
150b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        // Test with null input
151b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        boolean result;
152b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        result = parser.parseSingleLine(null);
153b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        assertFalse(result);
154a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
155b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        // Test with empty input
156b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        result = parser.parseSingleLine("");
157b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler        assertFalse(result);
158b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler    }
159a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
160b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler    /**
16196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Tests that variants on the RFC-specified formatting of UIDL work properly.
16296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
16396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void testUIDLComcastVariant() {
164a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
16596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // multi-line mode
16696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Pop3Store.Pop3Folder.UidlParser parser = mFolder.new UidlParser();
167a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
16896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // Comcast servers send multiple spaces in their darn UIDL strings.
16996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        parser.parseMultiLine("101   " + UNIQUE_ID_1);
17096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(101, parser.mMessageNumber);
17196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(UNIQUE_ID_1, parser.mUniqueId);
17296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertFalse(parser.mEndOfMessage);
17396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertFalse(parser.mErr);
17496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
175a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
17696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
17796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Confirms simple non-SSL non-TLS login
17896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
17996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void testSimpleLogin() throws MessagingException {
180a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
18196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        MockTransport mockTransport = openAndInjectMockTransport();
182a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
18396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // try to open it
18496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupOpenFolder(mockTransport, 0, null);
185244d306ebb0addbc5d87008af9412b76c80e861eMarc Blank        mFolder.open(OpenMode.READ_ONLY);
18696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
187a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
18896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
18996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * TODO: Test with SSL negotiation (faked)
19096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * TODO: Test with SSL required but not supported
19196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * TODO: Test with TLS negotiation (faked)
19296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * TODO: Test with TLS required but not supported
19396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * TODO: Test calling getMessageCount(), getMessages(), etc.
19496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
195a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
19696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
19796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test the operation of checkSettings(), which requires (a) a good open and (b) UIDL support.
19896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
19996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void testCheckSettings() throws MessagingException {
20096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
20196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        MockTransport mockTransport = openAndInjectMockTransport();
202a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
20396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // scenario 1:  CAPA returns -ERR, so we try UIDL explicitly
20496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupOpenFolder(mockTransport, 0, null);
20596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupUidlSequence(mockTransport, 1);
20696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mockTransport.expect("QUIT", "");
20796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mStore.checkSettings();
208a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
20996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // scenario 2:  CAPA indicates UIDL, so we don't try UIDL
21096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupOpenFolder(mockTransport, 0, "UIDL");
21196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mockTransport.expect("QUIT", "");
21296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mStore.checkSettings();
213a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
21496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // scenario 3:  CAPA returns -ERR, and UIDL fails
21596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        try {
21696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            setupOpenFolder(mockTransport, 0, null);
21796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            mockTransport.expect("UIDL", "-ERR unsupported");
21896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            mockTransport.expect("QUIT", "");
21996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            mStore.checkSettings();
22096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            fail("MessagingException was expected due to UIDL unsupported.");
22196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        } catch (MessagingException me) {
22296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            // this is expected, so eat it
22396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
22496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
22596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
22696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
22754ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler     * Test a strange case that causes open to proceed without mCapabilities
22854ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler     *  open - fail with "-" error code
22954ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler     *  then check capabilities
23054ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler     */
23154ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler    public void testCheckSettingsCapabilities() throws MessagingException {
23254ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler
23354ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        MockTransport mockTransport = openAndInjectMockTransport();
23454ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler
23554ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        // First, preload an open that fails for some reason
23654ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        mockTransport.expect(null, "-ERR from the Mock Transport.");
23754ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler
23854ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        // And watch it fail
23954ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        try {
24054ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler            Pop3Store.Pop3Folder folder = mStore.new Pop3Folder("INBOX");
241244d306ebb0addbc5d87008af9412b76c80e861eMarc Blank            folder.open(OpenMode.READ_WRITE);
24254ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler            fail("Should have thrown exception");
24354ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        } catch (MessagingException me) {
24454ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler            // Expected - continue.
24554ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        }
24654ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler
24754ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        // Now try again (assuming a slightly different connection setup - successful)
24854ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        // Note, checkSettings is going to try to close the connection again, so we expect
24954ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        // one extra QUIT before we spin it up again
25054ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        mockTransport.expect("QUIT", "");
25154ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        mockTransport.expectClose();
25254ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        setupOpenFolder(mockTransport, 0, "UIDL");
25354ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        mockTransport.expect("QUIT", "");
25454ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler        mStore.checkSettings();
25554ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler    }
25654ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler
25754ab7a27a3756a241ba06f0762969cf5a338bf60Andy Stadler    /**
25896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test small Store & Folder functions that manage folders & namespace
25996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
260e87ff6c3cbbfc5e3636f9827b58820652e3ea1c5Todd Kennedy    public void testStoreFoldersFunctions() {
261a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
26296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // getPersonalNamespaces() always returns INBOX folder
263200c6bd9fa19b78acc2c1664f858521aa9885353Todd Kennedy        Folder[] folders = mStore.updateFolders();
26496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(1, folders.length);
26596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertSame(mFolder, folders[0]);
26696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
26796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // getName() returns the name we were created with.  If "inbox", converts to INBOX
26896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals("INBOX", mFolder.getName());
26996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Pop3Store.Pop3Folder folderMixedCaseInbox = mStore.new Pop3Folder("iNbOx");
27096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals("INBOX", folderMixedCaseInbox.getName());
27196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Pop3Store.Pop3Folder folderNotInbox = mStore.new Pop3Folder("NOT-INBOX");
27296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals("NOT-INBOX", folderNotInbox.getName());
273a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
27496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // exists() true if name is INBOX
27596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertTrue(mFolder.exists());
27696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertTrue(folderMixedCaseInbox.exists());
27796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertFalse(folderNotInbox.exists());
27896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
279a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
28096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
28196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test small Folder functions that don't really do anything in Pop3
28296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
283a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy    public void testSmallFolderFunctions() {
284a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
2854f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        // getMode() returns OpenMode.READ_WRITE
2864f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        assertEquals(OpenMode.READ_WRITE, mFolder.getMode());
287c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler
288c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        // canCreate() && create() return false
289c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertFalse(mFolder.canCreate(FolderType.HOLDS_FOLDERS));
290c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler        assertFalse(mFolder.canCreate(FolderType.HOLDS_MESSAGES));
29196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertFalse(mFolder.create(FolderType.HOLDS_FOLDERS));
29296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertFalse(mFolder.create(FolderType.HOLDS_MESSAGES));
293c41c47fa07a22f8a7612fb0191f152a36d95b7a5Andrew Stadler
29496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // getUnreadMessageCount() always returns -1
29596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(-1, mFolder.getUnreadMessageCount());
296a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
29796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // getPermanentFlags() returns { Flag.DELETED }
29896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Flag[] flags = mFolder.getPermanentFlags();
29996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(1, flags.length);
30096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(Flag.DELETED, flags[0]);
301a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
30296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // appendMessages(Message[] messages) does nothing
30396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mFolder.appendMessages(null);
304a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
30596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // delete(boolean recurse) does nothing
30696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // TODO - it should!
30796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mFolder.delete(false);
308a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
30996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // expunge() returns null
31096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertNull(mFolder.expunge());
311a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
31296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // copyMessages() is unsupported
31396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        try {
3145551f7feb210313aaf3e5a33cdaec5f991ba3288Andy Stadler            mFolder.copyMessages(null, null, null);
31596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            fail("Exception not thrown by copyMessages()");
31696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        } catch (UnsupportedOperationException e) {
31796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            // expected - succeed
31896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
31996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
320a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
32196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
3221f48259d22001f3e745e34e1bf142dfaf6cad94bAndy Stadler     * Lightweight test to confirm that POP3 hasn't implemented any folder roles yet.
3231f48259d22001f3e745e34e1bf142dfaf6cad94bAndy Stadler     */
324e87ff6c3cbbfc5e3636f9827b58820652e3ea1c5Todd Kennedy    public void testNoFolderRolesYet() {
325200c6bd9fa19b78acc2c1664f858521aa9885353Todd Kennedy        Folder[] remoteFolders = mStore.updateFolders();
3261f48259d22001f3e745e34e1bf142dfaf6cad94bAndy Stadler        for (Folder folder : remoteFolders) {
327a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy            assertEquals(Folder.FolderRole.UNKNOWN, folder.getRole());
3281f48259d22001f3e745e34e1bf142dfaf6cad94bAndy Stadler        }
3291f48259d22001f3e745e34e1bf142dfaf6cad94bAndy Stadler    }
3301f48259d22001f3e745e34e1bf142dfaf6cad94bAndy Stadler
3311f48259d22001f3e745e34e1bf142dfaf6cad94bAndy Stadler    /**
332c9f151d4fe47c5d426109822a7042ae8bbeb0a06Andy Stadler     * Lightweight test to confirm that POP3 is requesting sent-message-upload.
333c9f151d4fe47c5d426109822a7042ae8bbeb0a06Andy Stadler     */
334c9f151d4fe47c5d426109822a7042ae8bbeb0a06Andy Stadler    public void testSentUploadRequested() {
335a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        assertTrue(mStore.requireCopyMessageToSentFolder());
336c9f151d4fe47c5d426109822a7042ae8bbeb0a06Andy Stadler    }
337c9f151d4fe47c5d426109822a7042ae8bbeb0a06Andy Stadler
338c9f151d4fe47c5d426109822a7042ae8bbeb0a06Andy Stadler    /**
33996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test the process of opening and indexing a mailbox with one unread message in it.
340a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
34196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * TODO should create an instrumented listener to confirm all expected callbacks.  Then use
34296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * it everywhere we could have passed a message listener.
34396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
34496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void testOneUnread() throws MessagingException {
345a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
34696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        MockTransport mockTransport = openAndInjectMockTransport();
347a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
34896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        checkOneUnread(mockTransport);
34996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
35096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
35196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
3524f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi     * Test the process of opening and getting message by uid.
3534f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi     */
3544f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi    public void testGetMessageByUid() throws MessagingException {
355a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
3564f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        MockTransport mockTransport = openAndInjectMockTransport();
357a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
3584f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        setupOpenFolder(mockTransport, 2, null);
359244d306ebb0addbc5d87008af9412b76c80e861eMarc Blank        mFolder.open(OpenMode.READ_WRITE);
3604f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        // check message count
3614f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        assertEquals(2, mFolder.getMessageCount());
3624f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi
3634f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        // setup 2 messages
3644f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        setupUidlSequence(mockTransport, 2);
3654f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        String uid1 = getSingleMessageUID(1);
3664f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        String uid2 = getSingleMessageUID(2);
3674f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        String uid3 = getSingleMessageUID(3);
368a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
3694f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        Message msg1 = mFolder.getMessage(uid1);
3704f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        assertTrue("message with uid1", msg1 != null);
3714f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi
3724f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        // uid3 does not exist
3734f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        Message msg3 = mFolder.getMessage(uid3);
3744f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        assertTrue("message with uid3", msg3 == null);
3754f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi
3764f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        Message msg2 = mFolder.getMessage(uid2);
3774f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi        assertTrue("message with uid2", msg2 != null);
3784f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi    }
3794f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi
3804f23ebd3dcca596533a33e6faedb446a814d32e3Takaoka G. Tadashi    /**
38196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test the scenario where the transport is "open" but not really (e.g. server closed).  Two
38296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * things should happen:  We should see an intermediate failure that makes sense, and the next
38396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * operation should reopen properly.
384a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
385092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * There are multiple versions of this test because we are simulating the steps of
38696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * MessagingController.synchronizeMailboxSyncronous() and we will inject the failure a bit
38796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * further along in each case, to test various recovery points.
388a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
389092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * This test confirms that Pop3Store needs to call close() in the IOExceptionHandler in
390092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * Pop3Folder.getMessages(), due to a closure before the UIDL command completes.
39196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
392092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    public void testCatchClosed1a() throws MessagingException {
393092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
39496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        MockTransport mockTransport = openAndInjectMockTransport();
395092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
39696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        openFolderWithMessage(mockTransport);
397092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
39896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // cause the next sequence to fail on the readLine() calls
39996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mockTransport.closeInputStream();
400092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
40196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // index the message(s) - it should fail, because our stream is broken
40296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        try {
40396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            setupUidlSequence(mockTransport, 1);
40496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            Message[] messages = mFolder.getMessages(1, 1, null);
40596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            assertEquals(1, messages.length);
40696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            assertEquals(getSingleMessageUID(1), messages[0].getUid());
40796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            fail("Broken stream should cause getMessages() to throw.");
408092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        } catch(MessagingException me) {
409092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            // success
41096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
411092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
412092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // At this point the UI would display connection error, which is fine.  Now, the real
413092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // test is, can we recover?  So I'll just repeat the above steps, without the failure.
414092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // NOTE: everything from here down is copied from testOneUnread() and should be consolidated
415092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
416092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // confirm that we're closed at this point
4172720a818d5de169734434b114adfdf824a485f55Marc Blank        assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
418092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
419092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // and confirm that the next connection will be OK
420092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        checkOneUnread(mockTransport);
421092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    }
422092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
423092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    /**
424092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * Test the scenario where the transport is "open" but not really (e.g. server closed).  Two
425092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * things should happen:  We should see an intermediate failure that makes sense, and the next
426092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * operation should reopen properly.
427a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
428092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * There are multiple versions of this test because we are simulating the steps of
429092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * MessagingController.synchronizeMailboxSyncronous() and we will inject the failure a bit
430092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * further along in each case, to test various recovery points.
431a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
432092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * This test confirms that Pop3Store needs to call close() in the IOExceptionHandler in
433092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * Pop3Folder.getMessages(), due to non-numeric data in a multi-line UIDL.
434092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     */
435092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    public void testCatchClosed1b() throws MessagingException {
436092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
437092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        MockTransport mockTransport = openAndInjectMockTransport();
438092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
439092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        openFolderWithMessage(mockTransport);
440092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
441092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // index the message(s) - it should fail, because our stream is broken
442092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        try {
443092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            // setupUidlSequence(mockTransport, 1);
444092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            mockTransport.expect("UIDL", "+OK sending UIDL list");
445092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            mockTransport.expect(null, "bad-data" + " " + "THE-UIDL");
446092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            mockTransport.expect(null, ".");
447092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
448092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            Message[] messages = mFolder.getMessages(1, 1, null);
449092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            fail("Bad UIDL should cause getMessages() to throw.");
450092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        } catch(MessagingException me) {
45196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            // success
45296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
453092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
45496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // At this point the UI would display connection error, which is fine.  Now, the real
45596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // test is, can we recover?  So I'll just repeat the above steps, without the failure.
45696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // NOTE: everything from here down is copied from testOneUnread() and should be consolidated
457092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
45896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // confirm that we're closed at this point
4592720a818d5de169734434b114adfdf824a485f55Marc Blank        assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
460092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
461092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // and confirm that the next connection will be OK
462092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        checkOneUnread(mockTransport);
463092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    }
464092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
465092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    /**
466092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * Test the scenario where the transport is "open" but not really (e.g. server closed).  Two
467092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * things should happen:  We should see an intermediate failure that makes sense, and the next
468092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * operation should reopen properly.
469a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
470092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * There are multiple versions of this test because we are simulating the steps of
471092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * MessagingController.synchronizeMailboxSyncronous() and we will inject the failure a bit
472092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * further along in each case, to test various recovery points.
473a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
474092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * This test confirms that Pop3Store needs to call close() in the IOExceptionHandler in
475092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * Pop3Folder.getMessages(), due to non-numeric data in a single-line UIDL.
476092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     */
477092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    public void testCatchClosed1c() throws MessagingException {
478092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
479092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        MockTransport mockTransport = openAndInjectMockTransport();
480092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
481092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // openFolderWithMessage(mockTransport);
482092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        setupOpenFolder(mockTransport, 6000, null);
483244d306ebb0addbc5d87008af9412b76c80e861eMarc Blank        mFolder.open(OpenMode.READ_ONLY);
484092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        assertEquals(6000, mFolder.getMessageCount());
485092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
486092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // index the message(s) - it should fail, because our stream is broken
487092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        try {
488092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            // setupUidlSequence(mockTransport, 1);
489092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            mockTransport.expect("UIDL 1", "+OK " + "bad-data" + " " + "THE-UIDL");
490092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
491092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            Message[] messages = mFolder.getMessages(1, 1, null);
492092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            fail("Bad UIDL should cause getMessages() to throw.");
493092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        } catch(MessagingException me) {
494092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            // success
495092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        }
496092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
497092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // At this point the UI would display connection error, which is fine.  Now, the real
498092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // test is, can we recover?  So I'll just repeat the above steps, without the failure.
499092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // NOTE: everything from here down is copied from testOneUnread() and should be consolidated
500092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
501092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // confirm that we're closed at this point
5022720a818d5de169734434b114adfdf824a485f55Marc Blank        assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
503092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
50496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // and confirm that the next connection will be OK
50596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        checkOneUnread(mockTransport);
50696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
50796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
50896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
50996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test the scenario where the transport is "open" but not really (e.g. server closed).  Two
51096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * things should happen:  We should see an intermediate failure that makes sense, and the next
51196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * operation should reopen properly.
512a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
513a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     * There are multiple versions of this test because we are simulating the steps of
51496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * MessagingController.synchronizeMailboxSyncronous() and we will inject the failure a bit
51596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * further along in each case, to test various recovery points.
516a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
517a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     * This test confirms that Pop3Store needs to call close() in the first IOExceptionHandler in
51896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Pop3Folder.fetch(), for a failure in the call to indexUids().
51996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
52096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void testCatchClosed2() throws MessagingException {
521a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
52296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        MockTransport mockTransport = openAndInjectMockTransport();
523a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
52496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        openFolderWithMessage(mockTransport);
525a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
52696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // index the message(s)
52796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupUidlSequence(mockTransport, 1);
52896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Message[] messages = mFolder.getMessages(1, 1, null);
52996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(1, messages.length);
530a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        assertEquals(getSingleMessageUID(1), messages[0].getUid());
531a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
53296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // cause the next sequence to fail on the readLine() calls
53396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mockTransport.closeInputStream();
534a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
53596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        try {
53696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            // try the basic fetch of flags & envelope
53796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            setupListSequence(mockTransport, 1);
53896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            FetchProfile fp = new FetchProfile();
53996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            fp.add(FetchProfile.Item.FLAGS);
54096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            fp.add(FetchProfile.Item.ENVELOPE);
54196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            mFolder.fetch(messages, fp, null);
54296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            assertEquals(PER_MESSAGE_SIZE, messages[0].getSize());
54396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            fail("Broken stream should cause fetch() to throw.");
54496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
54596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        catch(MessagingException me) {
54696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            // success
54796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
54896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
54996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // At this point the UI would display connection error, which is fine.  Now, the real
55096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // test is, can we recover?  So I'll just repeat the above steps, without the failure.
55196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // NOTE: everything from here down is copied from testOneUnread() and should be consolidated
552a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
55396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // confirm that we're closed at this point
5542720a818d5de169734434b114adfdf824a485f55Marc Blank        assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
555a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
55696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // and confirm that the next connection will be OK
55796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        checkOneUnread(mockTransport);
55896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
559a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
56096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
56196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test the scenario where the transport is "open" but not really (e.g. server closed).  Two
56296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * things should happen:  We should see an intermediate failure that makes sense, and the next
56396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * operation should reopen properly.
564a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
56596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * There are multiple versions of this test because we have to check additional places where
56696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Pop3Store and/or Pop3Folder should be dealing with IOErrors.
567a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
568a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     * This test confirms that Pop3Store needs to call close() in the first IOExceptionHandler in
56996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Pop3Folder.fetch(), for a failure in the call to fetchEnvelope().
57096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
571092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    public void testCatchClosed2a() throws MessagingException {
572a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
573092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        MockTransport mockTransport = openAndInjectMockTransport();
574a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
575092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        openFolderWithMessage(mockTransport);
576a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
577092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // index the message(s)
578092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        setupUidlSequence(mockTransport, 1);
579092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        Message[] messages = mFolder.getMessages(1, 1, null);
580092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        assertEquals(1, messages.length);
581a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        assertEquals(getSingleMessageUID(1), messages[0].getUid());
582092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
583092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // try the basic fetch of flags & envelope, but the LIST command fails
584092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        setupBrokenListSequence(mockTransport, 1);
585092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        try {
586092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            FetchProfile fp = new FetchProfile();
587092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            fp.add(FetchProfile.Item.FLAGS);
588092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            fp.add(FetchProfile.Item.ENVELOPE);
589092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            mFolder.fetch(messages, fp, null);
590092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            assertEquals(PER_MESSAGE_SIZE, messages[0].getSize());
591092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            fail("Broken stream should cause fetch() to throw.");
592092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        } catch(MessagingException me) {
593092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            // success
594092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        }
595092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
596092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // At this point the UI would display connection error, which is fine.  Now, the real
597092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // test is, can we recover?  So I'll just repeat the above steps, without the failure.
598092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // NOTE: everything from here down is copied from testOneUnread() and should be consolidated
599a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
600092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // confirm that we're closed at this point
6012720a818d5de169734434b114adfdf824a485f55Marc Blank        assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
602a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
603092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // and confirm that the next connection will be OK
604092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        checkOneUnread(mockTransport);
60596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
606a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
60796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
60896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test the scenario where the transport is "open" but not really (e.g. server closed).  Two
60996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * things should happen:  We should see an intermediate failure that makes sense, and the next
61096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * operation should reopen properly.
611a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
612a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     * There are multiple versions of this test because we are simulating the steps of
61396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * MessagingController.synchronizeMailboxSyncronous() and we will inject the failure a bit
61496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * further along in each case, to test various recovery points.
615a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
616a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     * This test confirms that Pop3Store needs to call close() in the second IOExceptionHandler in
61796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Pop3Folder.fetch().
61896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
61996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void testCatchClosed3() throws MessagingException {
620a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
62196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        MockTransport mockTransport = openAndInjectMockTransport();
622a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
62396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        openFolderWithMessage(mockTransport);
624a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
62596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // index the message(s)
62696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupUidlSequence(mockTransport, 1);
62796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Message[] messages = mFolder.getMessages(1, 1, null);
62896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(1, messages.length);
629a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        assertEquals(getSingleMessageUID(1), messages[0].getUid());
63096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
63196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // try the basic fetch of flags & envelope
63296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupListSequence(mockTransport, 1);
63396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        FetchProfile fp = new FetchProfile();
63496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        fp.add(FetchProfile.Item.FLAGS);
63596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        fp.add(FetchProfile.Item.ENVELOPE);
63696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mFolder.fetch(messages, fp, null);
63796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(PER_MESSAGE_SIZE, messages[0].getSize());
63896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
63996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // cause the next sequence to fail on the readLine() calls
64096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mockTransport.closeInputStream();
64196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
64296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        try {
64396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            // now try fetching the message
64496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            setupSingleMessage(mockTransport, 1, false);
64596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            fp = new FetchProfile();
64696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            fp.add(FetchProfile.Item.BODY);
64796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            mFolder.fetch(messages, fp, null);
64896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            checkFetchedMessage(messages[0], 1, false);
64996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            fail("Broken stream should cause fetch() to throw.");
65096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
65196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        catch(MessagingException me) {
65296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            // success
65396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
65496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
65596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // At this point the UI would display connection error, which is fine.  Now, the real
65696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // test is, can we recover?  So I'll just repeat the above steps, without the failure.
65796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // NOTE: everything from here down is copied from testOneUnread() and should be consolidated
658a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
65996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // confirm that we're closed at this point
6602720a818d5de169734434b114adfdf824a485f55Marc Blank        assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
661a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
66296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // and confirm that the next connection will be OK
66396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        checkOneUnread(mockTransport);
66496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
665a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
66696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
66796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test the scenario where the transport is "open" but not really (e.g. server closed).  Two
66896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * things should happen:  We should see an intermediate failure that makes sense, and the next
66996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * operation should reopen properly.
670a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
67196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * There are multiple versions of this test because we have to check additional places where
67296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Pop3Store and/or Pop3Folder should be dealing with IOErrors.
673a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
674a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     * This test confirms that Pop3Store needs to call close() in the IOExceptionHandler in
67596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Pop3Folder.setFlags().
67696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
67796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void testCatchClosed4() throws MessagingException {
678a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
67996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        MockTransport mockTransport = openAndInjectMockTransport();
680a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
68196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        openFolderWithMessage(mockTransport);
682a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
68396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // index the message(s)
68496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupUidlSequence(mockTransport, 1);
68596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Message[] messages = mFolder.getMessages(1, 1, null);
68696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(1, messages.length);
68796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(getSingleMessageUID(1), messages[0].getUid());
688a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
68996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // cause the next sequence to fail on the readLine() calls
69096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mockTransport.closeInputStream();
69196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
69296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // delete 'em all - should fail because of broken stream
69396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        try {
69496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            mockTransport.expect("DELE 1", "+OK message deleted");
69596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            mFolder.setFlags(messages, new Flag[] { Flag.DELETED }, true);
69696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            fail("Broken stream should cause fetch() to throw.");
69796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
69896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        catch(MessagingException me) {
69996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            // success
70096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
70196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
70296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // At this point the UI would display connection error, which is fine.  Now, the real
70396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // test is, can we recover?  So I'll just repeat the above steps, without the failure.
70496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // NOTE: everything from here down is copied from testOneUnread() and should be consolidated
705a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
70696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // confirm that we're closed at this point
7072720a818d5de169734434b114adfdf824a485f55Marc Blank        assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
708a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
70996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // and confirm that the next connection will be OK
71096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        checkOneUnread(mockTransport);
71196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
712a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
71396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
71496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test the scenario where the transport is "open" but not really (e.g. server closed).  Two
71596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * things should happen:  We should see an intermediate failure that makes sense, and the next
71696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * operation should reopen properly.
717a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
71896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * There are multiple versions of this test because we have to check additional places where
71996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Pop3Store and/or Pop3Folder should be dealing with IOErrors.
720a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
721a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     * This test confirms that Pop3Store needs to call close() in the first IOExceptionHandler in
72296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Pop3Folder.open().
72396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
72496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    public void testCatchClosed5() {
72596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // TODO cannot write this test until we can inject stream closures mid-sequence
72696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
727a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
72896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
72996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Test the scenario where the transport is "open" but not really (e.g. server closed).  Two
73096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * things should happen:  We should see an intermediate failure that makes sense, and the next
73196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * operation should reopen properly.
732a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
73396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * There are multiple versions of this test because we have to check additional places where
73496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Pop3Store and/or Pop3Folder should be dealing with IOErrors.
735a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
736a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     * This test confirms that Pop3Store needs to call close() in the second IOExceptionHandler in
737092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * Pop3Folder.open() (when it calls STAT and the response is empty of garbagey).
73896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
739092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    public void testCatchClosed6a() throws MessagingException {
740a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
741092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        MockTransport mockTransport = openAndInjectMockTransport();
742a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
743092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // like openFolderWithMessage(mockTransport) but with a broken STAT report (empty response)
744092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        setupOpenFolder(mockTransport, -1, null);
745092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        try {
746244d306ebb0addbc5d87008af9412b76c80e861eMarc Blank            mFolder.open(OpenMode.READ_ONLY);
747092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            fail("Broken STAT should cause open() to throw.");
748092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        } catch(MessagingException me) {
749092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            // success
750092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        }
751a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
752092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // At this point the UI would display connection error, which is fine.  Now, the real
753092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // test is, can we recover?  So I'll try a new connection, without the failure.
754a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
755092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // confirm that we're closed at this point
7562720a818d5de169734434b114adfdf824a485f55Marc Blank        assertFalse("folder should be 'closed' after an IOError", mFolder.isOpen());
757a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
758092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        // and confirm that the next connection will be OK
759092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        checkOneUnread(mockTransport);
760092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    }
761a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
762092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    /**
763092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * Test the scenario where the transport is "open" but not really (e.g. server closed).  Two
764092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * things should happen:  We should see an intermediate failure that makes sense, and the next
765092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * operation should reopen properly.
766a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
767092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * There are multiple versions of this test because we have to check additional places where
768092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * Pop3Store and/or Pop3Folder should be dealing with IOErrors.
769a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
770a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     * This test confirms that Pop3Store needs to call close() in the second IOExceptionHandler in
771092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * Pop3Folder.open() (when it calls STAT, and there is no response at all).
772092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     */
773a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy    public void testCatchClosed6b() {
77496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // TODO cannot write this test until we can inject stream closures mid-sequence
77596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
776a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
77796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
778a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     * Given an initialized mock transport, open it and attempt to "read" one unread message from
77996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * it.  This can be used as a basic test of functionality and it should be possible to call this
78096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * repeatedly (if you close the folder between calls).
781a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
78296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param mockTransport the mock transport we're using
78396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
78496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private void checkOneUnread(MockTransport mockTransport) throws MessagingException {
78596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        openFolderWithMessage(mockTransport);
786a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
78796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // index the message(s)
78896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupUidlSequence(mockTransport, 1);
78996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Message[] messages = mFolder.getMessages(1, 1, null);
79096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(1, messages.length);
79196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(getSingleMessageUID(1), messages[0].getUid());
792a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
79396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // try the basic fetch of flags & envelope
79496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupListSequence(mockTransport, 1);
79596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        FetchProfile fp = new FetchProfile();
79696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        fp.add(FetchProfile.Item.FLAGS);
79796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        fp.add(FetchProfile.Item.ENVELOPE);
79896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mFolder.fetch(messages, fp, null);
79996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(PER_MESSAGE_SIZE, messages[0].getSize());
800a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
801a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        // A side effect of how messages work is that if you get fields that are empty,
8023469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        // then empty arrays are written back into the parsed header fields (e.g. mTo, mFrom).  The
8033469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        // standard message parser needs to clear these before parsing.  Make sure that this
8043469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        // is happening.  (This doesn't affect IMAP, which reads the headers directly via
8053469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        // IMAP evelopes.)
8063469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        MimeMessage message = (MimeMessage) messages[0];
8073469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        message.getRecipients(RecipientType.TO);
8083469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        message.getRecipients(RecipientType.CC);
8093469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        message.getRecipients(RecipientType.BCC);
81096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
81196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // now try fetching the message
81296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupSingleMessage(mockTransport, 1, false);
81396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        fp = new FetchProfile();
81496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        fp.add(FetchProfile.Item.BODY);
81596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mFolder.fetch(messages, fp, null);
81696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        checkFetchedMessage(messages[0], 1, false);
81796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
818645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler
819645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler    /**
820645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     * A group of tests to confirm that we're properly juggling the RETR and TOP commands.
821645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     * Some servers (hello, live.com) support TOP but don't support CAPA.  So we ignore CAPA
822645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     * and just try TOP.
823645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     */
824645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler    public void testRetrVariants() throws MessagingException {
825645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        MockTransport mockTransport = openAndInjectMockTransport();
826645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        openFolderWithMessage(mockTransport);
827645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler
828645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        // index the message(s)
829645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        setupUidlSequence(mockTransport, 2);
830645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        Message[] messages = mFolder.getMessages(1, 2, null);
831645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        assertEquals(2, messages.length);
832645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler
833645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        // basic fetch of flags & envelope
834645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        setupListSequence(mockTransport, 2);
835645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        FetchProfile fp = new FetchProfile();
836645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        fp.add(FetchProfile.Item.FLAGS);
837645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        fp.add(FetchProfile.Item.ENVELOPE);
838645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        mFolder.fetch(messages, fp, null);
839645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler
840a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        // A side effect of how messages work is that if you get fields that are empty,
841645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        // then empty arrays are written back into the parsed header fields (e.g. mTo, mFrom).  The
842645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        // standard message parser needs to clear these before parsing.  Make sure that this
843645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        // is happening.  (This doesn't affect IMAP, which reads the headers directly via
844645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        // IMAP envelopes.)
845645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        for (Message message : messages) {
846645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler            message.getRecipients(RecipientType.TO);
847645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler            message.getRecipients(RecipientType.CC);
848645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler            message.getRecipients(RecipientType.BCC);
849645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        }
850645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler
851645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        // In the cases below, we fetch BODY_SANE which tries to load the first chunk of the
852645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        // message (not the entire thing) in order to quickly access the headers.
853645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        // In the first test, TOP succeeds
854645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        Message[] singleMessage = new Message[] { messages[0] };
855645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        setupSingleMessageTop(mockTransport, 1, true, true);        // try TOP & succeed
856645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        fp = new FetchProfile();
857645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        fp.add(FetchProfile.Item.BODY_SANE);
858645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        mFolder.fetch(singleMessage, fp, null);
859645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        checkFetchedMessage(singleMessage[0], 1, false);
860645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler
861645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        // In the 2nd test, TOP fails, so we should fall back to RETR
862645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        singleMessage[0] = messages[1];
863645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        setupSingleMessageTop(mockTransport, 2, true, false);        // try TOP & fail
864645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        fp = new FetchProfile();
865645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        fp.add(FetchProfile.Item.BODY_SANE);
866645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        mFolder.fetch(singleMessage, fp, null);
867645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        checkFetchedMessage(singleMessage[0], 2, false);
868645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler    }
869645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler
87096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
87196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Set up a basic MockTransport. open it, and inject it into mStore
87296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
87396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private MockTransport openAndInjectMockTransport() {
87496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // Create mock transport and inject it into the POP3Store that's already set up
87596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        MockTransport mockTransport = new MockTransport();
876e4a7cc440f081ef9c4375a2bd2f82680cc11b152Andrew Stadler        mockTransport.setSecurity(Transport.CONNECTION_SECURITY_NONE, false);
87796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mStore.setTransport(mockTransport);
87896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return mockTransport;
87996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
880a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
88196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
88296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Open a folder that's preloaded with one unread message.
883a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
88496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param mockTransport the mock transport we're using
88596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
88696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private void openFolderWithMessage(MockTransport mockTransport) throws MessagingException {
88796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // try to open it
88896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        setupOpenFolder(mockTransport, 1, null);
889244d306ebb0addbc5d87008af9412b76c80e861eMarc Blank        mFolder.open(OpenMode.READ_ONLY);
890a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
89196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // check message count
89296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(1, mFolder.getMessageCount());
89396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
894a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
89596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
89696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Look at a fetched message and confirm that it is complete.
897a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
89896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * TODO this needs to be more dynamic, not just hardcoded for empty message #1.
899a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
90096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param message the fetched message to be checked
90196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param msgNum the message number
90296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
903a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy    private void checkFetchedMessage(Message message, int msgNum, boolean body)
90496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            throws MessagingException {
90596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // check To:
90696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Address[] to = message.getRecipients(RecipientType.TO);
90796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertNotNull(to);
90896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(1, to.length);
90996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals("Smith@Registry.Org", to[0].getAddress());
91096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertNull(to[0].getPersonal());
911a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
91296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // check From:
91396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        Address[] from = message.getFrom();
91496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertNotNull(from);
91596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals(1, from.length);
91696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertEquals("Jones@Registry.Org", from[0].getAddress());
91796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        assertNull(from[0].getPersonal());
918a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
9193469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        // check Cc:
9203469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        Address[] cc = message.getRecipients(RecipientType.CC);
9213469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        assertNotNull(cc);
9223469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        assertEquals(1, cc.length);
9233469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        assertEquals("Chris@Registry.Org", cc[0].getAddress());
9243469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        assertNull(cc[0].getPersonal());
9253469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project
9263469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        // check Reply-To:
9273469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        Address[] replyto = message.getReplyTo();
9283469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        assertNotNull(replyto);
9293469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        assertEquals(1, replyto.length);
9303469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        assertEquals("Roger@Registry.Org", replyto[0].getAddress());
9313469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        assertNull(replyto[0].getPersonal());
93296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
93396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // TODO date
934a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy
93596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        // TODO check body (if applicable)
93696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
937092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
93896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
93996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Helper which stuffs the mock with enough strings to satisfy a call to Pop3Folder.open()
940a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
94196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param mockTransport the mock transport we're using
942092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * @param statCount the number of messages to indicate in the STAT, or -1 for broken STAT
94396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param capabilities if non-null, comma-separated list of capabilities
94496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
94596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private void setupOpenFolder(MockTransport mockTransport, int statCount, String capabilities) {
94696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mockTransport.expect(null, "+OK Hello there from the Mock Transport.");
94796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        if (capabilities == null) {
94896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            mockTransport.expect("CAPA", "-ERR unimplemented");
94996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        } else {
95096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            mockTransport.expect("CAPA", "+OK capabilities follow");
95196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            mockTransport.expect(null, capabilities.split(","));        // one capability per line
95296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            mockTransport.expect(null, ".");                            // terminated by "."
95396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
95496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mockTransport.expect("USER user", "+OK User name accepted");
95596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        mockTransport.expect("PASS password", "+OK Logged in");
956092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        if (statCount == -1) {
957092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            mockTransport.expect("STAT", "");
958092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        } else {
959092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            String stat = "+OK " + Integer.toString(statCount) + " "
960092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler                    + Integer.toString(PER_MESSAGE_SIZE * statCount);
961092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            mockTransport.expect("STAT", stat);
962092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        }
96396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
964092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
96596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
96696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Setup expects for a UIDL on a mailbox with 0 or more messages in it.
96796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param transport The mock transport to preload
96896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param numMessages The number of messages to return from UIDL.
96996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
97096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private static void setupUidlSequence(MockTransport transport, int numMessages) {
971a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        transport.expect("UIDL", "+OK sending UIDL list");
97296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        for (int msgNum = 1; msgNum <= numMessages; ++msgNum) {
97396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project            transport.expect(null, Integer.toString(msgNum) + " " + getSingleMessageUID(msgNum));
97496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
97596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        transport.expect(null, ".");
97696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
977092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
97896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
97996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Setup expects for a LIST on a mailbox with 0 or more messages in it.
98096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param transport The mock transport to preload
98196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param numMessages The number of messages to return from LIST.
98296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
98396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private static void setupListSequence(MockTransport transport, int numMessages) {
984a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy        transport.expect("LIST", "+OK sending scan listing");
98596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        for (int msgNum = 1; msgNum <= numMessages; ++msgNum) {
986a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy            transport.expect(null, Integer.toString(msgNum) + " " +
98796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project                    Integer.toString(PER_MESSAGE_SIZE * msgNum));
98896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        }
98996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        transport.expect(null, ".");
99096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
991092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
992092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    /**
993092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * Setup expects for a LIST on a mailbox with 0 or more messages in it, except that
994092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * this time the pipe fails, and we return empty lines.
995092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * @param transport The mock transport to preload
996092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     * @param numMessages The number of messages to return from LIST.
997092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler     */
998092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    private static void setupBrokenListSequence(MockTransport transport, int numMessages) {
999092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        transport.expect("LIST", "");
1000092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        for (int msgNum = 1; msgNum <= numMessages; ++msgNum) {
1001092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler            transport.expect(null, "");
1002092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        }
1003092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler        transport.expect(null, "");
1004092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler    }
1005092d35c98d00c5a8b1ba93f51f8e59220f1488cbAndrew Stadler
100696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
100796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Setup a single message to be retrieved.
1008a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
100996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Per RFC822 here is a minimal message header:
101096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *     Date:     26 Aug 76 1429 EDT
101196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *     From:     Jones@Registry.Org
101296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     *     To:       Smith@Registry.Org
1013a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
10143469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project     * We'll add the following fields to support additional tests:
10153469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project     *     Cc:       Chris@Registry.Org
10163469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project     *     Reply-To: Roger@Registry.Org
1017a50fc99b0c433f0cde31ba1c7ab87fb9ea86345dTodd Kennedy     *
101896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param transport the mock transport to preload
101996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param msgNum the message number to expect and return
102096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param body if true, a non-empty body will be added
102196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
102296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private static void setupSingleMessage(MockTransport transport, int msgNum, boolean body) {
1023645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        setupSingleMessageTop(transport, msgNum, false, false);
1024645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler    }
1025645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler
1026645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler    /**
1027645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     * Setup a single message to be retrieved (headers only).
1028645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     * This is very similar to setupSingleMessage() but is intended to test the BODY_SANE
1029645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     * fetch mode.
1030645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     * @param transport the mock transport
1031645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     * @param msgNum the message number to expect and return
1032645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     * @param topTry if true, the "client" is going to attempt the TOP command
1033645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     * @param topSupported if true, the "server" supports the TOP command
1034645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler     */
1035645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler    private static void setupSingleMessageTop(MockTransport transport, int msgNum,
1036645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler            boolean topTry, boolean topSupported) {
1037645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        String msgNumString = Integer.toString(msgNum);
1038645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        String topCommand = "TOP " + msgNumString + " 673";
1039645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        String retrCommand = "RETR " + msgNumString;
1040645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler
1041645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        if (topTry) {
1042645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler            if (topSupported) {
1043645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler                transport.expect(topCommand, "+OK message follows");
1044645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler            } else {
1045645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler                transport.expect(topCommand, "-ERR unsupported command");
1046645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler                transport.expect(retrCommand, "+OK message follows");
1047645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler            }
1048645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        } else {
1049645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler            transport.expect(retrCommand, "+OK message follows");
1050645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler        }
1051645fc2830118e19e604f24ba7ffe71c775631f64Andrew Stadler
105296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        transport.expect(null, "Date: 26 Aug 76 1429 EDT");
105396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        transport.expect(null, "From: Jones@Registry.Org");
105496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        transport.expect(null, "To:   Smith@Registry.Org");
10553469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        transport.expect(null, "CC:   Chris@Registry.Org");
10563469902379242c723b871d1dcb09b02d0998d538The Android Open Source Project        transport.expect(null, "Reply-To: Roger@Registry.Org");
105796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        transport.expect(null, "");
105896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        transport.expect(null, ".");
105996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
106096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project
106196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    /**
106296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * Generates a simple unique code for each message.  Repeatable.
106396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @param msgNum The message number
106496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     * @return a string that can be used as the UID
106596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project     */
106696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    private static String getSingleMessageUID(int msgNum) {
106796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        final String UID_HEAD = "ABCDEF-";
106896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        final String UID_TAIL = "";
106996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project        return UID_HEAD + Integer.toString(msgNum) + UID_TAIL;
107096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project    }
107196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project}
1072