Merge pull request #1559 from k9mail/deferred-file-body-fix
Fix DeferredFileBody
This commit is contained in:
commit
77f9e82b41
2 changed files with 159 additions and 2 deletions
|
@ -11,6 +11,7 @@ import java.io.InputStream;
|
|||
import java.io.OutputStream;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.util.Log;
|
||||
|
||||
import com.fsck.k9.K9;
|
||||
|
@ -26,11 +27,12 @@ import org.apache.commons.io.IOUtils;
|
|||
* @see FileFactory
|
||||
*/
|
||||
public class DeferredFileBody implements RawDataBody, SizeAware {
|
||||
public static final int MEMORY_BACKED_THRESHOLD = 1024 * 8;
|
||||
public static final int DEFAULT_MEMORY_BACKED_THRESHOLD = 1024 * 8;
|
||||
|
||||
|
||||
private final FileFactory fileFactory;
|
||||
private final String encoding;
|
||||
private final int memoryBackedThreshold;
|
||||
|
||||
@Nullable
|
||||
private byte[] data;
|
||||
|
@ -38,12 +40,19 @@ public class DeferredFileBody implements RawDataBody, SizeAware {
|
|||
|
||||
|
||||
public DeferredFileBody(FileFactory fileFactory, String transferEncoding) {
|
||||
this(DEFAULT_MEMORY_BACKED_THRESHOLD, fileFactory, transferEncoding);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
DeferredFileBody(int memoryBackedThreshold, FileFactory fileFactory,
|
||||
String transferEncoding) {
|
||||
this.fileFactory = fileFactory;
|
||||
this.memoryBackedThreshold = memoryBackedThreshold;
|
||||
this.encoding = transferEncoding;
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
return new DeferredFileOutputStream(MEMORY_BACKED_THRESHOLD, fileFactory) {
|
||||
return new DeferredFileOutputStream(memoryBackedThreshold, fileFactory) {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
|
@ -104,6 +113,7 @@ public class DeferredFileBody implements RawDataBody, SizeAware {
|
|||
|
||||
Log.d(K9.LOG_TAG, "Writing body to file for attachment access");
|
||||
|
||||
file = fileFactory.createFile();
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
fos.write(data);
|
||||
fos.close();
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
package com.fsck.k9.mailstore;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import com.fsck.k9.mailstore.util.FileFactory;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.output.ByteArrayOutputStream;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(manifest = Config.NONE, sdk = 21)
|
||||
public class DeferredFileBodyTest {
|
||||
public static final String TEST_ENCODING = "test-encoding";
|
||||
public static final byte[] TEST_DATA_SHORT = "test data".getBytes();
|
||||
public static final byte[] TEST_DATA_LONG = "test data long enough to be file backed".getBytes();
|
||||
public static final int TEST_THRESHOLD = 15;
|
||||
|
||||
|
||||
private File createdFile;
|
||||
private DeferredFileBody deferredFileBody;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
FileFactory fileFactory = new FileFactory() {
|
||||
@Override
|
||||
public File createFile() throws IOException {
|
||||
assertNull("only a single file should be created", createdFile);
|
||||
createdFile = File.createTempFile("test", "tmp");
|
||||
createdFile.deleteOnExit();
|
||||
return createdFile;
|
||||
}
|
||||
};
|
||||
|
||||
deferredFileBody = new DeferredFileBody(TEST_THRESHOLD, fileFactory, TEST_ENCODING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withShortData__getLength__shouldReturnWrittenLength() throws Exception {
|
||||
writeShortTestData();
|
||||
|
||||
assertNull(createdFile);
|
||||
assertEquals(TEST_DATA_SHORT.length, deferredFileBody.getSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withLongData__getLength__shouldReturnWrittenLength() throws Exception {
|
||||
writeLongTestData();
|
||||
|
||||
assertNotNull(createdFile);
|
||||
assertEquals(TEST_DATA_LONG.length, deferredFileBody.getSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withShortData__shouldReturnData() throws Exception {
|
||||
writeShortTestData();
|
||||
|
||||
InputStream inputStream = deferredFileBody.getInputStream();
|
||||
byte[] data = IOUtils.toByteArray(inputStream);
|
||||
|
||||
assertNull(createdFile);
|
||||
assertArrayEquals(TEST_DATA_SHORT, data);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withLongData__shouldReturnData() throws Exception {
|
||||
writeLongTestData();
|
||||
|
||||
InputStream inputStream = deferredFileBody.getInputStream();
|
||||
byte[] data = IOUtils.toByteArray(inputStream);
|
||||
InputStream fileInputStream = new FileInputStream(createdFile);
|
||||
byte[] dataFromFile = IOUtils.toByteArray(fileInputStream);
|
||||
|
||||
assertArrayEquals(TEST_DATA_LONG, data);
|
||||
assertArrayEquals(TEST_DATA_LONG, dataFromFile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withShortData__getFile__shouldWriteDataToFile() throws Exception {
|
||||
writeShortTestData();
|
||||
|
||||
File returnedFile = deferredFileBody.getFile();
|
||||
InputStream fileInputStream = new FileInputStream(returnedFile);
|
||||
byte[] dataFromFile = IOUtils.toByteArray(fileInputStream);
|
||||
|
||||
assertSame(createdFile, returnedFile);
|
||||
assertArrayEquals(TEST_DATA_SHORT, dataFromFile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withLongData__getFile__shouldReturnCreatedFile() throws Exception {
|
||||
writeLongTestData();
|
||||
|
||||
File returnedFile = deferredFileBody.getFile();
|
||||
|
||||
assertSame(createdFile, returnedFile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withShortData__writeTo__shouldWriteData() throws Exception {
|
||||
writeShortTestData();
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
deferredFileBody.writeTo(baos);
|
||||
|
||||
assertArrayEquals(TEST_DATA_SHORT, baos.toByteArray());
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
public void setEncoding__shouldThrow() throws Exception {
|
||||
deferredFileBody.setEncoding("anything");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEncoding__shouldReturnEncoding() throws Exception {
|
||||
assertEquals(TEST_ENCODING, deferredFileBody.getEncoding());
|
||||
}
|
||||
|
||||
private void writeShortTestData() throws IOException {
|
||||
OutputStream outputStream = deferredFileBody.getOutputStream();
|
||||
outputStream.write(TEST_DATA_SHORT);
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
private void writeLongTestData() throws IOException {
|
||||
OutputStream outputStream = deferredFileBody.getOutputStream();
|
||||
outputStream.write(TEST_DATA_LONG);
|
||||
outputStream.close();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue