提交
This commit is contained in:
+40
@@ -0,0 +1,40 @@
|
||||
package com.baiyue.lastleg.dispatch.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
|
||||
import com.baiyue.lastleg.dispatch.repository.MerchantTransportPhotoRepository;
|
||||
import org.mybatis.spring.SqlSessionTemplate;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import java.util.UUID;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
class MerchantTransportPhotoMapperTest {
|
||||
/** 同编号、混装和撤销安排均不能扩大客户读取范围,实际查询使用正式Mapper。 */
|
||||
@Test void queriesOnlyExactCustomerOrderAndActiveDispatches() throws Exception {
|
||||
var data=new DriverManagerDataSource("jdbc:h2:mem:"+UUID.randomUUID()+";MODE=MySQL;DB_CLOSE_DELAY=-1","sa","");
|
||||
var db=new JdbcTemplate(data);
|
||||
db.execute("CREATE TABLE ll_local_looseboard_order(customer_id VARCHAR(20),order_no VARCHAR(30),lastleg_order_id BIGINT)");
|
||||
db.execute("CREATE TABLE ll_inbound_plan(id BIGINT,customer_id VARCHAR(20),source_order_id BIGINT)");
|
||||
db.execute("CREATE TABLE ll_inbound_plan_pallet(id BIGINT,plan_id BIGINT,customer_id VARCHAR(20))");
|
||||
db.execute("CREATE TABLE ll_dispatch_item(plan_pallet_id BIGINT,customer_id VARCHAR(20),dispatch_order_id BIGINT)");
|
||||
db.execute("CREATE TABLE ll_dispatch_order(id BIGINT,dispatch_no VARCHAR(30),status VARCHAR(20),task_type VARCHAR(20))");
|
||||
db.execute("CREATE TABLE ll_dispatch_truck_task(dispatch_no VARCHAR(30),customer_id VARCHAR(20),order_no VARCHAR(30),active_order VARCHAR(50))");
|
||||
db.update("INSERT INTO ll_local_looseboard_order VALUES('C1','LB1',1),('C2','LB1',2)");
|
||||
db.update("INSERT INTO ll_inbound_plan VALUES(11,'C1',1),(12,'C2',2)");
|
||||
db.update("INSERT INTO ll_inbound_plan_pallet VALUES(21,11,'C1'),(22,12,'C2')");
|
||||
db.update("INSERT INTO ll_dispatch_order VALUES(31,'PC1','ACTIVE','DELIVERY'),(32,'PC2','CANCELLED','DELIVERY'),(33,'PC3','ACTIVE','LOCAL_TRUCK')");
|
||||
db.update("INSERT INTO ll_dispatch_item VALUES(21,'C1',31),(22,'C2',31),(21,'C1',32),(22,'C1',33)");
|
||||
db.update("INSERT INTO ll_dispatch_truck_task VALUES('PC3','C1','TR1','C1:TR1'),('PC2','C1','TR1','C1:TR1'),('PC1','C2','TR1','C2:TR1')");
|
||||
var config=new MybatisConfiguration();config.addMapper(MerchantTransportPhotoMapper.class);
|
||||
var factory=new MybatisSqlSessionFactoryBean();factory.setDataSource(data);factory.setConfiguration(config);factory.afterPropertiesSet();
|
||||
var repository=new MerchantTransportPhotoRepository(new SqlSessionTemplate(factory.getObject()).getMapper(MerchantTransportPhotoMapper.class));
|
||||
assertThat(repository.looseboardDispatches("C1","LB1")).containsExactly("PC1");
|
||||
assertThat(repository.looseboardDispatches("C3","LB1")).isEmpty();
|
||||
assertThat(repository.truckDispatches("C1","TR1")).containsExactly("PC3");
|
||||
assertThat(repository.truckDispatches("C2","TR1")).isEmpty();
|
||||
db.update("UPDATE ll_dispatch_truck_task SET active_order=NULL WHERE dispatch_no='PC3'");
|
||||
assertThat(repository.truckDispatches("C1","TR1")).isEmpty();
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
package com.baiyue.lastleg.dispatch.service;
|
||||
|
||||
import com.baiyue.lastleg.trucking.port.MerchantTransportPhotos.*;
|
||||
import com.baiyue.lastleg.dispatch.entity.*;
|
||||
import com.baiyue.lastleg.dispatch.repository.*;
|
||||
import com.baiyue.lastleg.dispatch.gateway.DispatchEvidenceGateway;
|
||||
import com.baiyue.lastleg.dispatch.transport.*;
|
||||
import com.baiyue.lastleg.fleet.reporting.TripOperationsRecordModels.EvidenceFile;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
class MerchantTransportPhotoServiceTest {
|
||||
/** 混装只回显本客户本票当前照片,阶段和文件ID不能绕过授权;删除后立即不可下载。 */
|
||||
@Test void looseboardPhotosStayWithinCustomerOrderAndCurrentBinding(){
|
||||
var f=new Fixture();var row=new DispatchAggregate();row.setId(1L);row.setStatus("ACTIVE");
|
||||
when(f.links.looseboardDispatches("C1","LB1")).thenReturn(List.of("PC1"));when(f.roots.find("PC1")).thenReturn(row);
|
||||
var item=new DispatchItem();item.setId(10L);item.setCustomerId("C1");
|
||||
when(f.facts.cargo(1)).thenReturn(List.of(new DispatchLooseboardFacts.Cargo(item,"LB1")));
|
||||
when(f.facts.current(row)).thenReturn(List.of(evidence("C1","LB1",10,DispatchLooseboardFacts.Phase.PICKUP,71),
|
||||
evidence("C1","LB1",10,DispatchLooseboardFacts.Phase.ARRIVAL,72),evidence("C2","LB2",20,DispatchLooseboardFacts.Phase.PICKUP,73),
|
||||
evidence("C1","LB1",99,DispatchLooseboardFacts.Phase.PICKUP,74)));
|
||||
var photos=f.service.photos(Business.LOOSEBOARD,"C1","LB1");
|
||||
assertThat(photos.pickupPhotos()).extracting(Photo::fileId).containsExactly("71");
|
||||
assertThat(photos.arrivalPhotos()).extracting(Photo::fileId).containsExactly("72");
|
||||
assertThatThrownBy(()->f.service.content(Business.LOOSEBOARD,"C1","LB1",Phase.PICKUP,73)).hasMessageContaining("没有该照片");
|
||||
assertThatThrownBy(()->f.service.content(Business.LOOSEBOARD,"C1","LB1",Phase.ARRIVAL,71)).hasMessageContaining("没有该照片");
|
||||
verifyNoInteractions(f.files);
|
||||
when(f.files.download(1,DispatchEvidenceGateway.Kind.LOOSEBOARD_PICKUP,71)).thenReturn(new byte[]{1});
|
||||
assertThat(f.service.content(Business.LOOSEBOARD,"C1","LB1",Phase.PICKUP,71).bytes()).containsExactly(1);
|
||||
when(f.facts.current(row)).thenReturn(List.of());
|
||||
assertThatThrownBy(()->f.service.content(Business.LOOSEBOARD,"C1","LB1",Phase.PICKUP,71)).hasMessageContaining("没有该照片");
|
||||
when(f.facts.current(row)).thenReturn(List.of(evidence("C1","LB1",10,DispatchLooseboardFacts.Phase.PICKUP,71)));
|
||||
row.setStatus("CANCELLED");assertThat(f.service.photos(Business.LOOSEBOARD,"C1","LB1").pickupPhotos()).isEmpty();
|
||||
}
|
||||
/** 卡车保持取货与完成分类,读取已绑定凭证且不披露司机证件;关联客户异常直接拒绝。 */
|
||||
@Test void truckPhotosUseOnlyLinkedTransportEvidence(){
|
||||
var f=new Fixture();when(f.links.truckDispatches("C1","TR1")).thenReturn(List.of("PC2"));
|
||||
when(f.trucks.detail("PC2")).thenReturn(truck("C1","TR1"));
|
||||
var photos=f.service.photos(Business.TRUCK,"C1","TR1");
|
||||
assertThat(photos.pickupPhotos()).extracting(Photo::fileId).containsExactly("81");
|
||||
assertThat(photos.arrivalPhotos()).extracting(Photo::fileId).containsExactly("82");
|
||||
when(f.trucks.evidence("PC2",82)).thenReturn(new byte[]{2});
|
||||
assertThat(f.service.content(Business.TRUCK,"C1","TR1",Phase.ARRIVAL,82).bytes()).containsExactly(2);
|
||||
assertThatThrownBy(()->f.service.content(Business.TRUCK,"C1","TR1",Phase.PICKUP,82)).hasMessageContaining("没有该照片");
|
||||
when(f.trucks.detail("PC2")).thenReturn(truck("C2","TR1"));
|
||||
assertThatThrownBy(()->f.service.photos(Business.TRUCK,"C1","TR1")).hasMessageContaining("归属不匹配");
|
||||
}
|
||||
/** 测试凭证保留真实节点身份,不将上传回执当作保存事实。 */
|
||||
private static DispatchLooseboardFacts.Evidence evidence(String customer,String order,long item,DispatchLooseboardFacts.Phase phase,long file){
|
||||
return new DispatchLooseboardFacts.Evidence(Long.toString(item),customer,order,phase,"hash",1,
|
||||
List.of(new DispatchEvidenceGateway.File(file,"photo.png","image/png",5)),Instant.now(),"operator","key","hash");
|
||||
}
|
||||
/** 卡车资料夹具仅包含取货与完成附件。 */
|
||||
private static TransportTaskModels.Detail truck(String customer,String order){return new TransportTaskModels.Detail("PC2","LOCAL_TRUCK",null,customer,order,List.of(),
|
||||
List.of(new EvidenceFile("81","pickup.png","image/png",5)),List.of(new EvidenceFile("82","arrival.png","image/png",5)),1L,null,null);}
|
||||
static class Fixture {
|
||||
final MerchantTransportPhotoRepository links=mock(MerchantTransportPhotoRepository.class);
|
||||
final DispatchAggregateRepository roots=mock(DispatchAggregateRepository.class);
|
||||
final DispatchLooseboardFacts facts=mock(DispatchLooseboardFacts.class);
|
||||
final DispatchEvidenceGateway files=mock(DispatchEvidenceGateway.class);
|
||||
final TransportTaskService trucks=mock(TransportTaskService.class);
|
||||
final MerchantTransportPhotoService service=new MerchantTransportPhotoService(links,roots,facts,files,trucks);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user