package cn.iocoder.yudao.module.infra.service.file;
|
|
import cn.hutool.core.io.resource.ResourceUtil;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
|
import jakarta.annotation.Resource;
|
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.Test;
|
import org.springframework.context.annotation.Import;
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
|
import java.time.LocalDateTime;
|
import java.util.concurrent.atomic.AtomicReference;
|
|
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
|
import static org.junit.jupiter.api.Assertions.*;
|
import static org.mockito.ArgumentMatchers.same;
|
import static org.mockito.Mockito.*;
|
|
@Import({FileServiceImpl.class})
|
public class FileServiceImplTest extends BaseDbUnitTest {
|
|
@Resource
|
private FileServiceImpl fileService;
|
|
@Resource
|
private FileMapper fileMapper;
|
|
@MockitoBean
|
private FileConfigService fileConfigService;
|
|
@BeforeEach
|
public void setUp() {
|
FileServiceImpl.PATH_PREFIX_DATE_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_AS_DIRECTORY = true;
|
}
|
|
@Test
|
public void testGetFilePage() {
|
// mock 数据
|
FileDO dbFile = randomPojo(FileDO.class, o -> { // 等会查询到
|
o.setPath("yunai");
|
o.setType("image/jpg");
|
o.setCreateTime(buildTime(2021, 1, 15));
|
});
|
fileMapper.insert(dbFile);
|
// 测试 path 不匹配
|
fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> o.setPath("tudou")));
|
// 测试 type 不匹配
|
fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> {
|
o.setType("image/png");
|
}));
|
// 测试 createTime 不匹配
|
fileMapper.insert(ObjectUtils.cloneIgnoreId(dbFile, o -> {
|
o.setCreateTime(buildTime(2020, 1, 15));
|
}));
|
// 准备参数
|
FilePageReqVO reqVO = new FilePageReqVO();
|
reqVO.setPath("yunai");
|
reqVO.setType("jp");
|
reqVO.setCreateTime((new LocalDateTime[]{buildTime(2021, 1, 10), buildTime(2021, 1, 20)}));
|
|
// 调用
|
PageResult<FileDO> pageResult = fileService.getFilePage(reqVO);
|
// 断言
|
assertEquals(1, pageResult.getTotal());
|
assertEquals(1, pageResult.getList().size());
|
AssertUtils.assertPojoEquals(dbFile, pageResult.getList().get(0));
|
}
|
|
/**
|
* content、name、directory、type 都非空
|
*/
|
@Test
|
public void testCreateFile_success_01() throws Exception {
|
// 准备参数
|
byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
|
String name = "单测文件名";
|
String directory = randomString();
|
String type = "image/jpeg";
|
// mock Master 文件客户端
|
FileClient client = mock(FileClient.class);
|
when(fileConfigService.getMasterFileClient()).thenReturn(client);
|
String url = randomString();
|
AtomicReference<String> pathRef = new AtomicReference<>();
|
when(client.upload(same(content), argThat(path -> {
|
assertTrue(path.matches(directory + "/\\d{8}/\\d+/" + name + ".jpg"));
|
pathRef.set(path);
|
return true;
|
}), eq(type))).thenReturn(url);
|
when(client.getId()).thenReturn(10L);
|
// 调用
|
String result = fileService.createFile(content, name, directory, type);
|
// 断言
|
assertEquals(result, url);
|
// 校验数据
|
FileDO file = fileMapper.selectOne(FileDO::getUrl, url);
|
assertEquals(10L, file.getConfigId());
|
assertEquals(pathRef.get(), file.getPath());
|
assertEquals(url, file.getUrl());
|
assertEquals(type, file.getType());
|
assertEquals(content.length, file.getSize());
|
}
|
|
/**
|
* content 非空,其它都空
|
*/
|
@Test
|
public void testCreateFile_success_02() throws Exception {
|
// 准备参数
|
byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
|
// mock Master 文件客户端
|
String type = "image/jpeg";
|
FileClient client = mock(FileClient.class);
|
when(fileConfigService.getMasterFileClient()).thenReturn(client);
|
String url = randomString();
|
AtomicReference<String> pathRef = new AtomicReference<>();
|
when(client.upload(same(content), argThat(path -> {
|
assertTrue(path.matches("\\d{8}/\\d+/6318848e882d8a7e7e82789d87608f684ee52d41966bfc8cad3ce15aad2b970e\\.jpg"));
|
pathRef.set(path);
|
return true;
|
}), eq(type))).thenReturn(url);
|
when(client.getId()).thenReturn(10L);
|
// 调用
|
String result = fileService.createFile(content, null, null, null);
|
// 断言
|
assertEquals(result, url);
|
// 校验数据
|
FileDO file = fileMapper.selectOne(FileDO::getUrl, url);
|
assertEquals(10L, file.getConfigId());
|
assertEquals(pathRef.get(), file.getPath());
|
assertEquals(url, file.getUrl());
|
assertEquals(type, file.getType());
|
assertEquals(content.length, file.getSize());
|
}
|
|
@Test
|
public void testDeleteFile_success() throws Exception {
|
// mock 数据
|
FileDO dbFile = randomPojo(FileDO.class, o -> o.setConfigId(10L).setPath("tudou.jpg"));
|
fileMapper.insert(dbFile);// @Sql: 先插入出一条存在的数据
|
// mock Master 文件客户端
|
FileClient client = mock(FileClient.class);
|
when(fileConfigService.getFileClient(eq(10L))).thenReturn(client);
|
// 准备参数
|
Long id = dbFile.getId();
|
|
// 调用
|
fileService.deleteFile(id);
|
// 校验数据不存在了
|
assertNull(fileMapper.selectById(id));
|
// 校验调用
|
verify(client).delete(eq("tudou.jpg"));
|
}
|
|
@Test
|
public void testDeleteFile_notExists() {
|
// 准备参数
|
Long id = randomLongId();
|
|
// 调用, 并断言异常
|
assertServiceException(() -> fileService.deleteFile(id), FILE_NOT_EXISTS);
|
}
|
|
@Test
|
public void testGetFileContent() throws Exception {
|
// 准备参数
|
Long configId = 10L;
|
String path = "tudou.jpg";
|
// mock 方法
|
FileClient client = mock(FileClient.class);
|
when(fileConfigService.getFileClient(eq(10L))).thenReturn(client);
|
byte[] content = new byte[]{};
|
when(client.getContent(eq("tudou.jpg"))).thenReturn(content);
|
|
// 调用
|
byte[] result = fileService.getFileContent(configId, path);
|
// 断言
|
assertSame(result, content);
|
}
|
|
@Test
|
public void testGenerateUploadPath_AllEnabled() {
|
// 准备参数
|
String name = "test.jpg";
|
String directory = "avatar";
|
FileServiceImpl.PATH_PREFIX_DATE_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true;
|
|
// 调用
|
String path = fileService.generateUploadPath(name, directory);
|
|
// 断言
|
// 格式为:avatar/yyyyMMdd/{时间戳+随机数}/test.jpg
|
assertTrue(path.startsWith(directory + "/"));
|
// 包含日期格式:8 位数字,如 20240517
|
assertTrue(path.matches(directory + "/\\d{8}/\\d+/test\\.jpg"));
|
}
|
|
@Test
|
public void testGenerateUploadPath_PrefixEnabled_SuffixDisabled() {
|
// 准备参数
|
String name = "test.jpg";
|
String directory = "avatar";
|
FileServiceImpl.PATH_PREFIX_DATE_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = false;
|
|
// 调用
|
String path = fileService.generateUploadPath(name, directory);
|
|
// 断言
|
// 格式为:avatar/yyyyMMdd/test.jpg
|
assertTrue(path.startsWith(directory + "/"));
|
// 包含日期格式:8 位数字,如 20240517
|
assertTrue(path.matches(directory + "/\\d{8}/test\\.jpg"));
|
}
|
|
@Test
|
public void testGenerateUploadPath_PrefixDisabled_SuffixEnabled() {
|
// 准备参数
|
String name = "test.jpg";
|
String directory = "avatar";
|
FileServiceImpl.PATH_PREFIX_DATE_ENABLE = false;
|
FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true;
|
|
// 调用
|
String path = fileService.generateUploadPath(name, directory);
|
|
// 断言
|
// 格式为:avatar/{时间戳+随机数}/test.jpg
|
assertTrue(path.startsWith(directory + "/"));
|
assertTrue(path.matches(directory + "/\\d+/test\\.jpg"));
|
}
|
|
@Test
|
public void testGenerateUploadPath_AllDisabled() {
|
// 准备参数
|
String name = "test.jpg";
|
String directory = "avatar";
|
FileServiceImpl.PATH_PREFIX_DATE_ENABLE = false;
|
FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = false;
|
|
// 调用
|
String path = fileService.generateUploadPath(name, directory);
|
|
// 断言
|
// 格式为:avatar/test.jpg
|
assertEquals(directory + "/" + name, path);
|
}
|
|
@Test
|
public void testGenerateUploadPath_NoExtension() {
|
// 准备参数
|
String name = "test";
|
String directory = "avatar";
|
FileServiceImpl.PATH_PREFIX_DATE_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true;
|
|
// 调用
|
String path = fileService.generateUploadPath(name, directory);
|
|
// 断言
|
// 格式为:avatar/yyyyMMdd/{时间戳+随机数}/test
|
assertTrue(path.startsWith(directory + "/"));
|
assertTrue(path.matches(directory + "/\\d{8}/\\d+/test"));
|
}
|
|
@Test
|
public void testGenerateUploadPath_DirectoryNull() {
|
// 准备参数
|
String name = "test.jpg";
|
String directory = null;
|
FileServiceImpl.PATH_PREFIX_DATE_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true;
|
|
// 调用
|
String path = fileService.generateUploadPath(name, directory);
|
|
// 断言
|
// 格式为:yyyyMMdd/{时间戳+随机数}/test.jpg
|
assertTrue(path.matches("\\d{8}/\\d+/test\\.jpg"));
|
}
|
|
@Test
|
public void testGenerateUploadPath_SuffixAsName_AllEnabled() {
|
// 准备参数
|
String name = "test.jpg";
|
String directory = "avatar";
|
FileServiceImpl.PATH_PREFIX_DATE_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_AS_DIRECTORY = false;
|
|
// 调用
|
String path = fileService.generateUploadPath(name, directory);
|
|
// 断言
|
// 格式为:avatar/yyyyMMdd/test_{时间戳+随机数}.jpg
|
assertTrue(path.matches(directory + "/\\d{8}/test_\\d+\\.jpg"));
|
}
|
|
@Test
|
public void testGenerateUploadPath_SuffixAsName_PrefixDisabled() {
|
// 准备参数
|
String name = "test.jpg";
|
String directory = "avatar";
|
FileServiceImpl.PATH_PREFIX_DATE_ENABLE = false;
|
FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_AS_DIRECTORY = false;
|
|
// 调用
|
String path = fileService.generateUploadPath(name, directory);
|
|
// 断言
|
// 格式为:avatar/test_{时间戳+随机数}.jpg
|
assertTrue(path.matches(directory + "/test_\\d+\\.jpg"));
|
}
|
|
@Test
|
public void testGenerateUploadPath_SuffixAsName_NoExtension() {
|
// 准备参数
|
String name = "test";
|
String directory = "avatar";
|
FileServiceImpl.PATH_PREFIX_DATE_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_AS_DIRECTORY = false;
|
|
// 调用
|
String path = fileService.generateUploadPath(name, directory);
|
|
// 断言
|
// 格式为:avatar/yyyyMMdd/test_{时间戳+随机数}
|
assertTrue(path.matches(directory + "/\\d{8}/test_\\d+"));
|
}
|
|
@Test
|
public void testGenerateUploadPath_DirectoryEmpty() {
|
// 准备参数
|
String name = "test.jpg";
|
String directory = "";
|
FileServiceImpl.PATH_PREFIX_DATE_ENABLE = true;
|
FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true;
|
|
// 调用
|
String path = fileService.generateUploadPath(name, directory);
|
|
// 断言
|
// 格式为:yyyyMMdd/{时间戳+随机数}/test.jpg
|
assertTrue(path.matches("\\d{8}/\\d+/test\\.jpg"));
|
}
|
|
}
|