mirror of
https://github.com/MinimalBible/MinimalBible
synced 2024-11-22 07:58:20 -05:00
Clean and make more strict the InstalledManager tests
Unfortunately, they're currently always going to succeed. I'm having issues with the API not giving me a fresh list of what is installed.
This commit is contained in:
parent
d6d52cea04
commit
46e1285b61
@ -1,13 +1,29 @@
|
||||
package org.bspeice.minimalbible.test.activity.downloader.manager;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.bspeice.minimalbible.Injector;
|
||||
import org.bspeice.minimalbible.activity.downloader.manager.BookDownloadManager;
|
||||
import org.bspeice.minimalbible.activity.downloader.manager.DLProgressEvent;
|
||||
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.BooksEvent;
|
||||
import org.crosswire.jsword.book.BooksListener;
|
||||
import org.crosswire.jsword.book.install.InstallManager;
|
||||
import org.crosswire.jsword.book.install.Installer;
|
||||
import org.crosswire.jsword.book.sword.SwordBook;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -17,14 +33,20 @@ import dagger.Module;
|
||||
import dagger.ObjectGraph;
|
||||
import dagger.Provides;
|
||||
import rx.Observable;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.functions.Action0;
|
||||
import rx.functions.Action1;
|
||||
import rx.functions.Func1;
|
||||
|
||||
import static com.jayway.awaitility.Awaitility.await;
|
||||
|
||||
public class InstalledManagerTest extends TestCase implements Injector {
|
||||
ObjectGraph mObjectGraph;
|
||||
|
||||
@Module(injects = {InstalledManager.class,
|
||||
InstalledManagerTest.class})
|
||||
InstalledManagerTest.class,
|
||||
RefreshManager.class,
|
||||
BookDownloadManager.class})
|
||||
static class IMTestModules {
|
||||
Injector i;
|
||||
public IMTestModules(Injector i) {
|
||||
@ -45,10 +67,17 @@ public class InstalledManagerTest extends TestCase implements Injector {
|
||||
List<Book> provideInstalledBooksList(Books b) {
|
||||
return b.getBooks();
|
||||
}
|
||||
|
||||
@Provides @Singleton
|
||||
Collection<Installer> provideInstallers() {
|
||||
return new InstallManager().getInstallers().values();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject Books installedBooks;
|
||||
@Inject InstalledManager iM;
|
||||
@Inject BookDownloadManager bDM;
|
||||
@Inject RefreshManager rM;
|
||||
@Inject Books installedBooks;
|
||||
|
||||
@Override
|
||||
public void inject(Object o) {
|
||||
@ -60,17 +89,55 @@ public class InstalledManagerTest extends TestCase implements Injector {
|
||||
mObjectGraph = ObjectGraph.create(new IMTestModules(this));
|
||||
mObjectGraph.inject(this);
|
||||
|
||||
//TODO: Guarantee that a book is installed.
|
||||
// Guarantee something is installed
|
||||
getInstalledBooks()
|
||||
.count()
|
||||
.subscribe(new Action1<Integer>() {
|
||||
@Override
|
||||
public void call(Integer count) {
|
||||
if (count <= 0) {
|
||||
Log.i("InstalledManagerTest", "Nothing installed!");
|
||||
final AtomicBoolean isInstalled = new AtomicBoolean(false);
|
||||
final Book toInstall = rM.getAvailableModulesFlattened().toBlocking().first();
|
||||
bDM.installBook(toInstall);
|
||||
bDM.getDownloadEvents()
|
||||
.subscribe(new Action1<DLProgressEvent>() {
|
||||
@Override
|
||||
public void call(DLProgressEvent dlProgressEvent) {
|
||||
if (dlProgressEvent.getProgress() == DLProgressEvent.PROGRESS_COMPLETE &&
|
||||
dlProgressEvent.getB().getName().equals(toInstall.getName())) {
|
||||
|
||||
isInstalled.set(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
await().atMost(30, TimeUnit.SECONDS)
|
||||
.untilTrue(isInstalled);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Observable<Book> getInstalledBooks() {
|
||||
public Observable<Book> getInstalledBooks() {
|
||||
/* The golden copy for testing of what's installed.
|
||||
NOTE: Currently, I have yet to find a guaranteed way to know if a book
|
||||
is installed or not. So while the test cases are semantically correct,
|
||||
nothing is actually proven until I can guarantee this list is correct.
|
||||
*/
|
||||
// TODO: Guarantee that we return newly-installed books
|
||||
return Observable.from(installedBooks.getBooks())
|
||||
.filter(new Func1<Book, Boolean>() {
|
||||
@Override
|
||||
public Boolean call(Book book) {
|
||||
// Double check that the book is actually installed
|
||||
return book.getDriver().isDeletable(book);
|
||||
}
|
||||
})
|
||||
.filter(new Func1<Book, Boolean>() {
|
||||
@Override
|
||||
public Boolean call(Book book) {
|
||||
// Not sure why, but this book can't be deleted...
|
||||
return !book.getInitials().equals("ot1nt2");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -80,14 +147,22 @@ public class InstalledManagerTest extends TestCase implements Injector {
|
||||
.subscribe(new Action1<Book>() {
|
||||
@Override
|
||||
public void call(Book book) {
|
||||
if (!iM.isInstalled(book)) {
|
||||
foundMismatch.set(true);
|
||||
// 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());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that we can remove a book. Currently this test is neutered until I can fix
|
||||
* issues with @link{getInstalledBooks}.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testRemoveBook() throws Exception {
|
||||
final AtomicBoolean isRemoved = new AtomicBoolean(false);
|
||||
getInstalledBooks()
|
||||
@ -96,9 +171,23 @@ public class InstalledManagerTest extends TestCase implements Injector {
|
||||
@Override
|
||||
public void call(Book book) {
|
||||
iM.removeBook(book);
|
||||
isRemoved.set(!book.getDriver().isDeletable(book));
|
||||
|
||||
// The AbstractBook returns false all the time, make sure we have
|
||||
// an actual implementation
|
||||
Log.w("testRemoveBook", book.getInitials());
|
||||
isRemoved.set(!book.getDriver().isDeletable(book) &&
|
||||
book instanceof SwordBook);
|
||||
}
|
||||
}, new Action1<Throwable>() {
|
||||
@Override
|
||||
public void call(Throwable throwable) {
|
||||
fail(throwable.getLocalizedMessage());
|
||||
}
|
||||
}, new Action0() {
|
||||
@Override
|
||||
public void call() {
|
||||
assertTrue(isRemoved.get());
|
||||
}
|
||||
});
|
||||
assertTrue(isRemoved.get());
|
||||
}
|
||||
}
|
@ -14,6 +14,8 @@ import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import rx.Observable;
|
||||
|
||||
/**
|
||||
* Manager to keep track of which books have been installed
|
||||
*/
|
||||
@ -28,6 +30,7 @@ public class InstalledManager implements BooksListener {
|
||||
@Inject
|
||||
InstalledManager(Injector injector) {
|
||||
injector.inject(this);
|
||||
installedBooksList.addAll(installedBooks.getBooks());
|
||||
installedBooks.addBooksListener(this);
|
||||
}
|
||||
|
||||
@ -35,6 +38,12 @@ public class InstalledManager implements BooksListener {
|
||||
return installedBooksList.contains(b);
|
||||
}
|
||||
|
||||
public Observable<Book> getInstalledBooks() {
|
||||
// This method is needed to provide a fresher copy of what's installed
|
||||
// than Books.getInstalled() does.
|
||||
return Observable.from(installedBooksList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bookAdded(BooksEvent booksEvent) {
|
||||
Log.d(TAG, "Book added: " + booksEvent.getBook().toString());
|
||||
@ -54,16 +63,13 @@ public class InstalledManager implements BooksListener {
|
||||
}
|
||||
|
||||
public void removeBook(Book b) {
|
||||
// Not sure why we need to call this multiple times, but...
|
||||
while (Books.installed().getBooks().contains(b)) {
|
||||
try {
|
||||
// This worked in the past, but isn't now...
|
||||
// installedBooks.remove(b);
|
||||
Book realBook = installedBooks.getBook(b.getInitials());
|
||||
b.getDriver().delete(realBook);
|
||||
} catch (BookException e) {
|
||||
Log.e("InstalledManager", "Unable to remove book (already uninstalled?): " + e.getLocalizedMessage());
|
||||
}
|
||||
try {
|
||||
// This worked in the past, but isn't now...
|
||||
// installedBooks.remove(b);
|
||||
Book realBook = installedBooks.getBook(b.getInitials());
|
||||
b.getDriver().delete(realBook);
|
||||
} catch (BookException e) {
|
||||
Log.e("InstalledManager", "Unable to remove book (already uninstalled?): " + e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,9 @@ public class RefreshManager {
|
||||
/**
|
||||
* Do the work of kicking off the AsyncTask to refresh books, and make sure we know
|
||||
* when it's done.
|
||||
* TODO: Should I have a better way of scheduling than Schedulers.io()?
|
||||
* NOTE: This code assigns its own thread. This is because we are called privately, and
|
||||
* don't want to expose this method. I don't like hiding the side effects like this, but
|
||||
* in this case I'm making an exception.
|
||||
*/
|
||||
private Observable<Map<Installer, List<Book>>> refreshModules() {
|
||||
if (availableModules == null) {
|
||||
|
Loading…
Reference in New Issue
Block a user