package co.smartreceipts.android.persistence.database.tables.adapters;
import android.content.ContentValues;
import android.database.Cursor;
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.math.BigDecimal;
import java.sql.Date;
import java.util.TimeZone;
import co.smartreceipts.android.model.Distance;
import co.smartreceipts.android.model.Price;
import co.smartreceipts.android.model.PriceCurrency;
import co.smartreceipts.android.model.Trip;
import co.smartreceipts.android.model.factory.DistanceBuilderFactory;
import co.smartreceipts.android.persistence.database.operations.DatabaseOperationMetadata;
import co.smartreceipts.android.persistence.database.operations.OperationFamilyType;
import co.smartreceipts.android.persistence.database.tables.Table;
import co.smartreceipts.android.persistence.database.tables.keys.PrimaryKey;
import co.smartreceipts.android.sync.model.SyncState;
import io.reactivex.Single;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(RobolectricTestRunner.class)
public class DistanceDatabaseAdapterTest {
private static final int ID = 5;
private static final int PRIMARY_KEY_ID = 11;
private static final String PARENT = "Trip";
private static final double DISTANCE = 12.55d;
private static final String LOCATION = "Location";
private static final long DATE = 1409703721000L;
private static final String TIMEZONE = TimeZone.getDefault().getID();
private static final String COMMENT = "Comment";
private static final double RATE = 0.33d;
private static final String CURRENCY_CODE = "USD";
// Class under test
DistanceDatabaseAdapter mDistanceDatabaseAdapter;
@Mock
Table<Trip, String> mTripsTable;
@Mock
Trip mTrip;
@Mock
Cursor mCursor;
@Mock
Distance mDistance;
@Mock
Price mPrice;
@Mock
PrimaryKey<Distance, Integer> mPrimaryKey;
@Mock
SyncStateAdapter mSyncStateAdapter;
@Mock
SyncState mSyncState, mGetSyncState;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
final int idIndex = 1;
final int parentIndex = 2;
final int distanceIndex = 3;
final int locationIndex = 4;
final int dateIndex = 5;
final int timezoneIndex = 6;
final int commentIndex = 7;
final int rateIndex = 8;
final int rateCurrencyIndex = 9;
when(mCursor.getColumnIndex("id")).thenReturn(idIndex);
when(mCursor.getColumnIndex("parent")).thenReturn(parentIndex);
when(mCursor.getColumnIndex("distance")).thenReturn(distanceIndex);
when(mCursor.getColumnIndex("location")).thenReturn(locationIndex);
when(mCursor.getColumnIndex("date")).thenReturn(dateIndex);
when(mCursor.getColumnIndex("timezone")).thenReturn(timezoneIndex);
when(mCursor.getColumnIndex("comment")).thenReturn(commentIndex);
when(mCursor.getColumnIndex("rate")).thenReturn(rateIndex);
when(mCursor.getColumnIndex("rate_currency")).thenReturn(rateCurrencyIndex);
when(mCursor.getInt(idIndex)).thenReturn(ID);
when(mCursor.getString(parentIndex)).thenReturn(PARENT);
when(mCursor.getDouble(distanceIndex)).thenReturn(DISTANCE);
when(mCursor.getString(locationIndex)).thenReturn(LOCATION);
when(mCursor.getLong(dateIndex)).thenReturn(DATE);
when(mCursor.getString(timezoneIndex)).thenReturn(TIMEZONE);
when(mCursor.getString(commentIndex)).thenReturn(COMMENT);
when(mCursor.getDouble(rateIndex)).thenReturn(RATE);
when(mCursor.getString(rateCurrencyIndex)).thenReturn(CURRENCY_CODE);
when(mDistance.getTrip()).thenReturn(mTrip);
when(mDistance.getLocation()).thenReturn(LOCATION);
when(mDistance.getDistance()).thenReturn(new BigDecimal(DISTANCE));
when(mDistance.getTimeZone()).thenReturn(TimeZone.getTimeZone(TIMEZONE));
when(mDistance.getDate()).thenReturn(new Date(DATE));
when(mDistance.getRate()).thenReturn(new BigDecimal(RATE));
when(mDistance.getPrice()).thenReturn(mPrice);
when(mDistance.getComment()).thenReturn(COMMENT);
when(mDistance.getSyncState()).thenReturn(mSyncState);
when(mTrip.getName()).thenReturn(PARENT);
when(mPrice.getCurrencyCode()).thenReturn(CURRENCY_CODE);
when(mPrice.getCurrency()).thenReturn(PriceCurrency.getInstance(CURRENCY_CODE));
when(mTripsTable.findByPrimaryKey(PARENT)).thenReturn(Single.just(mTrip));
when(mPrimaryKey.getPrimaryKeyValue(mDistance)).thenReturn(PRIMARY_KEY_ID);
when(mSyncStateAdapter.read(mCursor)).thenReturn(mSyncState);
when(mSyncStateAdapter.get(any(SyncState.class), any(DatabaseOperationMetadata.class))).thenReturn(mGetSyncState);
mDistanceDatabaseAdapter = new DistanceDatabaseAdapter(mTripsTable, mSyncStateAdapter);
}
@Test
public void read() throws Exception {
final Distance distance = new DistanceBuilderFactory(ID).setTrip(mTrip).setLocation(LOCATION).setDistance(DISTANCE).setDate(DATE).setTimezone(TIMEZONE).setRate(RATE).setCurrency(CURRENCY_CODE).setComment(COMMENT).setSyncState(mSyncState).build();
assertEquals(distance, mDistanceDatabaseAdapter.read(mCursor));
}
@Test
public void readForSelectionDescending() throws Exception {
final Distance distance = new DistanceBuilderFactory(ID).setTrip(mTrip).setLocation(LOCATION).setDistance(DISTANCE).setDate(DATE).setTimezone(TIMEZONE).setRate(RATE).setCurrency(CURRENCY_CODE).setComment(COMMENT).setSyncState(mSyncState).build();
assertEquals(distance, mDistanceDatabaseAdapter.readForSelection(mCursor, mTrip, true));
}
@Test
public void readForSelectionAscending() throws Exception {
final Distance distance = new DistanceBuilderFactory(ID).setTrip(mTrip).setLocation(LOCATION).setDistance(DISTANCE).setDate(DATE).setTimezone(TIMEZONE).setRate(RATE).setCurrency(CURRENCY_CODE).setComment(COMMENT).setSyncState(mSyncState).build();
assertEquals(distance, mDistanceDatabaseAdapter.readForSelection(mCursor, mTrip, false));
}
@Test
public void writeUnsycned() throws Exception {
final String sync = "sync";
final ContentValues syncValues = new ContentValues();
syncValues.put(sync, sync);
when(mSyncStateAdapter.writeUnsynced(mSyncState)).thenReturn(syncValues);
final ContentValues contentValues = mDistanceDatabaseAdapter.write(mDistance, new DatabaseOperationMetadata());
assertEquals(PARENT, contentValues.getAsString("parent"));
assertEquals(DISTANCE, contentValues.getAsDouble("distance"), 0.0001d);
assertEquals(LOCATION, contentValues.getAsString("location"));
assertEquals(DATE, (long) contentValues.getAsLong("date"));
assertEquals(TIMEZONE, contentValues.getAsString("timezone"));
assertEquals(COMMENT, contentValues.getAsString("comment"));
assertEquals(RATE, contentValues.getAsDouble("rate"), 0.0001d);
assertEquals(CURRENCY_CODE, contentValues.getAsString("rate_currency"));
assertEquals(sync, contentValues.getAsString(sync));
assertFalse(contentValues.containsKey("id"));
}
@Test
public void write() throws Exception {
final String sync = "sync";
final ContentValues syncValues = new ContentValues();
syncValues.put(sync, sync);
when(mSyncStateAdapter.write(mSyncState)).thenReturn(syncValues);
final ContentValues contentValues = mDistanceDatabaseAdapter.write(mDistance, new DatabaseOperationMetadata(OperationFamilyType.Sync));
assertEquals(PARENT, contentValues.getAsString("parent"));
assertEquals(DISTANCE, contentValues.getAsDouble("distance"), 0.0001d);
assertEquals(LOCATION, contentValues.getAsString("location"));
assertEquals(DATE, (long) contentValues.getAsLong("date"));
assertEquals(TIMEZONE, contentValues.getAsString("timezone"));
assertEquals(COMMENT, contentValues.getAsString("comment"));
assertEquals(RATE, contentValues.getAsDouble("rate"), 0.0001d);
assertEquals(CURRENCY_CODE, contentValues.getAsString("rate_currency"));
assertEquals(sync, contentValues.getAsString(sync));
assertFalse(contentValues.containsKey("id"));
}
@Test
public void build() throws Exception {
final Distance distance = new DistanceBuilderFactory(PRIMARY_KEY_ID).setTrip(mTrip).setLocation(LOCATION).setDistance(DISTANCE).setDate(DATE).setTimezone(TIMEZONE).setRate(RATE).setCurrency(CURRENCY_CODE).setComment(COMMENT).setSyncState(mGetSyncState).build();
assertEquals(distance, mDistanceDatabaseAdapter.build(mDistance, mPrimaryKey, mock(DatabaseOperationMetadata.class)));
assertEquals(distance.getSyncState(), mDistanceDatabaseAdapter.build(mDistance, mPrimaryKey, mock(DatabaseOperationMetadata.class)).getSyncState());
}
}