From 4dc97f8dbb43183e8ea1487380481eb55cbf38e7 Mon Sep 17 00:00:00 2001 From: Andrew DeMaria Date: Wed, 11 Jan 2017 11:11:13 -0700 Subject: [PATCH] Removed synchronized from dao layer and replaced with transactions Also improved tests to be more spring like Signed-off-by: Andrew DeMaria --- libresonic-main/pom.xml | 15 +- .../libresonic/player/boot/Application.java | 22 +- .../org/libresonic/player/dao/AlbumDao.java | 19 +- .../org/libresonic/player/dao/ArtistDao.java | 4 +- .../libresonic/player/dao/BookmarkDao.java | 10 +- .../libresonic/player/dao/MediaFileDao.java | 4 +- .../libresonic/player/dao/PlayQueueDao.java | 14 +- .../org/libresonic/player/dao/PlayerDao.java | 4 +- .../libresonic/player/dao/PlaylistDao.java | 7 +- .../org/libresonic/player/dao/PodcastDao.java | 15 +- .../org/libresonic/player/dao/ShareDao.java | 13 +- .../libresonic/player/dao/TranscodingDao.java | 13 +- .../org/libresonic/player/dao/UserDao.java | 157 +++++++------ .../main/resources/applicationContext-db.xml | 10 +- .../org/libresonic/player/TestCaseUtils.java | 2 - .../player/dao/DaoTestCaseBean2.java | 40 ++++ .../player/dao/InternetRadioDaoTestCase.java | 18 +- .../player/dao/MusicFolderDaoTestCase.java | 19 +- ...rDaoMock.java => MusicFolderTestData.java} | 15 +- .../player/dao/PlayerDaoTestCase.java | 29 ++- .../player/dao/PodcastDaoTestCase.java | 30 ++- .../player/dao/TranscodingDaoTestCase.java | 27 ++- .../player/dao/UserDaoTestCase.java | 47 +++- .../LegacyDatabaseStartupTestCase.java | 54 +++++ .../service/MediaScannerServiceTestCase.java | 81 ++++--- .../player/service/StartupTestCase.java | 32 --- .../player/util/LibresonicHomeRule.java | 14 ++ .../applicationContext-mockSonos.xml | 11 + .../resources/applicationContext-testdb.xml | 14 ++ .../applicationContext-cache.xml | 17 -- .../applicationContext-service.xml | 217 ------------------ 31 files changed, 506 insertions(+), 468 deletions(-) create mode 100644 libresonic-main/src/test/java/org/libresonic/player/dao/DaoTestCaseBean2.java rename libresonic-main/src/test/java/org/libresonic/player/dao/{MusicFolderDaoMock.java => MusicFolderTestData.java} (58%) create mode 100644 libresonic-main/src/test/java/org/libresonic/player/service/LegacyDatabaseStartupTestCase.java delete mode 100644 libresonic-main/src/test/java/org/libresonic/player/service/StartupTestCase.java create mode 100644 libresonic-main/src/test/java/org/libresonic/player/util/LibresonicHomeRule.java create mode 100644 libresonic-main/src/test/resources/applicationContext-mockSonos.xml create mode 100644 libresonic-main/src/test/resources/applicationContext-testdb.xml delete mode 100644 libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-cache.xml delete mode 100644 libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-service.xml diff --git a/libresonic-main/pom.xml b/libresonic-main/pom.xml index ac1fe759..9bc72bed 100644 --- a/libresonic-main/pom.xml +++ b/libresonic-main/pom.xml @@ -253,7 +253,20 @@ junit junit - 4.1 + 4.12 + test + + + + org.springframework + spring-test + test + + + + org.mockito + mockito-core + 2.5.7 test diff --git a/libresonic-main/src/main/java/org/libresonic/player/boot/Application.java b/libresonic-main/src/main/java/org/libresonic/player/boot/Application.java index aa1909e8..bd84a820 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/boot/Application.java +++ b/libresonic-main/src/main/java/org/libresonic/player/boot/Application.java @@ -1,17 +1,15 @@ package org.libresonic.player.boot; -import javax.servlet.Filter; -import javax.servlet.ServletContextListener; import net.sf.ehcache.constructs.web.ShutdownListener; import org.directwebremoting.servlet.DwrServlet; -import org.libresonic.player.filter.BootstrapVerificationFilter; -import org.libresonic.player.filter.ParameterDecodingFilter; -import org.libresonic.player.filter.RESTFilter; -import org.libresonic.player.filter.RequestEncodingFilter; -import org.libresonic.player.filter.ResponseHeaderFilter; +import org.libresonic.player.filter.*; import org.libresonic.player.spring.AdditionalPropertySourceConfigurer; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration; +import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; @@ -20,7 +18,15 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; -@SpringBootApplication(exclude = {JmxAutoConfiguration.class}) +import javax.servlet.Filter; +import javax.servlet.ServletContextListener; + +@SpringBootApplication(exclude = { + JmxAutoConfiguration.class, + JdbcTemplateAutoConfiguration.class, + DataSourceAutoConfiguration.class, + DataSourceTransactionManagerAutoConfiguration.class, + LiquibaseAutoConfiguration.class}) @Configuration @ImportResource(value = {"classpath:/applicationContext-service.xml", "classpath:/applicationContext-cache.xml", diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java index 19644344..913c7ed7 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/AlbumDao.java @@ -19,21 +19,17 @@ */ package org.libresonic.player.dao; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import org.apache.commons.lang.ObjectUtils; -import org.springframework.jdbc.core.RowMapper; - import org.libresonic.player.domain.Album; import org.libresonic.player.domain.MediaFile; import org.libresonic.player.domain.MusicFolder; import org.libresonic.player.util.FileUtil; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.transaction.annotation.Transactional; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; /** * Provides database services for albums. @@ -114,7 +110,8 @@ public class AlbumDao extends AbstractDao { * * @param album The album to create/update. */ - public synchronized void createOrUpdateAlbum(Album album) { + @Transactional + public void createOrUpdateAlbum(Album album) { String sql = "update album set " + "path=?," + "song_count=?," + diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java index df293c91..91658b28 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/ArtistDao.java @@ -24,6 +24,7 @@ import org.libresonic.player.domain.Artist; import org.libresonic.player.domain.MusicFolder; import org.springframework.jdbc.core.RowMapper; +import org.springframework.transaction.annotation.Transactional; import java.sql.ResultSet; import java.sql.SQLException; @@ -91,7 +92,8 @@ public class ArtistDao extends AbstractDao { * * @param artist The artist to create/update. */ - public synchronized void createOrUpdateArtist(Artist artist) { + @Transactional + public void createOrUpdateArtist(Artist artist) { String sql = "update artist set " + "cover_art_path=?," + "album_count=?," + diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java index a4917b55..b006b609 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/BookmarkDao.java @@ -19,14 +19,14 @@ */ package org.libresonic.player.dao; +import org.libresonic.player.domain.Bookmark; import org.springframework.jdbc.core.RowMapper; +import org.springframework.transaction.annotation.Transactional; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import org.libresonic.player.domain.Bookmark; - /** * Provides database services for media file bookmarks. * @@ -62,7 +62,8 @@ public class BookmarkDao extends AbstractDao { /** * Creates or updates a bookmark. If created, the ID of the bookmark will be set by this method. */ - public synchronized void createOrUpdateBookmark(Bookmark bookmark) { + @Transactional + public void createOrUpdateBookmark(Bookmark bookmark) { int n = update("update bookmark set position_millis=?, comment=?, changed=? where media_file_id=? and username=?", bookmark.getPositionMillis(), bookmark.getComment(), bookmark.getChanged(), bookmark.getMediaFileId(), bookmark.getUsername()); @@ -78,7 +79,8 @@ public class BookmarkDao extends AbstractDao { /** * Deletes the bookmark for the given username and media file. */ - public synchronized void deleteBookmark(String username, int mediaFileId) { + @Transactional + public void deleteBookmark(String username, int mediaFileId) { update("delete from bookmark where username=? and media_file_id=?", username, mediaFileId); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java index dd111334..550153da 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/MediaFileDao.java @@ -26,6 +26,7 @@ import org.springframework.jdbc.core.RowMapper; import org.libresonic.player.domain.Genre; import org.libresonic.player.domain.MediaFile; import org.libresonic.player.domain.MusicFolder; +import org.springframework.transaction.annotation.Transactional; import java.sql.ResultSet; import java.sql.SQLException; @@ -129,7 +130,8 @@ public class MediaFileDao extends AbstractDao { * * @param file The media file to create/update. */ - public synchronized void createOrUpdateMediaFile(MediaFile file) { + @Transactional + public void createOrUpdateMediaFile(MediaFile file) { String sql = "update media_file set " + "folder=?," + "type=?," + diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java index 28e32da7..8642fe94 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayQueueDao.java @@ -18,14 +18,14 @@ */ package org.libresonic.player.dao; +import org.libresonic.player.domain.SavedPlayQueue; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.transaction.annotation.Transactional; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import org.springframework.jdbc.core.RowMapper; - -import org.libresonic.player.domain.SavedPlayQueue; - /** * Provides database services for play queues * @@ -37,7 +37,8 @@ public class PlayQueueDao extends AbstractDao { private static final String QUERY_COLUMNS = "id, " + INSERT_COLUMNS; private final RowMapper rowMapper = new PlayQueueMapper(); - public synchronized SavedPlayQueue getPlayQueue(String username) { + @Transactional + public SavedPlayQueue getPlayQueue(String username) { SavedPlayQueue playQueue = queryOne("select " + QUERY_COLUMNS + " from play_queue where username=?", rowMapper, username); if (playQueue == null) { return null; @@ -47,7 +48,8 @@ public class PlayQueueDao extends AbstractDao { return playQueue; } - public synchronized void savePlayQueue(SavedPlayQueue playQueue) { + @Transactional + public void savePlayQueue(SavedPlayQueue playQueue) { update("delete from play_queue where username=?", playQueue.getUsername()); update("insert into play_queue(" + INSERT_COLUMNS + ") values (" + questionMarks(INSERT_COLUMNS) + ")", playQueue.getUsername(), playQueue.getCurrentMediaFileId(), playQueue.getPositionMillis(), diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java index 0754a493..5668bb78 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PlayerDao.java @@ -22,6 +22,7 @@ package org.libresonic.player.dao; import org.libresonic.player.Logger; import org.libresonic.player.domain.*; import org.springframework.jdbc.core.RowMapper; +import org.springframework.transaction.annotation.Transactional; import java.sql.ResultSet; import java.sql.SQLException; @@ -86,7 +87,8 @@ public class PlayerDao extends AbstractDao { * * @param player The player to create. */ - public synchronized void createPlayer(Player player) { + @Transactional + public void createPlayer(Player player) { Integer existingMax = getJdbcTemplate().queryForObject("select max(id) from player", Integer.class); if(existingMax == null) { existingMax = 0; diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java index e653297b..319760b2 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PlaylistDao.java @@ -23,6 +23,7 @@ import org.libresonic.player.Logger; import org.libresonic.player.domain.MediaFile; import org.libresonic.player.domain.Playlist; import org.springframework.jdbc.core.RowMapper; +import org.springframework.transaction.annotation.Transactional; import java.sql.ResultSet; import java.sql.SQLException; @@ -80,7 +81,8 @@ public class PlaylistDao extends AbstractDao { return query("select " + QUERY_COLUMNS + " from playlist", rowMapper); } - public synchronized void createPlaylist(Playlist playlist) { + @Transactional + public void createPlaylist(Playlist playlist) { update("insert into playlist(" + INSERT_COLUMNS + ") values(" + questionMarks(INSERT_COLUMNS) + ")", playlist.getUsername(), playlist.isShared(), playlist.getName(), playlist.getComment(), 0, 0, playlist.getCreated(), playlist.getChanged(), playlist.getImportedFrom()); @@ -115,7 +117,8 @@ public class PlaylistDao extends AbstractDao { update("delete from playlist_user where playlist_id=? and username=?", playlistId, username); } - public synchronized void deletePlaylist(int id) { + @Transactional + public void deletePlaylist(int id) { update("delete from playlist where id=?", id); } diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java index 8d4890bc..6f7b6168 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/PodcastDao.java @@ -19,15 +19,15 @@ */ package org.libresonic.player.dao; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.List; - -import org.springframework.jdbc.core.RowMapper; - import org.libresonic.player.domain.PodcastChannel; import org.libresonic.player.domain.PodcastEpisode; import org.libresonic.player.domain.PodcastStatus; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.transaction.annotation.Transactional; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; /** * Provides database services for Podcast channels and episodes. @@ -51,7 +51,8 @@ public class PodcastDao extends AbstractDao { * @param channel The Podcast channel to create. * @return The ID of the newly created channel. */ - public synchronized int createChannel(PodcastChannel channel) { + @Transactional + public int createChannel(PodcastChannel channel) { String sql = "insert into podcast_channel (" + CHANNEL_INSERT_COLUMNS + ") values (" + questionMarks( CHANNEL_INSERT_COLUMNS) + ")"; update(sql, channel.getUrl(), channel.getTitle(), channel.getDescription(), channel.getImageUrl(), diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java index dc5ab836..0e7a12b6 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/ShareDao.java @@ -19,6 +19,11 @@ */ package org.libresonic.player.dao; +import org.libresonic.player.domain.MusicFolder; +import org.libresonic.player.domain.Share; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.transaction.annotation.Transactional; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collections; @@ -26,11 +31,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.springframework.jdbc.core.RowMapper; - -import org.libresonic.player.domain.MusicFolder; -import org.libresonic.player.domain.Share; - /** * Provides database services for shared media. * @@ -49,7 +49,8 @@ public class ShareDao extends AbstractDao { * * @param share The share to create. The ID of the share will be set by this method. */ - public synchronized void createShare(Share share) { + @Transactional + public void createShare(Share share) { String sql = "insert into share (" + INSERT_COLUMNS + ") values (" + questionMarks(INSERT_COLUMNS) + ")"; update(sql, share.getName(), share.getDescription(), share.getUsername(), share.getCreated(), share.getExpires(), share.getLastVisited(), share.getVisitCount()); diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java index ad7c43e2..b23a06df 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/TranscodingDao.java @@ -19,15 +19,15 @@ */ package org.libresonic.player.dao; +import org.libresonic.player.Logger; +import org.libresonic.player.domain.Transcoding; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.transaction.annotation.Transactional; + import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import org.springframework.jdbc.core.RowMapper; - -import org.libresonic.player.Logger; -import org.libresonic.player.domain.Transcoding; - /** * Provides database services for transcoding configurations. * @@ -82,7 +82,8 @@ public class TranscodingDao extends AbstractDao { * * @param transcoding The transcoding to create. */ - public synchronized void createTranscoding(Transcoding transcoding) { + @Transactional + public void createTranscoding(Transcoding transcoding) { Integer existingMax = getJdbcTemplate().queryForObject("select max(id) from transcoding2", Integer.class); if(existingMax == null) { existingMax = 0; diff --git a/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java b/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java index 37c774e7..cb08ff5d 100644 --- a/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java +++ b/libresonic-main/src/main/java/org/libresonic/player/dao/UserDao.java @@ -23,6 +23,7 @@ import org.libresonic.player.Logger; import org.libresonic.player.domain.*; import org.libresonic.player.util.StringUtil; import org.springframework.jdbc.core.RowMapper; +import org.springframework.transaction.annotation.Transactional; import java.sql.ResultSet; import java.sql.SQLException; @@ -33,6 +34,7 @@ import java.util.List; * * @author Sindre Mehus */ +@Transactional public class UserDao extends AbstractDao { private static final Logger LOG = Logger.getLogger(UserDao.class); @@ -71,7 +73,11 @@ public class UserDao extends AbstractDao { */ public User getUserByName(String username) { String sql = "select " + USER_COLUMNS + " from " + getUserTable() + " where username=?"; - return queryOne(sql, userRowMapper, username); + User user = queryOne(sql, userRowMapper, username); + if(user != null) { + readRoles(user); + } + return user; } /** @@ -82,7 +88,11 @@ public class UserDao extends AbstractDao { */ public User getUserByEmail(String email) { String sql = "select " + USER_COLUMNS + " from " + getUserTable() + " where email=?"; - return queryOne(sql, userRowMapper, email); + User user = queryOne(sql, userRowMapper, email); + if(user != null) { + readRoles(user); + } + return user; } /** @@ -92,7 +102,9 @@ public class UserDao extends AbstractDao { */ public List getAllUsers() { String sql = "select " + USER_COLUMNS + " from " + getUserTable(); - return query(sql, userRowMapper); + List users = query(sql, userRowMapper); + users.forEach(this::readRoles); + return users; } /** @@ -219,86 +231,85 @@ public class UserDao extends AbstractDao { } private void readRoles(User user) { - synchronized (user.getUsername().intern()) { - String sql = "select role_id from user_role where username=?"; - List roles = getJdbcTemplate().queryForList(sql, new Object[]{user.getUsername()}, Integer.class); - for (Object role : roles) { - if (ROLE_ID_ADMIN.equals(role)) { - user.setAdminRole(true); - } else if (ROLE_ID_DOWNLOAD.equals(role)) { - user.setDownloadRole(true); - } else if (ROLE_ID_UPLOAD.equals(role)) { - user.setUploadRole(true); - } else if (ROLE_ID_PLAYLIST.equals(role)) { - user.setPlaylistRole(true); - } else if (ROLE_ID_COVER_ART.equals(role)) { - user.setCoverArtRole(true); - } else if (ROLE_ID_COMMENT.equals(role)) { - user.setCommentRole(true); - } else if (ROLE_ID_PODCAST.equals(role)) { - user.setPodcastRole(true); - } else if (ROLE_ID_STREAM.equals(role)) { - user.setStreamRole(true); - } else if (ROLE_ID_SETTINGS.equals(role)) { - user.setSettingsRole(true); - } else if (ROLE_ID_JUKEBOX.equals(role)) { - user.setJukeboxRole(true); - } else if (ROLE_ID_SHARE.equals(role)) { - user.setShareRole(true); - } else { - LOG.warn("Unknown role: '" + role + '\''); - } + String sql = "select role_id from user_role where username=?"; + List roles = getJdbcTemplate().queryForList(sql, new Object[]{user.getUsername()}, Integer.class); + for (Object role : roles) { + if (ROLE_ID_ADMIN.equals(role)) { + user.setAdminRole(true); + } else if (ROLE_ID_DOWNLOAD.equals(role)) { + user.setDownloadRole(true); + } else if (ROLE_ID_UPLOAD.equals(role)) { + user.setUploadRole(true); + } else if (ROLE_ID_PLAYLIST.equals(role)) { + user.setPlaylistRole(true); + } else if (ROLE_ID_COVER_ART.equals(role)) { + user.setCoverArtRole(true); + } else if (ROLE_ID_COMMENT.equals(role)) { + user.setCommentRole(true); + } else if (ROLE_ID_PODCAST.equals(role)) { + user.setPodcastRole(true); + } else if (ROLE_ID_STREAM.equals(role)) { + user.setStreamRole(true); + } else if (ROLE_ID_SETTINGS.equals(role)) { + user.setSettingsRole(true); + } else if (ROLE_ID_JUKEBOX.equals(role)) { + user.setJukeboxRole(true); + } else if (ROLE_ID_SHARE.equals(role)) { + user.setShareRole(true); + } else { + LOG.warn("Unknown role: '" + role + '\''); } } } private void writeRoles(User user) { - synchronized (user.getUsername().intern()) { - String sql = "delete from user_role where username=?"; - getJdbcTemplate().update(sql, new Object[]{user.getUsername()}); - sql = "insert into user_role (username, role_id) values(?, ?)"; - if (user.isAdminRole()) { - getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_ADMIN}); - } - if (user.isDownloadRole()) { - getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_DOWNLOAD}); - } - if (user.isUploadRole()) { - getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_UPLOAD}); - } - if (user.isPlaylistRole()) { - getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_PLAYLIST}); - } - if (user.isCoverArtRole()) { - getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_COVER_ART}); - } - if (user.isCommentRole()) { - getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_COMMENT}); - } - if (user.isPodcastRole()) { - getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_PODCAST}); - } - if (user.isStreamRole()) { - getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_STREAM}); - } - if (user.isJukeboxRole()) { - getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_JUKEBOX}); - } - if (user.isSettingsRole()) { - getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_SETTINGS}); - } - if (user.isShareRole()) { - getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_SHARE}); - } + String sql = "delete from user_role where username=?"; + getJdbcTemplate().update(sql, new Object[]{user.getUsername()}); + sql = "insert into user_role (username, role_id) values(?, ?)"; + if (user.isAdminRole()) { + getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_ADMIN}); + } + if (user.isDownloadRole()) { + getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_DOWNLOAD}); + } + if (user.isUploadRole()) { + getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_UPLOAD}); + } + if (user.isPlaylistRole()) { + getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_PLAYLIST}); + } + if (user.isCoverArtRole()) { + getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_COVER_ART}); + } + if (user.isCommentRole()) { + getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_COMMENT}); + } + if (user.isPodcastRole()) { + getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_PODCAST}); + } + if (user.isStreamRole()) { + getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_STREAM}); + } + if (user.isJukeboxRole()) { + getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_JUKEBOX}); + } + if (user.isSettingsRole()) { + getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_SETTINGS}); + } + if (user.isShareRole()) { + getJdbcTemplate().update(sql, new Object[]{user.getUsername(), ROLE_ID_SHARE}); } } private class UserRowMapper implements RowMapper { public User mapRow(ResultSet rs, int rowNum) throws SQLException { - User user = new User(rs.getString(1), decrypt(rs.getString(2)), rs.getString(3), rs.getBoolean(4), - rs.getLong(5), rs.getLong(6), rs.getLong(7)); - readRoles(user); - return user; + return new User(rs.getString(1), + decrypt(rs.getString(2)), + rs.getString(3), + rs.getBoolean(4), + rs.getLong(5), + rs.getLong(6), + rs.getLong(7)); } } diff --git a/libresonic-main/src/main/resources/applicationContext-db.xml b/libresonic-main/src/main/resources/applicationContext-db.xml index 81b5bb36..b49a44dd 100644 --- a/libresonic-main/src/main/resources/applicationContext-db.xml +++ b/libresonic-main/src/main/resources/applicationContext-db.xml @@ -1,12 +1,18 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> + + + + + + diff --git a/libresonic-main/src/test/java/org/libresonic/player/TestCaseUtils.java b/libresonic-main/src/test/java/org/libresonic/player/TestCaseUtils.java index 8be3071a..b6f90416 100644 --- a/libresonic-main/src/test/java/org/libresonic/player/TestCaseUtils.java +++ b/libresonic-main/src/test/java/org/libresonic/player/TestCaseUtils.java @@ -15,8 +15,6 @@ import java.util.stream.Collectors; public class TestCaseUtils { - private static final String LIBRESONIC_HOME_FOR_TEST = "/tmp/libresonic"; - private static File libresonicHomeDirForTest = null; /** diff --git a/libresonic-main/src/test/java/org/libresonic/player/dao/DaoTestCaseBean2.java b/libresonic-main/src/test/java/org/libresonic/player/dao/DaoTestCaseBean2.java new file mode 100644 index 00000000..1ed12dab --- /dev/null +++ b/libresonic-main/src/test/java/org/libresonic/player/dao/DaoTestCaseBean2.java @@ -0,0 +1,40 @@ +package org.libresonic.player.dao; + +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.libresonic.player.util.LibresonicHomeRule; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.rules.SpringClassRule; +import org.springframework.test.context.junit4.rules.SpringMethodRule; + +@ContextConfiguration(locations = { + "/applicationContext-service.xml", + "/applicationContext-cache.xml", + "/applicationContext-testdb.xml", + "/applicationContext-mockSonos.xml"}) +public class DaoTestCaseBean2 { + @ClassRule + public static final SpringClassRule classRule = new SpringClassRule() { + LibresonicHomeRule libresonicRule = new LibresonicHomeRule(); + @Override + public Statement apply(Statement base, Description description) { + Statement spring = super.apply(base, description); + return libresonicRule.apply(spring, description); + } + }; + + @Rule + public final SpringMethodRule springMethodRule = new SpringMethodRule(); + + @Autowired + GenericDaoHelper genericDaoHelper; + + + JdbcTemplate getJdbcTemplate() { + return genericDaoHelper.getJdbcTemplate(); + } +} diff --git a/libresonic-main/src/test/java/org/libresonic/player/dao/InternetRadioDaoTestCase.java b/libresonic-main/src/test/java/org/libresonic/player/dao/InternetRadioDaoTestCase.java index f411aab3..8bc4826c 100644 --- a/libresonic-main/src/test/java/org/libresonic/player/dao/InternetRadioDaoTestCase.java +++ b/libresonic-main/src/test/java/org/libresonic/player/dao/InternetRadioDaoTestCase.java @@ -1,20 +1,30 @@ package org.libresonic.player.dao; +import org.junit.Before; +import org.junit.Test; +import org.libresonic.player.domain.InternetRadio; +import org.springframework.beans.factory.annotation.Autowired; + import java.util.Date; -import org.libresonic.player.domain.InternetRadio; +import static org.junit.Assert.assertEquals; /** * Unit test of {@link InternetRadioDao}. * * @author Sindre Mehus */ -public class InternetRadioDaoTestCase extends DaoTestCaseBase { +public class InternetRadioDaoTestCase extends DaoTestCaseBean2 { + + @Autowired + InternetRadioDao internetRadioDao; - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { getJdbcTemplate().execute("delete from internet_radio"); } + @Test public void testCreateInternetRadio() { InternetRadio radio = new InternetRadio("name", "streamUrl", "homePageUrl", true, new Date()); internetRadioDao.createInternetRadio(radio); @@ -23,6 +33,7 @@ public class InternetRadioDaoTestCase extends DaoTestCaseBase { assertInternetRadioEquals(radio, newRadio); } + @Test public void testUpdateInternetRadio() { InternetRadio radio = new InternetRadio("name", "streamUrl", "homePageUrl", true, new Date()); internetRadioDao.createInternetRadio(radio); @@ -39,6 +50,7 @@ public class InternetRadioDaoTestCase extends DaoTestCaseBase { assertInternetRadioEquals(radio, newRadio); } + @Test public void testDeleteInternetRadio() { assertEquals("Wrong number of radios.", 0, internetRadioDao.getAllInternetRadios().size()); diff --git a/libresonic-main/src/test/java/org/libresonic/player/dao/MusicFolderDaoTestCase.java b/libresonic-main/src/test/java/org/libresonic/player/dao/MusicFolderDaoTestCase.java index 173bddea..95818919 100644 --- a/libresonic-main/src/test/java/org/libresonic/player/dao/MusicFolderDaoTestCase.java +++ b/libresonic-main/src/test/java/org/libresonic/player/dao/MusicFolderDaoTestCase.java @@ -19,23 +19,32 @@ */ package org.libresonic.player.dao; +import org.junit.Before; +import org.junit.Test; +import org.libresonic.player.domain.MusicFolder; +import org.springframework.beans.factory.annotation.Autowired; + import java.io.File; import java.util.Date; -import org.libresonic.player.domain.MusicFolder; +import static org.junit.Assert.assertEquals; /** * Unit test of {@link MusicFolderDao}. * * @author Sindre Mehus */ -public class MusicFolderDaoTestCase extends DaoTestCaseBase { +public class MusicFolderDaoTestCase extends DaoTestCaseBean2 { + + @Autowired + MusicFolderDao musicFolderDao; - @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { getJdbcTemplate().execute("delete from music_folder"); } + @Test public void testCreateMusicFolder() { MusicFolder musicFolder = new MusicFolder(new File("path"), "name", true, new Date()); musicFolderDao.createMusicFolder(musicFolder); @@ -44,6 +53,7 @@ public class MusicFolderDaoTestCase extends DaoTestCaseBase { assertMusicFolderEquals(musicFolder, newMusicFolder); } + @Test public void testUpdateMusicFolder() { MusicFolder musicFolder = new MusicFolder(new File("path"), "name", true, new Date()); musicFolderDao.createMusicFolder(musicFolder); @@ -59,6 +69,7 @@ public class MusicFolderDaoTestCase extends DaoTestCaseBase { assertMusicFolderEquals(musicFolder, newMusicFolder); } + @Test public void testDeleteMusicFolder() { assertEquals("Wrong number of music folders.", 0, musicFolderDao.getAllMusicFolders().size()); diff --git a/libresonic-main/src/test/java/org/libresonic/player/dao/MusicFolderDaoMock.java b/libresonic-main/src/test/java/org/libresonic/player/dao/MusicFolderTestData.java similarity index 58% rename from libresonic-main/src/test/java/org/libresonic/player/dao/MusicFolderDaoMock.java rename to libresonic-main/src/test/java/org/libresonic/player/dao/MusicFolderTestData.java index f4127d44..007d0666 100644 --- a/libresonic-main/src/test/java/org/libresonic/player/dao/MusicFolderDaoMock.java +++ b/libresonic-main/src/test/java/org/libresonic/player/dao/MusicFolderTestData.java @@ -7,31 +7,30 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -public class MusicFolderDaoMock extends MusicFolderDao { +public class MusicFolderTestData { private static String baseResources = "/MEDIAS/"; public static String resolveBaseMediaPath() { - String baseDir = MusicFolderDaoMock.class.getResource(baseResources).toString().replace("file:",""); + String baseDir = MusicFolderTestData.class.getResource(baseResources).toString().replace("file:",""); return baseDir; } public static String resolveMusicFolderPath() { - return (MusicFolderDaoMock.resolveBaseMediaPath() + "Music"); + return (MusicFolderTestData.resolveBaseMediaPath() + "Music"); } public static String resolveMusic2FolderPath() { - return (MusicFolderDaoMock.resolveBaseMediaPath() + "Music2"); + return (MusicFolderTestData.resolveBaseMediaPath() + "Music2"); } - @Override - public List getAllMusicFolders() { + public static List getTestMusicFolders() { List liste = new ArrayList<>(); - File musicDir = new File(MusicFolderDaoMock.resolveMusicFolderPath()); + File musicDir = new File(MusicFolderTestData.resolveMusicFolderPath()); MusicFolder musicFolder = new MusicFolder(1,musicDir,"Music",true,new Date()); liste.add(musicFolder); - File music2Dir = new File(MusicFolderDaoMock.resolveMusic2FolderPath()); + File music2Dir = new File(MusicFolderTestData.resolveMusic2FolderPath()); MusicFolder musicFolder2 = new MusicFolder(2,music2Dir,"Music2",true,new Date()); liste.add(musicFolder2); return liste; diff --git a/libresonic-main/src/test/java/org/libresonic/player/dao/PlayerDaoTestCase.java b/libresonic-main/src/test/java/org/libresonic/player/dao/PlayerDaoTestCase.java index c33583fc..5fb44097 100644 --- a/libresonic-main/src/test/java/org/libresonic/player/dao/PlayerDaoTestCase.java +++ b/libresonic-main/src/test/java/org/libresonic/player/dao/PlayerDaoTestCase.java @@ -1,25 +1,34 @@ package org.libresonic.player.dao; -import java.util.Date; -import java.util.List; - +import org.junit.Before; +import org.junit.Test; +import org.libresonic.player.domain.PlayQueue; import org.libresonic.player.domain.Player; import org.libresonic.player.domain.PlayerTechnology; -import org.libresonic.player.domain.PlayQueue; import org.libresonic.player.domain.TranscodeScheme; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.*; /** * Unit test of {@link PlayerDao}. * * @author Sindre Mehus */ -public class PlayerDaoTestCase extends DaoTestCaseBase { +public class PlayerDaoTestCase extends DaoTestCaseBean2 { + + @Autowired + PlayerDao playerDao; - @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { getJdbcTemplate().execute("delete from player"); } + @Test public void testCreatePlayer() { Player player = new Player(); player.setName("name"); @@ -41,6 +50,7 @@ public class PlayerDaoTestCase extends DaoTestCaseBase { assertPlayerEquals(player, newPlayer2); } + @Test public void testDefaultValues() { playerDao.createPlayer(new Player()); Player player = playerDao.getAllPlayers().get(0); @@ -50,6 +60,7 @@ public class PlayerDaoTestCase extends DaoTestCaseBase { assertNull("Player client ID should be null by default.", player.getClientId()); } + @Test public void testIdentity() { Player player = new Player(); @@ -76,6 +87,7 @@ public class PlayerDaoTestCase extends DaoTestCaseBase { assertEquals("Wrong number of players.", 3, playerDao.getAllPlayers().size()); } + @Test public void testPlaylist() { Player player = new Player(); playerDao.createPlayer(player); @@ -87,6 +99,7 @@ public class PlayerDaoTestCase extends DaoTestCaseBase { assertNotSame("Wrong playlist.", playQueue, player.getPlayQueue()); } + @Test public void testGetPlayersForUserAndClientId() { Player player = new Player(); player.setUsername("sindre"); @@ -108,6 +121,7 @@ public class PlayerDaoTestCase extends DaoTestCaseBase { assertPlayerEquals(player, players.get(0)); } + @Test public void testUpdatePlayer() { Player player = new Player(); playerDao.createPlayer(player); @@ -129,6 +143,7 @@ public class PlayerDaoTestCase extends DaoTestCaseBase { assertPlayerEquals(player, newPlayer); } + @Test public void testDeletePlayer() { assertEquals("Wrong number of players.", 0, playerDao.getAllPlayers().size()); diff --git a/libresonic-main/src/test/java/org/libresonic/player/dao/PodcastDaoTestCase.java b/libresonic-main/src/test/java/org/libresonic/player/dao/PodcastDaoTestCase.java index 759bfea3..ad11342f 100644 --- a/libresonic-main/src/test/java/org/libresonic/player/dao/PodcastDaoTestCase.java +++ b/libresonic-main/src/test/java/org/libresonic/player/dao/PodcastDaoTestCase.java @@ -1,24 +1,33 @@ package org.libresonic.player.dao; -import java.util.Date; -import java.util.List; - +import org.junit.Before; +import org.junit.Test; import org.libresonic.player.domain.PodcastChannel; import org.libresonic.player.domain.PodcastEpisode; import org.libresonic.player.domain.PodcastStatus; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.*; /** * Unit test of {@link PodcastDao}. * * @author Sindre Mehus */ -public class PodcastDaoTestCase extends DaoTestCaseBase { +public class PodcastDaoTestCase extends DaoTestCaseBean2 { + + @Autowired + PodcastDao podcastDao; - @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { getJdbcTemplate().execute("delete from podcast_channel"); } + @Test public void testCreateChannel() { PodcastChannel channel = new PodcastChannel("http://foo"); podcastDao.createChannel(channel); @@ -28,6 +37,7 @@ public class PodcastDaoTestCase extends DaoTestCaseBase { assertChannelEquals(channel, newChannel); } + @Test public void testChannelId() { int channelId = podcastDao.createChannel(new PodcastChannel("http://foo")); @@ -42,6 +52,7 @@ public class PodcastDaoTestCase extends DaoTestCaseBase { assertEquals("Error in createChannel.", channelId + 5, podcastDao.createChannel(new PodcastChannel("http://foo"))); } + @Test public void testUpdateChannel() { PodcastChannel channel = new PodcastChannel("http://foo"); podcastDao.createChannel(channel); @@ -61,6 +72,7 @@ public class PodcastDaoTestCase extends DaoTestCaseBase { assertChannelEquals(channel, newChannel); } + @Test public void testDeleteChannel() { assertEquals("Wrong number of channels.", 0, podcastDao.getAllChannels().size()); @@ -78,6 +90,7 @@ public class PodcastDaoTestCase extends DaoTestCaseBase { assertEquals("Wrong number of channels.", 0, podcastDao.getAllChannels().size()); } + @Test public void testCreateEpisode() { int channelId = createChannel(); PodcastEpisode episode = new PodcastEpisode(null, channelId, "http://bar", "path", "title", "description", @@ -89,6 +102,7 @@ public class PodcastDaoTestCase extends DaoTestCaseBase { assertEpisodeEquals(episode, newEpisode); } + @Test public void testGetEpisode() { assertNull("Error in getEpisode()", podcastDao.getEpisode(23)); @@ -102,6 +116,7 @@ public class PodcastDaoTestCase extends DaoTestCaseBase { assertEpisodeEquals(episode, newEpisode); } + @Test public void testGetEpisodes() { int channelId = createChannel(); PodcastEpisode a = new PodcastEpisode(null, channelId, "a", null, null, null, @@ -126,6 +141,7 @@ public class PodcastDaoTestCase extends DaoTestCaseBase { } + @Test public void testUpdateEpisode() { int channelId = createChannel(); PodcastEpisode episode = new PodcastEpisode(null, channelId, "http://bar", null, null, null, @@ -150,6 +166,7 @@ public class PodcastDaoTestCase extends DaoTestCaseBase { assertEpisodeEquals(episode, newEpisode); } + @Test public void testDeleteEpisode() { int channelId = createChannel(); @@ -172,6 +189,7 @@ public class PodcastDaoTestCase extends DaoTestCaseBase { } + @Test public void testCascadingDelete() { int channelId = createChannel(); PodcastEpisode episode = new PodcastEpisode(null, channelId, "http://bar", null, null, null, diff --git a/libresonic-main/src/test/java/org/libresonic/player/dao/TranscodingDaoTestCase.java b/libresonic-main/src/test/java/org/libresonic/player/dao/TranscodingDaoTestCase.java index 70a080aa..728af5d9 100644 --- a/libresonic-main/src/test/java/org/libresonic/player/dao/TranscodingDaoTestCase.java +++ b/libresonic-main/src/test/java/org/libresonic/player/dao/TranscodingDaoTestCase.java @@ -1,22 +1,34 @@ package org.libresonic.player.dao; -import java.util.List; - +import org.junit.Before; +import org.junit.Test; import org.libresonic.player.domain.Player; import org.libresonic.player.domain.Transcoding; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.assertEquals; /** * Unit test of {@link TranscodingDao}. * * @author Sindre Mehus */ -public class TranscodingDaoTestCase extends DaoTestCaseBase { +public class TranscodingDaoTestCase extends DaoTestCaseBean2 { + + @Autowired + TranscodingDao transcodingDao; + + @Autowired + PlayerDao playerDao; - @Override - protected void setUp() throws Exception { + @Before + public void setUp() throws Exception { getJdbcTemplate().execute("delete from transcoding2"); } + @Test public void testCreateTranscoding() { Transcoding transcoding = new Transcoding(null, "name", "sourceFormats", "targetFormat", "step1", "step2", "step3", false); transcodingDao.createTranscoding(transcoding); @@ -25,6 +37,7 @@ public class TranscodingDaoTestCase extends DaoTestCaseBase { assertTranscodingEquals(transcoding, newTranscoding); } + @Test public void testUpdateTranscoding() { Transcoding transcoding = new Transcoding(null, "name", "sourceFormats", "targetFormat", "step1", "step2", "step3", false); transcodingDao.createTranscoding(transcoding); @@ -43,6 +56,7 @@ public class TranscodingDaoTestCase extends DaoTestCaseBase { assertTranscodingEquals(transcoding, newTranscoding); } + @Test public void testDeleteTranscoding() { assertEquals("Wrong number of transcodings.", 0, transcodingDao.getAllTranscodings().size()); @@ -59,6 +73,7 @@ public class TranscodingDaoTestCase extends DaoTestCaseBase { assertEquals("Wrong number of transcodings.", 0, transcodingDao.getAllTranscodings().size()); } + @Test public void testPlayerTranscoding() { Player player = new Player(); playerDao.createPlayer(player); @@ -89,6 +104,7 @@ public class TranscodingDaoTestCase extends DaoTestCaseBase { assertEquals("Wrong number of transcodings.", 0, activeTranscodings.size()); } + @Test public void testCascadingDeletePlayer() { Player player = new Player(); playerDao.createPlayer(player); @@ -105,6 +121,7 @@ public class TranscodingDaoTestCase extends DaoTestCaseBase { assertEquals("Wrong number of transcodings.", 0, activeTranscodings.size()); } + @Test public void testCascadingDeleteTranscoding() { Player player = new Player(); playerDao.createPlayer(player); diff --git a/libresonic-main/src/test/java/org/libresonic/player/dao/UserDaoTestCase.java b/libresonic-main/src/test/java/org/libresonic/player/dao/UserDaoTestCase.java index 8a5eb206..16aab9c5 100644 --- a/libresonic-main/src/test/java/org/libresonic/player/dao/UserDaoTestCase.java +++ b/libresonic-main/src/test/java/org/libresonic/player/dao/UserDaoTestCase.java @@ -1,29 +1,36 @@ package org.libresonic.player.dao; +import org.junit.Before; +import org.junit.Test; import org.libresonic.player.domain.AvatarScheme; import org.libresonic.player.domain.TranscodeScheme; import org.libresonic.player.domain.User; import org.libresonic.player.domain.UserSettings; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.jdbc.core.JdbcTemplate; import java.util.Date; import java.util.Locale; +import static org.junit.Assert.*; + /** * Unit test of {@link UserDao}. * * @author Sindre Mehus */ -public class UserDaoTestCase extends DaoTestCaseBase { +public class UserDaoTestCase extends DaoTestCaseBean2 { + + @Autowired + UserDao userDao; - @Override - protected void setUp() throws Exception { - JdbcTemplate template = getJdbcTemplate(); - template.execute("delete from user_role"); - template.execute("delete from user"); + @Before + public void setUp() throws Exception { + getJdbcTemplate().execute("delete from user_role"); + getJdbcTemplate().execute("delete from user"); } + @Test public void testCreateUser() { User user = new User("sindre", "secret", "sindre@activeobjects.no", false, 1000L, 2000L, 3000L); user.setAdminRole(true); @@ -42,6 +49,28 @@ public class UserDaoTestCase extends DaoTestCaseBase { assertUserEquals(user, newUser); } + @Test + public void testCreateUserTransactionalError() { + User user = new User ("muff1nman", "secret", "noemail") { + @Override + public boolean isPlaylistRole() { + throw new RuntimeException(); + } + }; + + user.setAdminRole(true); + int beforeSize = userDao.getAllUsers().size(); + boolean caughtException = false; + try { + userDao.createUser(user); + } catch (RuntimeException e) { + caughtException = true; + } + assertTrue("It was expected for createUser to throw an exception", caughtException); + assertEquals(beforeSize, userDao.getAllUsers().size()); + } + + @Test public void testUpdateUser() { User user = new User("sindre", "secret", null); user.setAdminRole(true); @@ -81,6 +110,7 @@ public class UserDaoTestCase extends DaoTestCaseBase { assertEquals("Wrong bytes uploaded.", 3, newUser.getBytesUploaded()); } + @Test public void testGetUserByName() { User user = new User("sindre", "secret", null); userDao.createUser(user); @@ -96,6 +126,7 @@ public class UserDaoTestCase extends DaoTestCaseBase { assertNull("Error in getUserByName().", userDao.getUserByName(null)); } + @Test public void testDeleteUser() { assertEquals("Wrong number of users.", 0, userDao.getAllUsers().size()); @@ -112,6 +143,7 @@ public class UserDaoTestCase extends DaoTestCaseBase { assertEquals("Wrong number of users.", 0, userDao.getAllUsers().size()); } + @Test public void testGetRolesForUser() { User user = new User("sindre", "secret", null); user.setAdminRole(true); @@ -130,6 +162,7 @@ public class UserDaoTestCase extends DaoTestCaseBase { assertEquals("Wrong role.", "settings", roles[4]); } + @Test public void testUserSettings() { assertNull("Error in getUserSettings.", userDao.getUserSettings("sindre")); diff --git a/libresonic-main/src/test/java/org/libresonic/player/service/LegacyDatabaseStartupTestCase.java b/libresonic-main/src/test/java/org/libresonic/player/service/LegacyDatabaseStartupTestCase.java new file mode 100644 index 00000000..317689c5 --- /dev/null +++ b/libresonic-main/src/test/java/org/libresonic/player/service/LegacyDatabaseStartupTestCase.java @@ -0,0 +1,54 @@ +package org.libresonic.player.service; + +import org.apache.commons.io.FileUtils; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.libresonic.player.TestCaseUtils; +import org.libresonic.player.util.LibresonicHomeRule; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.rules.SpringClassRule; +import org.springframework.test.context.junit4.rules.SpringMethodRule; + +import java.io.File; + +@ContextConfiguration(locations = { + "/applicationContext-service.xml", + "/applicationContext-cache.xml", + "/applicationContext-testdb.xml", + "/applicationContext-mockSonos.xml"}) +public class LegacyDatabaseStartupTestCase { + + @ClassRule + public static final SpringClassRule classRule = new SpringClassRule() { + LibresonicHomeRule libresonicRule = new LibresonicHomeRule() { + @Override + protected void before() throws Throwable { + super.before(); + String homeParent = TestCaseUtils.libresonicHomePathForTest(); + System.setProperty("libresonic.home", TestCaseUtils.libresonicHomePathForTest()); + TestCaseUtils.cleanLibresonicHomeForTest(); + File dbDirectory = new File(homeParent, "/db"); + FileUtils.forceMkdir(dbDirectory); + org.libresonic.player.util.FileUtils.copyResourcesRecursively(getClass().getResource("/db/pre-liquibase/db"), new File(homeParent)); + } + }; + + @Override + public Statement apply(Statement base, Description description) { + Statement spring = super.apply(base, description); + return libresonicRule.apply(spring, description); + } + }; + + @Rule + public final SpringMethodRule springMethodRule = new SpringMethodRule(); + + @Test + public void testStartup() throws Exception { + System.out.println("Successful startup"); + } + +} diff --git a/libresonic-main/src/test/java/org/libresonic/player/service/MediaScannerServiceTestCase.java b/libresonic-main/src/test/java/org/libresonic/player/service/MediaScannerServiceTestCase.java index 12f76490..89c26fea 100644 --- a/libresonic-main/src/test/java/org/libresonic/player/service/MediaScannerServiceTestCase.java +++ b/libresonic-main/src/test/java/org/libresonic/player/service/MediaScannerServiceTestCase.java @@ -1,17 +1,24 @@ package org.libresonic.player.service; import com.codahale.metrics.ConsoleReporter; -import com.codahale.metrics.JmxReporter; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.Timer; import junit.framework.Assert; -import junit.framework.TestCase; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; import org.libresonic.player.TestCaseUtils; import org.libresonic.player.dao.*; import org.libresonic.player.domain.Album; import org.libresonic.player.domain.Artist; import org.libresonic.player.domain.MediaFile; -import org.springframework.context.ApplicationContext; +import org.libresonic.player.util.LibresonicHomeRule; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.rules.SpringClassRule; +import org.springframework.test.context.junit4.rules.SpringMethodRule; import java.util.List; import java.util.Map; @@ -30,47 +37,59 @@ import java.util.concurrent.TimeUnit; * An empty database is created on the fly. * */ -public class MediaScannerServiceTestCase extends TestCase { - - private static String baseResources = "/org/libresonic/player/service/mediaScannerServiceTestCase/"; +@ContextConfiguration(locations = { + "/applicationContext-service.xml", + "/applicationContext-cache.xml", + "/applicationContext-testdb.xml", + "/applicationContext-mockSonos.xml"}) +public class MediaScannerServiceTestCase { + + @ClassRule + public static final SpringClassRule classRule = new SpringClassRule() { + LibresonicHomeRule libresonicRule = new LibresonicHomeRule(); + @Override + public Statement apply(Statement base, Description description) { + Statement spring = super.apply(base, description); + return libresonicRule.apply(spring, description); + } + }; + + @Rule + public final SpringMethodRule springMethodRule = new SpringMethodRule(); private final MetricRegistry metrics = new MetricRegistry(); + @Autowired + private MediaScannerService mediaScannerService; - private MediaScannerService mediaScannerService = null; - private MediaFileDao mediaFileDao = null; - private MusicFolderDao musicFolderDao = null; - private DaoHelper daoHelper = null; - private MediaFileService mediaFileService = null; - private ArtistDao artistDao = null; - private AlbumDao albumDao = null; - + @Autowired + private MediaFileDao mediaFileDao; - @Override - protected void setUp() throws Exception { - super.setUp(); + @Autowired + private MusicFolderDao musicFolderDao; - System.setProperty("libresonic.home", TestCaseUtils.libresonicHomePathForTest()); + @Autowired + private DaoHelper daoHelper; - TestCaseUtils.cleanLibresonicHomeForTest(); + @Autowired + private MediaFileService mediaFileService; - // load spring context - ApplicationContext context = TestCaseUtils.loadSpringApplicationContext(baseResources); + @Autowired + private ArtistDao artistDao; - mediaScannerService = (MediaScannerService)context.getBean("mediaScannerService"); - mediaFileDao = (MediaFileDao)context.getBean("mediaFileDao"); - musicFolderDao = (MusicFolderDao) context.getBean("musicFolderDao"); - daoHelper = (DaoHelper) context.getBean("daoHelper"); - mediaFileService = (MediaFileService) context.getBean("mediaFileService"); - artistDao = (ArtistDao) context.getBean("artistDao"); - albumDao = (AlbumDao) context.getBean("albumDao"); - } + @Autowired + private AlbumDao albumDao; + @Autowired + private SettingsService settingsService; /** * Tests the MediaScannerService by scanning the test media library into an empty database. */ + @Test public void testScanLibrary() { + MusicFolderTestData.getTestMusicFolders().forEach(musicFolderDao::createMusicFolder); + settingsService.clearMusicFolderCache(); Timer globalTimer = metrics.timer(MetricRegistry.name(MediaScannerServiceTestCase.class, "Timer.global")); @@ -85,10 +104,10 @@ public class MediaScannerServiceTestCase extends TestCase { // Music Folder Music must have 3 children - List listeMusicChildren = mediaFileDao.getChildrenOf(MusicFolderDaoMock.resolveMusicFolderPath()); + List listeMusicChildren = mediaFileDao.getChildrenOf(MusicFolderTestData.resolveMusicFolderPath()); Assert.assertEquals(3,listeMusicChildren.size()); // Music Folder Music2 must have 1 children - List listeMusic2Children = mediaFileDao.getChildrenOf(MusicFolderDaoMock.resolveMusic2FolderPath()); + List listeMusic2Children = mediaFileDao.getChildrenOf(MusicFolderTestData.resolveMusic2FolderPath()); Assert.assertEquals(1,listeMusic2Children.size()); System.out.println("--- List of all artists ---"); diff --git a/libresonic-main/src/test/java/org/libresonic/player/service/StartupTestCase.java b/libresonic-main/src/test/java/org/libresonic/player/service/StartupTestCase.java deleted file mode 100644 index d183399b..00000000 --- a/libresonic-main/src/test/java/org/libresonic/player/service/StartupTestCase.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.libresonic.player.service; - -import junit.framework.TestCase; -import org.apache.commons.io.FileUtils; -import org.libresonic.player.TestCaseUtils; -import org.springframework.context.ApplicationContext; - -import java.io.File; - -public class StartupTestCase extends TestCase { - - private static String baseResources = "/org/libresonic/player/service/mediaScannerServiceTestCase/"; - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public void testStartup() throws Exception { - String homeParent = TestCaseUtils.libresonicHomePathForTest(); - System.setProperty("libresonic.home", TestCaseUtils.libresonicHomePathForTest()); - TestCaseUtils.cleanLibresonicHomeForTest(); - File dbDirectory = new File(homeParent, "/db"); - FileUtils.forceMkdir(dbDirectory); - org.libresonic.player.util.FileUtils.copyResourcesRecursively(getClass().getResource("/db/pre-liquibase/db"), new File(homeParent)); - - // load spring context - ApplicationContext context = TestCaseUtils.loadSpringApplicationContext(baseResources); - - } - -} diff --git a/libresonic-main/src/test/java/org/libresonic/player/util/LibresonicHomeRule.java b/libresonic-main/src/test/java/org/libresonic/player/util/LibresonicHomeRule.java new file mode 100644 index 00000000..c8752ae5 --- /dev/null +++ b/libresonic-main/src/test/java/org/libresonic/player/util/LibresonicHomeRule.java @@ -0,0 +1,14 @@ +package org.libresonic.player.util; + +import org.junit.rules.ExternalResource; +import org.libresonic.player.TestCaseUtils; + +public class LibresonicHomeRule extends ExternalResource { + @Override + protected void before() throws Throwable { + super.before(); + System.setProperty("libresonic.home", TestCaseUtils.libresonicHomePathForTest()); + + TestCaseUtils.cleanLibresonicHomeForTest(); + } +} diff --git a/libresonic-main/src/test/resources/applicationContext-mockSonos.xml b/libresonic-main/src/test/resources/applicationContext-mockSonos.xml new file mode 100644 index 00000000..5f739911 --- /dev/null +++ b/libresonic-main/src/test/resources/applicationContext-mockSonos.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/libresonic-main/src/test/resources/applicationContext-testdb.xml b/libresonic-main/src/test/resources/applicationContext-testdb.xml new file mode 100644 index 00000000..62e9877d --- /dev/null +++ b/libresonic-main/src/test/resources/applicationContext-testdb.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-cache.xml b/libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-cache.xml deleted file mode 100644 index da4c296a..00000000 --- a/libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-cache.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-service.xml b/libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-service.xml deleted file mode 100644 index 167f8bd1..00000000 --- a/libresonic-main/src/test/resources/org/libresonic/player/service/mediaScannerServiceTestCase/applicationContext-service.xml +++ /dev/null @@ -1,217 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -