parent
							
								
									685f4fa7e5
								
							
						
					
					
						commit
						6b4874f33c
					
				| @ -0,0 +1,12 @@ | |||||||
|  | package org.airsonic.player.dao; | ||||||
|  | 
 | ||||||
|  | import org.airsonic.player.domain.PlayQueue; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | public class PlayerDaoPlayQueueFactory { | ||||||
|  | 
 | ||||||
|  |     public PlayQueue createPlayQueue() { | ||||||
|  |         return new PlayQueue(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,14 @@ | |||||||
|  | package org.airsonic.player.service.jukebox; | ||||||
|  | 
 | ||||||
|  | import org.airsonic.player.service.JukeboxLegacySubsonicService; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | import java.io.InputStream; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | public class AudioPlayerFactory { | ||||||
|  | 
 | ||||||
|  |     public AudioPlayer createAudioPlayer(InputStream in, JukeboxLegacySubsonicService jukeboxLegacySubsonicService) throws Exception { | ||||||
|  |         return new AudioPlayer(in, jukeboxLegacySubsonicService); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | package org.airsonic.player.service.jukebox; | ||||||
|  | 
 | ||||||
|  | import com.github.biconou.AudioPlayer.JavaPlayer; | ||||||
|  | import com.github.biconou.AudioPlayer.api.Player; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | public class JavaPlayerFactory { | ||||||
|  | 
 | ||||||
|  |     public Player createJavaPlayer() { | ||||||
|  |         return new JavaPlayer(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Player createJavaPlayer(String mixerName) { | ||||||
|  |         return new JavaPlayer(mixerName); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,59 @@ | |||||||
|  | package org.airsonic.player.api; | ||||||
|  | 
 | ||||||
|  | import org.airsonic.player.TestCaseUtils; | ||||||
|  | import org.airsonic.player.util.HomeRule; | ||||||
|  | import org.junit.BeforeClass; | ||||||
|  | import org.junit.ClassRule; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.test.context.junit4.SpringRunner; | ||||||
|  | import org.springframework.test.web.servlet.MockMvc; | ||||||
|  | 
 | ||||||
|  | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; | ||||||
|  | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; | ||||||
|  | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; | ||||||
|  | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringRunner.class) | ||||||
|  | @SpringBootTest | ||||||
|  | @AutoConfigureMockMvc | ||||||
|  | public class AirsonicRestApiIntTest { | ||||||
|  | 
 | ||||||
|  |     public static final String CLIENT_NAME = "airsonic"; | ||||||
|  |     public static final String AIRSONIC_USER = "admin"; | ||||||
|  |     public static final String AIRSONIC_PASSWORD = "admin"; | ||||||
|  |     public static final String EXPECTED_FORMAT = "json"; | ||||||
|  | 
 | ||||||
|  |     private static String AIRSONIC_API_VERSION; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private MockMvc mvc; | ||||||
|  | 
 | ||||||
|  |     @ClassRule | ||||||
|  |     public static final HomeRule classRule = new HomeRule(); // sets airsonic.home to a temporary dir
 | ||||||
|  | 
 | ||||||
|  |     @BeforeClass | ||||||
|  |     public static void setupClass() { | ||||||
|  |         AIRSONIC_API_VERSION = TestCaseUtils.restApiVersion(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void pingTest() throws Exception { | ||||||
|  |         mvc.perform(get("/rest/ping") | ||||||
|  |                 .param("v", AIRSONIC_API_VERSION) | ||||||
|  |                 .param("c", CLIENT_NAME) | ||||||
|  |                 .param("u", AIRSONIC_USER) | ||||||
|  |                 .param("p", AIRSONIC_PASSWORD) | ||||||
|  |                 .param("f", EXPECTED_FORMAT) | ||||||
|  |                 .contentType(MediaType.APPLICATION_JSON)) | ||||||
|  |                 .andExpect(status().isOk()) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.status").value("ok")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.version").value(AIRSONIC_API_VERSION)) | ||||||
|  |                 .andDo(print()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,279 @@ | |||||||
|  | package org.airsonic.player.api.jukebox; | ||||||
|  | 
 | ||||||
|  | import org.airsonic.player.TestCaseUtils; | ||||||
|  | import org.airsonic.player.dao.*; | ||||||
|  | import org.airsonic.player.domain.*; | ||||||
|  | import org.airsonic.player.service.MediaScannerService; | ||||||
|  | import org.airsonic.player.service.PlayerService; | ||||||
|  | import org.airsonic.player.service.SettingsService; | ||||||
|  | import org.airsonic.player.util.HomeRule; | ||||||
|  | import org.junit.*; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.boot.test.context.TestConfiguration; | ||||||
|  | import org.springframework.context.annotation.Bean; | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.security.test.context.support.WithMockUser; | ||||||
|  | import org.springframework.test.annotation.DirtiesContext; | ||||||
|  | import org.springframework.test.context.junit4.SpringRunner; | ||||||
|  | import org.springframework.test.web.servlet.MockMvc; | ||||||
|  | import org.springframework.test.web.servlet.ResultActions; | ||||||
|  | import org.springframework.test.web.servlet.ResultMatcher; | ||||||
|  | 
 | ||||||
|  | import java.text.SimpleDateFormat; | ||||||
|  | import java.util.Date; | ||||||
|  | import java.util.TimeZone; | ||||||
|  | 
 | ||||||
|  | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  | import static org.mockito.Mockito.*; | ||||||
|  | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; | ||||||
|  | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; | ||||||
|  | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; | ||||||
|  | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringRunner.class) | ||||||
|  | @SpringBootTest | ||||||
|  | @AutoConfigureMockMvc | ||||||
|  | @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) | ||||||
|  | public abstract class AbstractAirsonicRestApiJukeboxIntTest { | ||||||
|  | 
 | ||||||
|  |     @ClassRule | ||||||
|  |     public static final HomeRule classRule = new HomeRule(); // sets airsonic.home to a temporary dir
 | ||||||
|  | 
 | ||||||
|  |     @TestConfiguration | ||||||
|  |     static class Config { | ||||||
|  |         private static class SpiedPlayerDaoPlayQueueFactory extends PlayerDaoPlayQueueFactory { | ||||||
|  |             @Override | ||||||
|  |             public PlayQueue createPlayQueue() { | ||||||
|  |                 return spy(super.createPlayQueue()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @Bean | ||||||
|  |         public PlayerDaoPlayQueueFactory playerDaoPlayQueueFactory() { | ||||||
|  |             return new SpiedPlayerDaoPlayQueueFactory(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected static final String CLIENT_NAME = "airsonic"; | ||||||
|  |     protected static final String JUKEBOX_PLAYER_NAME = CLIENT_NAME + "-jukebox"; | ||||||
|  |     private static final String EXPECTED_FORMAT = "json"; | ||||||
|  |     private static String AIRSONIC_API_VERSION; | ||||||
|  | 
 | ||||||
|  |     private static boolean dataBasePopulated; | ||||||
|  |     private static DaoHelper staticDaoHelper; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     protected PlayerService playerService; | ||||||
|  |     @Autowired | ||||||
|  |     private MockMvc mvc; | ||||||
|  |     @Autowired | ||||||
|  |     private MusicFolderDao musicFolderDao; | ||||||
|  |     @Autowired | ||||||
|  |     private SettingsService settingsService; | ||||||
|  |     @Autowired | ||||||
|  |     private MediaScannerService mediaScannerService; | ||||||
|  |     @Autowired | ||||||
|  |     private PlayerDao playerDao; | ||||||
|  |     @Autowired | ||||||
|  |     private MediaFileDao mediaFileDao; | ||||||
|  |     @Autowired | ||||||
|  |     private DaoHelper daoHelper; | ||||||
|  |     @Autowired | ||||||
|  |     private AlbumDao albumDao; | ||||||
|  |     @Autowired | ||||||
|  |     private ArtistDao artistDao; | ||||||
|  | 
 | ||||||
|  |     private Player testJukeboxPlayer; | ||||||
|  | 
 | ||||||
|  |     @BeforeClass | ||||||
|  |     public static void setupClass() { | ||||||
|  |         AIRSONIC_API_VERSION = TestCaseUtils.restApiVersion(); | ||||||
|  |         dataBasePopulated = false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @AfterClass | ||||||
|  |     public static void cleanDataBase() { | ||||||
|  |         staticDaoHelper.getJdbcTemplate().execute("DROP SCHEMA PUBLIC CASCADE"); | ||||||
|  |         staticDaoHelper = null; | ||||||
|  |         dataBasePopulated = false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Populate test datas in the database only once. | ||||||
|  |      * | ||||||
|  |      * <ul> | ||||||
|  |      *     <li>Creates 2 music folder</li> | ||||||
|  |      *     <li>Scans the music folders</li> | ||||||
|  |      *     <li>Creates a test jukebox player</li> | ||||||
|  |      * </ul> | ||||||
|  |      */ | ||||||
|  |     private void populateDatabase() { | ||||||
|  |         if (!dataBasePopulated) { | ||||||
|  |             staticDaoHelper = daoHelper; | ||||||
|  | 
 | ||||||
|  |             assertThat(musicFolderDao.getAllMusicFolders().size()).isEqualTo(1); | ||||||
|  |             MusicFolderTestData.getTestMusicFolders().forEach(musicFolderDao::createMusicFolder); | ||||||
|  |             settingsService.clearMusicFolderCache(); | ||||||
|  | 
 | ||||||
|  |             TestCaseUtils.execScan(mediaScannerService); | ||||||
|  | 
 | ||||||
|  |             assertThat(playerDao.getAllPlayers().size()).isEqualTo(0); | ||||||
|  |             createTestPlayer(); | ||||||
|  |             assertThat(playerDao.getAllPlayers().size()).isEqualTo(1); | ||||||
|  | 
 | ||||||
|  |             dataBasePopulated = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Before | ||||||
|  |     public void setup() throws Exception { | ||||||
|  |         populateDatabase(); | ||||||
|  | 
 | ||||||
|  |         testJukeboxPlayer = findTestJukeboxPlayer(); | ||||||
|  |         assertThat(testJukeboxPlayer).isNotNull(); | ||||||
|  |         reset(testJukeboxPlayer.getPlayQueue()); | ||||||
|  |         testJukeboxPlayer.getPlayQueue().clear(); | ||||||
|  |         assertThat(testJukeboxPlayer.getPlayQueue().size()).isEqualTo(0); | ||||||
|  |         testJukeboxPlayer.getPlayQueue().addFiles(true, | ||||||
|  |                 mediaFileDao.getSongsForAlbum("_DIR_ Ravel", "Complete Piano Works")); | ||||||
|  |         assertThat(testJukeboxPlayer.getPlayQueue().size()).isEqualTo(2); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected abstract void createTestPlayer(); | ||||||
|  | 
 | ||||||
|  |     private Player findTestJukeboxPlayer() { | ||||||
|  |         return playerDao.getAllPlayers().stream().filter(player -> player.getName().equals(JUKEBOX_PLAYER_NAME)) | ||||||
|  |                 .findFirst().orElseThrow(() -> new RuntimeException("No player found in database")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private String convertDateToString(Date date) { | ||||||
|  |        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.000'Z'"); | ||||||
|  |        formatter.setTimeZone(TimeZone.getTimeZone("UTC")); | ||||||
|  |        return formatter.format(date); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private ResultMatcher playListItem1isCorrect() { | ||||||
|  |         MediaFile mediaFile = testJukeboxPlayer.getPlayQueue().getFile(0); | ||||||
|  |         MediaFile parent = mediaFileDao.getMediaFile(mediaFile.getParentPath()); | ||||||
|  |         Album album = albumDao.getAlbum(mediaFile.getArtist(), mediaFile.getAlbumName()); | ||||||
|  |         Artist artist = artistDao.getArtist(mediaFile.getArtist()); | ||||||
|  |         assertThat(album).isNotNull(); | ||||||
|  |         return result -> { | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].id").value(mediaFile.getId()).match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].parent").value(parent.getId()).match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].isDir").value(false).match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].title").value("01 - Gaspard de la Nuit - i. Ondine").match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].album").value("Complete Piano Works").match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].artist").value("_DIR_ Ravel").match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].coverArt").value(parent.getId()).match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].size").value(45138).match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].contentType").value("audio/mpeg").match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].suffix").value("mp3").match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].duration").value(2).match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].bitRate").value(128).match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].path").value("_DIR_ Ravel/_DIR_ Ravel - Complete Piano Works/01 - Gaspard de la Nuit - i. Ondine.mp3").match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].isVideo").value(false).match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].playCount").isNumber().match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].created").value(convertDateToString(mediaFile.getCreated())).match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].albumId").value(album.getId()).match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].artistId").value(artist.getId()).match(result); | ||||||
|  |             jsonPath("$.subsonic-response.jukeboxPlaylist.entry[0].type").value("music").match(result); | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     @WithMockUser(username = "admin") | ||||||
|  |     public void jukeboxStartActionTest() throws Exception { | ||||||
|  |         // Given
 | ||||||
|  | 
 | ||||||
|  |         // When and Then
 | ||||||
|  |         performStartAction(); | ||||||
|  |         performStatusAction("true"); | ||||||
|  |         performGetAction() | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxPlaylist.currentIndex").value("0")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxPlaylist.playing").value("true")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxPlaylist.gain").value("0.75")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxPlaylist.position").value("0")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxPlaylist.entry").isArray()) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxPlaylist.entry.length()").value(2)) | ||||||
|  |                 .andExpect(playListItem1isCorrect()) | ||||||
|  |                 .andDo(print()); | ||||||
|  | 
 | ||||||
|  |         verify(testJukeboxPlayer.getPlayQueue(), times(2)).setStatus(PlayQueue.Status.PLAYING); | ||||||
|  |         assertThat(testJukeboxPlayer.getPlayQueue().getIndex()).isEqualTo(0); | ||||||
|  |         assertThat(testJukeboxPlayer.getPlayQueue().getStatus()).isEqualTo(PlayQueue.Status.PLAYING); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     @WithMockUser(username = "admin") | ||||||
|  |     public void jukeboxStopActionTest() throws Exception { | ||||||
|  |         // Given
 | ||||||
|  | 
 | ||||||
|  |         // When and Then
 | ||||||
|  |         performStartAction(); | ||||||
|  |         performStatusAction("true"); | ||||||
|  |         performStopAction(); | ||||||
|  |         performStatusAction("false"); | ||||||
|  | 
 | ||||||
|  |         verify(testJukeboxPlayer.getPlayQueue(), times(2)).setStatus(PlayQueue.Status.PLAYING); | ||||||
|  |         verify(testJukeboxPlayer.getPlayQueue(), times(1)).setStatus(PlayQueue.Status.STOPPED); | ||||||
|  |         assertThat(testJukeboxPlayer.getPlayQueue().getIndex()).isEqualTo(0); | ||||||
|  |         assertThat(testJukeboxPlayer.getPlayQueue().getStatus()).isEqualTo(PlayQueue.Status.STOPPED); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void performStatusAction(String expectedPlayingValue) throws Exception { | ||||||
|  |         mvc.perform(get("/rest/jukeboxControl.view") | ||||||
|  |                 .param("v", AIRSONIC_API_VERSION) | ||||||
|  |                 .param("c", CLIENT_NAME) | ||||||
|  |                 .param("f", EXPECTED_FORMAT) | ||||||
|  |                 .param("action", "status") | ||||||
|  |                 .contentType(MediaType.APPLICATION_JSON)) | ||||||
|  |                 .andExpect(status().isOk()) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.status").value("ok")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxStatus.currentIndex").value("0")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxStatus.playing").value(expectedPlayingValue)) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxStatus.position").value("0")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private ResultActions performGetAction() throws Exception { | ||||||
|  |         return mvc.perform(get("/rest/jukeboxControl.view") | ||||||
|  |                 .param("v", AIRSONIC_API_VERSION) | ||||||
|  |                 .param("c", CLIENT_NAME) | ||||||
|  |                 .param("f", EXPECTED_FORMAT) | ||||||
|  |                 .param("action", "get") | ||||||
|  |                 .contentType(MediaType.APPLICATION_JSON)) | ||||||
|  |                 .andExpect(status().isOk()) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.status").value("ok")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void performStopAction() throws Exception { | ||||||
|  |         mvc.perform(get("/rest/jukeboxControl.view") | ||||||
|  |                 .param("v", AIRSONIC_API_VERSION) | ||||||
|  |                 .param("c", CLIENT_NAME) | ||||||
|  |                 .param("f", EXPECTED_FORMAT) | ||||||
|  |                 .param("action", "stop") | ||||||
|  |                 .contentType(MediaType.APPLICATION_JSON)) | ||||||
|  |                 .andExpect(status().isOk()) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.status").value("ok")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxStatus.currentIndex").value("0")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxStatus.playing").value("false")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxStatus.position").value("0")); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void performStartAction() throws Exception { | ||||||
|  |         mvc.perform(get("/rest/jukeboxControl.view") | ||||||
|  |                 .param("v", AIRSONIC_API_VERSION) | ||||||
|  |                 .param("c", CLIENT_NAME) | ||||||
|  |                 .param("f", EXPECTED_FORMAT) | ||||||
|  |                 .param("action", "start") | ||||||
|  |                 .contentType(MediaType.APPLICATION_JSON)) | ||||||
|  |                 .andExpect(status().isOk()) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.status").value("ok")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxStatus.currentIndex").value("0")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxStatus.playing").value("true")) | ||||||
|  |                 .andExpect(jsonPath("$.subsonic-response.jukeboxStatus.position").value("0")); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | package org.airsonic.player.api.jukebox; | ||||||
|  | 
 | ||||||
|  | import com.github.biconou.AudioPlayer.JavaPlayer; | ||||||
|  | import org.airsonic.player.domain.Player; | ||||||
|  | import org.airsonic.player.domain.PlayerTechnology; | ||||||
|  | import org.airsonic.player.service.jukebox.JavaPlayerFactory; | ||||||
|  | import org.junit.Before; | ||||||
|  | import org.springframework.boot.test.mock.mockito.MockBean; | ||||||
|  | 
 | ||||||
|  | import static org.mockito.Mockito.mock; | ||||||
|  | import static org.mockito.Mockito.when; | ||||||
|  | 
 | ||||||
|  | public class AirsonicRestApiJukeboxIntTest extends AbstractAirsonicRestApiJukeboxIntTest { | ||||||
|  | 
 | ||||||
|  |     @MockBean | ||||||
|  |     protected JavaPlayerFactory javaPlayerFactory; | ||||||
|  | 
 | ||||||
|  |     @Before | ||||||
|  |     @Override | ||||||
|  |     public void setup() throws Exception { | ||||||
|  |         super.setup(); | ||||||
|  |         JavaPlayer mockJavaPlayer = mock(JavaPlayer.class); | ||||||
|  |         when(mockJavaPlayer.getPlayingInfos()).thenReturn( () -> 0 ); | ||||||
|  |         when(mockJavaPlayer.getGain()).thenReturn(0.75f); | ||||||
|  |         when(javaPlayerFactory.createJavaPlayer()).thenReturn(mockJavaPlayer); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected void createTestPlayer() { | ||||||
|  |         Player jukeBoxPlayer = new Player(); | ||||||
|  |         jukeBoxPlayer.setName(JUKEBOX_PLAYER_NAME); | ||||||
|  |         jukeBoxPlayer.setUsername("admin"); | ||||||
|  |         jukeBoxPlayer.setClientId(CLIENT_NAME + "-jukebox"); | ||||||
|  |         jukeBoxPlayer.setTechnology(PlayerTechnology.JAVA_JUKEBOX); | ||||||
|  |         playerService.createPlayer(jukeBoxPlayer); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,62 @@ | |||||||
|  | package org.airsonic.player.api.jukebox; | ||||||
|  | 
 | ||||||
|  | import org.airsonic.player.domain.Player; | ||||||
|  | import org.airsonic.player.domain.PlayerTechnology; | ||||||
|  | import org.airsonic.player.service.TranscodingService; | ||||||
|  | import org.airsonic.player.service.jukebox.AudioPlayer; | ||||||
|  | import org.airsonic.player.service.jukebox.AudioPlayerFactory; | ||||||
|  | import org.junit.Before; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.springframework.boot.test.mock.mockito.MockBean; | ||||||
|  | import org.springframework.boot.test.mock.mockito.SpyBean; | ||||||
|  | import org.springframework.security.test.context.support.WithMockUser; | ||||||
|  | 
 | ||||||
|  | import static org.mockito.Matchers.any; | ||||||
|  | import static org.mockito.Mockito.*; | ||||||
|  | 
 | ||||||
|  | public class AirsonicRestApiJukeboxLegacyIntTest extends AirsonicRestApiJukeboxIntTest { | ||||||
|  | 
 | ||||||
|  |     @SpyBean | ||||||
|  |     private TranscodingService transcodingService; | ||||||
|  |     @MockBean | ||||||
|  |     protected AudioPlayerFactory audioPlayerFactory; | ||||||
|  | 
 | ||||||
|  |     private AudioPlayer mockAudioPlayer; | ||||||
|  | 
 | ||||||
|  |     @Before | ||||||
|  |     @Override | ||||||
|  |     public void setup() throws Exception { | ||||||
|  |         super.setup(); | ||||||
|  |         mockAudioPlayer = mock(AudioPlayer.class); | ||||||
|  |         when(audioPlayerFactory.createAudioPlayer(any(), any())).thenReturn(mockAudioPlayer); | ||||||
|  |         doReturn(null).when(transcodingService).getTranscodedInputStream(any()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected final void createTestPlayer() { | ||||||
|  |         Player jukeBoxPlayer = new Player(); | ||||||
|  |         jukeBoxPlayer.setName(JUKEBOX_PLAYER_NAME); | ||||||
|  |         jukeBoxPlayer.setUsername("admin"); | ||||||
|  |         jukeBoxPlayer.setClientId(CLIENT_NAME + "-jukebox"); | ||||||
|  |         jukeBoxPlayer.setTechnology(PlayerTechnology.JUKEBOX); | ||||||
|  |         playerService.createPlayer(jukeBoxPlayer); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     @WithMockUser(username = "admin") | ||||||
|  |     @Override | ||||||
|  |     public void jukeboxStartActionTest() throws Exception { | ||||||
|  |         super.jukeboxStartActionTest(); | ||||||
|  |         verify(mockAudioPlayer).play(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     @WithMockUser(username = "admin") | ||||||
|  |     @Override | ||||||
|  |     public void jukeboxStopActionTest() throws Exception { | ||||||
|  |         super.jukeboxStopActionTest(); | ||||||
|  |         verify(mockAudioPlayer).play(); | ||||||
|  |         verify(mockAudioPlayer).pause(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,41 @@ | |||||||
|  | package org.airsonic.player.service; | ||||||
|  | 
 | ||||||
|  | import org.airsonic.player.domain.Transcoding; | ||||||
|  | import org.airsonic.player.util.HomeRule; | ||||||
|  | import org.junit.ClassRule; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.boot.test.context.SpringBootTest; | ||||||
|  | import org.springframework.boot.test.mock.mockito.SpyBean; | ||||||
|  | import org.springframework.test.context.junit4.SpringRunner; | ||||||
|  | import static org.mockito.Mockito.*; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringRunner.class) | ||||||
|  | @SpringBootTest | ||||||
|  | public class TranscodingServiceIntTest { | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private TranscodingService transcodingService; | ||||||
|  |     @SpyBean | ||||||
|  |     private PlayerService playerService; | ||||||
|  | 
 | ||||||
|  |     @ClassRule | ||||||
|  |     public static final HomeRule classRule = new HomeRule(); // sets airsonic.home to a temporary dir
 | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void createTranscodingTest() { | ||||||
|  |         // Given
 | ||||||
|  |         Transcoding transcoding = new Transcoding(null, | ||||||
|  |                 "test-transcoding", | ||||||
|  |                 "mp3", | ||||||
|  |                 "wav", | ||||||
|  |                 "step1", | ||||||
|  |                 "step2", | ||||||
|  |                 "step3", | ||||||
|  |                 true); | ||||||
|  | 
 | ||||||
|  |         transcodingService.createTranscoding(transcoding); | ||||||
|  |         verify(playerService).getAllPlayers(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | spring.mvc.view.prefix: /WEB-INF/jsp/ | ||||||
|  | spring.mvc.view.suffix: .jsp | ||||||
|  | server.error.includeStacktrace: ALWAYS | ||||||
|  | logging.level.root=WARN | ||||||
|  | logging.level.org.airsonic=INFO | ||||||
|  | logging.level.liquibase=INFO | ||||||
|  | logging.pattern.console=%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p){green} %clr(---){faint} %clr(%-40.40logger{32}){blue} %clr(:){faint} %m%n%wEx | ||||||
|  | logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} %5p --- %-40.40logger{32} : %m%n%wEx | ||||||
|  | DatabaseConfigType=embed | ||||||
|  | DatabaseConfigEmbedDriver=org.hsqldb.jdbcDriver | ||||||
|  | DatabaseConfigEmbedUrl=jdbc:hsqldb:mem:airsonic | ||||||
|  | DatabaseConfigEmbedUsername=sa | ||||||
|  | DatabaseConfigEmbedPassword= | ||||||
					Loading…
					
					
				
		Reference in new issue