This commit is contained in:
2026-10-21 17:52:28 +08:00
parent ae361879e5
commit 044812cd90
9 changed files with 218 additions and 11 deletions
@@ -0,0 +1,73 @@
package com.baiyue.lastleg.dispatch.transport;
import com.baiyue.lastleg.dispatch.entity.DispatchAggregate;
import com.baiyue.lastleg.dispatch.gateway.DispatchEvidenceGateway;
import com.baiyue.lastleg.fleet.driver.*;
import com.baiyue.lastleg.fleet.trip.FleetTripEntity;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.*;
import java.time.*;
import java.util.*;
import static com.baiyue.lastleg.dispatch.port.DispatchContracts.*;
import static com.baiyue.lastleg.dispatch.port.DispatchTypes.*;
import static com.baiyue.lastleg.dispatch.gateway.DispatchEvidenceGateway.Kind.*;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.Mockito.*;
class TransportReviewPhotosTest {
final ObjectMapper json=new ObjectMapper().findAndRegisterModules();
final DispatchEvidenceGateway files=mock(DispatchEvidenceGateway.class);
final DriverService drivers=mock(DriverService.class);
final TransportReviewPhotos service=new TransportReviewPhotos(files,drivers,json);
final DispatchAggregate row=new DispatchAggregate();
final FleetTripEntity trip=new FleetTripEntity();
/** 使用已审核海外司机及未来任务时间,不依赖运行中的服务。 */
@BeforeEach void setup() {
row.setId(10L);row.setRecordVersion(9L);
trip.setVehicleId(1L);trip.setDriverId(2L);trip.setRecordVersion(4L);trip.setExpectedDriverEndAt(LocalDateTime.of(2099,1,1,0,0));
var response=mock(DriverModels.Response.class,RETURNS_DEEP_STUBS);
when(response.details().region()).thenReturn("OVERSEAS");when(response.details().licenseNumber()).thenReturn("TEST");
when(response.details().licenseExpiresOn()).thenReturn(LocalDate.of(2099,2,1));when(response.licenseFileId()).thenReturn("33");
when(drivers.requireDispatchable(eq(2L),any())).thenReturn(response);
}
/** 必填照片不足时不能调用文件或资源保存。 */
@Test void requiresAllThreeCategories() {
for(var photos:List.of(new ReviewAttachments(List.of(),List.of(22L),List.of(23L)),
new ReviewAttachments(List.of(21L),List.of(),List.of(23L)),new ReviewAttachments(List.of(21L),List.of(22L),List.of()))) {
assertThatThrownBy(()->service.validate(row,trip,request(photos,null))).hasMessageContaining("补齐");
}
verifyNoInteractions(files,drivers);
}
/** 主档与本车补传走各自归属,禁止拿别人的证照冒充当前司机。 */
@Test void distinguishesMasterLicenseFromDispatchUploads() {
var evidence=service.validate(row,trip,request(new ReviewAttachments(List.of(21L),List.of(22L),List.of()),33L));
assertThat(evidence.fileIds()).containsExactly(33L);assertThat(evidence.masterLicenseFileId()).isEqualTo(33L);
verify(drivers).download(2L,33L);verify(files,never()).metadata(10L,DRIVER,33L);
var uploaded=service.validate(row,trip,request(new ReviewAttachments(List.of(21L),List.of(22L),List.of(23L)),null));
assertThat(uploaded.masterLicenseFileId()).isNull();verify(files).metadata(10L,DRIVER,23L);
assertThatThrownBy(()->service.validate(row,trip,request(new ReviewAttachments(List.of(21L),List.of(22L),List.of()),99L))).hasMessageContaining("主档驾驶证已变化");
}
/** 同车不同分类及跨排车文件由文件网关拒绝。 */
@Test void rejectsForeignOrWrongCategoryPhoto() {
when(files.metadata(10L,DRIVER_PHOTO,22L)).thenThrow(new IllegalArgumentException("文件归属错误"));
assertThatThrownBy(()->service.validate(row,trip,request(new ReviewAttachments(List.of(21L),List.of(22L),List.of(23L)),null))).hasMessageContaining("归属错误");
}
/** 换司机后旧人像不允许重复绑定。 */
@Test void rejectsPhotosCarriedFromAnotherDriver() throws Exception {
row.setResourcesJson(json.writeValueAsString(new Resources(null,new DriverSnapshot(ResourceMode.MASTER,5L,"原司机","000",
new DriverEvidence(null,null,List.of(23L),null,List.of(22L))))));
assertThatThrownBy(()->service.validate(row,trip,request(new ReviewAttachments(List.of(21L),List.of(22L),List.of(24L)),null))).hasMessageContaining("重新上传");
}
/** 审核复验已保存证据,照片后续失效也不能通过。 */
@Test void reviewRevalidatesPersistedPhotoOwnership() throws Exception {
row.setResourcesJson(json.writeValueAsString(new Resources(new VehicleSnapshot(ResourceMode.MASTER,1L,"TEST",null,null,null,List.of(21L)),
new DriverSnapshot(ResourceMode.MASTER,2L,"司机","000",new DriverEvidence(null,null,List.of(23L),null,List.of(22L))))));
service.verifyReview(row,trip);verify(files).metadata(10L,VEHICLE,21L);
when(files.metadata(10L,DRIVER,23L)).thenThrow(new IllegalArgumentException("附件失效"));
assertThatThrownBy(()->service.verifyReview(row,trip)).hasMessageContaining("附件失效");
}
/** 构造同一车辆、司机的双版本保存请求。 */
private TransportTaskModels.Assign request(ReviewAttachments photos,Long master) {
return new TransportTaskModels.Assign(4L,1L,2L,"维护照片",9L,photos,master);
}
}