package com.tcm.training.admin.upload; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; import org.springframework.mock.web.MockMultipartFile; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; class LocalAppPackageStorageServiceTest { @TempDir Path tempDir; @Test void storeShouldWritePackageAndReturnPublicUrl() throws IOException { LocalUploadProperties properties = buildProperties(); LocalAppPackageStorageService service = new LocalAppPackageStorageService(properties); MockMultipartFile file = new MockMultipartFile( "file", "demo.apk", "application/vnd.android.package-archive", "apk-content".getBytes() ); UploadFileResult result = service.store(file, "ANDROID"); assertEquals("demo.apk", result.getFileName()); assertTrue(result.getUrl().startsWith("https://api.example.com/uploads/app-package/android/")); Path storedFile = tempDir.resolve(result.getObjectKey()); assertTrue(Files.exists(storedFile)); assertEquals("apk-content", new String(Files.readAllBytes(storedFile))); } @Test void storeShouldRejectMissingPublicBaseUrl() { LocalUploadProperties properties = buildProperties(); properties.setPublicBaseUrl(" "); LocalAppPackageStorageService service = new LocalAppPackageStorageService(properties); MockMultipartFile file = new MockMultipartFile( "file", "demo.apk", "application/vnd.android.package-archive", "apk-content".getBytes() ); IllegalArgumentException error = assertThrows(IllegalArgumentException.class, () -> service.store(file, "ANDROID")); assertEquals("安装包公网下载地址未配置", error.getMessage()); } @Test void storeShouldRejectPackageDirOutsideUploadRoot() { LocalUploadProperties properties = buildProperties(); properties.setAppPackageDir("../packages"); LocalAppPackageStorageService service = new LocalAppPackageStorageService(properties); MockMultipartFile file = new MockMultipartFile( "file", "demo.apk", "application/vnd.android.package-archive", "apk-content".getBytes() ); IllegalArgumentException error = assertThrows(IllegalArgumentException.class, () -> service.store(file, "ANDROID")); assertEquals("安装包存储目录不合法", error.getMessage()); } @Test void buildPublicUrlShouldAvoidDoubleSlash() { LocalUploadProperties properties = buildProperties(); properties.setPublicBaseUrl("https://api.example.com/"); properties.setPathPrefix("/uploads/"); LocalAppPackageStorageService service = new LocalAppPackageStorageService(properties); String publicUrl = service.buildPublicUrl("app-package/android/2026/04/23/demo.apk"); assertEquals("https://api.example.com/uploads/app-package/android/2026/04/23/demo.apk", publicUrl); } private LocalUploadProperties buildProperties() { LocalUploadProperties properties = new LocalUploadProperties(); properties.setDir(tempDir.toString()); properties.setPathPrefix("/uploads"); properties.setAppPackageDir("app-package"); properties.setPublicBaseUrl("https://api.example.com"); return properties; } }