- mid commit

Took 4 hours 2 minutes
This commit is contained in:
2023-05-12 16:26:15 +01:00
parent 243a20a9c4
commit 068bd2068e
19 changed files with 199 additions and 13 deletions

View File

@@ -121,6 +121,7 @@ dependencies {
androidTestImplementation "androidx.test.espresso.idling:idling-concurrent:$espressoVersion" androidTestImplementation "androidx.test.espresso.idling:idling-concurrent:$espressoVersion"
implementation "androidx.test.espresso:espresso-idling-resource:$espressoVersion" implementation "androidx.test.espresso:espresso-idling-resource:$espressoVersion"
androidTestImplementation "androidx.test:runner:$testRunnerVersion" androidTestImplementation "androidx.test:runner:$testRunnerVersion"
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
/ * Google play services */ / * Google play services */
implementation "com.google.android.gms:play-services-auth:20.4.1" implementation "com.google.android.gms:play-services-auth:20.4.1"
/ * Google firebase */ / * Google firebase */
@@ -156,4 +157,8 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.10.0' implementation 'com.squareup.okhttp3:okhttp:4.10.0'
/ * Kotlin Reflect */ / * Kotlin Reflect */
implementation "org.jetbrains.kotlin:kotlin-reflect:1.8.10" implementation "org.jetbrains.kotlin:kotlin-reflect:1.8.10"
/ * Retrofit2 */
def retrofit_version = "2.9.0"
androidTestImplementation "com.squareup.retrofit2:retrofit:$retrofit_version"
androidTestImplementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
} }

View File

@@ -7,4 +7,8 @@ const val deleteAccountFirebase =
"http://10.0.2.2:9099/identitytoolkit.googleapis.com/v1/accounts:delete?key=$apiKey" "http://10.0.2.2:9099/identitytoolkit.googleapis.com/v1/accounts:delete?key=$apiKey"
const val USER_PASSWORD = "LetMeIn123!" const val USER_PASSWORD = "LetMeIn123!"
const val DRIVER_EMAIL = "existing-driver@driver.com"
const val ADMIN_EMAIL = "admin@driver.com"
const val PASSWORD = "test123456"

View File

@@ -0,0 +1,56 @@
package h_mal.appttude.com.driver.firebase.api
import h_mal.appttude.com.driver.firebase.model.*
import okhttp3.OkHttpClient
import okhttp3.Request
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.PUT
import retrofit2.http.Query
interface FirebaseApi {
@PUT("v1/accounts:signUp")
suspend fun signUp(@Body request: SignUpRequest): Response<SignUpResponse>
@PUT("v1/accounts:signInWithPassword")
suspend fun signInWithPassword(@Body request: SignUpRequest): Response<SignUpResponse>
@PUT("v1/accounts:sendOobCode")
suspend fun sendOobCode(@Body request: Map<String, String>): Response<OobCodeResponse>
@PUT("v1/accounts:resetPassword")
suspend fun resetPassword(@Body request: ResetPasswordRequest): Response<ResetPasswordResponse>
// invoke method creating an invocation of the api call
companion object{
operator fun invoke() : FirebaseApi {
val host = "10.0.2.2"
val baseUrl = "http://$host:9099/identitytoolkit.googleapis.com/"
val okkHttpclient = OkHttpClient.Builder()
.addInterceptor {
val original = it.request()
val url = original.url.newBuilder()
.addQueryParameter("key", "apikeydfasdfasdfasdf")
.build()
val requestBuilder = original.newBuilder().url(url)
val request: Request = requestBuilder.build()
it.proceed(request)
}
.build()
// creation of retrofit class
return Retrofit.Builder()
.client(okkHttpclient)
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(FirebaseApi::class.java)
}
}
}

View File

@@ -0,0 +1,38 @@
package h_mal.appttude.com.driver.firebase.api
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import okhttp3.Interceptor
import java.io.IOException
class NetworkConnectionInterceptor(
context: Context
) : Interceptor {
private val applicationContext = context.applicationContext
override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
if (!isInternetAvailable()){
throw IOException("Make sure you have an active data connection")
}
return chain.proceed(chain.request())
}
private fun isInternetAvailable(): Boolean {
var result = false
val connectivityManager =
applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
connectivityManager?.let {
it.getNetworkCapabilities(connectivityManager.activeNetwork)?.apply {
result = when {
hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
else -> false
}
}
}
return result
}
}

View File

@@ -0,0 +1,9 @@
package h_mal.appttude.com.driver.firebase.model
data class OobCodeResponse(
val kind: String? = null,
val oobLink: String? = null,
val oobCode: String? = null,
val email: String? = null
)

View File

@@ -0,0 +1,10 @@
package h_mal.appttude.com.driver.firebase.model
data class ResetPasswordRequest(
val oldPassword: String? = null,
val tenantId: String? = null,
val newPassword: String? = null,
val oobCode: String? = null,
val email: String? = null
)

View File

@@ -0,0 +1,9 @@
package h_mal.appttude.com.driver.firebase.model
data class ResetPasswordResponse(
val requestType: String? = null,
val kind: String? = null,
val newEmail: String? = null,
val email: String? = null
)

View File

@@ -0,0 +1,7 @@
package h_mal.appttude.com.driver.firebase.model
data class SignUpRequest(
val password: String? = null,
val email: String? = null
)

View File

@@ -1,4 +1,4 @@
package h_mal.appttude.com.driver.firebase package h_mal.appttude.com.driver.firebase.model
data class SignUpResponse( data class SignUpResponse(
val expiresIn: String? = null, val expiresIn: String? = null,

View File

@@ -1,5 +1,8 @@
package h_mal.appttude.com.driver.robots package h_mal.appttude.com.driver.robots
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.contrib.DrawerActions
import androidx.test.espresso.matcher.ViewMatchers.withId
import h_mal.appttude.com.driver.BaseTestRobot import h_mal.appttude.com.driver.BaseTestRobot
import h_mal.appttude.com.driver.R import h_mal.appttude.com.driver.R
@@ -8,4 +11,20 @@ class HomeRobot : BaseTestRobot() {
fun checkTitleExists(title: String) = matchText(R.id.prova_title_tv, title) fun checkTitleExists(title: String) = matchText(R.id.prova_title_tv, title)
fun openDrawer() {
onView(withId(R.id.drawer_layout)).perform(DrawerActions.open())
}
fun closeDrawer() {
onView(withId(R.id.drawer_layout)).perform(DrawerActions.close())
}
fun updateProfile() {
openDrawer()
clickButton(R.id.nav_user_settings)
}
fun openDriverProfile() = clickButton(R.id.driver)
fun openVehicleProfile() = clickButton(R.id.car)
} }

View File

@@ -0,0 +1,17 @@
package h_mal.appttude.com.driver.robots
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.contrib.DrawerActions
import androidx.test.espresso.matcher.ViewMatchers.withId
import h_mal.appttude.com.driver.BaseTestRobot
import h_mal.appttude.com.driver.R
fun update(func: UpdateRobot.() -> Unit) = UpdateRobot().apply { func() }
class UpdateRobot : BaseTestRobot() {
fun updateEmail() = clickButton(R.id.update_email_button)
fun updatePassword() = clickButton(R.id.update_password_button)
fun updateProfile() = clickButton(R.id.update_profile_button)
fun deleteProfile() = clickButton(R.id.delete_profile)
}

View File

@@ -33,7 +33,10 @@ class UserAuthenticationActivityTest : FirebaseTest<LoginActivity>(LoginActivity
} }
home { home {
checkTitleExists(getResourceString(R.string.welcome_title)) checkTitleExists(getResourceString(R.string.welcome_title))
updateProfile()
} }
// TODO: update user details
} }
} }

View File

@@ -33,6 +33,7 @@ class MainActivity : DrawerActivity<MainViewModel, ActivityMainBinding>() {
setupDrawer(data) setupDrawer(data)
} }
} }
} }
private fun setupDrawer(user: FirebaseUser) { private fun setupDrawer(user: FirebaseUser) {

View File

@@ -1,6 +1,9 @@
package h_mal.appttude.com.driver.application package h_mal.appttude.com.driver.application
import android.app.Application import android.app.Application
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.storage.FirebaseStorage
import h_mal.appttude.com.driver.data.FirebaseAuthSource import h_mal.appttude.com.driver.data.FirebaseAuthSource
import h_mal.appttude.com.driver.data.FirebaseDatabaseSource import h_mal.appttude.com.driver.data.FirebaseDatabaseSource
import h_mal.appttude.com.driver.data.FirebaseStorageSource import h_mal.appttude.com.driver.data.FirebaseStorageSource
@@ -15,6 +18,16 @@ import org.kodein.di.generic.singleton
class DriverApplication : Application(), KodeinAware { class DriverApplication : Application(), KodeinAware {
override fun onCreate() {
super.onCreate()
val localHost = "10.0.2.2"
FirebaseAuth.getInstance().useEmulator(localHost, 9099)
FirebaseDatabase.getInstance().useEmulator(localHost, 9000)
FirebaseStorage.getInstance().useEmulator(localHost, 9199)
}
// Kodein aware to initialise the classes used for DI // Kodein aware to initialise the classes used for DI
override val kodein = Kodein.lazy { override val kodein = Kodein.lazy {
import(androidXModule(this@DriverApplication)) import(androidXModule(this@DriverApplication))

View File

@@ -45,8 +45,6 @@ abstract class BaseActivity<V : BaseViewModel, VB : ViewBinding> : AppCompatActi
{ defaultViewModelCreationExtras } { defaultViewModelCreationExtras }
) )
private var loading: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
configureObserver() configureObserver()
@@ -95,7 +93,6 @@ abstract class BaseActivity<V : BaseViewModel, VB : ViewBinding> : AppCompatActi
*/ */
open fun onStarted() { open fun onStarted() {
loadingView.fadeIn() loadingView.fadeIn()
loading = true
mIdlingResource?.setIdleState(false) mIdlingResource?.setIdleState(false)
} }
@@ -104,7 +101,6 @@ abstract class BaseActivity<V : BaseViewModel, VB : ViewBinding> : AppCompatActi
*/ */
open fun onSuccess(data: Any?) { open fun onSuccess(data: Any?) {
loadingView.fadeOut() loadingView.fadeOut()
loading = false
mIdlingResource?.setIdleState(true) mIdlingResource?.setIdleState(true)
} }
@@ -114,7 +110,6 @@ abstract class BaseActivity<V : BaseViewModel, VB : ViewBinding> : AppCompatActi
open fun onFailure(error: String?) { open fun onFailure(error: String?) {
error?.let { displayToast(it) } error?.let { displayToast(it) }
loadingView.fadeOut() loadingView.fadeOut()
loading = false
mIdlingResource?.setIdleState(true) mIdlingResource?.setIdleState(true)
} }
@@ -140,7 +135,8 @@ abstract class BaseActivity<V : BaseViewModel, VB : ViewBinding> : AppCompatActi
override fun onBackPressed() { override fun onBackPressed() {
if (!loading) super.onBackPressed() loadingView.hide()
super.onBackPressed()
} }
/** /**

View File

@@ -48,7 +48,6 @@ abstract class DrawerActivity<V : BaseViewModel, VB : ViewBinding> : BaseActivit
appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout) appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
navView.setupWithNavController(navController) navView.setupWithNavController(navController)
setupActionBarWithNavController(navController, appBarConfiguration) setupActionBarWithNavController(navController, appBarConfiguration)
} }
override fun onSupportNavigateUp(): Boolean { override fun onSupportNavigateUp(): Boolean {

View File

@@ -44,13 +44,13 @@
android:text="@string/update_password" /> android:text="@string/update_password" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
style="@style/TextButton.WithIcon"
android:id="@+id/update_profile_button" android:id="@+id/update_profile_button"
android:layout_marginBottom="12dp" style="@style/TextButton.WithIcon"
android:layout_marginBottom="8dp"
android:text="@string/update_profile"
app:layout_constraintBottom_toTopOf="@id/delete_profile" app:layout_constraintBottom_toTopOf="@id/delete_profile"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent" />
android:text="@string/update_profile" />
<com.google.android.material.button.MaterialButton <com.google.android.material.button.MaterialButton
style="@style/TextButton.WithIcon" style="@style/TextButton.WithIcon"