完成作业
Some checks failed
autograde-final-vibevault / check-trigger (push) Successful in 11s
autograde-final-vibevault / grade (push) Failing after 44s

This commit is contained in:
liyitian 2025-12-14 17:04:34 +08:00
parent a8e82ee558
commit 503b97815b
3 changed files with 215 additions and 0 deletions

View File

@ -3,8 +3,11 @@ package com.vibevault.repository;
import com.vibevault.model.Playlist; import com.vibevault.model.Playlist;
import com.vibevault.model.User; import com.vibevault.model.User;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.Optional;
import java.util.List; import java.util.List;
/** /**
@ -23,4 +26,8 @@ public interface PlaylistRepository extends JpaRepository<Playlist, Long> {
// [Advanced] 按名称模糊搜索歌单 // [Advanced] 按名称模糊搜索歌单
List<Playlist> findByNameContainingIgnoreCase(String keyword); List<Playlist> findByNameContainingIgnoreCase(String keyword);
// 加载歌单及其包含的歌曲
@Query("SELECT p FROM Playlist p LEFT JOIN FETCH p.songs WHERE p.id = :id")
Optional<Playlist> findByIdWithSongs(Long id);
} }

View File

@ -0,0 +1,103 @@
package com.vibevault.integration;
import com.vibevault.controller.PlaylistController;
import com.vibevault.dto.SongCreateDTO;
import com.vibevault.exception.UnauthorizedException;
import com.vibevault.model.Playlist;
import com.vibevault.model.User;
import com.vibevault.repository.PlaylistRepository;
import com.vibevault.repository.UserRepository;
import com.vibevault.service.PlaylistServiceImpl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
@TestPropertySource(locations = "classpath:application-test.properties")
class PlaylistIntegrationTest {
@Autowired
private PlaylistServiceImpl playlistService;
@Autowired
private PlaylistRepository playlistRepository;
@Autowired
private UserRepository userRepository;
@BeforeEach
void setUp() {
// 清理数据库
playlistRepository.deleteAll();
userRepository.deleteAll();
}
@Test
void testDeletePlaylist_PermissionCheck() {
// 创建所有者用户
User owner = new User("testowner", "password123");
owner.setRole("ROLE_USER");
userRepository.save(owner);
// 创建另一个用户
User otherUser = new User("testuser", "password456");
otherUser.setRole("ROLE_USER");
userRepository.save(otherUser);
// 创建歌单
Playlist playlist = new Playlist("Test Playlist", owner);
playlistRepository.save(playlist);
Long playlistId = playlist.getId();
// 验证歌单已创建
assertEquals(1, playlistRepository.count());
// 所有者应该能够删除歌单
assertDoesNotThrow(() -> playlistService.deletePlaylist(playlistId, "testowner"));
assertEquals(0, playlistRepository.count());
// 重新创建歌单
playlist = new Playlist("Test Playlist", owner);
playlistRepository.save(playlist);
Long newPlaylistId = playlist.getId();
assertEquals(1, playlistRepository.count());
// 非所有者不应该能够删除歌单
assertThrows(UnauthorizedException.class, () -> playlistService.deletePlaylist(newPlaylistId, "testuser"));
assertEquals(1, playlistRepository.count());
}
@Test
void testAddSong_PermissionCheck() {
// 创建所有者用户
User owner = new User("testowner", "password123");
owner.setRole("ROLE_USER");
userRepository.save(owner);
// 创建另一个用户
User otherUser = new User("testuser", "password456");
otherUser.setRole("ROLE_USER");
userRepository.save(otherUser);
// 创建歌单
Playlist playlist = new Playlist("Test Playlist", owner);
playlistRepository.save(playlist);
Long playlistId = playlist.getId();
// 所有者应该能够添加歌曲
SongCreateDTO song = new SongCreateDTO("Test Song", "Test Artist", 180);
assertDoesNotThrow(() -> playlistService.addSongToPlaylist(playlistId, song, "testowner"));
Playlist updatedPlaylist = playlistRepository.findByIdWithSongs(playlistId).orElseThrow();
assertEquals(1, updatedPlaylist.getSongs().size());
// 非所有者不应该能够添加歌曲
SongCreateDTO song2 = new SongCreateDTO("Test Song 2", "Test Artist", 200);
assertThrows(UnauthorizedException.class, () -> playlistService.addSongToPlaylist(playlistId, song2, "testuser"));
updatedPlaylist = playlistRepository.findByIdWithSongs(playlistId).orElseThrow();
assertEquals(1, updatedPlaylist.getSongs().size());
}
}

View File

@ -0,0 +1,105 @@
package com.vibevault.service;
import com.vibevault.exception.UnauthorizedException;
import com.vibevault.model.Playlist;
import com.vibevault.model.User;
import com.vibevault.repository.PlaylistRepository;
import com.vibevault.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.*;
class PlaylistDeleteTest {
@Mock
private PlaylistRepository playlistRepository;
@Mock
private UserRepository userRepository;
@InjectMocks
private PlaylistServiceImpl playlistService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
void testDeletePlaylist_OwnerCanDelete() {
// 创建用户和歌单
User owner = new User("testuser", "password");
owner.setRole("ROLE_USER");
Playlist playlist = new Playlist("Test Playlist", owner);
playlist.setId(1L);
// 模拟用户存储库
when(userRepository.findByUsername("testuser")).thenReturn(Optional.of(owner));
// 模拟歌单存储库
when(playlistRepository.findById(1L)).thenReturn(Optional.of(playlist));
// 所有者应该能够删除自己的歌单不应该抛出异常
playlistService.deletePlaylist(1L, "testuser");
// 验证歌单已被删除
verify(playlistRepository, times(1)).delete(playlist);
}
@Test
void testDeletePlaylist_NonOwnerCannotDelete() {
// 创建所有者用户和歌单
User owner = new User("owner", "password");
owner.setRole("ROLE_USER");
Playlist playlist = new Playlist("Test Playlist", owner);
playlist.setId(1L);
// 创建另一个用户
User otherUser = new User("otheruser", "password");
otherUser.setRole("ROLE_USER");
// 模拟用户存储库
when(userRepository.findByUsername("otheruser")).thenReturn(Optional.of(otherUser));
// 模拟歌单存储库
when(playlistRepository.findById(1L)).thenReturn(Optional.of(playlist));
// 非所有者不应该能够删除歌单应该抛出 UnauthorizedException
assertThrows(UnauthorizedException.class, () -> playlistService.deletePlaylist(1L, "otheruser"));
// 验证歌单没有被删除
verify(playlistRepository, never()).delete(any(Playlist.class));
}
@Test
void testDeletePlaylist_AdminCanDelete() {
// 创建所有者用户和歌单
User owner = new User("owner", "password");
owner.setRole("ROLE_USER");
Playlist playlist = new Playlist("Test Playlist", owner);
playlist.setId(1L);
// 创建管理员用户
User adminUser = new User("admin", "password");
adminUser.setRole("ROLE_ADMIN");
// 模拟用户存储库
when(userRepository.findByUsername("admin")).thenReturn(Optional.of(adminUser));
// 模拟歌单存储库
when(playlistRepository.findById(1L)).thenReturn(Optional.of(playlist));
// 管理员应该能够删除任何歌单不应该抛出异常
playlistService.deletePlaylist(1L, "admin");
// 验证歌单已被删除
verify(playlistRepository, times(1)).delete(playlist);
}
}