/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ package org.mozilla.gecko.sync.repositories.android.test; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.junit.Before; import org.junit.Test; import org.mozilla.gecko.sync.Logger; import org.mozilla.gecko.sync.Utils; import org.mozilla.gecko.sync.repositories.android.BookmarksInsertionManager; import org.mozilla.gecko.sync.repositories.domain.BookmarkRecord; public class TestBookmarksInsertionManager { public BookmarksInsertionManager manager; public ArrayList<String[]> insertions; @Before public void setUp() { insertions = new ArrayList<String[]>(); Set<String> writtenFolders = new HashSet<String>(); writtenFolders.add("mobile"); BookmarksInsertionManager.BookmarkInserter inserter = new BookmarksInsertionManager.BookmarkInserter() { @Override public boolean insertFolder(BookmarkRecord record) { if (record.guid == "fail") { return false; } Logger.debug(BookmarksInsertionManager.LOG_TAG, "Inserted folder (" + record.guid + ")."); insertions.add(new String[] { record.guid }); return true; } @Override public void bulkInsertNonFolders(Collection<BookmarkRecord> records) { ArrayList<String> guids = new ArrayList<String>(); for (BookmarkRecord record : records) { guids.add(record.guid); } String[] guidList = guids.toArray(new String[guids.size()]); insertions.add(guidList); Logger.debug(BookmarksInsertionManager.LOG_TAG, "Inserted non-folders (" + Utils.toCommaSeparatedString(guids) + ")."); } }; manager = new BookmarksInsertionManager(3, writtenFolders, inserter); BookmarksInsertionManager.DEBUG = true; } protected static BookmarkRecord bookmark(String guid, String parent) { BookmarkRecord bookmark = new BookmarkRecord(guid); bookmark.type = "bookmark"; bookmark.parentID = parent; return bookmark; } protected static BookmarkRecord folder(String guid, String parent) { BookmarkRecord bookmark = new BookmarkRecord(guid); bookmark.type = "folder"; bookmark.parentID = parent; return bookmark; } @Test public void testChildrenBeforeFolder() { BookmarkRecord folder = folder("folder", "mobile"); BookmarkRecord child1 = bookmark("child1", "folder"); BookmarkRecord child2 = bookmark("child2", "folder"); manager.enqueueRecord(child1); assertTrue(insertions.isEmpty()); manager.enqueueRecord(child2); assertTrue(insertions.isEmpty()); manager.enqueueRecord(folder); assertEquals(1, insertions.size()); manager.finishUp(); assertTrue(manager.isClear()); assertEquals(2, insertions.size()); assertArrayEquals(new String[] { "folder" }, insertions.get(0)); assertArrayEquals(new String[] { "child1", "child2" }, insertions.get(1)); } @Test public void testChildAfterFolder() { BookmarkRecord folder = folder("folder", "mobile"); BookmarkRecord child1 = bookmark("child1", "folder"); BookmarkRecord child2 = bookmark("child2", "folder"); manager.enqueueRecord(child1); assertTrue(insertions.isEmpty()); manager.enqueueRecord(folder); assertEquals(1, insertions.size()); manager.enqueueRecord(child2); assertEquals(1, insertions.size()); manager.finishUp(); assertTrue(manager.isClear()); assertEquals(2, insertions.size()); assertArrayEquals(new String[] { "folder" }, insertions.get(0)); assertArrayEquals(new String[] { "child1", "child2" }, insertions.get(1)); } @Test public void testFolderAfterFolder() { manager.enqueueRecord(bookmark("child1", "folder1")); assertEquals(0, insertions.size()); manager.enqueueRecord(folder("folder1", "mobile")); assertEquals(1, insertions.size()); manager.enqueueRecord(bookmark("child2", "folder2")); assertEquals(1, insertions.size()); manager.enqueueRecord(folder("folder2", "folder1")); assertEquals(2, insertions.size()); manager.enqueueRecord(bookmark("child3", "folder1")); manager.enqueueRecord(bookmark("child4", "folder2")); assertEquals(3, insertions.size()); manager.finishUp(); assertTrue(manager.isClear()); assertEquals(4, insertions.size()); assertArrayEquals(new String[] { "folder1" }, insertions.get(0)); assertArrayEquals(new String[] { "folder2" }, insertions.get(1)); assertArrayEquals(new String[] { "child1", "child2", "child3" }, insertions.get(2)); assertArrayEquals(new String[] { "child4" }, insertions.get(3)); } @Test public void testFolderRecursion() { manager.enqueueRecord(folder("1", "mobile")); manager.enqueueRecord(folder("2", "1")); assertEquals(2, insertions.size()); manager.enqueueRecord(bookmark("3a", "3")); manager.enqueueRecord(bookmark("3b", "3")); manager.enqueueRecord(bookmark("3c", "3")); manager.enqueueRecord(bookmark("4a", "4")); manager.enqueueRecord(bookmark("4b", "4")); manager.enqueueRecord(bookmark("4c", "4")); assertEquals(2, insertions.size()); manager.enqueueRecord(folder("3", "2")); assertEquals(4, insertions.size()); manager.enqueueRecord(folder("4", "2")); assertEquals(6, insertions.size()); assertTrue(manager.isClear()); manager.finishUp(); assertTrue(manager.isClear()); // Folders in order. assertArrayEquals(new String[] { "1" }, insertions.get(0)); assertArrayEquals(new String[] { "2" }, insertions.get(1)); assertArrayEquals(new String[] { "3" }, insertions.get(2)); // Then children in batches of 3. assertArrayEquals(new String[] { "3a", "3b", "3c" }, insertions.get(3)); // Then last folder. assertArrayEquals(new String[] { "4" }, insertions.get(4)); assertArrayEquals(new String[] { "4a", "4b", "4c" }, insertions.get(5)); } @Test public void testFailedFolderInsertion() { manager.enqueueRecord(bookmark("failA", "fail")); manager.enqueueRecord(bookmark("failB", "fail")); assertEquals(0, insertions.size()); manager.enqueueRecord(folder("fail", "mobile")); assertEquals(0, insertions.size()); manager.enqueueRecord(bookmark("failC", "fail")); assertEquals(0, insertions.size()); manager.finishUp(); // Children inserted at the end; they will be treated as orphans. assertTrue(manager.isClear()); assertEquals(1, insertions.size()); assertArrayEquals(new String[] { "failA", "failB", "failC" }, insertions.get(0)); } @Test public void testIncrementalFlush() { manager.enqueueRecord(bookmark("a", "1")); manager.enqueueRecord(bookmark("b", "1")); manager.enqueueRecord(folder("1", "mobile")); assertEquals(1, insertions.size()); manager.enqueueRecord(bookmark("c", "1")); assertEquals(2, insertions.size()); manager.enqueueRecord(bookmark("d", "1")); manager.enqueueRecord(bookmark("e", "1")); manager.enqueueRecord(bookmark("f", "1")); assertEquals(3, insertions.size()); manager.enqueueRecord(bookmark("g", "1")); // Start of new batch. assertEquals(3, insertions.size()); manager.finishUp(); // Children inserted at the end; they will be treated as orphans. assertTrue(manager.isClear()); assertEquals(4, insertions.size()); assertArrayEquals(new String[] { "1" }, insertions.get(0)); assertArrayEquals(new String[] { "a", "b", "c"}, insertions.get(1)); assertArrayEquals(new String[] { "d", "e", "f"}, insertions.get(2)); assertArrayEquals(new String[] { "g" }, insertions.get(3)); } @Test public void testFinishUp() { manager.enqueueRecord(bookmark("a", "1")); manager.enqueueRecord(bookmark("b", "1")); manager.enqueueRecord(folder("2", "1")); manager.enqueueRecord(bookmark("c", "1")); manager.enqueueRecord(bookmark("d", "1")); manager.enqueueRecord(folder("3", "1")); assertEquals(0, insertions.size()); manager.finishUp(); // Children inserted at the end; they will be treated as orphans. assertTrue(manager.isClear()); assertEquals(3, insertions.size()); assertArrayEquals(new String[] { "2" }, insertions.get(0)); assertArrayEquals(new String[] { "3" }, insertions.get(1)); assertArrayEquals(new String[] { "a", "b", "c", "d" }, insertions.get(2)); // Last insertion could be big. } }