diff --git a/app/src/androidTest/java/ch/sdp/vibester/activity/GameSetupActivityTest.kt b/app/src/androidTest/java/ch/sdp/vibester/activity/GameSetupActivityTest.kt index 850b0c381..042dc6e1e 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/activity/GameSetupActivityTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/activity/GameSetupActivityTest.kt @@ -16,6 +16,8 @@ import androidx.test.espresso.matcher.ViewMatchers.withSpinnerText import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import ch.sdp.vibester.R +import dagger.hilt.android.testing.HiltAndroidRule +import dagger.hilt.android.testing.HiltAndroidTest import org.hamcrest.Matchers import org.junit.After import org.junit.Before @@ -24,13 +26,18 @@ import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) +@HiltAndroidTest class GameSetupActivityTest { - @get: Rule + @get:Rule(order = 0) + var hiltRule = HiltAndroidRule(this) + + @get: Rule(order = 1) val activityRule = ActivityScenarioRule(GameSetupActivity::class.java) @Before fun setUp() { + hiltRule.inject() Intents.init() } diff --git a/app/src/androidTest/java/ch/sdp/vibester/activity/ProfileActivityTest.kt b/app/src/androidTest/java/ch/sdp/vibester/activity/ProfileActivityTest.kt index ad3e756fe..693888ef0 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/activity/ProfileActivityTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/activity/ProfileActivityTest.kt @@ -68,7 +68,9 @@ class ProfileActivityTest { every { mockUsersRepo.getUserData(any(), any()) } answers { secondArg<(User) -> Unit>().invoke(mockProfile) } - every { mockUsersRepo.updateFieldString(any(), any(), any()) } answers {} + + every { mockUsersRepo.setFieldValue(any(), any(), any()) } answers {} + every { mockUsersRepo.setFieldValue(any(), any(), any()) } answers {} } @After diff --git a/app/src/androidTest/java/ch/sdp/vibester/activity/SearchUserActivityTest.kt b/app/src/androidTest/java/ch/sdp/vibester/activity/SearchUserActivityTest.kt index e4773582b..607319414 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/activity/SearchUserActivityTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/activity/SearchUserActivityTest.kt @@ -62,7 +62,9 @@ class SearchUserActivityTest { secondArg<(User) -> Unit>().invoke(mockUser) } - every {mockUsersRepo.updateFieldSubFieldBoolean(any(), any(), any(), any())} answers {} + every {mockUsersRepo.updateSubFieldInt(any(), any(), any(), any(),any())} answers {} + every {mockUsersRepo.setSubFieldValue(any(), any(), any(), any())} answers {} + } @BindValue @JvmField @@ -191,13 +193,13 @@ class SearchUserActivityTest { /** * Custom functions to match the item views inside Recycle View */ - fun checkRecyclerSubViews( recyclerViewId: Int, position: Int, itemMatcher: Matcher, subViewId: Int) { + private fun checkRecyclerSubViews( recyclerViewId: Int, position: Int, itemMatcher: Matcher, subViewId: Int) { onView(withId(recyclerViewId)).perform( RecyclerViewActions.scrollToPosition(position)) .check(matches(atPositionOnView(position, itemMatcher, subViewId))) } - fun atPositionOnView(position: Int, itemMatcher: Matcher, targetViewId: Int): Matcher { + private fun atPositionOnView(position: Int, itemMatcher: Matcher, targetViewId: Int): Matcher { return object : BoundedMatcher(RecyclerView::class.java) { override fun describeTo(description: Description) { description.appendText("has view id $itemMatcher at position $position") diff --git a/app/src/androidTest/java/ch/sdp/vibester/activity/TypingGameActivityTest.kt b/app/src/androidTest/java/ch/sdp/vibester/activity/TypingGameActivityTest.kt index 3065522af..754c7c20d 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/activity/TypingGameActivityTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/activity/TypingGameActivityTest.kt @@ -18,10 +18,15 @@ import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import ch.sdp.vibester.R -import ch.sdp.vibester.TestMode import ch.sdp.vibester.api.LastfmMethod +import ch.sdp.vibester.database.DataGetter import ch.sdp.vibester.helper.TypingGameManager import ch.sdp.vibester.model.Song +import dagger.hilt.android.testing.BindValue +import dagger.hilt.android.testing.HiltAndroidRule +import dagger.hilt.android.testing.HiltAndroidTest +import io.mockk.every +import io.mockk.mockk import org.junit.After import org.junit.Assert.assertEquals import org.junit.Before @@ -30,14 +35,18 @@ import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) +@HiltAndroidTest class TypingGameActivityTest { - @JvmField - @get:Rule + @get:Rule(order = 0) + var hiltRule = HiltAndroidRule(this) + + @get:Rule(order = 1) val activityRule = ActivityScenarioRule(TypingGameActivity::class.java) @Before fun setUp() { + hiltRule.inject() Intents.init() } @@ -46,6 +55,18 @@ class TypingGameActivityTest { Intents.release() } + @BindValue + @JvmField + val mockUsersRepo = mockk() + + private fun createMockInvocation() { + every { mockUsersRepo.setSubFieldValue(any(), any(), any(), any()) } answers {} + every { mockUsersRepo.updateFieldInt(any(), any(), any(), any()) } answers {} + every { mockUsersRepo.setFieldValue(any(), any(), any()) } answers {} + every { mockUsersRepo.updateSubFieldInt(any(), any(), any(), any(), any()) } answers {} + + } + private val expectedSize = 200 private fun setGameManager(numSongs:Int = 1, valid: Boolean = true): TypingGameManager { val epilogue = "{\"tracks\":{\"track\":[" @@ -110,7 +131,7 @@ class TypingGameActivityTest { @Test fun guessLayoutTest() { - TestMode.setTest() + createMockInvocation() val inputTxt = """ { "resultCount":1, @@ -163,6 +184,7 @@ class TypingGameActivityTest { // Do not put gameManager as an extra val scn: ActivityScenario = ActivityScenario.launch(intent) val ctx = ApplicationProvider.getApplicationContext() as Context + createMockInvocation() scn.onActivity { activity -> activity.checkAnswer(ctx, songTest, gameManager) } @@ -188,6 +210,7 @@ class TypingGameActivityTest { Intent(ApplicationProvider.getApplicationContext(), TypingGameActivity::class.java) val scn: ActivityScenario = ActivityScenario.launch(intent) val ctx = ApplicationProvider.getApplicationContext() as Context + createMockInvocation() scn.onActivity { activity -> activity.checkAnswer(ctx, songTest, gameManager) } @@ -201,7 +224,7 @@ class TypingGameActivityTest { */ @Test fun checkIntentOnEnding() { - TestMode.setTest() + createMockInvocation() val inputTxt = """ { "resultCount":1, @@ -249,6 +272,7 @@ class TypingGameActivityTest { val intent = Intent(ApplicationProvider.getApplicationContext(), TypingGameActivity::class.java) val scn: ActivityScenario = ActivityScenario.launch(intent) val ctx = ApplicationProvider.getApplicationContext() as Context + createMockInvocation() scn.onActivity { activity -> activity.testFirstRound(ctx, gameManager) activity.testProgressBar() @@ -276,7 +300,7 @@ class TypingGameActivityTest { @Test fun nextButtonOnClick(){ - TestMode.setTest() + createMockInvocation() val gameManager = setGameManager(2) assertEquals(gameManager.getSongList().size, 2) diff --git a/app/src/main/java/ch/sdp/vibester/activity/CreateProfileActivity.kt b/app/src/main/java/ch/sdp/vibester/activity/CreateProfileActivity.kt index 2f0ca72cc..f668a35aa 100644 --- a/app/src/main/java/ch/sdp/vibester/activity/CreateProfileActivity.kt +++ b/app/src/main/java/ch/sdp/vibester/activity/CreateProfileActivity.kt @@ -42,7 +42,7 @@ class CreateProfileActivity : AppCompatActivity() { btCreateAcc.setOnClickListener { if (!TestMode.isTest()){ - dataGetter.updateFieldString(FireBaseAuthenticator.getCurrentUID(), username.text.toString(), "username") + dataGetter.setFieldValue(FireBaseAuthenticator.getCurrentUID(), "username", username.text.toString()) } startNewActivity(email) } diff --git a/app/src/main/java/ch/sdp/vibester/activity/GameSetupActivity.kt b/app/src/main/java/ch/sdp/vibester/activity/GameSetupActivity.kt index ee8ba0183..143b72764 100644 --- a/app/src/main/java/ch/sdp/vibester/activity/GameSetupActivity.kt +++ b/app/src/main/java/ch/sdp/vibester/activity/GameSetupActivity.kt @@ -142,14 +142,15 @@ class GameSetupActivity : AppCompatActivity(), AdapterView.OnItemSelectedListene var method = "" var artist = "" var tag = "" + var mode = "" val uri = LastfmUri() when (view.id) { - R.id.btsButton -> {method = LastfmMethod.BY_ARTIST.method; artist = "BTS" } - R.id.kpopButton -> {method = LastfmMethod.BY_TAG.method; tag = "kpop" } - R.id.imagDragonsButton -> {method = LastfmMethod.BY_ARTIST.method; artist = "Imagine Dragons"} - R.id.rockButton-> {method = LastfmMethod.BY_TAG.method; tag = "rock" } - R.id.topTracksButton -> {method = LastfmMethod.BY_CHART.method} - R.id.billieEilishButton -> {method =LastfmMethod.BY_ARTIST.method; artist = "Billie Eilish"} + R.id.btsButton -> {method = LastfmMethod.BY_ARTIST.method; artist = "BTS"; mode = "BTS" } + R.id.kpopButton -> {method = LastfmMethod.BY_TAG.method; tag = "kpop"; mode = "kpop" } + R.id.imagDragonsButton -> {method = LastfmMethod.BY_ARTIST.method; artist = "Imagine Dragons"; mode = "Imagine Dragons"} + R.id.rockButton-> {method = LastfmMethod.BY_TAG.method; tag = "rock"; mode = "rock" } + R.id.topTracksButton -> {method = LastfmMethod.BY_CHART.method; mode = "top tracks"} + R.id.billieEilishButton -> {method =LastfmMethod.BY_ARTIST.method; artist = "Billie Eilish"; mode = "billie eilish"} } uri.method = method uri.artist = artist @@ -158,6 +159,7 @@ class GameSetupActivity : AppCompatActivity(), AdapterView.OnItemSelectedListene findViewById(R.id.chooseGenre).visibility = GONE findViewById(R.id.chooseDifficulty).visibility = VISIBLE + gameManager.gameMode = mode setGameSongList(uri) } diff --git a/app/src/main/java/ch/sdp/vibester/activity/ProfileActivity.kt b/app/src/main/java/ch/sdp/vibester/activity/ProfileActivity.kt index 29e7dc91d..e6d2b96d9 100644 --- a/app/src/main/java/ch/sdp/vibester/activity/ProfileActivity.kt +++ b/app/src/main/java/ch/sdp/vibester/activity/ProfileActivity.kt @@ -125,7 +125,8 @@ class ProfileActivity : AppCompatActivity() { findViewById(textId).text = input.text.toString() if(name == "username"){ - dataGetter.updateFieldString(FireBaseAuthenticator.getCurrentUID(), input.text.toString(), "username") + dataGetter.setFieldValue(FireBaseAuthenticator.getCurrentUID(), "username", input.text.toString()) + } } diff --git a/app/src/main/java/ch/sdp/vibester/activity/TypingGameActivity.kt b/app/src/main/java/ch/sdp/vibester/activity/TypingGameActivity.kt index c1f6ac45e..289444590 100644 --- a/app/src/main/java/ch/sdp/vibester/activity/TypingGameActivity.kt +++ b/app/src/main/java/ch/sdp/vibester/activity/TypingGameActivity.kt @@ -17,20 +17,25 @@ import ch.sdp.vibester.helper.DisplayContents import ch.sdp.vibester.helper.GameManager import ch.sdp.vibester.helper.TypingGameManager import ch.sdp.vibester.model.Song +import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.launch import okhttp3.OkHttpClient +import javax.inject.Inject /** * Class that represent a game */ - +@AndroidEntryPoint class TypingGameActivity : GameActivity() { private lateinit var gameManager: TypingGameManager private var gameIsOn: Boolean = true // done to avoid clicks on songs after the round is over + @Inject + lateinit var dataGetter: DataGetter + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) requestWindowFeature(Window.FEATURE_NO_TITLE) @@ -212,12 +217,11 @@ class TypingGameActivity : GameActivity() { toggleNextBtnVisibility(true) // If currently not in test and has finished the game, update the scores - if (isEndGame(gameManager) && !TestMode.isTest()) { - val dataGetter = DataGetter() - dataGetter.updateRelativeFieldInt(FireBaseAuthenticator.getCurrentUID(), 1, "totalGames") - dataGetter.updateRelativeFieldInt(FireBaseAuthenticator.getCurrentUID(), gameManager.getCorrectSongs().size, "correctSongs") - dataGetter.updateBestFieldInt(FireBaseAuthenticator.getCurrentUID(), gameManager.getScore(), "bestScore") - + if (isEndGame(gameManager)) { + dataGetter.updateFieldInt(FireBaseAuthenticator.getCurrentUID(), "totalGames", 1, method = "sum") + dataGetter.updateFieldInt(FireBaseAuthenticator.getCurrentUID(), "correctSongs", gameManager.getCorrectSongs().size, method = "sum") + dataGetter.updateFieldInt(FireBaseAuthenticator.getCurrentUID(), "bestScore", gameManager.getScore(), method = "best") + dataGetter.updateSubFieldInt(FireBaseAuthenticator.getCurrentUID(), gameManager.getScore(), "scores", gameManager.gameMode, method = "best") } } diff --git a/app/src/main/java/ch/sdp/vibester/database/DataGetter.kt b/app/src/main/java/ch/sdp/vibester/database/DataGetter.kt index 0957cc361..5745d553b 100644 --- a/app/src/main/java/ch/sdp/vibester/database/DataGetter.kt +++ b/app/src/main/java/ch/sdp/vibester/database/DataGetter.kt @@ -21,81 +21,78 @@ class DataGetter @Inject constructor() { private val dbRoomRef = Database.get().getReference("rooms") private val authenticator: FireBaseAuthenticator = FireBaseAuthenticator() - /** - * This function updates a specific string field of a user in the database - * @param userID the id of the user which is being updated - * @param newVal (String) the new value of the field that is being updated - * @param fieldName the field name of the field that is being updated + * Set field value + * @param uid user identifier + * @param newVal new value to set + * @param fieldName */ - fun updateFieldString(userID: String, newVal: String, fieldName: String) { - dbUserRef.child(userID) + fun setFieldValue(uid: String, fieldName: String, newVal: Any) { + dbUserRef.child(uid) .child(fieldName) .setValue(newVal) } /** - * This function updates a specific int field of a user in the database - * @param userID the id of the user which is being updated - * @param newVal (Int) the new value of the field that is being updated - * @param fieldName the field name of the field that is being updated + * Set subfield value + * @param uid user identifier + * @param newVal new value to set + * @param fieldName + * @param subFieldName */ - fun updateFieldInt(userID: String, newVal: Int, fieldName: String) { - dbUserRef.child(userID) + fun setSubFieldValue(uid: String, fieldName: String, subFieldName: String, newVal: Any) { + dbUserRef.child(uid) .child(fieldName) + .child(subFieldName) .setValue(newVal) } /** - * This function increments a specific int field of a user in the database - * @param userID the id of the user which is being updated - * @param newVal (Int) the increment value of the field that is being updated - * @param fieldName the field name of the field that is being updated + * Update integer value in a subfield based on method sum/best + * @param userID + * @param newVal + * @param fieldName */ - fun updateRelativeFieldInt(userID: String, newVal: Int, fieldName: String) { - if(!TestMode.isTest()) { - dbUserRef.child(userID).child(fieldName) - .get().addOnSuccessListener { t -> - if(!TestMode.isTest()) { - updateFieldInt(userID, (t.value as Long?)!!.toInt() + newVal, fieldName) + fun updateFieldInt(uid: String, fieldName: String, newVal: Int, method:String) { + dbUserRef.child(uid).child(fieldName) + .get().addOnSuccessListener { t -> + var finalVal = newVal + if(t.value != null) { + val previousVal = (t.value as Long?)!!.toInt() + when (method) { + "sum" -> finalVal += previousVal + "best" -> finalVal = maxOf(previousVal, newVal) } } - } + setFieldValue(uid, fieldName, finalVal) + } } + /** - * This function sets the best between current and given in argument value - * @param userID the id of the user which is being updated - * @param newVal (Int) the new value of the field that is being compared and updated - * @param fieldName the field name of the field that is being updated + * Update the integer value of subfield based on method sum/best + * @param userID + * @param newVal + * @param fieldName + * @param subFieldName */ - fun updateBestFieldInt(userID: String, newVal: Int, fieldName: String) { - if(!TestMode.isTest()) { - dbUserRef.child(userID).child(fieldName) - .get().addOnSuccessListener { t -> - if(!TestMode.isTest()) { - updateFieldInt(userID, maxOf((t.value as Long?)!!.toInt(), newVal), fieldName) + fun updateSubFieldInt(userID: String, newVal: Int, fieldName: String, subFieldName: String, method: String) { + dbUserRef.child(userID).child(fieldName).child(subFieldName) + .get().addOnSuccessListener { t -> + var finalVal = newVal + if(t.value != null) { + val previousVal = (t.value as Long?)!!.toInt() + when (method) { + "sum" -> finalVal += previousVal + "best" -> finalVal = maxOf(previousVal, newVal) } } - } + setSubFieldValue(userID, fieldName, subFieldName, finalVal) + } } - /** - * Update a subfield of user's field - * @param userID the id of the user which is being updated - * @param newVal (Boolean) the new value of the field that is being updated - * @param fieldName the field name of the field that is being updated - * @param subFieldName the field name of the field that is being updated - */ - fun updateFieldSubFieldBoolean(userID: String, newVal: Boolean, fieldName: String, subFieldName: String) { - dbUserRef.child(userID) - .child(fieldName) - .child(subFieldName) - .setValue(newVal) - } - /** * This function creates a new user account in the database * @param email the email of the new user diff --git a/app/src/main/java/ch/sdp/vibester/helper/GameManager.kt b/app/src/main/java/ch/sdp/vibester/helper/GameManager.kt index c16c2a242..21026448f 100644 --- a/app/src/main/java/ch/sdp/vibester/helper/GameManager.kt +++ b/app/src/main/java/ch/sdp/vibester/helper/GameManager.kt @@ -13,6 +13,7 @@ open class GameManager : Serializable { private var score = 0 open var gameSize = 5 var numPlayedSongs = 0 + var gameMode = "" open lateinit var currentSong: Song var gameSongList: MutableList> = mutableListOf() private val correctSongs = mutableListOf() //TODO: question: why this is a val but the next one is a var? diff --git a/app/src/main/java/ch/sdp/vibester/user/UserProfileAdapter.kt b/app/src/main/java/ch/sdp/vibester/user/UserProfileAdapter.kt index da002cb40..3e6324411 100644 --- a/app/src/main/java/ch/sdp/vibester/user/UserProfileAdapter.kt +++ b/app/src/main/java/ch/sdp/vibester/user/UserProfileAdapter.kt @@ -78,9 +78,9 @@ class UserProfileAdapter constructor(val users: MutableList, val authentic changeBtnToImage() } else { - addFriendBtn.setOnClickListener{ - if(currentUser != null){ - usersRepo.updateFieldSubFieldBoolean(currentUser.uid, true, "friends", user.uid) + addFriendBtn.setOnClickListener { + if (currentUser != null) { + usersRepo.setSubFieldValue(currentUser.uid, "friends", user.uid,true) changeBtnToImage() } }