package i2p.bote.android.provider; import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.provider.OpenableColumns; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import android.test.ProviderTestCase2; import android.test.suitebuilder.annotation.LargeTest; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.mail.Part; import javax.mail.internet.MimeBodyPart; import i2p.bote.I2PBote; import i2p.bote.android.InitActivities; import i2p.bote.android.R; import i2p.bote.android.util.BoteHelper; import i2p.bote.android.util.ContentAttachment; import i2p.bote.email.Attachment; import i2p.bote.email.Email; import i2p.bote.folder.EmailFolder; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; @RunWith(AndroidJUnit4.class) @LargeTest public class AttachmentProviderTests extends ProviderTestCase2<AttachmentProvider> { private static final String URI_PREFIX = "content://" + AttachmentProvider.AUTHORITY; private static final String INVALID_URI = URI_PREFIX + "/invalid"; private static final String NO_MATCH_URI = URI_PREFIX + "/foo/bar/1/RAW"; public AttachmentProviderTests() { super(AttachmentProvider.class, AttachmentProvider.AUTHORITY); setContext(InstrumentationRegistry.getTargetContext()); } @Before public void setUp() throws Exception { super.setUp(); testAndroidTestCaseSetupProperly(); new InitActivities(getMockContext().getDir("botetest", Context.MODE_PRIVATE).getAbsolutePath()).initialize(); } @Test(expected = IllegalArgumentException.class) public void queryWithInvalidUriThrows() { Uri invalidUri = Uri.parse(INVALID_URI); getMockContentResolver().query(invalidUri, null, null, null, null); } @Test public void getTypeWithInvalidUriReturnsNull() { Uri invalidUri = Uri.parse(INVALID_URI); String type = getMockContentResolver().getType(invalidUri); assertThat("Type was not null", type, is(nullValue())); } @Test(expected = FileNotFoundException.class) public void openFileWithInvalidUriThrows() throws FileNotFoundException { Uri invalidUri = Uri.parse(INVALID_URI); getMockContentResolver().openFileDescriptor(invalidUri, "r"); } @Test public void queryWithNoMatchReturnsNull() { Uri noMatchUri = Uri.parse(NO_MATCH_URI); Cursor c = getMockContentResolver().query(noMatchUri, null, null, null, null); assertThat(c, is(nullValue())); } @Test public void queryWithValidTextUri() throws Exception { ContentAttachment attachment = createTextAttachment(); Uri uri = createEmailWithAttachment(attachment); Cursor c = getMockContentResolver().query(uri, null, null, null, null); assertThat(c.getCount(), is(1)); int nameIndex = c.getColumnIndex(OpenableColumns.DISPLAY_NAME); int sizeIndex = c.getColumnIndex(OpenableColumns.SIZE); c.moveToFirst(); assertThat(c.getString(nameIndex), is(equalTo(attachment.getFileName()))); assertThat(c.getLong(sizeIndex), is(equalTo(attachment.getSize()))); } @Test public void getTypeWithValidTextUri() throws Exception { ContentAttachment attachment = createTextAttachment(); Uri uri = createEmailWithAttachment(attachment); String type = getMockContentResolver().getType(uri); assertThat("Type was not correct", type, is("text/plain")); } @Test public void getTypeWithValidImageUri() throws Exception { ContentAttachment attachment = createImageAttachment(); Uri uri = createEmailWithAttachment(attachment); String type = getMockContentResolver().getType(uri); assertThat("Type was not correct", type, is("image/png")); } @Test public void openFileWithValidTextUri() throws Exception { ContentAttachment attachment = createTextAttachment(); Uri uri = createEmailWithAttachment(attachment); openFileWithValidUri(attachment, uri); } @Test public void openFileWithValidImageUri() throws Exception { ContentAttachment attachment = createImageAttachment(); Uri uri = createEmailWithAttachment(attachment); openFileWithValidUri(attachment, uri); assertThat("Image could not be decoded", BitmapFactory.decodeStream(getMockContentResolver().openInputStream(uri)), is(notNullValue())); } private void openFileWithValidUri(ContentAttachment attachment, Uri uri) throws Exception { InputStream inProv = getMockContentResolver().openInputStream(uri); InputStream inOrig = attachment.getDataHandler().getInputStream(); ByteArrayOutputStream outProv = new ByteArrayOutputStream(); ByteArrayOutputStream outOrig = new ByteArrayOutputStream(); BoteHelper.copyStream(inProv, outProv); BoteHelper.copyStream(inOrig, outOrig); assertThat("Provider content does not match original content", outProv.toByteArray(), is(equalTo(outOrig.toByteArray()))); } private ContentAttachment createTextAttachment() throws Exception { return createAttachment("test.txt", "text/plain", "Test file content".getBytes()); } private ContentAttachment createImageAttachment() throws Exception { Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.intro_1); ByteArrayOutputStream out = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); return createAttachment("intro_1.png", "image/png", out.toByteArray()); } private ContentAttachment createAttachment(final String fileName, final String mimeType, final byte[] content) throws Exception { Part part = new MimeBodyPart(); part.setDataHandler(new DataHandler(new DataSource() { @Override public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(content); } @Override public OutputStream getOutputStream() throws IOException { throw new IOException("Cannot write to attachments"); } @Override public String getContentType() { return mimeType; } @Override public String getName() { return fileName; } })); part.setFileName(fileName); return new ContentAttachment(getMockContext(), part); } private Uri createEmailWithAttachment(Attachment attachment) throws Exception { List<Attachment> attachments = new ArrayList<Attachment>(); attachments.add(attachment); Email email = new Email(false); email.setContent("", attachments); I2PBote.getInstance().getInbox().add(email); return AttachmentProvider.getUriForAttachment( I2PBote.getInstance().getInbox().getName(), email.getMessageID(), 1 ); } @After public void tearDown() throws Exception { super.tearDown(); EmailFolder inbox = I2PBote.getInstance().getInbox(); for (Email email : BoteHelper.getEmails(inbox, null, true)) { inbox.delete(email.getMessageID()); } System.setProperty("i2pbote.initialized", "false"); } }