mirror of
https://github.com/hmalik144/Driver.git
synced 2025-12-10 02:45:20 +00:00
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:
@@ -37,17 +37,43 @@ jobs:
|
||||
# The next step will run the unit tests
|
||||
- android/run-tests:
|
||||
test-command: ./gradlew testDriverDebugUnitTest --continue
|
||||
|
||||
# Then start the emulator and run the Instrumentation tests!
|
||||
# - android/start-emulator-and-run-tests:
|
||||
# test-command: ./gradlew connectedDebugAndroidTest
|
||||
# system-image: system-images;android-25;google_apis;x86
|
||||
|
||||
# Install Firebase tools needed for firebase emulator
|
||||
- run:
|
||||
name: Install firebase tools
|
||||
command: |
|
||||
curl -sL firebase.tools | bash
|
||||
# Then start firebase emulator in the background
|
||||
- run:
|
||||
name: Start firebase emulator
|
||||
command: |
|
||||
firebase emulators:start
|
||||
background: true
|
||||
# Then start the emulator and run the Instrumentation tests!
|
||||
- android/start-emulator-and-run-tests:
|
||||
post-emulator-launch-assemble-command: ./gradlew assembleDriverDebugAndroidTest
|
||||
test-command: ./gradlew connectedDriverDebugAndroidTest
|
||||
system-image: system-images;android-25;google_apis;x86
|
||||
# And finally run the release build
|
||||
# - run:
|
||||
# name: Assemble release build
|
||||
# command: |
|
||||
# ./gradlew assembleDriverRelease
|
||||
# Then publish the artifacts of the Instrumentation tests!
|
||||
- store_artifacts:
|
||||
path: app/build/reports/androidTests/connected
|
||||
destination: reports
|
||||
# Then publish the artifacts of the Firebase emulator logs!
|
||||
- run:
|
||||
name: save firebase emulator logs
|
||||
command: |
|
||||
mkdir -p tmp/firebase_logs
|
||||
cp *.log tmp/firebase_logs
|
||||
- store_artifacts:
|
||||
path: tmp/firebase_logs
|
||||
destination: logs
|
||||
# Then publish the results of the Instrumentation tests!
|
||||
- store_test_results:
|
||||
path: app/build/outputs/androidTest-results/connected
|
||||
|
||||
# Invoke jobs via workflows
|
||||
# See: https://circleci.com/docs/2.0/configuration-reference/#workflows
|
||||
|
||||
5
.firebaserc
Normal file
5
.firebaserc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"projects": {
|
||||
"default": "driver-8f4a1"
|
||||
}
|
||||
}
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -13,3 +13,5 @@
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
*.log
|
||||
local
|
||||
|
||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@@ -39,7 +39,7 @@
|
||||
</value>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17_PREVIEW" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
||||
@@ -27,6 +27,20 @@ android {
|
||||
versionCode 6
|
||||
versionName "1.6"
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
|
||||
boolean state = project.rootProject.file('local.properties').canRead()
|
||||
buildConfigField "boolean", "LocalState", "$state"
|
||||
}
|
||||
|
||||
android {
|
||||
sourceSets {
|
||||
test {
|
||||
resources.srcDirs += ['src/test/resources']
|
||||
}
|
||||
androidTest {
|
||||
resources.srcDirs += ['src/androidTest/resources']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
@@ -94,42 +108,47 @@ dependencies {
|
||||
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
|
||||
implementation 'androidx.viewpager:viewpager:1.0.0'
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
androidTestImplementation "androidx.test.ext:junit:1.1.5"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:3.5.1"
|
||||
androidTestImplementation "androidx.test:rules:1.5.0"
|
||||
implementation 'androidx.test.espresso:espresso-idling-resource:3.5.1'
|
||||
|
||||
implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
// Google play services
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
/ * Android Espresso */
|
||||
def testJunitVersion = "1.1.5"
|
||||
def testRunnerVersion = "1.5.2"
|
||||
def espressoVersion = "3.5.1"
|
||||
androidTestImplementation "androidx.test.ext:junit:$testJunitVersion"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
|
||||
androidTestImplementation "androidx.test.espresso.idling:idling-concurrent:$espressoVersion"
|
||||
implementation "androidx.test.espresso:espresso-idling-resource:$espressoVersion"
|
||||
androidTestImplementation "androidx.test:runner:$testRunnerVersion"
|
||||
/ * Google play services */
|
||||
implementation "com.google.android.gms:play-services-auth:20.4.1"
|
||||
// Google firebase
|
||||
def firebaseVer = "20.1.0"
|
||||
implementation "com.google.firebase:firebase-core:$firebaseVer"
|
||||
implementation "com.google.firebase:firebase-auth:21.0.0"
|
||||
implementation "com.google.firebase:firebase-storage:$firebaseVer"
|
||||
implementation "com.google.firebase:firebase-database:$firebaseVer"
|
||||
// Photoviewer
|
||||
/ * Google firebase */
|
||||
def firebaseCore = "21.1.1"
|
||||
def firebaseAuth = "20.0.0"
|
||||
def firebaseStorage = "20.0.0"
|
||||
def firebaseDatabase = "19.4.0"
|
||||
implementation "com.google.firebase:firebase-core:$firebaseCore"
|
||||
implementation "com.google.firebase:firebase-auth:$firebaseAuth"
|
||||
implementation "com.google.firebase:firebase-storage:$firebaseStorage"
|
||||
implementation "com.google.firebase:firebase-database:$firebaseDatabase"
|
||||
/ * Photoviewer */
|
||||
implementation "com.github.chrisbanes:PhotoView:2.1.0"
|
||||
/* Picasso photo loader */
|
||||
/ * Picasso photo loader */
|
||||
implementation "com.squareup.picasso:picasso:2.71828"
|
||||
/* Gson */
|
||||
/ * Gson */
|
||||
implementation "com.google.code.gson:gson:2.8.9"
|
||||
/* coroutines support for firebase operations */
|
||||
/ * coroutines support for firebase operations */
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.1"
|
||||
|
||||
// Circle Image View
|
||||
/ * Circle Image View */
|
||||
implementation "com.mikhaellopez:circularimageview:4.2.0"
|
||||
|
||||
//Kodein Dependency Injection
|
||||
/ * Kodein Dependency Injection */
|
||||
def kodein_version = "6.2.1"
|
||||
implementation "org.kodein.di:kodein-di-generic-jvm:$kodein_version"
|
||||
implementation "org.kodein.di:kodein-di-framework-android-x:$kodein_version"
|
||||
|
||||
/* Image Carousal */
|
||||
/ * Image Carousal */
|
||||
implementation 'com.synnapps:carouselview:0.1.5'
|
||||
|
||||
/ * Glide */
|
||||
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
||||
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
|
||||
/ * OKHttp */
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
|
||||
}
|
||||
|
||||
@@ -6,15 +6,15 @@ import androidx.test.espresso.Espresso.onData
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.ViewInteraction
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import androidx.test.espresso.assertion.ViewAssertions
|
||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import org.hamcrest.CoreMatchers.*
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.CoreMatchers.anything
|
||||
|
||||
open class BaseTestRobot {
|
||||
|
||||
fun fillEditText(resId: Int, text: String): ViewInteraction =
|
||||
fun fillEditText(resId: Int, text: String?): ViewInteraction =
|
||||
onView(withId(resId)).perform(ViewActions.replaceText(text), ViewActions.closeSoftKeyboard())
|
||||
|
||||
fun clickButton(resId: Int): ViewInteraction = onView((withId(resId))).perform(ViewActions.click())
|
||||
@@ -22,7 +22,7 @@ open class BaseTestRobot {
|
||||
fun textView(resId: Int): ViewInteraction = onView(withId(resId))
|
||||
|
||||
fun matchText(viewInteraction: ViewInteraction, text: String): ViewInteraction = viewInteraction
|
||||
.check(ViewAssertions.matches(ViewMatchers.withText(text)))
|
||||
.check(matches(ViewMatchers.withText(text)))
|
||||
|
||||
fun matchText(resId: Int, text: String): ViewInteraction = matchText(textView(resId), text)
|
||||
|
||||
|
||||
@@ -1,38 +1,60 @@
|
||||
package h_mal.appttude.com
|
||||
|
||||
import android.view.View
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.test.core.app.ActivityScenario
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.IdlingRegistry
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import h_mal.appttude.com.espresso.IdlingResourceClass
|
||||
import org.junit.AfterClass
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Ignore
|
||||
import org.junit.Rule
|
||||
import androidx.test.espresso.IdlingResource
|
||||
import androidx.test.espresso.UiController
|
||||
import androidx.test.espresso.ViewAction
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isRoot
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import h_mal.appttude.com.base.BaseActivity
|
||||
import org.hamcrest.Matcher
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
|
||||
abstract class BaseUiTest<T : AppCompatActivity> {
|
||||
|
||||
@Ignore
|
||||
abstract fun getApplicationClass(): Class<T>
|
||||
open class BaseUiTest<T : BaseActivity<*>>(
|
||||
private val activity: Class<T>
|
||||
) {
|
||||
|
||||
@get:Rule
|
||||
var mActivityTestRule = ActivityTestRule(getApplicationClass())
|
||||
private lateinit var mActivityScenarioRule: ActivityScenario<T>
|
||||
private var mIdlingResource: IdlingResource? = null
|
||||
|
||||
companion object {
|
||||
@BeforeClass
|
||||
@JvmStatic
|
||||
fun setUp() {
|
||||
IdlingRegistry.getInstance().register(IdlingResourceClass.countingIdlingResource)
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
@JvmStatic
|
||||
fun tearDown() {
|
||||
IdlingRegistry.getInstance().unregister(IdlingResourceClass.countingIdlingResource)
|
||||
@Before
|
||||
fun setup() {
|
||||
beforeLaunch()
|
||||
mActivityScenarioRule = ActivityScenario.launch(activity)
|
||||
mActivityScenarioRule.onActivity {
|
||||
mIdlingResource = it.getIdlingResource()!!
|
||||
IdlingRegistry.getInstance().register(mIdlingResource)
|
||||
}
|
||||
}
|
||||
|
||||
fun getResourceString(@StringRes stringRes: Int): String {
|
||||
return mActivityTestRule.activity.getString(stringRes)
|
||||
@After
|
||||
fun tearDown() {
|
||||
mIdlingResource?.let {
|
||||
IdlingRegistry.getInstance().unregister(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun getResourceString(@StringRes stringRes: Int): String {
|
||||
return InstrumentationRegistry.getInstrumentation().targetContext.resources.getString(
|
||||
stringRes
|
||||
)
|
||||
}
|
||||
|
||||
fun waitFor(delay: Long) {
|
||||
onView(isRoot()).perform(object : ViewAction {
|
||||
override fun getConstraints(): Matcher<View> = isRoot()
|
||||
override fun getDescription(): String? = "wait for $delay milliseconds"
|
||||
override fun perform(uiController: UiController, v: View?) {
|
||||
uiController.loopMainThreadForAtLeast(delay)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
open fun beforeLaunch() {}
|
||||
}
|
||||
9
app/src/androidTest/java/h_mal/appttude/com/Constants.kt
Normal file
9
app/src/androidTest/java/h_mal/appttude/com/Constants.kt
Normal file
@@ -0,0 +1,9 @@
|
||||
package h_mal.appttude.com
|
||||
|
||||
|
||||
private const val apiKey = "test_key"
|
||||
const val signUpFirebase = "http://identitytoolkit.googleapis.com/v1/accounts:signUp?key=$apiKey"
|
||||
const val deleteAccountFirebase = "http://10.0.2.2:9099/identitytoolkit.googleapis.com/v1/accounts:delete?key=$apiKey"
|
||||
|
||||
|
||||
const val USER_PASSWORD = "LetMeIn123!"
|
||||
87
app/src/androidTest/java/h_mal/appttude/com/FirebaseTest.kt
Normal file
87
app/src/androidTest/java/h_mal/appttude/com/FirebaseTest.kt
Normal file
@@ -0,0 +1,87 @@
|
||||
package h_mal.appttude.com
|
||||
|
||||
import com.google.firebase.auth.FirebaseAuth
|
||||
import com.google.firebase.database.FirebaseDatabase
|
||||
import com.google.firebase.storage.FirebaseStorage
|
||||
import h_mal.appttude.com.base.BaseActivity
|
||||
import h_mal.appttude.com.data.FirebaseAuthSource
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.tasks.await
|
||||
import org.junit.After
|
||||
import org.junit.BeforeClass
|
||||
|
||||
open class FirebaseTest<T : BaseActivity<*>>(
|
||||
activity: Class<T>,
|
||||
private val registered: Boolean = false,
|
||||
private val signedIn: Boolean = false
|
||||
) : BaseUiTest<T>(activity) {
|
||||
|
||||
private val firebaseAuthSource by lazy { FirebaseAuthSource() }
|
||||
|
||||
private var email: String? = null
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Setup firebase emulators before all tests
|
||||
*/
|
||||
@JvmStatic
|
||||
@BeforeClass
|
||||
fun setupFirebase() {
|
||||
val localHost = "10.0.2.2"
|
||||
|
||||
FirebaseAuth.getInstance().useEmulator(localHost, 9099)
|
||||
FirebaseDatabase.getInstance().useEmulator(localHost, 9000)
|
||||
FirebaseStorage.getInstance().useEmulator(localHost, 9199)
|
||||
}
|
||||
}
|
||||
|
||||
override fun beforeLaunch() {
|
||||
if (registered) {
|
||||
runBlocking {
|
||||
setupUser()
|
||||
}
|
||||
if (!signedIn) firebaseAuthSource.logOut()
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDownFirebase() = runBlocking {
|
||||
removeUser()
|
||||
firebaseAuthSource.logOut()
|
||||
}
|
||||
|
||||
suspend fun setupUser(
|
||||
signInEmail: String = generateEmailAddress(),
|
||||
password: String = USER_PASSWORD
|
||||
) {
|
||||
email = signInEmail
|
||||
firebaseAuthSource.registerUser(signInEmail, password).await().user
|
||||
}
|
||||
|
||||
// remove the user we created for testing
|
||||
suspend fun removeUser() {
|
||||
try {
|
||||
getEmail()?.let {
|
||||
if (firebaseAuthSource.getUser() == null) firebaseAuthSource.signIn(email = it, password = USER_PASSWORD).await()
|
||||
firebaseAuthSource.reauthenticate(it, USER_PASSWORD).await()
|
||||
firebaseAuthSource.deleteProfile().await()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun generateEmailAddress(): String {
|
||||
val suffix = (1000..50000).random()
|
||||
email ="test-${suffix}@test-account.com"
|
||||
return email!!
|
||||
}
|
||||
|
||||
fun getEmail(): String? {
|
||||
firebaseAuthSource.getUser()?.email?.let {
|
||||
return it
|
||||
}
|
||||
return email
|
||||
}
|
||||
}
|
||||
62
app/src/androidTest/java/h_mal/appttude/com/WebUtils.kt
Normal file
62
app/src/androidTest/java/h_mal/appttude/com/WebUtils.kt
Normal file
@@ -0,0 +1,62 @@
|
||||
package h_mal.appttude.com
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import okhttp3.*
|
||||
import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import java.io.IOException
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
|
||||
class WebUtils {
|
||||
private val okHttpClient by lazy { OkHttpClient() }
|
||||
|
||||
suspend fun <T : Any> post(url: String, body: String): T? {
|
||||
val requestBody = body.toRequestBody()
|
||||
val request = Request.Builder()
|
||||
.post(requestBody)
|
||||
.url(url)
|
||||
.build()
|
||||
|
||||
return okHttpClient.newCall(request).await()
|
||||
}
|
||||
|
||||
suspend fun get(url: String): String? {
|
||||
val request: Request = Request.Builder()
|
||||
.url(url)
|
||||
.build()
|
||||
return okHttpClient.newCall(request).await()
|
||||
}
|
||||
|
||||
private suspend fun <T> Call.await(): T? {
|
||||
val objectMapper = Gson()
|
||||
val typeToken: TypeToken<T> = object : TypeToken<T>() {}
|
||||
return suspendCancellableCoroutine { continuation ->
|
||||
enqueue(object : Callback {
|
||||
override fun onResponse(call: Call, response: Response) {
|
||||
continuation.resume(
|
||||
objectMapper.fromJson(
|
||||
response.body?.string(),
|
||||
typeToken.type
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call, e: IOException) {
|
||||
// Don't bother with resuming the continuation if it is already cancelled.
|
||||
if (continuation.isCancelled) return
|
||||
continuation.resumeWithException(e)
|
||||
}
|
||||
})
|
||||
|
||||
continuation.invokeOnCancellation {
|
||||
try {
|
||||
cancel()
|
||||
} catch (ex: Throwable) {
|
||||
//Ignore cancel exception
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package h_mal.appttude.com.firebase
|
||||
|
||||
data class SignUpResponse(
|
||||
val expiresIn: String? = null,
|
||||
val kind: String? = null,
|
||||
val idToken: String? = null,
|
||||
val localId: String? = null,
|
||||
val email: String? = null,
|
||||
val refreshToken: String? = null
|
||||
)
|
||||
@@ -8,10 +8,4 @@ class HomeRobot: BaseTestRobot() {
|
||||
|
||||
fun checkTitleExists(title: String) = matchText(R.id.prova_title_tv, title)
|
||||
|
||||
fun clickLogin() = clickButton(R.id.email_sign_in_button)
|
||||
|
||||
fun clickRegister() = clickButton(R.id.register_button)
|
||||
|
||||
fun clickForgotPassword() = clickButton(R.id.forgot)
|
||||
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import h_mal.appttude.com.R
|
||||
fun login(func: LoginRobot.() -> Unit) = LoginRobot().apply { func() }
|
||||
class LoginRobot: BaseTestRobot() {
|
||||
|
||||
fun setEmail(email: String) = fillEditText(R.id.email, email);
|
||||
fun setEmail(email: String?) = fillEditText(R.id.email, email)
|
||||
|
||||
fun setPassword(pass: String) = fillEditText(R.id.password, pass)
|
||||
|
||||
@@ -3,40 +3,31 @@ package h_mal.appttude.com.tests
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import com.google.firebase.auth.FirebaseAuth
|
||||
import h_mal.appttude.com.BaseUiTest
|
||||
import h_mal.appttude.com.FirebaseTest
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.USER_PASSWORD
|
||||
import h_mal.appttude.com.robots.home
|
||||
import h_mal.appttude.com.ui.user.LoginActivity
|
||||
import h_mal.appttude.com.robots.login
|
||||
import h_mal.appttude.com.robots.register
|
||||
import h_mal.appttude.com.ui.user.LoginActivity
|
||||
import org.junit.*
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
|
||||
@LargeTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class LoginActivityTest: BaseUiTest<LoginActivity>() {
|
||||
|
||||
@Ignore
|
||||
override fun getApplicationClass() = LoginActivity::class.java
|
||||
|
||||
@After
|
||||
fun afterTest(){
|
||||
FirebaseAuth.getInstance().signOut()
|
||||
}
|
||||
class RegisteredUserAuthenticationActivityTest : FirebaseTest<LoginActivity>(LoginActivity::class.java, registered = true, signedIn = false) {
|
||||
|
||||
@Test
|
||||
fun verifyUserLogin_validUsernameAndPassword_loggedIn() {
|
||||
login {
|
||||
setEmail("test-user@testuserdriver.com")
|
||||
setPassword("Password1234")
|
||||
waitFor(1100)
|
||||
setEmail(getEmail())
|
||||
setPassword(USER_PASSWORD)
|
||||
clickLogin()
|
||||
}
|
||||
home {
|
||||
checkTitleExists(getResourceString(R.string.welcome_title))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package h_mal.appttude.com.tests
|
||||
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import h_mal.appttude.com.FirebaseTest
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.USER_PASSWORD
|
||||
import h_mal.appttude.com.robots.home
|
||||
import h_mal.appttude.com.robots.login
|
||||
import h_mal.appttude.com.robots.register
|
||||
import h_mal.appttude.com.ui.user.LoginActivity
|
||||
import org.junit.*
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
|
||||
@LargeTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class UserAuthenticationActivityTest : FirebaseTest<LoginActivity>(LoginActivity::class.java) {
|
||||
|
||||
@Test
|
||||
fun verifyUserRegistration_validUsernameAndPassword_loggedIn() {
|
||||
login {
|
||||
waitFor(1100)
|
||||
clickRegister()
|
||||
}
|
||||
register {
|
||||
setName("Test User")
|
||||
setEmail(generateEmailAddress())
|
||||
setPassword(USER_PASSWORD)
|
||||
setPasswordConfirm(USER_PASSWORD)
|
||||
clickLogin()
|
||||
}
|
||||
home {
|
||||
checkTitleExists(getResourceString(R.string.welcome_title))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
7
app/src/debug/AndroidManifest.xml
Normal file
7
app/src/debug/AndroidManifest.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<manifest xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<application android:usesCleartextTraffic="true"
|
||||
tools:ignore="MissingApplicationIcon" />
|
||||
|
||||
</manifest>
|
||||
6
app/src/debug/res/xml/network_security_config.xml
Normal file
6
app/src/debug/res/xml/network_security_config.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain>10.0.2.2</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
||||
@@ -4,10 +4,7 @@ import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.base.BaseFragment
|
||||
import h_mal.appttude.com.utils.navigateTo
|
||||
import h_mal.appttude.com.viewmodels.DriverLicenseViewModel
|
||||
|
||||
import kotlinx.android.synthetic.main.fragment_driver_overall.*
|
||||
|
||||
class DriverOverallFragment : Fragment(R.layout.fragment_driver_overall) {
|
||||
|
||||
@@ -10,10 +10,8 @@ import h_mal.appttude.com.utils.navigateTo
|
||||
import h_mal.appttude.com.utils.show
|
||||
import h_mal.appttude.com.viewmodels.RoleViewModel
|
||||
import kotlinx.android.synthetic.main.driver_profile_request.*
|
||||
|
||||
import kotlinx.android.synthetic.main.fragment_home_driver.*
|
||||
import kotlinx.android.synthetic.main.home_buttons_container.*
|
||||
import kotlinx.android.synthetic.main.home_buttons_container.driver
|
||||
|
||||
|
||||
class HomeFragment : DataSubmissionBaseFragment<RoleViewModel, String>(R.layout.fragment_home_driver) {
|
||||
|
||||
@@ -4,9 +4,7 @@ import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.base.BaseFragment
|
||||
import h_mal.appttude.com.utils.navigateTo
|
||||
import h_mal.appttude.com.viewmodels.DriverLicenseViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_vehicle_overall.*
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package h_mal.appttude.com.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.utils.navigateTo
|
||||
import kotlinx.android.synthetic.driver.fragment_welcome.*
|
||||
|
||||
@@ -3,9 +3,9 @@ package h_mal.appttude.com.ui.driverprofile
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import h_mal.appttude.com.dialogs.DateDialog
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.base.DataSubmissionBaseFragment
|
||||
import h_mal.appttude.com.dialogs.DateDialog
|
||||
import h_mal.appttude.com.model.DriverProfileObject
|
||||
import h_mal.appttude.com.utils.setGlideImage
|
||||
import h_mal.appttude.com.viewmodels.DriverProfileViewModel
|
||||
|
||||
@@ -3,9 +3,9 @@ package h_mal.appttude.com.ui.driverprofile
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import h_mal.appttude.com.dialogs.DateDialog
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.base.DataSubmissionBaseFragment
|
||||
import h_mal.appttude.com.dialogs.DateDialog
|
||||
import h_mal.appttude.com.model.PrivateHireObject
|
||||
import h_mal.appttude.com.utils.setGlideImage
|
||||
import h_mal.appttude.com.viewmodels.PrivateHireLicenseViewModel
|
||||
|
||||
@@ -3,9 +3,9 @@ package h_mal.appttude.com.ui.vehicleprofile
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import h_mal.appttude.com.model.LogbookObject
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.base.DataSubmissionBaseFragment
|
||||
import h_mal.appttude.com.model.LogbookObject
|
||||
import h_mal.appttude.com.utils.setGlideImage
|
||||
import h_mal.appttude.com.viewmodels.LogbookViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_logbook.*
|
||||
|
||||
@@ -3,10 +3,9 @@ package h_mal.appttude.com.ui.vehicleprofile
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
|
||||
import h_mal.appttude.com.dialogs.DateDialog
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.base.DataSubmissionBaseFragment
|
||||
import h_mal.appttude.com.dialogs.DateDialog
|
||||
import h_mal.appttude.com.model.MotObject
|
||||
import h_mal.appttude.com.utils.setGlideImage
|
||||
import h_mal.appttude.com.viewmodels.MotViewModel
|
||||
|
||||
@@ -3,11 +3,10 @@ package h_mal.appttude.com.ui.vehicleprofile
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
|
||||
import h_mal.appttude.com.dialogs.DateDialog
|
||||
import h_mal.appttude.com.model.PrivateHireVehicleObject
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.base.DataSubmissionBaseFragment
|
||||
import h_mal.appttude.com.dialogs.DateDialog
|
||||
import h_mal.appttude.com.model.PrivateHireVehicleObject
|
||||
import h_mal.appttude.com.utils.setGlideImage
|
||||
import h_mal.appttude.com.viewmodels.PrivateHireVehicleViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_private_hire_vehicle.*
|
||||
|
||||
@@ -2,10 +2,9 @@ package h_mal.appttude.com.ui.vehicleprofile
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
|
||||
import h_mal.appttude.com.dialogs.DateDialog
|
||||
import h_mal.appttude.com.R
|
||||
import h_mal.appttude.com.base.DataSubmissionBaseFragment
|
||||
import h_mal.appttude.com.dialogs.DateDialog
|
||||
import h_mal.appttude.com.model.VehicleProfileObject
|
||||
import h_mal.appttude.com.viewmodels.VehicleProfileViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_vehicle_setup.*
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
3
app/src/main/java/h_mal/appttude/com/ui/.idea/.gitignore
generated
vendored
Normal file
3
app/src/main/java/h_mal/appttude/com/ui/.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>()
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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>()
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"></resources>
|
||||
@@ -9,7 +9,7 @@ buildscript {
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||
classpath 'com.android.tools.build:gradle:7.2.2'
|
||||
classpath 'com.google.gms:google-services:4.3.15'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"
|
||||
|
||||
|
||||
10
database.rules.json
Normal file
10
database.rules.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"rules": {
|
||||
"user": {
|
||||
".read": true,
|
||||
"$user_id": {
|
||||
".write": "$user_id === auth.uid"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
firebase.json
Normal file
23
firebase.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"emulators": {
|
||||
"auth": {
|
||||
"port": 9099
|
||||
},
|
||||
"database": {
|
||||
"port": 9000
|
||||
},
|
||||
"storage": {
|
||||
"port": 9199
|
||||
},
|
||||
"ui": {
|
||||
"enabled": true
|
||||
},
|
||||
"singleProjectMode": true
|
||||
},
|
||||
"database": {
|
||||
"rules": "database.rules.json"
|
||||
},
|
||||
"storage": {
|
||||
"rules": "storage.rules"
|
||||
}
|
||||
}
|
||||
8
storage.rules
Normal file
8
storage.rules
Normal file
@@ -0,0 +1,8 @@
|
||||
rules_version = '2';
|
||||
service firebase.storage {
|
||||
match /b/{bucket}/o {
|
||||
match /{allPaths=**} {
|
||||
allow read, write: if false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user