SmtpSenderUnitTests.java revision e4a7cc440f081ef9c4375a2bd2f82680cc11b152
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 1996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport com.android.email.mail.Address; 2096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport com.android.email.mail.MessagingException; 2196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport com.android.email.mail.Transport; 22c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport com.android.email.provider.EmailProvider; 23c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport com.android.email.provider.EmailContent.Attachment; 24c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport com.android.email.provider.EmailContent.Body; 25c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport com.android.email.provider.EmailContent.Message; 2696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 27c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport org.apache.commons.io.IOUtils; 28c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 29c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport android.content.Context; 30c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport android.test.ProviderTestCase2; 3196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Projectimport android.test.suitebuilder.annotation.SmallTest; 3296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 33c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport java.io.ByteArrayInputStream; 34c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport java.io.File; 35c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport java.io.FileOutputStream; 36c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport java.io.IOException; 37c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport java.io.InputStream; 38c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerimport java.io.OutputStream; 3996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 4096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project/** 4196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * This is a series of unit tests for the SMTP Sender class. These tests must be locally 4296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * complete - no server(s) required. 43c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * 44c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * These tests can be run with the following command: 45c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * runtest -c com.android.email.mail.transport.SmtpSenderUnitTests email 4696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 4796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project@SmallTest 48c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadlerpublic class SmtpSenderUnitTests extends ProviderTestCase2<EmailProvider> { 49c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 50c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler EmailProvider mProvider; 51c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Context mProviderContext; 52c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Context mContext; 5396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 5496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /* These values are provided by setUp() */ 5596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private SmtpSender mSender = null; 56c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 57c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /* Simple test string and its base64 equivalent */ 58c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler private final static String TEST_STRING = "Hello, world"; 59c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler private final static String TEST_STRING_BASE64 = "SGVsbG8sIHdvcmxk"; 60c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 61c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler public SmtpSenderUnitTests() { 62c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler super(EmailProvider.class, EmailProvider.EMAIL_AUTHORITY); 63c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 64c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 6596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 6696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Setup code. We generate a lightweight SmtpSender for testing. 6796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 6896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project @Override 6996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project protected void setUp() throws Exception { 7096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project super.setUp(); 71c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mProviderContext = getMockContext(); 72c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mContext = getContext(); 7396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 7496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // These are needed so we can get at the inner classes 75c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mSender = (SmtpSender) SmtpSender.newInstance(mProviderContext, 76c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler "smtp://user:password@server:999"); 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 */ 8296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project public void testSimpleLogin() throws MessagingException { 8396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 8496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project MockTransport mockTransport = openAndInjectMockTransport(); 8596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 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 } 9096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 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 */ 9996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 10096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 10196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Test: Open and send a single message (sunny day) 10296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 103c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler public void testSendMessageWithBody() throws MessagingException { 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) 145c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Attachment attachment = setupSimpleAttachment(mProviderContext, message.mId, false); 146c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.save(mProviderContext); 147c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 148c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleMessage(mockTransport); 149c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("MIME-Version: 1.0"); 150c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Type: multipart/mixed; boundary=\".*"); 151c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 152c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*"); 153c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleAttachment(mockTransport, attachment); 154c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 155c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*--"); 156c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("\r\n\\.", "250 2.0.0 kv2f1a00C02Rf8w3Vv mail accepted for delivery"); 157c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 158c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Now trigger the transmission 159c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mSender.sendMessage(message.mId); 160c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 161c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 162c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 163c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Test: Open and send a single message with an attachment (sunny day) 164c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 165c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler public void testSendMessageWithAttachment() throws MessagingException, IOException { 166c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler MockTransport mockTransport = openAndInjectMockTransport(); 167c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 168c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Since SmtpSender.sendMessage() does a close then open, we need to preset for the open 169c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expectClose(); 170c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler setupOpen(mockTransport, null); 171c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 172c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Message message = setupSimpleMessage(); 173c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.save(mProviderContext); 174c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 175c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Creates an attachment with a real file 176c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Attachment attachment = setupSimpleAttachment(mProviderContext, message.mId, true); 177c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.save(mProviderContext); 178c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 179c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleMessage(mockTransport); 180c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("MIME-Version: 1.0"); 181c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Type: multipart/mixed; boundary=\".*"); 182c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 183c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*"); 184c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleAttachment(mockTransport, attachment); 185c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 186c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*--"); 187c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("\r\n\\.", "250 2.0.0 kv2f1a00C02Rf8w3Vv mail accepted for delivery"); 188c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 189c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Now trigger the transmission 190c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mSender.sendMessage(message.mId); 191c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 192c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 193c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 194c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Test: Open and send a single message with two attachments 195c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 196c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler public void testSendMessageWithTwoAttachments() throws MessagingException, IOException { 197c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler MockTransport mockTransport = openAndInjectMockTransport(); 198c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 199c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Since SmtpSender.sendMessage() does a close then open, we need to preset for the open 200c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expectClose(); 201c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler setupOpen(mockTransport, null); 202c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 203c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Message message = setupSimpleMessage(); 204c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.save(mProviderContext); 205c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 206c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Creates an attachment with a real file 207c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Attachment attachment = setupSimpleAttachment(mProviderContext, message.mId, true); 208c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.save(mProviderContext); 209c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 210c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Creates an attachment with a real file 211c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Attachment attachment2 = setupSimpleAttachment(mProviderContext, message.mId, true); 212c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment2.save(mProviderContext); 213c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 214c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleMessage(mockTransport); 215c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("MIME-Version: 1.0"); 216c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Type: multipart/mixed; boundary=\".*"); 217c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 218c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*"); 219c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleAttachment(mockTransport, attachment); 220c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 221c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*"); 222c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleAttachment(mockTransport, attachment2); 223c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 224c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*--"); 225c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("\r\n\\.", "250 2.0.0 kv2f1a00C02Rf8w3Vv mail accepted for delivery"); 226c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 227c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Now trigger the transmission 228c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mSender.sendMessage(message.mId); 229c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 230c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 231c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 232c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Test: Open and send a single message with body & attachment (sunny day) 233c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 234c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler public void testSendMessageWithBodyAndAttachment() throws MessagingException, IOException { 235c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler MockTransport mockTransport = openAndInjectMockTransport(); 236c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 237c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Since SmtpSender.sendMessage() does a close then open, we need to preset for the open 238c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expectClose(); 239c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler setupOpen(mockTransport, null); 240c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 241c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Message message = setupSimpleMessage(); 242c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.save(mProviderContext); 243c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 244c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Body body = new Body(); 245c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler body.mMessageKey = message.mId; 246c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler body.mTextContent = TEST_STRING; 247c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler body.save(mProviderContext); 248c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 249c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Attachment attachment = setupSimpleAttachment(mProviderContext, message.mId, true); 250c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.save(mProviderContext); 251c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 25296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // prepare for the message traffic we'll see 253c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleMessage(mockTransport); 254c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("MIME-Version: 1.0"); 255c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Type: multipart/mixed; boundary=\".*"); 256c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 257c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*"); 258c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Type: text/plain; charset=utf-8"); 259c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Transfer-Encoding: base64"); 260c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 261c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(TEST_STRING_BASE64); 262c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*"); 263c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler expectSimpleAttachment(mockTransport, attachment); 264c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 265c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("----.*--"); 266c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("\r\n\\.", "250 2.0.0 kv2f1a00C02Rf8w3Vv mail accepted for delivery"); 267c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 268c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Now trigger the transmission 269c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mSender.sendMessage(message.mId); 270c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 271c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 272c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 273c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Prepare to send a simple message (see setReceiveSimpleMessage) 274c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 275c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler private Message setupSimpleMessage() { 276c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Message message = new Message(); 277c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.mTimeStamp = System.currentTimeMillis(); 278c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.mFrom = Address.parseAndPack("Jones@Registry.Org"); 279c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.mTo = Address.parseAndPack("Smith@Registry.Org"); 280c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler message.mMessageId = "1234567890"; 281c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler return message; 282c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 283c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 284c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 285c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Prepare to receive a simple message (see setupSimpleMessage) 286c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 287c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler private void expectSimpleMessage(MockTransport mockTransport) { 28896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect("MAIL FROM: <Jones@Registry.Org>", 28996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project "250 2.1.0 <Jones@Registry.Org> sender ok"); 29096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect("RCPT TO: <Smith@Registry.Org>", 29196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project "250 2.1.5 <Smith@Registry.Org> recipient ok"); 29296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect("DATA", "354 enter mail, end with . on a line by itself"); 293c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Date: .*"); 294c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Message-ID: .*"); 295c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("From: Jones@Registry.Org"); 296c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("To: Smith@Registry.Org"); 297c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 29896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 299c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 300c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Prepare to send a simple attachment 301c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 302c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler private Attachment setupSimpleAttachment(Context context, long messageId, boolean withBody) 303c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler throws IOException { 304c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler Attachment attachment = new Attachment(); 305c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mFileName = "the file.jpg"; 306c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mMimeType = "image/jpg"; 307c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mSize = 0; 308c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mContentId = null; 309c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mContentUri = "content://com.android.email/1/1"; 310c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mMessageKey = messageId; 311c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mLocation = null; 312c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mEncoding = null; 313c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 314c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler if (withBody) { 315c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler // Is there an easier way to set up a temp file? 316c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler InputStream inStream = new ByteArrayInputStream(TEST_STRING.getBytes()); 317c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler File cacheDir = context.getCacheDir(); 318c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler File tmpFile = File.createTempFile("setupSimpleAttachment", "tmp", cacheDir); 319c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler OutputStream outStream = new FileOutputStream(tmpFile); 320c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 321c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler IOUtils.copy(inStream, outStream); 322c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler attachment.mContentUri = "file://" + tmpFile.getAbsolutePath(); 323c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 324c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 325c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler return attachment; 32696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 327c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 328c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler /** 329c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler * Prepare to receive a simple attachment (note, no multipart support here) 330c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler */ 331c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler private void expectSimpleAttachment(MockTransport mockTransport, Attachment attachment) { 332c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Type: " + attachment.mMimeType + ";"); 333c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(" name=\"" + attachment.mFileName + "\""); 334c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Transfer-Encoding: base64"); 335c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect("Content-Disposition: attachment;"); 336c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(" filename=\"" + attachment.mFileName + "\";"); 337c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(" size=" + Long.toString(attachment.mSize)); 338c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(""); 339c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler if (attachment.mContentUri != null && attachment.mContentUri.startsWith("file://")) { 340c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mockTransport.expect(TEST_STRING_BASE64); 341c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 342c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler } 343c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler 34496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 345b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler * Test: Recover from a server closing early (or returning an empty string) 346b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler */ 347c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler public void testEmptyLineResponse() { 348b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler MockTransport mockTransport = openAndInjectMockTransport(); 349b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler 350b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // Since SmtpSender.sendMessage() does a close then open, we need to preset for the open 351b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler mockTransport.expectClose(); 352b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler 353b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // Load up just the bare minimum to expose the error 354b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler mockTransport.expect(null, "220 MockTransport 2000 Ready To Assist You Peewee"); 355b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler mockTransport.expect("EHLO .*", ""); 356b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler 357b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // Now trigger the transmission 358b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // Note, a null message is sufficient here, as we won't even get past open() 359b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler try { 360c640cbbaf385566e1b6de361b2b23156e10f695dAndrew Stadler mSender.sendMessage(-1); 361b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler fail("Should not be able to send with failed open()"); 362b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler } catch (MessagingException me) { 363b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // good - expected 364b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler // TODO maybe expect a particular exception? 365b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler } 366b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler } 367b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler 368b011a812e05902d7e417b8c47acc90a592f4b412Andrew Stadler /** 36996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Set up a basic MockTransport. open it, and inject it into mStore 37096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 37196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private MockTransport openAndInjectMockTransport() { 37296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project // Create mock transport and inject it into the SmtpSender that's already set up 37396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project MockTransport mockTransport = new MockTransport(); 374e4a7cc440f081ef9c4375a2bd2f82680cc11b152Andrew Stadler mockTransport.setSecurity(Transport.CONNECTION_SECURITY_NONE, false); 37596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mSender.setTransport(mockTransport); 37696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project return mockTransport; 37796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 37896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project 37996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project /** 38096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * Helper which stuffs the mock with enough strings to satisfy a call to SmtpSender.open() 38196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * 38296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param mockTransport the mock transport we're using 38396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project * @param capabilities if non-null, comma-separated list of capabilities 38496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project */ 38596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project private void setupOpen(MockTransport mockTransport, String capabilities) { 38696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "220 MockTransport 2000 Ready To Assist You Peewee"); 38796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect("EHLO .*", "250-10.20.30.40 hello"); 38896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project if (capabilities == null) { 38996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-HELP"); 39096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-AUTH LOGIN PLAIN CRAM-MD5"); 39196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-SIZE 15728640"); 39296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-ENHANCEDSTATUSCODES"); 39396c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-8BITMIME"); 39496c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } else { 39596c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project for (String capability : capabilities.split(",")) { 39696c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250-" + capability); 39796c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 39896c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 39996c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect(null, "250+OK"); 40096c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project mockTransport.expect("AUTH PLAIN .*", "235 2.7.0 ... authentication succeeded"); 40196c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project } 40296c5af40d639d629267794f4f0338a267ff94ce5The Android Open Source Project} 403