Added bookmark Wikidata items option (#4515)

* classes

* Almost done

* All done but build fail

* All done but build fail

* Modifications

* Modifications

* Fixed

* string resource

* minor change

* Maintained code conventions

* Moving

* Exception handled

* id name changed

* Test fail fixed

* Bookmark is available from other activities

* Test fail fixed

* Documentation error fixed

* Test added

* Revert Project_Default.xml

* Minor Change

* Revert changes
This commit is contained in:
Ayan Sarkar 2021-12-28 16:45:09 +05:30 committed by GitHub
parent 3c29f45f15
commit 38ed364423
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 1222 additions and 4 deletions

View file

@ -37,7 +37,7 @@ class BookmarksPagerAdapterTests {
@Test
fun testGetCount() {
Assert.assertEquals(bookmarksPagerAdapter.count, 2)
Assert.assertEquals(bookmarksPagerAdapter.count, 3)
}
@Test

View file

@ -0,0 +1,50 @@
package fr.free.nrw.commons.bookmarks.items
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import java.util.ArrayList
class BookmarkItemsControllerTest {
@Mock
var bookmarkDao: BookmarkItemsDao? = null
@InjectMocks
lateinit var bookmarkItemsController: BookmarkItemsController
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
whenever(bookmarkDao!!.allBookmarksItems)
.thenReturn(mockBookmarkList)
}
/**
* Get mock bookmark list
* @return list of DepictedItem
*/
private val mockBookmarkList: List<DepictedItem>
get() {
val list = ArrayList<DepictedItem>()
list.add(
DepictedItem(
"name", "description", "image url", listOf("instance"),
listOf("categories"), true, "id")
)
return list
}
/**
* Test case where all bookmark items are fetched and media is found against it
*/
@Test
fun loadBookmarkedItems() {
val bookmarkedItems =
bookmarkItemsController.loadFavoritesItems()
Assert.assertEquals(1, bookmarkedItems.size.toLong())
}
}

View file

@ -0,0 +1,270 @@
package fr.free.nrw.commons.bookmarks.items
import android.content.ContentProviderClient
import android.content.ContentValues
import android.database.Cursor
import android.database.MatrixCursor
import android.database.sqlite.SQLiteDatabase
import android.net.Uri
import android.os.RemoteException
import com.nhaarman.mockitokotlin2.*
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.*
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
class BookmarkItemsDaoTest {
private val columns = arrayOf(
COLUMN_NAME,
COLUMN_DESCRIPTION,
COLUMN_IMAGE,
COLUMN_INSTANCE_LIST,
COLUMN_CATEGORIES_LIST,
COLUMN_IS_SELECTED,
COLUMN_ID,
)
private val client: ContentProviderClient = mock()
private val database: SQLiteDatabase = mock()
private val captor = argumentCaptor<ContentValues>()
private lateinit var testObject: BookmarkItemsDao
private lateinit var exampleItemBookmark: DepictedItem
/**
* Set up Test DepictedItem and BookmarkItemsDao
*/
@Before
fun setUp() {
exampleItemBookmark = DepictedItem("itemName", "itemDescription",
"itemImageUrl", listOf("instance"), listOf("categories"), false,
"itemID")
testObject = BookmarkItemsDao { client }
}
@Test
fun createTable() {
onCreate(database)
verify(database).execSQL(CREATE_TABLE_STATEMENT)
}
@Test
fun deleteTable() {
onDelete(database)
inOrder(database) {
verify(database).execSQL(DROP_TABLE_STATEMENT)
verify(database).execSQL(CREATE_TABLE_STATEMENT)
}
}
@Test
fun createFromCursor() {
createCursor(1).let { cursor ->
cursor.moveToFirst()
testObject.fromCursor(cursor).let {
Assert.assertEquals("itemName", it.name)
Assert.assertEquals("itemDescription", it.description)
Assert.assertEquals("itemImageUrl", it.imageUrl)
Assert.assertEquals(listOf("instance"), it.instanceOfs)
Assert.assertEquals(listOf("categories"), it.commonsCategories)
Assert.assertEquals(false, it.isSelected)
Assert.assertEquals("itemID", it.id)
}
}
}
@Test
fun getAllItemsBookmarks() {
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull()))
.thenReturn(createCursor(14))
val result = testObject.allBookmarksItems
Assert.assertEquals(14, (result.size))
}
@Test(expected = RuntimeException::class)
fun getAllItemsBookmarksTranslatesExceptions() {
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenThrow(
RemoteException("")
)
testObject.allBookmarksItems
}
@Test
fun getAllItemsBookmarksReturnsEmptyList_emptyCursor() {
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull()))
.thenReturn(createCursor(0))
Assert.assertTrue(testObject.allBookmarksItems.isEmpty())
}
@Test
fun getAllItemsBookmarksReturnsEmptyList_nullCursor() {
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(null)
Assert.assertTrue(testObject.allBookmarksItems.isEmpty())
}
@Test
fun cursorsAreClosedAfterGetAllItemsBookmarksQuery() {
val mockCursor: Cursor = mock()
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(mockCursor)
whenever(mockCursor.moveToFirst()).thenReturn(false)
testObject.allBookmarksItems
verify(mockCursor).close()
}
@Test
fun updateNewItemBookmark() {
whenever(client.insert(any(), any())).thenReturn(Uri.EMPTY)
whenever(client.query(any(), any(), any(), any(), anyOrNull())).thenReturn(null)
Assert.assertTrue(testObject.updateBookmarkItem(exampleItemBookmark))
verify(client).insert(eq(BookmarkItemsContentProvider.BASE_URI), captor.capture())
captor.firstValue.let { cv ->
Assert.assertEquals(7, cv.size())
Assert.assertEquals(
exampleItemBookmark.name,
cv.getAsString(COLUMN_NAME)
)
Assert.assertEquals(
exampleItemBookmark.description,
cv.getAsString(COLUMN_DESCRIPTION)
)
Assert.assertEquals(
exampleItemBookmark.imageUrl,
cv.getAsString(COLUMN_IMAGE)
)
Assert.assertEquals(
exampleItemBookmark.instanceOfs[0],
cv.getAsString(COLUMN_INSTANCE_LIST)
)
Assert.assertEquals(
exampleItemBookmark.commonsCategories[0],
cv.getAsString(COLUMN_CATEGORIES_LIST)
)
Assert.assertEquals(
exampleItemBookmark.isSelected,
cv.getAsBoolean(COLUMN_IS_SELECTED)
)
Assert.assertEquals(
exampleItemBookmark.id,
cv.getAsString(COLUMN_ID)
)
}
}
@Test
fun updateExistingItemBookmark() {
whenever(client.delete(isA(), isNull(), isNull())).thenReturn(1)
whenever(client.query(any(), any(), any(), any(), anyOrNull())).thenReturn(createCursor(1))
Assert.assertFalse(testObject.updateBookmarkItem(exampleItemBookmark))
verify(client).delete(eq(BookmarkItemsContentProvider.uriForName(exampleItemBookmark.id)),
isNull(), isNull())
}
@Test
fun findExistingItemBookmark() {
whenever(client.query(any(), any(), any(), any(), anyOrNull())).thenReturn(createCursor(1))
Assert.assertTrue(testObject.findBookmarkItem(exampleItemBookmark.id))
}
@Test(expected = RuntimeException::class)
fun findItemBookmarkTranslatesExceptions() {
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenThrow(
RemoteException("")
)
testObject.findBookmarkItem(exampleItemBookmark.id)
}
@Test
fun findNotExistingItemBookmarkReturnsNull_emptyCursor() {
whenever(client.query(any(), any(), any(), any(), anyOrNull())).thenReturn(createCursor(0))
Assert.assertFalse(testObject.findBookmarkItem(exampleItemBookmark.id))
}
@Test
fun findNotExistingItemBookmarkReturnsNull_nullCursor() {
whenever(client.query(any(), any(), any(), any(), anyOrNull())).thenReturn(null)
Assert.assertFalse(testObject.findBookmarkItem(exampleItemBookmark.id))
}
@Test
fun cursorsAreClosedAfterFindItemBookmarkQuery() {
val mockCursor: Cursor = mock()
whenever(client.query(any(), any(), any(), any(), anyOrNull())).thenReturn(mockCursor)
whenever(mockCursor.moveToFirst()).thenReturn(false)
testObject.findBookmarkItem(exampleItemBookmark.id)
verify(mockCursor).close()
}
@Test
fun migrateTableVersionFrom_v1_to_v2() {
onUpdate(database, 1, 2)
// Table didn't exist before v5
verifyZeroInteractions(database)
}
@Test
fun migrateTableVersionFrom_v2_to_v3() {
onUpdate(database, 2, 3)
// Table didn't exist before v5
verifyZeroInteractions(database)
}
@Test
fun migrateTableVersionFrom_v3_to_v4() {
onUpdate(database, 3, 4)
// Table didn't exist before v5
verifyZeroInteractions(database)
}
@Test
fun migrateTableVersionFrom_v4_to_v5() {
onUpdate(database, 4, 5)
// Table didn't change in version 5
verifyZeroInteractions(database)
}
@Test
fun migrateTableVersionFrom_v5_to_v6() {
onUpdate(database, 5, 6)
// Table didn't change in version 6
verifyZeroInteractions(database)
}
@Test
fun migrateTableVersionFrom_v6_to_v7() {
onUpdate(database, 6, 7)
// Table didn't change in version 7
verifyZeroInteractions(database)
}
@Test
fun migrateTableVersionFrom_v7_to_v8() {
onUpdate(database, 7, 8)
verify(database).execSQL(CREATE_TABLE_STATEMENT)
}
private fun createCursor(rowCount: Int) = MatrixCursor(columns, rowCount).apply {
for (i in 0 until rowCount) {
addRow(listOf("itemName", "itemDescription",
"itemImageUrl", "instance", "categories", false,
"itemID"))
}
}
}

View file

@ -0,0 +1,131 @@
package fr.free.nrw.commons.bookmarks.items
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.ProgressBar
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import androidx.recyclerview.widget.RecyclerView
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.R
import fr.free.nrw.commons.TestAppAdapter
import fr.free.nrw.commons.TestCommonsApplication
import fr.free.nrw.commons.profile.ProfileActivity
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
import org.robolectric.annotation.Config
import org.robolectric.annotation.LooperMode
import org.wikipedia.AppAdapter
import java.lang.reflect.Method
import java.util.*
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [21], application = TestCommonsApplication::class)
@LooperMode(LooperMode.Mode.PAUSED)
class BookmarkItemsFragmentUnitTest {
private lateinit var fragment: BookmarkItemsFragment
private lateinit var context: Context
private lateinit var view: View
private lateinit var statusTextView: TextView
private lateinit var progressBar: ProgressBar
private lateinit var recyclerView: RecyclerView
private lateinit var layoutInflater: LayoutInflater
@Mock
private lateinit var parentLayout: RelativeLayout
@Mock
private lateinit var savedInstanceState: Bundle
@Mock
private lateinit var controller: BookmarkItemsController
/**
* Get Mock bookmark list.
*/
private val mockBookmarkList: List<DepictedItem>
get() {
val list = ArrayList<DepictedItem>()
list.add(
DepictedItem(
"name", "description", "image url", listOf("instance"),
listOf("categories"), true, "id")
)
return list
}
/**
* fragment Setup
*/
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
context = RuntimeEnvironment.application.applicationContext
AppAdapter.set(TestAppAdapter())
val activity = Robolectric.buildActivity(ProfileActivity::class.java).create().get()
fragment = BookmarkItemsFragment.newInstance()
val fragmentManager: FragmentManager = activity.supportFragmentManager
val fragmentTransaction: FragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction.add(fragment, null)
fragmentTransaction.commit()
layoutInflater = LayoutInflater.from(activity)
view = layoutInflater
.inflate(R.layout.fragment_bookmarks_items, null) as View
statusTextView = view.findViewById(R.id.status_message)
progressBar = view.findViewById(R.id.loading_images_progress_bar)
recyclerView = view.findViewById(R.id.list_view)
fragment.statusTextView = statusTextView
fragment.progressBar = progressBar
fragment.recyclerView = recyclerView
fragment.parentLayout = parentLayout
fragment.controller = controller
}
/**
* test init items when non empty
*/
@Test
fun testInitNonEmpty(){
whenever(controller.loadFavoritesItems()).thenReturn(mockBookmarkList)
val method: Method =
BookmarkItemsFragment::class.java.getDeclaredMethod("initList", Context::class.java)
method.isAccessible = true
method.invoke(fragment, context)
}
/**
* test onCreateView
*/
@Test
@Throws(Exception::class)
fun testOnCreateView() {
fragment.onCreateView(layoutInflater,null,savedInstanceState)
}
/**
* check fragment notnull
*/
@Test
@Throws(Exception::class)
fun checkFragmentNotNull() {
Assert.assertNotNull(fragment)
}
}

View file

@ -50,6 +50,9 @@ class WikidataItemDetailsActivityUnitTests {
@Mock
private lateinit var depictedItem: DepictedItem
@Mock
private lateinit var wikidataItem: DepictedItem
@Mock
private lateinit var mediaContainer: FrameLayout
@ -92,6 +95,9 @@ class WikidataItemDetailsActivityUnitTests {
viewPager = parent.findViewById(R.id.viewPager)
Whitebox.setInternalState(activity, "viewPager", viewPager)
Whitebox.setInternalState(activity, "wikidataItem", wikidataItem)
}
@Test