Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ dependencies {
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.legacy:legacy-support-core-utils:1.0.0'

debugImplementation 'androidx.fragment:fragment-testing:1.3.5'
debugImplementation 'androidx.test.espresso:espresso-contrib:3.3.0'

testImplementation "org.mockito:mockito-core:2.19.0"
testImplementation 'org.mockito:mockito-inline:2.8.9'
testImplementation('com.nhaarman:mockito-kotlin:1.5.0') {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
package com.joesemper.justrecipebook

import android.view.View
import androidx.core.os.bundleOf
import androidx.fragment.app.testing.FragmentScenario
import androidx.fragment.app.testing.launchFragmentInContainer
import androidx.lifecycle.Lifecycle
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.android.material.internal.CheckableImageButton
import com.google.android.material.textfield.TextInputLayout
import com.joesemper.justrecipebook.ui.fragments.home.HomeFragment
import com.joesemper.justrecipebook.ui.fragments.home.adapter.MealsRVAdapter
import com.joesemper.justrecipebook.ui.util.constants.SearchType
import kotlinx.android.synthetic.main.fragment_main.*
import org.hamcrest.Matcher
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class HomeFragmentEspressoTest {

private lateinit var scenario: FragmentScenario<HomeFragment>

@Before
fun setup() {
scenario = launchFragmentInContainer(themeResId = R.style.AppTheme)
}

@Test
fun test_fragment_notNull() {
scenario.onFragment {
assertNotNull(it)
}
}

@Test
fun test_fragment_presenter_notNull() {
scenario.onFragment {
assertNotNull(it.presenter)
}
}

@Test
fun test_bundle_goes_correct() {
val fragmentArgs = bundleOf("SEARCH" to SearchType.QUERY, "MEAL" to "")
val scenario =
launchFragmentInContainer<HomeFragment>(fragmentArgs, themeResId = R.style.AppTheme)

scenario.onFragment {
assertEquals("", it.presenter.query)
assertEquals(SearchType.QUERY, it.presenter.searchType)
}
}

@Test
fun test_searchView_isDisplayed() {
val fragmentArgs = bundleOf("SEARCH" to SearchType.QUERY)
val scenario =
launchFragmentInContainer<HomeFragment>(fragmentArgs, themeResId = R.style.AppTheme)

onView(withId(R.id.text_input_layout_search)).check(matches(isDisplayed()))
}

@Test
fun test_onFavorites_searchView_isGone() {
val fragmentArgs = bundleOf("SEARCH" to SearchType.FAVORITE)
val scenario =
launchFragmentInContainer<HomeFragment>(fragmentArgs, themeResId = R.style.AppTheme)

scenario.onFragment {
assertEquals(View.GONE, it.text_input_layout_search.visibility)
}
}

@Test
fun test_recycler_view_isDisplayed() {
val fragmentArgs = bundleOf("SEARCH" to SearchType.QUERY, "MEAL" to "")
val scenario =
launchFragmentInContainer<HomeFragment>(fragmentArgs, themeResId = R.style.AppTheme)

onView(withId(R.id.rv_meals)).check(matches(isDisplayed()))
}

@Test
fun test_recycler_view_empty_search() {
val fragmentArgs = bundleOf("SEARCH" to SearchType.QUERY, "MEAL" to "")
val scenario =
launchFragmentInContainer<HomeFragment>(fragmentArgs, themeResId = R.style.AppTheme)

onView(isRoot()).perform(delay())
onView(withId(R.id.rv_meals)).perform(
RecyclerViewActions.scrollTo<MealsRVAdapter.ViewHolder>(
hasDescendant(withText("Sugar Pie"))
)
)
}

@Test
fun test_recycler_view_category() {
val fragmentArgs = bundleOf("SEARCH" to SearchType.CATEGORY, "MEAL" to "Pasta")
val scenario =
launchFragmentInContainer<HomeFragment>(fragmentArgs, themeResId = R.style.AppTheme)

onView(isRoot()).perform(delay())
onView(withId(R.id.rv_meals)).perform(
RecyclerViewActions.scrollTo<MealsRVAdapter.ViewHolder>(
hasDescendant(withText("Lasagne"))
)
)
}

@Test
fun test_recycler_view_favorites() {
val fragmentArgs = bundleOf("SEARCH" to SearchType.FAVORITE)
val scenario =
launchFragmentInContainer<HomeFragment>(fragmentArgs, themeResId = R.style.AppTheme)

onView(isRoot()).perform(delay())
onView(withId(R.id.rv_meals)).perform(
RecyclerViewActions.scrollTo<MealsRVAdapter.ViewHolder>(
hasDescendant(withText("Sugar Pie"))
)
)
}

@Test
fun test_recycler_view_search() {
val fragmentArgs = bundleOf("SEARCH" to SearchType.QUERY)
val scenario =
launchFragmentInContainer<HomeFragment>(fragmentArgs, themeResId = R.style.AppTheme)

onView(withId(R.id.text_input_search)).perform(click())
onView(withId(R.id.text_input_search)).perform(
replaceText("Chicken"),
ViewActions.closeSoftKeyboard()
)

// val viewAction: ViewAction = clickOnEndIconInTextInputLayout(R.id.text_input_layout_search)
// onView(withId(R.id.text_input_layout_search)).perform(viewAction)

onView(withId(R.id.text_input_end_icon)).perform(click())

onView(isRoot()).perform(delay())
onView(withId(R.id.rv_meals)).perform(
RecyclerViewActions.scrollTo<MealsRVAdapter.ViewHolder>(
hasDescendant(withText("Chicken Handi"))
)
)
}

private fun delay(): ViewAction {
return object : ViewAction {
override fun getConstraints(): Matcher<View> = isRoot()
override fun getDescription(): String = "wait for $7 seconds"
override fun perform(uiController: UiController, v: View?) {
uiController.loopMainThreadForAtLeast(7000)
}
}
}



/**
* Не получилось сделать кастомный ViewAction,
* почему-то метод падает с NullPointerException.
* Должен кликать на EndIcon в TextInputLayout
*/
private fun clickOnEndIconInTextInputLayout(id: Int): ViewAction {
return object : ViewAction {
override fun getConstraints(): Matcher<View>? {
return null
}

override fun getDescription(): String {
return "Clicks on search icon"
}

override fun perform(uiController: UiController, view: View) {
val v = view.findViewById<TextInputLayout>(id)
(v.findViewById<View>(R.id.text_input_end_icon) as CheckableImageButton).performClick()
// v.findViewById<CheckableImageButton>(R.id.text_input_end_icon)?.performClick()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.joesemper.justrecipebook.ui.fragments.cart

import android.app.AlertDialog
import androidx.appcompat.app.AlertDialog
import android.content.Context
import android.content.DialogInterface
import android.os.Build
import android.os.Bundle
import android.os.VibrationEffect
Expand All @@ -21,7 +20,6 @@ import com.joesemper.justrecipebook.ui.fragments.dialog.ingredient.IngredientDia
import com.joesemper.justrecipebook.ui.interfaces.BackButtonListener
import com.joesemper.justrecipebook.ui.util.view.callback.SwipeCallback
import kotlinx.android.synthetic.main.fragment_cart.*
import kotlinx.android.synthetic.main.fragment_meal.*
import moxy.MvpAppCompatFragment
import moxy.ktx.moxyPresenter

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.view.View.GONE
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import android.widget.Toolbar
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager
Expand Down Expand Up @@ -81,8 +82,9 @@ class HomeFragment : MvpAppCompatFragment(), HomeFragmentView, BackButtonListene
}

private fun initActionBar() {
with(activity as AppCompatActivity) {
setSupportActionBar(toolbar_home)
with(requireActivity()) {
setActionBar(toolbar_home )
// setSupportActionBar(toolbar_home)
}
}

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/fragment_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
android:layout_height="wrap_content"
android:elevation="8dp">

<com.google.android.material.appbar.MaterialToolbar
<Toolbar
android:id="@+id/toolbar_home"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
Expand Down