package de.westnordost.streetcomplete.data; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteStatement; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import de.westnordost.osmapi.map.data.BoundingBox; import de.westnordost.osmapi.map.data.OsmLatLon; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class AQuestDaoTest extends AndroidDbTestCase { private static final String TABLE_NAME = "test", MERGED_VIEW_NAME = "test_full", ID_COL = "id", QS_COL = "quest_status", LAT_COL = "lat", LON_COL = "lon"; private static final String TESTDB = "testdb.db"; private TestQuestDao dao; private SQLiteOpenHelper dbHelper; public AQuestDaoTest() { super(TESTDB); } @Override public void setUp() { super.setUp(); dbHelper = new TestDbHelper(getContext()); dao = new TestQuestDao(dbHelper); } @Override public void tearDown() { // first close, then call super (= delete database) to avoid warning dbHelper.close(); super.tearDown(); } public void testAddGet() { long id = 3; Quest q = createQuest(id,0,0, QuestStatus.HIDDEN); dao.add(q); Quest q2 = dao.get(id); assertEquals(q.getId(), q2.getId()); assertEquals(q.getMarkerLocation(), q2.getMarkerLocation()); assertEquals(q.getStatus(), q2.getStatus()); } public void testAddAll() { Collection<Quest> quests = new ArrayList<>(); quests.add(createQuest(3,0,0, QuestStatus.NEW)); quests.add(createQuest(4,0,0, QuestStatus.ANSWERED)); assertEquals(2,dao.addAll(quests)); } public void testAddAllNoOverwrite() { Collection<Quest> quests = new ArrayList<>(); quests.add(createQuest(3,0,0, QuestStatus.NEW)); quests.add(createQuest(3,0,0, QuestStatus.ANSWERED)); assertEquals(1,dao.addAll(quests)); } public void testAddNoOverwrite() { assertTrue(dao.add(createQuest(3,0,0, QuestStatus.HIDDEN))); assertFalse(dao.add(createQuest(3,0,0, QuestStatus.NEW))); assertEquals(QuestStatus.HIDDEN, dao.get(3).getStatus()); } public void testReplace() { assertTrue(dao.add(createQuest(3,0,0, QuestStatus.HIDDEN))); assertTrue(dao.replace(createQuest(3,0,0, QuestStatus.NEW))); assertEquals(QuestStatus.NEW, dao.get(3).getStatus()); assertEquals(1,dao.getAll(null,null).size()); } public void testDelete() { assertFalse(dao.delete(0)); dao.add(createQuest(1,0,0, QuestStatus.NEW)); assertTrue(dao.delete(1)); } public void testDeleteAll() { dao.add(createQuest(0,0,0, QuestStatus.NEW)); dao.add(createQuest(1,0,0, QuestStatus.NEW)); dao.add(createQuest(2,0,0, QuestStatus.NEW)); assertEquals(2, dao.deleteAll(Arrays.asList(1L, 2L))); } public void testUpdateException() { try { dao.update(createQuest(0,0,0,QuestStatus.NEW)); fail(); } catch(NullPointerException e) { } } public void testUpdate() { dao.add(createQuest(1,0,0, QuestStatus.NEW)); dao.update(createQuest(1,0,0, QuestStatus.ANSWERED)); assertEquals(QuestStatus.ANSWERED, dao.get(1).getStatus()); } public void testGetAllByBoundingBox() { BoundingBox bbox = new BoundingBox(50,1,51,2); // on border dao.add(createQuest(1,50,1, QuestStatus.NEW)); // right lat but wrong lon dao.add(createQuest(2,50.5,50.5, QuestStatus.NEW)); // wrong lat but right lon dao.add(createQuest(3,1.5,1.5, QuestStatus.NEW)); // in dao.add(createQuest(4,50.5,1.5, QuestStatus.NEW)); List<Quest> quests = dao.getAll(bbox, QuestStatus.NEW); Collections.sort(quests, new Comparator<Quest>() { @Override public int compare(Quest lhs, Quest rhs) { return (int) (lhs.getId() - rhs.getId()); } }); assertEquals(2,quests.size()); assertEquals(1,(long) quests.get(0).getId()); assertEquals(4,(long) quests.get(1).getId()); assertEquals(2, dao.getCount(bbox, QuestStatus.NEW)); } public void testGetCountWhenEmpty() { assertEquals(0, dao.getCount(new BoundingBox(50,1,51,2), QuestStatus.NEW)); } private class TestQuestDao extends AQuestDao<Quest> { public TestQuestDao(SQLiteOpenHelper dbHelper) { super(dbHelper); } @Override protected String getTableName() { return TABLE_NAME; } @Override protected String getMergedViewName() { return TABLE_NAME; } @Override protected String getIdColumnName() { return ID_COL; } @Override protected String getQuestStatusColumnName() { return QS_COL; } @Override protected String getLatitudeColumnName() { return LAT_COL; } @Override protected String getLongitudeColumnName() { return LON_COL; } @Override protected long executeInsert(Quest quest, boolean replace) { String orWhat = replace ? "REPLACE" : "IGNORE"; SQLiteDatabase db = dbHelper.getWritableDatabase(); SQLiteStatement insert = db.compileStatement( "INSERT OR "+orWhat+" INTO " + TABLE_NAME + "("+ID_COL+","+QS_COL+","+LAT_COL+","+LON_COL+") VALUES (?,?,?,?)"); insert.bindLong(1, quest.getId()); insert.bindString(2, quest.getStatus().name()); insert.bindDouble(3, quest.getMarkerLocation().getLatitude()); insert.bindDouble(4, quest.getMarkerLocation().getLongitude()); return insert.executeInsert(); } @Override protected ContentValues createNonFinalContentValuesFrom(Quest quest) { ContentValues v = new ContentValues(); v.put(QS_COL, quest.getStatus().name()); return v; } @Override protected ContentValues createFinalContentValuesFrom(Quest quest) { ContentValues v = new ContentValues(); v.put(ID_COL, quest.getId()); v.put(LAT_COL, quest.getMarkerLocation().getLatitude()); v.put(LON_COL, quest.getMarkerLocation().getLongitude()); return v; } @Override protected Quest createObjectFrom(Cursor cursor) { return createQuest(cursor.getLong(0), cursor.getDouble(1), cursor.getDouble(2), QuestStatus.valueOf(cursor.getString(3))); } } private Quest createQuest(long id, double lat, double lon, QuestStatus status) { Quest quest = mock(Quest.class); when(quest.getStatus()).thenReturn(status); when(quest.getId()).thenReturn(id); when(quest.getMarkerLocation()).thenReturn(new OsmLatLon(lat,lon)); return quest; } private class TestDbHelper extends SQLiteOpenHelper { public TestDbHelper(Context context) { super(context, TESTDB, null, 1); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE "+TABLE_NAME+" ( " + ID_COL+" int PRIMARY KEY, " + LAT_COL+" double, " + LON_COL+" double, " + QS_COL+" varchar(255));"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } }