diff --git a/app/src/androidTestKiwix/java/org/kiwix/kiwixmobile/data/local/BookDatabaseTest.java b/app/src/androidTestKiwix/java/org/kiwix/kiwixmobile/data/local/BookDatabaseTest.java new file mode 100644 index 000000000..14ecfdcff --- /dev/null +++ b/app/src/androidTestKiwix/java/org/kiwix/kiwixmobile/data/local/BookDatabaseTest.java @@ -0,0 +1,192 @@ +/* + * Kiwix Android + * Copyright (C) 2018 Kiwix + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.kiwix.kiwixmobile.data.local; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.kiwix.kiwixmobile.data.local.dao.BookDao; +import org.kiwix.kiwixmobile.data.local.entity.BookDatabaseEntity; +import org.kiwix.kiwixmobile.library.entity.LibraryNetworkEntity.Book; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + + +@RunWith(AndroidJUnit4.class) +public class BookDatabaseTest { + + private Context context; + private @Mock KiwixDatabase kiwixDatabase; + private BookDao bookDao; + private boolean mockInitialized = false; + private File testDir; + + @Before + public void executeBefore() { + if (!mockInitialized) { + MockitoAnnotations.initMocks(this); + mockInitialized = true; + } + context = InstrumentationRegistry.getTargetContext(); + //kiwixDatabase = new KiwixDatabase(context); + bookDao = new BookDao(kiwixDatabase); + + // Create a temporary directory where all the test files will be saved + testDir = context.getDir("testDir", context.MODE_PRIVATE); + } + + //TODO : test books are saved after downloading the list of available zim files + + @Test + public void testGetBooks() throws IOException { + // Save the fake data to test + String testId = "6qq5301d-2cr0-ebg5-474h-6db70j52864p"; + String fileName = testDir.getPath() + "/" + testId + "testFile"; + ArrayList booksToAdd = getFakeData(fileName); + + // Set up the mocks + when(kiwixDatabase.deleteWhere(any(), any())).thenReturn(0); + + // Get the filtered book list from the database (using the internal selection logic in BookDao) + ArrayList booksRetrieved = bookDao.filterBookResults(booksToAdd); + + // Test whether the correct books are returned + + // Filename ends with .zim and the file exists in memory + if(!booksRetrieved.contains(booksToAdd.get(0))) assertEquals(0, 1); + verify(kiwixDatabase, never()).deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(booksToAdd.get(0).file.getPath())); + + // Filename ends with .part and the file exists in memory + if(booksRetrieved.contains(booksToAdd.get(1))) assertEquals(0, 1); + verify(kiwixDatabase, never()).deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(booksToAdd.get(1).file.getPath())); + + // Filename ends with .zim, however only the .zim.part file exists in memory + if(booksRetrieved.contains(booksToAdd.get(2))) assertEquals(0, 1); + verify(kiwixDatabase, never()).deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(booksToAdd.get(2).file.getPath())); + + // Filename ends with .zim but neither the .zim, nor the .zim.part file exists in memory + if(booksRetrieved.contains(booksToAdd.get(3))) assertEquals(0, 1); + verify(kiwixDatabase).deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(booksToAdd.get(3).file.getPath())); + + // Filename ends with .zim and both the .zim, and the .zim.part files exists in memory + if(!booksRetrieved.contains(booksToAdd.get(4))) assertEquals(0, 1); + verify(kiwixDatabase, never()).deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(booksToAdd.get(4).file.getPath())); + + // If the filename ends with .zimXX + + // FileName.zimXX.part does not exist for any value of "XX" from "aa" till "dr", but FileName.zimXX exists for all "XX" from "aa', till "ds", then it does not exist + // Also, the file inside the BooksToAdd does exist in memory + if(!booksRetrieved.contains(booksToAdd.get(5))) assertEquals(0, 1); + verify(kiwixDatabase, never()).deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(booksToAdd.get(5).file.getPath())); + + // FileName.zimXX.part does not exist for any value of "XX" from "aa" till "dr", but FileName.zimXX exists for all "XX" from "aa', till "ds", then it does not exist + // Also, the file inside the BooksToAdd also not exist in memory + if(booksRetrieved.contains(booksToAdd.get(6))) assertEquals(0, 1); + verify(kiwixDatabase).deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(booksToAdd.get(6).file.getPath())); + + // FileName.zimXX.part exists for some "XX" between "aa" till "bl" + // And FileName.zimXX exists for all "XX" from "aa', till "bk", and then it does not exist + // Also, the file inside the BooksToAdd does exist in memory + if(!booksRetrieved.contains(booksToAdd.get(7))) assertEquals(0, 1); + verify(kiwixDatabase, never()).deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(booksToAdd.get(7).file.getPath())); + + // FileName.zimXX.part exists for some "XX" between "aa" till "bl" + // And FileName.zimXX exists for all "XX" from "aa', till "bk", and then it does not exist + // Also, the file inside the BooksToAdd does not exist in memory + if(booksRetrieved.contains(booksToAdd.get(8))) assertEquals(0, 1); + verify(kiwixDatabase).deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(booksToAdd.get(8).file.getPath())); + } + + private ArrayList getFakeData(String baseFileName) throws IOException { + ArrayList books = new ArrayList<>(); + for(int i = 0; i < 9; i++){ + Book book = new Book(); + book.bookName = "Test Copy " + Integer.toString(i); + book.id = "Test ID " + Integer.toString(i); + String fileName = baseFileName + Integer.toString(i); + switch (i) { + case 0: book.file = new File(fileName + ".zim"); book.file.createNewFile(); break; + case 1: book.file = new File(fileName + ".part"); book.file.createNewFile(); break; + case 2: book.file = new File(fileName + ".zim"); + File t2 = new File(fileName + ".zim.part"); t2.createNewFile(); break; + case 3: book.file = new File(fileName + ".zim"); break; + case 4: book.file = new File(fileName + ".zim"); book.file.createNewFile(); + File t4 = new File(fileName + ".zim.part"); t4.createNewFile(); break; + case 5: book.file = new File(fileName + ".zimdg"); setupCase1(fileName); break; + case 6: book.file = new File(fileName + ".zimyr"); setupCase2(fileName); break; + case 7: book.file = new File(fileName + ".zimdg"); setupCase1(fileName); break; + case 8: book.file = new File(fileName + ".zimyr"); setupCase2(fileName); break; + } + books.add(book); + } + return books; + } + + private void setupCase1(String fileName) throws IOException { + for (char char1 = 'a'; char1 <= 'z'; char1++) { + for (char char2 = 'a'; char2 <= 'z'; char2++) { + File file = new File(fileName + ".zim" + char1 + char2); + file.createNewFile(); + if (char1 == 'd' && char2 == 'r') { + break; + } + } + if (char1 == 'd') { + break; + } + } + } + + private void setupCase2(String fileName) throws IOException { + for (char char1 = 'a'; char1 <= 'z'; char1++) { + for (char char2 = 'a'; char2 <= 'z'; char2++) { + File file = new File(fileName + ".zim" + char1 + char2); + file.createNewFile(); + if (char1 == 'd' && char2 == 'r') { + break; + } + } + if (char1 == 'd') { + break; + } + } + File t = new File(fileName + ".zimcp.part"); + } + + @After + public void RemoveTestDirectory() { + for(File child : testDir.listFiles()) { + child.delete(); + } + testDir.delete(); + } +} diff --git a/app/src/androidTestKiwix/java/org/kiwix/kiwixmobile/data/local/RecentSearchDatabaseTest.java b/app/src/androidTestKiwix/java/org/kiwix/kiwixmobile/data/local/RecentSearchDatabaseTest.java new file mode 100644 index 000000000..c8d0fd46e --- /dev/null +++ b/app/src/androidTestKiwix/java/org/kiwix/kiwixmobile/data/local/RecentSearchDatabaseTest.java @@ -0,0 +1,65 @@ +/* + * Kiwix Android + * Copyright (C) 2018 Kiwix + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.kiwix.kiwixmobile.data.local; + +import com.yahoo.squidb.data.AbstractModel; +import com.yahoo.squidb.data.SquidCursor; +import com.yahoo.squidb.sql.Query; +import org.junit.Before; +import org.junit.Test; +import org.kiwix.kiwixmobile.data.ZimContentProvider; +import org.kiwix.kiwixmobile.data.local.dao.RecentSearchDao; +import org.kiwix.kiwixmobile.data.local.entity.RecentSearch; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class RecentSearchDatabaseTest { + + @Mock private KiwixDatabase kiwixDatabase; + private RecentSearchDao recentSearchDao; + private boolean mockInitialized = false; + @Mock private SquidCursor mockedCursor; + + @Before + public void executeBefore() { + if (!mockInitialized) { + MockitoAnnotations.initMocks(this); + mockInitialized = true; + } + when(kiwixDatabase.query(any(), any())).thenReturn(mockedCursor); + recentSearchDao = new RecentSearchDao(kiwixDatabase); + } + + // verify the correct database query was called + @Test + public void testGetRecentSearches() { + recentSearchDao.getRecentSearches(); + + // verify ordering is in descending order of search ID and the results are limited to 5 only + verify(kiwixDatabase).query(any(), eq(Query.selectDistinct(RecentSearch.SEARCH_STRING).where(RecentSearch.ZIM_I_D.eq( + ZimContentProvider.getId())) + .orderBy(RecentSearch.ID.desc()) + .limit(5))); + } +} diff --git a/app/src/main/java/org/kiwix/kiwixmobile/data/local/dao/BookDao.java b/app/src/main/java/org/kiwix/kiwixmobile/data/local/dao/BookDao.java index 02d484c38..1bd115ca8 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/data/local/dao/BookDao.java +++ b/app/src/main/java/org/kiwix/kiwixmobile/data/local/dao/BookDao.java @@ -36,7 +36,7 @@ import javax.inject.Inject; */ public class BookDao { - private KiwixDatabase mDb; + public KiwixDatabase mDb; @Inject public BookDao(KiwixDatabase kiwixDatabase) { @@ -87,16 +87,25 @@ public class BookDao { while (bookCursor.moveToNext()) { Book book = new Book(); setBookDetails(book, bookCursor); + books.add(book); + } + bookCursor.close(); + ArrayList FinalList = filterBookResults(books); + return FinalList; + } + + public ArrayList filterBookResults(ArrayList books) { + ArrayList filteredBookList = new ArrayList<>(); + for (Book book : books){ if (!FileUtils.hasPart(book.file)) { if (book.file.exists()) { - books.add(book); + filteredBookList.add(book); } else { mDb.deleteWhere(BookDatabaseEntity.class, BookDatabaseEntity.URL.eq(book.file.getPath())); } } } - bookCursor.close(); - return books; + return filteredBookList; } public ArrayList getDownloadingBooks() {