mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Makes depicted place and category items unselectable for nearby place (#5325)
* Makes depicted place and category items unselectable for nearby place * UploadCategoriesFragmentUnitTests.kt fixes and javadoc addition * comment fix * Fixes tests and hidden category appearing and dissapearing issue
This commit is contained in:
parent
05fbfce865
commit
733c8709fc
15 changed files with 229 additions and 66 deletions
|
|
@ -136,7 +136,11 @@ class CategoriesModel @Inject constructor(
|
|||
return Observable.fromIterable(categoryNames)
|
||||
.map { categoryName ->
|
||||
buildCategories(categoryName)
|
||||
}.toList().toObservable()
|
||||
}
|
||||
.filter { categoryItem ->
|
||||
categoryItem.name != "Hidden"
|
||||
}
|
||||
.toList().toObservable()
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -293,6 +293,23 @@ public class UploadRepository {
|
|||
return depictModel.getPlaceDepictions(new ArrayList<>(qids));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the category for each unique {@link Place} associated with an {@link UploadItem}
|
||||
* from {@link #getUploads()}
|
||||
*
|
||||
* @return a single that provides the categories
|
||||
*/
|
||||
public Single<List<CategoryItem>> getPlaceCategories() {
|
||||
final Set<String> qids = new HashSet<>();
|
||||
for (final UploadItem item : getUploads()) {
|
||||
final Place place = item.getPlace();
|
||||
if (place != null) {
|
||||
qids.add(place.getCategory());
|
||||
}
|
||||
}
|
||||
return Single.fromObservable(categoriesModel.getCategoriesByName(new ArrayList<>(qids)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes depict IDs as a parameter, converts into a slash separated String and Gets DepictItem
|
||||
* from the server
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package fr.free.nrw.commons.upload;
|
|||
import static fr.free.nrw.commons.contributions.ContributionController.ACTION_INTERNAL_UPLOADS;
|
||||
import static fr.free.nrw.commons.utils.PermissionUtils.PERMISSIONS_STORAGE;
|
||||
import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT;
|
||||
import static fr.free.nrw.commons.wikidata.WikidataConstants.SELECTED_NEARBY_PLACE;
|
||||
import static fr.free.nrw.commons.wikidata.WikidataConstants.SELECTED_NEARBY_PLACE_CATEGORY;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
|
|
@ -483,9 +485,17 @@ public class UploadActivity extends BaseActivity implements UploadContract.View,
|
|||
}
|
||||
|
||||
uploadCategoriesFragment = new UploadCategoriesFragment();
|
||||
if (place != null) {
|
||||
Bundle categoryBundle = new Bundle();
|
||||
categoryBundle.putString(SELECTED_NEARBY_PLACE_CATEGORY, place.getCategory());
|
||||
uploadCategoriesFragment.setArguments(categoryBundle);
|
||||
}
|
||||
uploadCategoriesFragment.setCallback(this);
|
||||
|
||||
depictsFragment = new DepictsFragment();
|
||||
Bundle placeBundle = new Bundle();
|
||||
placeBundle.putParcelable(SELECTED_NEARBY_PLACE, place);
|
||||
depictsFragment.setArguments(placeBundle);
|
||||
depictsFragment.setCallback(this);
|
||||
|
||||
mediaLicenseFragment = new MediaLicenseFragment();
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package fr.free.nrw.commons.upload.categories;
|
|||
|
||||
import android.content.Context;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import fr.free.nrw.commons.BasePresenter;
|
||||
import fr.free.nrw.commons.Media;
|
||||
import fr.free.nrw.commons.category.CategoryItem;
|
||||
|
|
@ -80,6 +81,9 @@ public interface CategoriesContract {
|
|||
*/
|
||||
void updateCategories(Media media, String wikiText);
|
||||
|
||||
LiveData<List<CategoryItem>> getCategories();
|
||||
|
||||
void selectCategories();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package fr.free.nrw.commons.upload.categories
|
||||
|
||||
import android.text.TextUtils
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import fr.free.nrw.commons.Media
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.category.CategoryEditHelper
|
||||
|
|
@ -36,6 +38,7 @@ class CategoriesPresenter @Inject constructor(
|
|||
var view = DUMMY
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
private val searchTerms = PublishSubject.create<String>()
|
||||
private var categoryList: MutableLiveData<List<CategoryItem>> = MutableLiveData()
|
||||
/**
|
||||
* Current media
|
||||
*/
|
||||
|
|
@ -54,8 +57,6 @@ class CategoriesPresenter @Inject constructor(
|
|||
.observeOn(mainThreadScheduler)
|
||||
.doOnNext {
|
||||
view.showProgress(true)
|
||||
view.showError(null)
|
||||
view.setCategories(null)
|
||||
}
|
||||
.switchMap(::searchResults)
|
||||
.map { repository.selectedCategories + it }
|
||||
|
|
@ -63,13 +64,17 @@ class CategoriesPresenter @Inject constructor(
|
|||
.observeOn(mainThreadScheduler)
|
||||
.subscribe(
|
||||
{
|
||||
view.setCategories(it)
|
||||
setCategoryListValue(it)
|
||||
view.showProgress(false)
|
||||
if (it.isEmpty()) {
|
||||
view.showError(R.string.no_categories_found)
|
||||
}
|
||||
},
|
||||
Timber::e
|
||||
{ t: Throwable? ->
|
||||
view.showProgress(false)
|
||||
view.showError(R.string.no_categories_found)
|
||||
Timber.e(t)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -92,11 +97,10 @@ class CategoriesPresenter @Inject constructor(
|
|||
CategoryItem(it.name, it.description, it.thumbnail, true)
|
||||
}
|
||||
},
|
||||
repository.searchAll(term, getImageTitleList(), repository.selectedDepictions),
|
||||
{ it1, it2 ->
|
||||
it1 + it2
|
||||
}
|
||||
)
|
||||
repository.searchAll(term, getImageTitleList(), repository.selectedDepictions)
|
||||
) { it1, it2 ->
|
||||
it1 + it2
|
||||
}
|
||||
.subscribeOn(ioScheduler)
|
||||
.map { it.filter { categoryItem -> !repository.containsYear(categoryItem.name)
|
||||
|| categoryItem.name==term } }
|
||||
|
|
@ -161,8 +165,6 @@ class CategoriesPresenter @Inject constructor(
|
|||
.observeOn(mainThreadScheduler)
|
||||
.doOnNext {
|
||||
view.showProgress(true)
|
||||
view.showError(null)
|
||||
view.setCategories(null)
|
||||
}
|
||||
.switchMap(::searchResults)
|
||||
.map { repository.selectedCategories + it }
|
||||
|
|
@ -170,13 +172,17 @@ class CategoriesPresenter @Inject constructor(
|
|||
.observeOn(mainThreadScheduler)
|
||||
.subscribe(
|
||||
{
|
||||
view.setCategories(it)
|
||||
setCategoryListValue(it)
|
||||
view.showProgress(false)
|
||||
if (it.isEmpty()) {
|
||||
view.showError(R.string.no_categories_found)
|
||||
}
|
||||
},
|
||||
Timber::e
|
||||
{ t: Throwable? ->
|
||||
view.showProgress(false)
|
||||
view.showError(R.string.no_categories_found)
|
||||
Timber.e(t)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -230,4 +236,53 @@ class CategoriesPresenter @Inject constructor(
|
|||
view.showNoCategorySelected()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects each [CategoryItem] in a given list as if they were clicked by the user by calling
|
||||
* [onCategoryItemClicked] for each category and adding the category to [categoryList]
|
||||
*/
|
||||
private fun selectNewCategories(toSelect: List<CategoryItem>) {
|
||||
toSelect.forEach{
|
||||
it.isSelected = true
|
||||
repository.onCategoryClicked(it, media)
|
||||
}
|
||||
|
||||
// Add the new selections to the list of category items so that the selections appear
|
||||
// immediately (i.e. without any search term queries)
|
||||
categoryList.value?.toMutableList()
|
||||
?.let { toSelect + it }
|
||||
?.distinctBy(CategoryItem::name)
|
||||
?.let { setCategoryListValue(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Livedata being used to observe category list inside
|
||||
* @see UploadCategoriesFragment
|
||||
* Any changes to category list reflect immediately to the adapter list
|
||||
*/
|
||||
override fun getCategories(): LiveData<List<CategoryItem>> {
|
||||
return categoryList
|
||||
}
|
||||
|
||||
/**
|
||||
* needed for tests
|
||||
*/
|
||||
fun setCategoryList(categoryList: MutableLiveData<List<CategoryItem>>) {
|
||||
this.categoryList = categoryList
|
||||
}
|
||||
|
||||
/**
|
||||
* needed for tests
|
||||
*/
|
||||
fun setCategoryListValue(categoryItems: List<CategoryItem>) {
|
||||
categoryList.postValue(categoryItems)
|
||||
}
|
||||
|
||||
override fun selectCategories() {
|
||||
compositeDisposable.add(repository.placeCategories
|
||||
.subscribeOn(ioScheduler)
|
||||
.observeOn(mainThreadScheduler)
|
||||
.subscribe(::selectNewCategories)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package fr.free.nrw.commons.upload.categories;
|
||||
|
||||
import static fr.free.nrw.commons.wikidata.WikidataConstants.SELECTED_NEARBY_PLACE_CATEGORY;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
|
|
@ -81,6 +83,7 @@ public class UploadCategoriesFragment extends UploadBaseFragment implements Cate
|
|||
* WikiText from the server
|
||||
*/
|
||||
private String wikiText;
|
||||
private String nearbyPlaceCategory;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
|
|
@ -97,9 +100,10 @@ public class UploadCategoriesFragment extends UploadBaseFragment implements Cate
|
|||
if (bundle != null) {
|
||||
media = bundle.getParcelable("Existing_Categories");
|
||||
wikiText = bundle.getString("WikiText");
|
||||
nearbyPlaceCategory = bundle.getString(SELECTED_NEARBY_PLACE_CATEGORY);
|
||||
}
|
||||
|
||||
init();
|
||||
presenter.getCategories().observe(getViewLifecycleOwner(), this::setCategories);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
|
|
@ -160,7 +164,7 @@ public class UploadCategoriesFragment extends UploadBaseFragment implements Cate
|
|||
adapter = new UploadCategoryAdapter(categoryItem -> {
|
||||
presenter.onCategoryItemClicked(categoryItem);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}, nearbyPlaceCategory);
|
||||
rvCategories.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
rvCategories.setAdapter(adapter);
|
||||
}
|
||||
|
|
@ -189,10 +193,9 @@ public class UploadCategoriesFragment extends UploadBaseFragment implements Cate
|
|||
|
||||
@Override
|
||||
public void setCategories(List<CategoryItem> categories) {
|
||||
if(categories==null) {
|
||||
if (categories == null) {
|
||||
adapter.clear();
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
adapter.setItems(categories);
|
||||
}
|
||||
}
|
||||
|
|
@ -299,6 +302,7 @@ public class UploadCategoriesFragment extends UploadBaseFragment implements Cate
|
|||
@Override
|
||||
protected void onBecameVisible() {
|
||||
super.onBecameVisible();
|
||||
presenter.selectCategories();
|
||||
final Editable text = etSearch.getText();
|
||||
if (text != null) {
|
||||
presenter.searchForCategories(text.toString());
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import fr.free.nrw.commons.category.CategoryItem
|
|||
import org.jetbrains.annotations.NotNull
|
||||
|
||||
class UploadCategoryAdapter(
|
||||
onCategoryClicked: @NotNull() (CategoryItem) -> Unit) :
|
||||
onCategoryClicked: @NotNull() (CategoryItem) -> Unit, nearbyPlaceCategory: String?) :
|
||||
BaseDelegateAdapter<CategoryItem>(
|
||||
uploadCategoryDelegate(onCategoryClicked),
|
||||
uploadCategoryDelegate(onCategoryClicked, nearbyPlaceCategory),
|
||||
areItemsTheSame = { oldItem, newItem -> oldItem.name == newItem.name },
|
||||
areContentsTheSame = { oldItem, newItem ->
|
||||
oldItem.name == newItem.name && oldItem.isSelected == newItem.isSelected
|
||||
|
|
|
|||
|
|
@ -6,30 +6,39 @@ 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) =
|
||||
fun uploadCategoryDelegate(onCategoryClicked: (CategoryItem) -> Unit, nearbyPlaceCategory: String?) =
|
||||
adapterDelegateViewBinding<CategoryItem, CategoryItem,
|
||||
LayoutUploadCategoriesItemBinding>({ layoutInflater, root ->
|
||||
LayoutUploadCategoriesItemBinding.inflate(layoutInflater, root, false)
|
||||
}) {
|
||||
val onClickListener = { _: View? ->
|
||||
item.isSelected = !item.isSelected
|
||||
binding.uploadCategoryCheckbox.isChecked = item.isSelected
|
||||
onCategoryClicked(item)
|
||||
if (item.name != nearbyPlaceCategory) {
|
||||
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
|
||||
if (item.name == nearbyPlaceCategory) {
|
||||
item.isSelected = true
|
||||
binding.uploadCategoryCheckbox.isChecked = true
|
||||
binding.uploadCategoryCheckbox.isEnabled = false
|
||||
} else {
|
||||
binding.uploadCategoryCheckbox.isEnabled = true
|
||||
binding.uploadCategoryCheckbox.isChecked = item.isSelected
|
||||
}
|
||||
binding.categoryLabel.text = item.name
|
||||
if(item.thumbnail != "null") {
|
||||
if (item.thumbnail != "null") {
|
||||
binding.categoryImage.setImageURI(item.thumbnail)
|
||||
} else {
|
||||
binding.categoryImage.setActualImageResource(R.drawable.commons)
|
||||
}
|
||||
|
||||
if(item.description != "null") {
|
||||
if (item.description != "null") {
|
||||
binding.categoryDescription.text = item.description
|
||||
} else {
|
||||
binding.categoryDescription.text = ""
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
package fr.free.nrw.commons.upload.depicts;
|
||||
|
||||
import static fr.free.nrw.commons.wikidata.WikidataConstants.SELECTED_NEARBY_PLACE;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
|
|
@ -29,6 +31,7 @@ import fr.free.nrw.commons.R;
|
|||
import fr.free.nrw.commons.contributions.ContributionsFragment;
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.media.MediaDetailFragment;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import fr.free.nrw.commons.ui.PasteSensitiveTextInputEditText;
|
||||
import fr.free.nrw.commons.upload.UploadActivity;
|
||||
import fr.free.nrw.commons.upload.UploadBaseFragment;
|
||||
|
|
@ -83,6 +86,7 @@ public class DepictsFragment extends UploadBaseFragment implements DepictsContra
|
|||
* Determines each encounter of edit depicts
|
||||
*/
|
||||
private int count;
|
||||
private Place nearbyPlace;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
|
|
@ -99,6 +103,7 @@ public class DepictsFragment extends UploadBaseFragment implements DepictsContra
|
|||
Bundle bundle = getArguments();
|
||||
if (bundle != null) {
|
||||
media = bundle.getParcelable("Existing_Depicts");
|
||||
nearbyPlace = bundle.getParcelable(SELECTED_NEARBY_PLACE);
|
||||
}
|
||||
|
||||
init();
|
||||
|
|
@ -111,8 +116,7 @@ public class DepictsFragment extends UploadBaseFragment implements DepictsContra
|
|||
private void init() {
|
||||
|
||||
if (media == null) {
|
||||
depictsTitle
|
||||
.setText(getString(R.string.step_count, callback.getIndexInViewFlipper(this) + 1,
|
||||
depictsTitle.setText(String.format(getString(R.string.step_count), callback.getIndexInViewFlipper(this) + 1,
|
||||
callback.getTotalNumberOfSteps(), getString(R.string.depicts_step_title)));
|
||||
} else {
|
||||
depictsTitle.setText(R.string.edit_depictions);
|
||||
|
|
@ -156,12 +160,12 @@ public class DepictsFragment extends UploadBaseFragment implements DepictsContra
|
|||
adapter = new UploadDepictsAdapter(categoryItem -> {
|
||||
presenter.onDepictItemClicked(categoryItem);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}, nearbyPlace);
|
||||
} else {
|
||||
adapter = new UploadDepictsAdapter(item -> {
|
||||
presenter.onDepictItemClicked(item);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}, nearbyPlace);
|
||||
}
|
||||
depictsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
depictsRecyclerView.setAdapter(adapter);
|
||||
|
|
|
|||
|
|
@ -101,11 +101,10 @@ class DepictsPresenter @Inject constructor(
|
|||
it.commonsCategories, true, it.id)
|
||||
}
|
||||
},
|
||||
repository.searchAllEntities(querystring),
|
||||
{ it1, it2 ->
|
||||
it1 + it2
|
||||
}
|
||||
)
|
||||
repository.searchAllEntities(querystring)
|
||||
) { it1, it2 ->
|
||||
it1 + it2
|
||||
}
|
||||
.subscribeOn(ioScheduler)
|
||||
.map { repository.selectedDepictions + it + recentDepictedItemList + controller.loadFavoritesItems() }
|
||||
.map { it.filterNot { item -> WikidataDisambiguationItems.isDisambiguationItem(item.instanceOfs) } }
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
package fr.free.nrw.commons.upload.depicts
|
||||
|
||||
import fr.free.nrw.commons.nearby.Place
|
||||
import fr.free.nrw.commons.upload.categories.BaseDelegateAdapter
|
||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||
|
||||
class UploadDepictsAdapter(onDepictsClicked: (DepictedItem) -> Unit) :
|
||||
class UploadDepictsAdapter(onDepictsClicked: (DepictedItem) -> Unit, nearbyPlace: Place?) :
|
||||
BaseDelegateAdapter<DepictedItem>(
|
||||
uploadDepictsDelegate(onDepictsClicked),
|
||||
uploadDepictsDelegate(onDepictsClicked, nearbyPlace),
|
||||
areItemsTheSame = { oldItem, newItem -> oldItem.id == newItem.id },
|
||||
areContentsTheSame = { itemA, itemB -> itemA.isSelected == itemB.isSelected}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,29 +6,39 @@ import android.view.View
|
|||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.databinding.LayoutUploadDepictsItemBinding
|
||||
import fr.free.nrw.commons.nearby.Place
|
||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||
|
||||
|
||||
fun uploadDepictsDelegate(onDepictClicked: (DepictedItem) -> Unit) =
|
||||
fun uploadDepictsDelegate(onDepictClicked: (DepictedItem) -> Unit, nearbyPlace: Place?) =
|
||||
adapterDelegateViewBinding<DepictedItem, DepictedItem, LayoutUploadDepictsItemBinding>({ layoutInflater, parent ->
|
||||
LayoutUploadDepictsItemBinding.inflate(layoutInflater, parent, false)
|
||||
}) {
|
||||
val onClickListener = { _: View? ->
|
||||
item.isSelected = !item.isSelected
|
||||
binding.depictCheckbox.isChecked = item.isSelected
|
||||
onDepictClicked(item)
|
||||
if (item.name != nearbyPlace?.name) {
|
||||
item.isSelected = !item.isSelected
|
||||
binding.depictCheckbox.isChecked = item.isSelected
|
||||
onDepictClicked(item)
|
||||
}
|
||||
}
|
||||
binding.root.setOnClickListener(onClickListener)
|
||||
binding.depictCheckbox.setOnClickListener(onClickListener)
|
||||
bind {
|
||||
binding.depictCheckbox.isChecked = item.isSelected
|
||||
binding.depictsLabel.text = item.name
|
||||
binding.description.text = item.description
|
||||
val imageUrl = item.imageUrl
|
||||
if (TextUtils.isEmpty(imageUrl)) {
|
||||
binding.depictedImage.setActualImageResource(R.drawable.ic_wikidata_logo_24dp)
|
||||
if (item.name == nearbyPlace?.name) {
|
||||
item.isSelected = true
|
||||
binding.depictCheckbox.isChecked = true
|
||||
binding.depictCheckbox.isEnabled = false
|
||||
} else {
|
||||
binding.depictedImage.setImageURI(Uri.parse(imageUrl))
|
||||
binding.depictCheckbox.isEnabled = true
|
||||
binding.depictCheckbox.isChecked = item.isSelected
|
||||
}
|
||||
binding.depictsLabel.text = item.name
|
||||
binding.description.text = item.description
|
||||
val imageUrl = item.imageUrl
|
||||
if (TextUtils.isEmpty(imageUrl)) {
|
||||
binding.depictedImage.setActualImageResource(R.drawable.ic_wikidata_logo_24dp)
|
||||
} else {
|
||||
binding.depictedImage.setImageURI(Uri.parse(imageUrl))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,4 +3,6 @@ package fr.free.nrw.commons.wikidata;
|
|||
public class WikidataConstants {
|
||||
public static final String PLACE_OBJECT = "place";
|
||||
public static final String BOOKMARKS_ITEMS = "bookmarks.items";
|
||||
public static final String SELECTED_NEARBY_PLACE = "selected.nearby.place";
|
||||
public static final String SELECTED_NEARBY_PLACE_CATEGORY = "selected.nearby.place.category";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package fr.free.nrw.commons.upload
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import categoryItem
|
||||
import com.nhaarman.mockitokotlin2.*
|
||||
import fr.free.nrw.commons.R
|
||||
import fr.free.nrw.commons.category.CategoryItem
|
||||
import fr.free.nrw.commons.repository.UploadRepository
|
||||
import fr.free.nrw.commons.upload.categories.CategoriesContract
|
||||
import fr.free.nrw.commons.upload.categories.CategoriesPresenter
|
||||
|
|
@ -13,9 +15,9 @@ import org.junit.Before
|
|||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.powermock.reflect.Whitebox
|
||||
import java.lang.reflect.Method
|
||||
|
||||
|
||||
/**
|
||||
* The class contains unit test cases for CategoriesPresenter
|
||||
*/
|
||||
|
|
@ -39,7 +41,7 @@ class CategoriesPresenterTest {
|
|||
MockitoAnnotations.initMocks(this)
|
||||
testScheduler = TestScheduler()
|
||||
categoriesPresenter = CategoriesPresenter(repository, testScheduler, testScheduler)
|
||||
categoriesPresenter.onAttachView(view)
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -51,7 +53,7 @@ class CategoriesPresenterTest {
|
|||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun `Test onAttachViewWithMedia when media is not null`() {
|
||||
Whitebox.setInternalState(categoriesPresenter, "media", media())
|
||||
categoriesPresenter.onAttachViewWithMedia(view, media())
|
||||
whenever(repository.getCategories(repository.selectedExistingCategories))
|
||||
.thenReturn(Observable.just(mutableListOf(categoryItem())))
|
||||
whenever(repository.searchAll("mock", emptyList(), repository.selectedDepictions))
|
||||
|
|
@ -68,6 +70,11 @@ class CategoriesPresenterTest {
|
|||
*/
|
||||
@Test
|
||||
fun `searchForCategories combines selection and search results without years distinctly`() {
|
||||
categoriesPresenter.onAttachView(view)
|
||||
val liveData = MutableLiveData<List<CategoryItem>>()
|
||||
categoriesPresenter.setCategoryList(liveData)
|
||||
categoriesPresenter.setCategoryListValue(listOf(
|
||||
categoryItem("selected", "", "", true)))
|
||||
val nonEmptyCaptionUploadItem = mock<UploadItem>()
|
||||
whenever(nonEmptyCaptionUploadItem.uploadMediaDetails)
|
||||
.thenReturn(listOf(UploadMediaDetail(captionText = "nonEmpty")))
|
||||
|
|
@ -80,7 +87,7 @@ class CategoriesPresenterTest {
|
|||
emptyCaptionUploadItem
|
||||
)
|
||||
)
|
||||
whenever(repository.searchAll("test", listOf("nonEmpty"), repository.selectedDepictions))
|
||||
whenever(repository.searchAll(any(), any(), any()))
|
||||
.thenReturn(
|
||||
Observable.just(
|
||||
listOf(
|
||||
|
|
@ -96,25 +103,34 @@ class CategoriesPresenterTest {
|
|||
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).showProgress(false)
|
||||
verifyNoMoreInteractions(view)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `searchForCategoriesTest sets Error when list is empty`() {
|
||||
whenever(repository.uploads).thenReturn(listOf())
|
||||
whenever(repository.searchAll(any(), any(), any())).thenReturn(Observable.just(listOf()))
|
||||
categoriesPresenter.onAttachView(view)
|
||||
val liveData = MutableLiveData<List<CategoryItem>>()
|
||||
categoriesPresenter.setCategoryList(liveData)
|
||||
// Arrange
|
||||
val query = "testQuery"
|
||||
val emptyCategories = ArrayList<CategoryItem>()
|
||||
|
||||
liveData.postValue(emptyCategories)
|
||||
|
||||
whenever(repository.searchAll(any(), any(), any()))
|
||||
.thenReturn(Observable.just(emptyCategories))
|
||||
whenever(repository.selectedCategories).thenReturn(listOf())
|
||||
categoriesPresenter.searchForCategories("test")
|
||||
categoriesPresenter.searchForCategories(query)
|
||||
testScheduler.triggerActions()
|
||||
val method: Method = CategoriesPresenter::class.java.getDeclaredMethod(
|
||||
"searchResults",
|
||||
String::class.java
|
||||
)
|
||||
method.isAccessible = true
|
||||
method.invoke(categoriesPresenter, query)
|
||||
|
||||
verify(view).showProgress(true)
|
||||
verify(view).showError(null)
|
||||
verify(view).setCategories(null)
|
||||
verify(view).setCategories(listOf())
|
||||
verify(view).showProgress(false)
|
||||
verify(view).showError(R.string.no_categories_found)
|
||||
verifyNoMoreInteractions(view)
|
||||
|
|
@ -125,6 +141,7 @@ class CategoriesPresenterTest {
|
|||
*/
|
||||
@Test
|
||||
fun `verifyCategories with non empty selection goes to next screen`() {
|
||||
categoriesPresenter.onAttachView(view)
|
||||
val item = categoryItem()
|
||||
whenever(repository.selectedCategories).thenReturn(listOf(item))
|
||||
categoriesPresenter.verifyCategories()
|
||||
|
|
@ -134,6 +151,7 @@ class CategoriesPresenterTest {
|
|||
|
||||
@Test
|
||||
fun `verifyCategories with empty selection show no category selected`() {
|
||||
categoriesPresenter.onAttachView(view)
|
||||
whenever(repository.selectedCategories).thenReturn(listOf())
|
||||
categoriesPresenter.verifyCategories()
|
||||
verify(view).showNoCategorySelected()
|
||||
|
|
@ -156,6 +174,7 @@ class CategoriesPresenterTest {
|
|||
|
||||
@Test
|
||||
fun testUpdateCategories() {
|
||||
categoriesPresenter.onAttachView(view)
|
||||
categoriesPresenter.updateCategories(media(), "[[Category:Test]]")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,9 +145,34 @@ class UploadCategoriesFragmentUnitTests {
|
|||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnViewCreated() {
|
||||
fun testInitMethod() {
|
||||
val method: Method = UploadCategoriesFragment::class.java.getDeclaredMethod(
|
||||
"init"
|
||||
)
|
||||
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
||||
fragment.onViewCreated(view, null)
|
||||
method.isAccessible = true
|
||||
method.invoke(fragment)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun `Test init when media is non null`() {
|
||||
Whitebox.setInternalState(fragment, "media", media)
|
||||
val method: Method = UploadCategoriesFragment::class.java.getDeclaredMethod(
|
||||
"init"
|
||||
)
|
||||
method.isAccessible = true
|
||||
method.invoke(fragment)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testFragmentOnBecameVisible() {
|
||||
val method: Method = UploadCategoriesFragment::class.java.getDeclaredMethod(
|
||||
"onBecameVisible"
|
||||
)
|
||||
method.isAccessible = true
|
||||
method.invoke(fragment)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue