mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
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:
parent
0914eeea53
commit
92957f4204
31 changed files with 373 additions and 151 deletions
|
|
@ -5,6 +5,7 @@ import android.content.ContentValues;
|
|||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.RemoteException;
|
||||
import fr.free.nrw.commons.category.CategoryItem;
|
||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -141,9 +142,17 @@ public class BookmarkItemsDao {
|
|||
final String instanceListString
|
||||
= cursor.getString(cursor.getColumnIndex(Table.COLUMN_INSTANCE_LIST));
|
||||
final List<String> instanceList = StringToArray(instanceListString);
|
||||
final String categoryListString = cursor.getString(cursor
|
||||
.getColumnIndex(Table.COLUMN_CATEGORIES_LIST));
|
||||
final List<String> categoryList = StringToArray(categoryListString);
|
||||
final String categoryNameListString = cursor.getString(cursor
|
||||
.getColumnIndex(Table.COLUMN_CATEGORIES_NAME_LIST));
|
||||
final List<String> categoryNameList = StringToArray(categoryNameListString);
|
||||
final String categoryDescriptionListString = cursor.getString(cursor
|
||||
.getColumnIndex(Table.COLUMN_CATEGORIES_DESCRIPTION_LIST));
|
||||
final List<String> categoryDescriptionList = StringToArray(categoryDescriptionListString);
|
||||
final String categoryThumbnailListString = cursor.getString(cursor
|
||||
.getColumnIndex(Table.COLUMN_CATEGORIES_THUMBNAIL_LIST));
|
||||
final List<String> categoryThumbnailList = StringToArray(categoryThumbnailListString);
|
||||
final List<CategoryItem> categoryList = convertToCategoryItems(categoryNameList,
|
||||
categoryDescriptionList, categoryThumbnailList);
|
||||
final boolean isSelected
|
||||
= Boolean.parseBoolean(cursor.getString(cursor
|
||||
.getColumnIndex(Table.COLUMN_IS_SELECTED)));
|
||||
|
|
@ -160,6 +169,17 @@ public class BookmarkItemsDao {
|
|||
);
|
||||
}
|
||||
|
||||
private List<CategoryItem> convertToCategoryItems(List<String> categoryNameList,
|
||||
List<String> categoryDescriptionList, List<String> categoryThumbnailList) {
|
||||
List<CategoryItem> categoryItems = new ArrayList<>();
|
||||
for(int i=0; i<categoryNameList.size(); i++){
|
||||
categoryItems.add(new CategoryItem(categoryNameList.get(i),
|
||||
categoryDescriptionList.get(i),
|
||||
categoryThumbnailList.get(i), false));
|
||||
}
|
||||
return categoryItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts string to List
|
||||
* @param listString comma separated single string from of list items
|
||||
|
|
@ -188,12 +208,35 @@ public class BookmarkItemsDao {
|
|||
* @return ContentValues
|
||||
*/
|
||||
private ContentValues toContentValues(final DepictedItem depictedItem) {
|
||||
|
||||
final List<String> namesOfCommonsCategories = new ArrayList<>();
|
||||
for (final CategoryItem category :
|
||||
depictedItem.getCommonsCategories()) {
|
||||
namesOfCommonsCategories.add(category.getName());
|
||||
}
|
||||
|
||||
final List<String> descriptionsOfCommonsCategories = new ArrayList<>();
|
||||
for (final CategoryItem category :
|
||||
depictedItem.getCommonsCategories()) {
|
||||
descriptionsOfCommonsCategories.add(category.getDescription());
|
||||
}
|
||||
|
||||
final List<String> thumbnailsOfCommonsCategories = new ArrayList<>();
|
||||
for (final CategoryItem category :
|
||||
depictedItem.getCommonsCategories()) {
|
||||
thumbnailsOfCommonsCategories.add(category.getThumbnail());
|
||||
}
|
||||
|
||||
final ContentValues cv = new ContentValues();
|
||||
cv.put(Table.COLUMN_NAME, depictedItem.getName());
|
||||
cv.put(Table.COLUMN_DESCRIPTION, depictedItem.getDescription());
|
||||
cv.put(Table.COLUMN_IMAGE, depictedItem.getImageUrl());
|
||||
cv.put(Table.COLUMN_INSTANCE_LIST, ArrayToString(depictedItem.getInstanceOfs()));
|
||||
cv.put(Table.COLUMN_CATEGORIES_LIST, ArrayToString(depictedItem.getCommonsCategories()));
|
||||
cv.put(Table.COLUMN_CATEGORIES_NAME_LIST, ArrayToString(namesOfCommonsCategories));
|
||||
cv.put(Table.COLUMN_CATEGORIES_DESCRIPTION_LIST,
|
||||
ArrayToString(descriptionsOfCommonsCategories));
|
||||
cv.put(Table.COLUMN_CATEGORIES_THUMBNAIL_LIST,
|
||||
ArrayToString(thumbnailsOfCommonsCategories));
|
||||
cv.put(Table.COLUMN_IS_SELECTED, depictedItem.isSelected());
|
||||
cv.put(Table.COLUMN_ID, depictedItem.getId());
|
||||
return cv;
|
||||
|
|
@ -208,7 +251,9 @@ public class BookmarkItemsDao {
|
|||
public static final String COLUMN_DESCRIPTION = "item_description";
|
||||
public static final String COLUMN_IMAGE = "item_image_url";
|
||||
public static final String COLUMN_INSTANCE_LIST = "item_instance_of";
|
||||
public static final String COLUMN_CATEGORIES_LIST = "item_categories";
|
||||
public static final String COLUMN_CATEGORIES_NAME_LIST = "item_name_categories";
|
||||
public static final String COLUMN_CATEGORIES_DESCRIPTION_LIST = "item_description_categories";
|
||||
public static final String COLUMN_CATEGORIES_THUMBNAIL_LIST = "item_thumbnail_categories";
|
||||
public static final String COLUMN_IS_SELECTED = "item_is_selected";
|
||||
public static final String COLUMN_ID = "item_id";
|
||||
|
||||
|
|
@ -217,7 +262,9 @@ public class BookmarkItemsDao {
|
|||
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
|
||||
};
|
||||
|
|
@ -228,7 +275,9 @@ public class BookmarkItemsDao {
|
|||
+ COLUMN_DESCRIPTION + " STRING,"
|
||||
+ COLUMN_IMAGE + " STRING,"
|
||||
+ COLUMN_INSTANCE_LIST + " STRING,"
|
||||
+ COLUMN_CATEGORIES_LIST + " STRING,"
|
||||
+ COLUMN_CATEGORIES_NAME_LIST + " STRING,"
|
||||
+ COLUMN_CATEGORIES_DESCRIPTION_LIST + " STRING,"
|
||||
+ COLUMN_CATEGORIES_THUMBNAIL_LIST + " STRING,"
|
||||
+ COLUMN_IS_SELECTED + " STRING,"
|
||||
+ COLUMN_ID + " STRING PRIMARY KEY"
|
||||
+ ");";
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class CategoriesModel @Inject constructor(
|
|||
|
||||
// Newly used category...
|
||||
if (category == null) {
|
||||
category = Category(null, item.name, Date(), 0)
|
||||
category = Category(null, item.name, item.description, item.thumbnail, Date(), 0)
|
||||
}
|
||||
category.incTimesUsed()
|
||||
categoryDao.save(category)
|
||||
|
|
@ -74,14 +74,14 @@ class CategoriesModel @Inject constructor(
|
|||
selectedDepictions: List<DepictedItem>
|
||||
): Observable<List<CategoryItem>> {
|
||||
return suggestionsOrSearch(term, imageTitleList, selectedDepictions)
|
||||
.map { it.map { CategoryItem(it, false) } }
|
||||
.map { it.map { CategoryItem(it.name, it.description, it.thumbnail, false) } }
|
||||
}
|
||||
|
||||
private fun suggestionsOrSearch(
|
||||
term: String,
|
||||
imageTitleList: List<String>,
|
||||
selectedDepictions: List<DepictedItem>
|
||||
): Observable<List<String>> {
|
||||
): Observable<List<CategoryItem>> {
|
||||
return if (TextUtils.isEmpty(term))
|
||||
Observable.combineLatest(
|
||||
categoriesFromDepiction(selectedDepictions),
|
||||
|
|
@ -100,10 +100,10 @@ class CategoriesModel @Inject constructor(
|
|||
Observable.just(selectedDepictions.map { it.commonsCategories }.flatten())
|
||||
|
||||
private fun combine(
|
||||
depictionCategories: List<String>,
|
||||
locationCategories: List<String>,
|
||||
titles: List<String>,
|
||||
recents: List<String>
|
||||
depictionCategories: List<CategoryItem>,
|
||||
locationCategories: List<CategoryItem>,
|
||||
titles: List<CategoryItem>,
|
||||
recents: List<CategoryItem>
|
||||
) = depictionCategories + locationCategories + titles + recents
|
||||
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ class CategoriesModel @Inject constructor(
|
|||
private fun titleCategories(titleList: List<String>) =
|
||||
if (titleList.isNotEmpty())
|
||||
Observable.combineLatest(titleList.map { getTitleCategories(it) }) { searchResults ->
|
||||
searchResults.map { it as List<String> }.flatten()
|
||||
searchResults.map { it as List<CategoryItem> }.flatten()
|
||||
}
|
||||
else
|
||||
Observable.just(emptyList())
|
||||
|
|
@ -125,7 +125,7 @@ class CategoriesModel @Inject constructor(
|
|||
* @param title
|
||||
* @return
|
||||
*/
|
||||
private fun getTitleCategories(title: String): Observable<List<String>> {
|
||||
private fun getTitleCategories(title: String): Observable<List<CategoryItem>> {
|
||||
return categoryClient.searchCategories(title, SEARCH_CATS_LIMIT).toObservable()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,15 +10,19 @@ import java.util.Date;
|
|||
public class Category {
|
||||
private Uri contentUri;
|
||||
private String name;
|
||||
private String description;
|
||||
private String thumbnail;
|
||||
private Date lastUsed;
|
||||
private int timesUsed;
|
||||
|
||||
public Category() {
|
||||
}
|
||||
|
||||
public Category(Uri contentUri, String name, Date lastUsed, int timesUsed) {
|
||||
public Category(Uri contentUri, String name, String description, String thumbnail, Date lastUsed, int timesUsed) {
|
||||
this.contentUri = contentUri;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.thumbnail = thumbnail;
|
||||
this.lastUsed = lastUsed;
|
||||
this.timesUsed = timesUsed;
|
||||
}
|
||||
|
|
@ -93,4 +97,19 @@ public class Category {
|
|||
this.contentUri = contentUri;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getThumbnail() {
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
public void setDescription(final String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public void setThumbnail(final String thumbnail) {
|
||||
this.thumbnail = thumbnail;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ const val CATEGORY_NEEDING_CATEGORIES = "needing categories"
|
|||
*/
|
||||
@Singleton
|
||||
class CategoryClient @Inject constructor(private val categoryInterface: CategoryInterface) :
|
||||
ContinuationClient<MwQueryResponse, String>() {
|
||||
ContinuationClient<MwQueryResponse, CategoryItem>() {
|
||||
|
||||
/**
|
||||
* Searches for categories containing the specified string.
|
||||
|
|
@ -28,7 +28,7 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
|||
*/
|
||||
@JvmOverloads
|
||||
fun searchCategories(filter: String?, itemLimit: Int, offset: Int = 0):
|
||||
Single<List<String>> {
|
||||
Single<List<CategoryItem>> {
|
||||
return responseMapper(categoryInterface.searchCategories(filter, itemLimit, offset))
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
|||
*/
|
||||
@JvmOverloads
|
||||
fun searchCategoriesForPrefix(prefix: String?, itemLimit: Int, offset: Int = 0):
|
||||
Single<List<String>> {
|
||||
Single<List<CategoryItem>> {
|
||||
return responseMapper(
|
||||
categoryInterface.searchCategoriesForPrefix(prefix, itemLimit, offset)
|
||||
)
|
||||
|
|
@ -55,7 +55,7 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
|||
* @param categoryName Category name as defined on commons
|
||||
* @return Observable emitting the categories returned. If our search yielded "Category:Test", "Test" is emitted.
|
||||
*/
|
||||
fun getSubCategoryList(categoryName: String): Single<List<String>> {
|
||||
fun getSubCategoryList(categoryName: String): Single<List<CategoryItem>> {
|
||||
return continuationRequest(SUB_CATEGORY_CONTINUATION_PREFIX, categoryName) {
|
||||
categoryInterface.getSubCategoryList(
|
||||
categoryName, it
|
||||
|
|
@ -70,7 +70,7 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
|||
* @param categoryName Category name as defined on commons
|
||||
* @return
|
||||
*/
|
||||
fun getParentCategoryList(categoryName: String): Single<List<String>> {
|
||||
fun getParentCategoryList(categoryName: String): Single<List<CategoryItem>> {
|
||||
return continuationRequest(PARENT_CATEGORY_CONTINUATION_PREFIX, categoryName) {
|
||||
categoryInterface.getParentCategoryList(categoryName, it)
|
||||
}
|
||||
|
|
@ -87,7 +87,7 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
|||
override fun responseMapper(
|
||||
networkResult: Single<MwQueryResponse>,
|
||||
key: String?
|
||||
): Single<List<String>> {
|
||||
): Single<List<CategoryItem>> {
|
||||
return networkResult
|
||||
.map {
|
||||
handleContinuationResponse(it.continuation(), key)
|
||||
|
|
@ -96,7 +96,10 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
|||
.map {
|
||||
it.filter {
|
||||
page -> page.categoryInfo() == null || !page.categoryInfo().isHidden
|
||||
}.map { page -> page.title().replace(CATEGORY_PREFIX, "") }
|
||||
}.map {
|
||||
CategoryItem(it.title().replace(CATEGORY_PREFIX, ""),
|
||||
it.description().toString(), it.thumbUrl().toString(), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,8 +79,8 @@ public class CategoryDao {
|
|||
* @return a list containing recent categories
|
||||
*/
|
||||
@NonNull
|
||||
List<String> recentCategories(int limit) {
|
||||
List<String> items = new ArrayList<>();
|
||||
List<CategoryItem> recentCategories(int limit) {
|
||||
List<CategoryItem> items = new ArrayList<>();
|
||||
Cursor cursor = null;
|
||||
ContentProviderClient db = clientProvider.get();
|
||||
try {
|
||||
|
|
@ -93,7 +93,9 @@ public class CategoryDao {
|
|||
// fixme add a limit on the original query instead of falling out of the loop?
|
||||
while (cursor != null && cursor.moveToNext()
|
||||
&& cursor.getPosition() < limit) {
|
||||
items.add(fromCursor(cursor).getName());
|
||||
items.add(new CategoryItem(fromCursor(cursor).getName(),
|
||||
fromCursor(cursor).getDescription(), fromCursor(cursor).getThumbnail(),
|
||||
false));
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
|
@ -112,6 +114,8 @@ public class CategoryDao {
|
|||
return new Category(
|
||||
CategoryContentProvider.uriForId(cursor.getInt(cursor.getColumnIndex(Table.COLUMN_ID))),
|
||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_NAME)),
|
||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_DESCRIPTION)),
|
||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_THUMBNAIL)),
|
||||
new Date(cursor.getLong(cursor.getColumnIndex(Table.COLUMN_LAST_USED))),
|
||||
cursor.getInt(cursor.getColumnIndex(Table.COLUMN_TIMES_USED))
|
||||
);
|
||||
|
|
@ -120,6 +124,8 @@ public class CategoryDao {
|
|||
private ContentValues toContentValues(Category category) {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(CategoryDao.Table.COLUMN_NAME, category.getName());
|
||||
cv.put(Table.COLUMN_DESCRIPTION, category.getDescription());
|
||||
cv.put(Table.COLUMN_THUMBNAIL, category.getThumbnail());
|
||||
cv.put(CategoryDao.Table.COLUMN_LAST_USED, category.getLastUsed().getTime());
|
||||
cv.put(CategoryDao.Table.COLUMN_TIMES_USED, category.getTimesUsed());
|
||||
return cv;
|
||||
|
|
@ -130,6 +136,8 @@ public class CategoryDao {
|
|||
|
||||
public static final String COLUMN_ID = "_id";
|
||||
static final String COLUMN_NAME = "name";
|
||||
static final String COLUMN_DESCRIPTION = "description";
|
||||
static final String COLUMN_THUMBNAIL = "thumbnail";
|
||||
static final String COLUMN_LAST_USED = "last_used";
|
||||
static final String COLUMN_TIMES_USED = "times_used";
|
||||
|
||||
|
|
@ -137,6 +145,8 @@ public class CategoryDao {
|
|||
public static final String[] ALL_FIELDS = {
|
||||
COLUMN_ID,
|
||||
COLUMN_NAME,
|
||||
COLUMN_DESCRIPTION,
|
||||
COLUMN_THUMBNAIL,
|
||||
COLUMN_LAST_USED,
|
||||
COLUMN_TIMES_USED
|
||||
};
|
||||
|
|
@ -146,6 +156,8 @@ public class CategoryDao {
|
|||
static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ COLUMN_ID + " INTEGER PRIMARY KEY,"
|
||||
+ COLUMN_NAME + " STRING,"
|
||||
+ COLUMN_DESCRIPTION + " STRING,"
|
||||
+ COLUMN_THUMBNAIL + " STRING,"
|
||||
+ COLUMN_LAST_USED + " INTEGER,"
|
||||
+ COLUMN_TIMES_USED + " INTEGER"
|
||||
+ ");";
|
||||
|
|
|
|||
|
|
@ -94,8 +94,14 @@ public class CategoryEditSearchRecyclerViewAdapter
|
|||
@Override
|
||||
protected FilterResults performFiltering(CharSequence constraint) {
|
||||
FilterResults results = new FilterResults();
|
||||
List<String> resultCategories = categoryClient.searchCategories(constraint.toString(), 10).blockingGet();
|
||||
results.values = resultCategories;
|
||||
List<CategoryItem> resultCategories = categoryClient
|
||||
.searchCategories(constraint.toString(), 10).blockingGet();
|
||||
final List<String> namesOfCommonsCategories = new ArrayList<>();
|
||||
for (final CategoryItem category :
|
||||
resultCategories) {
|
||||
namesOfCommonsCategories.add(category.getName());
|
||||
}
|
||||
results.values = namesOfCommonsCategories;
|
||||
results.count = resultCategories.size();
|
||||
return results;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@ public interface CategoryInterface {
|
|||
* @return
|
||||
*/
|
||||
@GET("w/api.php?action=query&format=json&formatversion=2"
|
||||
+ "&generator=search&gsrnamespace=14")
|
||||
+ "&generator=search&prop=description|pageimages&piprop=thumbnail&pithumbsize=70"
|
||||
+ "&gsrnamespace=14")
|
||||
Single<MwQueryResponse> searchCategories(@Query("gsrsearch") String filter,
|
||||
@Query("gsrlimit") int itemLimit, @Query("gsroffset") int offset);
|
||||
@Query("gsrlimit") int itemLimit,
|
||||
@Query("gsroffset") int offset);
|
||||
|
||||
/**
|
||||
* Searches for categories starting with the specified prefix.
|
||||
|
|
@ -32,9 +34,11 @@ public interface CategoryInterface {
|
|||
* @return
|
||||
*/
|
||||
@GET("w/api.php?action=query&format=json&formatversion=2"
|
||||
+ "&generator=allcategories&prop=categoryinfo")
|
||||
+ "&generator=allcategories&prop=categoryinfo|description|pageimages&piprop=thumbnail"
|
||||
+ "&pithumbsize=70")
|
||||
Single<MwQueryResponse> searchCategoriesForPrefix(@Query("gacprefix") String prefix,
|
||||
@Query("gaclimit") int itemLimit, @Query("gacoffset") int offset);
|
||||
@Query("gaclimit") int itemLimit,
|
||||
@Query("gacoffset") int offset);
|
||||
|
||||
@GET("w/api.php?action=query&format=json&formatversion=2"
|
||||
+ "&generator=categorymembers&gcmtype=subcat"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ import android.os.Parcelable
|
|||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class CategoryItem(val name: String, var isSelected: Boolean) : Parcelable {
|
||||
data class CategoryItem(val name: String, val description: String,
|
||||
val thumbnail: String, var isSelected: Boolean) : Parcelable {
|
||||
|
||||
override fun toString(): String {
|
||||
return "CategoryItem: '$name'"
|
||||
|
|
|
|||
|
|
@ -250,8 +250,10 @@ public class NetworkingModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
public CategoryInterface provideCategoryInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) {
|
||||
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, CategoryInterface.class);
|
||||
public CategoryInterface provideCategoryInterface(
|
||||
@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) {
|
||||
return ServiceFactory
|
||||
.get(commonsWikiSite, BuildConfig.COMMONS_URL, CategoryInterface.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -14,6 +14,6 @@ class PageableParentCategoriesDataSource @Inject constructor(
|
|||
if (startPosition == 0) {
|
||||
categoryClient.resetParentCategoryContinuation(query)
|
||||
}
|
||||
categoryClient.getParentCategoryList(query).blockingGet()
|
||||
categoryClient.getParentCategoryList(query).blockingGet().map { it.name }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,5 +12,6 @@ class PageableSearchCategoriesDataSource @Inject constructor(
|
|||
|
||||
override val loadFunction = { loadSize: Int, startPosition: Int ->
|
||||
categoryClient.searchCategories(query, loadSize, startPosition).blockingGet()
|
||||
.map { it.name }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,6 @@ class PageableSubCategoriesDataSource @Inject constructor(
|
|||
if (startPosition == 0) {
|
||||
categoryClient.resetSubCategoryContinuation(query)
|
||||
}
|
||||
categoryClient.getSubCategoryList(query).blockingGet()
|
||||
categoryClient.getSubCategoryList(query).blockingGet().map { it.name }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package fr.free.nrw.commons.mwapi;
|
|||
import static fr.free.nrw.commons.category.CategoryClientKt.CATEGORY_PREFIX;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import fr.free.nrw.commons.category.CategoryItem;
|
||||
import io.reactivex.Single;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
|
@ -40,7 +41,7 @@ public class CategoryApi {
|
|||
this.gson = gson;
|
||||
}
|
||||
|
||||
public Single<List<String>> request(String coords) {
|
||||
public Single<List<CategoryItem>> request(String coords) {
|
||||
return Single.fromCallable(() -> {
|
||||
HttpUrl apiUrl = buildUrl(coords);
|
||||
Timber.d("URL: %s", apiUrl.toString());
|
||||
|
|
@ -53,12 +54,12 @@ public class CategoryApi {
|
|||
}
|
||||
|
||||
MwQueryResponse apiResponse = gson.fromJson(body.charStream(), MwQueryResponse.class);
|
||||
Set<String> categories = new LinkedHashSet<>();
|
||||
Set<CategoryItem> categories = new LinkedHashSet<>();
|
||||
if (apiResponse != null && apiResponse.query() != null && apiResponse.query().pages() != null) {
|
||||
for (MwQueryPage page : apiResponse.query().pages()) {
|
||||
if (page.categories() != null) {
|
||||
for (MwQueryPage.Category category : page.categories()) {
|
||||
categories.add(category.title().replace(CATEGORY_PREFIX, ""));
|
||||
categories.add(new CategoryItem(category.title().replace(CATEGORY_PREFIX, ""), "", "", false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
package fr.free.nrw.commons.upload
|
||||
|
||||
import fr.free.nrw.commons.category.CategoryItem
|
||||
import io.reactivex.subjects.BehaviorSubject
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class GpsCategoryModel @Inject constructor() {
|
||||
val categoriesFromLocation = BehaviorSubject.createDefault(emptyList<String>())
|
||||
val categoriesFromLocation = BehaviorSubject.createDefault(emptyList<CategoryItem>())
|
||||
|
||||
fun clear() {
|
||||
categoriesFromLocation.onNext(emptyList())
|
||||
}
|
||||
|
||||
fun setCategoriesFromLocation(categoryList: List<String>) {
|
||||
fun setCategoriesFromLocation(categoryList: List<CategoryItem>) {
|
||||
categoriesFromLocation.onNext(categoryList)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package fr.free.nrw.commons.upload.categories
|
||||
|
||||
import fr.free.nrw.commons.category.CategoryItem
|
||||
import org.jetbrains.annotations.NotNull
|
||||
|
||||
class UploadCategoryAdapter(onCategoryClicked: (CategoryItem) -> Unit) :
|
||||
class UploadCategoryAdapter(
|
||||
onCategoryClicked: @NotNull() (CategoryItem) -> Unit) :
|
||||
BaseDelegateAdapter<CategoryItem>(
|
||||
uploadCategoryDelegate(onCategoryClicked),
|
||||
areItemsTheSame = { oldItem, newItem -> oldItem.name == newItem.name },
|
||||
|
|
|
|||
|
|
@ -1,20 +1,38 @@
|
|||
package fr.free.nrw.commons.upload.categories
|
||||
|
||||
import android.view.View
|
||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.category.CategoryItem
|
||||
import fr.free.nrw.commons.databinding.LayoutUploadCategoriesItemBinding
|
||||
|
||||
fun uploadCategoryDelegate(onCategoryClicked: (CategoryItem) -> Unit) =
|
||||
adapterDelegateViewBinding<CategoryItem, CategoryItem, LayoutUploadCategoriesItemBinding>({ layoutInflater, root ->
|
||||
adapterDelegateViewBinding<CategoryItem, CategoryItem,
|
||||
LayoutUploadCategoriesItemBinding>({ layoutInflater, root ->
|
||||
LayoutUploadCategoriesItemBinding.inflate(layoutInflater, root, false)
|
||||
}) {
|
||||
binding.root.setOnClickListener {
|
||||
val onClickListener = { _: View? ->
|
||||
item.isSelected = !item.isSelected
|
||||
binding.uploadCategoryCheckbox.isChecked = item.isSelected
|
||||
onCategoryClicked(item)
|
||||
}
|
||||
|
||||
binding.root.setOnClickListener(onClickListener)
|
||||
binding.uploadCategoryCheckbox.setOnClickListener(onClickListener)
|
||||
|
||||
bind {
|
||||
binding.uploadCategoryCheckbox.isChecked = item.isSelected
|
||||
binding.uploadCategoryCheckbox.text = item.name
|
||||
binding.categoryLabel.text = item.name
|
||||
if(item.thumbnail != "null") {
|
||||
binding.categoryImage.setImageURI(item.thumbnail)
|
||||
} else {
|
||||
binding.categoryImage.setActualImageResource(R.drawable.commons)
|
||||
}
|
||||
|
||||
if(item.description != "null") {
|
||||
binding.categoryDescription.text = item.description
|
||||
} else {
|
||||
binding.categoryDescription.text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package fr.free.nrw.commons.upload.structure.depictions
|
|||
import android.os.Parcelable
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import fr.free.nrw.commons.category.CategoryItem
|
||||
import fr.free.nrw.commons.nearby.Place
|
||||
import fr.free.nrw.commons.upload.WikidataItem
|
||||
import fr.free.nrw.commons.wikidata.WikidataProperties
|
||||
|
|
@ -28,7 +29,7 @@ data class DepictedItem constructor(
|
|||
val description: String?,
|
||||
val imageUrl: String?,
|
||||
val instanceOfs: List<String>,
|
||||
val commonsCategories: List<String>,
|
||||
val commonsCategories: List<CategoryItem>,
|
||||
var isSelected: Boolean,
|
||||
@PrimaryKey override val id: String
|
||||
) : WikidataItem, Parcelable {
|
||||
|
|
@ -52,7 +53,8 @@ data class DepictedItem constructor(
|
|||
getImageUrl(it.value, THUMB_IMAGE_SIZE)
|
||||
},
|
||||
entity[INSTANCE_OF].toIds(),
|
||||
entity[COMMONS_CATEGORY]?.map { (it.mainSnak.dataValue as DataValue.ValueString).value }
|
||||
entity[COMMONS_CATEGORY]?.map { CategoryItem((it.mainSnak.dataValue as DataValue.ValueString).value,
|
||||
"", "", false) }
|
||||
?: emptyList(),
|
||||
false,
|
||||
entity.id()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package fr.free.nrw.commons.utils;
|
||||
|
||||
import fr.free.nrw.commons.category.CategoryItem;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class StringSortingUtils {
|
||||
|
|
@ -16,10 +17,10 @@ public class StringSortingUtils {
|
|||
* @param filter String to compare similarity with
|
||||
* @return Comparator with string similarity
|
||||
*/
|
||||
public static Comparator<String> sortBySimilarity(final String filter) {
|
||||
public static Comparator<CategoryItem> sortBySimilarity(final String filter) {
|
||||
return (firstItem, secondItem) -> {
|
||||
double firstItemSimilarity = calculateSimilarity(firstItem, filter);
|
||||
double secondItemSimilarity = calculateSimilarity(secondItem, filter);
|
||||
double firstItemSimilarity = calculateSimilarity(firstItem.getName(), filter);
|
||||
double secondItemSimilarity = calculateSimilarity(secondItem.getName(), filter);
|
||||
return (int) Math.signum(secondItemSimilarity - firstItemSimilarity);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/uploadCategoryCheckbox"
|
||||
android:layout_width="match_parent"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/category_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/upload_category_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checkMark="?android:attr/textCheckMark"
|
||||
android:checked="false"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="@dimen/tiny_gap"/>
|
||||
android:padding="@dimen/tiny_gap"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/category_image"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.facebook.drawee.view.SimpleDraweeView
|
||||
android:id="@+id/category_image"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="50dp"
|
||||
android:paddingEnd="@dimen/tiny_gap"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@+id/upload_category_checkbox"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:placeholderImage="@drawable/commons" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/category_image"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/category_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="@string/label"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/category_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="@string/description" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -652,6 +652,8 @@ Upload your first media by tapping on the add button.</string>
|
|||
The shadow of the image view of the location picker</string>
|
||||
<string name="image_location">Image Location</string>
|
||||
<string name="check_whether_location_is_correct">Check whether location is correct</string>
|
||||
<string name="label">Label</string>
|
||||
<string name="description">Description</string>
|
||||
<string name="title_page_bookmarks_items">Items</string>
|
||||
<string name="custom_selector_title">Custom Selector</string>
|
||||
<string name="custom_selector_empty_text">No Images</string>
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class DepictedItemTest {
|
|||
)
|
||||
)
|
||||
)
|
||||
).commonsCategories,
|
||||
).commonsCategories.map { it.name },
|
||||
listOf("1", "2"))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue