Firebase emulator testing (#9)

- Firebase emulator added
 - Update to Espresso tests
 - Updated gradle dependencies for espresso
 - Updated config.yml
 - Updated android gradle version
This commit is contained in:
2023-03-17 18:37:20 +00:00
committed by GitHub
parent 88604e6970
commit 7f4060f1c2
53 changed files with 491 additions and 183 deletions

View File

@@ -6,11 +6,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ListView
import androidx.fragment.app.Fragment
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.DatabaseReference
import com.google.firebase.database.ValueEventListener
import h_mal.appttude.com.R
class ArchiveFragment : Fragment() {

View File

@@ -1,19 +1,13 @@
package h_mal.appttude.com.Archive
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
//import h_mal.appttude.com.Global.FirebaseClass
//import h_mal.appttude.com.Global.ImageSwiperClass
//import h_mal.appttude.com.Objects.ArchiveObject
import h_mal.appttude.com.model.InsuranceObject
import h_mal.appttude.com.R
import h_mal.appttude.com.model.VehicleProfileObject
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView
import h_mal.appttude.com.utils.DateUtils.convertDateStringDatePattern
import java.text.ParseException

View File

@@ -4,7 +4,6 @@ import android.app.Application
import h_mal.appttude.com.data.FirebaseAuthSource
import h_mal.appttude.com.data.FirebaseDatabaseSource
import h_mal.appttude.com.data.FirebaseStorageSource
import h_mal.appttude.com.espresso.IdlingResourceClass
import org.kodein.di.Kodein
import org.kodein.di.KodeinAware
import org.kodein.di.android.x.androidXModule

View File

@@ -4,27 +4,25 @@ import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.ViewGroup.LayoutParams
import android.view.ViewGroup.LayoutParams.*
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import androidx.activity.viewModels
import androidx.annotation.VisibleForTesting
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import h_mal.appttude.com.application.ApplicationViewModelFactory
import androidx.test.espresso.IdlingResource
import h_mal.appttude.com.R
import h_mal.appttude.com.application.ApplicationViewModelFactory
import h_mal.appttude.com.data.ViewState
import h_mal.appttude.com.espresso.IdlingResourceClass
import h_mal.appttude.com.utils.displayToast
import h_mal.appttude.com.utils.hide
import h_mal.appttude.com.utils.show
import h_mal.appttude.com.utils.triggerAnimation
import h_mal.appttude.com.utils.*
import org.kodein.di.KodeinAware
import org.kodein.di.android.kodein
import org.kodein.di.generic.instance
abstract class BaseActivity<V : BaseViewModel> : AppCompatActivity(), KodeinAware {
// The Idling Resource which will be null in production.
private var mIdlingResource: BasicIdlingResource? = null
private lateinit var loadingView: View
abstract fun getViewModel(): V?
@@ -32,7 +30,6 @@ abstract class BaseActivity<V : BaseViewModel> : AppCompatActivity(), KodeinAwar
override val kodein by kodein()
val factory by instance<ApplicationViewModelFactory>()
private val idlingResource by instance<IdlingResourceClass>()
inline fun <reified VM : ViewModel> createLazyViewModel(): Lazy<VM> = viewModels { factory }
inline fun <reified VM : ViewModel> createViewModel(): VM =
@@ -54,6 +51,7 @@ abstract class BaseActivity<V : BaseViewModel> : AppCompatActivity(), KodeinAwar
* loading
*/
private fun instantiateLoadingView(){
// loadingView = View.inflate(this, R.layout.progress_layout, null)
loadingView = layoutInflater.inflate(R.layout.progress_layout, null)
loadingView.setOnClickListener(null)
addContentView(loadingView, LayoutParams(MATCH_PARENT, MATCH_PARENT))
@@ -76,7 +74,7 @@ abstract class BaseActivity<V : BaseViewModel> : AppCompatActivity(), KodeinAwar
open fun onStarted() {
loadingView.fadeIn()
loading = true
IdlingResourceClass.increment()
mIdlingResource?.setIdleState(false)
}
/**
@@ -85,7 +83,7 @@ abstract class BaseActivity<V : BaseViewModel> : AppCompatActivity(), KodeinAwar
open fun onSuccess(data: Any?) {
loadingView.fadeOut()
loading = false
IdlingResourceClass.decrement()
mIdlingResource?.setIdleState(true)
}
/**
@@ -95,17 +93,17 @@ abstract class BaseActivity<V : BaseViewModel> : AppCompatActivity(), KodeinAwar
error?.let { displayToast(it) }
loadingView.fadeOut()
loading = false
IdlingResourceClass.decrement()
mIdlingResource?.setIdleState(true)
}
private fun configureObserver() {
getViewModel()?.uiState?.observe(this, Observer {
getViewModel()?.uiState?.observe(this) {
when (it) {
is ViewState.HasStarted -> onStarted()
is ViewState.HasData<*> -> onSuccess(it.data.getContentIfNotHandled())
is ViewState.HasError -> onFailure(it.error.getContentIfNotHandled())
}
})
}
}
private fun View.fadeIn() = apply {
@@ -123,4 +121,14 @@ abstract class BaseActivity<V : BaseViewModel> : AppCompatActivity(), KodeinAwar
if (!loading) super.onBackPressed()
}
/**
* Only called from test, creates and returns a new [BasicIdlingResource].
*/
@VisibleForTesting
fun getIdlingResource(): IdlingResource? {
if (mIdlingResource == null) {
mIdlingResource = BasicIdlingResource()
}
return mIdlingResource
}
}

View File

@@ -1,10 +1,12 @@
package h_mal.appttude.com.base
import android.net.Uri
import androidx.lifecycle.MutableLiveData
import com.google.firebase.database.DatabaseReference
import com.google.firebase.storage.StorageReference
import h_mal.appttude.com.data.*
import h_mal.appttude.com.data.FirebaseAuthentication
import h_mal.appttude.com.data.FirebaseCompletion
import h_mal.appttude.com.data.FirebaseDatabaseSource
import h_mal.appttude.com.data.FirebaseStorageSource
import h_mal.appttude.com.utils.Coroutines.io
import h_mal.appttude.com.utils.DateUtils.getDateTimeStamp
import h_mal.appttude.com.utils.getDataFromDatabaseRef

View File

@@ -28,7 +28,7 @@ class FirebaseAuthSource: FirebaseAuthentication{
): Task<Void> {
val profileUpdates = UserProfileChangeRequest.Builder().apply {
name?.let { setDisplayName(it) }
profilePic?.let { setPhotoUri(it) }
profilePic?.let { photoUri = it }
}.build()
return getCurrentUser().updateProfile(profileUpdates)
}

View File

@@ -2,7 +2,6 @@ package h_mal.appttude.com.data
import androidx.lifecycle.LiveData
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
class FirebaseLiveData(
private val firebaseAuth: FirebaseAuth

View File

@@ -1,7 +1,6 @@
package h_mal.appttude.com.data
import com.google.firebase.auth.FirebaseUser
import h_mal.appttude.com.utils.Event
sealed class UserAuthState {
object LoggedOut : UserAuthState()

View File

@@ -5,16 +5,13 @@ import android.app.AlertDialog
import android.app.DatePickerDialog
import android.app.DatePickerDialog.OnDateSetListener
import android.icu.util.Calendar
import android.os.Build
import android.view.View
import android.widget.EditText
import androidx.annotation.RequiresApi
import h_mal.appttude.com.R
import h_mal.appttude.com.utils.DateUtils
private const val DATE_FORMAT = "dd/MM/yyyy"
@RequiresApi(api = Build.VERSION_CODES.N)
@Suppress("DEPRECATION")
class DateDialog(
private val editText: EditText,
dateSelected:(String?) -> Unit

View File

@@ -1,24 +0,0 @@
package h_mal.appttude.com.espresso
import androidx.test.espresso.idling.CountingIdlingResource
object IdlingResourceClass {
private val CLASS_NAME = "IdlingResourceClass"
private const val RESOURCE = "GLOBAL"
@JvmField val countingIdlingResource = CountingIdlingResource(RESOURCE)
fun increment() {
if (!countingIdlingResource.isIdleNow) {
countingIdlingResource.increment()
}
}
fun decrement() {
if (countingIdlingResource.isIdleNow) {
countingIdlingResource.decrement()
}
}
}

View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

View File

@@ -5,9 +5,9 @@ import android.content.Intent
import android.os.Bundle
import com.google.firebase.auth.AuthResult
import com.google.firebase.auth.FirebaseUser
import h_mal.appttude.com.ui.MainActivity
import h_mal.appttude.com.R
import h_mal.appttude.com.base.BaseActivity
import h_mal.appttude.com.ui.MainActivity
import h_mal.appttude.com.viewmodels.UserViewModel

View File

@@ -0,0 +1,32 @@
package h_mal.appttude.com.utils
import androidx.test.espresso.IdlingResource
import androidx.test.espresso.IdlingResource.ResourceCallback
import java.util.concurrent.atomic.AtomicBoolean
class BasicIdlingResource : IdlingResource {
private lateinit var mCallback: ResourceCallback
// Idleness is controlled with this boolean.
private val mIsIdleNow: AtomicBoolean = AtomicBoolean(true)
override fun getName(): String = this.javaClass.name
override fun isIdleNow(): Boolean = mIsIdleNow.get()
override fun registerIdleTransitionCallback(callback: ResourceCallback) {
mCallback = callback
}
/**
* Sets the new idle state, if isIdleNow is true, it pings the [ResourceCallback].
* @param isIdleNow false if there are pending operations, true if idle.
*/
fun setIdleState(isIdleNow: Boolean) {
mIsIdleNow.set(isIdleNow)
if (isIdleNow) {
mCallback.onTransitionToIdle()
}
}
}

View File

@@ -3,8 +3,7 @@ package h_mal.appttude.com.utils
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.PackageManager.*
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.net.Uri
import android.provider.Settings
import androidx.appcompat.app.AlertDialog

View File

@@ -1,5 +1,6 @@
package h_mal.appttude.com.utils
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
@@ -20,13 +21,9 @@ import androidx.annotation.DrawableRes
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.Fragment
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.squareup.picasso.Picasso
import com.squareup.picasso.Target
import h_mal.appttude.com.R
import com.bumptech.glide.request.target.Target as GlideRequestTarget
fun View.show() {
this.visibility = View.VISIBLE
@@ -54,6 +51,7 @@ fun EditText.setEnterPressedListener(action: () -> Unit) {
})
}
@SuppressLint("CheckResult")
fun ImageView.setGlideImage(
url: String?,
@DrawableRes placeholderRes: Int = R.drawable.choice_img_round
@@ -70,6 +68,7 @@ fun ImageView.setGlideImage(
.into(this)
}
@SuppressLint("CheckResult")
fun ImageView.setGlideImage(
url: Uri?,
@DrawableRes placeholderRes: Int = R.drawable.choice_img_round

View File

@@ -3,11 +3,11 @@ package h_mal.appttude.com.viewmodels
import android.net.Uri
import com.google.firebase.database.DatabaseReference
import com.google.firebase.storage.StorageReference
import h_mal.appttude.com.model.InsuranceObject
import h_mal.appttude.com.base.DataSubmissionBaseViewModel
import h_mal.appttude.com.data.FirebaseAuthentication
import h_mal.appttude.com.data.FirebaseDatabaseSource
import h_mal.appttude.com.data.FirebaseStorageSource
import h_mal.appttude.com.model.InsuranceObject
import h_mal.appttude.com.utils.Coroutines.io
class InsuranceViewModel (
@@ -17,7 +17,7 @@ class InsuranceViewModel (
) : DataSubmissionBaseViewModel<InsuranceObject>(auth, database, storage) {
override val databaseRef: DatabaseReference = database.getInsuranceDetailsRef(uid)
override val storageRef: StorageReference? = storage.insuranceStorageRef(uid)
override val storageRef: StorageReference = storage.insuranceStorageRef(uid)
override val objectName: String = "insurance"
override fun getDataFromDatabase() = getDataClass<InsuranceObject>()

View File

@@ -3,11 +3,11 @@ package h_mal.appttude.com.viewmodels
import android.net.Uri
import com.google.firebase.database.DatabaseReference
import com.google.firebase.storage.StorageReference
import h_mal.appttude.com.model.LogbookObject
import h_mal.appttude.com.base.DataSubmissionBaseViewModel
import h_mal.appttude.com.data.FirebaseAuthentication
import h_mal.appttude.com.data.FirebaseDatabaseSource
import h_mal.appttude.com.data.FirebaseStorageSource
import h_mal.appttude.com.model.LogbookObject
import h_mal.appttude.com.utils.Coroutines.io
class LogbookViewModel (

View File

@@ -3,11 +3,11 @@ package h_mal.appttude.com.viewmodels
import android.net.Uri
import com.google.firebase.database.DatabaseReference
import com.google.firebase.storage.StorageReference
import h_mal.appttude.com.model.PrivateHireVehicleObject
import h_mal.appttude.com.base.DataSubmissionBaseViewModel
import h_mal.appttude.com.data.FirebaseAuthentication
import h_mal.appttude.com.data.FirebaseDatabaseSource
import h_mal.appttude.com.data.FirebaseStorageSource
import h_mal.appttude.com.model.PrivateHireVehicleObject
import h_mal.appttude.com.utils.Coroutines.io
class PrivateHireVehicleViewModel (
@@ -17,7 +17,7 @@ class PrivateHireVehicleViewModel (
) : DataSubmissionBaseViewModel<PrivateHireVehicleObject>(auth, database, storage) {
override val databaseRef: DatabaseReference = database.getPrivateHireVehicleRef(uid)
override val storageRef: StorageReference? = storage.privateHireVehicleStorageRef(uid)
override val storageRef: StorageReference = storage.privateHireVehicleStorageRef(uid)
override val objectName: String = "private hire vehicle license"
override fun getDataFromDatabase() = getDataClass<PrivateHireVehicleObject>()

View File

@@ -7,8 +7,6 @@ import h_mal.appttude.com.data.FirebaseCompletion
import h_mal.appttude.com.data.FirebaseStorageSource
import h_mal.appttude.com.utils.Coroutines.io
import kotlinx.coroutines.tasks.await
import java.io.IOException
import java.lang.Exception
class UpdateUserViewModel(
private val auth: FirebaseAuthentication,

View File

@@ -7,8 +7,6 @@ import h_mal.appttude.com.data.FirebaseCompletion
import h_mal.appttude.com.utils.Coroutines.io
import kotlinx.coroutines.delay
import kotlinx.coroutines.tasks.await
import java.io.IOException
import java.lang.Exception
class UserViewModel(
val auth: FirebaseAuthentication

View File

@@ -1 +0,0 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"></resources>