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.K9RobolectricTestRunner;
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.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;
@RunWith(K9RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
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();
}
}