feat: 完善工作流 Public API 调用能力

- 支持 JSON 文件 URL 简写与 Multipart 单请求文件上传

- 完善执行拓扑、枚举状态、节点名称、恢复校验和安全错误响应

- 增加临时上传生命周期清理并升级 MinIO SDK

- 重构工作流接口调用说明弹窗的扁平响应式布局
This commit is contained in:
2026-08-09 21:27:30 +08:00
parent 0d14f1c165
commit 54d85ae460
61 changed files with 8131 additions and 161 deletions

View File

@@ -0,0 +1,89 @@
package tech.easyflow.common.web.multipart;
import org.junit.Assert;
import org.junit.Test;
/**
* {@link MultipartFileMetadataNormalizer} 回归测试。
*/
public class MultipartFileMetadataNormalizerTest {
/**
* 验证合法媒体类型会被保留。
*/
@Test
public void shouldKeepValidDeclaredContentType() {
Assert.assertEquals(
"application/pdf",
MultipartFileMetadataNormalizer.normalizeContentType(
"report.pdf",
"application/pdf"));
}
/**
* 验证客户端占位值会按扩展名推断。
*/
@Test
public void shouldInferContentTypeWhenClientSendsOther() {
Assert.assertEquals(
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
MultipartFileMetadataNormalizer.normalizeContentType(
"report.docx",
"Other"));
}
/**
* 验证空媒体类型也会按扩展名推断。
*/
@Test
public void shouldInferContentTypeWhenClientOmitsIt() {
Assert.assertEquals(
"application/pdf",
MultipartFileMetadataNormalizer.normalizeContentType(
"report.pdf",
" "));
}
/**
* 验证非法媒体类型且无法推断时使用二进制兜底。
*/
@Test
public void shouldFallbackToOctetStreamForUnknownFile() {
Assert.assertEquals(
"application/octet-stream",
MultipartFileMetadataNormalizer.normalizeContentType(
"payload.unknown-extension",
"invalid content type"));
}
/**
* 验证文件名不会携带客户端目录片段。
*/
@Test
public void shouldRemoveClientPathFromFilename() {
Assert.assertEquals(
"report.pdf",
MultipartFileMetadataNormalizer.sanitizeFilename(
"C:\\fakepath\\report.pdf"));
}
/**
* 验证超长文件名截断后仍保留可用于 MIME 推断的扩展名。
*/
@Test
public void shouldKeepExtensionWhenSanitizingLongFilename() {
String filename = "a".repeat(300) + ".pdf";
String sanitized =
MultipartFileMetadataNormalizer.sanitizeFilename(
filename);
Assert.assertEquals(255, sanitized.length());
Assert.assertTrue(sanitized.endsWith(".pdf"));
Assert.assertEquals(
"application/pdf",
MultipartFileMetadataNormalizer.normalizeContentType(
sanitized,
"Other"));
}
}