Skip to content
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

Better nav + cache improvement #131

Merged
merged 15 commits into from
May 26, 2022
3 changes: 1 addition & 2 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

110 changes: 54 additions & 56 deletions app/src/androidTest/java/ch/epfl/sweng/rps/CacheTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ch.epfl.sweng.rps
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.net.Uri
import androidx.annotation.ColorInt
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
Expand All @@ -14,7 +15,6 @@ import ch.epfl.sweng.rps.persistence.Cache
import ch.epfl.sweng.rps.persistence.PrivateStorage
import ch.epfl.sweng.rps.persistence.Storage
import ch.epfl.sweng.rps.remote.Env
import ch.epfl.sweng.rps.remote.FirebaseRepository
import ch.epfl.sweng.rps.services.ServiceLocator
import com.google.firebase.ktx.Firebase
import io.mockk.mockk
Expand All @@ -23,120 +23,118 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.util.*
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue

@RunWith(AndroidJUnit4::class)
class CacheTests {
lateinit var cache: Cache
lateinit var cacheWithoutAuth: Cache
lateinit var storage: Storage
private lateinit var cache: Cache
private lateinit var cacheWithoutAuth: Cache
private lateinit var storage: Storage


@Before
fun setUp() {
ServiceLocator.setCurrentEnv(Env.Prod)
Firebase.initializeForTest()
cacheWithoutAuth = Cache.createInstance(
cacheWithoutAuth = Cache.initialize(
InstrumentationRegistry.getInstrumentation().targetContext,
mockk<FirebaseRepository>(relaxed = true)
mockk(relaxed = true)
)
cache = Cache.createInstance(InstrumentationRegistry.getInstrumentation().targetContext)
cache = Cache.initialize(InstrumentationRegistry.getInstrumentation().targetContext)
storage = PrivateStorage(InstrumentationRegistry.getInstrumentation().targetContext)
storage.removeFile(Storage.FILES.STATSDATA)
storage.removeFile(Storage.FILES.USERINFO)
storage.removeFile(Storage.FILES.LEADERBOARDDATA)
storage.removeFile(Storage.FILES.USERPICTURE)
for (file in Storage.FILES.values()) {
storage.deleteFile(file)
}
}

@After
fun tearDown() {
storage.removeFile(Storage.FILES.STATSDATA)
storage.removeFile(Storage.FILES.USERINFO)
storage.removeFile(Storage.FILES.LEADERBOARDDATA)
storage.removeFile(Storage.FILES.USERPICTURE)
for (file in Storage.FILES.values()) {
storage.deleteFile(file)
}
}

@Test
fun cacheContainsNoDataWhenCreated() {
assert(cache.getUserDetails() == null)
assert(cache.getStatsData(0).isEmpty())
assert(cache.getLeaderBoardData(0).isEmpty())
assertNull(cache.getUserDetailsFromCache())
assertTrue(cache.getStatsDataFromCache(0).isEmpty())
assertTrue(cache.getLeaderBoardDataFromCache(0).isEmpty())
}

@Test
fun cacheCorrectlyRetrievesUserDetailsFromStorage() {
runBlocking {
assert(cacheWithoutAuth.getUserDetails() == null)
cacheWithoutAuth.updateUserDetails(User(uid = "RAND"))
assert(cacheWithoutAuth.getUserDetails()?.uid == "RAND")
}
fun cacheCorrectlyRetrievesUserDetailsFromStorage() = runBlocking {
assertNull(cacheWithoutAuth.getUserDetailsFromCache())
cacheWithoutAuth.setUserDetails(User(uid = "RAND"))
assertEquals(cacheWithoutAuth.getUserDetailsFromCache()?.uid, "RAND")
}

@Test
fun cacheCorrectlySavesUser() {
val user: User? = User(username = "USERNAME", uid = "01234", email = "[email protected]")
cache.updateUserDetails(user)
assert(cache.getUserDetails()!! == user)
val user = User(username = "USERNAME", uid = "01234", email = "[email protected]")
cache.setUserDetails(user)
cache.clearLocalVars()
assertEquals(cache.getUserDetailsFromCache()!!, user)
}

@Test
fun cacheCorrectlySavesStatsData() {
assert(cache.getStatsData(0).isEmpty())
val lst = listOf<UserStat>(
assertTrue(cache.getStatsDataFromCache(0).isEmpty())
val lst = listOf(
UserStat(gameId = "1234", date = "14/07/2020", opponents = "Opp", "Best 5", "0"),
UserStat(gameId = "1244", date = "14/07/1020", opponents = "Opp1", "Best 3", "0"),
UserStat(gameId = "12134", date = "14/07/3020", opponents = "Opp2", "Best 1", "0"),
)
cache.updateStatsData(lst)
val result = cache.getStatsData(0)
assert(result == lst)
cache.clearLocalVars()
val result = cache.getStatsDataFromCache(0)
assertEquals(result, lst)
}

@Test
fun cacheCorrectlySavesLeaderBoardData() {
assert(cache.getLeaderBoardData(0).isEmpty())
assertTrue(cache.getLeaderBoardDataFromCache(0).isEmpty())
val user1 =
LeaderBoardInfo("jinglun", "1", null, 100)
LeaderBoardInfo("jinglun", "1", Uri.parse("https://example.com/"), 100)
val user2 =
LeaderBoardInfo("Leonardo", "2", null, 80)
val user3 =
LeaderBoardInfo("Adam", "3", null, 60)
val allPlayers = listOf(user1, user2, user3)
cache.updateLeaderBoardData(allPlayers)
val result = cache.getLeaderBoardData(0)
assert(result == allPlayers)
cache.clearLocalVars()
val result = cache.getLeaderBoardDataFromCache(0)
assertEquals(result, allPlayers)
}

@Test
fun cacheCorrectlySavesProfileImage() {
assert(cacheWithoutAuth.getUserPicture() == null)
val btm = createTestBitmap(30, 30, null)
runBlocking {
cacheWithoutAuth.updateUserPicture(btm)
}
assert(cacheWithoutAuth.getUserPicture() == btm)
fun cacheCorrectlySavesProfileImage() = runBlocking {
assertNull(cacheWithoutAuth.getUserPicture())
val btm = createTestBitmap(30, 30, Color.GREEN)
cacheWithoutAuth.updateUserPicture(btm)
cache.clearLocalVars()
assertEquals(cacheWithoutAuth.getUserPicture(), btm)
}

@Test
fun cacheCorrectlyRetrievesProfileImageFromStorage() {
assert(cache.getUserPicture() == null)
assertNull(cache.getUserPicture())
val bitmap = createTestBitmap(20, 20, Color.RED)
storage.writeBackUserPicture(bitmap)
assert(cache.getUserPicture() != null)
cache.clearLocalVars()
assertNotNull(cache.getUserPicture())
}

fun createTestBitmap(w: Int, h: Int, @ColorInt color: Int?): Bitmap {
var color = color
private fun createTestBitmap(w: Int, h: Int, @ColorInt color: Int?): Bitmap {
val c = color ?: intArrayOf(
Color.BLUE, Color.GREEN, Color.RED,
Color.YELLOW, Color.WHITE
).random()
val bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
if (color == null) {
val colors = intArrayOf(
Color.BLUE, Color.GREEN, Color.RED,
Color.YELLOW, Color.WHITE
)
val rgen = Random()
color = colors[rgen.nextInt(colors.size - 1)]
}
canvas.drawColor(color)
canvas.drawColor(c)
return bitmap
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class LoadingActivityTest {
}

@get:Rule
val rule = ActivityScenarioRuleWithSetup.default<LoginActivity>(createIntent())
val rule = ActivityScenarioRuleWithSetup.default<LoadingActivity>(createIntent())

@Test
fun start() {
Expand Down
8 changes: 4 additions & 4 deletions app/src/androidTest/java/ch/epfl/sweng/rps/LoginPageTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@ import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class LoginPageTest {
lateinit var scenario: ActivityScenario<LoginActivity>
private lateinit var scenario: ActivityScenario<LoginActivity>

@Before
fun setUp() {
Firebase.initializeForTest()
FirebaseAuth.getInstance().signOut()
PrivateStorage(InstrumentationRegistry.getInstrumentation().targetContext).removeFile(
PrivateStorage(InstrumentationRegistry.getInstrumentation().targetContext).deleteFile(
Storage.FILES.USERINFO
)
Intents.init()
Cache.createInstance(InstrumentationRegistry.getInstrumentation().targetContext)
.updateUserDetails(null)
Cache.initialize(InstrumentationRegistry.getInstrumentation().targetContext)
.setUserDetails(null)
scenario = ActivityScenario.launch(LoginActivity::class.java)
}

Expand Down
36 changes: 13 additions & 23 deletions app/src/androidTest/java/ch/epfl/sweng/rps/ProfileFragmentTest.kt
Original file line number Diff line number Diff line change
@@ -1,55 +1,45 @@
package ch.epfl.sweng.rps

import android.content.Intent
import android.os.Bundle
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.Espresso.pressBack
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.matcher.ViewMatchers.*
import androidx.test.platform.app.InstrumentationRegistry
import ch.epfl.sweng.rps.TestUtils.initializeForTest
import ch.epfl.sweng.rps.models.remote.User
import com.google.firebase.ktx.Firebase
import ch.epfl.sweng.rps.persistence.Cache
import org.junit.Rule
import org.junit.Test


class ProfileFragmentTest {

private val bundle = run {
val b: Bundle = Bundle()
val data = mapOf(
"email" to "[email protected]",
"display_name" to "asdino",
"uid" to "123",
"privacy" to User.Privacy.PUBLIC.toString()
)
data.forEach { (k, v) -> b.putString(k, v) }
b
}


private fun createIntent(): Intent {
Firebase.initializeForTest()
val i: Intent = Intent(
return Intent(
InstrumentationRegistry.getInstrumentation().targetContext,
MainActivity::class.java
)
i.putExtra("User", bundle)
return i
}

@get:Rule
val testRule = ActivityScenarioRuleWithSetup.default<MainActivity>(createIntent())

@Test
fun testFields() {
val user = User(
username = "test",
uid = "uid",
games_history_privacy = User.Privacy.PUBLIC.name,
has_profile_photo = false,
email = "email",
)
Cache.getInstance().setUserDetails(user)
onView(withId(R.id.nav_profile)).perform(click())
onView(withId(R.id.TextDisplayName)).check(matches(withText(bundle.getString("display_name"))))
onView(withId(R.id.TextEmail)).check(matches(withText(bundle.getString("email"))))
onView(withId(R.id.TextPrivacy)).check(matches(withText(bundle.getString("privacy"))))
onView(withId(R.id.TextDisplayName)).check(matches(withText(user.username)))
onView(withId(R.id.TextEmail)).check(matches(withText(user.email)))
onView(withId(R.id.TextPrivacy)).check(matches(withText(user.games_history_privacy)))
}

@Test
Expand Down
34 changes: 17 additions & 17 deletions app/src/androidTest/java/ch/epfl/sweng/rps/SettingsPageTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,10 @@ class SettingsPageTest {
return themeIdToAppCompatThemeId[themeId]!!
}

private fun getThemeIdFromAppCompatTheme(appCompatThemeId: Int): String {
val filtered = themeIdToAppCompatThemeId.entries.filter { it.value == appCompatThemeId }
if (filtered.isEmpty()) {
throw IllegalArgumentException("No theme id found for appCompatThemeId $appCompatThemeId")
}
return filtered.first().key
private fun getThemeIdFromAppCompatTheme(appCompatThemeId: Int): String? {
val filtered =
themeIdToAppCompatThemeId.entries.firstOrNull { it.value == appCompatThemeId }
return filtered?.key
}


Expand All @@ -84,21 +82,23 @@ class SettingsPageTest {
// the activity's onPause method has been called at this point
scenarioRule.scenario.moveToState(Lifecycle.State.RESUMED)

for (entry in computeThemeMap()) {
Log.i("SettingsPageTest", "Testing theme ${entry.key}")
for ((key, value) in computeThemeMap()) {
Log.i("SettingsPageTest", "Testing theme ${key}")
onView(withText(R.string.theme_mode)).perform(click())
onView(withText(entry.key)).perform(click())
onView(withText(key)).perform(click())
onView(isRoot()).perform(waitFor(1000))

val appCompatThemeId = getCurrentNightMode()

assertEquals(
getAppCompatThemeFromThemeId(entry.value),
appCompatThemeId,
"Theme should be ${entry.value} (${getAppCompatThemeFromThemeId(entry.value)}) after clicking ${entry.key}, but is $appCompatThemeId (${
getThemeIdFromAppCompatTheme(appCompatThemeId)
})"
)
val themeId = getAppCompatThemeFromThemeId(value)
if (appCompatThemeId != AppCompatDelegate.MODE_NIGHT_UNSPECIFIED) {
assertEquals(
themeId,
appCompatThemeId,
"Theme should be $value ($themeId) after clicking $key, but is $appCompatThemeId (${
getThemeIdFromAppCompatTheme(appCompatThemeId)
})"
)
}

}
}
Expand Down
3 changes: 3 additions & 0 deletions app/src/androidTest/java/ch/epfl/sweng/rps/TestUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry
import androidx.test.runner.lifecycle.Stage
import ch.epfl.sweng.rps.TestUtils.initializeForTest
import ch.epfl.sweng.rps.persistence.Cache
import ch.epfl.sweng.rps.remote.Env
import ch.epfl.sweng.rps.services.ServiceLocator
import com.google.firebase.FirebaseApp
Expand Down Expand Up @@ -170,9 +171,11 @@ class ActivityScenarioRuleWithSetup<A : Activity?> : ExternalResource {
{
ServiceLocator.setCurrentEnv(Env.Test)
Firebase.initializeForTest()
Cache.initialize(InstrumentationRegistry.getInstrumentation().targetContext)
ServiceLocator.localRepository.setCurrentUid("test")
},
{
Cache.getInstance().clear()
FirebaseAuth.getInstance().signOut()
FirebaseApp.clearInstancesForTest()
ServiceLocator.setCurrentEnv(Env.Prod)
Expand Down
Loading