mirror of
https://github.com/hmalik144/EasyCC_Master.git
synced 2026-03-18 07:26:16 +00:00
- lint checks done
- added service intent Took 1 hour 7 minutes
This commit is contained in:
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
@@ -22,7 +22,7 @@ import org.kodein.di.generic.singleton
|
|||||||
|
|
||||||
class AppClass : Application(), KodeinAware {
|
class AppClass : Application(), KodeinAware {
|
||||||
|
|
||||||
// Kodein Dependecy Injection singletons and providers created
|
// KODEIN DI components declaration
|
||||||
override val kodein by Kodein.lazy {
|
override val kodein by Kodein.lazy {
|
||||||
import(androidXModule(this@AppClass))
|
import(androidXModule(this@AppClass))
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.appttude.h_mal.easycc.data.network
|
package com.appttude.h_mal.easycc.data.network
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
@@ -10,7 +9,6 @@ import java.io.IOException
|
|||||||
* This abstract class extract objects from Retrofit [Response]
|
* This abstract class extract objects from Retrofit [Response]
|
||||||
* or throws IOException if object does not exist
|
* or throws IOException if object does not exist
|
||||||
*/
|
*/
|
||||||
private const val TAG = "SafeApiRequest"
|
|
||||||
abstract class SafeApiRequest {
|
abstract class SafeApiRequest {
|
||||||
|
|
||||||
suspend fun <T : Any> responseUnwrap(
|
suspend fun <T : Any> responseUnwrap(
|
||||||
@@ -45,10 +43,6 @@ abstract class SafeApiRequest {
|
|||||||
}
|
}
|
||||||
print(log)
|
print(log)
|
||||||
|
|
||||||
// Log.e("Api Response Error", log)
|
|
||||||
|
|
||||||
//return error message
|
|
||||||
//if null return error code
|
|
||||||
return errorMessageString ?: errorCode
|
return errorMessageString ?: errorCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,18 +11,16 @@ import retrofit2.http.GET
|
|||||||
import retrofit2.http.Query
|
import retrofit2.http.Query
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrofit2 Network class to create network requests
|
* Retrofit Network class to currency api calls
|
||||||
*/
|
*/
|
||||||
interface BackupCurrencyApi {
|
interface BackupCurrencyApi {
|
||||||
|
|
||||||
// Get rate from server with arguments passed in Repository
|
|
||||||
@GET("latest?")
|
@GET("latest?")
|
||||||
suspend fun getCurrencyRate(
|
suspend fun getCurrencyRate(
|
||||||
@Query("from") currencyFrom: String,
|
@Query("from") currencyFrom: String,
|
||||||
@Query("to") currencyTo: String
|
@Query("to") currencyTo: String
|
||||||
): Response<CurrencyResponse>
|
): Response<CurrencyResponse>
|
||||||
|
|
||||||
// interface invokation to be used in application class
|
|
||||||
companion object {
|
companion object {
|
||||||
operator fun invoke(
|
operator fun invoke(
|
||||||
networkConnectionInterceptor: NetworkConnectionInterceptor,
|
networkConnectionInterceptor: NetworkConnectionInterceptor,
|
||||||
@@ -34,7 +32,6 @@ interface BackupCurrencyApi {
|
|||||||
.addNetworkInterceptor(networkConnectionInterceptor)
|
.addNetworkInterceptor(networkConnectionInterceptor)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
// Build retrofit
|
|
||||||
return Retrofit.Builder()
|
return Retrofit.Builder()
|
||||||
.client(okkHttpclient)
|
.client(okkHttpclient)
|
||||||
.baseUrl("https://api.frankfurter.app/")
|
.baseUrl("https://api.frankfurter.app/")
|
||||||
@@ -44,6 +41,4 @@ interface BackupCurrencyApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ import retrofit2.http.GET
|
|||||||
import retrofit2.http.Query
|
import retrofit2.http.Query
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrofit2 Network class to create network requests
|
* Retrofit Network class to currency api calls
|
||||||
*/
|
*/
|
||||||
interface CurrencyApi {
|
interface CurrencyApi {
|
||||||
|
|
||||||
@@ -28,14 +28,12 @@ interface CurrencyApi {
|
|||||||
interceptor: HttpLoggingInterceptor
|
interceptor: HttpLoggingInterceptor
|
||||||
): CurrencyApi {
|
): CurrencyApi {
|
||||||
|
|
||||||
// okkHttpclient with injected interceptors
|
|
||||||
val okkHttpclient = OkHttpClient.Builder()
|
val okkHttpclient = OkHttpClient.Builder()
|
||||||
.addInterceptor(interceptor)
|
.addInterceptor(interceptor)
|
||||||
.addInterceptor(queryInterceptor)
|
.addInterceptor(queryInterceptor)
|
||||||
.addNetworkInterceptor(networkConnectionInterceptor)
|
.addNetworkInterceptor(networkConnectionInterceptor)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
// Build retrofit
|
|
||||||
return Retrofit.Builder()
|
return Retrofit.Builder()
|
||||||
.client(okkHttpclient)
|
.client(okkHttpclient)
|
||||||
.baseUrl("https://free.currencyconverterapi.com/api/v3/")
|
.baseUrl("https://free.currencyconverterapi.com/api/v3/")
|
||||||
|
|||||||
@@ -3,14 +3,17 @@ package com.appttude.h_mal.easycc.data.network.interceptors
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.NetworkCapabilities
|
import android.net.NetworkCapabilities
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interceptor used in [CurrencyApi] to intercept network status
|
* Interceptor used in network classes to check network status
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
class NetworkConnectionInterceptor(
|
class NetworkConnectionInterceptor(
|
||||||
context: Context
|
context: Context
|
||||||
) : Interceptor {
|
) : Interceptor {
|
||||||
@@ -29,6 +32,7 @@ class NetworkConnectionInterceptor(
|
|||||||
val connectivityManager =
|
val connectivityManager =
|
||||||
applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
|
applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
|
||||||
connectivityManager?.let {
|
connectivityManager?.let {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
it.getNetworkCapabilities(connectivityManager.activeNetwork)?.apply {
|
it.getNetworkCapabilities(connectivityManager.activeNetwork)?.apply {
|
||||||
result = when {
|
result = when {
|
||||||
hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
|
hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
|
||||||
@@ -36,6 +40,16 @@ class NetworkConnectionInterceptor(
|
|||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
it.activeNetworkInfo?.run {
|
||||||
|
result = when (type) {
|
||||||
|
ConnectivityManager.TYPE_WIFI -> true
|
||||||
|
ConnectivityManager.TYPE_MOBILE -> true
|
||||||
|
ConnectivityManager.TYPE_ETHERNET -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.appttude.h_mal.easycc.data.network.interceptors
|
package com.appttude.h_mal.easycc.data.network.interceptors
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.appttude.h_mal.easycc.BuildConfig
|
|
||||||
import com.appttude.h_mal.easycc.R
|
import com.appttude.h_mal.easycc.R
|
||||||
import okhttp3.HttpUrl
|
import okhttp3.HttpUrl
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ class PreferenceProvider(context: Context) {
|
|||||||
private val appContext = context.applicationContext
|
private val appContext = context.applicationContext
|
||||||
|
|
||||||
// Instance of Shared preferences
|
// Instance of Shared preferences
|
||||||
private val preference: SharedPreferences
|
private val preference: SharedPreferences =
|
||||||
= PreferenceManager.getDefaultSharedPreferences(appContext)
|
PreferenceManager.getDefaultSharedPreferences(appContext)
|
||||||
|
|
||||||
// Lazy declaration of default rate if no rate is retrieved from
|
// Lazy declaration of default rate if no rate is retrieved from
|
||||||
private val defaultRate: String by lazy {
|
private val defaultRate: String by lazy {
|
||||||
@@ -50,8 +50,10 @@ class PreferenceProvider(context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save currency pairs for widget
|
// Save currency pairs for widget
|
||||||
fun saveWidgetConversionPair(fromString: String,
|
fun saveWidgetConversionPair(
|
||||||
toString: String, appWidgetId: Int) {
|
fromString: String,
|
||||||
|
toString: String, appWidgetId: Int
|
||||||
|
) {
|
||||||
|
|
||||||
preference.edit()
|
preference.edit()
|
||||||
.putString("${appWidgetId}_$CURRENCY_ONE", fromString)
|
.putString("${appWidgetId}_$CURRENCY_ONE", fromString)
|
||||||
@@ -68,7 +70,8 @@ class PreferenceProvider(context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getWidgetConversionString(
|
private fun getWidgetConversionString(
|
||||||
appWidgetId: Int, conversionName: String): String? {
|
appWidgetId: Int, conversionName: String
|
||||||
|
): String? {
|
||||||
return preference
|
return preference
|
||||||
.getString("${appWidgetId}_$conversionName", defaultRate)
|
.getString("${appWidgetId}_$conversionName", defaultRate)
|
||||||
}
|
}
|
||||||
@@ -78,7 +81,6 @@ class PreferenceProvider(context: Context) {
|
|||||||
.remove("${id}_$CURRENCY_ONE")
|
.remove("${id}_$CURRENCY_ONE")
|
||||||
.remove("${id}_$CURRENCY_TWO")
|
.remove("${id}_$CURRENCY_TWO")
|
||||||
.apply()
|
.apply()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -49,8 +49,10 @@ class RepositoryImpl (
|
|||||||
override fun getWidgetConversionPairs(appWidgetId: Int): Pair<String?, String?> =
|
override fun getWidgetConversionPairs(appWidgetId: Int): Pair<String?, String?> =
|
||||||
prefs.getWidgetConversionPair(appWidgetId)
|
prefs.getWidgetConversionPair(appWidgetId)
|
||||||
|
|
||||||
override fun setWidgetConversionPairs(fromCurrency: String,
|
override fun setWidgetConversionPairs(
|
||||||
toCurrency: String, appWidgetId: Int) {
|
fromCurrency: String,
|
||||||
|
toCurrency: String, appWidgetId: Int
|
||||||
|
) {
|
||||||
return prefs.saveWidgetConversionPair(fromCurrency, toCurrency, appWidgetId)
|
return prefs.saveWidgetConversionPair(fromCurrency, toCurrency, appWidgetId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.appttude.h_mal.easycc.helper
|
|||||||
|
|
||||||
import com.appttude.h_mal.easycc.data.repository.Repository
|
import com.appttude.h_mal.easycc.data.repository.Repository
|
||||||
import com.appttude.h_mal.easycc.models.CurrencyModelInterface
|
import com.appttude.h_mal.easycc.models.CurrencyModelInterface
|
||||||
import java.lang.Exception
|
|
||||||
|
|
||||||
class CurrencyDataHelper(
|
class CurrencyDataHelper(
|
||||||
val repository: Repository
|
val repository: Repository
|
||||||
|
|||||||
@@ -4,10 +4,8 @@ import com.appttude.h_mal.easycc.data.repository.Repository
|
|||||||
import com.appttude.h_mal.easycc.models.CurrencyModel
|
import com.appttude.h_mal.easycc.models.CurrencyModel
|
||||||
import com.appttude.h_mal.easycc.utils.trimToThree
|
import com.appttude.h_mal.easycc.utils.trimToThree
|
||||||
|
|
||||||
import kotlin.Exception
|
|
||||||
|
|
||||||
class WidgetHelper(
|
class WidgetHelper(
|
||||||
val helper: CurrencyDataHelper,
|
private val helper: CurrencyDataHelper,
|
||||||
val repository: Repository
|
val repository: Repository
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import kotlinx.android.synthetic.main.custom_dialog.*
|
|||||||
/**
|
/**
|
||||||
* Custom dialog when selecting currencies from list with filter
|
* Custom dialog when selecting currencies from list with filter
|
||||||
*/
|
*/
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
class CustomDialogClass(
|
class CustomDialogClass(
|
||||||
context: Context,
|
context: Context,
|
||||||
private val clickListener: ClickListener
|
private val clickListener: ClickListener
|
||||||
@@ -31,7 +32,8 @@ class CustomDialogClass(
|
|||||||
val arrayAdapter =
|
val arrayAdapter =
|
||||||
ArrayAdapter.createFromResource(
|
ArrayAdapter.createFromResource(
|
||||||
context, R.array.currency_arrays,
|
context, R.array.currency_arrays,
|
||||||
android.R.layout.simple_list_item_1)
|
android.R.layout.simple_list_item_1
|
||||||
|
)
|
||||||
|
|
||||||
list_view.adapter = arrayAdapter
|
list_view.adapter = arrayAdapter
|
||||||
|
|
||||||
@@ -41,6 +43,7 @@ class CustomDialogClass(
|
|||||||
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
|
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
|
||||||
arrayAdapter.filter.filter(charSequence)
|
arrayAdapter.filter.filter(charSequence)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun afterTextChanged(editable: Editable) {}
|
override fun afterTextChanged(editable: Editable) {}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.kodein.di.KodeinAware
|
|||||||
import org.kodein.di.android.kodein
|
import org.kodein.di.android.kodein
|
||||||
import org.kodein.di.generic.instance
|
import org.kodein.di.generic.instance
|
||||||
|
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
class MainActivity : AppCompatActivity(), KodeinAware, View.OnClickListener {
|
class MainActivity : AppCompatActivity(), KodeinAware, View.OnClickListener {
|
||||||
|
|
||||||
// Retrieve MainViewModelFactory via dependency injection
|
// Retrieve MainViewModelFactory via dependency injection
|
||||||
@@ -54,10 +55,10 @@ class MainActivity : AppCompatActivity(), KodeinAware, View.OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setUpObservers() {
|
private fun setUpObservers() {
|
||||||
viewModel.operationStartedListener.observe(this, Observer {
|
viewModel.operationStartedListener.observe(this, {
|
||||||
progressBar.hideView(false)
|
progressBar.hideView(false)
|
||||||
})
|
})
|
||||||
viewModel.operationFinishedListener.observe(this, Observer { pair ->
|
viewModel.operationFinishedListener.observe(this, { pair ->
|
||||||
// hide progress bar
|
// hide progress bar
|
||||||
progressBar.hideView(true)
|
progressBar.hideView(true)
|
||||||
if (pair.first) {
|
if (pair.first) {
|
||||||
|
|||||||
@@ -98,7 +98,9 @@ class MainViewModel(
|
|||||||
when (tag.toString()) {
|
when (tag.toString()) {
|
||||||
"top" -> rateIdFrom = currencyName
|
"top" -> rateIdFrom = currencyName
|
||||||
"bottom" -> rateIdTo = currencyName
|
"bottom" -> rateIdTo = currencyName
|
||||||
else -> { return }
|
else -> {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getExchangeRate()
|
getExchangeRate()
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ import org.kodein.di.generic.instance
|
|||||||
/**
|
/**
|
||||||
* The configuration screen for the [CurrencyAppWidgetKotlin] AppWidget.
|
* The configuration screen for the [CurrencyAppWidgetKotlin] AppWidget.
|
||||||
*/
|
*/
|
||||||
class CurrencyAppWidgetConfigureActivityKotlin : AppCompatActivity(), KodeinAware, View.OnClickListener {
|
class CurrencyAppWidgetConfigureActivityKotlin : AppCompatActivity(), KodeinAware,
|
||||||
|
View.OnClickListener {
|
||||||
|
|
||||||
override val kodein by kodein()
|
override val kodein by kodein()
|
||||||
private val factory: WidgetViewModelFactory by instance()
|
private val factory: WidgetViewModelFactory by instance()
|
||||||
@@ -47,7 +48,8 @@ class CurrencyAppWidgetConfigureActivityKotlin : AppCompatActivity(), KodeinAwar
|
|||||||
val extras = intent.extras
|
val extras = intent.extras
|
||||||
if (extras != null) {
|
if (extras != null) {
|
||||||
mAppWidgetId = extras.getInt(
|
mAppWidgetId = extras.getInt(
|
||||||
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
|
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this activity was started with an intent without an app widget ID, finish with an error.
|
// If this activity was started with an intent without an app widget ID, finish with an error.
|
||||||
@@ -72,7 +74,7 @@ class CurrencyAppWidgetConfigureActivityKotlin : AppCompatActivity(), KodeinAwar
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupObserver() {
|
private fun setupObserver() {
|
||||||
viewModel.operationFinishedListener.observe(this, Observer {
|
viewModel.operationFinishedListener.observe(this, {
|
||||||
|
|
||||||
// it.first is a the success of the operation
|
// it.first is a the success of the operation
|
||||||
if (it.first) {
|
if (it.first) {
|
||||||
@@ -136,7 +138,8 @@ class CurrencyAppWidgetConfigureActivityKotlin : AppCompatActivity(), KodeinAwar
|
|||||||
fun sendUpdateIntent() {
|
fun sendUpdateIntent() {
|
||||||
// It is the responsibility of the configuration activity to update the app widget
|
// It is the responsibility of the configuration activity to update the app widget
|
||||||
// Send update broadcast to widget app class
|
// Send update broadcast to widget app class
|
||||||
Intent(this@CurrencyAppWidgetConfigureActivityKotlin,
|
Intent(
|
||||||
|
this@CurrencyAppWidgetConfigureActivityKotlin,
|
||||||
CurrencyAppWidgetKotlin::class.java
|
CurrencyAppWidgetKotlin::class.java
|
||||||
).apply {
|
).apply {
|
||||||
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
package com.appttude.h_mal.easycc.ui.widget
|
|
||||||
|
|
||||||
import android.app.Dialog
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.text.Editable
|
|
||||||
import android.text.TextWatcher
|
|
||||||
import android.view.WindowManager
|
|
||||||
import android.widget.ArrayAdapter
|
|
||||||
import com.appttude.h_mal.easycc.R
|
|
||||||
import kotlinx.android.synthetic.main.custom_dialog.*
|
|
||||||
|
|
||||||
/*
|
|
||||||
widget for when submitting the completed selections
|
|
||||||
*/
|
|
||||||
class WidgetItemSelectDialog(
|
|
||||||
context: Context,
|
|
||||||
private val dialogResult: DialogResult
|
|
||||||
) :Dialog(context){
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
setContentView(R.layout.custom_dialog)
|
|
||||||
|
|
||||||
window!!.setBackgroundDrawableResource(android.R.color.transparent)
|
|
||||||
window!!.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
|
|
||||||
|
|
||||||
val arrayAdapter = ArrayAdapter.createFromResource(context, R.array.currency_arrays, android.R.layout.simple_list_item_1)
|
|
||||||
list_view.adapter = arrayAdapter
|
|
||||||
|
|
||||||
search_text.addTextChangedListener(object : TextWatcher {
|
|
||||||
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
|
|
||||||
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
|
|
||||||
arrayAdapter.filter.filter(charSequence)
|
|
||||||
}
|
|
||||||
override fun afterTextChanged(editable: Editable) {}
|
|
||||||
})
|
|
||||||
|
|
||||||
list_view.setOnItemClickListener{ adapterView, _, i, _ ->
|
|
||||||
dialogResult.result(adapterView.getItemAtPosition(i).toString())
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface DialogResult{
|
|
||||||
fun result(result : String)
|
|
||||||
}
|
|
||||||
@@ -23,8 +23,7 @@ class WidgetViewModel(
|
|||||||
// Set default values for text views
|
// Set default values for text views
|
||||||
fun initiate(appId: Int) {
|
fun initiate(appId: Int) {
|
||||||
appWidgetId = appId
|
appWidgetId = appId
|
||||||
val widgetString
|
val widgetString = repository.getWidgetConversionPairs(appId)
|
||||||
= repository.getWidgetConversionPairs(appId)
|
|
||||||
|
|
||||||
rateIdFrom = widgetString.first ?: defaultCurrency
|
rateIdFrom = widgetString.first ?: defaultCurrency
|
||||||
rateIdTo = widgetString.second ?: defaultCurrency
|
rateIdTo = widgetString.second ?: defaultCurrency
|
||||||
@@ -61,7 +60,9 @@ class WidgetViewModel(
|
|||||||
when (tag.toString()) {
|
when (tag.toString()) {
|
||||||
"top" -> rateIdFrom = currencyName
|
"top" -> rateIdFrom = currencyName
|
||||||
"bottom" -> rateIdTo = currencyName
|
"bottom" -> rateIdTo = currencyName
|
||||||
else -> { return }
|
else -> {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.appttude.h_mal.easycc.utils
|
|||||||
|
|
||||||
import java.lang.Double.valueOf
|
import java.lang.Double.valueOf
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
fun transformIntToArray(int: Int): IntArray{
|
fun transformIntToArray(int: Int): IntArray{
|
||||||
return intArrayOf(int)
|
return intArrayOf(int)
|
||||||
|
|||||||
@@ -10,7 +10,11 @@ fun EditText.clearEditText(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun View.hideView(vis: Boolean) {
|
fun View.hideView(vis: Boolean) {
|
||||||
visibility = if (vis){ View.GONE } else { View.VISIBLE }
|
visibility = if (vis) {
|
||||||
|
View.GONE
|
||||||
|
} else {
|
||||||
|
View.VISIBLE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.displayToast(message: String) {
|
fun Context.displayToast(message: String) {
|
||||||
|
|||||||
@@ -1,21 +1,11 @@
|
|||||||
package com.appttude.h_mal.easycc.widget
|
package com.appttude.h_mal.easycc.widget
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.appwidget.AppWidgetManager
|
import android.appwidget.AppWidgetManager
|
||||||
import android.appwidget.AppWidgetProvider
|
import android.appwidget.AppWidgetProvider
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.util.Log
|
|
||||||
import android.widget.RemoteViews
|
|
||||||
import com.appttude.h_mal.easycc.R
|
|
||||||
import com.appttude.h_mal.easycc.helper.WidgetHelper
|
import com.appttude.h_mal.easycc.helper.WidgetHelper
|
||||||
import com.appttude.h_mal.easycc.ui.main.MainActivity
|
import com.appttude.h_mal.easycc.widget.WidgetServiceIntent.Companion.enqueueWork
|
||||||
import com.appttude.h_mal.easycc.utils.transformIntToArray
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.kodein.di.KodeinAware
|
import org.kodein.di.KodeinAware
|
||||||
import org.kodein.di.LateInitKodein
|
import org.kodein.di.LateInitKodein
|
||||||
import org.kodein.di.generic.instance
|
import org.kodein.di.generic.instance
|
||||||
@@ -23,9 +13,8 @@ import org.kodein.di.generic.instance
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of App Widget functionality.
|
* Implementation of App Widget functionality.
|
||||||
* App Widget Configuration implemented in [CurrencyAppWidgetConfigureActivityKotlin]
|
* App Widget Configuration implemented in [CurrencyAppWidgetKotlin]
|
||||||
*/
|
*/
|
||||||
private const val TAG = "CurrencyAppWidgetKotlin"
|
|
||||||
|
|
||||||
class CurrencyAppWidgetKotlin : AppWidgetProvider() {
|
class CurrencyAppWidgetKotlin : AppWidgetProvider() {
|
||||||
|
|
||||||
@@ -39,12 +28,7 @@ class CurrencyAppWidgetKotlin : AppWidgetProvider() {
|
|||||||
appWidgetManager: AppWidgetManager,
|
appWidgetManager: AppWidgetManager,
|
||||||
appWidgetIds: IntArray
|
appWidgetIds: IntArray
|
||||||
) {
|
) {
|
||||||
kodein.baseKodein = (context.applicationContext as KodeinAware).kodein
|
loadWidget(context)
|
||||||
Log.i(TAG, "onUpdate() appWidgetIds = ${appWidgetIds.size}")
|
|
||||||
// There may be multiple widgets active, so update all of them
|
|
||||||
for (appWidgetId in appWidgetIds) {
|
|
||||||
updateAppWidget(context, appWidgetManager, appWidgetId)
|
|
||||||
}
|
|
||||||
super.onUpdate(context, appWidgetManager, appWidgetIds)
|
super.onUpdate(context, appWidgetManager, appWidgetIds)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,113 +42,13 @@ class CurrencyAppWidgetKotlin : AppWidgetProvider() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onEnabled(context: Context) {
|
override fun onEnabled(context: Context) {
|
||||||
kodein.baseKodein = (context.applicationContext as KodeinAware).kodein
|
loadWidget(context)
|
||||||
// Enter relevant functionality for when the first widget is created
|
|
||||||
AppWidgetManager.getInstance(context).apply {
|
|
||||||
val thisAppWidget =
|
|
||||||
ComponentName(context.packageName, CurrencyAppWidgetKotlin::class.java.name)
|
|
||||||
val appWidgetIds = getAppWidgetIds(thisAppWidget)
|
|
||||||
onUpdate(context, this, appWidgetIds)
|
|
||||||
}
|
|
||||||
super.onEnabled(context)
|
super.onEnabled(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDisabled(context: Context) {
|
private fun loadWidget(context: Context) {
|
||||||
kodein.baseKodein = (context.applicationContext as KodeinAware).kodein
|
val mIntent = Intent(context, CurrencyAppWidgetKotlin::class.java)
|
||||||
// Enter relevant functionality for when the last widget is disabled
|
enqueueWork(context, mIntent)
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun updateAppWidget(
|
|
||||||
context: Context,
|
|
||||||
appWidgetManager: AppWidgetManager,
|
|
||||||
appWidgetId: Int
|
|
||||||
) {
|
|
||||||
// Construct the RemoteViews object
|
|
||||||
val views = RemoteViews(context.packageName, R.layout.currency_app_widget)
|
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
|
||||||
val exchangeResponse = repository.getWidgetData()
|
|
||||||
|
|
||||||
exchangeResponse?.let {
|
|
||||||
val titleString = "${it.from}${it.to}"
|
|
||||||
views.setTextViewText(R.id.exchangeName, titleString)
|
|
||||||
views.setTextViewText(R.id.exchangeRate, it.rate.toString())
|
|
||||||
|
|
||||||
setUpdateIntent(context, appWidgetId).let { intent ->
|
|
||||||
//set the pending intent to the icon
|
|
||||||
views.setImageViewResource(R.id.refresh_icon, R.drawable.ic_refresh_white_24dp)
|
|
||||||
views.setOnClickPendingIntent(R.id.refresh_icon, intent)
|
|
||||||
}
|
|
||||||
|
|
||||||
val clickIntentTemplate = clickingIntent(context)
|
|
||||||
|
|
||||||
val configPendingIntent =
|
|
||||||
PendingIntent.getActivity(
|
|
||||||
context, appWidgetId, clickIntentTemplate,
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
|
||||||
)
|
|
||||||
views.setOnClickPendingIntent(R.id.widget_view, configPendingIntent)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Instruct the widget manager to update the widget
|
|
||||||
appWidgetManager.updateAppWidget(appWidgetId, views)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setUpdateIntent(context: Context, appWidgetId: Int): PendingIntent? {
|
|
||||||
//Create update intent for refresh icon
|
|
||||||
val updateIntent = Intent(
|
|
||||||
context, CurrencyAppWidgetKotlin::class.java
|
|
||||||
).apply {
|
|
||||||
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
|
||||||
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, transformIntToArray(appWidgetId))
|
|
||||||
}
|
|
||||||
//add previous intent to this pending intent
|
|
||||||
return PendingIntent.getBroadcast(
|
|
||||||
context,
|
|
||||||
appWidgetId,
|
|
||||||
updateIntent,
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun clickingIntent(
|
|
||||||
context: Context
|
|
||||||
): Intent {
|
|
||||||
val pair = repository.repository.getConversionPair()
|
|
||||||
val s1 = pair.first
|
|
||||||
val s2 = pair.second
|
|
||||||
return Intent(context, MainActivity::class.java).apply {
|
|
||||||
action = Intent.ACTION_MAIN
|
|
||||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
|
||||||
putExtra("parse_1", s1)
|
|
||||||
putExtra("parse_2", s2)
|
|
||||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T: Activity> clickingIntent(
|
|
||||||
context: Context,
|
|
||||||
activity: Class<T>,
|
|
||||||
vararg argPairs: Pair<String, Any?>
|
|
||||||
): Intent {
|
|
||||||
|
|
||||||
return Intent(context, activity::class.java).apply {
|
|
||||||
action = Intent.ACTION_MAIN
|
|
||||||
addCategory(Intent.CATEGORY_LAUNCHER)
|
|
||||||
argPairs.forEach {
|
|
||||||
putExtra(it.first, it.second)
|
|
||||||
}
|
|
||||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun <T: Any> Intent.putExtra(s: String, second: T?) {
|
|
||||||
when(second){
|
|
||||||
is String -> putExtra(s,second)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
package com.appttude.h_mal.easycc.widget
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.appwidget.AppWidgetManager
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.widget.RemoteViews
|
||||||
|
import androidx.core.app.JobIntentService
|
||||||
|
import com.appttude.h_mal.easycc.R
|
||||||
|
import com.appttude.h_mal.easycc.helper.WidgetHelper
|
||||||
|
import com.appttude.h_mal.easycc.ui.main.MainActivity
|
||||||
|
import com.appttude.h_mal.easycc.utils.transformIntToArray
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.kodein.di.LateInitKodein
|
||||||
|
import org.kodein.di.generic.instance
|
||||||
|
|
||||||
|
class WidgetServiceIntent : JobIntentService() {
|
||||||
|
|
||||||
|
//DI with kodein to use in CurrencyAppWidgetKotlin
|
||||||
|
private val kodein = LateInitKodein()
|
||||||
|
private val repository: WidgetHelper by kodein.instance()
|
||||||
|
|
||||||
|
override fun onHandleWork(intent: Intent) {
|
||||||
|
kodein.baseKodein = this.kodein
|
||||||
|
|
||||||
|
val appWidgetManager = AppWidgetManager.getInstance(this)
|
||||||
|
val thisAppWidget = ComponentName(packageName, CurrencyAppWidgetKotlin::class.java.name)
|
||||||
|
val appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget)
|
||||||
|
|
||||||
|
for (appWidgetId in appWidgetIds) {
|
||||||
|
updateAppWidget(this, appWidgetManager, appWidgetId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateAppWidget(
|
||||||
|
context: Context,
|
||||||
|
appWidgetManager: AppWidgetManager,
|
||||||
|
appWidgetId: Int
|
||||||
|
) {
|
||||||
|
// Construct the RemoteViews object
|
||||||
|
val views = RemoteViews(context.packageName, R.layout.currency_app_widget)
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
val exchangeResponse = repository.getWidgetData()
|
||||||
|
|
||||||
|
exchangeResponse?.let {
|
||||||
|
val titleString = "${it.from}${it.to}"
|
||||||
|
views.setTextViewText(R.id.exchangeName, titleString)
|
||||||
|
views.setTextViewText(R.id.exchangeRate, it.rate.toString())
|
||||||
|
|
||||||
|
setUpdateIntent(context, appWidgetId).let { intent ->
|
||||||
|
//set the pending intent to the icon
|
||||||
|
views.setImageViewResource(R.id.refresh_icon, R.drawable.ic_refresh_white_24dp)
|
||||||
|
views.setOnClickPendingIntent(R.id.refresh_icon, intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
val clickIntentTemplate = clickingIntent(context)
|
||||||
|
|
||||||
|
val configPendingIntent =
|
||||||
|
PendingIntent.getActivity(
|
||||||
|
context, appWidgetId, clickIntentTemplate,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
views.setOnClickPendingIntent(R.id.widget_view, configPendingIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Instruct the widget manager to update the widget
|
||||||
|
appWidgetManager.updateAppWidget(appWidgetId, views)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setUpdateIntent(context: Context, appWidgetId: Int): PendingIntent? {
|
||||||
|
//Create update intent for refresh icon
|
||||||
|
val updateIntent = Intent(
|
||||||
|
context, CurrencyAppWidgetKotlin::class.java
|
||||||
|
).apply {
|
||||||
|
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||||
|
putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, transformIntToArray(appWidgetId))
|
||||||
|
}
|
||||||
|
//add previous intent to this pending intent
|
||||||
|
return PendingIntent.getBroadcast(
|
||||||
|
context,
|
||||||
|
appWidgetId,
|
||||||
|
updateIntent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clickingIntent(
|
||||||
|
context: Context
|
||||||
|
): Intent {
|
||||||
|
val pair = repository.repository.getConversionPair()
|
||||||
|
val s1 = pair.first
|
||||||
|
val s2 = pair.second
|
||||||
|
return Intent(context, MainActivity::class.java).apply {
|
||||||
|
action = Intent.ACTION_MAIN
|
||||||
|
addCategory(Intent.CATEGORY_LAUNCHER)
|
||||||
|
putExtra("parse_1", s1)
|
||||||
|
putExtra("parse_2", s2)
|
||||||
|
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Unique job ID for this service.
|
||||||
|
*/
|
||||||
|
private const val JOB_ID = 1000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method for enqueuing work in to this service.
|
||||||
|
*/
|
||||||
|
fun enqueueWork(context: Context, work: Intent) {
|
||||||
|
enqueueWork(context, WidgetServiceIntent::class.java, JOB_ID, work)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package com.appttude.h_mal.easycc;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Example local unit test, which will execute on the development machine (host).
|
|
||||||
*
|
|
||||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
|
||||||
*/
|
|
||||||
public class ExampleUnitTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void addition_isCorrect() throws Exception {
|
|
||||||
assertEquals(4, 2 + 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,6 @@ package com.appttude.h_mal.easycc.repository
|
|||||||
|
|
||||||
import com.appttude.h_mal.easycc.data.network.api.BackupCurrencyApi
|
import com.appttude.h_mal.easycc.data.network.api.BackupCurrencyApi
|
||||||
import com.appttude.h_mal.easycc.data.network.api.CurrencyApi
|
import com.appttude.h_mal.easycc.data.network.api.CurrencyApi
|
||||||
import com.appttude.h_mal.easycc.data.network.response.CurrencyResponse
|
|
||||||
import com.appttude.h_mal.easycc.data.network.response.ResponseObject
|
import com.appttude.h_mal.easycc.data.network.response.ResponseObject
|
||||||
import com.appttude.h_mal.easycc.data.prefs.PreferenceProvider
|
import com.appttude.h_mal.easycc.data.prefs.PreferenceProvider
|
||||||
import com.appttude.h_mal.easycc.data.repository.Repository
|
import com.appttude.h_mal.easycc.data.repository.Repository
|
||||||
@@ -29,8 +28,10 @@ class RepositoryNetworkTest{
|
|||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var api: CurrencyApi
|
lateinit var api: CurrencyApi
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var apiBackup: BackupCurrencyApi
|
lateinit var apiBackup: BackupCurrencyApi
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var prefs: PreferenceProvider
|
lateinit var prefs: PreferenceProvider
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.appttude.h_mal.easycc.repository
|
package com.appttude.h_mal.easycc.repository
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import com.appttude.h_mal.easycc.data.network.api.BackupCurrencyApi
|
import com.appttude.h_mal.easycc.data.network.api.BackupCurrencyApi
|
||||||
import com.appttude.h_mal.easycc.data.network.api.CurrencyApi
|
import com.appttude.h_mal.easycc.data.network.api.CurrencyApi
|
||||||
import com.appttude.h_mal.easycc.data.prefs.PreferenceProvider
|
import com.appttude.h_mal.easycc.data.prefs.PreferenceProvider
|
||||||
@@ -19,8 +18,10 @@ class RepositoryStorageTest {
|
|||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var api: CurrencyApi
|
lateinit var api: CurrencyApi
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var apiBackup: BackupCurrencyApi
|
lateinit var apiBackup: BackupCurrencyApi
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
lateinit var prefs: PreferenceProvider
|
lateinit var prefs: PreferenceProvider
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
|||||||
import com.appttude.h_mal.easycc.data.network.response.ResponseObject
|
import com.appttude.h_mal.easycc.data.network.response.ResponseObject
|
||||||
import com.appttude.h_mal.easycc.data.repository.Repository
|
import com.appttude.h_mal.easycc.data.repository.Repository
|
||||||
import com.appttude.h_mal.easycc.helper.CurrencyDataHelper
|
import com.appttude.h_mal.easycc.helper.CurrencyDataHelper
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import org.junit.Before
|
|
||||||
import com.appttude.h_mal.easycc.utils.observeOnce
|
import com.appttude.h_mal.easycc.utils.observeOnce
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.*
|
||||||
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
@@ -48,7 +48,8 @@ class MainViewModelTest {
|
|||||||
//WHEN
|
//WHEN
|
||||||
Mockito.`when`(bundle.getString("parse_1")).thenReturn(currencyOne)
|
Mockito.`when`(bundle.getString("parse_1")).thenReturn(currencyOne)
|
||||||
Mockito.`when`(bundle.getString("parse_2")).thenReturn(currencyTwo)
|
Mockito.`when`(bundle.getString("parse_2")).thenReturn(currencyTwo)
|
||||||
Mockito.`when`(repository.getDataFromApi(currencyOne, currencyTwo)).thenReturn(responseObject)
|
Mockito.`when`(repository.getDataFromApi(currencyOne, currencyTwo))
|
||||||
|
.thenReturn(responseObject)
|
||||||
|
|
||||||
//THEN
|
//THEN
|
||||||
viewModel.initiate(bundle)
|
viewModel.initiate(bundle)
|
||||||
@@ -71,7 +72,8 @@ class MainViewModelTest {
|
|||||||
|
|
||||||
//WHEN
|
//WHEN
|
||||||
Mockito.`when`(repository.getConversionPair()).thenReturn(pair)
|
Mockito.`when`(repository.getConversionPair()).thenReturn(pair)
|
||||||
Mockito.`when`(repository.getDataFromApi(currencyOne, currencyTwo)).thenReturn(responseObject)
|
Mockito.`when`(repository.getDataFromApi(currencyOne, currencyTwo))
|
||||||
|
.thenReturn(responseObject)
|
||||||
|
|
||||||
//THEN
|
//THEN
|
||||||
viewModel.initiate(null)
|
viewModel.initiate(null)
|
||||||
@@ -128,7 +130,6 @@ class MainViewModelTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setCurrencyName_validValues_successResponse() = runBlocking {
|
fun setCurrencyName_validValues_successResponse() = runBlocking {
|
||||||
//GIVEN
|
//GIVEN
|
||||||
@@ -139,7 +140,8 @@ class MainViewModelTest {
|
|||||||
val responseObject = mock(ResponseObject::class.java)
|
val responseObject = mock(ResponseObject::class.java)
|
||||||
|
|
||||||
//WHEN
|
//WHEN
|
||||||
Mockito.`when`(repository.getDataFromApi(currencyOne, currencyTwo)).thenReturn(responseObject)
|
Mockito.`when`(repository.getDataFromApi(currencyOne, currencyTwo))
|
||||||
|
.thenReturn(responseObject)
|
||||||
|
|
||||||
//THEN
|
//THEN
|
||||||
viewModel.setCurrencyName(tag, currencyOne)
|
viewModel.setCurrencyName(tag, currencyOne)
|
||||||
@@ -163,7 +165,8 @@ class MainViewModelTest {
|
|||||||
val responseObject = mock(ResponseObject::class.java)
|
val responseObject = mock(ResponseObject::class.java)
|
||||||
|
|
||||||
//WHEN
|
//WHEN
|
||||||
Mockito.`when`(repository.getDataFromApi(currencyOne, currencyTwo)).thenReturn(responseObject)
|
Mockito.`when`(repository.getDataFromApi(currencyOne, currencyTwo))
|
||||||
|
.thenReturn(responseObject)
|
||||||
|
|
||||||
//THEN
|
//THEN
|
||||||
viewModel.setCurrencyName(tag, currencyOne)
|
viewModel.setCurrencyName(tag, currencyOne)
|
||||||
@@ -185,7 +188,8 @@ class MainViewModelTest {
|
|||||||
val responseObject = mock(ResponseObject::class.java)
|
val responseObject = mock(ResponseObject::class.java)
|
||||||
|
|
||||||
//WHEN
|
//WHEN
|
||||||
Mockito.`when`(repository.getDataFromApi(currencyOne, currencyTwo)).thenReturn(responseObject)
|
Mockito.`when`(repository.getDataFromApi(currencyOne, currencyTwo))
|
||||||
|
.thenReturn(responseObject)
|
||||||
|
|
||||||
//THEN
|
//THEN
|
||||||
viewModel.setCurrencyName(tag, currencyOne)
|
viewModel.setCurrencyName(tag, currencyOne)
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package com.appttude.h_mal.easycc.ui.widget
|
|||||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||||
import com.appttude.h_mal.easycc.data.repository.Repository
|
import com.appttude.h_mal.easycc.data.repository.Repository
|
||||||
import com.appttude.h_mal.easycc.utils.observeOnce
|
import com.appttude.h_mal.easycc.utils.observeOnce
|
||||||
import org.junit.Before
|
|
||||||
import org.junit.Assert.*
|
import org.junit.Assert.*
|
||||||
|
import org.junit.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
@@ -14,6 +14,7 @@ import org.mockito.MockitoAnnotations
|
|||||||
|
|
||||||
private const val currencyOne = "AUD - Australian Dollar"
|
private const val currencyOne = "AUD - Australian Dollar"
|
||||||
private const val currencyTwo = "GBP - British Pound"
|
private const val currencyTwo = "GBP - British Pound"
|
||||||
|
|
||||||
class WidgetViewModelTest {
|
class WidgetViewModelTest {
|
||||||
|
|
||||||
// Run tasks synchronously
|
// Run tasks synchronously
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.appttude.h_mal.easycc
|
package com.appttude.h_mal.easycc.utils
|
||||||
|
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.appttude.h_mal.easycc.utils
|
package com.appttude.h_mal.easycc.utils
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import com.appttude.h_mal.easycc.OneTimeObserver
|
|
||||||
|
|
||||||
fun <T> LiveData<T>.observeOnce(onChangeHandler: (T) -> Unit) {
|
fun <T> LiveData<T>.observeOnce(onChangeHandler: (T) -> Unit) {
|
||||||
val observer = OneTimeObserver(handler = onChangeHandler)
|
val observer = OneTimeObserver(handler = onChangeHandler)
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.3.61'
|
ext.kotlin_version = '1.4.10'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.6.1'
|
classpath 'com.android.tools.build:gradle:4.0.2'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
|||||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
|||||||
#Thu Mar 05 18:27:33 UTC 2020
|
#Sat Jun 12 22:27:25 BST 2021
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
|
||||||
|
|||||||
Reference in New Issue
Block a user