From 003499018eb8d59e9e08e987708e9a86473c3477 Mon Sep 17 00:00:00 2001
From: jg175 <jg175@hdm-stuttgart.de>
Date: Tue, 20 Feb 2024 15:45:49 +0100
Subject: [PATCH] Add: Tests (Unit and Integrationtests) for MusicPlayer

---
 pom.xml                                       |  11 +-
 .../Controller/Enum/GameState.java            |   3 +-
 .../battlearena/Model/Sound/MusicPlayer.java  |  32 +++--
 .../battlearena/Model/Sound/SoundEffects.java |   5 -
 src/main/java/module-info.java                |   4 +
 src/main/resources/player/appSettings.json    |   2 +-
 .../music/wrongFile/License Information.txt   |  44 +++++++
 src/test/java/MusicPlayerTest.java            | 119 +++++++++++++++++-
 8 files changed, 190 insertions(+), 30 deletions(-)
 create mode 100644 src/main/resources/sound/music/wrongFile/License Information.txt

diff --git a/pom.xml b/pom.xml
index 00cecae4..48360299 100644
--- a/pom.xml
+++ b/pom.xml
@@ -71,11 +71,6 @@
             <version>0.5.0-ALPHA4</version>
         </dependency>
 
-        <!--<dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-core</artifactId>
-            <version>4.3.24.RELEASE</version>
-        </dependency>-->
 
         <dependency>
             <groupId>com.oracle.database.jdbc</groupId>
@@ -102,6 +97,12 @@
             <scope>test</scope>
         </dependency>
 
+        <dependency>
+            <groupId>org.testfx</groupId>
+            <artifactId>testfx-core</artifactId>
+            <version>4.0.18</version>
+        </dependency>
+
     </dependencies>
 
     <build>
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameState.java b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameState.java
index c1e336dc..ae6aecc0 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameState.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Controller/Enum/GameState.java
@@ -8,7 +8,8 @@ public enum GameState {
     LOST(""),
     WON(""),
     PLACEHOLDER("src/main/resources/sound/music/placeholder"),
-    MEMES("src/main/resources/sound/music/memes");
+    MEMES("src/main/resources/sound/music/memes"),
+    TEST("src/main/resources/sound/music/wrongFile");
 
     private String path;
     GameState(String path){
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/MusicPlayer.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/MusicPlayer.java
index f77fa54d..8adefbee 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/MusicPlayer.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/MusicPlayer.java
@@ -2,23 +2,18 @@ package de.hdm_stuttgart.battlearena.Model.Sound;
 
 
 import de.hdm_stuttgart.battlearena.Controller.Enum.GameState;
-import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.AppSettings;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Persistence;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.RuntimeInfo;
-import javafx.application.Platform;
-import javafx.fxml.Initializable;
 import javafx.scene.media.Media;
+import javafx.scene.media.MediaException;
 import javafx.scene.media.MediaPlayer;
-import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.LogManager;
-
+import org.apache.logging.log4j.Logger;
 
 import java.io.IOException;
-import java.net.URL;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.List;
-import java.util.ResourceBundle;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
@@ -32,6 +27,8 @@ public class MusicPlayer{
     private static final MusicPlayer  musicPlayerSingleton = new MusicPlayer();
 
     private final Persistence persistence = Persistence.getInstance();
+
+
     private MediaPlayer mediaPlayer;
     private GameState currentGameState;
     private SoundFileManager fileManager = new SoundFileManager();
@@ -78,12 +75,16 @@ public class MusicPlayer{
                 musicPaths.clear();
 
                 Thread thread = new Thread(() -> {
-                    Media media = new Media(getClass().getResource(resource).toExternalForm());
-                    mediaPlayer = new MediaPlayer(media);
-                    mediaPlayer.setOnEndOfMedia(()->playRandomMusic());
-                    mediaPlayer.setVolume((double) persistence.getSettings().getMusicVolume() / 100);
-                    mediaPlayer.play();
-                    log.info("Music is playing");
+                    try {
+                        Media media = new Media(getClass().getResource(resource).toExternalForm());
+                        mediaPlayer = new MediaPlayer(media);
+                        mediaPlayer.setOnEndOfMedia(() -> playRandomMusic());
+                        mediaPlayer.setVolume((double) persistence.getSettings().getMusicVolume() / 100);
+                        mediaPlayer.play();
+                        log.info("Music is playing");
+                    }catch (MediaException mediaException){
+                       log.warn("unsupported media");
+                    }
                 });
                 thread.setDaemon(true);
                 thread.start();
@@ -108,6 +109,11 @@ public class MusicPlayer{
         return persistence.getSettings().getMusicVolume();
     }
     public ScheduledExecutorService getScheduler(){return scheduler;}
+    public GameState getMusicPlayerGameState(){return currentGameState;}
+
+    public MediaPlayer getMediaPlayer() {
+        return mediaPlayer;
+    }
 
     public static MusicPlayer getInstance(){return musicPlayerSingleton;}
 
diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundEffects.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundEffects.java
index 6460e778..8a403b54 100644
--- a/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundEffects.java
+++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/Sound/SoundEffects.java
@@ -66,8 +66,6 @@ public class SoundEffects {
         });
         sfx.setDaemon(true);
         sfx.start();
-
-
     }
 
 
@@ -78,7 +76,4 @@ public class SoundEffects {
     public int getVolume(){
         return Persistence.getInstance().getSettings().getSfxVolume();
     }
-
-
-
 }
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index c00c6404..69c2210f 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -9,6 +9,7 @@ module gui {
     requires com.oracle.database.jdbc;
     requires java.naming;
 
+
     opens de.hdm_stuttgart.battlearena.Controller to javafx.fxml;
     opens de.hdm_stuttgart.battlearena.Model.DataStorage.Classes to com.google.gson;
     opens de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions to com.google.gson;
@@ -26,4 +27,7 @@ module gui {
     exports de.hdm_stuttgart.battlearena.Controller.Utilities;
     exports de.hdm_stuttgart.battlearena.Model.Multiplayer;
     exports de.hdm_stuttgart.battlearena.Model.Entity.GameplayObjects to javafx.fxml;
+    exports de.hdm_stuttgart.battlearena.Model.Sound;
+    exports de.hdm_stuttgart.battlearena.Model.DataStorage.Classes;
+    exports de.hdm_stuttgart.battlearena.Controller.Enum;
 }
\ No newline at end of file
diff --git a/src/main/resources/player/appSettings.json b/src/main/resources/player/appSettings.json
index 29ddb093..7c4eba52 100644
--- a/src/main/resources/player/appSettings.json
+++ b/src/main/resources/player/appSettings.json
@@ -1,4 +1,4 @@
 {
   "sfxVolume": 16,
-  "musicVolume": 39
+  "musicVolume": 81
 }
\ No newline at end of file
diff --git a/src/main/resources/sound/music/wrongFile/License Information.txt b/src/main/resources/sound/music/wrongFile/License Information.txt
new file mode 100644
index 00000000..66ec28db
--- /dev/null
+++ b/src/main/resources/sound/music/wrongFile/License Information.txt	
@@ -0,0 +1,44 @@
+--------------------
+License Information:
+--------------------
+////////////////////
+--------------------
+Downloaded music:
+--------------------
+--------------------
+Track: Only the Braves
+Music by https://www.fiftysounds.com
+--------------------
+Track: In This Place
+Music by https://www.fiftysounds.com
+--------------------
+Track: Giants
+Music by https://www.fiftysounds.com
+--------------------
+Track: The Awakening
+Music by https://www.fiftysounds.com
+--------------------
+Track: Introspective Demon
+Music by https://www.fiftysounds.com
+--------------------
+////////////////////
+--------------------
+Original music:
+--------------------
+--------------------
+Track: Master_Szene_1
+Artist: Uwe Schuh
+--------------------
+Track: Eclipse of the Lord - Original Soundtrack
+Artist: Maximilian Scherbaum
+--------------------
+Track: Tempest Overture - A BattleArena Medley
+Artist: Maximilian Scherbaum
+Samples: (licenses listed above)
+    - Only the Braves
+    - In This Place
+    - Giants
+    - The Awakening
+    - Introspective Demon
+    - Master_Szene_1
+    - Eclipse of the Lord - Original Soundtrack
\ No newline at end of file
diff --git a/src/test/java/MusicPlayerTest.java b/src/test/java/MusicPlayerTest.java
index b56177a7..e1f7d582 100644
--- a/src/test/java/MusicPlayerTest.java
+++ b/src/test/java/MusicPlayerTest.java
@@ -1,26 +1,135 @@
 import de.hdm_stuttgart.battlearena.Controller.Enum.GameState;
+import de.hdm_stuttgart.battlearena.Main.Driver;
+import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.DatabaseException;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Persistence;
 import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.RuntimeInfo;
 import de.hdm_stuttgart.battlearena.Model.Sound.MusicPlayer;
-import org.apache.logging.log4j.Logger;
+import javafx.application.Application;
+import javafx.application.Platform;
+import javafx.scene.media.MediaPlayer;
+import javafx.stage.Stage;
 import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.testfx.api.FxToolkit;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import static org.testfx.util.WaitForAsyncUtils.sleep;
 
-public class MusicPlayerTest {
+public class MusicPlayerTest extends Application {
     private static final Logger log = LogManager.getLogger(MusicPlayerTest.class);
 
+    Persistence persistence;
     RuntimeInfo runtimeInfo;
     MusicPlayer musicPlayer;
     @BeforeEach
     void setup(){
+    persistence = Persistence.getInstance();
     musicPlayer = MusicPlayer.getInstance();
     runtimeInfo = RuntimeInfo.getInstance();
+
+    runtimeInfo.setGameState(GameState.NONE);
+        try {
+            persistence.loadSettings();
+        } catch (DatabaseException e) {
+            throw new RuntimeException(e);
+        }
+
+        try {
+            FxToolkit.registerPrimaryStage();
+        } catch (TimeoutException e) {
+            throw new RuntimeException(e);
+        }
     }
 
+    @AfterEach
+    void tearDown(){
+        runtimeInfo.setGameState(GameState.NONE);
+        musicPlayer.getScheduler().shutdown();
+        try {
+            FxToolkit.cleanupStages();
+        } catch (TimeoutException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+
     @Test
-    void startGameStateMonitoringTest(){
-        runtimeInfo.setGameState(GameState.MENU);
-        musicPlayer.startGameStateMonitoring();
+    void startMusicTest(){
+        Platform.runLater(()->{
+            musicPlayer.startGameStateMonitoring();
+            runtimeInfo.setGameState(GameState.MENU);
+        });
+
+        sleep(200, TimeUnit.MILLISECONDS);
+
+        MediaPlayer player = musicPlayer.getMediaPlayer();
+        Assertions.assertAll(()->{
+            // Test: Gamestate wird geupdatet in der Runtimeinfo sowie in der MusicPlayer-Klasse
+            Assertions.assertEquals(GameState.MENU, runtimeInfo.getGameState());
+            Assertions.assertEquals(GameState.MENU, musicPlayer.getMusicPlayerGameState());
+            Assertions.assertNotNull(player);
+            Assertions.assertEquals(MediaPlayer.Status.PLAYING, player.getStatus());
+        });
+    }
+
+    @Test
+    void startMusicWithUnrecognisedFile(){
+
+        Assertions.assertAll(()->{
+            Assertions.assertDoesNotThrow(()->{
+                Platform.runLater(()->{
+                    musicPlayer.startGameStateMonitoring();
+                    runtimeInfo.setGameState(GameState.TEST);
+                });
+            });
+            Assertions.assertTrue(musicPlayer.getMediaPlayer() == null);
+        });
+    }
+
+    @Test
+    void MusicPlayerIntegrationTest(){
+        Platform.runLater(()->{
+            musicPlayer.startGameStateMonitoring();
+            runtimeInfo.setGameState(GameState.MENU);
+        });
+        sleep(200, TimeUnit.MILLISECONDS);
+
+        MediaPlayer player = musicPlayer.getMediaPlayer();
+
+        Assertions.assertAll(()->{
+            // Test: Gamestate wird geupdatet in der Runtimeinfo sowie in der MusicPlayer-Klasse
+            Assertions.assertEquals(GameState.MENU, runtimeInfo.getGameState());
+            Assertions.assertEquals(GameState.MENU, musicPlayer.getMusicPlayerGameState());
+            Assertions.assertNotNull(player);
+            Assertions.assertEquals(MediaPlayer.Status.PLAYING, player.getStatus());
+        });
+
+
+        Platform.runLater(()->{
+            runtimeInfo.setGameState(GameState.PLAYING);
+            musicPlayer.setVolume(50);
+        });
+        sleep(1, TimeUnit.SECONDS);
+
+        MediaPlayer mediaPlayer = musicPlayer.getMediaPlayer();
+        Assertions.assertAll(()->{
+            Assertions.assertEquals(GameState.PLAYING, runtimeInfo.getGameState());
+            Assertions.assertEquals(GameState.PLAYING, musicPlayer.getMusicPlayerGameState());
+            Assertions.assertNotNull(mediaPlayer);
+            Assertions.assertEquals(MediaPlayer.Status.PLAYING, mediaPlayer.getStatus());
+            Assertions.assertEquals(50, persistence.getSettings().getMusicVolume());
+            Assertions.assertEquals(0.5, player.getVolume());
+        });
+    }
+
+    @Override
+    public void start(Stage stage) throws Exception {
+        new Driver().start(stage);
     }
 }
-- 
GitLab