From f9aac8b75549a303293526d80d8a5ec02da1d147 Mon Sep 17 00:00:00 2001 From: hmalik144 Date: Sun, 13 Jun 2021 01:45:10 +0100 Subject: [PATCH] - Instrumentation tests added Took 1 hour 32 minutes --- .idea/caches/build_file_checksums.ser | Bin 537 -> 537 bytes app/build.gradle | 4 +- .../easycc/application/TestApplication.kt | 31 +++++++ .../h_mal/easycc/application/TestRunner.kt | 22 +++++ .../application/modules/MockRepository.kt | 69 ++++++++++++++ .../h_mal/easycc/robots/CurrencyRobot.kt | 84 ++++++++++++++++++ .../h_mal/easycc/ui/main/MainActivityTest.kt | 35 ++++++++ .../h_mal/easycc/application/AppClass.kt | 2 +- .../NetworkConnectionInterceptor.kt | 3 +- .../network/interceptors/QueryInterceptor.kt | 6 +- .../data/network/response/CurrencyResponse.kt | 10 +-- .../data/network/response/ResponseObject.kt | 23 +++-- .../h_mal/easycc/ui/main/MainActivity.kt | 1 - .../easycc/ui/main/MainViewModelFactory.kt | 4 +- ...urrencyAppWidgetConfigureActivityKotlin.kt | 1 - .../h_mal/easycc/utils/PrimitiveUtils.kt | 10 +-- app/src/main/res/drawable-nodpi/gradient.xml | 2 +- .../res/drawable-nodpi/round_edit_text.xml | 5 +- app/src/main/res/drawable/ic_background.xml | 31 ++++--- .../res/drawable/ic_refresh_white_24dp.xml | 13 ++- .../main/res/layout/currency_app_widget.xml | 23 ++--- .../layout/currency_app_widget_configure.xml | 2 +- app/src/main/res/layout/custom_dialog.xml | 16 ++-- .../xml/currency_kotlin_app_widget_info.xml | 2 +- 24 files changed, 323 insertions(+), 76 deletions(-) create mode 100644 app/src/androidTest/java/com/appttude/h_mal/easycc/application/TestApplication.kt create mode 100644 app/src/androidTest/java/com/appttude/h_mal/easycc/application/TestRunner.kt create mode 100644 app/src/androidTest/java/com/appttude/h_mal/easycc/application/modules/MockRepository.kt create mode 100644 app/src/androidTest/java/com/appttude/h_mal/easycc/robots/CurrencyRobot.kt create mode 100644 app/src/androidTest/java/com/appttude/h_mal/easycc/ui/main/MainActivityTest.kt diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 4ae680807ca54564ce1582ca1d5b9103a4dd6792..687112a71a6537357f9d8563d884968b2fb8ea4a 100644 GIT binary patch delta 55 zcmbQqGLvP(Oy-ST7bngs7YNlY%Y0et-c?#t78Y9}6fs$u(N#cR!JAh{d`n^jm!xO_ Lhv%Ki6^si3I`|V1 delta 55 zcmV-70LcHD1epYonFBGdOOc#+5UIqt$cN { + return Pair("AUD - Australian Dollar", "GBP - British Pound") + } + + override fun setConversionPair(fromCurrency: String, toCurrency: String) {} + + override fun getCurrenciesList(): Array = + arrayOf("AUD - Australian Dollar", "GBP - British Pound") + + override fun getWidgetConversionPairs(appWidgetId: Int): Pair { + return Pair(null, null) + } + + override fun setWidgetConversionPairs( + fromCurrency: String, + toCurrency: String, + appWidgetId: Int + ) { + } + + override fun removeWidgetConversionPairs(id: Int) {} + +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/appttude/h_mal/easycc/robots/CurrencyRobot.kt b/app/src/androidTest/java/com/appttude/h_mal/easycc/robots/CurrencyRobot.kt new file mode 100644 index 0000000..dace4cb --- /dev/null +++ b/app/src/androidTest/java/com/appttude/h_mal/easycc/robots/CurrencyRobot.kt @@ -0,0 +1,84 @@ +package com.appttude.h_mal.easycc.robots + +import android.view.View +import android.view.ViewGroup +import androidx.test.espresso.Espresso +import androidx.test.espresso.action.ViewActions +import androidx.test.espresso.assertion.ViewAssertions +import androidx.test.espresso.matcher.ViewMatchers +import com.appttude.h_mal.easycc.R +import org.hamcrest.Description +import org.hamcrest.Matcher +import org.hamcrest.Matchers +import org.hamcrest.TypeSafeMatcher + +fun currencyRobot(func: CurrencyRobot.() -> Unit) = CurrencyRobot() + .apply { func() } + +class CurrencyRobot { + + fun clickOnTopList() { + Espresso.onView(ViewMatchers.withId(R.id.currency_one)).perform(ViewActions.click()) + } + + fun clickOnBottomList() { + Espresso.onView(ViewMatchers.withId(R.id.currency_two)).perform(ViewActions.click()) + } + + fun searchInCurrencyList(search: String) { + Espresso.onView(ViewMatchers.withId(R.id.search_text)) + .perform(ViewActions.replaceText(search), ViewActions.closeSoftKeyboard()) + } + + fun enterValueInTopEditText(text: String) { + Espresso.onView(ViewMatchers.withId(R.id.topInsertValue)) + .perform(ViewActions.replaceText(text), ViewActions.closeSoftKeyboard()) + } + + fun selectItemInCurrencyList() { + Espresso.onData(Matchers.anything()) + .inAdapterView( + Matchers.allOf( + ViewMatchers.withId(R.id.list_view), + childAtPosition( + ViewMatchers.withClassName(Matchers.`is`("androidx.cardview.widget.CardView")), + 0 + ) + ) + ) + .atPosition(0) + .perform(ViewActions.click()) + } + + fun assertTextInTop(text: String) { + Espresso.onView( + ViewMatchers.withId(R.id.topInsertValue) + + ).check(ViewAssertions.matches(ViewMatchers.withText(text))) + } + + fun assertTextInBottom(text: String) { + Espresso.onView( + ViewMatchers.withId(R.id.bottomInsertValues) + + ).check(ViewAssertions.matches(ViewMatchers.withText(text))) + } + + private fun childAtPosition( + parentMatcher: Matcher, position: Int + ): Matcher { + + return object : TypeSafeMatcher() { + override fun describeTo(description: Description) { + description.appendText("Child at position $position in parent ") + parentMatcher.describeTo(description) + } + + public override fun matchesSafely(view: View): Boolean { + val parent = view.parent + return parent is ViewGroup && parentMatcher.matches(parent) + && view == parent.getChildAt(position) + } + } + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/appttude/h_mal/easycc/ui/main/MainActivityTest.kt b/app/src/androidTest/java/com/appttude/h_mal/easycc/ui/main/MainActivityTest.kt new file mode 100644 index 0000000..19e298f --- /dev/null +++ b/app/src/androidTest/java/com/appttude/h_mal/easycc/ui/main/MainActivityTest.kt @@ -0,0 +1,35 @@ +@file:Suppress("DEPRECATION") + +package com.appttude.h_mal.easycc.ui.main + + +import androidx.test.filters.LargeTest +import androidx.test.rule.ActivityTestRule +import androidx.test.runner.AndroidJUnit4 +import com.appttude.h_mal.easycc.robots.currencyRobot +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@LargeTest +@RunWith(AndroidJUnit4::class) +class MainActivityTest { + + @Rule + @JvmField + var mActivityTestRule = ActivityTestRule(MainActivity::class.java) + + @Test + fun mainActivityTest() { + currencyRobot { + clickOnTopList() + searchInCurrencyList("AUD") + selectItemInCurrencyList() + clickOnBottomList() + searchInCurrencyList("GBP") + selectItemInCurrencyList() + enterValueInTopEditText("1") + assertTextInBottom("0.55") + } + } +} diff --git a/app/src/main/java/com/appttude/h_mal/easycc/application/AppClass.kt b/app/src/main/java/com/appttude/h_mal/easycc/application/AppClass.kt index d38cdc8..f1a2a05 100644 --- a/app/src/main/java/com/appttude/h_mal/easycc/application/AppClass.kt +++ b/app/src/main/java/com/appttude/h_mal/easycc/application/AppClass.kt @@ -30,7 +30,7 @@ class AppClass : Application(), KodeinAware { bind() from singleton { loggingInterceptor() } bind() from singleton { QueryInterceptor(instance()) } bind() from singleton { CurrencyApi(instance(), instance(), instance()) } - bind() from singleton { BackupCurrencyApi(instance(),instance()) } + bind() from singleton { BackupCurrencyApi(instance(), instance()) } bind() from singleton { PreferenceProvider(instance()) } bind() from singleton { RepositoryImpl(instance(), instance(), instance()) } bind() from singleton { CurrencyDataHelper(instance()) } diff --git a/app/src/main/java/com/appttude/h_mal/easycc/data/network/interceptors/NetworkConnectionInterceptor.kt b/app/src/main/java/com/appttude/h_mal/easycc/data/network/interceptors/NetworkConnectionInterceptor.kt index fe42194..248f22f 100644 --- a/app/src/main/java/com/appttude/h_mal/easycc/data/network/interceptors/NetworkConnectionInterceptor.kt +++ b/app/src/main/java/com/appttude/h_mal/easycc/data/network/interceptors/NetworkConnectionInterceptor.kt @@ -4,7 +4,6 @@ import android.content.Context import android.net.ConnectivityManager import android.net.NetworkCapabilities import android.os.Build -import androidx.annotation.RequiresApi import okhttp3.Interceptor import okhttp3.Response import java.io.IOException @@ -21,7 +20,7 @@ class NetworkConnectionInterceptor( private val applicationContext = context.applicationContext override fun intercept(chain: Interceptor.Chain): Response { - if (!isInternetAvailable()){ + if (!isInternetAvailable()) { throw IOException("Make sure you have an active data connection") } return chain.proceed(chain.request()) diff --git a/app/src/main/java/com/appttude/h_mal/easycc/data/network/interceptors/QueryInterceptor.kt b/app/src/main/java/com/appttude/h_mal/easycc/data/network/interceptors/QueryInterceptor.kt index 3906453..d38b90a 100644 --- a/app/src/main/java/com/appttude/h_mal/easycc/data/network/interceptors/QueryInterceptor.kt +++ b/app/src/main/java/com/appttude/h_mal/easycc/data/network/interceptors/QueryInterceptor.kt @@ -20,12 +20,12 @@ class QueryInterceptor( val originalHttpUrl: HttpUrl = original.url val url = originalHttpUrl.newBuilder() - .addQueryParameter("apiKey", context.getString(R.string.apiKey)) - .build() + .addQueryParameter("apiKey", context.getString(R.string.apiKey)) + .build() // Add amended Url back to request val requestBuilder: Request.Builder = original.newBuilder() - .url(url) + .url(url) val request: Request = requestBuilder.build() return chain.proceed(request) diff --git a/app/src/main/java/com/appttude/h_mal/easycc/data/network/response/CurrencyResponse.kt b/app/src/main/java/com/appttude/h_mal/easycc/data/network/response/CurrencyResponse.kt index f1efcc0..02b585d 100644 --- a/app/src/main/java/com/appttude/h_mal/easycc/data/network/response/CurrencyResponse.kt +++ b/app/src/main/java/com/appttude/h_mal/easycc/data/network/response/CurrencyResponse.kt @@ -13,18 +13,18 @@ data class CurrencyResponse( val amount: Double? = null, @field:SerializedName("rates") - var rates : Map? = null, + var rates: Map? = null, @field:SerializedName("base") val base: String? = null -): CurrencyModelInterface { +) : CurrencyModelInterface { - override fun getCurrencyModel(): CurrencyModel { - return CurrencyModel( + override fun getCurrencyModel(): CurrencyModel { + return CurrencyModel( base, rates?.iterator()?.next()?.key, rates?.iterator()?.next()?.value ?: 0.0 ) - } + } } diff --git a/app/src/main/java/com/appttude/h_mal/easycc/data/network/response/ResponseObject.kt b/app/src/main/java/com/appttude/h_mal/easycc/data/network/response/ResponseObject.kt index 862d615..ab8742f 100644 --- a/app/src/main/java/com/appttude/h_mal/easycc/data/network/response/ResponseObject.kt +++ b/app/src/main/java/com/appttude/h_mal/easycc/data/network/response/ResponseObject.kt @@ -7,18 +7,17 @@ import com.google.gson.annotations.SerializedName data class ResponseObject( @field:SerializedName("query") - var query : Any? = null, + var query: Any? = null, @field:SerializedName("results") - var results : Map? = null -): CurrencyModelInterface { - - override fun getCurrencyModel(): CurrencyModel { - val res = results?.iterator()?.next()?.value - return CurrencyModel( - res?.fr, - res?.to, - res?.value ?: 0.0 - ) - } + var results: Map? = null +) : CurrencyModelInterface { + override fun getCurrencyModel(): CurrencyModel { + val res = results?.iterator()?.next()?.value + return CurrencyModel( + res?.fr, + res?.to, + res?.value ?: 0.0 + ) + } } \ No newline at end of file diff --git a/app/src/main/java/com/appttude/h_mal/easycc/ui/main/MainActivity.kt b/app/src/main/java/com/appttude/h_mal/easycc/ui/main/MainActivity.kt index bc00ce2..c81f544 100644 --- a/app/src/main/java/com/appttude/h_mal/easycc/ui/main/MainActivity.kt +++ b/app/src/main/java/com/appttude/h_mal/easycc/ui/main/MainActivity.kt @@ -8,7 +8,6 @@ import android.view.WindowManager import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.databinding.DataBindingUtil -import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import com.appttude.h_mal.easycc.R import com.appttude.h_mal.easycc.databinding.ActivityMainBinding diff --git a/app/src/main/java/com/appttude/h_mal/easycc/ui/main/MainViewModelFactory.kt b/app/src/main/java/com/appttude/h_mal/easycc/ui/main/MainViewModelFactory.kt index 5102663..8c5f3a5 100644 --- a/app/src/main/java/com/appttude/h_mal/easycc/ui/main/MainViewModelFactory.kt +++ b/app/src/main/java/com/appttude/h_mal/easycc/ui/main/MainViewModelFactory.kt @@ -2,7 +2,7 @@ package com.appttude.h_mal.easycc.ui.main import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider -import com.appttude.h_mal.easycc.data.repository.RepositoryImpl +import com.appttude.h_mal.easycc.data.repository.Repository import com.appttude.h_mal.easycc.helper.CurrencyDataHelper /** @@ -11,7 +11,7 @@ import com.appttude.h_mal.easycc.helper.CurrencyDataHelper */ @Suppress("UNCHECKED_CAST") class MainViewModelFactory( - private val repository: RepositoryImpl, + private val repository: Repository, private val helper: CurrencyDataHelper ) : ViewModelProvider.NewInstanceFactory() { diff --git a/app/src/main/java/com/appttude/h_mal/easycc/ui/widget/CurrencyAppWidgetConfigureActivityKotlin.kt b/app/src/main/java/com/appttude/h_mal/easycc/ui/widget/CurrencyAppWidgetConfigureActivityKotlin.kt index 428317b..2ce3050 100644 --- a/app/src/main/java/com/appttude/h_mal/easycc/ui/widget/CurrencyAppWidgetConfigureActivityKotlin.kt +++ b/app/src/main/java/com/appttude/h_mal/easycc/ui/widget/CurrencyAppWidgetConfigureActivityKotlin.kt @@ -8,7 +8,6 @@ import android.view.View import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.databinding.DataBindingUtil -import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders import com.appttude.h_mal.easycc.R import com.appttude.h_mal.easycc.databinding.CurrencyAppWidgetConfigureBinding diff --git a/app/src/main/java/com/appttude/h_mal/easycc/utils/PrimitiveUtils.kt b/app/src/main/java/com/appttude/h_mal/easycc/utils/PrimitiveUtils.kt index b417ce3..d972e02 100644 --- a/app/src/main/java/com/appttude/h_mal/easycc/utils/PrimitiveUtils.kt +++ b/app/src/main/java/com/appttude/h_mal/easycc/utils/PrimitiveUtils.kt @@ -3,11 +3,11 @@ package com.appttude.h_mal.easycc.utils import java.lang.Double.valueOf import java.text.DecimalFormat -fun transformIntToArray(int: Int): IntArray{ +fun transformIntToArray(int: Int): IntArray { return intArrayOf(int) } -fun String.trimToThree(): String{ +fun String.trimToThree(): String { val size = length return when { size > 3 -> substring(0, 3) @@ -16,19 +16,19 @@ fun String.trimToThree(): String{ } fun convertPairsListToString(s1: String, s2: String): String = - "${s1.trimToThree()}_${s2.trimToThree()}" + "${s1.trimToThree()}_${s2.trimToThree()}" fun Double.toTwoDp() = run { try { val df = DecimalFormat("0.00") valueOf(df.format(this)) - }catch (e: NumberFormatException){ + } catch (e: NumberFormatException) { e.printStackTrace() this } } -fun Double.toTwoDpString(): String{ +fun Double.toTwoDpString(): String { return this.toTwoDp().toBigDecimal().toPlainString() } \ No newline at end of file diff --git a/app/src/main/res/drawable-nodpi/gradient.xml b/app/src/main/res/drawable-nodpi/gradient.xml index 42142be..b911027 100644 --- a/app/src/main/res/drawable-nodpi/gradient.xml +++ b/app/src/main/res/drawable-nodpi/gradient.xml @@ -5,5 +5,5 @@ android:startColor="#b3001b" android:endColor="#262626" android:type="linear" - android:angle="45"/> + android:angle="45" /> \ No newline at end of file diff --git a/app/src/main/res/drawable-nodpi/round_edit_text.xml b/app/src/main/res/drawable-nodpi/round_edit_text.xml index f0b8224..9cb281a 100644 --- a/app/src/main/res/drawable-nodpi/round_edit_text.xml +++ b/app/src/main/res/drawable-nodpi/round_edit_text.xml @@ -1,6 +1,7 @@ - + - - - - - - - - + + + + + + + + diff --git a/app/src/main/res/drawable/ic_refresh_white_24dp.xml b/app/src/main/res/drawable/ic_refresh_white_24dp.xml index cc2d1e0..a27ba3c 100644 --- a/app/src/main/res/drawable/ic_refresh_white_24dp.xml +++ b/app/src/main/res/drawable/ic_refresh_white_24dp.xml @@ -1,5 +1,10 @@ - - + + diff --git a/app/src/main/res/layout/currency_app_widget.xml b/app/src/main/res/layout/currency_app_widget.xml index 393e531..8d9d1b1 100644 --- a/app/src/main/res/layout/currency_app_widget.xml +++ b/app/src/main/res/layout/currency_app_widget.xml @@ -8,10 +8,10 @@ android:background="#4D000000"> - + + + android:adjustViewBounds="true" /> - - - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/currency_app_widget_configure.xml b/app/src/main/res/layout/currency_app_widget_configure.xml index f851bc0..844d821 100644 --- a/app/src/main/res/layout/currency_app_widget_configure.xml +++ b/app/src/main/res/layout/currency_app_widget_configure.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools"> + @@ -78,6 +79,5 @@ - diff --git a/app/src/main/res/layout/custom_dialog.xml b/app/src/main/res/layout/custom_dialog.xml index d3dd7dd..7b6354b 100644 --- a/app/src/main/res/layout/custom_dialog.xml +++ b/app/src/main/res/layout/custom_dialog.xml @@ -1,13 +1,11 @@ - - - - + + \ No newline at end of file + android:widgetCategory="home_screen|keyguard" /> \ No newline at end of file