diff --git a/app/src/androidTest/java/ch/sdp/vibester/activity/DeleteSongsActivityTest.kt b/app/src/androidTest/java/ch/sdp/vibester/activity/DeleteSongsActivityTest.kt index 4603aa4f4..3f9edafaf 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/activity/DeleteSongsActivityTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/activity/DeleteSongsActivityTest.kt @@ -72,12 +72,17 @@ class DeleteSongsActivityTest { val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext var records = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "records.txt") records.createNewFile() - records.appendText("Testing 1\n") - records.appendText("Testing 2\n") + records.appendText("Song 1 - Artist 1\n") + records.appendText("Song 2 - Artist 2\n") - var testing1 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Testing 1") + var properties = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + properties.createNewFile() + properties.appendText("Song 1 - Artist 1 - Artwork 1 - Preview 1\n") + properties.appendText("Song 2 - Artist 2 - Artwork 2 - Preview 2\n") + + var testing1 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 1 - Artist 1") testing1.createNewFile() - var testing2 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Testing 2") + var testing2 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 2 - Artist 2") testing2.createNewFile() val intent = Intent(ApplicationProvider.getApplicationContext(), DeleteSongsActivity::class.java) @@ -89,9 +94,10 @@ class DeleteSongsActivityTest { } - onView(withId(layout.getChildAt(0).id)).check(matches(withText("TESTING 1"))) - onView(withId(layout.getChildAt(1).id)).check(matches(withText("TESTING 2"))) + onView(withId(layout.getChildAt(0).id)).check(matches(withText("SONG 1 - ARTIST 1"))) + onView(withId(layout.getChildAt(1).id)).check(matches(withText("SONG 2 - ARTIST 2"))) records.delete() + properties.delete() testing1.delete() testing2.delete() } @@ -101,12 +107,17 @@ class DeleteSongsActivityTest { val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext var records = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "records.txt") records.createNewFile() - records.appendText("Testing 1\n") - records.appendText("Testing 2\n") + records.appendText("Song 1 - Artist 1\n") + records.appendText("Song 2 - Artist 2\n") + + var properties = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + properties.createNewFile() + properties.appendText("Song 1 - Artist 1 - Artwork 1 - Preview 1\n") + properties.appendText("Song 2 - Artist 2 - Artwork 2 - Preview 2\n") - var testing1 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Testing 1") + var testing1 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 1 - Artist 1") testing1.createNewFile() - var testing2 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Testing 2") + var testing2 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 2 - Artist 2") testing2.createNewFile() val intent = Intent(ApplicationProvider.getApplicationContext(), DeleteSongsActivity::class.java) @@ -121,9 +132,10 @@ class DeleteSongsActivityTest { assert(!testing1.exists()) assert(testing2.exists()) - onView(withId(layout.getChildAt(0).id)).check(matches(withText("TESTING 2"))) + onView(withId(layout.getChildAt(0).id)).check(matches(withText("SONG 2 - ARTIST 2"))) records.delete() + properties.delete() testing1.delete() testing2.delete() } @@ -133,12 +145,17 @@ class DeleteSongsActivityTest { val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext var records = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "records.txt") records.createNewFile() - records.appendText("Testing 1\n") - records.appendText("Testing 2\n") + records.appendText("Song 1 - Artist 1\n") + records.appendText("Song 2 - Artist 2\n") - var testing1 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Testing 1") + var properties = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + properties.createNewFile() + properties.appendText("Song 1 - Artist 1 - Artwork 1 - Preview 1\n") + properties.appendText("Song 2 - Artist 2 - Artwork 2 - Preview 2\n") + + var testing1 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 1 - Artist 1") testing1.createNewFile() - var testing2 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Testing 2") + var testing2 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 2 - Artist 2") testing2.createNewFile() val intent = Intent(ApplicationProvider.getApplicationContext(), DeleteSongsActivity::class.java) @@ -153,9 +170,10 @@ class DeleteSongsActivityTest { assert(testing1.exists()) assert(!testing2.exists()) - onView(withId(layout.getChildAt(0).id)).check(matches(withText("TESTING 1"))) + onView(withId(layout.getChildAt(0).id)).check(matches(withText("SONG 1 - ARTIST 1"))) records.delete() + properties.delete() testing1.delete() testing2.delete() } @@ -165,12 +183,17 @@ class DeleteSongsActivityTest { val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext var records = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "records.txt") records.createNewFile() - records.appendText("Testing 1\n") - records.appendText("Testing 2\n") + records.appendText("Song 1 - Artist 1\n") + records.appendText("Song 2 - Artist 2\n") + + var properties = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + properties.createNewFile() + properties.appendText("Song 1 - Artist 1 - Artwork 1 - Preview 1\n") + properties.appendText("Song 2 - Artist 2 - Artwork 2 - Preview 2\n") - var testing1 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Testing 1") + var testing1 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 1 - Artist 1") testing1.createNewFile() - var testing2 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Testing 2") + var testing2 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 2 - Artist 2") testing2.createNewFile() val intent = Intent(ApplicationProvider.getApplicationContext(), DeleteSongsActivity::class.java) @@ -189,6 +212,7 @@ class DeleteSongsActivityTest { onView(withId(layout.getChildAt(0).id)).check(matches(withText(R.string.delete_nothing_to_delete))) records.delete() + properties.delete() testing1.delete() testing2.delete() } diff --git a/app/src/androidTest/java/ch/sdp/vibester/activity/DownloadActivityTest.kt b/app/src/androidTest/java/ch/sdp/vibester/activity/DownloadActivityTest.kt index 6bc71fe84..e9d440657 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/activity/DownloadActivityTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/activity/DownloadActivityTest.kt @@ -76,6 +76,12 @@ class DownloadActivityTest { if(records.exists()) { records.delete() } + + val properties = File(activity.applicationContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + assert(!properties.exists()) + if(properties.exists()) { + properties.delete() + } } } diff --git a/app/src/androidTest/java/ch/sdp/vibester/fragment/GameSetupFragmentTest.kt b/app/src/androidTest/java/ch/sdp/vibester/fragment/GameSetupFragmentTest.kt index ebd9cf1e9..34e07cf68 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/fragment/GameSetupFragmentTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/fragment/GameSetupFragmentTest.kt @@ -297,5 +297,13 @@ class GameSetupFragmentTest { onView(withId(R.id.validateSearch)).perform(scrollTo(), click()) } + @Test + fun internetButtonClick() { + onView(withId(R.id.game_setup_has_internet)).check(matches(withText("Internet is on"))) + onView(withId(R.id.game_setup_has_internet)).perform(click()) + onView(withId(R.id.game_setup_has_internet)).check(matches(withText("Internet is off"))) + onView(withId(R.id.game_setup_has_internet)).perform(click()) + onView(withId(R.id.game_setup_has_internet)).check(matches(withText("Internet is on"))) + } } \ No newline at end of file diff --git a/app/src/androidTest/java/ch/sdp/vibester/helper/GameManagerTest.kt b/app/src/androidTest/java/ch/sdp/vibester/helper/GameManagerTest.kt index 402d69baa..b1aa11913 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/helper/GameManagerTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/helper/GameManagerTest.kt @@ -1,8 +1,12 @@ package ch.sdp.vibester.helper +import android.os.Environment +import androidx.test.platform.app.InstrumentationRegistry import ch.sdp.vibester.api.LastfmMethod import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue import org.junit.Test +import java.io.File class GameManagerTest { private fun setGameManager(valid:Boolean = true): GameManager { @@ -85,4 +89,133 @@ class GameManagerTest { assertEquals(gameManager.getCurrentSong().getArtistName().lowercase(), "imagine dragons") assertEquals(gameManager.getCurrentSong().getTrackName().lowercase(), "monday") } + + //OFFLINE TESTS + + private fun offlineTestSetup(): GameManager { + val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext + var records = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "records.txt") + records.createNewFile() + records.appendText("Song 1 - Artist 1\n") + + var properties = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + properties.createNewFile() + properties.appendText("Song 1 - Artist 1 - Artwork 1 - Preview 1\n") + + var testing1 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 1 - Artist 1") + testing1.createNewFile() + var testing2 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 2 - Artist 2") + testing2.createNewFile() + + lateinit var manager: GameManager + val path = context?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + if(path != null) { + manager = createOfflineGameManager(path) + } + return manager + } + + private fun createOfflineGameManager(path: File): GameManager { + val gameManager = GameManager() + if(path != null) { + gameManager.setOffline(path, false) + } + gameManager.setGameSongList("", LastfmMethod.BY_TAG.method) + return gameManager + } + + @Test + fun checkExistsError() { + val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext + val gameManager = offlineTestSetup() + + var properties = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + if(properties.exists()){ + properties.delete() + } + + assert(!gameManager.setNextSong()) + + offlineTestCleanup() + } + + @Test + fun checkEmptyLineError() { + val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext + val gameManager = offlineTestSetup() + + var properties = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + if(properties.exists()) { + properties.delete() + } + properties.createNewFile() + properties.appendText("\n") + + assert(!gameManager.setNextSong()) + + offlineTestCleanup() + } + + @Test + fun checkIncorrectInformationInPropertiesShort() { + val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext + val gameManager = offlineTestSetup() + + var properties = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + if(properties.exists()){ + properties.delete() + } + properties.createNewFile() + properties.appendText("Song 1 - Artist 1 - Preview 1\n") + + assert(!gameManager.setNextSong()) + + offlineTestCleanup() + } + + @Test + fun checkIncorrectInformationInPropertiesLong() { + val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext + val gameManager = offlineTestSetup() + + var properties = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + if(properties.exists()){ + properties.delete() + } + properties.createNewFile() + properties.appendText("Song 1 - Artist 1 - Preview 1 - Artwork 1 - Extra 1\n") + + assert(!gameManager.setNextSong()) + + offlineTestCleanup() + } + + @Test + fun checkCurrentSong() { + val gameManager = offlineTestSetup() + + assert(gameManager.setNextSong()) + + val curSong = gameManager.currentSong + assertEquals(curSong.getTrackName(), "Song 1") + assertEquals(curSong.getArtistName(), "Artist 1") + assertEquals(curSong.getPreviewUrl(), "Preview 1") + assertEquals(curSong.getArtworkUrl(), "Artwork 1") + + + offlineTestCleanup() + } + + private fun offlineTestCleanup() { + val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext + var records = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "records.txt") + var properties = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + var testing1 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 1 - Artist 1") + var testing2 = File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_Song 2 - Artist 2") + + records.delete() + properties.delete() + testing1.delete() + testing2.delete() + } } \ No newline at end of file diff --git a/app/src/androidTest/java/ch/sdp/vibester/model/OfflineSongListTest.kt b/app/src/androidTest/java/ch/sdp/vibester/model/OfflineSongListTest.kt index 37d6a8ae8..e7be83155 100644 --- a/app/src/androidTest/java/ch/sdp/vibester/model/OfflineSongListTest.kt +++ b/app/src/androidTest/java/ch/sdp/vibester/model/OfflineSongListTest.kt @@ -12,7 +12,11 @@ class OfflineSongListTest { @Test fun noSongsAvailableInitialization() { val context = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext - val mySongsList = OfflineSongList(context) + val path = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + lateinit var mySongsList: OfflineSongList + if (path != null) { + mySongsList = OfflineSongList(path) + } val inputSongsList = mutableListOf>() val page = "1" @@ -35,7 +39,11 @@ class OfflineSongListTest { records.createNewFile() records.appendText("bones - imagine dragons\n") - val mySongsList = OfflineSongList(context) + val path = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + lateinit var mySongsList: OfflineSongList + if (path != null) { + mySongsList = OfflineSongList(path) + } val songName = "bones" val artistName = "imagine dragons" diff --git a/app/src/main/java/ch/sdp/vibester/activity/BuzzerScreenActivity.kt b/app/src/main/java/ch/sdp/vibester/activity/BuzzerScreenActivity.kt index ba8ac88f4..b20867a3e 100644 --- a/app/src/main/java/ch/sdp/vibester/activity/BuzzerScreenActivity.kt +++ b/app/src/main/java/ch/sdp/vibester/activity/BuzzerScreenActivity.kt @@ -107,7 +107,11 @@ class BuzzerScreenActivity : GameActivity() { val trackName = gameManager.getCurrentSong().getTrackName() val artist = gameManager.getCurrentSong().getArtistName() findViewById(R.id.songTitle).text= "$trackName - $artist" - Glide.with(ctx).load(gameManager.getCurrentSong().getArtworkUrl()).override(artworkDim, artworkDim).into(findViewById(R.id.songArtwork)) + //Checks if internet is available. If not, skip the loading of the artwork from url. + if(gameManager.getInternet()) { + Glide.with(ctx).load(gameManager.getCurrentSong().getArtworkUrl()).override(artworkDim, artworkDim).into(findViewById(R.id.songArtwork)) + } + gameManager.playSong() checkRunnable() super.barTimer(findViewById(R.id.progressBarBuzzer), ctx, gameManager, ::timeoutAnswer) diff --git a/app/src/main/java/ch/sdp/vibester/activity/DeleteSongsActivity.kt b/app/src/main/java/ch/sdp/vibester/activity/DeleteSongsActivity.kt index 2e54c7a68..2406c3ddb 100644 --- a/app/src/main/java/ch/sdp/vibester/activity/DeleteSongsActivity.kt +++ b/app/src/main/java/ch/sdp/vibester/activity/DeleteSongsActivity.kt @@ -91,11 +91,12 @@ class DeleteSongsActivity : AppCompatActivity() { var currentLine = recordReader.readLine() var button: Button = btn as Button + val buttonText = button.text.toString() - while(currentLine != null) { + while (currentLine != null) { var trimmed = currentLine.trim() - if(trimmed == button.text.toString()) { + if (trimmed == buttonText) { currentLine = recordReader.readLine() continue } @@ -108,15 +109,15 @@ class DeleteSongsActivity : AppCompatActivity() { recordWriter.close() recordReader.close() - if(tempRecords.length() == 0L) { + if (tempRecords.length() == 0L) { createNoSongsView(layout) } records.delete() - if(tempRecords.renameTo(records)) { + if (tempRecords.renameTo(records) && removeFromProperties(buttonText)) { layout.removeView(btn) var songToDelete = File(applicationContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "extract_of_${button.text}") - if(songToDelete.delete()) { + if (songToDelete.delete()) { Toast.makeText(applicationContext, "Song successfully removed!", Toast.LENGTH_LONG).show() return true } @@ -125,6 +126,48 @@ class DeleteSongsActivity : AppCompatActivity() { return false } + /** + * Removes the line correspoding to the song-to-be-deleted from the properties.txt file. + * @param buttonText: Text which contains song name - artist name + */ + private fun removeFromProperties(buttonText: String): Boolean { + var properties = File(applicationContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") + var tempProp = File(applicationContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "tempProp.txt") + + var propReader = BufferedReader(FileReader(properties)) + var propWriter = BufferedWriter(FileWriter(tempProp, true)) + + var currentLine = propReader.readLine() + val buttonSplit = buttonText.trim().split("-") + + /* + * Current line here should be in the form of "song name - artist name - artwork url - preview url. + * We want to tokenize(split) this string into 4 tokens: song name, artist name, artwork url and preview url. + * Comparison between the first two tokens are checked to see whether this line is the one we want or not. + * We write every line on a new file except the one which we want to delete, thus we continue if we match. + */ + while (currentLine != null) { + var trimmed = currentLine.trim() + val split = trimmed.split(" - ") + + if (split[0].trim().lowercase() == buttonSplit[0].trim().lowercase() + && split[1].trim().lowercase() == buttonSplit[1].trim().lowercase()) { + currentLine = propReader.readLine() + continue + } + + propWriter.write(currentLine) + propWriter.newLine() + currentLine = propReader.readLine() + } + + propWriter.close() + propReader.close() + + properties.delete() + return tempProp.renameTo(properties) + } + /** * Handles the creation and initialization of a TextView which is then added to the layout. */ diff --git a/app/src/main/java/ch/sdp/vibester/activity/DownloadActivity.kt b/app/src/main/java/ch/sdp/vibester/activity/DownloadActivity.kt index 09c3d63bf..26c4c380c 100644 --- a/app/src/main/java/ch/sdp/vibester/activity/DownloadActivity.kt +++ b/app/src/main/java/ch/sdp/vibester/activity/DownloadActivity.kt @@ -101,6 +101,7 @@ class DownloadActivity : AppCompatActivity() { val songFuture = ItunesMusicApi.querySong(songName, OkHttpClient(), 1) try { song = Song.singleSong(songFuture.get()) + songName = song.getTrackName().lowercase() + " - " + song.getArtistName().lowercase() checkPermissionsAndDownload() } catch (e: IllegalArgumentException) { alert( @@ -204,16 +205,13 @@ class DownloadActivity : AppCompatActivity() { records.createNewFile() } records.appendText("$songName\n") - /* TODO: OFFLINE recordProperties() - */ } /** * Records the properties of a song. * Order of storage: Track name - artist name - artwork URL - preview URL. */ - /* TODO: OFFLINE private fun recordProperties() { var properties = File(applicationContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "properties.txt") @@ -227,7 +225,6 @@ class DownloadActivity : AppCompatActivity() { val previewURL = song.getPreviewUrl() properties.appendText("$trackName - $artistName - $artworkURL - $previewURL\n") } - */ fun switchToDeleteSongs(view: View) { val intent = Intent(this, DeleteSongsActivity::class.java) diff --git a/app/src/main/java/ch/sdp/vibester/fragment/GameSetupFragment.kt b/app/src/main/java/ch/sdp/vibester/fragment/GameSetupFragment.kt index b7b6c31eb..38f33d808 100644 --- a/app/src/main/java/ch/sdp/vibester/fragment/GameSetupFragment.kt +++ b/app/src/main/java/ch/sdp/vibester/fragment/GameSetupFragment.kt @@ -3,6 +3,7 @@ package ch.sdp.vibester.fragment import android.content.Context import android.content.Intent import android.os.Bundle +import android.os.Environment import android.text.Editable import android.view.LayoutInflater import android.view.View @@ -38,9 +39,8 @@ class GameSetupFragment : Fragment(), View.OnClickListener, AdapterView.OnItemSe var gameSize = R.string.one.toString() var searchArtistEditable: Editable? = null lateinit var gameManager: GameManager - /* TODO: OFFLINE + // TODO: OFFLINE private var hasInternet: Boolean = true - */ override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -60,6 +60,7 @@ class GameSetupFragment : Fragment(), View.OnClickListener, AdapterView.OnItemSe view.findViewById