fix(firstleg): map customs document versions explicitly
This commit is contained in:
+29
@@ -4,6 +4,10 @@ import com.baiyue.firstleg.customs.container.mapper.ContainerCustomsMapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.reflect.RecordComponent;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class ContainerCustomsMapperContractTest {
|
||||
@@ -27,6 +31,31 @@ class ContainerCustomsMapperContractTest {
|
||||
assertThat(value).contains("p.plan_status='COMPLETED'","i.tax_mode='BUY_DECLARATION'","item.deleted=0")
|
||||
.contains("item.id>#{cursor}","item.id<=#{maximumId}");
|
||||
}
|
||||
|
||||
@Test void documentQueriesExplicitlyMapEveryRecordComponentIncludingVersion() throws Exception {
|
||||
assertRecordProjection("document", ContainerCustomsMapper.DocumentRow.class, long.class);
|
||||
assertRecordProjection("lockDocument", ContainerCustomsMapper.DocumentRow.class, long.class);
|
||||
assertRecordProjection("documents", ContainerCustomsMapper.DocumentRow.class, long.class, Long.class);
|
||||
assertRecordProjection("lockActiveDocuments", ContainerCustomsMapper.DocumentRow.class, long.class);
|
||||
}
|
||||
|
||||
@Test void completionQueriesExplicitlyMapEveryRecordComponentIncludingVersion() throws Exception {
|
||||
assertRecordProjection("completion", ContainerCustomsMapper.CompletionRow.class, long.class);
|
||||
assertRecordProjection("lockCompletion", ContainerCustomsMapper.CompletionRow.class, long.class);
|
||||
}
|
||||
|
||||
private static void assertRecordProjection(String method,Class<?> recordType,Class<?>... parameterTypes) throws Exception {
|
||||
String value=sql(method,parameterTypes).replaceAll("\\s+"," ").trim();
|
||||
assertThat(value).doesNotContainIgnoringCase("SELECT *");
|
||||
String projection=value.substring(value.indexOf("SELECT ")+7,value.indexOf(" FROM "));
|
||||
List<String> aliases=Arrays.stream(projection.split(","))
|
||||
.map(String::trim)
|
||||
.map(column->column.substring(column.lastIndexOf(' ')+1))
|
||||
.toList();
|
||||
List<String> components=Arrays.stream(recordType.getRecordComponents()).map(RecordComponent::getName).toList();
|
||||
assertThat(aliases).containsExactlyElementsOf(components).contains("version");
|
||||
}
|
||||
|
||||
private static String sql(String name,Class<?>... types) throws Exception {
|
||||
return String.join(" ",ContainerCustomsMapper.class.getMethod(name,types).getAnnotation(Select.class).value());
|
||||
}
|
||||
|
||||
+29
@@ -13,6 +13,7 @@ import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
@@ -51,6 +52,34 @@ class ContainerCustomsServiceTest {
|
||||
assertThat(view.inbounds()).extracting(value->value.orderId()).containsExactly(21L);
|
||||
}
|
||||
|
||||
@Test void uploadedSourceViewReturnsPersistedNonNullVersion(){
|
||||
var inbound=new ContainerCustomsMapper.InboundRow(9L,"LP9",8L,"COMPLETED","CAB","C",11L,21L,"O","I",7L,"客户","TAX_REFUND");
|
||||
var aggregate=container(ContainerCustomsService.READY,2);
|
||||
var persisted=new ContainerCustomsMapper.DocumentRow(31L,2L,7L,10L,"source.bin","a".repeat(64),
|
||||
"application/octet-stream",1L,"ACTIVE",5L,java.time.LocalDateTime.now(),null,null,1);
|
||||
var file=new MockMultipartFile("file","source.bin","application/octet-stream",new byte[]{1});
|
||||
var requestHash=new AtomicReference<String>();
|
||||
when(mapper.planInbounds(9L)).thenReturn(List.of(inbound));
|
||||
when(mapper.container(9L)).thenReturn(aggregate);
|
||||
when(mapper.lockContainer(9L)).thenReturn(aggregate);
|
||||
when(mapper.missingRefundCount(9L,2L)).thenReturn(0);
|
||||
when(mapper.claimCommand(anyLong(),eq(5L),eq("UPLOAD_SOURCE"),eq("k"),anyString())).thenAnswer(invocation->{
|
||||
requestHash.set(invocation.getArgument(4));
|
||||
return 0;
|
||||
});
|
||||
when(mapper.command(5L,"UPLOAD_SOURCE","k"))
|
||||
.thenAnswer(invocation->new ContainerCustomsMapper.CommandRow(41L,5L,"UPLOAD_SOURCE","k",
|
||||
requestHash.get(),"SUCCESS",31L,null,null));
|
||||
when(mapper.document(anyLong())).thenReturn(persisted);
|
||||
when(mapper.scopes(31L)).thenReturn(List.of(new ContainerCustomsMapper.ScopeRow(31L,11L,21L,"I")));
|
||||
when(mapper.containerById(2L)).thenReturn(aggregate);
|
||||
|
||||
var view=service.uploadSource(7L,9L,5L,"k",List.of(11L),file);
|
||||
|
||||
assertThat(view.source().version()).isEqualTo(1);
|
||||
verifyNoInteractions(files);
|
||||
}
|
||||
|
||||
@Test void startFailsClosedWhenAnyRefundInboundHasNoActiveDocumentCoverage(){
|
||||
var row=new ContainerCustomsMapper.InboundRow(9L,"LP9",8L,"COMPLETED","CAB","C",11L,21L,"O","I",7L,"客户","TAX_REFUND");
|
||||
var container=new ContainerCustomsMapper.ContainerRow(1L,9L,8L,ContainerCustomsService.READY,null,null,null,null,null,null,null,null,2);
|
||||
|
||||
Reference in New Issue
Block a user