Skip to content

Fixes: #3179 Make category search non case-sensitive #3326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 29, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@ public Observable<CategoryItem> searchAll(String term, List<String> imageTitleLi
}

//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, SEARCH_CATS_LIMIT)
.searchCategoriesForPrefix(term.toLowerCase(), SEARCH_CATS_LIMIT)
.map(name -> new CategoryItem(name, false));
}

Expand Down Expand Up @@ -183,11 +184,12 @@ private Observable<CategoryItem> titleCategories(List<String> titleList) {

/**
* Return category for single title
* title is converted to lower case to make search case-insensitive
* @param title
* @return
*/
private Observable<CategoryItem> getTitleCategories(String title) {
return categoryClient.searchCategories(title, SEARCH_CATS_LIMIT)
return categoryClient.searchCategories(title.toLowerCase(), SEARCH_CATS_LIMIT)
.map(name -> new CategoryItem(name, false));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public Observable<String> searchCategories(String filter, int itemLimit) {

/**
* 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
Expand Down
37 changes: 1 addition & 36 deletions app/src/main/java/fr/free/nrw/commons/category/CategoryItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
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;
Expand All @@ -28,53 +24,28 @@ public CategoryItem(String name, boolean selected) {
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);
Expand All @@ -96,19 +67,13 @@ public boolean equals(Object o) {

}

/**
* 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 + '\'';
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package fr.free.nrw.commons.category

import io.reactivex.Observable
import junit.framework.Assert.*
import org.junit.Before
import org.junit.Test
import org.mockito.*
import org.wikipedia.dataclient.mwapi.MwQueryPage
import org.wikipedia.dataclient.mwapi.MwQueryResponse
import org.wikipedia.dataclient.mwapi.MwQueryResult

//class for testing CategoriesModel class
class CategoriesModelTest {
@Mock
internal var categoryInterface: CategoryInterface? = null

@Mock
internal var categoryItem: CategoryItem? = null

@InjectMocks
var categoryClient: CategoryClient? = null

@Before
@Throws(Exception::class)
fun setUp() {
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())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class CategoryClientTest {
{ fail("SearchCategories returned element when it shouldn't have.") },
{ s -> throw s })
}

@Test
fun searchCategoriesForPrefixFound() {
val mwQueryPage = Mockito.mock(MwQueryPage::class.java)
Expand Down Expand Up @@ -92,6 +93,7 @@ class CategoryClientTest {
{ fail("SearchCategories returned element when it shouldn't have.") },
{ s -> throw s })
}

@Test
fun getParentCategoryListFound() {
val mwQueryPage = Mockito.mock(MwQueryPage::class.java)
Expand Down