diff --git a/app/src/androidTest/java/ch/sdp/vibester/activity/BuzzerScreenActivityTest.kt b/app/src/androidTest/java/ch/sdp/vibester/activity/BuzzerScreenActivityTest.kt index 618949c0d..25f59625f 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/activity/BuzzerScreenActivityTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/activity/BuzzerScreenActivityTest.kt @@ -16,8 +16,14 @@ 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.BuzzerGameManager import ch.sdp.vibester.helper.TypingGameManager +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.Before import org.junit.Rule @@ -25,15 +31,20 @@ import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) +@HiltAndroidTest class BuzzerScreenActivityTest { - @get:Rule + @get:Rule(order = 0) + var hiltRule = HiltAndroidRule(this) + + @get:Rule(order = 1) val testRule = ActivityScenarioRule( BuzzerScreenActivity::class.java ) @Before fun setUp() { + hiltRule.inject() Intents.init() } diff --git a/app/src/androidTest/java/ch/sdp/vibester/activity/BuzzerSetupActivityTest.kt b/app/src/androidTest/java/ch/sdp/vibester/activity/BuzzerSetupActivityTest.kt index 2375dba4f..af4a75430 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/activity/BuzzerSetupActivityTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/activity/BuzzerSetupActivityTest.kt @@ -18,6 +18,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import ch.sdp.vibester.R import ch.sdp.vibester.api.LastfmMethod import ch.sdp.vibester.helper.BuzzerGameManager +import dagger.hilt.android.testing.HiltAndroidRule +import dagger.hilt.android.testing.HiltAndroidTest import org.hamcrest.Matchers import org.junit.After import org.junit.Assert.assertEquals @@ -27,8 +29,12 @@ import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) +@HiltAndroidTest class BuzzerSetupActivityTest { - @get: Rule + @get:Rule(order = 0) + var hiltRule = HiltAndroidRule(this) + + @get:Rule(order = 1) val activityRule = ActivityScenarioRule(BuzzerSetupActivity::class.java) val mockArray = arrayOf("Player1", "Player2", "Player3", "Player4") @@ -47,6 +53,7 @@ class BuzzerSetupActivityTest { @Before fun setUp() { + hiltRule.inject() Intents.init() } diff --git a/app/src/androidTest/java/ch/sdp/vibester/activity/LyricsBelongGameActivityTest.kt b/app/src/androidTest/java/ch/sdp/vibester/activity/LyricsBelongGameActivityTest.kt index e99ccd207..cc54e45a6 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/activity/LyricsBelongGameActivityTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/activity/LyricsBelongGameActivityTest.kt @@ -15,7 +15,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.rule.GrantPermissionRule import ch.sdp.vibester.R import ch.sdp.vibester.api.LastfmMethod +import ch.sdp.vibester.database.DataGetter import ch.sdp.vibester.helper.TypingGameManager +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.hamcrest.CoreMatchers.not import org.junit.After import org.junit.Assert.assertEquals @@ -26,6 +32,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) +@HiltAndroidTest class LyricsBelongGameActivityTest { private val sleepTime: Long = 5000 @@ -113,7 +120,10 @@ class LyricsBelongGameActivityTest { return gameManager } - @get: Rule + @get:Rule(order = 0) + var hiltRule = HiltAndroidRule(this) + + @get:Rule(order = 1) val activityRule = ActivityScenarioRule(LyricsBelongGameActivity::class.java) @get:Rule @@ -122,6 +132,7 @@ class LyricsBelongGameActivityTest { @Before fun setUp() { + hiltRule.inject() Intents.init() } @@ -129,19 +140,28 @@ class LyricsBelongGameActivityTest { fun clean() { Intents.release() } -/* - @Test - fun elementsShouldBeDisplayedOnCreate() { - onView(withId(R.id.btnSpeak)).check(matches(isDisplayed())) - onView(withId(R.id.progressBarLyrics)).check(matches(isDisplayed())) - } - */ + @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 {} + } + // FIXME: this test fails after implement QR code reader for no reason + /*@Test + fun elementsShouldBeDisplayedOnCreate() { + onView(withId(R.id.btnSpeak)).check(matches(isDisplayed())) + onView(withId(R.id.progressBarLyrics)).check(matches(isDisplayed())) + }*/ @Test fun handleLyricsNoFoundCorrectly() { + createMockInvocation() val gameManager = setGameManager() val intent = Intent( ApplicationProvider.getApplicationContext(), @@ -154,15 +174,16 @@ class LyricsBelongGameActivityTest { } /** FIXME: API takes a lot of time to process this request comment the following lines if this test fail */ -// Thread.sleep(sleepTime) -// onView(withId(R.id.nextSongButton)).check(matches(isDisplayed())) + // Thread.sleep(sleepTime) + // onView(withId(R.id.nextSongButton)).check(matches(isDisplayed())) //song skipped, not consider as wrong -// assertEquals(true, gameManager.getScore() == 0) -// assertEquals(true, gameManager.getWrongSongs().size == 0) + // assertEquals(true, gameManager.getScore() == 0) + // assertEquals(true, gameManager.getWrongSongs().size == 0) } @Test fun shouldUpdateSpeechFromInput() { + createMockInvocation() val intent = Intent( ApplicationProvider.getApplicationContext(), LyricsBelongGameActivity::class.java @@ -171,11 +192,13 @@ class LyricsBelongGameActivityTest { scn.onActivity { activity -> activity.testUpdateSpeechResult("hey") } + onView(withId(R.id.lyricResult)).check(matches(withText("hey"))) } @Test fun nextButtonOnClick() { + createMockInvocation() val gameManager = setGameManager(2) val intent = Intent(ApplicationProvider.getApplicationContext(), LyricsBelongGameActivity::class.java) intent.putExtra("gameManager", gameManager) @@ -194,15 +217,17 @@ class LyricsBelongGameActivityTest { val statVal: ArrayList = arrayListOf() val score = "0" statVal.addAll(arrayOf(score, score, score, score, score)) + Intents.intended(IntentMatchers.hasComponent(GameEndingActivity::class.java.name)) Intents.intended(IntentMatchers.hasExtra("nbIncorrectSong", 2)) Intents.intended(IntentMatchers.hasExtra("str_arr_name", statNames)) Intents.intended(IntentMatchers.hasExtra("str_arr_val", statVal)) } - /* - @Test + // FIXME: this test fails after implement QR code reader for no reason +/* @Test fun btnCheckVisibilityAfterSpeak() { + createMockInvocation() val intent = Intent( ApplicationProvider.getApplicationContext(), LyricsBelongGameActivity::class.java @@ -212,13 +237,14 @@ class LyricsBelongGameActivityTest { scn.onActivity { activity -> activity.testUpdateSpeechResult("hey") } + onView(withId(R.id.lyricMatchButton)).check(matches(withEffectiveVisibility(Visibility.VISIBLE))) - } + }*/ - */ @Test fun getAndCheckLyricsGivesCorrectAnswerWhenMatch() { + createMockInvocation() val gameManager = setGameManager() gameManager.setNextSong() val intent = Intent( @@ -230,14 +256,15 @@ class LyricsBelongGameActivityTest { scn.onActivity { activity -> activity.testGetAndCheckLyrics(ctx, songName, artistName, speechInputCorrect, gameManager) } - //FIXME: API takes a lot of time to process this request - //comment the following lines if this test fail -// Thread.sleep(sleepTime) -// assertEquals(true, gameManager.getScore() == 1) + /*FIXME: API takes a lot of time to process this request + comment the following lines if this test fail*/ + //Thread.sleep(sleepTime) + //assertEquals(true, gameManager.getScore() == 1) } @Test fun checkIntentOnEndingForWrongSong() { + createMockInvocation() val gameManager = setGameManager() gameManager.setNextSong() gameManager.gameSize = 1 @@ -271,6 +298,7 @@ class LyricsBelongGameActivityTest { @Test fun checkIntentOnNextRoundForCorrectSong() { + createMockInvocation() val gameManager = setGameManager(2) gameManager.setNextSong() @@ -285,6 +313,7 @@ class LyricsBelongGameActivityTest { currentArtist = activity.getArtistName() currentSong = activity.getSongName() } + onView(withId(R.id.lyricMatchButton)).check(matches(not(isDisplayed()))) assertEquals(artistName, currentArtist) assertEquals("Monday", currentSong) diff --git a/app/src/main/java/ch/sdp/vibester/activity/GameActivity.kt b/app/src/main/java/ch/sdp/vibester/activity/GameActivity.kt index 5a1a9aed1..6036878f9 100644 --- a/app/src/main/java/ch/sdp/vibester/activity/GameActivity.kt +++ b/app/src/main/java/ch/sdp/vibester/activity/GameActivity.kt @@ -12,22 +12,30 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import ch.sdp.vibester.R import ch.sdp.vibester.api.BitmapGetterApi +import ch.sdp.vibester.auth.FireBaseAuthenticator +import ch.sdp.vibester.database.DataGetter import ch.sdp.vibester.helper.GameManager 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 javax.inject.Inject /** * Common set up for all games (difficulty level, progress bar) * CHECK IF THE DOCS ARE CORRECT OR NOT! */ +@AndroidEntryPoint open class GameActivity : AppCompatActivity() { open val handler = Handler() open var maxTime: Int = 30 var runnable: Runnable? = null + @Inject + lateinit var dataGetter: DataGetter + /** * Sets the countdown timer's maximum(initial) value. */ @@ -124,6 +132,18 @@ open class GameActivity : AppCompatActivity() { return !gameManager.checkGameStatus() || !gameManager.setNextSong() } + /** + * Function to set scores in the end of the game + */ + fun setScores(gameManager: GameManager) { + if(FireBaseAuthenticator.isLoggedIn()){ + 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") + } + } + /** * Function used for testing. Do not call unless it is for that specific purpose. */ diff --git a/app/src/main/java/ch/sdp/vibester/activity/LyricsBelongGameActivity.kt b/app/src/main/java/ch/sdp/vibester/activity/LyricsBelongGameActivity.kt index 1c492907a..f0b55c699 100644 --- a/app/src/main/java/ch/sdp/vibester/activity/LyricsBelongGameActivity.kt +++ b/app/src/main/java/ch/sdp/vibester/activity/LyricsBelongGameActivity.kt @@ -98,7 +98,7 @@ class LyricsBelongGameActivity : GameActivity() { } override fun endRound(gameManager: GameManager, callback: (() -> Unit)?) { - super.endRound(gameManager, null) + super.endRound(gameManager, this::setScores) toggleBtnVisibility(R.id.nextSongButton, true) } @@ -201,10 +201,22 @@ class LyricsBelongGameActivity : GameActivity() { handler.post(runnable!!) } - /** helper functions to test private functions */ + /** + * Function to set scores in the end of the game + */ + private fun setScores() { + if(::gameManager.isInitialized) { + super.setScores(gameManager) + } + } + + /* + * The following functions are helper for testing + */ fun testCheckLyrics(ctx: Context, lyricToBeCheck: String, lyrics: String, gameManager: GameManager) { checkAnswer(ctx, lyricToBeCheck, lyrics, gameManager) } + fun testUpdateSpeechResult(speechInput: String) { updateSpeechResult(speechInput) } 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 ce63dbb8c..41d7b358f 100644 --- a/app/src/main/java/ch/sdp/vibester/activity/ProfileActivity.kt +++ b/app/src/main/java/ch/sdp/vibester/activity/ProfileActivity.kt @@ -156,7 +156,6 @@ class ProfileActivity : AppCompatActivity() { if(name == "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 6955cf68f..309beab2e 100644 --- a/app/src/main/java/ch/sdp/vibester/activity/TypingGameActivity.kt +++ b/app/src/main/java/ch/sdp/vibester/activity/TypingGameActivity.kt @@ -10,31 +10,23 @@ import androidx.core.content.ContextCompat.getColor import androidx.core.widget.addTextChangedListener import ch.sdp.vibester.R import ch.sdp.vibester.api.ItunesMusicApi -import ch.sdp.vibester.auth.FireBaseAuthenticator -import ch.sdp.vibester.database.DataGetter 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) @@ -175,7 +167,7 @@ class TypingGameActivity : GameActivity() { //Create the Listener that is executed if we click on the frame layer frameLay.setOnClickListener { - if(gameIsOn){ + if (gameIsOn) { frameLay.setBackgroundColor(getColor(ctx, R.color.tiffany_blue)) guessLayout.removeAllViews() guessLayout.addView(frameLay) @@ -210,7 +202,7 @@ class TypingGameActivity : GameActivity() { override fun endRound(gameManager: GameManager, callback: (() -> Unit)?) { gameIsOn = false findViewById(R.id.yourGuessET).isEnabled = false - super.endRound(gameManager,this::setScores) + super.endRound(gameManager, this::setScores) toggleNextBtnVisibility(true) } @@ -233,15 +225,13 @@ class TypingGameActivity : GameActivity() { * Function to set scores in the end of the game */ private fun setScores() { - if(::gameManager.isInitialized && FireBaseAuthenticator.isLoggedIn()){ - 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") + if (::gameManager.isInitialized) { + super.setScores(gameManager) } } - /** - * Functions for testing + + /* + * The following functions are helper for testing */ fun testProgressBar(progressTime:Int = 0) { superTestProgressBar(findViewById(R.id.progressBarTyping), progressTime) 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 e01043ee6..732e205a3 100644 --- a/app/src/main/java/ch/sdp/vibester/database/DataGetter.kt +++ b/app/src/main/java/ch/sdp/vibester/database/DataGetter.kt @@ -50,7 +50,7 @@ class DataGetter @Inject constructor() { /** * Update integer value in a subfield based on method sum/best - * @param userID + * @param uid User ID * @param newVal * @param fieldName */ diff --git a/app/src/main/java/ch/sdp/vibester/model/SongList.kt b/app/src/main/java/ch/sdp/vibester/model/SongList.kt index 65b1ec1c7..6c334e457 100644 --- a/app/src/main/java/ch/sdp/vibester/model/SongList.kt +++ b/app/src/main/java/ch/sdp/vibester/model/SongList.kt @@ -1,6 +1,5 @@ package ch.sdp.vibester.model -//import ch.sdp.vibester.api.LastfmHelper import ch.sdp.vibester.api.LastfmMethod import org.json.JSONArray import org.json.JSONObject diff --git a/app/src/main/java/ch/sdp/vibester/user/User.kt b/app/src/main/java/ch/sdp/vibester/user/User.kt index e7cc70bf8..50f41b91c 100644 --- a/app/src/main/java/ch/sdp/vibester/user/User.kt +++ b/app/src/main/java/ch/sdp/vibester/user/User.kt @@ -11,7 +11,7 @@ data class User( var ranking: Int = 0, var uid: String = "", var friends: Map = mapOf() - /* Comment on friend's structure + /** Comment on friend's structure * There is no list structure in the firebase. The most conventional way to push and pull data with * several values in one field was to use it as a map. String is user ID, and Boolean plays a filler role here, can be anything. * */