/** * Copyright (c) 2012 Todoroo Inc * * See the file "LICENSE" for the full license governing this code. */ package com.todoroo.astrid.dao; import com.todoroo.andlib.data.Property; import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.sql.Query; import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Task; import com.todoroo.astrid.test.DatabaseTestCase; public class MetadataDaoTests extends DatabaseTestCase { @Autowired MetadataDao metadataDao; @Autowired TaskDao taskDao; public static Property<?>[] KEYS = new Property<?>[] { Metadata.ID, Metadata.KEY }; /** * Test basic creation, fetch, and save */ public void testCrud() throws Exception { TodorooCursor<Metadata> cursor = metadataDao.query( Query.select(Metadata.ID)); assertEquals(0, cursor.getCount()); cursor.close(); // create "happy" Metadata metadata = new Metadata(); metadata.setValue(Metadata.KEY, "happy"); assertTrue(metadataDao.persist(metadata)); cursor = metadataDao.query( Query.select(Metadata.ID)); assertEquals(1, cursor.getCount()); cursor.close(); long happyId = metadata.getId(); assertNotSame(Metadata.NO_ID, happyId); metadata = metadataDao.fetch(happyId, KEYS); assertEquals("happy", metadata.getValue(Metadata.KEY)); // create "sad" metadata = new Metadata(); metadata.setValue(Metadata.KEY, "sad"); assertTrue(metadataDao.persist(metadata)); cursor = metadataDao.query(Query.select(Metadata.ID)); assertEquals(2, cursor.getCount()); cursor.close(); // rename sad to melancholy long sadId = metadata.getId(); assertNotSame(Metadata.NO_ID, sadId); metadata.setValue(Metadata.KEY, "melancholy"); assertTrue(metadataDao.persist(metadata)); cursor = metadataDao.query( Query.select(Metadata.ID)); assertEquals(2, cursor.getCount()); cursor.close(); // check state metadata = metadataDao.fetch(happyId, KEYS); assertEquals("happy", metadata.getValue(Metadata.KEY)); metadata = metadataDao.fetch(sadId, KEYS); assertEquals("melancholy", metadata.getValue(Metadata.KEY)); // delete sad assertTrue(metadataDao.delete(sadId)); cursor = metadataDao.query( Query.select(KEYS)); assertEquals(1, cursor.getCount()); cursor.moveToFirst(); metadata.readFromCursor(cursor); assertEquals("happy", metadata.getValue(Metadata.KEY)); cursor.close(); } /** * Test metadata bound to task */ public void testMetadataConditions() throws Exception { // create "happy" Metadata metadata = new Metadata(); metadata.setValue(Metadata.KEY, "with1"); metadata.setValue(Metadata.TASK, 1L); assertTrue(metadataDao.persist(metadata)); metadata = new Metadata(); metadata.setValue(Metadata.KEY, "with2"); metadata.setValue(Metadata.TASK, 2L); assertTrue(metadataDao.persist(metadata)); metadata = new Metadata(); metadata.setValue(Metadata.KEY, "with1"); metadata.setValue(Metadata.TASK, 1L); assertTrue(metadataDao.persist(metadata)); TodorooCursor<Metadata> cursor = metadataDao.query( Query.select(KEYS).where(MetadataCriteria.byTask(1))); assertEquals(2, cursor.getCount()); cursor.moveToFirst(); metadata.readFromCursor(cursor); assertEquals("with1", metadata.getValue(Metadata.KEY)); cursor.moveToNext(); metadata.readFromCursor(cursor); assertEquals("with1", metadata.getValue(Metadata.KEY)); cursor.close(); cursor = metadataDao.query( Query.select(KEYS).where(MetadataCriteria.byTask(3))); assertEquals(0, cursor.getCount()); cursor.close(); int deleted = metadataDao.deleteWhere(MetadataCriteria.byTask(1)); assertEquals(2, deleted); cursor = metadataDao.query( Query.select(KEYS)); assertEquals(1, cursor.getCount()); cursor.close(); } /** * Test metadata deletion */ public void testFetchDangling() throws Exception { // fetch with nothing in db TodorooCursor<Metadata> cursor = metadataDao.fetchDangling(KEYS); assertEquals(0, cursor.getCount()); cursor.close(); Task task1 = new Task(); taskDao.persist(task1); Task task2 = new Task(); taskDao.persist(task2); Task task3 = new Task(); taskDao.persist(task3); // fetch with only tasks cursor = metadataDao.fetchDangling(KEYS); assertEquals(0, cursor.getCount()); cursor.close(); Metadata metadata = new Metadata(); metadata.setValue(Metadata.KEY, "with1"); metadata.setValue(Metadata.TASK, task1.getId()); assertTrue(metadataDao.persist(metadata)); metadata = new Metadata(); metadata.setValue(Metadata.KEY, "with2"); metadata.setValue(Metadata.TASK, task2.getId()); assertTrue(metadataDao.persist(metadata)); metadata = new Metadata(); metadata.setValue(Metadata.KEY, "with3"); metadata.setValue(Metadata.TASK, task3.getId()); assertTrue(metadataDao.persist(metadata)); // fetch with tasks and corresponding metadata cursor = metadataDao.fetchDangling(KEYS); assertEquals(0, cursor.getCount()); cursor.close(); long task2Id = task2.getId(); taskDao.delete(task2.getId()); // note: we should not have any dangling, since deleting a task // will automatically delete metadata cursor = metadataDao.fetchDangling(KEYS); assertEquals(0, cursor.getCount()); cursor.close(); metadata = new Metadata(); metadata.setValue(Metadata.KEY, "with2"); metadata.setValue(Metadata.TASK, task2Id); assertTrue(metadataDao.persist(metadata)); // but if we simulate something bad happening by creating // it manually.. well, what can i say, it should be broken cursor = metadataDao.fetchDangling(KEYS); assertEquals(1, cursor.getCount()); cursor.moveToFirst(); metadata.readFromCursor(cursor); assertEquals("with2", metadata.getValue(Metadata.KEY)); cursor.close(); } }