优化
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package com.baiyue.file.controller;
|
||||
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.file.service.InternalBusinessFileService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SpringJUnitConfig(InternalBusinessFileController.class)
|
||||
@TestPropertySource(properties = "baiyue.security.internal-service-token=internal-token")
|
||||
class InternalBusinessFileControllerTest {
|
||||
@MockBean InternalBusinessFileService service;
|
||||
@Resource InternalBusinessFileController controller;
|
||||
|
||||
@Test void zeroTenantUploadAndMetadataRemainBehindInternalToken() {
|
||||
var file = new MockMultipartFile("file", "clearance.pdf", "application/pdf", "%PDF-1.4".getBytes());
|
||||
var metadata = new InternalBusinessFileService.Metadata(81L, 0L, "CONTAINER_CLEARANCE_DOCUMENT",
|
||||
"41", "clearance.pdf", "hash", "application/pdf", file.getSize());
|
||||
when(service.upload(0L, "CONTAINER_CLEARANCE_DOCUMENT", "41", 7L, file)).thenReturn(metadata);
|
||||
when(service.metadata(0L, "CONTAINER_CLEARANCE_DOCUMENT", "41", 81L)).thenReturn(metadata);
|
||||
|
||||
assertThat(controller.upload("internal-token", 7L, 0L, "CONTAINER_CLEARANCE_DOCUMENT", "41", file).data())
|
||||
.isEqualTo(metadata);
|
||||
assertThat(controller.metadata("internal-token", 0L, "CONTAINER_CLEARANCE_DOCUMENT", "41", 81L).data())
|
||||
.isEqualTo(metadata);
|
||||
}
|
||||
|
||||
@Test void zeroTenantDownloadReturnsOwnedContentWithoutCaching() {
|
||||
when(service.download(0L, "LOADING_CUSTOMS_DOCUMENT", "51", 91L))
|
||||
.thenReturn(new InternalBusinessFileService.Download("declaration.pdf", "application/pdf", new byte[]{1, 2}));
|
||||
|
||||
var response = controller.download("internal-token", 0L, "LOADING_CUSTOMS_DOCUMENT", "51", 91L);
|
||||
|
||||
assertThat(response.getBody()).containsExactly(1, 2);
|
||||
assertThat(response.getHeaders().getCacheControl()).contains("no-store");
|
||||
verify(service).download(0L, "LOADING_CUSTOMS_DOCUMENT", "51", 91L);
|
||||
}
|
||||
|
||||
@Test void rejectsInvalidTokenAndNegativeTenantBeforeServiceAccess() {
|
||||
var file = new MockMultipartFile("file", "x.txt", "text/plain", "x".getBytes());
|
||||
assertThatThrownBy(() -> controller.upload("wrong", 7L, 0L,
|
||||
"CONTAINER_CLEARANCE_DOCUMENT", "41", file))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("令牌无效");
|
||||
assertThatThrownBy(() -> controller.metadata("internal-token", -1L,
|
||||
"CONTAINER_CLEARANCE_DOCUMENT", "41", 81L))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("不能为负数");
|
||||
verifyNoInteractions(service);
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,39 @@ class InternalBusinessFileServiceTest {
|
||||
assertThat(result.contentType()).isEqualTo("text/plain");
|
||||
}
|
||||
|
||||
@Test void platformContainerAndLoadingDocumentsSupportZeroTenantScope() {
|
||||
MockMultipartFile file = new MockMultipartFile("file", "customs.pdf", "application/pdf", "%PDF-1.4".getBytes());
|
||||
when(storage.storeLoading(eq(0L), anyLong(), same(file))).thenAnswer(invocation ->
|
||||
new BusinessFileStorage.Stored("business-files/0/" + invocation.getArgument(1) + "/customs.pdf",
|
||||
"application/pdf", file.getSize(), "b".repeat(64), "customs.pdf"));
|
||||
when(files.insert(any(FileObjectEntity.class))).thenAnswer(invocation -> {
|
||||
((FileObjectEntity) invocation.getArgument(0)).setId(81L); return 1;
|
||||
});
|
||||
|
||||
var clearance = service.upload(0L, "CONTAINER_CLEARANCE_DOCUMENT", "41", 7L, file);
|
||||
var customs = service.upload(0L, "LOADING_CUSTOMS_DOCUMENT", "51", 7L, file);
|
||||
|
||||
assertThat(clearance).extracting(InternalBusinessFileService.Metadata::tenantId,
|
||||
InternalBusinessFileService.Metadata::businessType,
|
||||
InternalBusinessFileService.Metadata::businessId).containsExactly(0L, "CONTAINER_CLEARANCE_DOCUMENT", "41");
|
||||
assertThat(customs).extracting(InternalBusinessFileService.Metadata::tenantId,
|
||||
InternalBusinessFileService.Metadata::businessType,
|
||||
InternalBusinessFileService.Metadata::businessId).containsExactly(0L, "LOADING_CUSTOMS_DOCUMENT", "51");
|
||||
verify(storage).storeLoading(0L, 41L, file);
|
||||
verify(storage).storeLoading(0L, 51L, file);
|
||||
}
|
||||
|
||||
@Test void rejectsNegativeTenantAndInvalidOwnershipInputs() {
|
||||
MockMultipartFile file = new MockMultipartFile("file", "a.txt", "text/plain", "x".getBytes());
|
||||
assertThatThrownBy(() -> service.upload(-1L, "CONTAINER_CLEARANCE_DOCUMENT", "41", 7L, file))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("归属");
|
||||
assertThatThrownBy(() -> service.upload(0L, "CONTAINER_CLEARANCE_DOCUMENT", "0", 7L, file))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("业务ID");
|
||||
assertThatThrownBy(() -> service.upload(0L, "CONTAINER_CLEARANCE_DOCUMENT", "41", 0L, file))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("操作人");
|
||||
verifyNoInteractions(files, storage);
|
||||
}
|
||||
|
||||
@Test void unsupportedBusinessTypeFailsClosed() {
|
||||
assertThatThrownBy(() -> service.upload(10001L, "ARBITRARY", "41", 7L,
|
||||
new MockMultipartFile("file", "a.txt", "text/plain", "x".getBytes())))
|
||||
@@ -55,4 +88,25 @@ class InternalBusinessFileServiceTest {
|
||||
assertThat(result.content()).isEqualTo("released".getBytes());
|
||||
verify(storage).read(value.getObjectKey());
|
||||
}
|
||||
|
||||
@Test void platformMetadataAndDownloadRequireExactCompositeOwnership() {
|
||||
FileObjectEntity value = new FileObjectEntity(); value.setId(91L); value.setTenantId(0L);
|
||||
value.setBusinessType("LOADING_CUSTOMS_DOCUMENT"); value.setBusinessId("51");
|
||||
value.setOriginalName("declaration.pdf"); value.setObjectKey("business-files/0/51/declaration.pdf");
|
||||
value.setContentType("application/pdf"); value.setSha256("c".repeat(64)); value.setSizeBytes(8L);
|
||||
when(files.selectOne(any())).thenReturn(value, value, null, null, null);
|
||||
when(storage.read(value.getObjectKey())).thenReturn("document".getBytes());
|
||||
|
||||
assertThat(service.metadata(0L, "LOADING_CUSTOMS_DOCUMENT", "51", 91L).fileName())
|
||||
.isEqualTo("declaration.pdf");
|
||||
assertThat(service.download(0L, "LOADING_CUSTOMS_DOCUMENT", "51", 91L).content())
|
||||
.isEqualTo("document".getBytes());
|
||||
assertThatThrownBy(() -> service.metadata(0L, "CONTAINER_CLEARANCE_DOCUMENT", "51", 91L))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("归属不匹配");
|
||||
assertThatThrownBy(() -> service.metadata(0L, "LOADING_CUSTOMS_DOCUMENT", "52", 91L))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("归属不匹配");
|
||||
assertThatThrownBy(() -> service.metadata(0L, "LOADING_CUSTOMS_DOCUMENT", "51", 92L))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("归属不匹配");
|
||||
verify(storage).read(value.getObjectKey());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user