Remove the InstalledManager

Largely duplicated work, and makes testing easier!
This commit is contained in:
Bradlee Speice
2014-11-11 23:46:51 -05:00
parent 35b515add7
commit b65b5680f9
7 changed files with 106 additions and 283 deletions

View File

@ -7,14 +7,17 @@ import android.util.Log;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.MBTestCase;
import org.bspeice.minimalbible.activity.downloader.DownloadPrefs;
import org.bspeice.minimalbible.activity.downloader.manager.BookDownloadManager;
import org.bspeice.minimalbible.activity.downloader.manager.BookManager;
import org.bspeice.minimalbible.activity.downloader.manager.DLProgressEvent;
import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager;
import org.crosswire.common.progress.JobManager;
import org.crosswire.common.progress.WorkEvent;
import org.crosswire.common.progress.WorkListener;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.book.BookDriver;
import org.crosswire.jsword.book.BookException;
import org.crosswire.jsword.book.Books;
import org.crosswire.jsword.book.BooksEvent;
import org.crosswire.jsword.book.install.InstallManager;
import org.crosswire.jsword.book.install.Installer;
import org.mockito.Mockito;
@ -35,13 +38,15 @@ import rx.functions.Func1;
import static com.jayway.awaitility.Awaitility.await;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.internal.verification.VerificationModeFactory.times;
public class BookDownloadManagerTest extends MBTestCase implements Injector {
public class BookManagerTest extends MBTestCase implements Injector {
ObjectGraph mObjectGraph;
@Inject
BookDownloadManager bookDownloadManager;
BookManager bookManager;
@Inject
RefreshManager refreshManager;
@Inject
@ -71,10 +76,10 @@ public class BookDownloadManagerTest extends MBTestCase implements Injector {
public void testInstallBook() throws Exception {
final Book toInstall = installableBooks().toBlocking().first();
bookDownloadManager.installBook(toInstall);
bookManager.installBook(toInstall);
final AtomicBoolean signal = new AtomicBoolean(false);
bookDownloadManager.getDownloadEvents()
bookManager.getDownloadEvents()
.subscribe(new Action1<DLProgressEvent>() {
@Override
public void call(DLProgressEvent dlProgressEvent) {
@ -91,7 +96,7 @@ public class BookDownloadManagerTest extends MBTestCase implements Injector {
public void testJobIdMatch() {
final Book toInstall = installableBooks().toBlocking().first();
final String jobName = bookDownloadManager.getJobId(toInstall);
final String jobName = bookManager.getJobId(toInstall);
final AtomicBoolean jobNameMatch = new AtomicBoolean(false);
JobManager.addWorkListener(new WorkListener() {
@ -108,17 +113,46 @@ public class BookDownloadManagerTest extends MBTestCase implements Injector {
}
});
bookDownloadManager.installBook(toInstall);
bookManager.installBook(toInstall);
await().atMost(1, TimeUnit.SECONDS)
.untilTrue(jobNameMatch);
}
public void testLocalListUpdatedAfterAdd() {
Book mockBook = mock(Book.class);
BooksEvent event = mock(BooksEvent.class);
when(event.getBook()).thenReturn(mockBook);
bookManager.bookAdded(event);
assertTrue(bookManager.getInstalledBooksList().contains(mockBook));
}
/**
* This test requires deep knowledge of how to remove a book in order to test,
* but the Kotlin interface is nice!
*/
public void testLocalListUpdatedAfterRemove() throws BookException {
BookDriver driver = mock(BookDriver.class);
Book mockBook = mock(Book.class);
when(mockBook.getDriver()).thenReturn(driver);
BooksEvent event = mock(BooksEvent.class);
when(event.getBook()).thenReturn(mockBook);
bookManager.getInstalledBooksList().add(mockBook);
assertTrue(bookManager.getInstalledBooksList().contains(mockBook));
bookManager.removeBook(mockBook);
assertFalse(bookManager.getInstalledBooksList().contains(mockBook));
verify(driver, times(1)).delete(mockBook);
}
/**
* Modules needed for this test case
*/
@Module(injects = {BookDownloadManager.class,
@Module(injects = {BookManager.class,
RefreshManager.class,
BookDownloadManagerTest.class})
BookManagerTest.class})
@SuppressWarnings("unused")
public static class BookDownloadManagerTestModules {
Injector i;
@ -167,8 +201,8 @@ public class BookDownloadManagerTest extends MBTestCase implements Injector {
@Provides
@Singleton
BookDownloadManager bookDownloadManager(Books installed, RefreshManager rm) {
return new BookDownloadManager(installed, rm);
BookManager bookDownloadManager(Books installed, RefreshManager rm) {
return new BookManager(installed, rm);
}
}
}

View File

@ -1,162 +0,0 @@
package org.bspeice.minimalbible.test.activity.downloader.manager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;
import org.bspeice.minimalbible.Injector;
import org.bspeice.minimalbible.MBTestCase;
import org.bspeice.minimalbible.activity.downloader.DownloadPrefs;
import org.bspeice.minimalbible.activity.downloader.manager.BookDownloadManager;
import org.bspeice.minimalbible.activity.downloader.manager.InstalledManager;
import org.bspeice.minimalbible.activity.downloader.manager.RefreshManager;
import org.crosswire.jsword.book.Book;
import org.crosswire.jsword.book.Books;
import org.crosswire.jsword.book.install.InstallManager;
import org.crosswire.jsword.book.install.Installer;
import org.mockito.Mockito;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Module;
import dagger.ObjectGraph;
import dagger.Provides;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Test the InstalledManager
* Currently due to limitations with JSword (which I'm currently investigating) you can't delete
* books without restarting the application. That is, if you install it, there must be a restart
* in between it being deleted. Unfortunately, that means that this TestCase really can't guarantee
* much, since I can't install a book at runtime to be removed.
*/
public class InstalledManagerTest extends MBTestCase implements Injector {
ObjectGraph mObjectGraph;
@Inject
InstalledManager iM;
@Inject
Books installedBooks;
@Override
public void inject(Object o) {
mObjectGraph.inject(o);
}
@Override
public void setUp() {
super.setUp();
mObjectGraph = ObjectGraph.create(new IMTestModules(this));
mObjectGraph.inject(this);
// Unfortunately, unless something is already installed, we can't actually remove anything
int count = getInstalledBooks().count().toBlocking().first();
if (count <= 0) {
Log.w("InstalledManagerTest", "No books available, test can not guarantee anything.");
}
}
public Observable<Book> getInstalledBooks() {
/* The golden copy for testing of what's installed.
NOTE: Currently, I have yet to find a guaranteed way to immediately delete
a book that is freshly installed. While the tests are semantically correct, unfortunately,
this test case specifically doesn't guarantee much of anything.
*/
return Observable.from(installedBooks.getBooks())
.filter(new Func1<Book, Boolean>() {
@Override
public Boolean call(Book book) {
// Not sure why, but this book can't be deleted...
return book.getDriver().isDeletable(book);
}
});
}
public void testIsInstalled() throws Exception {
final AtomicBoolean foundMismatch = new AtomicBoolean(false);
getInstalledBooks()
.subscribe(new Action1<Book>() {
@Override
public void call(Book book) {
// Skip if we've already found a mismatch
if (!foundMismatch.get()) {
// We've already filtered to what we know is installed,
// so set to true if iM doesn't think it's installed.
foundMismatch.set(!iM.isInstalled(book));
}
}
});
assertFalse(foundMismatch.get());
}
@Module(injects = {InstalledManager.class,
InstalledManagerTest.class,
RefreshManager.class,
BookDownloadManager.class})
@SuppressWarnings("unused")
static class IMTestModules {
Injector i;
ConnectivityManager manager;
DownloadPrefs prefs;
public IMTestModules(Injector i) {
this.i = i;
// Set reasonable defaults for the manager and preferences, can over-ride if need-be
manager = mock(ConnectivityManager.class);
NetworkInfo mockNetworkInfo = Mockito.mock(NetworkInfo.class);
when(manager.getActiveNetworkInfo()).thenReturn(mockNetworkInfo);
when(mockNetworkInfo.getType()).thenReturn(ConnectivityManager.TYPE_WIFI);
prefs = mock(DownloadPrefs.class);
}
@Provides
@Singleton
Injector provideInjector() {
return this.i;
}
@Provides
@Singleton
Books provideInstalledBooks() {
return Books.installed();
}
@Provides
List<Book> provideInstalledBooksList(Books b) {
return b.getBooks();
}
@Provides
@Singleton
Collection<Installer> provideInstallers() {
return new InstallManager().getInstallers().values();
}
void setConnectivityManager(ConnectivityManager manager) {
this.manager = manager;
}
void setPrefs(DownloadPrefs prefs) {
this.prefs = prefs;
}
@Provides
@Singleton
RefreshManager refreshManager(Collection<Installer> installers) {
return new RefreshManager(installers,
prefs, manager);
}
}
}