diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 73870258b0..4c2d5e7209 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -46,6 +46,9 @@ + + diff --git a/app/src/main/java/eu/kanade/mangafeed/data/helpers/DownloadManager.java b/app/src/main/java/eu/kanade/mangafeed/data/helpers/DownloadManager.java new file mode 100644 index 0000000000..fe3badc8d8 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/data/helpers/DownloadManager.java @@ -0,0 +1,128 @@ +package eu.kanade.mangafeed.data.helpers; + +import android.content.Context; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import eu.kanade.mangafeed.data.models.Chapter; +import eu.kanade.mangafeed.data.models.Manga; +import eu.kanade.mangafeed.data.models.Page; +import eu.kanade.mangafeed.events.DownloadChapterEvent; +import eu.kanade.mangafeed.sources.base.Source; +import eu.kanade.mangafeed.util.DiskUtils; +import rx.Observable; +import rx.Subscription; +import rx.schedulers.Schedulers; +import rx.subjects.PublishSubject; + +public class DownloadManager { + + private PublishSubject downloadsSubject; + private Subscription downloadsSubscription; + + private Context context; + private SourceManager sourceManager; + + public DownloadManager(Context context, SourceManager sourceManager) { + this.context = context; + this.sourceManager = sourceManager; + + initializeDownloadSubscription(); + } + + private void initializeDownloadSubscription() { + if (downloadsSubscription != null && !downloadsSubscription.isUnsubscribed()) { + downloadsSubscription.unsubscribe(); + } + + downloadsSubject = PublishSubject.create(); + + downloadsSubscription = downloadsSubject + .subscribeOn(Schedulers.io()) + .concatMap(event -> downloadChapter(event.getManga(), event.getChapter())) + .onBackpressureBuffer() + .subscribe(); + } + + private Observable downloadChapter(Manga manga, Chapter chapter) { + final Source source = sourceManager.get(manga.source); + final File chapterDirectory = new File(getDownloadsDirectory(), getChapterDirectory(chapter)); + + return source + .pullPageListFromNetwork(chapter.url) + // Ensure we don't download a chapter already downloaded + .filter(pages -> !isChapterDownloaded(chapterDirectory, pages)) + // Get all the URLs to the source images, fetch pages if necessary + .flatMap(pageList -> Observable.merge( + Observable.from(pageList).filter(page -> page.getImageUrl() != null), + source.getRemainingImageUrlsFromPageList(pageList))) + // Start downloading images + .flatMap(page -> getDownloadedImage(page, source, chapterDirectory)); + } + + private File getDownloadsDirectory() { + // TODO + return new File(DiskUtils.getStorageDirectories(context)[0]); + } + + private String getChapterDirectory(Chapter chapter) { + return chapter.name.replaceAll("[^a-zA-Z0-9.-]", "_"); + } + + private String getImageFilename(Page page) { + return page.getImageUrl().substring( + page.getImageUrl().lastIndexOf("/") + 1, + page.getImageUrl().length()); + } + + private boolean isChapterDownloaded(File chapterDir, List pages) { + return chapterDir.exists() && chapterDir.listFiles().length == pages.size(); + } + + private boolean isImageDownloaded(File imagePath) { + return imagePath.exists() && !imagePath.isDirectory(); + } + + public Observable getDownloadedImage(final Page page, Source source, File chapterDir) { + Observable obs = Observable.just(page); + if (page.getImageUrl() == null) + return obs; + + String imageFilename = getImageFilename(page); + File imagePath = new File(chapterDir, imageFilename); + + if (!isImageDownloaded(imagePath)) { + page.setStatus(Page.DOWNLOAD_IMAGE); + obs = downloadImage(page, source, chapterDir, imageFilename); + } + + return obs.flatMap(p -> { + page.setImagePath(imagePath.getAbsolutePath()); + page.setStatus(Page.READY); + return Observable.just(page); + }).onErrorResumeNext(e -> { + page.setStatus(Page.ERROR); + return Observable.just(page); + }); + } + + private Observable downloadImage(final Page page, Source source, File chapterDir, String imageFilename) { + return source.getImageProgressResponse(page) + .flatMap(resp -> { + try { + DiskUtils.saveBufferedSourceToDirectory(resp.body().source(), chapterDir, imageFilename); + } catch (IOException e) { + e.printStackTrace(); + throw new IllegalStateException("Unable to save image"); + } + return Observable.just(page); + }); + } + + public PublishSubject getDownloadsSubject() { + return downloadsSubject; + } + +} diff --git a/app/src/main/java/eu/kanade/mangafeed/data/helpers/PreferencesHelper.java b/app/src/main/java/eu/kanade/mangafeed/data/helpers/PreferencesHelper.java index cb73a99bff..51b400eec6 100644 --- a/app/src/main/java/eu/kanade/mangafeed/data/helpers/PreferencesHelper.java +++ b/app/src/main/java/eu/kanade/mangafeed/data/helpers/PreferencesHelper.java @@ -6,6 +6,7 @@ import android.preference.PreferenceManager; import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.sources.base.Source; +import eu.kanade.mangafeed.util.DiskUtils; public class PreferencesHelper { @@ -53,4 +54,9 @@ public class PreferencesHelper { .apply(); } + public String getDownloadsDirectory() { + return mPref.getString(getKey(R.string.pref_download_directory_key), + DiskUtils.getStorageDirectories(context)[0]); + } + } diff --git a/app/src/main/java/eu/kanade/mangafeed/data/services/DownloadService.java b/app/src/main/java/eu/kanade/mangafeed/data/services/DownloadService.java new file mode 100644 index 0000000000..f97873f17e --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/data/services/DownloadService.java @@ -0,0 +1,58 @@ +package eu.kanade.mangafeed.data.services; + +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.os.IBinder; + +import javax.inject.Inject; + +import de.greenrobot.event.EventBus; +import eu.kanade.mangafeed.App; +import eu.kanade.mangafeed.data.helpers.DownloadManager; +import eu.kanade.mangafeed.events.DownloadChapterEvent; +import eu.kanade.mangafeed.util.AndroidComponentUtil; +import eu.kanade.mangafeed.util.EventBusHook; + +public class DownloadService extends Service { + + @Inject DownloadManager downloadManager; + + public static Intent getStartIntent(Context context) { + return new Intent(context, DownloadService.class); + } + + public static boolean isRunning(Context context) { + return AndroidComponentUtil.isServiceRunning(context, DownloadService.class); + } + + @Override + public void onCreate() { + super.onCreate(); + App.get(this).getComponent().inject(this); + + EventBus.getDefault().register(this); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return START_STICKY; + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @EventBusHook + public void onEvent(DownloadChapterEvent event) { + downloadManager.getDownloadsSubject().onNext(event); + } + + @Override + public void onDestroy() { + EventBus.getDefault().unregister(this); + super.onDestroy(); + } + +} diff --git a/app/src/main/java/eu/kanade/mangafeed/events/DownloadChapterEvent.java b/app/src/main/java/eu/kanade/mangafeed/events/DownloadChapterEvent.java new file mode 100644 index 0000000000..4cc9352657 --- /dev/null +++ b/app/src/main/java/eu/kanade/mangafeed/events/DownloadChapterEvent.java @@ -0,0 +1,22 @@ +package eu.kanade.mangafeed.events; + +import eu.kanade.mangafeed.data.models.Chapter; +import eu.kanade.mangafeed.data.models.Manga; + +public class DownloadChapterEvent { + private Manga manga; + private Chapter chapter; + + public DownloadChapterEvent(Manga manga, Chapter chapter) { + this.manga = manga; + this.chapter = chapter; + } + + public Manga getManga() { + return manga; + } + + public Chapter getChapter() { + return chapter; + } +} diff --git a/app/src/main/java/eu/kanade/mangafeed/injection/component/AppComponent.java b/app/src/main/java/eu/kanade/mangafeed/injection/component/AppComponent.java index 90a117d18c..4cc52fc5d1 100644 --- a/app/src/main/java/eu/kanade/mangafeed/injection/component/AppComponent.java +++ b/app/src/main/java/eu/kanade/mangafeed/injection/component/AppComponent.java @@ -5,6 +5,7 @@ import android.app.Application; import javax.inject.Singleton; import dagger.Component; +import eu.kanade.mangafeed.data.services.DownloadService; import eu.kanade.mangafeed.data.services.LibraryUpdateService; import eu.kanade.mangafeed.injection.module.AppModule; import eu.kanade.mangafeed.injection.module.DataModule; @@ -42,6 +43,7 @@ public interface AppComponent { void inject(Source source); void inject(LibraryUpdateService libraryUpdateService); + void inject(DownloadService downloadService); Application application(); diff --git a/app/src/main/java/eu/kanade/mangafeed/injection/module/DataModule.java b/app/src/main/java/eu/kanade/mangafeed/injection/module/DataModule.java index b56b9f5db6..c98dfcbce7 100644 --- a/app/src/main/java/eu/kanade/mangafeed/injection/module/DataModule.java +++ b/app/src/main/java/eu/kanade/mangafeed/injection/module/DataModule.java @@ -8,11 +8,10 @@ import dagger.Module; import dagger.Provides; import eu.kanade.mangafeed.data.caches.CacheManager; import eu.kanade.mangafeed.data.helpers.DatabaseHelper; +import eu.kanade.mangafeed.data.helpers.DownloadManager; import eu.kanade.mangafeed.data.helpers.NetworkHelper; import eu.kanade.mangafeed.data.helpers.PreferencesHelper; import eu.kanade.mangafeed.data.helpers.SourceManager; -import rx.Scheduler; -import rx.schedulers.Schedulers; /** * Provide dependencies to the DataManager, mainly Helper classes and Retrofit services. @@ -32,12 +31,6 @@ public class DataModule { return new DatabaseHelper(app); } - @Provides - @Singleton - Scheduler provideSubscribeScheduler() { - return Schedulers.io(); - } - @Provides @Singleton CacheManager provideCacheManager(Application app) { @@ -56,4 +49,10 @@ public class DataModule { return new SourceManager(app); } + @Provides + @Singleton + DownloadManager provideDownloadManager(Application app, SourceManager sourceManager) { + return new DownloadManager(app, sourceManager); + } + } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java index ad83d3d0b6..6b85278553 100644 --- a/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java +++ b/app/src/main/java/eu/kanade/mangafeed/presenter/MangaChaptersPresenter.java @@ -85,6 +85,10 @@ public class MangaChaptersPresenter extends BasePresenter } } + public Manga getManga() { + return manga; + } + public void refreshChapters() { if (getView() != null) getView().setSwipeRefreshing(); diff --git a/app/src/main/java/eu/kanade/mangafeed/sources/base/Source.java b/app/src/main/java/eu/kanade/mangafeed/sources/base/Source.java index afd068b8c7..9005084f2d 100644 --- a/app/src/main/java/eu/kanade/mangafeed/sources/base/Source.java +++ b/app/src/main/java/eu/kanade/mangafeed/sources/base/Source.java @@ -4,6 +4,7 @@ package eu.kanade.mangafeed.sources.base; import android.content.Context; import com.squareup.okhttp.Headers; +import com.squareup.okhttp.Response; import java.util.ArrayList; import java.util.List; @@ -123,7 +124,7 @@ public abstract class Source extends BaseSource { } private Observable cacheImage(final Page page) { - return mNetworkService.getProgressResponse(page.getImageUrl(), mRequestHeaders, page) + return getImageProgressResponse(page) .flatMap(resp -> { if (!mCacheManager.putImageToDiskCache(page.getImageUrl(), resp)) { throw new IllegalStateException("Unable to save image"); @@ -132,6 +133,10 @@ public abstract class Source extends BaseSource { }); } + public Observable getImageProgressResponse(final Page page) { + return mNetworkService.getProgressResponse(page.getImageUrl(), mRequestHeaders, page); + } + public void savePageList(String chapterUrl, List pages) { if (pages != null) mCacheManager.putPageUrlsToDiskCache(chapterUrl, pages); diff --git a/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java b/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java index f2d94f7b91..0fb6d30e42 100644 --- a/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java +++ b/app/src/main/java/eu/kanade/mangafeed/ui/fragment/MangaChaptersFragment.java @@ -18,8 +18,11 @@ import java.util.List; import butterknife.Bind; import butterknife.ButterKnife; +import de.greenrobot.event.EventBus; import eu.kanade.mangafeed.R; import eu.kanade.mangafeed.data.models.Chapter; +import eu.kanade.mangafeed.data.services.DownloadService; +import eu.kanade.mangafeed.events.DownloadChapterEvent; import eu.kanade.mangafeed.presenter.MangaChaptersPresenter; import eu.kanade.mangafeed.ui.activity.MangaDetailActivity; import eu.kanade.mangafeed.ui.activity.ReaderActivity; @@ -28,6 +31,8 @@ import eu.kanade.mangafeed.ui.adapter.ChaptersAdapter; import eu.kanade.mangafeed.ui.fragment.base.BaseRxFragment; import nucleus.factory.RequiresPresenter; import rx.Observable; +import rx.Subscription; +import rx.schedulers.Schedulers; @RequiresPresenter(MangaChaptersPresenter.class) public class MangaChaptersFragment extends BaseRxFragment implements @@ -39,6 +44,7 @@ public class MangaChaptersFragment extends BaseRxFragment { + EventBus.getDefault().post( + new DownloadChapterEvent(getPresenter().getManga(), chapter)); + downloadSubscription.unsubscribe(); + }); + } + } diff --git a/app/src/main/java/eu/kanade/mangafeed/util/DiskUtils.java b/app/src/main/java/eu/kanade/mangafeed/util/DiskUtils.java index c91593e7f3..a30ccfb3c4 100644 --- a/app/src/main/java/eu/kanade/mangafeed/util/DiskUtils.java +++ b/app/src/main/java/eu/kanade/mangafeed/util/DiskUtils.java @@ -18,7 +18,7 @@ import okio.BufferedSource; import okio.Okio; public final class DiskUtils { - private static final Pattern DIR_SEPORATOR = Pattern.compile("/"); + private static final Pattern DIR_SEPARATOR = Pattern.compile("/"); private DiskUtils() { throw new AssertionError(); @@ -58,7 +58,7 @@ public final class DiskUtils { rawUserId = ""; } else { final String path = Environment.getExternalStorageDirectory().getAbsolutePath(); - final String[] folders = DIR_SEPORATOR.split(path); + final String[] folders = DIR_SEPARATOR.split(path); final String lastFolder = folders[folders.length - 1]; boolean isDigit = false; @@ -114,18 +114,17 @@ public final class DiskUtils { return sb.toString(); } - public static File saveBufferedSourceToDirectory(BufferedSource bufferedSource, String directory, String name) throws IOException { - File fileDirectory = new File(directory); - if (!fileDirectory.exists()) { - if (!fileDirectory.mkdirs()) { + public static File saveBufferedSourceToDirectory(BufferedSource bufferedSource, File directory, String name) throws IOException { + if (!directory.exists()) { + if (!directory.mkdirs()) { throw new IOException("Failed Creating Directory"); } } - File writeFile = new File(fileDirectory, name); + File writeFile = new File(directory, name); if (writeFile.exists()) { if (writeFile.delete()) { - writeFile = new File(fileDirectory, name); + writeFile = new File(directory, name); } else { throw new IOException("Failed Deleting Existing File for Overwrite"); } diff --git a/app/src/main/res/drawable-hdpi/ic_file_download.png b/app/src/main/res/drawable-hdpi/ic_file_download.png new file mode 100644 index 0000000000..a1714bc050 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_file_download.png differ diff --git a/app/src/main/res/drawable-ldpi/ic_file_download.png b/app/src/main/res/drawable-ldpi/ic_file_download.png new file mode 100644 index 0000000000..be2b7d3b9a Binary files /dev/null and b/app/src/main/res/drawable-ldpi/ic_file_download.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_file_download.png b/app/src/main/res/drawable-mdpi/ic_file_download.png new file mode 100644 index 0000000000..5cf7333355 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_file_download.png differ diff --git a/app/src/main/res/drawable-tvdpi/ic_file_download.png b/app/src/main/res/drawable-tvdpi/ic_file_download.png new file mode 100644 index 0000000000..dd0db5bd97 Binary files /dev/null and b/app/src/main/res/drawable-tvdpi/ic_file_download.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_file_download.png b/app/src/main/res/drawable-xhdpi/ic_file_download.png new file mode 100644 index 0000000000..c9843ba8a2 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_file_download.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_file_download.png b/app/src/main/res/drawable-xxhdpi/ic_file_download.png new file mode 100644 index 0000000000..ea828d089a Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_file_download.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_file_download.png b/app/src/main/res/drawable-xxxhdpi/ic_file_download.png new file mode 100644 index 0000000000..0f286755cd Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_file_download.png differ diff --git a/app/src/main/res/menu/chapter_selection.xml b/app/src/main/res/menu/chapter_selection.xml index 8c435ef842..ce8a808cd5 100644 --- a/app/src/main/res/menu/chapter_selection.xml +++ b/app/src/main/res/menu/chapter_selection.xml @@ -3,6 +3,11 @@ + + pref_category_accounts_key pref_fullscreen_key pref_default_viewer_key + pref_download_directory_key \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e8ab12505d..af17e20169 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -86,6 +86,7 @@ Update completed No new chapters found Found new chapters for: + Download diff --git a/app/src/test/java/eu/kanade/mangafeed/BatotoTest.java b/app/src/test/java/eu/kanade/mangafeed/BatotoTest.java deleted file mode 100644 index 669e1afdef..0000000000 --- a/app/src/test/java/eu/kanade/mangafeed/BatotoTest.java +++ /dev/null @@ -1,85 +0,0 @@ -package eu.kanade.mangafeed; - -import android.os.Build; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -import java.util.List; - -import eu.kanade.mangafeed.data.caches.CacheManager; -import eu.kanade.mangafeed.data.helpers.NetworkHelper; -import eu.kanade.mangafeed.data.models.Chapter; -import eu.kanade.mangafeed.data.models.Manga; -import eu.kanade.mangafeed.sources.Batoto; -import eu.kanade.mangafeed.sources.base.Source; - -@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP) -@RunWith(RobolectricGradleTestRunner.class) -public class BatotoTest { - - NetworkHelper net; - CacheManager cache; - Source b; - final String chapterUrl ="http://bato.to/read/_/345144/minamoto-kun-monogatari_ch178_by_vortex-scans"; - final String mangaUrl = "http://bato.to/comic/_/comics/natsuzora-and-run-r9597"; - final String mangaUrl2 = "http://bato.to/comic/_/comics/bungaku-shoujo-to-shinitagari-no-pierrot-r534"; - final String nisekoiUrl = "http://bato.to/comic/_/comics/nisekoi-r951"; - - @Before - public void setUp() { - net = new NetworkHelper(); - cache = new CacheManager(RuntimeEnvironment.application.getApplicationContext()); - b = new Batoto(net, cache); - } - - @Test - public void testImageList() { - List imageUrls = b.getRemainingImageUrlsFromPageList(chapterUrl) - .toList().toBlocking().single(); - - Assert.assertTrue(imageUrls.size() > 5); - } - - @Test - public void testMangaList() { - List mangaList = b.pullPopularMangasFromNetwork(1) - .toBlocking().first(); - - Manga m = mangaList.get(0); - Assert.assertNotNull(m.title); - Assert.assertNotNull(m.artist); - Assert.assertNotNull(m.author); - Assert.assertNotNull(m.url); - - Assert.assertTrue(mangaList.size() > 25); - } - - @Test - public void testChapterList() { - List mangaList = b.pullChaptersFromNetwork(mangaUrl) - .toBlocking().first(); - - Assert.assertTrue(mangaList.size() > 5); - } - - @Test - public void testMangaDetails() { - Manga nisekoi = b.pullMangaFromNetwork(nisekoiUrl) - .toBlocking().single(); - - Assert.assertEquals("Nisekoi", nisekoi.title); - Assert.assertEquals("Komi Naoshi", nisekoi.author); - Assert.assertEquals("Komi Naoshi", nisekoi.artist); - Assert.assertEquals("http://bato.to/comic/_/nisekoi-r951", nisekoi.url); - Assert.assertEquals("http://img.bato.to/forums/uploads/a2a850c644a50bccc462f36922c1cbf2.jpg", nisekoi.thumbnail_url); - Assert.assertTrue(nisekoi.description.length() > 20); - Assert.assertTrue(nisekoi.genre.length() > 20); - } -} diff --git a/app/src/test/java/eu/kanade/mangafeed/MangahereTest.java b/app/src/test/java/eu/kanade/mangafeed/MangahereTest.java deleted file mode 100644 index 49b06c7d86..0000000000 --- a/app/src/test/java/eu/kanade/mangafeed/MangahereTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package eu.kanade.mangafeed; - -import android.os.Build; - -import junit.framework.Assert; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricGradleTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -import java.util.List; - -import eu.kanade.mangafeed.data.caches.CacheManager; -import eu.kanade.mangafeed.data.helpers.NetworkHelper; -import eu.kanade.mangafeed.data.models.Chapter; -import eu.kanade.mangafeed.data.models.Manga; -import eu.kanade.mangafeed.sources.MangaHere; -import eu.kanade.mangafeed.sources.base.Source; - -@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP) -@RunWith(RobolectricGradleTestRunner.class) -public class MangahereTest { - - NetworkHelper net; - CacheManager cache; - Source b; - final String chapterUrl ="http://www.mangahere.co/manga/kimi_ni_todoke/v15/c099/"; - final String mangaUrl = "http://www.mangahere.co/manga/kimi_ni_todoke/"; - - @Before - public void setUp() { - net = new NetworkHelper(); - cache = new CacheManager(RuntimeEnvironment.application.getApplicationContext()); - b = new MangaHere(net, cache); - } - - @Test - public void testImageList() { - List imageUrls = b.getRemainingImageUrlsFromPageList(chapterUrl) - .toList().toBlocking().single(); - - Assert.assertTrue(imageUrls.size() > 5); - } - - @Test - public void testMangaList() { - List mangaList = b.pullPopularMangasFromNetwork(1) - .toBlocking().first(); - - Manga m = mangaList.get(0); - Assert.assertNotNull(m.title); - Assert.assertNotNull(m.url); - - Assert.assertTrue(mangaList.size() > 25); - } - - @Test - public void testChapterList() { - List mangaList = b.pullChaptersFromNetwork(mangaUrl) - .toBlocking().first(); - - Assert.assertTrue(mangaList.size() > 5); - } - - @Test - public void testMangaDetails() { - Manga manga = b.pullMangaFromNetwork(mangaUrl) - .toBlocking().single(); - - Assert.assertEquals("Shiina Karuho", manga.author); - Assert.assertEquals("Shiina Karuho", manga.artist); - Assert.assertEquals("http://www.mangahere.co/manga/kimi_ni_todoke/", manga.url); - Assert.assertEquals("http://a.mhcdn.net/store/manga/4999/cover.jpg?v=1433950383", manga.thumbnail_url); - Assert.assertTrue(manga.description.length() > 20); - Assert.assertTrue(manga.genre.length() > 20); - } -}