|
|
|
@ -8,6 +8,8 @@ import com.crm.auth.domain.enums.MenuType; |
|
|
|
import com.crm.auth.mapper.SysRoleMenuMapper; |
|
|
|
import com.crm.auth.service.ISysMenuService; |
|
|
|
import com.crm.base.domain.exception.BusinessErrorException; |
|
|
|
import com.crm.file.api.FileApi; |
|
|
|
import com.crm.file.domain.dto.FileInfoDTO; |
|
|
|
import org.junit.jupiter.api.BeforeEach; |
|
|
|
import org.junit.jupiter.api.DisplayName; |
|
|
|
import org.junit.jupiter.api.Test; |
|
|
|
@ -16,12 +18,16 @@ import org.mockito.ArgumentCaptor; |
|
|
|
import org.mockito.InjectMocks; |
|
|
|
import org.mockito.Mock; |
|
|
|
import org.mockito.junit.jupiter.MockitoExtension; |
|
|
|
import org.springframework.web.multipart.MultipartFile; |
|
|
|
|
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat; |
|
|
|
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
|
|
|
import static org.mockito.ArgumentMatchers.any; |
|
|
|
import static org.mockito.ArgumentMatchers.anyLong; |
|
|
|
import static org.mockito.ArgumentMatchers.anyString; |
|
|
|
import static org.mockito.ArgumentMatchers.eq; |
|
|
|
import static org.mockito.Mockito.*; |
|
|
|
|
|
|
|
/** |
|
|
|
@ -34,6 +40,8 @@ class ResourceServiceImplTest { |
|
|
|
private ISysMenuService sysMenuService; |
|
|
|
@Mock |
|
|
|
private SysRoleMenuMapper sysRoleMenuMapper; |
|
|
|
@Mock |
|
|
|
private FileApi fileApi; |
|
|
|
|
|
|
|
@InjectMocks |
|
|
|
private ResourceServiceImpl resourceService; |
|
|
|
@ -461,6 +469,81 @@ class ResourceServiceImplTest { |
|
|
|
verify(sysRoleMenuMapper).delete(captor.capture()); |
|
|
|
} |
|
|
|
|
|
|
|
// ==================== 图标上传 ====================
|
|
|
|
|
|
|
|
@Test |
|
|
|
@DisplayName("合法 PNG 上传 -> 返回 FileInfoDTO") |
|
|
|
void uploadIcon_legalPng_success() throws Exception { |
|
|
|
MultipartFile file = mock(MultipartFile.class); |
|
|
|
when(file.getOriginalFilename()).thenReturn("icon.png"); |
|
|
|
when(file.getContentType()).thenReturn("image/png"); |
|
|
|
when(file.getBytes()).thenReturn(new byte[100]); |
|
|
|
when(file.getSize()).thenReturn(100L); |
|
|
|
|
|
|
|
FileInfoDTO expected = new FileInfoDTO(); |
|
|
|
expected.setFileId("12345"); |
|
|
|
when(fileApi.upload(any(byte[].class), anyString(), anyString(), eq("resources/icon"))) |
|
|
|
.thenReturn(expected); |
|
|
|
|
|
|
|
FileInfoDTO result = resourceService.uploadIcon(file); |
|
|
|
|
|
|
|
assertThat(result.getFileId()).isEqualTo("12345"); |
|
|
|
verify(fileApi).upload(any(byte[].class), eq("icon.png"), eq("image/png"), eq("resources/icon")); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@DisplayName("非法扩展名(.exe)-> 拒绝") |
|
|
|
void uploadIcon_illegalExtension_rejected() { |
|
|
|
MultipartFile file = mock(MultipartFile.class); |
|
|
|
when(file.isEmpty()).thenReturn(false); |
|
|
|
when(file.getSize()).thenReturn(100L); |
|
|
|
when(file.getOriginalFilename()).thenReturn("virus.exe"); |
|
|
|
|
|
|
|
assertThatThrownBy(() -> resourceService.uploadIcon(file)) |
|
|
|
.isInstanceOf(BusinessErrorException.class) |
|
|
|
.hasMessageContaining("格式"); |
|
|
|
|
|
|
|
verify(fileApi, never()).upload(any(byte[].class), anyString(), anyString(), anyString()); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@DisplayName("无扩展名 -> 拒绝") |
|
|
|
void uploadIcon_noExtension_rejected() { |
|
|
|
MultipartFile file = mock(MultipartFile.class); |
|
|
|
when(file.isEmpty()).thenReturn(false); |
|
|
|
when(file.getSize()).thenReturn(100L); |
|
|
|
when(file.getOriginalFilename()).thenReturn("noext"); |
|
|
|
|
|
|
|
assertThatThrownBy(() -> resourceService.uploadIcon(file)) |
|
|
|
.isInstanceOf(BusinessErrorException.class) |
|
|
|
.hasMessageContaining("格式"); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@DisplayName("超过 500KB -> 拒绝") |
|
|
|
void uploadIcon_exceedsMaxSize_rejected() { |
|
|
|
MultipartFile file = mock(MultipartFile.class); |
|
|
|
when(file.isEmpty()).thenReturn(false); |
|
|
|
when(file.getSize()).thenReturn(600 * 1024L); // 600KB
|
|
|
|
|
|
|
|
assertThatThrownBy(() -> resourceService.uploadIcon(file)) |
|
|
|
.isInstanceOf(BusinessErrorException.class) |
|
|
|
.hasMessageContaining("500"); |
|
|
|
|
|
|
|
verify(fileApi, never()).upload(any(byte[].class), anyString(), anyString(), anyString()); |
|
|
|
} |
|
|
|
|
|
|
|
@Test |
|
|
|
@DisplayName("空文件 -> 拒绝") |
|
|
|
void uploadIcon_emptyFile_rejected() { |
|
|
|
MultipartFile file = mock(MultipartFile.class); |
|
|
|
when(file.isEmpty()).thenReturn(true); |
|
|
|
|
|
|
|
assertThatThrownBy(() -> resourceService.uploadIcon(file)) |
|
|
|
.isInstanceOf(BusinessErrorException.class) |
|
|
|
.hasMessageContaining("空"); |
|
|
|
} |
|
|
|
|
|
|
|
// ==================== 辅助方法 ====================
|
|
|
|
|
|
|
|
private SysMenu buildMenu(Long id, Long parentId, String name, int menuType) { |
|
|
|
|