Displaying Category image and Description (#4531)

* API call done

* API call

* Image implementation done

* Gradle

* Java docs and code convention

* Description added

* Refactoring Category

* Refactoring Category

* Refactoring Category

* Description and thumbnail issue fixed

* Description and thumbnail issue fixed

* Minor issue fixed

* Minor issue fixed

* Server changed

* Logo changed

* Change in structure

* Fixed failed tests

* Fixed Test failed

* Optimized imports

* Dialog can't be dismissed

* Dialog can't be dismissed

* Resolved Conflicts

* UI fixed

* Added description and thumbnail in local DB

* Added description and thumbnail in local DB

* Test fixed

* Added

* Updated with latest master

* Test Updated with latest master

* Issue fixed

* Revert gradle changes

* Revert gradle changes

* Update gradle-wrapper.properties

* Require Api removed
This commit is contained in:
Ayan Sarkar 2022-01-20 11:49:57 +05:30 committed by GitHub
parent 0914eeea53
commit 92957f4204
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 373 additions and 151 deletions

View file

@ -16,7 +16,7 @@ fun depictedItem(
description: String = "desc",
imageUrl: String = "",
instanceOfs: List<String> = listOf(),
commonsCategories: List<String> = listOf(),
commonsCategories: List<CategoryItem> = listOf(),
isSelected: Boolean = false,
id: String = "entityId"
) = DepictedItem(
@ -29,8 +29,9 @@ fun depictedItem(
id = id
)
fun categoryItem(name: String = "name", selected: Boolean = false) =
CategoryItem(name, selected)
fun categoryItem(name: String = "name", description: String = "desc",
thumbUrl: String = "thumbUrl", selected: Boolean = false) =
CategoryItem(name, description, thumbUrl, selected)
fun media(
thumbUrl: String? = "thumbUrl",

View file

@ -1,6 +1,7 @@
package fr.free.nrw.commons.bookmarks.items
import com.nhaarman.mockitokotlin2.whenever
import fr.free.nrw.commons.category.CategoryItem
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
import org.junit.Assert
import org.junit.Before
@ -33,7 +34,8 @@ class BookmarkItemsControllerTest {
list.add(
DepictedItem(
"name", "description", "image url", listOf("instance"),
listOf("categories"), true, "id")
listOf(CategoryItem("category name", "category description",
"category thumbnail", false)), true, "id")
)
return list
}

View file

@ -10,6 +10,7 @@ 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.category.CategoryItem
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
import org.junit.Assert
import org.junit.Before
@ -26,7 +27,9 @@ class BookmarkItemsDaoTest {
COLUMN_DESCRIPTION,
COLUMN_IMAGE,
COLUMN_INSTANCE_LIST,
COLUMN_CATEGORIES_LIST,
COLUMN_CATEGORIES_NAME_LIST,
COLUMN_CATEGORIES_DESCRIPTION_LIST,
COLUMN_CATEGORIES_THUMBNAIL_LIST,
COLUMN_IS_SELECTED,
COLUMN_ID,
)
@ -43,7 +46,10 @@ class BookmarkItemsDaoTest {
@Before
fun setUp() {
exampleItemBookmark = DepictedItem("itemName", "itemDescription",
"itemImageUrl", listOf("instance"), listOf("categories"), false,
"itemImageUrl", listOf("instance"), listOf(
CategoryItem("category name", "category description",
"category thumbnail", false)
), false,
"itemID")
testObject = BookmarkItemsDao { client }
}
@ -72,7 +78,9 @@ class BookmarkItemsDaoTest {
Assert.assertEquals("itemDescription", it.description)
Assert.assertEquals("itemImageUrl", it.imageUrl)
Assert.assertEquals(listOf("instance"), it.instanceOfs)
Assert.assertEquals(listOf("categories"), it.commonsCategories)
Assert.assertEquals(listOf(CategoryItem("category name",
"category description",
"category thumbnail", false)), it.commonsCategories)
Assert.assertEquals(false, it.isSelected)
Assert.assertEquals("itemID", it.id)
}
@ -131,7 +139,7 @@ class BookmarkItemsDaoTest {
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(9, cv.size())
Assert.assertEquals(
exampleItemBookmark.name,
cv.getAsString(COLUMN_NAME)
@ -149,8 +157,16 @@ class BookmarkItemsDaoTest {
cv.getAsString(COLUMN_INSTANCE_LIST)
)
Assert.assertEquals(
exampleItemBookmark.commonsCategories[0],
cv.getAsString(COLUMN_CATEGORIES_LIST)
exampleItemBookmark.commonsCategories[0].name,
cv.getAsString(COLUMN_CATEGORIES_NAME_LIST)
)
Assert.assertEquals(
exampleItemBookmark.commonsCategories[0].description,
cv.getAsString(COLUMN_CATEGORIES_DESCRIPTION_LIST)
)
Assert.assertEquals(
exampleItemBookmark.commonsCategories[0].thumbnail,
cv.getAsString(COLUMN_CATEGORIES_THUMBNAIL_LIST)
)
Assert.assertEquals(
exampleItemBookmark.isSelected,
@ -263,8 +279,8 @@ class BookmarkItemsDaoTest {
for (i in 0 until rowCount) {
addRow(listOf("itemName", "itemDescription",
"itemImageUrl", "instance", "categories", false,
"itemID"))
"itemImageUrl", "instance", "category name", "category description",
"category thumbnail", false, "itemID"))
}
}
}

View file

@ -14,6 +14,7 @@ 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.category.CategoryItem
import fr.free.nrw.commons.profile.ProfileActivity
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
import org.junit.Assert
@ -62,7 +63,10 @@ class BookmarkItemsFragmentUnitTest {
list.add(
DepictedItem(
"name", "description", "image url", listOf("instance"),
listOf("categories"), true, "id")
listOf(
CategoryItem("category name", "category description",
"category thumbnail", false)
), true, "id")
)
return list
}

View file

@ -34,7 +34,8 @@ class CategoriesModelTest {
fun searchAllFoundCaseTest() {
val categoriesModel = CategoriesModel(categoryClient, mock(), mock())
val expectedList = listOf("Test")
val expectedList = listOf(CategoryItem(
"Test", "", "", false))
whenever(
categoryClient.searchCategoriesForPrefix(
ArgumentMatchers.anyString(),
@ -45,7 +46,8 @@ class CategoriesModelTest {
.thenReturn(Single.just(expectedList))
// Checking if both return "Test"
val expectedItems = expectedList.map { CategoryItem(it, false) }
val expectedItems = expectedList.map { CategoryItem(
it.name, it.description, it.thumbnail, false) }
var categoryTerm = "Test"
categoriesModel.searchAll(categoryTerm, emptyList(), emptyList())
.test()
@ -65,10 +67,12 @@ class CategoriesModelTest {
@Test
fun `searchAll with empty search terms creates results from gps, title search & recents`() {
val gpsCategoryModel: GpsCategoryModel = mock()
val depictedItem = depictedItem(commonsCategories = listOf("depictionCategory"))
val depictedItem = depictedItem(commonsCategories = listOf(CategoryItem(
"depictionCategory", "", "", false)))
whenever(gpsCategoryModel.categoriesFromLocation)
.thenReturn(BehaviorSubject.createDefault(listOf("gpsCategory")))
.thenReturn(BehaviorSubject.createDefault(listOf(CategoryItem(
"gpsCategory", "", "", false))))
whenever(
categoryClient.searchCategories(
ArgumentMatchers.anyString(),
@ -76,8 +80,10 @@ class CategoriesModelTest {
ArgumentMatchers.anyInt()
)
)
.thenReturn(Single.just(listOf("titleSearch")))
whenever(categoryDao.recentCategories(25)).thenReturn(listOf("recentCategories"))
.thenReturn(Single.just(listOf(CategoryItem(
"titleSearch", "", "", false))))
whenever(categoryDao.recentCategories(25)).thenReturn(listOf(CategoryItem(
"recentCategories","","", false)))
val imageTitleList = listOf("Test")
CategoriesModel(categoryClient, categoryDao, gpsCategoryModel)
.searchAll("", imageTitleList, listOf(depictedItem))

View file

@ -34,10 +34,10 @@ class CategoryClientTest {
.thenReturn(Single.just(mockResponse))
categoryClient.searchCategories("tes", 10)
.test()
.assertValues(listOf("Test"))
.assertValues(listOf(CategoryItem("Test", "", "", false)))
categoryClient.searchCategories("tes", 10, 10)
.test()
.assertValues(listOf("Test"))
.assertValues(listOf(CategoryItem("Test", "", "", false)))
}
@Test
@ -59,10 +59,10 @@ class CategoryClientTest {
.thenReturn(Single.just(mockResponse))
categoryClient.searchCategoriesForPrefix("tes", 10)
.test()
.assertValues(listOf("Test"))
.assertValues(listOf(CategoryItem("Test", "", "", false)))
categoryClient.searchCategoriesForPrefix("tes", 10, 10)
.test()
.assertValues(listOf("Test"))
.assertValues(listOf(CategoryItem("Test", "", "", false)))
}
@Test
@ -84,7 +84,7 @@ class CategoryClientTest {
.thenReturn(Single.just(mockResponse))
categoryClient.getParentCategoryList("tes")
.test()
.assertValues(listOf("Test"))
.assertValues(listOf(CategoryItem("Test", "", "", false)))
}
@Test
@ -104,7 +104,7 @@ class CategoryClientTest {
.thenReturn(Single.just(mockResponse))
categoryClient.getSubCategoryList("tes")
.test()
.assertValues(listOf("Test"))
.assertValues(listOf(CategoryItem("Test", "", "", false)))
}
@Test

View file

@ -24,7 +24,8 @@ import java.util.*
@Config(sdk = [21], application = TestCommonsApplication::class)
class CategoryDaoTest {
private val columns = arrayOf(COLUMN_ID, COLUMN_NAME, COLUMN_LAST_USED, COLUMN_TIMES_USED)
private val columns = arrayOf(COLUMN_ID, COLUMN_NAME, COLUMN_DESCRIPTION,
COLUMN_THUMBNAIL, COLUMN_LAST_USED, COLUMN_TIMES_USED)
private val client: ContentProviderClient = mock()
private val database: SQLiteDatabase = mock()
private val captor = argumentCaptor<ContentValues>()
@ -122,8 +123,10 @@ class CategoryDaoTest {
verify(client).update(eq(category.contentUri), captor.capture(), isNull(), isNull())
captor.firstValue.let { cv ->
assertEquals(3, cv.size())
assertEquals(5, cv.size())
assertEquals(category.name, cv.getAsString(COLUMN_NAME))
assertEquals(category.description, cv.getAsString(COLUMN_DESCRIPTION))
assertEquals(category.thumbnail, cv.getAsString(COLUMN_THUMBNAIL))
assertEquals(category.lastUsed.time, cv.getAsLong(COLUMN_LAST_USED))
assertEquals(category.timesUsed, cv.getAsInteger(COLUMN_TIMES_USED))
}
@ -134,14 +137,17 @@ class CategoryDaoTest {
fun saveNewCategory() {
val contentUri = CategoryContentProvider.uriForId(111)
whenever(client.insert(isA(), isA())).thenReturn(contentUri)
val category = Category(null, "showImageWithItem", Date(234L), 1)
val category = Category(null, "showImageWithItem", "description",
"image", Date(234L), 1)
testObject.save(category)
verify(client).insert(eq(BASE_URI), captor.capture())
captor.firstValue.let { cv ->
assertEquals(3, cv.size())
assertEquals(5, cv.size())
assertEquals(category.name, cv.getAsString(COLUMN_NAME))
assertEquals(category.description, cv.getAsString(COLUMN_DESCRIPTION))
assertEquals(category.thumbnail, cv.getAsString(COLUMN_THUMBNAIL))
assertEquals(category.lastUsed.time, cv.getAsLong(COLUMN_LAST_USED))
assertEquals(category.timesUsed, cv.getAsInteger(COLUMN_TIMES_USED))
assertEquals(contentUri, category.contentUri)
@ -186,6 +192,8 @@ class CategoryDaoTest {
assertEquals(uriForId(1), category?.contentUri)
assertEquals("showImageWithItem", category?.name)
assertEquals("description", category?.description)
assertEquals("image", category?.thumbnail)
assertEquals(123L, category?.lastUsed?.time)
assertEquals(2, category?.timesUsed)
@ -241,7 +249,7 @@ class CategoryDaoTest {
val result = testObject.recentCategories(10)
assertEquals(1, result.size)
assertEquals("showImageWithItem", result[0])
assertEquals("showImageWithItem", result[0].name)
verify(client).query(
eq(BASE_URI),
@ -264,7 +272,7 @@ class CategoryDaoTest {
private fun createCursor(rowCount: Int) = MatrixCursor(columns, rowCount).apply {
for (i in 0 until rowCount) {
addRow(listOf("1", "showImageWithItem", "123", "2"))
addRow(listOf("1", "showImageWithItem", "description", "image", "123", "2"))
}
}

View file

@ -67,13 +67,15 @@ class CategoriesPresenterTest {
)
whenever(repository.containsYear("selected")).thenReturn(false)
whenever(repository.containsYear("doesContainYear")).thenReturn(true)
whenever(repository.selectedCategories).thenReturn(listOf(categoryItem("selected", true)))
whenever(repository.selectedCategories).thenReturn(listOf(
categoryItem("selected", "", "",true)))
categoriesPresenter.searchForCategories("test")
testScheduler.triggerActions()
verify(view).showProgress(true)
verify(view).showError(null)
verify(view).setCategories(null)
verify(view).setCategories(listOf(categoryItem("selected", true)))
verify(view).setCategories(listOf(
categoryItem("selected", "", "", true)))
verify(view).showProgress(false)
verifyNoMoreInteractions(view)
}

View file

@ -1,5 +1,6 @@
package fr.free.nrw.commons.upload
import fr.free.nrw.commons.category.CategoryItem
import org.junit.Before
import org.junit.Test
@ -18,7 +19,8 @@ class GpsCategoryModelTest {
@Test
fun `setCategoriesFromLocation emits the new value`() {
val expectedList = listOf("category")
val expectedList = listOf(
CategoryItem("category", "", "", false))
gpsCategoryModel.categoriesFromLocation.test()
.also { gpsCategoryModel.setCategoriesFromLocation(expectedList) }
.assertValues(emptyList(), expectedList)

View file

@ -110,7 +110,7 @@ class DepictedItemTest {
)
)
)
).commonsCategories,
).commonsCategories.map { it.name },
listOf("1", "2"))
}

View file

@ -1,5 +1,6 @@
package fr.free.nrw.commons.utils
import fr.free.nrw.commons.category.CategoryItem
import fr.free.nrw.commons.utils.StringSortingUtils.sortBySimilarity
import org.junit.Assert.assertEquals
import org.junit.Test
@ -9,8 +10,18 @@ class StringSortingUtilsTest {
@Test
fun testSortingNumbersBySimilarity() {
val actualList = listOf("1234567", "4567", "12345", "123", "1234")
val expectedList = listOf("1234", "12345", "123", "1234567", "4567")
val actualList = listOf(
CategoryItem("1234567", "", "", false),
CategoryItem("4567", "", "", false),
CategoryItem("12345", "", "", false),
CategoryItem("123", "", "", false),
CategoryItem("1234", "", "", false))
val expectedList = listOf(
CategoryItem("1234", "", "", false),
CategoryItem("12345", "", "", false),
CategoryItem("123", "", "", false),
CategoryItem("1234567", "", "", false),
CategoryItem("4567", "", "", false))
sort(actualList, sortBySimilarity("1234"))
@ -20,22 +31,22 @@ class StringSortingUtilsTest {
@Test
fun testSortingTextBySimilarity() {
val actualList = listOf(
"The quick brown fox",
"quick brown fox",
"The",
"The quick ",
"The fox",
"brown fox",
"fox"
CategoryItem("The quick brown fox", "", "", false),
CategoryItem("quick brown fox", "", "", false),
CategoryItem("The", "", "", false),
CategoryItem("The quick ", "", "", false),
CategoryItem("The fox", "", "", false),
CategoryItem("brown fox", "", "", false),
CategoryItem("fox", "", "", false)
)
val expectedList = listOf(
"The",
"The fox",
"The quick ",
"The quick brown fox",
"quick brown fox",
"brown fox",
"fox"
CategoryItem("The", "", "", false),
CategoryItem("The fox", "", "", false),
CategoryItem("The quick ", "", "", false),
CategoryItem("The quick brown fox", "", "", false),
CategoryItem("quick brown fox", "", "", false),
CategoryItem("brown fox", "", "", false),
CategoryItem("fox", "", "", false)
)
sort(actualList, sortBySimilarity("The"))
@ -46,18 +57,18 @@ class StringSortingUtilsTest {
@Test
fun testSortingSymbolsBySimilarity() {
val actualList = listOf(
"$$$$$",
"****",
"**$*",
"*$*$",
".*$"
CategoryItem("$$$$$", "", "", false),
CategoryItem("****", "", "", false),
CategoryItem("**$*", "", "", false),
CategoryItem("*$*$", "", "", false),
CategoryItem(".*$", "", "", false)
)
val expectedList = listOf(
"**$*",
"*$*$",
".*$",
"****",
"$$$$$"
CategoryItem("**$*", "", "", false),
CategoryItem("*$*$", "", "", false),
CategoryItem(".*$", "", "", false),
CategoryItem("****", "", "", false),
CategoryItem("$$$$$", "", "", false)
)
sort(actualList, sortBySimilarity("**$"))
@ -69,25 +80,25 @@ class StringSortingUtilsTest {
fun testSortingMixedStringsBySimilarity() {
// Sample from Category:2018 Android phones
val actualList = listOf(
"ASUS ZenFone 5 (2018)",
"Google Pixel 3",
"HTC U12",
"Huawei P20",
"LG G7 ThinQ",
"Samsung Galaxy A8 (2018)",
"Samsung Galaxy S9",
CategoryItem("ASUS ZenFone 5 (2018)", "", "", false),
CategoryItem("Google Pixel 3", "", "", false),
CategoryItem("HTC U12", "", "", false),
CategoryItem("Huawei P20", "", "", false),
CategoryItem("LG G7 ThinQ", "", "", false),
CategoryItem("Samsung Galaxy A8 (2018)", "", "", false),
CategoryItem("Samsung Galaxy S9", "", "", false),
// One with more complicated symbols
"MadeUpPhone 2018.$£#你好"
CategoryItem("MadeUpPhone 2018.$£#你好", "", "", false)
)
val expectedList = listOf(
"Samsung Galaxy S9",
"ASUS ZenFone 5 (2018)",
"Samsung Galaxy A8 (2018)",
"Google Pixel 3",
"HTC U12",
"Huawei P20",
"LG G7 ThinQ",
"MadeUpPhone 2018.$£#你好"
CategoryItem("Samsung Galaxy S9", "", "", false),
CategoryItem("ASUS ZenFone 5 (2018)", "", "", false),
CategoryItem("Samsung Galaxy A8 (2018)", "", "", false),
CategoryItem("Google Pixel 3", "", "", false),
CategoryItem("HTC U12", "", "", false),
CategoryItem("Huawei P20", "", "", false),
CategoryItem("LG G7 ThinQ", "", "", false),
CategoryItem("MadeUpPhone 2018.$£#你好", "", "", false)
)
sort(actualList, sortBySimilarity("S9"))
@ -98,26 +109,26 @@ class StringSortingUtilsTest {
@Test
fun testSortingWithEmptyStrings() {
val actualList = listOf(
"brown fox",
"",
"quick brown fox",
"the",
"",
"the fox",
"fox",
"",
""
CategoryItem("brown fox", "", "", false),
CategoryItem("", "", "", false),
CategoryItem("quick brown fox", "", "", false),
CategoryItem("the", "", "", false),
CategoryItem("", "", "", false),
CategoryItem("the fox", "", "", false),
CategoryItem("fox", "", "", false),
CategoryItem("", "", "", false),
CategoryItem("", "", "", false)
)
val expectedList = listOf(
"the fox",
"brown fox",
"the",
"fox",
"quick brown fox",
"",
"",
"",
""
CategoryItem("the fox", "", "", false),
CategoryItem("brown fox", "", "", false),
CategoryItem("the", "", "", false),
CategoryItem("fox", "", "", false),
CategoryItem("quick brown fox", "", "", false),
CategoryItem("", "", "", false),
CategoryItem("", "", "", false),
CategoryItem("", "", "", false),
CategoryItem("", "", "", false)
)
sort(actualList, sortBySimilarity("the fox"))