Fix tests

This commit is contained in:
len 2016-06-14 15:17:44 +02:00
parent 237af4b07d
commit eed295587d
9 changed files with 815 additions and 834 deletions

View file

@ -1,573 +0,0 @@
package eu.kanade.tachiyomi;
import android.app.Application;
import android.os.Build;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.ArrayList;
import java.util.List;
import eu.kanade.tachiyomi.data.backup.BackupManager;
import eu.kanade.tachiyomi.data.database.DatabaseHelper;
import eu.kanade.tachiyomi.data.database.models.Category;
import eu.kanade.tachiyomi.data.database.models.Chapter;
import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.database.models.MangaCategory;
import eu.kanade.tachiyomi.data.database.models.MangaSync;
import static org.assertj.core.api.Assertions.assertThat;
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
@RunWith(CustomRobolectricGradleTestRunner.class)
public class BackupTest {
DatabaseHelper db;
BackupManager backupManager;
Gson gson;
JsonObject root;
@Before
public void setup() {
Application app = RuntimeEnvironment.application;
db = new DatabaseHelper(app);
backupManager = new BackupManager(db);
gson = new Gson();
root = new JsonObject();
}
@Test
public void testRestoreCategory() {
String catName = "cat";
root = createRootJson(null, toJson(createCategories(catName)));
backupManager.restoreFromJson(root);
List<Category> dbCats = db.getCategories().executeAsBlocking();
assertThat(dbCats).hasSize(1);
assertThat(dbCats.get(0).name).isEqualTo(catName);
}
@Test
public void testRestoreEmptyCategory() {
root = createRootJson(null, toJson(new ArrayList<>()));
backupManager.restoreFromJson(root);
List<Category> dbCats = db.getCategories().executeAsBlocking();
assertThat(dbCats).isEmpty();
}
@Test
public void testRestoreExistingCategory() {
String catName = "cat";
db.insertCategory(createCategory(catName)).executeAsBlocking();
root = createRootJson(null, toJson(createCategories(catName)));
backupManager.restoreFromJson(root);
List<Category> dbCats = db.getCategories().executeAsBlocking();
assertThat(dbCats).hasSize(1);
assertThat(dbCats.get(0).name).isEqualTo(catName);
}
@Test
public void testRestoreCategories() {
root = createRootJson(null, toJson(createCategories("cat", "cat2", "cat3")));
backupManager.restoreFromJson(root);
List<Category> dbCats = db.getCategories().executeAsBlocking();
assertThat(dbCats).hasSize(3);
}
@Test
public void testRestoreExistingCategories() {
db.insertCategories(createCategories("cat", "cat2")).executeAsBlocking();
root = createRootJson(null, toJson(createCategories("cat", "cat2", "cat3")));
backupManager.restoreFromJson(root);
List<Category> dbCats = db.getCategories().executeAsBlocking();
assertThat(dbCats).hasSize(3);
}
@Test
public void testRestoreExistingCategoriesAlt() {
db.insertCategories(createCategories("cat", "cat2", "cat3")).executeAsBlocking();
root = createRootJson(null, toJson(createCategories("cat", "cat2")));
backupManager.restoreFromJson(root);
List<Category> dbCats = db.getCategories().executeAsBlocking();
assertThat(dbCats).hasSize(3);
}
@Test
public void testRestoreManga() {
String mangaName = "title";
List<Manga> mangas = createMangas(mangaName);
List<JsonElement> elements = new ArrayList<>();
for (Manga manga : mangas) {
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
elements.add(entry);
}
root = createRootJson(toJson(elements), null);
backupManager.restoreFromJson(root);
List<Manga> dbMangas = db.getMangas().executeAsBlocking();
assertThat(dbMangas).hasSize(1);
assertThat(dbMangas.get(0).title).isEqualTo(mangaName);
}
@Test
public void testRestoreExistingManga() {
String mangaName = "title";
Manga manga = createManga(mangaName);
db.insertManga(manga).executeAsBlocking();
List<JsonElement> elements = new ArrayList<>();
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
elements.add(entry);
root = createRootJson(toJson(elements), null);
backupManager.restoreFromJson(root);
List<Manga> dbMangas = db.getMangas().executeAsBlocking();
assertThat(dbMangas).hasSize(1);
}
@Test
public void testRestoreExistingMangaWithUpdatedFields() {
// Store a manga in db
String mangaName = "title";
String updatedThumbnailUrl = "updated thumbnail url";
Manga manga = createManga(mangaName);
manga.chapter_flags = 1024;
manga.thumbnail_url = updatedThumbnailUrl;
db.insertManga(manga).executeAsBlocking();
// Add an entry for a new manga with different attributes
manga = createManga(mangaName);
manga.chapter_flags = 512;
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
// Append the entry to the backup list
List<JsonElement> elements = new ArrayList<>();
elements.add(entry);
// Restore from json
root = createRootJson(toJson(elements), null);
backupManager.restoreFromJson(root);
List<Manga> dbMangas = db.getMangas().executeAsBlocking();
assertThat(dbMangas).hasSize(1);
assertThat(dbMangas.get(0).thumbnail_url).isEqualTo(updatedThumbnailUrl);
assertThat(dbMangas.get(0).chapter_flags).isEqualTo(512);
}
@Test
public void testRestoreChaptersForManga() {
// Create a manga and 3 chapters
Manga manga = createManga("title");
manga.id = 1L;
List<Chapter> chapters = createChapters(manga, "1", "2", "3");
// Add an entry for the manga
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
entry.add("chapters", toJson(chapters));
// Append the entry to the backup list
List<JsonElement> mangas = new ArrayList<>();
mangas.add(entry);
// Restore from json
root = createRootJson(toJson(mangas), null);
backupManager.restoreFromJson(root);
Manga dbManga = db.getManga(1).executeAsBlocking();
assertThat(dbManga).isNotNull();
List<Chapter> dbChapters = db.getChapters(dbManga).executeAsBlocking();
assertThat(dbChapters).hasSize(3);
}
@Test
public void testRestoreChaptersForExistingManga() {
long mangaId = 3;
// Create a manga and 3 chapters
Manga manga = createManga("title");
manga.id = mangaId;
List<Chapter> chapters = createChapters(manga, "1", "2", "3");
db.insertManga(manga).executeAsBlocking();
// Add an entry for the manga
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
entry.add("chapters", toJson(chapters));
// Append the entry to the backup list
List<JsonElement> mangas = new ArrayList<>();
mangas.add(entry);
// Restore from json
root = createRootJson(toJson(mangas), null);
backupManager.restoreFromJson(root);
Manga dbManga = db.getManga(mangaId).executeAsBlocking();
assertThat(dbManga).isNotNull();
List<Chapter> dbChapters = db.getChapters(dbManga).executeAsBlocking();
assertThat(dbChapters).hasSize(3);
}
@Test
public void testRestoreExistingChaptersForExistingManga() {
long mangaId = 5;
// Store a manga and 3 chapters
Manga manga = createManga("title");
manga.id = mangaId;
List<Chapter> chapters = createChapters(manga, "1", "2", "3");
db.insertManga(manga).executeAsBlocking();
db.insertChapters(chapters).executeAsBlocking();
// The backup contains a existing chapter and a new one, so it should have 4 chapters
chapters = createChapters(manga, "3", "4");
// Add an entry for the manga
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
entry.add("chapters", toJson(chapters));
// Append the entry to the backup list
List<JsonElement> mangas = new ArrayList<>();
mangas.add(entry);
// Restore from json
root = createRootJson(toJson(mangas), null);
backupManager.restoreFromJson(root);
Manga dbManga = db.getManga(mangaId).executeAsBlocking();
assertThat(dbManga).isNotNull();
List<Chapter> dbChapters = db.getChapters(dbManga).executeAsBlocking();
assertThat(dbChapters).hasSize(4);
}
@Test
public void testRestoreCategoriesForManga() {
// Create a manga
Manga manga = createManga("title");
// Create categories
List<Category> categories = createCategories("cat1", "cat2", "cat3");
// Add an entry for the manga
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
entry.add("categories", toJson(createStringCategories("cat1")));
// Append the entry to the backup list
List<JsonElement> mangas = new ArrayList<>();
mangas.add(entry);
// Restore from json
root = createRootJson(toJson(mangas), toJson(categories));
backupManager.restoreFromJson(root);
Manga dbManga = db.getManga(1).executeAsBlocking();
assertThat(dbManga).isNotNull();
assertThat(db.getCategoriesForManga(dbManga).executeAsBlocking())
.hasSize(1)
.contains(Category.create("cat1"))
.doesNotContain(Category.create("cat2"));
}
@Test
public void testRestoreCategoriesForExistingManga() {
// Store a manga
Manga manga = createManga("title");
db.insertManga(manga).executeAsBlocking();
// Create categories
List<Category> categories = createCategories("cat1", "cat2", "cat3");
// Add an entry for the manga
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
entry.add("categories", toJson(createStringCategories("cat1")));
// Append the entry to the backup list
List<JsonElement> mangas = new ArrayList<>();
mangas.add(entry);
// Restore from json
root = createRootJson(toJson(mangas), toJson(categories));
backupManager.restoreFromJson(root);
Manga dbManga = db.getManga(1).executeAsBlocking();
assertThat(dbManga).isNotNull();
assertThat(db.getCategoriesForManga(dbManga).executeAsBlocking())
.hasSize(1)
.contains(Category.create("cat1"))
.doesNotContain(Category.create("cat2"));
}
@Test
public void testRestoreMultipleCategoriesForManga() {
// Create a manga
Manga manga = createManga("title");
// Create categories
List<Category> categories = createCategories("cat1", "cat2", "cat3");
// Add an entry for the manga
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
entry.add("categories", toJson(createStringCategories("cat1", "cat3")));
// Append the entry to the backup list
List<JsonElement> mangas = new ArrayList<>();
mangas.add(entry);
// Restore from json
root = createRootJson(toJson(mangas), toJson(categories));
backupManager.restoreFromJson(root);
Manga dbManga = db.getManga(1).executeAsBlocking();
assertThat(dbManga).isNotNull();
assertThat(db.getCategoriesForManga(dbManga).executeAsBlocking())
.hasSize(2)
.contains(Category.create("cat1"), Category.create("cat3"))
.doesNotContain(Category.create("cat2"));
}
@Test
public void testRestoreMultipleCategoriesForExistingMangaAndCategory() {
// Store a manga and a category
Manga manga = createManga("title");
manga.id = 1L;
db.insertManga(manga).executeAsBlocking();
Category cat = createCategory("cat1");
cat.id = 1;
db.insertCategory(cat).executeAsBlocking();
db.insertMangaCategory(MangaCategory.create(manga, cat)).executeAsBlocking();
// Create categories
List<Category> categories = createCategories("cat1", "cat2", "cat3");
// Add an entry for the manga
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
entry.add("categories", toJson(createStringCategories("cat1", "cat2")));
// Append the entry to the backup list
List<JsonElement> mangas = new ArrayList<>();
mangas.add(entry);
// Restore from json
root = createRootJson(toJson(mangas), toJson(categories));
backupManager.restoreFromJson(root);
Manga dbManga = db.getManga(1).executeAsBlocking();
assertThat(dbManga).isNotNull();
assertThat(db.getCategoriesForManga(dbManga).executeAsBlocking())
.hasSize(2)
.contains(Category.create("cat1"), Category.create("cat2"))
.doesNotContain(Category.create("cat3"));
}
@Test
public void testRestoreSyncForManga() {
// Create a manga and mangaSync
Manga manga = createManga("title");
manga.id = 1L;
List<MangaSync> mangaSync = createMangaSync(manga, 1, 2, 3);
// Add an entry for the manga
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
entry.add("sync", toJson(mangaSync));
// Append the entry to the backup list
List<JsonElement> mangas = new ArrayList<>();
mangas.add(entry);
// Restore from json
root = createRootJson(toJson(mangas), null);
backupManager.restoreFromJson(root);
Manga dbManga = db.getManga(1).executeAsBlocking();
assertThat(dbManga).isNotNull();
List<MangaSync> dbSync = db.getMangasSync(dbManga).executeAsBlocking();
assertThat(dbSync).hasSize(3);
}
@Test
public void testRestoreSyncForExistingManga() {
long mangaId = 3;
// Create a manga and 3 sync
Manga manga = createManga("title");
manga.id = mangaId;
List<MangaSync> mangaSync = createMangaSync(manga, 1, 2, 3);
db.insertManga(manga).executeAsBlocking();
// Add an entry for the manga
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
entry.add("sync", toJson(mangaSync));
// Append the entry to the backup list
List<JsonElement> mangas = new ArrayList<>();
mangas.add(entry);
// Restore from json
root = createRootJson(toJson(mangas), null);
backupManager.restoreFromJson(root);
Manga dbManga = db.getManga(mangaId).executeAsBlocking();
assertThat(dbManga).isNotNull();
List<MangaSync> dbSync = db.getMangasSync(dbManga).executeAsBlocking();
assertThat(dbSync).hasSize(3);
}
@Test
public void testRestoreExistingSyncForExistingManga() {
long mangaId = 5;
// Store a manga and 3 sync
Manga manga = createManga("title");
manga.id = mangaId;
List<MangaSync> mangaSync = createMangaSync(manga, 1, 2, 3);
db.insertManga(manga).executeAsBlocking();
db.insertMangasSync(mangaSync).executeAsBlocking();
// The backup contains a existing sync and a new one, so it should have 4 sync
mangaSync = createMangaSync(manga, 3, 4);
// Add an entry for the manga
JsonObject entry = new JsonObject();
entry.add("manga", toJson(manga));
entry.add("sync", toJson(mangaSync));
// Append the entry to the backup list
List<JsonElement> mangas = new ArrayList<>();
mangas.add(entry);
// Restore from json
root = createRootJson(toJson(mangas), null);
backupManager.restoreFromJson(root);
Manga dbManga = db.getManga(mangaId).executeAsBlocking();
assertThat(dbManga).isNotNull();
List<MangaSync> dbSync = db.getMangasSync(dbManga).executeAsBlocking();
assertThat(dbSync).hasSize(4);
}
private JsonObject createRootJson(JsonElement mangas, JsonElement categories) {
JsonObject root = new JsonObject();
if (mangas != null)
root.add("mangas", mangas);
if (categories != null)
root.add("categories", categories);
return root;
}
private Category createCategory(String name) {
Category c = new Category();
c.name = name;
return c;
}
private List<Category> createCategories(String... names) {
List<Category> cats = new ArrayList<>();
for (String name : names) {
cats.add(createCategory(name));
}
return cats;
}
private List<String> createStringCategories(String... names) {
List<String> cats = new ArrayList<>();
for (String name : names) {
cats.add(name);
}
return cats;
}
private Manga createManga(String title) {
Manga m = new Manga();
m.title = title;
m.author = "";
m.artist = "";
m.thumbnail_url = "";
m.genre = "a list of genres";
m.description = "long description";
m.url = "url to manga";
m.favorite = true;
m.source = 1;
return m;
}
private List<Manga> createMangas(String... titles) {
List<Manga> mangas = new ArrayList<>();
for (String title : titles) {
mangas.add(createManga(title));
}
return mangas;
}
private Chapter createChapter(Manga manga, String url) {
Chapter c = Chapter.create();
c.url = url;
c.name = url;
c.manga_id = manga.id;
return c;
}
private List<Chapter> createChapters(Manga manga, String... urls) {
List<Chapter> chapters = new ArrayList<>();
for (String url : urls) {
chapters.add(createChapter(manga, url));
}
return chapters;
}
private MangaSync createMangaSync(Manga manga, int syncId) {
MangaSync m = MangaSync.create();
m.manga_id = manga.id;
m.sync_id = syncId;
m.title = "title";
return m;
}
private List<MangaSync> createMangaSync(Manga manga, Integer... syncIds) {
List<MangaSync> ms = new ArrayList<>();
for (int title : syncIds) {
ms.add(createMangaSync(manga, title));
}
return ms;
}
private JsonElement toJson(Object element) {
return gson.toJsonTree(element);
}
}

View file

@ -1,115 +0,0 @@
package eu.kanade.tachiyomi;
import android.app.Application;
import android.os.Build;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import java.util.List;
import eu.kanade.tachiyomi.data.database.DatabaseHelper;
import eu.kanade.tachiyomi.data.database.models.Category;
import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.database.models.MangaCategory;
import static org.assertj.core.api.Assertions.assertThat;
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
@RunWith(CustomRobolectricGradleTestRunner.class)
public class CategoryTest {
DatabaseHelper db;
@Before
public void setup() {
Application app = RuntimeEnvironment.application;
db = new DatabaseHelper(app);
// Create 5 mangas
createManga("a");
createManga("b");
createManga("c");
createManga("d");
createManga("e");
}
@Test
public void testHasCategories() {
// Create 2 categories
createCategory("Reading");
createCategory("Hold");
List<Category> categories = db.getCategories().executeAsBlocking();
assertThat(categories).hasSize(2);
}
@Test
public void testHasLibraryMangas() {
List<Manga> mangas = db.getLibraryMangas().executeAsBlocking();
assertThat(mangas).hasSize(5);
}
@Test
public void testHasCorrectFavorites() {
Manga m = new Manga();
m.title = "title";
m.author = "";
m.artist = "";
m.thumbnail_url = "";
m.genre = "a list of genres";
m.description = "long description";
m.url = "url to manga";
m.favorite = false;
db.insertManga(m).executeAsBlocking();
List<Manga> mangas = db.getLibraryMangas().executeAsBlocking();
assertThat(mangas).hasSize(5);
}
@Test
public void testMangaInCategory() {
// Create 2 categories
createCategory("Reading");
createCategory("Hold");
// It should not have 0 as id
Category c = db.getCategories().executeAsBlocking().get(0);
assertThat(c.id).isNotZero();
// Add a manga to a category
Manga m = db.getMangas().executeAsBlocking().get(0);
MangaCategory mc = MangaCategory.create(m, c);
db.insertMangaCategory(mc).executeAsBlocking();
// Get mangas from library and assert manga category is the same
List<Manga> mangas = db.getLibraryMangas().executeAsBlocking();
for (Manga manga : mangas) {
if (manga.id.equals(m.id)) {
assertThat(manga.category).isEqualTo(c.id);
}
}
}
private void createManga(String title) {
Manga m = new Manga();
m.title = title;
m.author = "";
m.artist = "";
m.thumbnail_url = "";
m.genre = "a list of genres";
m.description = "long description";
m.url = "url to manga";
m.favorite = true;
db.insertManga(m).executeAsBlocking();
}
private void createCategory(String name) {
Category c = new Category();
c.name = name;
db.insertCategory(c).executeAsBlocking();
}
}

View file

@ -0,0 +1,109 @@
package eu.kanade.tachiyomi
import android.os.Build
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.CategoryImpl
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.MangaCategory
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
@Config(constants = BuildConfig::class, sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP))
@RunWith(CustomRobolectricGradleTestRunner::class)
class CategoryTest {
lateinit var db: DatabaseHelper
@Before
fun setup() {
val app = RuntimeEnvironment.application
db = DatabaseHelper(app)
// Create 5 manga
createManga("a")
createManga("b")
createManga("c")
createManga("d")
createManga("e")
}
@Test
fun testHasCategories() {
// Create 2 categories
createCategory("Reading")
createCategory("Hold")
val categories = db.getCategories().executeAsBlocking()
assertThat(categories).hasSize(2)
}
@Test
fun testHasLibraryMangas() {
val mangas = db.getLibraryMangas().executeAsBlocking()
assertThat(mangas).hasSize(5)
}
@Test
fun testHasCorrectFavorites() {
val m = Manga.create(0)
m.title = "title"
m.author = ""
m.artist = ""
m.thumbnail_url = ""
m.genre = "a list of genres"
m.description = "long description"
m.url = "url to manga"
m.favorite = false
db.insertManga(m).executeAsBlocking()
val mangas = db.getLibraryMangas().executeAsBlocking()
assertThat(mangas).hasSize(5)
}
@Test
fun testMangaInCategory() {
// Create 2 categories
createCategory("Reading")
createCategory("Hold")
// It should not have 0 as id
val c = db.getCategories().executeAsBlocking()[0]
assertThat(c.id).isNotZero()
// Add a manga to a category
val m = db.getMangas().executeAsBlocking()[0]
val mc = MangaCategory.create(m, c)
db.insertMangaCategory(mc).executeAsBlocking()
// Get mangas from library and assert manga category is the same
val mangas = db.getLibraryMangas().executeAsBlocking()
for (manga in mangas) {
if (manga.id == m.id) {
assertThat(manga.category).isEqualTo(c.id)
}
}
}
private fun createManga(title: String) {
val m = Manga.create(0)
m.title = title
m.author = ""
m.artist = ""
m.thumbnail_url = ""
m.genre = "a list of genres"
m.description = "long description"
m.url = "url to manga"
m.favorite = true
db.insertManga(m).executeAsBlocking()
}
private fun createCategory(name: String) {
val c = CategoryImpl()
c.name = name
db.insertCategory(c).executeAsBlocking()
}
}

View file

@ -43,7 +43,7 @@ class ChapterRecognitionTest {
* Called before test
*/
@Before fun setup() {
manga = Manga().apply { title = "random" }
manga = Manga.create(0).apply { title = "random" }
chapter = Chapter.create()
}

View file

@ -1,19 +1,7 @@
package eu.kanade.tachiyomi
import eu.kanade.tachiyomi.injection.component.AppComponent
import eu.kanade.tachiyomi.injection.component.DaggerAppComponent
import eu.kanade.tachiyomi.injection.module.AppModule
import eu.kanade.tachiyomi.injection.module.TestDataModule
open class TestApp : App() {
override fun createAppComponent(): AppComponent {
return DaggerAppComponent.builder()
.appModule(AppModule(this))
.dataModule(TestDataModule())
.build()
}
override fun setupAcra() {
// Do nothing
}

View file

@ -0,0 +1,568 @@
package eu.kanade.tachiyomi.data.backup
import android.os.Build
import com.google.gson.Gson
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.CustomRobolectricGradleTestRunner
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
import uy.kohesive.injekt.injectLazy
import java.util.*
@Config(constants = BuildConfig::class, sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP))
@RunWith(CustomRobolectricGradleTestRunner::class)
class BackupTest {
val gson: Gson by injectLazy()
lateinit var db: DatabaseHelper
lateinit var backupManager: BackupManager
lateinit var root: JsonObject
@Before
fun setup() {
val app = RuntimeEnvironment.application
db = DatabaseHelper(app)
backupManager = BackupManager(db)
root = JsonObject()
}
@Test
fun testRestoreCategory() {
val catName = "cat"
root = createRootJson(null, toJson(createCategories(catName)))
backupManager.restoreFromJson(root)
val dbCats = db.getCategories().executeAsBlocking()
assertThat(dbCats).hasSize(1)
assertThat(dbCats[0].name).isEqualTo(catName)
}
@Test
fun testRestoreEmptyCategory() {
root = createRootJson(null, toJson(ArrayList<Any>()))
backupManager.restoreFromJson(root)
val dbCats = db.getCategories().executeAsBlocking()
assertThat(dbCats).isEmpty()
}
@Test
fun testRestoreExistingCategory() {
val catName = "cat"
db.insertCategory(createCategory(catName)).executeAsBlocking()
root = createRootJson(null, toJson(createCategories(catName)))
backupManager.restoreFromJson(root)
val dbCats = db.getCategories().executeAsBlocking()
assertThat(dbCats).hasSize(1)
assertThat(dbCats[0].name).isEqualTo(catName)
}
@Test
fun testRestoreCategories() {
root = createRootJson(null, toJson(createCategories("cat", "cat2", "cat3")))
backupManager.restoreFromJson(root)
val dbCats = db.getCategories().executeAsBlocking()
assertThat(dbCats).hasSize(3)
}
@Test
fun testRestoreExistingCategories() {
db.insertCategories(createCategories("cat", "cat2")).executeAsBlocking()
root = createRootJson(null, toJson(createCategories("cat", "cat2", "cat3")))
backupManager.restoreFromJson(root)
val dbCats = db.getCategories().executeAsBlocking()
assertThat(dbCats).hasSize(3)
}
@Test
fun testRestoreExistingCategoriesAlt() {
db.insertCategories(createCategories("cat", "cat2", "cat3")).executeAsBlocking()
root = createRootJson(null, toJson(createCategories("cat", "cat2")))
backupManager.restoreFromJson(root)
val dbCats = db.getCategories().executeAsBlocking()
assertThat(dbCats).hasSize(3)
}
@Test
fun testRestoreManga() {
val mangaName = "title"
val mangas = createMangas(mangaName)
val elements = ArrayList<JsonElement>()
for (manga in mangas) {
val entry = JsonObject()
entry.add("manga", toJson(manga))
elements.add(entry)
}
root = createRootJson(toJson(elements), null)
backupManager.restoreFromJson(root)
val dbMangas = db.getMangas().executeAsBlocking()
assertThat(dbMangas).hasSize(1)
assertThat(dbMangas[0].title).isEqualTo(mangaName)
}
@Test
fun testRestoreExistingManga() {
val mangaName = "title"
val manga = createManga(mangaName)
db.insertManga(manga).executeAsBlocking()
val elements = ArrayList<JsonElement>()
val entry = JsonObject()
entry.add("manga", toJson(manga))
elements.add(entry)
root = createRootJson(toJson(elements), null)
backupManager.restoreFromJson(root)
val dbMangas = db.getMangas().executeAsBlocking()
assertThat(dbMangas).hasSize(1)
}
@Test
fun testRestoreExistingMangaWithUpdatedFields() {
// Store a manga in db
val mangaName = "title"
val updatedThumbnailUrl = "updated thumbnail url"
var manga = createManga(mangaName)
manga.chapter_flags = 1024
manga.thumbnail_url = updatedThumbnailUrl
db.insertManga(manga).executeAsBlocking()
// Add an entry for a new manga with different attributes
manga = createManga(mangaName)
manga.chapter_flags = 512
val entry = JsonObject()
entry.add("manga", toJson(manga))
// Append the entry to the backup list
val elements = ArrayList<JsonElement>()
elements.add(entry)
// Restore from json
root = createRootJson(toJson(elements), null)
backupManager.restoreFromJson(root)
val dbMangas = db.getMangas().executeAsBlocking()
assertThat(dbMangas).hasSize(1)
assertThat(dbMangas[0].thumbnail_url).isEqualTo(updatedThumbnailUrl)
assertThat(dbMangas[0].chapter_flags).isEqualTo(512)
}
@Test
fun testRestoreChaptersForManga() {
// Create a manga and 3 chapters
val manga = createManga("title")
manga.id = 1L
val chapters = createChapters(manga, "1", "2", "3")
// Add an entry for the manga
val entry = JsonObject()
entry.add("manga", toJson(manga))
entry.add("chapters", toJson(chapters))
// Append the entry to the backup list
val mangas = ArrayList<JsonElement>()
mangas.add(entry)
// Restore from json
root = createRootJson(toJson(mangas), null)
backupManager.restoreFromJson(root)
val dbManga = db.getManga(1).executeAsBlocking()
assertThat(dbManga).isNotNull()
val dbChapters = db.getChapters(dbManga!!).executeAsBlocking()
assertThat(dbChapters).hasSize(3)
}
@Test
fun testRestoreChaptersForExistingManga() {
val mangaId: Long = 3
// Create a manga and 3 chapters
val manga = createManga("title")
manga.id = mangaId
val chapters = createChapters(manga, "1", "2", "3")
db.insertManga(manga).executeAsBlocking()
// Add an entry for the manga
val entry = JsonObject()
entry.add("manga", toJson(manga))
entry.add("chapters", toJson(chapters))
// Append the entry to the backup list
val mangas = ArrayList<JsonElement>()
mangas.add(entry)
// Restore from json
root = createRootJson(toJson(mangas), null)
backupManager.restoreFromJson(root)
val dbManga = db.getManga(mangaId).executeAsBlocking()
assertThat(dbManga).isNotNull()
val dbChapters = db.getChapters(dbManga!!).executeAsBlocking()
assertThat(dbChapters).hasSize(3)
}
@Test
fun testRestoreExistingChaptersForExistingManga() {
val mangaId: Long = 5
// Store a manga and 3 chapters
val manga = createManga("title")
manga.id = mangaId
var chapters = createChapters(manga, "1", "2", "3")
db.insertManga(manga).executeAsBlocking()
db.insertChapters(chapters).executeAsBlocking()
// The backup contains a existing chapter and a new one, so it should have 4 chapters
chapters = createChapters(manga, "3", "4")
// Add an entry for the manga
val entry = JsonObject()
entry.add("manga", toJson(manga))
entry.add("chapters", toJson(chapters))
// Append the entry to the backup list
val mangas = ArrayList<JsonElement>()
mangas.add(entry)
// Restore from json
root = createRootJson(toJson(mangas), null)
backupManager.restoreFromJson(root)
val dbManga = db.getManga(mangaId).executeAsBlocking()
assertThat(dbManga).isNotNull()
val dbChapters = db.getChapters(dbManga!!).executeAsBlocking()
assertThat(dbChapters).hasSize(4)
}
@Test
fun testRestoreCategoriesForManga() {
// Create a manga
val manga = createManga("title")
// Create categories
val categories = createCategories("cat1", "cat2", "cat3")
// Add an entry for the manga
val entry = JsonObject()
entry.add("manga", toJson(manga))
entry.add("categories", toJson(createStringCategories("cat1")))
// Append the entry to the backup list
val mangas = ArrayList<JsonElement>()
mangas.add(entry)
// Restore from json
root = createRootJson(toJson(mangas), toJson(categories))
backupManager.restoreFromJson(root)
val dbManga = db.getManga(1).executeAsBlocking()
assertThat(dbManga).isNotNull()
val result = db.getCategoriesForManga(dbManga!!).executeAsBlocking()
assertThat(result).hasSize(1)
assertThat(result).contains(Category.create("cat1"))
assertThat(result).doesNotContain(Category.create("cat2"))
}
@Test
fun testRestoreCategoriesForExistingManga() {
// Store a manga
val manga = createManga("title")
db.insertManga(manga).executeAsBlocking()
// Create categories
val categories = createCategories("cat1", "cat2", "cat3")
// Add an entry for the manga
val entry = JsonObject()
entry.add("manga", toJson(manga))
entry.add("categories", toJson(createStringCategories("cat1")))
// Append the entry to the backup list
val mangas = ArrayList<JsonElement>()
mangas.add(entry)
// Restore from json
root = createRootJson(toJson(mangas), toJson(categories))
backupManager.restoreFromJson(root)
val dbManga = db.getManga(1).executeAsBlocking()
assertThat(dbManga).isNotNull()
val result = db.getCategoriesForManga(dbManga!!).executeAsBlocking()
assertThat(result).hasSize(1)
assertThat(result).contains(Category.create("cat1"))
assertThat(result).doesNotContain(Category.create("cat2"))
}
@Test
fun testRestoreMultipleCategoriesForManga() {
// Create a manga
val manga = createManga("title")
// Create categories
val categories = createCategories("cat1", "cat2", "cat3")
// Add an entry for the manga
val entry = JsonObject()
entry.add("manga", toJson(manga))
entry.add("categories", toJson(createStringCategories("cat1", "cat3")))
// Append the entry to the backup list
val mangas = ArrayList<JsonElement>()
mangas.add(entry)
// Restore from json
root = createRootJson(toJson(mangas), toJson(categories))
backupManager.restoreFromJson(root)
val dbManga = db.getManga(1).executeAsBlocking()
assertThat(dbManga).isNotNull()
val result = db.getCategoriesForManga(dbManga!!).executeAsBlocking()
assertThat(result).hasSize(2)
assertThat(result).contains(Category.create("cat1"), Category.create("cat3"))
assertThat(result).doesNotContain(Category.create("cat2"))
}
@Test
fun testRestoreMultipleCategoriesForExistingMangaAndCategory() {
// Store a manga and a category
val manga = createManga("title")
manga.id = 1L
db.insertManga(manga).executeAsBlocking()
val cat = createCategory("cat1")
cat.id = 1
db.insertCategory(cat).executeAsBlocking()
db.insertMangaCategory(MangaCategory.create(manga, cat)).executeAsBlocking()
// Create categories
val categories = createCategories("cat1", "cat2", "cat3")
// Add an entry for the manga
val entry = JsonObject()
entry.add("manga", toJson(manga))
entry.add("categories", toJson(createStringCategories("cat1", "cat2")))
// Append the entry to the backup list
val mangas = ArrayList<JsonElement>()
mangas.add(entry)
// Restore from json
root = createRootJson(toJson(mangas), toJson(categories))
backupManager.restoreFromJson(root)
val dbManga = db.getManga(1).executeAsBlocking()
assertThat(dbManga).isNotNull()
val result = db.getCategoriesForManga(dbManga!!).executeAsBlocking()
assertThat(result).hasSize(2)
assertThat(result).contains(Category.create("cat1"), Category.create("cat2"))
assertThat(result).doesNotContain(Category.create("cat3"))
}
@Test
fun testRestoreSyncForManga() {
// Create a manga and mangaSync
val manga = createManga("title")
manga.id = 1L
val mangaSync = createMangaSync(manga, 1, 2, 3)
// Add an entry for the manga
val entry = JsonObject()
entry.add("manga", toJson(manga))
entry.add("sync", toJson(mangaSync))
// Append the entry to the backup list
val mangas = ArrayList<JsonElement>()
mangas.add(entry)
// Restore from json
root = createRootJson(toJson(mangas), null)
backupManager.restoreFromJson(root)
val dbManga = db.getManga(1).executeAsBlocking()
assertThat(dbManga).isNotNull()
val dbSync = db.getMangasSync(dbManga!!).executeAsBlocking()
assertThat(dbSync).hasSize(3)
}
@Test
fun testRestoreSyncForExistingManga() {
val mangaId: Long = 3
// Create a manga and 3 sync
val manga = createManga("title")
manga.id = mangaId
val mangaSync = createMangaSync(manga, 1, 2, 3)
db.insertManga(manga).executeAsBlocking()
// Add an entry for the manga
val entry = JsonObject()
entry.add("manga", toJson(manga))
entry.add("sync", toJson(mangaSync))
// Append the entry to the backup list
val mangas = ArrayList<JsonElement>()
mangas.add(entry)
// Restore from json
root = createRootJson(toJson(mangas), null)
backupManager.restoreFromJson(root)
val dbManga = db.getManga(mangaId).executeAsBlocking()
assertThat(dbManga).isNotNull()
val dbSync = db.getMangasSync(dbManga!!).executeAsBlocking()
assertThat(dbSync).hasSize(3)
}
@Test
fun testRestoreExistingSyncForExistingManga() {
val mangaId: Long = 5
// Store a manga and 3 sync
val manga = createManga("title")
manga.id = mangaId
var mangaSync = createMangaSync(manga, 1, 2, 3)
db.insertManga(manga).executeAsBlocking()
db.insertMangasSync(mangaSync).executeAsBlocking()
// The backup contains a existing sync and a new one, so it should have 4 sync
mangaSync = createMangaSync(manga, 3, 4)
// Add an entry for the manga
val entry = JsonObject()
entry.add("manga", toJson(manga))
entry.add("sync", toJson(mangaSync))
// Append the entry to the backup list
val mangas = ArrayList<JsonElement>()
mangas.add(entry)
// Restore from json
root = createRootJson(toJson(mangas), null)
backupManager.restoreFromJson(root)
val dbManga = db.getManga(mangaId).executeAsBlocking()
assertThat(dbManga).isNotNull()
val dbSync = db.getMangasSync(dbManga!!).executeAsBlocking()
assertThat(dbSync).hasSize(4)
}
private fun createRootJson(mangas: JsonElement?, categories: JsonElement?): JsonObject {
val root = JsonObject()
if (mangas != null)
root.add("mangas", mangas)
if (categories != null)
root.add("categories", categories)
return root
}
private fun createCategory(name: String): Category {
val c = CategoryImpl()
c.name = name
return c
}
private fun createCategories(vararg names: String): List<Category> {
val cats = ArrayList<Category>()
for (name in names) {
cats.add(createCategory(name))
}
return cats
}
private fun createStringCategories(vararg names: String): List<String> {
val cats = ArrayList<String>()
for (name in names) {
cats.add(name)
}
return cats
}
private fun createManga(title: String): Manga {
val m = Manga.create(1)
m.title = title
m.author = ""
m.artist = ""
m.thumbnail_url = ""
m.genre = "a list of genres"
m.description = "long description"
m.url = "url to manga"
m.favorite = true
return m
}
private fun createMangas(vararg titles: String): List<Manga> {
val mangas = ArrayList<Manga>()
for (title in titles) {
mangas.add(createManga(title))
}
return mangas
}
private fun createChapter(manga: Manga, url: String): Chapter {
val c = Chapter.create()
c.url = url
c.name = url
c.manga_id = manga.id
return c
}
private fun createChapters(manga: Manga, vararg urls: String): List<Chapter> {
val chapters = ArrayList<Chapter>()
for (url in urls) {
chapters.add(createChapter(manga, url))
}
return chapters
}
private fun createMangaSync(manga: Manga, syncId: Int): MangaSync {
val m = MangaSync.create(syncId)
m.manga_id = manga.id!!
m.title = "title"
return m
}
private fun createMangaSync(manga: Manga, vararg syncIds: Int): List<MangaSync> {
val ms = ArrayList<MangaSync>()
for (title in syncIds) {
ms.add(createMangaSync(manga, title))
}
return ms
}
private fun toJson(element: Any): JsonElement {
return gson.toJsonTree(element)
}
}

View file

@ -1,115 +0,0 @@
package eu.kanade.tachiyomi.data.library;
import android.content.Context;
import android.os.Build;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowApplication;
import java.util.ArrayList;
import java.util.List;
import eu.kanade.tachiyomi.BuildConfig;
import eu.kanade.tachiyomi.CustomRobolectricGradleTestRunner;
import eu.kanade.tachiyomi.data.database.models.Chapter;
import eu.kanade.tachiyomi.data.database.models.Manga;
import eu.kanade.tachiyomi.data.source.online.OnlineSource;
import rx.Observable;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
@RunWith(CustomRobolectricGradleTestRunner.class)
public class LibraryUpdateServiceTest {
ShadowApplication app;
Context context;
LibraryUpdateService service;
OnlineSource source;
@Before
public void setup() {
app = ShadowApplication.getInstance();
context = app.getApplicationContext();
service = Robolectric.setupService(LibraryUpdateService.class);
source = mock(OnlineSource.class);
when(service.sourceManager.get(anyInt())).thenReturn(source);
}
@Test
public void testLifecycle() {
// Smoke test
Robolectric.buildService(LibraryUpdateService.class)
.attach()
.create()
.startCommand(0, 0)
.destroy()
.get();
}
@Test
public void testUpdateManga() {
Manga manga = createManga("/manga1").get(0);
manga.id = 1L;
service.db.insertManga(manga).executeAsBlocking();
List<Chapter> sourceChapters = createChapters("/chapter1", "/chapter2");
when(source.fetchChapterList(manga)).thenReturn(Observable.just(sourceChapters));
service.updateManga(manga).subscribe();
assertThat(service.db.getChapters(manga).executeAsBlocking()).hasSize(2);
}
@Test
public void testContinuesUpdatingWhenAMangaFails() {
List<Manga> favManga = createManga("/manga1", "/manga2", "/manga3");
service.db.insertMangas(favManga).executeAsBlocking();
favManga = service.db.getFavoriteMangas().executeAsBlocking();
List<Chapter> chapters = createChapters("/chapter1", "/chapter2");
List<Chapter> chapters3 = createChapters("/achapter1", "/achapter2");
// One of the updates will fail
when(source.fetchChapterList(favManga.get(0))).thenReturn(Observable.just(chapters));
when(source.fetchChapterList(favManga.get(1))).thenReturn(Observable.<List<Chapter>>error(new Exception()));
when(source.fetchChapterList(favManga.get(2))).thenReturn(Observable.just(chapters3));
service.updateMangaList(service.getMangaToUpdate(null)).subscribe();
// There are 3 network attempts and 2 insertions (1 request failed)
assertThat(service.db.getChapters(favManga.get(0)).executeAsBlocking()).hasSize(2);
assertThat(service.db.getChapters(favManga.get(1)).executeAsBlocking()).hasSize(0);
assertThat(service.db.getChapters(favManga.get(2)).executeAsBlocking()).hasSize(2);
}
private List<Chapter> createChapters(String... urls) {
List<Chapter> list = new ArrayList<>();
for (String url : urls) {
Chapter c = Chapter.create();
c.url = url;
c.name = url.substring(1);
list.add(c);
}
return list;
}
private List<Manga> createManga(String... urls) {
List<Manga> list = new ArrayList<>();
for (String url : urls) {
Manga m = Manga.create(url);
m.title = url.substring(1);
m.favorite = true;
list.add(m);
}
return list;
}
}

View file

@ -0,0 +1,137 @@
package eu.kanade.tachiyomi.data.library
import android.app.Application
import android.content.Context
import android.os.Build
import eu.kanade.tachiyomi.AppModule
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.CustomRobolectricGradleTestRunner
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.source.SourceManager
import eu.kanade.tachiyomi.data.source.online.OnlineSource
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Matchers.anyInt
import org.mockito.Mockito
import org.mockito.Mockito.*
import org.robolectric.Robolectric
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
import rx.Observable
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.InjektModule
import uy.kohesive.injekt.api.InjektRegistrar
import uy.kohesive.injekt.api.InjektScope
import uy.kohesive.injekt.api.addSingleton
import uy.kohesive.injekt.registry.default.DefaultRegistrar
import java.util.*
@Config(constants = BuildConfig::class, sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP))
@RunWith(CustomRobolectricGradleTestRunner::class)
class LibraryUpdateServiceTest {
lateinit var app: Application
lateinit var context: Context
lateinit var service: LibraryUpdateService
lateinit var source: OnlineSource
@Before
fun setup() {
app = RuntimeEnvironment.application
context = app.applicationContext
// Mock the source manager
val module = object : InjektModule {
override fun InjektRegistrar.registerInjectables() {
addSingleton(Mockito.mock(SourceManager::class.java, RETURNS_DEEP_STUBS))
}
}
// Restart injections for each test
Injekt = InjektScope(DefaultRegistrar())
Injekt.importModule(AppModule(app))
Injekt.importModule(module)
service = Robolectric.setupService(LibraryUpdateService::class.java)
source = mock(OnlineSource::class.java)
`when`(service.sourceManager.get(anyInt())).thenReturn(source)
}
@Test
fun testLifecycle() {
println(service.db)
// Smoke test
Robolectric.buildService(LibraryUpdateService::class.java)
.attach()
.create()
.startCommand(0, 0)
.destroy()
.get()
}
@Test
fun testUpdateManga() {
println(service.db)
val manga = createManga("/manga1")[0]
manga.id = 1L
service.db.insertManga(manga).executeAsBlocking()
val sourceChapters = createChapters("/chapter1", "/chapter2")
`when`(source.fetchChapterList(manga)).thenReturn(Observable.just(sourceChapters))
service.updateManga(manga).subscribe()
assertThat(service.db.getChapters(manga).executeAsBlocking()).hasSize(2)
}
@Test
fun testContinuesUpdatingWhenAMangaFails() {
var favManga = createManga("/manga1", "/manga2", "/manga3")
println(service.db)
service.db.insertMangas(favManga).executeAsBlocking()
favManga = service.db.getFavoriteMangas().executeAsBlocking()
val chapters = createChapters("/chapter1", "/chapter2")
val chapters3 = createChapters("/achapter1", "/achapter2")
// One of the updates will fail
`when`(source.fetchChapterList(favManga[0])).thenReturn(Observable.just(chapters))
`when`(source.fetchChapterList(favManga[1])).thenReturn(Observable.error<List<Chapter>>(Exception()))
`when`(source.fetchChapterList(favManga[2])).thenReturn(Observable.just(chapters3))
service.updateMangaList(service.getMangaToUpdate(null)).subscribe()
// There are 3 network attempts and 2 insertions (1 request failed)
assertThat(service.db.getChapters(favManga[0]).executeAsBlocking()).hasSize(2)
assertThat(service.db.getChapters(favManga[1]).executeAsBlocking()).hasSize(0)
assertThat(service.db.getChapters(favManga[2]).executeAsBlocking()).hasSize(2)
}
private fun createChapters(vararg urls: String): List<Chapter> {
val list = ArrayList<Chapter>()
for (url in urls) {
val c = Chapter.create()
c.url = url
c.name = url.substring(1)
list.add(c)
}
return list
}
private fun createManga(vararg urls: String): List<Manga> {
val list = ArrayList<Manga>()
for (url in urls) {
val m = Manga.create(url)
m.title = url.substring(1)
m.favorite = true
list.add(m)
}
return list
}
}

View file

@ -1,18 +0,0 @@
package eu.kanade.tachiyomi.injection.module
import android.app.Application
import eu.kanade.tachiyomi.data.network.NetworkHelper
import eu.kanade.tachiyomi.data.source.SourceManager
import org.mockito.Mockito
class TestDataModule : DataModule() {
override fun provideNetworkHelper(app: Application): NetworkHelper {
return Mockito.mock(NetworkHelper::class.java)
}
override fun provideSourceManager(app: Application): SourceManager {
return Mockito.mock(SourceManager::class.java, Mockito.RETURNS_DEEP_STUBS)
}
}