package co.smartreceipts.android.persistence.database.controllers.alterations;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import co.smartreceipts.android.model.Receipt;
import co.smartreceipts.android.model.Trip;
import co.smartreceipts.android.model.factory.BuilderFactory1;
import co.smartreceipts.android.model.factory.ReceiptBuilderFactory;
import co.smartreceipts.android.persistence.database.tables.ReceiptsTable;
import io.reactivex.Single;
import wb.android.storage.StorageManager;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@RunWith(RobolectricTestRunner.class)
public class ReceiptTableActionAlterationsTest {
// Class under test
ReceiptTableActionAlterations mReceiptTableActionAlterations;
File file1;
File file2;
@Mock
ReceiptsTable mReceiptsTable;
@Mock
StorageManager mStorageManager;
@Mock
BuilderFactory1<Receipt, ReceiptBuilderFactory> mReceiptBuilderFactoryFactory;
@Mock
ReceiptBuilderFactory mReceiptBuilderFactory;
@Mock
Receipt mReceipt;
@Mock
Trip mTrip;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
when(mReceipt.getTrip()).thenReturn(mTrip);
when(mReceiptBuilderFactory.build()).thenReturn(mReceipt);
when(mReceiptBuilderFactoryFactory.build(mReceipt)).thenReturn(mReceiptBuilderFactory);
when(mReceiptBuilderFactory.setIndex(anyInt())).thenReturn(mReceiptBuilderFactory);
doAnswer(new Answer() {
@Override
public File answer(InvocationOnMock invocation) throws Throwable {
return new File((String) invocation.getArguments()[1]);
}
}).when(mStorageManager).getFile(any(File.class), anyString());
doAnswer(new Answer() {
@Override
public File answer(InvocationOnMock invocation) throws Throwable {
return new File((String) invocation.getArguments()[1]);
}
}).when(mStorageManager).rename(any(File.class), anyString());
doAnswer(new Answer() {
@Override
public ReceiptBuilderFactory answer(InvocationOnMock invocation) throws Throwable {
when(mReceipt.getFile()).thenReturn((File) invocation.getArguments()[0]);
return mReceiptBuilderFactory;
}
}).when(mReceiptBuilderFactory).setFile(any(File.class));
doAnswer(new Answer() {
@Override
public ReceiptBuilderFactory answer(InvocationOnMock invocation) throws Throwable {
when(mReceipt.getIndex()).thenReturn((Integer) invocation.getArguments()[0]);
return mReceiptBuilderFactory;
}
}).when(mReceiptBuilderFactory).setIndex(anyInt());
mReceiptTableActionAlterations = new ReceiptTableActionAlterations(RuntimeEnvironment.application, mReceiptsTable, mStorageManager, mReceiptBuilderFactoryFactory);
}
@SuppressWarnings("ResultOfMethodCallIgnored")
@After
public void tearDown() throws Exception {
if (file1 != null) {
file1.delete();
}
if (file2 != null) {
file2.delete();
}
}
@Test
public void preInsertWithoutFile() {
final String name = "name";
final List<Receipt> receiptsInTrip = Arrays.asList(mock(Receipt.class), mock(Receipt.class), mock(Receipt.class));
when(mReceiptsTable.get(mTrip)).thenReturn(Single.just(receiptsInTrip));
when(mReceipt.hasFile()).thenReturn(false);
when(mReceipt.getName()).thenReturn(name);
mReceiptTableActionAlterations.preInsert(mReceipt)
.test()
.assertValue(mReceipt)
.assertComplete()
.assertNoErrors();
assertNull(mReceipt.getFile());
verify(mReceiptBuilderFactory).setIndex(4);
}
@Test
public void preInsertWithFile() {
final String name = "name";
final List<Receipt> receiptsInTrip = Arrays.asList(mock(Receipt.class), mock(Receipt.class), mock(Receipt.class));
when(mReceiptsTable.get(mTrip)).thenReturn(Single.just(receiptsInTrip));
when(mReceipt.hasFile()).thenReturn(true);
when(mReceipt.getName()).thenReturn(name);
when(mReceipt.getFile()).thenReturn(new File("12345.jpg"));
mReceiptTableActionAlterations.preInsert(mReceipt)
.test()
.assertValue(mReceipt)
.assertComplete()
.assertNoErrors();
assertEquals(new File("4_name.jpg"), mReceipt.getFile());
verify(mReceiptBuilderFactory).setIndex(4);
}
@Test
public void preInsertWithIllegalCharactersInName() {
final String name = "before_|\\\\?*<\\:>+[]/'\n\r\t\0\f_after";
final List<Receipt> receiptsInTrip = Arrays.asList(mock(Receipt.class), mock(Receipt.class), mock(Receipt.class));
when(mReceiptsTable.get(mTrip)).thenReturn(Single.just(receiptsInTrip));
when(mReceipt.hasFile()).thenReturn(true);
when(mReceipt.getName()).thenReturn(name);
when(mReceipt.getFile()).thenReturn(new File("12345.jpg"));
mReceiptTableActionAlterations.preInsert(mReceipt)
.test()
.assertValue(mReceipt)
.assertComplete()
.assertNoErrors();
assertEquals(new File("4_before__after.jpg"), mReceipt.getFile());
verify(mReceiptBuilderFactory).setIndex(4);
}
@Test
public void preUpdateWithoutFile() {
final Receipt oldReceipt = mock(Receipt.class);
when(mReceipt.getFile()).thenReturn(null);
mReceiptTableActionAlterations.preUpdate(oldReceipt, mReceipt)
.test()
.assertValue(mReceipt)
.assertComplete()
.assertNoErrors();
}
@Test
public void preUpdateWithBrandNewFile() {
final String name = "name";
final Receipt oldReceipt = mock(Receipt.class);
when(oldReceipt.getFile()).thenReturn(null);
when(mReceipt.getIndex()).thenReturn(4);
when(mReceipt.getName()).thenReturn(name);
when(mReceipt.getFile()).thenReturn(new File("12345.jpg"));
final List<Receipt> result = mReceiptTableActionAlterations.preUpdate(oldReceipt, mReceipt)
.test()
.assertComplete()
.assertNoErrors()
.values();
// final List<Receipt> onNextResults = testSubscriber.getOnNextEvents();
// assertNotNull(onNextResults);
assertTrue(result.size() == 1);
final Receipt receipt = result.get(0);
assertEquals(new File("4_name.jpg"), receipt.getFile());
}
@Test
public void preUpdateWithUpdatedFile() throws Exception {
this.file1 = new File("1_name.jpg");
this.file2 = new File("12345.jpg");
assertTrue(this.file1.createNewFile());
assertTrue(this.file2.createNewFile());
final String name = "name";
final Receipt oldReceipt = mock(Receipt.class);
when(oldReceipt.getIndex()).thenReturn(1);
when(oldReceipt.getName()).thenReturn(name);
when(oldReceipt.getFile()).thenReturn(file1);
when(mReceipt.getIndex()).thenReturn(1);
when(mReceipt.getName()).thenReturn(name);
when(mReceipt.getFile()).thenReturn(file2);
final List<Receipt> onNextResults =
mReceiptTableActionAlterations.preUpdate(oldReceipt, mReceipt)
.test()
.assertComplete()
.assertNoErrors()
.values();
assertNotNull(onNextResults);
assertTrue(onNextResults.size() == 1);
final Receipt result = onNextResults.get(0);
assertNotNull(result.getFile());
assertEquals("1_name.jpg", result.getFile().getName());
}
@Test
public void preUpdateWithUpdatedFileAndFileType() throws Exception {
this.file1 = new File("1_name.jpg");
this.file2 = new File("12345.pdf");
assertTrue(this.file1.createNewFile());
assertTrue(this.file2.createNewFile());
final String name = "name";
final Receipt oldReceipt = mock(Receipt.class);
when(oldReceipt.getIndex()).thenReturn(1);
when(oldReceipt.getName()).thenReturn(name);
when(oldReceipt.getFile()).thenReturn(file1);
when(mReceipt.getIndex()).thenReturn(1);
when(mReceipt.getName()).thenReturn(name);
when(mReceipt.getFile()).thenReturn(file2);
final List<Receipt> onNextResults =
mReceiptTableActionAlterations.preUpdate(oldReceipt, mReceipt)
.test()
.assertComplete()
.assertNoErrors()
.values();
assertNotNull(onNextResults);
assertTrue(onNextResults.size() == 1);
final Receipt result = onNextResults.get(0);
assertNotNull(result.getFile());
assertEquals("1_name.pdf", result.getFile().getName());
assertTrue(result.getFile().delete());
}
@Test
public void preUpdateWithNewIndex() {
final String name = "name";
final Receipt oldReceipt = mock(Receipt.class);
when(oldReceipt.getIndex()).thenReturn(1);
when(oldReceipt.getName()).thenReturn(name);
when(oldReceipt.getFile()).thenReturn(new File("1_name.jpg"));
when(mReceipt.getIndex()).thenReturn(4);
when(mReceipt.getName()).thenReturn(name);
when(mReceipt.getFile()).thenReturn(new File("1_name.jpg"));
final List<Receipt> onNextResults =
mReceiptTableActionAlterations.preUpdate(oldReceipt, mReceipt)
.test()
.assertComplete()
.assertNoErrors()
.values();
assertNotNull(onNextResults);
assertTrue(onNextResults.size() == 1);
final Receipt result = onNextResults.get(0);
assertEquals(new File("4_name.jpg"), result.getFile());
}
@Test
public void postUpdateNull() throws Exception {
mReceiptTableActionAlterations.postUpdate(mReceipt, null)
.test()
.assertNoValues()
.assertNotComplete()
.assertError(Exception.class);
verifyZeroInteractions(mStorageManager);
}
@Test
public void postUpdateSuccessWithoutFile() throws Exception {
when(mReceipt.hasFile()).thenReturn(false);
final Receipt updatedReceipt = mock(Receipt.class);
mReceiptTableActionAlterations.postUpdate(mReceipt, updatedReceipt)
.test()
.assertValue(updatedReceipt)
.assertComplete()
.assertNoErrors();
verifyZeroInteractions(mStorageManager);
}
@Test
public void postUpdateSuccessWithSameFile() throws Exception {
final Receipt updatedReceipt = mock(Receipt.class);
final File file = new File("abc");
when(mReceipt.hasFile()).thenReturn(true);
when(updatedReceipt.hasFile()).thenReturn(true);
when(mReceipt.getFile()).thenReturn(file);
when(updatedReceipt.getFile()).thenReturn(file);
mReceiptTableActionAlterations.postUpdate(mReceipt, updatedReceipt)
.test()
.assertValue(updatedReceipt)
.assertComplete()
.assertNoErrors();
verify(mStorageManager, never()).delete(file);
}
@Test
public void postUpdateSuccessWithNewFile() throws Exception {
final Receipt updatedReceipt = mock(Receipt.class);
final File file = new File("abc");
final File newFile = new File("efg");
when(mReceipt.hasFile()).thenReturn(true);
when(updatedReceipt.hasFile()).thenReturn(true);
when(mReceipt.getFile()).thenReturn(file);
when(updatedReceipt.getFile()).thenReturn(newFile);
mReceiptTableActionAlterations.postUpdate(mReceipt, updatedReceipt)
.test()
.assertValue(updatedReceipt)
.assertComplete()
.assertNoErrors();
verify(mStorageManager).delete(file);
}
@Test
public void postDeleteNull() throws Exception {
mReceiptTableActionAlterations.postDelete(null)
.test()
.assertNoValues()
.assertNotComplete()
.assertError(Exception.class);
verifyZeroInteractions(mStorageManager);
}
@Test
public void postDeleteSuccessWithoutFile() throws Exception {
when(mReceipt.hasFile()).thenReturn(false);
mReceiptTableActionAlterations.postDelete(mReceipt)
.test()
.assertValue(mReceipt)
.assertComplete()
.assertNoErrors();
verifyZeroInteractions(mStorageManager);
}
@Test
public void postDeleteSuccessWithFile() throws Exception {
final File file = new File("abc");
when(mReceipt.hasFile()).thenReturn(true);
when(mReceipt.getFile()).thenReturn(file);
mReceiptTableActionAlterations.postDelete(mReceipt)
.test()
.assertValue(mReceipt)
.assertComplete()
.assertNoErrors();
verify(mStorageManager).delete(file);
}
}