mirror of
				https://github.com/MinimalBible/MinimalBible
				synced 2025-11-04 02:20:26 -05:00 
			
		
		
		
	Handle no books installed on start properly.
This commit is contained in:
		@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					package org.bspeice.minimalbible.test.activity.viewer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import android.test.ActivityInstrumentationTestCase2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.bspeice.minimalbible.Modules;
 | 
				
			||||||
 | 
					import org.bspeice.minimalbible.activity.viewer.BibleViewer;
 | 
				
			||||||
 | 
					import org.bspeice.minimalbible.activity.viewer.BookManager;
 | 
				
			||||||
 | 
					import org.crosswire.jsword.book.Book;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import rx.Observable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.mockito.Mockito.mock;
 | 
				
			||||||
 | 
					import static org.mockito.Mockito.when;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class BibleViewerTest extends ActivityInstrumentationTestCase2<BibleViewer> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public BibleViewerTest() {
 | 
				
			||||||
 | 
					        super(BibleViewer.class);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void setUp() {
 | 
				
			||||||
 | 
					        // For some reason this test requires us to set the dexcache...
 | 
				
			||||||
 | 
					        System.setProperty("dexmaker.dexcache", getInstrumentation().getTargetContext()
 | 
				
			||||||
 | 
					                .getCacheDir().toString());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * It may happen to be the case that we start and there are no installed books.
 | 
				
			||||||
 | 
					     * This likely triggers a runtime exception from Rx, and is no excuse for dying.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public void testInitializationNoInstalledBooks() {
 | 
				
			||||||
 | 
					        BookManager mockBookManager = mock(BookManager.class);
 | 
				
			||||||
 | 
					        when(mockBookManager.getInstalledBooks()).thenReturn(
 | 
				
			||||||
 | 
					                Observable.from(new ArrayList<Book>()));
 | 
				
			||||||
 | 
					        Modules.testModules.setBookManager(mockBookManager);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertNotNull(getActivity());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -25,6 +25,7 @@ import javax.inject.Inject;
 | 
				
			|||||||
import dagger.ObjectGraph;
 | 
					import dagger.ObjectGraph;
 | 
				
			||||||
import rx.android.schedulers.AndroidSchedulers;
 | 
					import rx.android.schedulers.AndroidSchedulers;
 | 
				
			||||||
import rx.functions.Action1;
 | 
					import rx.functions.Action1;
 | 
				
			||||||
 | 
					import rx.functions.Func1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class BibleViewer extends BaseActivity implements
 | 
					public class BibleViewer extends BaseActivity implements
 | 
				
			||||||
        NavDrawerFragment.NavigationDrawerCallbacks,
 | 
					        NavDrawerFragment.NavigationDrawerCallbacks,
 | 
				
			||||||
@ -66,35 +67,42 @@ public class BibleViewer extends BaseActivity implements
 | 
				
			|||||||
        bvObjectGraph.inject(o);
 | 
					        bvObjectGraph.inject(o);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
					    /**
 | 
				
			||||||
 | 
					     * Set up the application
 | 
				
			||||||
 | 
					     * TODO: Get the main book, rather than the first installed book.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param savedInstanceState Android's savedInstanceState
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
	protected void onCreate(Bundle savedInstanceState) {
 | 
						protected void onCreate(Bundle savedInstanceState) {
 | 
				
			||||||
		super.onCreate(savedInstanceState);
 | 
							super.onCreate(savedInstanceState);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.inject(this);
 | 
					        this.inject(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // If no books are installed, we need to download one first.
 | 
					        // If no books are installed, we need to download one first. However,
 | 
				
			||||||
        int count = bookManager.getInstalledBooks()
 | 
					        // RxJava will error if there's nothing installed.
 | 
				
			||||||
                .count()
 | 
					        bookManager.getInstalledBooks()
 | 
				
			||||||
                .toBlocking()
 | 
					                .first()
 | 
				
			||||||
                .last();
 | 
					                .onErrorReturn(new Func1<Throwable, Book>() {
 | 
				
			||||||
        if (count <= 0) {
 | 
					                    @Override
 | 
				
			||||||
            Intent i = new Intent(this, DownloadActivity.class);
 | 
					                    public Book call(Throwable throwable) {
 | 
				
			||||||
            startActivityForResult(i, 0);
 | 
					                        // If there are no books installed...
 | 
				
			||||||
            finish();
 | 
					                        Log.e(getLocalClassName(), "No books are currently installed, starting DownloadManager");
 | 
				
			||||||
        } else {
 | 
					                        Intent i = new Intent(BibleViewer.this, DownloadActivity.class);
 | 
				
			||||||
            bookManager.getInstalledBooks()
 | 
					                        startActivityForResult(i, 0);
 | 
				
			||||||
                    .first()
 | 
					                        finish();
 | 
				
			||||||
                    .subscribeOn(AndroidSchedulers.mainThread())
 | 
					                        return null;
 | 
				
			||||||
                    .subscribe(new Action1<Book>() {
 | 
					                    }
 | 
				
			||||||
                        @Override
 | 
					                })
 | 
				
			||||||
                        public void call(Book book) {
 | 
					                .subscribeOn(AndroidSchedulers.mainThread())
 | 
				
			||||||
                            Log.d("BibleViewer", "Subscribed to display book: " + book.getName());
 | 
					                .subscribe(new Action1<Book>() {
 | 
				
			||||||
                            displayMainBook(book);
 | 
					                    @Override
 | 
				
			||||||
                        }
 | 
					                    public void call(Book book) {
 | 
				
			||||||
                    });
 | 
					                        Log.e("BibleViewer", "Subscribed to display book: " + book.getName());
 | 
				
			||||||
        }
 | 
					                        displayMainBook(book);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
		setContentView(R.layout.activity_bible_viewer);
 | 
					                });
 | 
				
			||||||
 | 
					        setContentView(R.layout.activity_bible_viewer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mNavigationDrawerFragment = (ExpListNavDrawerFragment) getSupportFragmentManager()
 | 
					        mNavigationDrawerFragment = (ExpListNavDrawerFragment) getSupportFragmentManager()
 | 
				
			||||||
                .findFragmentById(R.id.navigation_drawer);
 | 
					                .findFragmentById(R.id.navigation_drawer);
 | 
				
			||||||
 | 
				
			|||||||
@ -2,13 +2,12 @@ package org.bspeice.minimalbible.activity.viewer;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import android.util.Log;
 | 
					import android.util.Log;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.google.gson.Gson;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import org.bspeice.minimalbible.activity.navigation.ExpListNavAdapter;
 | 
					import org.bspeice.minimalbible.activity.navigation.ExpListNavAdapter;
 | 
				
			||||||
import org.bspeice.minimalbible.activity.viewer.bookutil.VersificationUtil;
 | 
					import org.bspeice.minimalbible.activity.viewer.bookutil.VersificationUtil;
 | 
				
			||||||
import org.bspeice.minimalbible.service.book.VerseLookupModules;
 | 
					import org.bspeice.minimalbible.service.book.VerseLookupModules;
 | 
				
			||||||
import org.crosswire.jsword.book.Book;
 | 
					import org.crosswire.jsword.book.Book;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.NoSuchElementException;
 | 
				
			||||||
import java.util.concurrent.atomic.AtomicReference;
 | 
					import java.util.concurrent.atomic.AtomicReference;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.inject.Named;
 | 
					import javax.inject.Named;
 | 
				
			||||||
@ -69,13 +68,25 @@ public class BibleViewerModules {
 | 
				
			|||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (mBook.get() == null) {
 | 
					        if (mBook.get() == null) {
 | 
				
			||||||
            Book fallback;
 | 
					            try {
 | 
				
			||||||
            fallback = bookManager.getInstalledBooks()
 | 
					                Book fallback;
 | 
				
			||||||
                    .toBlocking().first();
 | 
					                fallback = bookManager.getInstalledBooks()
 | 
				
			||||||
 | 
					                        .onErrorReturn(new Func1<Throwable, Book>() {
 | 
				
			||||||
            prefs.defaultBookName(fallback.getName());
 | 
					                            @Override
 | 
				
			||||||
            return fallback;
 | 
					                            public Book call(Throwable throwable) {
 | 
				
			||||||
 | 
					                                // If there's no book installed, we can't select the main one...
 | 
				
			||||||
 | 
					                                return null;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        })
 | 
				
			||||||
 | 
					                        .toBlocking().first();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                prefs.defaultBookName(fallback.getName());
 | 
				
			||||||
 | 
					                return fallback;
 | 
				
			||||||
 | 
					            } catch (NoSuchElementException e) {
 | 
				
			||||||
 | 
					                // If no books are installed, there's really nothing we can do...
 | 
				
			||||||
 | 
					                Log.d("BibleViewerModules", "No books are installed, so can't select a main book.");
 | 
				
			||||||
 | 
					                return null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            return mBook.get();
 | 
					            return mBook.get();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -58,46 +58,52 @@ public class ExpListNavDrawerFragment extends NavDrawerFragment {
 | 
				
			|||||||
                });
 | 
					                });
 | 
				
			||||||
        */
 | 
					        */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        List<String> bibleBooks = vUtil.getBookNames(mainBook)
 | 
					        List<String> bibleBooks;
 | 
				
			||||||
                .toList().toBlocking().first();
 | 
					        if (mainBook != null) {
 | 
				
			||||||
 | 
					            bibleBooks = vUtil.getBookNames(mainBook)
 | 
				
			||||||
 | 
					                    .toList().toBlocking().first();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            bibleBooks = new ArrayList<String>();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // I really don't like how we build the chapters, but I'm not adding Guava just for Range.
 | 
					        // I really don't like how we build the chapters, but I'm not adding Guava just for Range.
 | 
				
			||||||
        // RXJava does get ridiculous with the angle brackets, you have me there. But Intellij
 | 
					        // RXJava does get ridiculous with the angle brackets, you have me there. But Intellij
 | 
				
			||||||
        // folds nicely.
 | 
					        // folds nicely.
 | 
				
			||||||
        Map<String, List<Integer>> chapterMap =
 | 
					        Map<String, List<Integer>> chapterMap = new HashMap<String, List<Integer>>();
 | 
				
			||||||
                vUtil.getBooks(mainBook).map(new Func1<BibleBook, Map<String, List<Integer>>>() {
 | 
					        if (mainBook != null) {
 | 
				
			||||||
                    @Override
 | 
					            vUtil.getBooks(mainBook).map(new Func1<BibleBook, Map<String, List<Integer>>>() {
 | 
				
			||||||
                    public Map<String, List<Integer>> call(BibleBook bibleBook) {
 | 
					                @Override
 | 
				
			||||||
                        // These lines are important
 | 
					                public Map<String, List<Integer>> call(BibleBook bibleBook) {
 | 
				
			||||||
                        int bookCount = vUtil.getChapterCount(mainBook, bibleBook);
 | 
					                    // These lines are important
 | 
				
			||||||
                        List<Integer> chapterList = new ArrayList<Integer>(bookCount);
 | 
					                    int bookCount = vUtil.getChapterCount(mainBook, bibleBook);
 | 
				
			||||||
                        for (int i = 0; i < bookCount; i++) {
 | 
					                    List<Integer> chapterList = new ArrayList<Integer>(bookCount);
 | 
				
			||||||
                            chapterList.add(i + 1); // Index to chapter number
 | 
					                    for (int i = 0; i < bookCount; i++) {
 | 
				
			||||||
                        }
 | 
					                        chapterList.add(i + 1); // Index to chapter number
 | 
				
			||||||
                        // </important>
 | 
					 | 
				
			||||||
                        Map<String, List<Integer>> bookListMap =
 | 
					 | 
				
			||||||
                                new HashMap<String, List<Integer>>(1);
 | 
					 | 
				
			||||||
                        bookListMap.put(vUtil.getBookName(mainBook, bibleBook), chapterList);
 | 
					 | 
				
			||||||
                        return bookListMap;
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                })
 | 
					                    // </important>
 | 
				
			||||||
                        .reduce(new Func2<Map<String, List<Integer>>,
 | 
					                    Map<String, List<Integer>> bookListMap =
 | 
				
			||||||
                                Map<String, List<Integer>>,
 | 
					                            new HashMap<String, List<Integer>>(1);
 | 
				
			||||||
                                Map<String, List<Integer>>>() {
 | 
					                    bookListMap.put(vUtil.getBookName(mainBook, bibleBook), chapterList);
 | 
				
			||||||
                            @Override
 | 
					                    return bookListMap;
 | 
				
			||||||
                            public Map<String, List<Integer>>
 | 
					                }
 | 
				
			||||||
                            call(Map<String, List<Integer>> acc,
 | 
					            })
 | 
				
			||||||
                                 Map<String, List<Integer>> value) {
 | 
					                    .reduce(new Func2<Map<String, List<Integer>>,
 | 
				
			||||||
                                // These lines are important
 | 
					                            Map<String, List<Integer>>,
 | 
				
			||||||
                                acc.putAll(value);
 | 
					                            Map<String, List<Integer>>>() {
 | 
				
			||||||
                                return acc;
 | 
					                        @Override
 | 
				
			||||||
                                // </important>
 | 
					                        public Map<String, List<Integer>>
 | 
				
			||||||
                            }
 | 
					                        call(Map<String, List<Integer>> acc,
 | 
				
			||||||
                        })
 | 
					                             Map<String, List<Integer>> value) {
 | 
				
			||||||
                        .toBlocking()
 | 
					                            // These lines are important
 | 
				
			||||||
                        .first();
 | 
					                            acc.putAll(value);
 | 
				
			||||||
 | 
					                            return acc;
 | 
				
			||||||
 | 
					                            // </important>
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    })
 | 
				
			||||||
 | 
					                    .toBlocking()
 | 
				
			||||||
 | 
					                    .first();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ExpListNavAdapter<String, Integer> adapter =
 | 
					        ExpListNavAdapter<String, Integer> adapter =
 | 
				
			||||||
                new ExpListNavAdapter<String, Integer>(bibleBooks, chapterMap);
 | 
					                new ExpListNavAdapter<String, Integer>(bibleBooks, chapterMap);
 | 
				
			||||||
 | 
				
			|||||||
@ -6,12 +6,14 @@ package org.bspeice.minimalbible;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class Modules {
 | 
					public class Modules {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static TestModules testModules = new TestModules();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private Modules() {}
 | 
					    private Modules() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static Object[] list(MinimalBible app) {
 | 
					    public static Object[] list(MinimalBible app) {
 | 
				
			||||||
        return new Object[] {
 | 
					        return new Object[] {
 | 
				
			||||||
                new MinimalBibleModules(app),
 | 
					                new MinimalBibleModules(app),
 | 
				
			||||||
                new TestModules()
 | 
					                testModules
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ package org.bspeice.minimalbible;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.bspeice.minimalbible.activity.downloader.DownloadActivity;
 | 
					import org.bspeice.minimalbible.activity.downloader.DownloadActivity;
 | 
				
			||||||
 | 
					import org.bspeice.minimalbible.activity.viewer.BookManager;
 | 
				
			||||||
import org.crosswire.jsword.book.BookCategory;
 | 
					import org.crosswire.jsword.book.BookCategory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
@ -22,7 +23,10 @@ import dagger.Provides;
 | 
				
			|||||||
public class TestModules {
 | 
					public class TestModules {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static CharSequence testActivityTitle = "Test";
 | 
					    public static CharSequence testActivityTitle = "Test";
 | 
				
			||||||
    @Provides CharSequence provideString() {
 | 
					    private BookManager bookManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Provides
 | 
				
			||||||
 | 
					    CharSequence provideString() {
 | 
				
			||||||
        return testActivityTitle;
 | 
					        return testActivityTitle;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -36,4 +40,13 @@ public class TestModules {
 | 
				
			|||||||
            add(BookCategory.MAPS);
 | 
					            add(BookCategory.MAPS);
 | 
				
			||||||
        }};
 | 
					        }};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void setBookManager(BookManager bookManager) {
 | 
				
			||||||
 | 
					        this.bookManager = bookManager;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Provides
 | 
				
			||||||
 | 
					    BookManager provideBookManager() {
 | 
				
			||||||
 | 
					        return bookManager;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user