From c961099013a19b91c46763216331795c36957b5d Mon Sep 17 00:00:00 2001 From: Kaartic Sivaraam Date: Fri, 10 Apr 2020 09:38:51 +0000 Subject: [PATCH] Revert "Fixes: #3179 Make category search non case-sensitive (#3326)" (#3636) Simply lower casing the name of the category sent to the server doesn't result in the server doing a case insensitive category search. In fact, it reduces the category search space as only categories that has a lower case character is searched even if the search text contains upper case characters. The test case did not catch this issue as the first character of the title is case insensitive[1]. So, revert the changes done in commit afdeaae0757d4d7773921169eb65d3ba9916834a. See further disucssion in the issue thread of #3179 starting from [2]. [1]: https://www.mediawiki.org/wiki/Manual:Page_title [2]: https://github.com/commons-app/apps-android-commons/issues/3179#issuecomment-605462140 --- .../nrw/commons/category/CategoriesModel.java | 6 +-- .../nrw/commons/category/CategoryClient.java | 2 +- .../nrw/commons/category/CategoryItem.java | 37 ++++++++++++++++++- .../commons/category/CategoriesModelTest.kt | 25 ------------- .../commons/category/CategoryClientTest.kt | 2 - 5 files changed, 39 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoriesModel.java b/app/src/main/java/fr/free/nrw/commons/category/CategoriesModel.java index caa66e433..e2030ee9a 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoriesModel.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoriesModel.java @@ -123,9 +123,8 @@ public class CategoriesModel{ } //otherwise, search API for matching categories - //term passed as lower case to make search case-insensitive(taking only lower case for everything) return categoryClient - .searchCategoriesForPrefix(term.toLowerCase(), SEARCH_CATS_LIMIT) + .searchCategoriesForPrefix(term, SEARCH_CATS_LIMIT) .map(name -> new CategoryItem(name, false)); } @@ -184,12 +183,11 @@ public class CategoriesModel{ /** * Return category for single title - * title is converted to lower case to make search case-insensitive * @param title * @return */ private Observable getTitleCategories(String title) { - return categoryClient.searchCategories(title.toLowerCase(), SEARCH_CATS_LIMIT) + return categoryClient.searchCategories(title, SEARCH_CATS_LIMIT) .map(name -> new CategoryItem(name, false)); } diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryClient.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryClient.java index 7a4d1718b..329c3635a 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryClient.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryClient.java @@ -55,7 +55,7 @@ public class CategoryClient { /** * Searches for categories starting with the specified string. - * + * * @param prefix The prefix to be searched * @param itemLimit How many results are returned * @param offset Starts returning items from the nth result. If offset is 9, the response starts with the 9th item of the search result diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryItem.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryItem.java index c8f2a2713..bb89a11c4 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryItem.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryItem.java @@ -3,6 +3,10 @@ package fr.free.nrw.commons.category; import android.os.Parcel; import android.os.Parcelable; +/** + * Represents a Category Item. + * Implemented as Parcelable so that its object could be parsed between activity components. + */ public class CategoryItem implements Parcelable { private final String name; private boolean selected; @@ -24,28 +28,53 @@ public class CategoryItem implements Parcelable { this.selected = selected; } + /** + * Reads from the received Parcel + * @param in + */ private CategoryItem(Parcel in) { name = in.readString(); selected = in.readInt() == 1; } + /** + * Gets Name + * @return + */ public String getName() { return name; } + /** + * Checks if that Category Item has been selected. + * @return + */ public boolean isSelected() { return selected; } + /** + * Selects the Category Item. + * @param selected + */ public void setSelected(boolean selected) { this.selected = selected; } + /** + * Used by Parcelable + * @return + */ @Override public int describeContents() { return 0; } + /** + * Writes to the received Parcel + * @param parcel + * @param flags + */ @Override public void writeToParcel(Parcel parcel, int flags) { parcel.writeString(name); @@ -67,13 +96,19 @@ public class CategoryItem implements Parcelable { } + /** + * Returns hash code for current object + */ @Override public int hashCode() { return name.hashCode(); } + /** + * Return String form of current object + */ @Override public String toString() { return "CategoryItem: '" + name + '\''; } -} \ No newline at end of file +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/category/CategoriesModelTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/category/CategoriesModelTest.kt index 8cd7e292c..fea98f450 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/category/CategoriesModelTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/category/CategoriesModelTest.kt @@ -17,9 +17,6 @@ class CategoriesModelTest { @Mock internal var categoryInterface: CategoryInterface? = null - @Mock - internal var categoryItem: CategoryItem? = null - @Spy internal lateinit var gson: Gson @@ -43,28 +40,6 @@ class CategoriesModelTest { MockitoAnnotations.initMocks(this) } - // Test Case for verifying that Categories search (MW api calls) are case-insensitive - @Test - fun searchAllFoundCaseTest() { - val mwQueryPage = Mockito.mock(MwQueryPage::class.java) - Mockito.`when`(mwQueryPage.title()).thenReturn("Category:Test") - val mwQueryResult = Mockito.mock(MwQueryResult::class.java) - Mockito.`when`(mwQueryResult.pages()).thenReturn(listOf(mwQueryPage)) - val mockResponse = Mockito.mock(MwQueryResponse::class.java) - Mockito.`when`(mockResponse.query()).thenReturn(mwQueryResult) - val categoriesModel: CategoriesModel = CategoriesModel(categoryClient,null,null) - - Mockito.`when`(categoryInterface!!.searchCategoriesForPrefix(ArgumentMatchers.anyString(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt())) - .thenReturn(Observable.just(mockResponse)) - - // Checking if both return "Test" - val actualCategoryName = categoriesModel!!.searchAll("tes",null).blockingFirst() - assertEquals("Test", actualCategoryName.getName()) - - val actualCategoryNameCaps = categoriesModel!!.searchAll("Tes",null).blockingFirst() - assertEquals("Test", actualCategoryNameCaps.getName()) - } - /** * For testing the substring search algorithm for Categories search * To be more precise it tests the In Between substring( ex: searching `atte` diff --git a/app/src/test/kotlin/fr/free/nrw/commons/category/CategoryClientTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/category/CategoryClientTest.kt index a668e5704..7c26cc323 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/category/CategoryClientTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/category/CategoryClientTest.kt @@ -58,7 +58,6 @@ class CategoryClientTest { { fail("SearchCategories returned element when it shouldn't have.") }, { s -> throw s }) } - @Test fun searchCategoriesForPrefixFound() { val mwQueryPage = Mockito.mock(MwQueryPage::class.java) @@ -93,7 +92,6 @@ class CategoryClientTest { { fail("SearchCategories returned element when it shouldn't have.") }, { s -> throw s }) } - @Test fun getParentCategoryListFound() { val mwQueryPage = Mockito.mock(MwQueryPage::class.java)