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.transport; 1896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 19cb1d65c47825dc7a45c7954cd93669296b35305eBen Komaloimport android.content.Context; 20cb1d65c47825dc7a45c7954cd93669296b35305eBen Komaloimport android.test.AndroidTestCase; 21cb1d65c47825dc7a45c7954cd93669296b35305eBen Komaloimport android.test.suitebuilder.annotation.SmallTest; 22cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo 23c849936a36424645af73dc307b19778a89d6ee84Makoto Onukiimport com.android.email.DBTestHelper; 2496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport com.android.email.mail.Transport; 25c849936a36424645af73dc307b19778a89d6ee84Makoto Onukiimport com.android.email.provider.EmailProvider; 262193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.Address; 272193962ca2b3157e79f731736afa2a0c972e778aMarc Blankimport com.android.emailcommon.mail.MessagingException; 28f5418f1f93b02e7fab9f15eb201800b65510998eMarc Blankimport com.android.emailcommon.provider.Account; 29a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent.Attachment; 30a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent.Body; 31a7bc0319a75184ad706bb35c049af107ac3688e6Marc Blankimport com.android.emailcommon.provider.EmailContent.Message; 3212b82d9374947c9268217f45befe8a74bd9b60d7Ben Komaloimport com.android.emailcommon.provider.HostAuth; 3396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 34c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport java.io.IOException; 35f4dac9f266906a84f4710d8af5d4a24f2290b1baMakoto Onukiimport java.net.InetAddress; 36f4dac9f266906a84f4710d8af5d4a24f2290b1baMakoto Onukiimport java.net.UnknownHostException; 3796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 3896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/** 3996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * This is a series of unit tests for the SMTP Sender class. These tests must be locally 4096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * complete - no server(s) required. 41c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * 42c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * These tests can be run with the following command: 43c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * runtest -c com.android.email.mail.transport.SmtpSenderUnitTests email 4496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 4596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project@SmallTest 46c849936a36424645af73dc307b19778a89d6ee84Makoto Onukipublic class SmtpSenderUnitTests extends AndroidTestCase { 47c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 48c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler EmailProvider mProvider; 49c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Context mProviderContext; 50c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Context mContext; 51f4dac9f266906a84f4710d8af5d4a24f2290b1baMakoto Onuki private static final String LOCAL_ADDRESS = "1.2.3.4"; 5296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 5396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /* These values are provided by setUp() */ 5496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private SmtpSender mSender = null; 55c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 56c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /* Simple test string and its base64 equivalent */ 57c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler private final static String TEST_STRING = "Hello, world"; 58c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler private final static String TEST_STRING_BASE64 = "SGVsbG8sIHdvcmxk"; 59c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 6096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 6196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Setup code. We generate a lightweight SmtpSender for testing. 6296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 6396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project @Override 6496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project protected void setUp() throws Exception { 6596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project super.setUp(); 66c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki mProviderContext = DBTestHelper.ProviderContextSetupHelper.getProviderContext( 67c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki getContext()); 68c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mContext = getContext(); 69c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki 70daf869cf60de75bc91ed3aef6ac0bff1fe371733Todd Kennedy HostAuth testAuth = new HostAuth(); 71daf869cf60de75bc91ed3aef6ac0bff1fe371733Todd Kennedy Account testAccount = new Account(); 72daf869cf60de75bc91ed3aef6ac0bff1fe371733Todd Kennedy 73daf869cf60de75bc91ed3aef6ac0bff1fe371733Todd Kennedy testAuth.setLogin("user", "password"); 74daf869cf60de75bc91ed3aef6ac0bff1fe371733Todd Kennedy testAuth.setConnection("smtp", "server", 999); 75daf869cf60de75bc91ed3aef6ac0bff1fe371733Todd Kennedy testAccount.mHostAuthSend = testAuth; 76daf869cf60de75bc91ed3aef6ac0bff1fe371733Todd Kennedy mSender = (SmtpSender) SmtpSender.newInstance(testAccount, mProviderContext); 7796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 7896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 7996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 8096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Confirms simple non-SSL non-TLS login 8196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 82f4dac9f266906a84f4710d8af5d4a24f2290b1baMakoto Onuki public void testSimpleLogin() throws Exception { 83c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki 8496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project MockTransport mockTransport = openAndInjectMockTransport(); 85c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki 8696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // try to open it 8796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project setupOpen(mockTransport, null); 8896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mSender.open(); 8996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 90c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki 9196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 9296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * TODO: Test with SSL negotiation (faked) 9396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * TODO: Test with SSL required but not supported 9496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * TODO: Test with TLS negotiation (faked) 9596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * TODO: Test with TLS required but not supported 9696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * TODO: Test other capabilities. 9796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * TODO: Test AUTH LOGIN 9896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 99c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki 10096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 10196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Test: Open and send a single message (sunny day) 10296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 103f4dac9f266906a84f4710d8af5d4a24f2290b1baMakoto Onuki public void testSendMessageWithBody() throws Exception { 10496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project MockTransport mockTransport = openAndInjectMockTransport(); 105c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 10696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // Since SmtpSender.sendMessage() does a close then open, we need to preset for the open 10796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expectClose(); 10896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project setupOpen(mockTransport, null); 10996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 110c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Message message = setupSimpleMessage(); 111c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.save(mProviderContext); 112c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 113c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Body body = new Body(); 114c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler body.mMessageKey = message.mId; 115c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler body.mTextContent = TEST_STRING; 116c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler body.save(mProviderContext); 117c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 118c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // prepare for the message traffic we'll see 119c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // TODO The test is a bit fragile, as we are order-dependent (and headers are not) 120c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleMessage(mockTransport); 121c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Type: text/plain; charset=utf-8"); 122c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Transfer-Encoding: base64"); 123c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 124c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(TEST_STRING_BASE64); 125c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("\r\n\\.", "250 2.0.0 kv2f1a00C02Rf8w3Vv mail accepted for delivery"); 126c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 127c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Now trigger the transmission 128c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mSender.sendMessage(message.mId); 129c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 130c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 131c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 132c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Test: Open and send a single message with an empty attachment (no file) (sunny day) 133c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 134c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler public void testSendMessageWithEmptyAttachment() throws MessagingException, IOException { 135c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler MockTransport mockTransport = openAndInjectMockTransport(); 136c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 137c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Since SmtpSender.sendMessage() does a close then open, we need to preset for the open 138c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expectClose(); 139c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler setupOpen(mockTransport, null); 140c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 141c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Message message = setupSimpleMessage(); 142c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.save(mProviderContext); 143c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 144c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Creates an attachment with a bogus file (so we get headers only) 145cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo Attachment attachment = setupSimpleAttachment(mProviderContext, message.mId); 146c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.save(mProviderContext); 147c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 148c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleMessage(mockTransport); 149c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Type: multipart/mixed; boundary=\".*"); 150c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 151c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*"); 152c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleAttachment(mockTransport, attachment); 153c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 154c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*--"); 155c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("\r\n\\.", "250 2.0.0 kv2f1a00C02Rf8w3Vv mail accepted for delivery"); 156c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 157c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Now trigger the transmission 158c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mSender.sendMessage(message.mId); 159c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 160c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 161c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 162c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Prepare to send a simple message (see setReceiveSimpleMessage) 163c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 164c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler private Message setupSimpleMessage() { 165c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Message message = new Message(); 166c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.mTimeStamp = System.currentTimeMillis(); 167c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.mFrom = Address.parseAndPack("Jones@Registry.Org"); 168c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.mTo = Address.parseAndPack("Smith@Registry.Org"); 169c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.mMessageId = "1234567890"; 170c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler return message; 171c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 172c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 173c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 174c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Prepare to receive a simple message (see setupSimpleMessage) 175c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 176c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler private void expectSimpleMessage(MockTransport mockTransport) { 177c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki mockTransport.expect("MAIL FROM: <Jones@Registry.Org>", 17896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project "250 2.1.0 <Jones@Registry.Org> sender ok"); 17996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect("RCPT TO: <Smith@Registry.Org>", 18096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project "250 2.1.5 <Smith@Registry.Org> recipient ok"); 18196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect("DATA", "354 enter mail, end with . on a line by itself"); 182c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Date: .*"); 183c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Message-ID: .*"); 184c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("From: Jones@Registry.Org"); 185c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("To: Smith@Registry.Org"); 1866bcccf628413d40696980d0d86c7ab2b4f831952Andrew Stadler mockTransport.expect("MIME-Version: 1.0"); 187c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 18896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 189c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 190c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Prepare to send a simple attachment 191c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 192cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo private Attachment setupSimpleAttachment(Context context, long messageId) { 193c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Attachment attachment = new Attachment(); 194c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mFileName = "the file.jpg"; 195c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mMimeType = "image/jpg"; 196c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mSize = 0; 197c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mContentId = null; 198c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mContentUri = "content://com.android.email/1/1"; 199c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mMessageKey = messageId; 200c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mLocation = null; 201c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mEncoding = null; 202c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 203c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler return attachment; 20496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 205c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 206c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 207c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Prepare to receive a simple attachment (note, no multipart support here) 208c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 209c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler private void expectSimpleAttachment(MockTransport mockTransport, Attachment attachment) { 210c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Type: " + attachment.mMimeType + ";"); 211c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(" name=\"" + attachment.mFileName + "\""); 212c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Transfer-Encoding: base64"); 213c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Disposition: attachment;"); 214c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(" filename=\"" + attachment.mFileName + "\";"); 215c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(" size=" + Long.toString(attachment.mSize)); 216c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 217c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler if (attachment.mContentUri != null && attachment.mContentUri.startsWith("file://")) { 218c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(TEST_STRING_BASE64); 219c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 220c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 221c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 22296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 223b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler * Test: Recover from a server closing early (or returning an empty string) 224b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler */ 225f4dac9f266906a84f4710d8af5d4a24f2290b1baMakoto Onuki public void testEmptyLineResponse() throws Exception { 226b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler MockTransport mockTransport = openAndInjectMockTransport(); 227c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki 228b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // Since SmtpSender.sendMessage() does a close then open, we need to preset for the open 229b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler mockTransport.expectClose(); 230c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki 231b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // Load up just the bare minimum to expose the error 232b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler mockTransport.expect(null, "220 MockTransport 2000 Ready To Assist You Peewee"); 233cb1d65c47825dc7a45c7954cd93669296b35305eBen Komalo mockTransport.expectLiterally("EHLO [" + LOCAL_ADDRESS + "]", null); 234c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki 235b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // Now trigger the transmission 236b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // Note, a null message is sufficient here, as we won't even get past open() 237b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler try { 238c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mSender.sendMessage(-1); 239b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler fail("Should not be able to send with failed open()"); 240b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler } catch (MessagingException me) { 241b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // good - expected 242b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // TODO maybe expect a particular exception? 243b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler } 244b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler } 245c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki 246b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler /** 24796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Set up a basic MockTransport. open it, and inject it into mStore 24896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 249f4dac9f266906a84f4710d8af5d4a24f2290b1baMakoto Onuki private MockTransport openAndInjectMockTransport() throws UnknownHostException { 25096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // Create mock transport and inject it into the SmtpSender that's already set up 25196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project MockTransport mockTransport = new MockTransport(); 252e4a7cc440f081ef9c4375a2bd2f82680cc11b152Andrew Stadler mockTransport.setSecurity(Transport.CONNECTION_SECURITY_NONE, false); 25396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mSender.setTransport(mockTransport); 254f4dac9f266906a84f4710d8af5d4a24f2290b1baMakoto Onuki mockTransport.setMockLocalAddress(InetAddress.getByName(LOCAL_ADDRESS)); 25596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return mockTransport; 25696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 257c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki 25896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 25996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Helper which stuffs the mock with enough strings to satisfy a call to SmtpSender.open() 260c849936a36424645af73dc307b19778a89d6ee84Makoto Onuki * 26196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param mockTransport the mock transport we're using 26296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param capabilities if non-null, comma-separated list of capabilities 26396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 26496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private void setupOpen(MockTransport mockTransport, String capabilities) { 26596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "220 MockTransport 2000 Ready To Assist You Peewee"); 26696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect("EHLO .*", "250-10.20.30.40 hello"); 26796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (capabilities == null) { 26896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-HELP"); 26996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-AUTH LOGIN PLAIN CRAM-MD5"); 27096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-SIZE 15728640"); 27196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-ENHANCEDSTATUSCODES"); 27296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-8BITMIME"); 27396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } else { 27496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project for (String capability : capabilities.split(",")) { 27596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-" + capability); 27696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 27796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 27896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250+OK"); 27996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect("AUTH PLAIN .*", "235 2.7.0 ... authentication succeeded"); 28096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 28196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project} 282