-
Notifications
You must be signed in to change notification settings - Fork 37
#297: Add child - search for child #320
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
base: master
Are you sure you want to change the base?
Changes from all commits
c1182a5
d8c4838
bac489b
bd977f7
d7a4960
9375a83
78d06cc
a5a38a3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,8 @@ | |
| import static android.support.test.espresso.Espresso.onView; | ||
| import static android.support.test.espresso.action.ViewActions.click; | ||
| import static android.support.test.espresso.action.ViewActions.replaceText; | ||
| import static android.support.test.espresso.action.ViewActions.typeText; | ||
| import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; | ||
| import static android.support.test.espresso.assertion.ViewAssertions.matches; | ||
| import static android.support.test.espresso.contrib.RecyclerViewActions.scrollToPosition; | ||
| import static android.support.test.espresso.matcher.ViewMatchers.assertThat; | ||
|
|
@@ -36,8 +38,8 @@ | |
| @RunWith(AndroidJUnit4.class) | ||
| public class ChildListActivityTest { | ||
|
|
||
| private static final String EXPECTED_FIRST_NAME = "FIRST NAME"; | ||
| private static final String EXPECTED_LAST_NAME = "LAST NAME"; | ||
| private static final String EXPECTED_FIRST_NAME = "FIRST_NAME"; | ||
| private static final String EXPECTED_LAST_NAME = "LAST_NAME"; | ||
|
|
||
| @ClassRule | ||
| public static DaoSessionResource daoSessionResource = new DaoSessionResource(); | ||
|
|
@@ -122,4 +124,84 @@ public void whenChildIsAddedToDBExpectProperlyDisplayedOnRecyclerView() { | |
| .check(matches(hasDescendant(withText(EXPECTED_FIRST_NAME + " " + EXPECTED_LAST_NAME | ||
| + testedChildPosition)))); | ||
| } | ||
|
|
||
| @Test | ||
| public void whenSearchForAChildWithOneLetterOfNameExpectThatChildOnFirstPosition() { | ||
| final int testedChildPosition = 0; | ||
| final int firstPosition = 0; | ||
| onView(withId(R.id.menu_search)).perform(typeText(Character.toString(EXPECTED_FIRST_NAME.charAt(0)))); | ||
| onView(withRecyclerView(R.id.rv_child_list) | ||
| .atPosition(firstPosition)) | ||
| .check(matches(hasDescendant(withText(EXPECTED_FIRST_NAME + " " + EXPECTED_LAST_NAME | ||
| + testedChildPosition)))); | ||
| } | ||
|
|
||
| @Test | ||
| public void whenSearchForAChildWithNameExpectThatChildOnFirstPosition() { | ||
| final int testedChildPosition = 0; | ||
| final int firstPosition = 0; | ||
| onView(withId(R.id.menu_search)).perform(typeText(EXPECTED_FIRST_NAME)); | ||
| onView(withRecyclerView(R.id.rv_child_list) | ||
| .atPosition(firstPosition)) | ||
| .check(matches(hasDescendant(withText(EXPECTED_FIRST_NAME + " " + EXPECTED_LAST_NAME | ||
| + testedChildPosition)))); | ||
| } | ||
|
|
||
| @Test | ||
| public void whenSearchForAChildWithOneLetterOfSurnameExpectThatChildOnFirstPosition() { | ||
| final int testedChildPosition = 0; | ||
| final int firstPosition = 0; | ||
| onView(withId(R.id.menu_search)).perform(typeText(Character.toString(EXPECTED_LAST_NAME.charAt(0)))); | ||
| onView(withRecyclerView(R.id.rv_child_list) | ||
| .atPosition(firstPosition)) | ||
| .check(matches(hasDescendant(withText(EXPECTED_FIRST_NAME + " " + EXPECTED_LAST_NAME | ||
| + testedChildPosition)))); | ||
| } | ||
| @Test | ||
| public void whenSearchForAChildWithSurnameExpectThatChildOnFirstPosition(){ | ||
| final int testedChildPosition = 3; | ||
| final int firstPosition = 0; | ||
| onView(withId(R.id.menu_search)).perform(typeText(EXPECTED_LAST_NAME + testedChildPosition)); | ||
| onView(withRecyclerView(R.id.rv_child_list) | ||
| .atPosition(firstPosition)) | ||
| .check(matches(hasDescendant(withText(EXPECTED_FIRST_NAME + " " + EXPECTED_LAST_NAME | ||
| + testedChildPosition)))); | ||
| } | ||
| @Test | ||
| public void whenSearchForAChildWithNameAndSurnameExpectOnlyThatChildToAppear() { //TO DO | ||
| final int testedChildPosition = 3; | ||
| final int firstPosition = 0; | ||
| final int nextPosition = 1; | ||
| onView(withId(R.id.menu_search)).perform(typeText( | ||
| EXPECTED_FIRST_NAME + " " + EXPECTED_LAST_NAME + testedChildPosition)); | ||
| onView(withRecyclerView(R.id.rv_child_list) | ||
| .atPosition(firstPosition)) | ||
| .check(matches(hasDescendant(withText(EXPECTED_FIRST_NAME + " " + EXPECTED_LAST_NAME | ||
| + testedChildPosition)))); | ||
| onView(withRecyclerView(R.id.rv_plan_list) | ||
| .atPosition(nextPosition)).check(doesNotExist()); | ||
| } | ||
| @Test | ||
| public void whenSearchForAChildWithSurnameAndNameExpectOnlyThatChildToAppear(){ | ||
| final int testedChildPosition = 3; | ||
| final int firstPosition = 0; | ||
| onView(withId(R.id.menu_search)).perform(typeText( | ||
| EXPECTED_LAST_NAME + testedChildPosition + " " + EXPECTED_FIRST_NAME)); | ||
| onView(withRecyclerView(R.id.rv_child_list) | ||
| .atPosition(firstPosition)) | ||
| .check(matches(hasDescendant(withText(EXPECTED_FIRST_NAME + " " + EXPECTED_LAST_NAME | ||
| + testedChildPosition)))); | ||
| } | ||
| @Test | ||
| public void whenSearchForAChildWithFirstLettersOfNameAndSurnameExpectThatChildOnFirstPosition(){ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I understand the tests search by first letter of surname and first of name eg. John Smith will be found after J S . I don't think this case should be covered. I think part of name or surname or both is enough. What do you think ? |
||
| final int testedChildPosition = 0; | ||
| final int firstPosition = 0; | ||
| onView(withId(R.id.menu_search)).perform(typeText( | ||
| Character.toString(EXPECTED_FIRST_NAME.charAt(0)) + " " | ||
| + Character.toString(EXPECTED_LAST_NAME.charAt(0)))); | ||
| onView(withRecyclerView(R.id.rv_child_list) | ||
| .atPosition(firstPosition)) | ||
| .check(matches(hasDescendant(withText(EXPECTED_FIRST_NAME + " " + EXPECTED_LAST_NAME | ||
| + testedChildPosition)))); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ | |
| import database.entities.Child; | ||
| import database.entities.ChildDao.Properties; | ||
| import database.entities.DaoSession; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class ChildRepository { | ||
|
|
@@ -27,6 +28,25 @@ public List<Child> getBySurname(String surname) { | |
| .list(); | ||
| } | ||
|
|
||
| public List<Child> getFilteredByFullName(String fullName) { | ||
| String[] splited = fullName.split("\\s+"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I found that Greendao supports like. What not write only: ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi, do you have an idea how to write "WHERE (name LIKE ? AND surname LIKE ?) OR (name LIKE ? AND surname LIKE ?)" this query using query builder?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why? What case are you trying to cover?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "WHERE (name LIKE firstWord AND surname secondWord ?) OR (name secondWord ? AND surname LIKE firstWord)" - line 43 in ChildRepository.java
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I didn't get your point. Sure, you need this case also. code: created sql ( you can see it in childQueryBuilder.build().sql): |
||
| for (int i=0; i<splited.length; i++) { | ||
| splited[i] = "%" + splited[i] + "%"; | ||
| } | ||
| if(splited.length == 1 ) { | ||
| String[] whereArguments = {splited[0], splited[0]}; | ||
| return daoSession.getChildDao().queryRaw("WHERE name LIKE ? OR surname LIKE ?", | ||
| whereArguments); | ||
| } | ||
| else { | ||
| String[] whereArguments = {splited[0], splited[1], splited[1], splited[0]}; | ||
| return daoSession.getChildDao().queryRaw( | ||
| "WHERE (name LIKE ? AND surname LIKE ?) OR (name LIKE ? AND surname LIKE ?)", | ||
| whereArguments); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| public Child get(Long id) { | ||
| return daoSession.getChildDao().load(id); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,11 @@ | |
| import android.support.v7.widget.LinearLayoutManager; | ||
| import android.support.v7.widget.RecyclerView; | ||
| import android.util.Log; | ||
| import android.view.Menu; | ||
| import android.view.MenuInflater; | ||
| import android.view.MenuItem; | ||
| import android.widget.SearchView; | ||
|
|
||
| import database.repository.ChildRepository; | ||
| import javax.inject.Inject; | ||
| import pg.autyzm.friendly_plans.App; | ||
|
|
@@ -22,6 +27,8 @@ public class ChildListActivity extends AppCompatActivity implements ChildListAct | |
| @Inject | ||
| ToastUserNotifier toastUserNotifier; | ||
|
|
||
| ChildRecyclerViewAdapter childListAdapter; | ||
|
|
||
| ChildListData childData; | ||
|
|
||
| @Override | ||
|
|
@@ -44,11 +51,34 @@ protected void onCreate(Bundle savedInstanceState) { | |
|
|
||
| } | ||
|
|
||
| @Override | ||
| public boolean onCreateOptionsMenu(Menu menu) { | ||
| MenuInflater menuInflater = getMenuInflater(); | ||
| menuInflater.inflate(R.menu.plan_list_menu, menu); | ||
| MenuItem searchViewItem = menu.findItem(R.id.menu_search); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you tried you use data binding here? (Similar to save data button)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean data binding for keeping searchViewItem object without finding it by id or implement setOnQueryTextListener with managing this action by data binding not manually finding it. Like in PlanCreate but for menu it could be a little different. |
||
| SearchView searchView = (SearchView) searchViewItem.getActionView(); | ||
| searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { | ||
| @Override | ||
| public boolean onQueryTextSubmit(String query) { | ||
| childListAdapter.setChildItems(childRepository.getFilteredByFullName(query)); | ||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean onQueryTextChange(String newText) { | ||
| childListAdapter.setChildItems(childRepository.getFilteredByFullName(newText)); | ||
| return false; | ||
| } | ||
| }); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| private void setUpViews() { | ||
| RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv_child_list); | ||
| recyclerView.setHasFixedSize(true); | ||
| recyclerView.setLayoutManager(new LinearLayoutManager(this)); | ||
| ChildRecyclerViewAdapter childListAdapter = new ChildRecyclerViewAdapter(); | ||
| childListAdapter = new ChildRecyclerViewAdapter(); | ||
| recyclerView.setAdapter(childListAdapter); | ||
| childListAdapter.setChildItems(childRepository.getAll()); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This case is OK, but I think it will be enough to cover only NAME or SURNAME or NAME SURNAME or part of this. You don't need to worry about more, but it's nice you tried :) Could you please leave only tests that are covering these cases ?