fix(lastleg): complete relabel document contract and regression gates

This commit is contained in:
2026-09-09 12:54:14 +08:00
parent ac3ce3703e
commit 655237e37f
19 changed files with 474 additions and 23 deletions
@@ -0,0 +1,103 @@
package com.baiyue.file.service;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.file.entity.FileObjectEntity;
import com.baiyue.file.mapper.FileObjectMapper;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.util.ReflectionTestUtils;
import java.nio.file.Path;
import java.nio.charset.StandardCharsets;
import java.util.Set;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
import static org.mockito.ArgumentMatchers.any;
class RelabelDocumentFileTest {
@TempDir Path root;
@ParameterizedTest
@EnumSource(value = BusinessFileCategory.class, names = {"OVERSEAS_RELABEL_TOTAL_DOCUMENT", "OVERSEAS_RELABEL_ITEM_DOCUMENT"})
void pdfPolicyChecksContentTypeSignatureAndSize(BusinessFileCategory category) {
BusinessFileStorage storage = storage();
byte[] exactLimit = new byte[10 * 1024 * 1024];
System.arraycopy("%PDF-1.7".getBytes(StandardCharsets.US_ASCII), 0, exactLimit, 0, 8);
var file = new MockMultipartFile("file", "label.pdf", "application/pdf", exactLimit);
var saved = storage.store(11L, "41", file, category);
assertThat(saved.size()).isEqualTo(10 * 1024 * 1024);
assertThat(saved.objectKey()).endsWith(".pdf");
assertThat(storage.read(saved.objectKey())).isEqualTo(exactLimit);
for (String type : new String[]{"image/png", "text/plain", "application/octet-stream"}) {
assertThatThrownBy(() -> storage.store(11L, "41",
new MockMultipartFile("file", "label.pdf", type, exactLimit), category))
.isInstanceOf(BizException.class).hasMessageContaining("仅支持PDF");
}
assertThatThrownBy(() -> storage.store(11L, "41",
new MockMultipartFile("file", "fake.pdf", "application/pdf", "not-pdf".getBytes()), category))
.isInstanceOf(BizException.class).hasMessageContaining("不是有效PDF");
assertThatThrownBy(() -> storage.store(11L, "41",
new MockMultipartFile("file", "empty.pdf", "application/pdf", new byte[0]), category))
.isInstanceOf(BizException.class).hasMessageContaining("不能为空");
assertThatThrownBy(() -> storage.store(11L, "41",
new MockMultipartFile("file", "large.pdf", "application/pdf", new byte[exactLimit.length + 1]), category))
.isInstanceOf(BizException.class).hasMessageContaining("10MB");
}
@ParameterizedTest
@EnumSource(value = BusinessFileCategory.class, names = {"OVERSEAS_RELABEL_TOTAL_DOCUMENT", "OVERSEAS_RELABEL_ITEM_DOCUMENT"})
void uploadAndReadRequireExactCustomerBusinessTypeBusinessAndFile(BusinessFileCategory category) throws Exception {
TableInfoHelper.initTableInfo(new MapperBuilderAssistant(new MybatisConfiguration(), "relabel-test"), FileObjectEntity.class);
FileObjectMapper files = mock(FileObjectMapper.class);
InternalBusinessFileService service = new InternalBusinessFileService();
ReflectionTestUtils.setField(service, "files", files);
ReflectionTestUtils.setField(service, "storage", storage());
FileObjectEntity[] persisted = new FileObjectEntity[1];
when(files.insert(any(FileObjectEntity.class))).thenAnswer(call -> {
persisted[0] = call.getArgument(0); persisted[0].setId(801L); return 1;
});
var pdf = new MockMultipartFile("file", "label.pdf", "application/pdf", "%PDF-1.7".getBytes());
var saved = service.upload(11L, category.name(), "41", 7L, pdf);
assertThat(saved.ownerScope()).isEqualTo("CUSTOMER");
assertThat(saved.tenantId()).isEqualTo(11L);
assertThat(saved.businessType()).isEqualTo(category.name());
assertThat(saved.businessId()).isEqualTo("41");
when(files.selectOne(any())).thenAnswer(call -> {
LambdaQueryWrapper<FileObjectEntity> query = call.getArgument(0);
assertThat(query.getSqlSegment()).contains("tenant_id", "business_type", "business_id", "id", "status", "deleted");
return Set.copyOf(query.getParamNameValuePairs().values())
.equals(Set.of(11L, category.name(), "41", 801L, "ACTIVE", false)) ? persisted[0] : null;
});
assertThat(service.download(11L, category.name(), "41", 801L).content()).isEqualTo(pdf.getBytes());
assertThatThrownBy(() -> service.download(12L, category.name(), "41", 801L)).isInstanceOf(BizException.class);
assertThatThrownBy(() -> service.download(11L, category.name(), "42", 801L)).isInstanceOf(BizException.class);
assertThatThrownBy(() -> service.download(11L, category.name(), "41", 802L)).isInstanceOf(BizException.class);
String other = category == BusinessFileCategory.OVERSEAS_RELABEL_TOTAL_DOCUMENT
? "OVERSEAS_RELABEL_ITEM_DOCUMENT" : "OVERSEAS_RELABEL_TOTAL_DOCUMENT";
assertThatThrownBy(() -> service.download(11L, other, "41", 801L)).isInstanceOf(BizException.class);
clearInvocations(files);
for (long owner : new long[]{0L, -1L}) {
assertThatThrownBy(() -> service.upload(owner, category.name(), "41", 7L, pdf)).isInstanceOf(BizException.class);
assertThatThrownBy(() -> service.metadata(owner, category.name(), "41", 801L)).isInstanceOf(BizException.class);
}
for (String id : new String[]{"0", "-1", "invalid", "9223372036854775808"}) {
assertThatThrownBy(() -> service.upload(11L, category.name(), id, 7L, pdf)).isInstanceOf(BizException.class);
assertThatThrownBy(() -> service.metadata(11L, category.name(), id, 801L)).isInstanceOf(BizException.class);
}
verifyNoInteractions(files);
}
private BusinessFileStorage storage() {
BusinessFileStorage storage = new BusinessFileStorage();
ReflectionTestUtils.setField(storage, "configuredRoot", root);
storage.initializeRoot();
return storage;
}
}