Skip to content

Firestore #479

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Aug 20, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix code review
  • Loading branch information
butterflyforever committed Aug 15, 2020
commit 588851a2f12102903f0f771c7bc5a2de77d2d9cc
53 changes: 50 additions & 3 deletions android/canonical/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ android {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}

staging {
initWith(buildTypes.debug) // keep versionName and PIN from 'debug'
defaultConfig.minSdkVersion 18
}
}

compileOptions {
Expand All @@ -38,6 +43,10 @@ android {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}

testOptions {
unitTests.returnDefaultValues = true
}
}

dependencies {
Expand All @@ -54,18 +63,56 @@ dependencies {
implementation 'com.google.android.libraries.places:places:2.3.0'
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'com.google.firebase:firebase-analytics:17.4.4'
implementation 'com.google.firebase:firebase-auth:19.3.2'
implementation 'com.google.firebase:firebase-analytics-ktx:17.4.4'
implementation 'com.google.firebase:firebase-auth-ktx:19.3.2'
implementation 'com.google.firebase:firebase-firestore-ktx:21.4.3'

implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.percentlayout:percentlayout:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'

debugImplementation "androidx.fragment:fragment-testing:1.2.5"

kapt 'com.android.databinding:compiler:3.1.4'
testImplementation 'junit:junit:4.12'

// Core library
androidTestImplementation 'androidx.test:core:1.0.0'

// AndroidJUnitRunner and JUnit Rules
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test:rules:1.1.0'


// Assertions
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.ext:truth:1.0.0'
androidTestImplementation 'com.google.truth:truth:0.42'

// Espresso dependencies
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.3'
// androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.1.0'
// androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.0'
// androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.1.0'
// androidTestImplementation 'androidx.test.espresso:espresso-web:3.1.0'
// androidTestImplementation 'androidx.test.espresso.idling:idling-concurrent:3.1.0'

// The following Espresso dependency can be either "implementation"
// or "androidTestImplementation", depending on whether you want the
// dependency to appear on your APK's compile classpath or the test APK
// classpath.
androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.1.0'

testImplementation 'junit:junit:4.12'
testImplementation "androidx.arch.core:core-testing:2.1.0"
testImplementation "androidx.test.ext:junit-ktx:1.1.1"
testImplementation "androidx.test:core-ktx:1.2.0"
testImplementation "org.robolectric:robolectric:4.1"




}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.google.samples.quickstart.canonical

import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.ActivityTestRule
import androidx.test.rule.GrantPermissionRule
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiSelector
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith


@RunWith(AndroidJUnit4::class)
class MapsFragmentTest {

@get:Rule
var activityRule: ActivityTestRule<MainActivity>
= ActivityTestRule(MainActivity::class.java)

@Rule @JvmField
val grantPermissionRule: GrantPermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION)

lateinit var device : UiDevice

@Before
fun setup() {
device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
// Your google account must have logged in before test.
// Otherwise the main page will be changed to login page,
// and all the test will fail.
// You only need to login the first time you open the app after
// installing it.
}


@Test
fun searchDestination() {
onView(ViewMatchers.withId(R.id.bottom_navigation_item_map))
.perform(ViewActions.click())
Thread.sleep(3000)
onView(ViewMatchers.withId(R.id.autocomplete_fragment))
.perform(ViewActions.click())
val new = device.findObject(UiSelector().text("Search"))
new.text = "Central Park"
Thread.sleep(2000)
device.click(300,800)
Thread.sleep(2000)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package com.google.samples.quickstart.canonical

import androidx.fragment.app.testing.launchFragmentInContainer
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.RootMatchers.isDialog
import androidx.test.espresso.matcher.RootMatchers.withDecorView
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.rule.ActivityTestRule
import org.hamcrest.core.IsNot.not
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith


@RunWith(AndroidJUnit4::class)
class RunFragmentTest {

@get:Rule
var activityRule: ActivityTestRule<MainActivity>
= ActivityTestRule(MainActivity::class.java)

@Before
fun makeSureYourAccountHasLoggedIn() {
// Your google account must have logged in before test.
// Otherwise the main page will be changed to login page,
// and all the test will fail.
// You only need to login the first time you open the app after
// installing it.
}

@Test
fun startClickTest() {
// launchFragmentInContainer<RunFragment>()
onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(2000)
onView(withId(R.id.running_chronometer))
.check(matches(withText("00:02")))
}

@Test
fun pauseClickTest() {
// launchFragmentInContainer<RunFragment>()
onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(2000)
onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(2000)
onView(withId(R.id.running_chronometer))
.check(matches(withText("00:02")))
}

@Test
fun startAndPauseClickTest() {
// launchFragmentInContainer<RunFragment>()
onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(2000)
onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(1000)
onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(1000)
onView(withId(R.id.running_chronometer))
.check(matches(withText("00:03")))
}

@Test
fun resetClickWhenWorkingTest() {
// launchFragmentInContainer<RunFragment>()
onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(2000)
onView(withId(R.id.reset_btn))
.perform(click())
onView(withId(R.id.running_chronometer))
.check(matches(withText("00:00")))
}

@Test
fun resetClickWhenPausingTest() {
// launchFragmentInContainer<RunFragment>()
onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(2000)
onView(withId(R.id.running_chronometer))
.check(matches(withText("00:02")))

onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(2000)
onView(withId(R.id.running_chronometer))
.check(matches(withText("00:02")))

onView(withId(R.id.reset_btn))
.perform(click())
onView(withId(R.id.running_chronometer))
.check(matches(withText("00:00")))
}

@Test
fun submitClickWhenWorkingTest() {
// launchFragmentInContainer<RunFragment>()
onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(2000)
onView(withId(R.id.running_chronometer))
.check(matches(withText("00:02")))

onView(withId(R.id.submit_btn))
.perform(click())
onView(withText("Submission Confirm"))
.inRoot(isDialog())
.check(matches(isDisplayed()))
}

@Test
fun submitClickWhenPausingTest() {
// launchFragmentInContainer<RunFragment>()
onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(2000)
onView(withId(R.id.start_pause_btn))
.perform(click())
Thread.sleep(1000)

onView(withId(R.id.submit_btn))
.perform(click())
onView(withText("Submission Confirm"))
.inRoot(isDialog())
.check(matches(isDisplayed()))
}

@Test
fun submitClickBeforeWorkingTest() {
onView(withId(R.id.submit_btn))
.perform(click())
onView(withText(R.string.submit_illegal))
.inRoot(withDecorView(not(activityRule.activity.window.decorView)))
.check(matches(isDisplayed()))
}

}
1 change: 1 addition & 0 deletions android/canonical/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.google.samples.quickstart.canonical">

<!--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ import android.view.ViewGroup
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.google.android.gms.common.SignInButton
import com.google.firebase.firestore.SetOptions
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.google.samples.quickstart.canonical.SignInViewModel.Companion.FIREBASE_AUTH_WITH_GOOGLE_FAIL
import com.google.samples.quickstart.canonical.SignInViewModel.Companion.FIREBASE_AUTH_WITH_GOOGLE_SUCCESSFUL
import com.google.samples.quickstart.canonical.SignInViewModel.Companion.GOOGLE_SIGN_IN_UNSUCCESSFUL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class MainActivity : AppCompatActivity() {
else -> false
}
} catch (e:Exception) {
Log.e(MAIN_ACTIVITY_TAG, "setOnNavigationItemSelectedListener failed", e)
Log.e(MAIN_ACTIVITY_TAG, "Navigation failed", e)
false
}
}
Expand Down Expand Up @@ -95,7 +95,9 @@ class MainActivity : AppCompatActivity() {
Log.d(MAIN_ACTIVITY_TAG, "Already login")
setupNavigationBar()
// Init Profile
profileVM.initAppUser(signInVM.getFirebaseAuthCurUser()!!)
val firebaseUser = signInVM.getFirebaseAuthCurUser()
profileVM.initAppUser(firebaseUser?.displayName ?: "", firebaseUser?.email ?: "",
firebaseUser?.uid ?: "", firebaseUser?.photoUrl.toString())
logoutUserObserver()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ImageView
import android.widget.ListView
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import androidx.databinding.DataBindingUtil
import com.google.samples.quickstart.canonical.databinding.FragmentProfileBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.android.synthetic.main.fragment_profile.*


class ProfileFragment : Fragment() {
Expand All @@ -20,12 +24,14 @@ class ProfileFragment : Fragment() {
private val profileVM : ProfileViewModel by activityViewModels()
private lateinit var binding : FragmentProfileBinding

private fun downloadPhotoAndSetView(view: View) {
private fun downloadPhotoAndSetView(userImage: ImageView) {
val url = profileVM.getUserPhotoURL()
if (url != "") {
Log.d(PROFILE_TAG, url)
DownloadImageTask(view.findViewById(R.id.usr_img))
.execute(url)
CoroutineScope(Dispatchers.Main).launch{
val bmImage = profileVM.downloadImage(url)
userImage.setImageBitmap(bmImage)
}
}
}

Expand Down Expand Up @@ -59,11 +65,11 @@ class ProfileFragment : Fragment() {
refreshButton.setOnClickListener {
profileVM.refreshUser(view.findViewById<ListView>(R.id.run_history_list_view).adapter
as RunHistoryAdapter)
downloadPhotoAndSetView(view)
downloadPhotoAndSetView(usr_img)
}
setRunHistory()
// update UI
downloadPhotoAndSetView(view)
downloadPhotoAndSetView(usr_img)
}

companion object {
Expand Down
Loading