package co.smartreceipts.android.persistence.database.controllers.alterations;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import co.smartreceipts.android.model.Price;
import co.smartreceipts.android.model.Trip;
import co.smartreceipts.android.persistence.DatabaseHelper;
import co.smartreceipts.android.persistence.database.operations.DatabaseOperationMetadata;
import co.smartreceipts.android.persistence.database.operations.OperationFamilyType;
import co.smartreceipts.android.persistence.database.tables.DistanceTable;
import co.smartreceipts.android.persistence.database.tables.ReceiptsTable;
import co.smartreceipts.android.persistence.database.tables.Table;
import io.reactivex.Single;
import wb.android.storage.StorageManager;
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 TripTableActionAlterationsTest {
TripTableActionAlterations mTripTableActionAlterations;
@Mock
Table<Trip, String> mTripsTable;
@Mock
ReceiptsTable mReceiptsTable;
@Mock
DistanceTable mDistanceTable;
@Mock
DatabaseHelper mDatabaseHelper;
@Mock
StorageManager mStorageManager;
@Mock
Trip mTrip1;
@Mock
Trip mTrip2;
@Mock
Price mPrice1;
@Mock
Price mPrice2;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mTripTableActionAlterations = new TripTableActionAlterations(mTripsTable, mReceiptsTable, mDistanceTable, mDatabaseHelper, mStorageManager);
when(mTrip1.getPrice()).thenReturn(mPrice1);
when(mTrip1.getDailySubTotal()).thenReturn(mPrice2);
}
@Test
public void postGet() throws Exception {
final List<Trip> trips = Arrays.asList(mTrip1, mTrip2);
mTripTableActionAlterations.postGet(trips)
.test()
.assertValue(trips)
.assertComplete()
.assertNoErrors();
verify(mDatabaseHelper).getTripPriceAndDailyPrice(mTrip1);
verify(mDatabaseHelper).getTripPriceAndDailyPrice(mTrip2);
}
@Test
public void postInsertForNullTrip() throws Exception {
mTripTableActionAlterations.postInsert(null)
.test()
.assertNoValues()
.assertNotComplete()
.assertError(Exception.class);
verify(mTripsTable, never()).delete(mTrip1, new DatabaseOperationMetadata());
}
@Test
public void postInsertForValidTrip() throws Exception {
final String name = "name";
when(mTrip1.getName()).thenReturn(name);
when(mStorageManager.mkdir(name)).thenReturn(new File(name));
mTripTableActionAlterations.postInsert(mTrip1)
.test()
.assertValue(mTrip1)
.assertComplete()
.assertNoErrors();
verify(mTripsTable, never()).delete(mTrip1, new DatabaseOperationMetadata());
}
@Test
public void postInsertForValidTripButIOFails() throws Exception {
final DatabaseOperationMetadata metadata = new DatabaseOperationMetadata(OperationFamilyType.Rollback);
final String name = "name";
when(mTrip1.getName()).thenReturn(name);
when(mStorageManager.mkdir(name)).thenReturn(null);
when(mTripsTable.delete(mTrip1, metadata)).thenReturn(Single.just(mTrip1));
mTripTableActionAlterations.postInsert(mTrip1)
.test()
.assertNoValues()
.assertNotComplete()
.assertError(IOException.class);
verify(mTripsTable).delete(mTrip1, metadata);
}
@Test
public void postUpdateForNullTrip() throws Exception {
mTripTableActionAlterations.postUpdate(mTrip1, null)
.test()
.assertNoValues()
.assertNotComplete()
.assertError(Exception.class);
}
@Test
public void postUpdateForTripWithSameName() throws Exception {
final String name = "name";
when(mTrip1.getName()).thenReturn(name);
when(mTrip2.getName()).thenReturn(name);
when(mTrip1.getDirectory()).thenReturn(new File(name));
when(mTrip2.getDirectory()).thenReturn(new File(name));
mTripTableActionAlterations.postUpdate(mTrip1, mTrip2)
.test()
.assertValue(mTrip2)
.assertComplete()
.assertNoErrors();
verify(mTrip2).setPrice(mPrice1);
verify(mTrip2).setDailySubTotal(mPrice2);
verifyZeroInteractions(mStorageManager, mReceiptsTable, mDistanceTable);
}
@Test
public void postUpdateForValidTripWithNewName() throws Exception {
final String name1 = "name1";
final String name2 = "name2";
when(mTrip1.getName()).thenReturn(name1);
when(mTrip2.getName()).thenReturn(name2);
when(mTrip1.getDirectory()).thenReturn(new File(name1));
when(mStorageManager.rename(new File(name1), name2)).thenReturn(new File(name2));
mTripTableActionAlterations.postUpdate(mTrip1, mTrip2)
.test()
.assertValue(mTrip2)
.assertComplete()
.assertNoErrors();
verify(mTrip2).setPrice(mPrice1);
verify(mTrip2).setDailySubTotal(mPrice2);
verify(mReceiptsTable).updateParentBlocking(mTrip1, mTrip2);
verify(mDistanceTable).updateParentBlocking(mTrip1, mTrip2);
verify(mTripsTable, never()).update(mTrip2, mTrip1, new DatabaseOperationMetadata());
verify(mReceiptsTable, never()).updateParentBlocking(mTrip2, mTrip1);
verify(mDistanceTable, never()).updateParentBlocking(mTrip2, mTrip1);
}
@Test
public void postUpdateForValidTripButIOFails() throws Exception {
final String name1 = "name1";
final String name2 = "name2";
when(mTrip1.getName()).thenReturn(name1);
when(mTrip2.getName()).thenReturn(name2);
when(mTrip1.getDirectory()).thenReturn(new File(name1));
when(mStorageManager.rename(new File(name1), name2)).thenReturn(new File(name1));
when(mTripsTable.update(mTrip2, mTrip1, new DatabaseOperationMetadata())).thenReturn(Single.just(mTrip1));
mTripTableActionAlterations.postUpdate(mTrip1, mTrip2)
.test()
.assertNoValues()
.assertNotComplete()
.assertError(IOException.class);
verify(mTrip2).setPrice(mPrice1);
verify(mTrip2).setDailySubTotal(mPrice2);
verify(mReceiptsTable).updateParentBlocking(mTrip1, mTrip2);
verify(mDistanceTable).updateParentBlocking(mTrip1, mTrip2);
verify(mReceiptsTable).updateParentBlocking(mTrip2, mTrip1);
verify(mDistanceTable).updateParentBlocking(mTrip2, mTrip1);
verify(mTripsTable).update(mTrip2, mTrip1, new DatabaseOperationMetadata());
}
@Test
public void postDeleteNull() throws Exception {
mTripTableActionAlterations.postDelete(null)
.test()
.assertNoValues()
.assertNotComplete()
.assertError(Exception.class);
verifyZeroInteractions(mReceiptsTable, mDistanceTable);
}
@Test
public void postDeleteSuccess() throws Exception {
final File dir = new File("name");
when(mTrip1.getDirectory()).thenReturn(dir);
mTripTableActionAlterations.postDelete(mTrip1)
.test()
.assertValue(mTrip1)
.assertComplete()
.assertNoErrors();
verify(mReceiptsTable).deleteParentBlocking(mTrip1);
verify(mDistanceTable).deleteParentBlocking(mTrip1);
verify(mStorageManager).deleteRecursively(dir);
}
}