feat(files): add storage policy skeleton

This commit is contained in:
yoyuzh
2026-04-08 15:37:43 +08:00
parent f582e600aa
commit 6da0d196ee
16 changed files with 507 additions and 2 deletions

View File

@@ -0,0 +1,103 @@
package com.yoyuzh.files;
import com.yoyuzh.config.FileStorageProperties;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class StoragePolicyServiceTest {
@Mock
private StoragePolicyRepository storagePolicyRepository;
private FileStorageProperties properties;
private StoragePolicyService storagePolicyService;
@BeforeEach
void setUp() {
properties = new FileStorageProperties();
storagePolicyService = new StoragePolicyService(storagePolicyRepository, properties);
}
@Test
void shouldCreateDefaultS3CompatiblePolicyFromCurrentStorageConfig() {
properties.setProvider("s3");
properties.setMaxFileSize(5000L);
properties.getS3().setScope("media-bucket:portal-prefix");
properties.getS3().setRegion("automatic");
when(storagePolicyRepository.findFirstByDefaultPolicyTrueOrderByIdAsc()).thenReturn(Optional.empty());
when(storagePolicyRepository.save(any(StoragePolicy.class))).thenAnswer(invocation -> {
StoragePolicy policy = invocation.getArgument(0);
policy.setId(1L);
return policy;
});
StoragePolicy policy = storagePolicyService.ensureDefaultPolicy();
assertThat(policy.getName()).isEqualTo("Default S3 Compatible Storage");
assertThat(policy.getType()).isEqualTo(StoragePolicyType.S3_COMPATIBLE);
assertThat(policy.getCredentialMode()).isEqualTo(StoragePolicyCredentialMode.DOGECLOUD_TEMP);
assertThat(policy.getBucketName()).isEqualTo("media-bucket");
assertThat(policy.getPrefix()).isEqualTo("portal-prefix");
assertThat(policy.getRegion()).isEqualTo("automatic");
assertThat(policy.isDefaultPolicy()).isTrue();
assertThat(policy.isEnabled()).isTrue();
StoragePolicyCapabilities capabilities = storagePolicyService.readCapabilities(policy);
assertThat(capabilities.directUpload()).isTrue();
assertThat(capabilities.multipartUpload()).isFalse();
assertThat(capabilities.signedDownloadUrl()).isTrue();
assertThat(capabilities.serverProxyDownload()).isTrue();
assertThat(capabilities.requiresCors()).isTrue();
assertThat(capabilities.maxObjectSize()).isEqualTo(5000L);
}
@Test
void shouldCreateDefaultLocalPolicyFromCurrentStorageConfig() {
properties.setProvider("local");
properties.setMaxFileSize(2048L);
properties.getLocal().setRootDir("./storage");
when(storagePolicyRepository.findFirstByDefaultPolicyTrueOrderByIdAsc()).thenReturn(Optional.empty());
when(storagePolicyRepository.save(any(StoragePolicy.class))).thenAnswer(invocation -> invocation.getArgument(0));
StoragePolicy policy = storagePolicyService.ensureDefaultPolicy();
assertThat(policy.getName()).isEqualTo("Default Local Storage");
assertThat(policy.getType()).isEqualTo(StoragePolicyType.LOCAL);
assertThat(policy.getCredentialMode()).isEqualTo(StoragePolicyCredentialMode.NONE);
assertThat(policy.getPrefix()).isEqualTo("./storage");
StoragePolicyCapabilities capabilities = storagePolicyService.readCapabilities(policy);
assertThat(capabilities.directUpload()).isFalse();
assertThat(capabilities.multipartUpload()).isFalse();
assertThat(capabilities.signedDownloadUrl()).isFalse();
assertThat(capabilities.serverProxyDownload()).isTrue();
assertThat(capabilities.requiresCors()).isFalse();
assertThat(capabilities.maxObjectSize()).isEqualTo(2048L);
}
@Test
void shouldReuseExistingDefaultPolicy() {
StoragePolicy existingPolicy = new StoragePolicy();
existingPolicy.setId(7L);
existingPolicy.setDefaultPolicy(true);
existingPolicy.setEnabled(true);
when(storagePolicyRepository.findFirstByDefaultPolicyTrueOrderByIdAsc()).thenReturn(Optional.of(existingPolicy));
StoragePolicy policy = storagePolicyService.ensureDefaultPolicy();
assertThat(policy).isSameAs(existingPolicy);
verify(storagePolicyRepository, never()).save(any(StoragePolicy.class));
}
}

View File

@@ -37,6 +37,8 @@ class UploadSessionServiceTest {
private FileService fileService;
@Mock
private FileContentStorage fileContentStorage;
@Mock
private StoragePolicyService storagePolicyService;
private UploadSessionService uploadSessionService;
@@ -49,6 +51,7 @@ class UploadSessionServiceTest {
storedFileRepository,
fileService,
fileContentStorage,
storagePolicyService,
properties,
Clock.fixed(Instant.parse("2026-04-08T06:00:00Z"), ZoneOffset.UTC)
);
@@ -58,6 +61,7 @@ class UploadSessionServiceTest {
void shouldCreateUploadSessionWithoutChangingLegacyUploadPath() {
User user = createUser(7L);
when(storedFileRepository.existsByUserIdAndPathAndFilename(7L, "/docs", "movie.mp4")).thenReturn(false);
when(storagePolicyService.ensureDefaultPolicy()).thenReturn(createDefaultStoragePolicy());
when(uploadSessionRepository.save(any(UploadSession.class))).thenAnswer(invocation -> {
UploadSession session = invocation.getArgument(0);
session.setId(100L);
@@ -72,6 +76,7 @@ class UploadSessionServiceTest {
assertThat(session.getSessionId()).isNotBlank();
assertThat(session.getObjectKey()).startsWith("blobs/");
assertThat(session.getStatus()).isEqualTo(UploadSessionStatus.CREATED);
assertThat(session.getStoragePolicyId()).isEqualTo(42L);
assertThat(session.getChunkSize()).isEqualTo(8L * 1024 * 1024);
assertThat(session.getChunkCount()).isEqualTo(3);
assertThat(session.getExpiresAt()).isEqualTo(LocalDateTime.of(2026, 4, 9, 6, 0));
@@ -214,6 +219,16 @@ class UploadSessionServiceTest {
return user;
}
private StoragePolicy createDefaultStoragePolicy() {
StoragePolicy policy = new StoragePolicy();
policy.setId(42L);
policy.setName("Default S3 Compatible Storage");
policy.setType(StoragePolicyType.S3_COMPATIBLE);
policy.setEnabled(true);
policy.setDefaultPolicy(true);
return policy;
}
private UploadSession createSession(User user) {
UploadSession session = new UploadSession();
session.setSessionId("session-1");