fix(firstleg): resolve loading list lifecycle by plan
This commit is contained in:
+9
-1
@@ -29,6 +29,7 @@ class LoadingListControllerContractTest {
|
||||
void permissionsMatch() throws Exception {
|
||||
authority("preloadPage", "platform:firstleg:preload:list", AuthenticatedUser.class, PreloadQuery.class);
|
||||
authority("preloadDetail", "platform:firstleg:preload:list", AuthenticatedUser.class, long.class, long.class);
|
||||
authority("lifecycle", "platform:firstleg:preload:list", AuthenticatedUser.class, long.class, long.class);
|
||||
authority("updateTransport", "platform:firstleg:preload:edit", AuthenticatedUser.class,
|
||||
long.class, long.class, String.class, TransportUpdateRequest.class);
|
||||
authority("confirmPreload", "platform:firstleg:preload:edit", AuthenticatedUser.class,
|
||||
@@ -72,6 +73,8 @@ class LoadingListControllerContractTest {
|
||||
.contains("校验ISO 6346结构、设备类别和校验位")
|
||||
.contains("PDA任务尚未领取且无任何物理作业事实")
|
||||
.contains("/loading-plans/{planId}/confirm")
|
||||
.contains("/loading-plans/{planId}/lifecycle")
|
||||
.contains("不得以错误文案或 A0404 猜测阶段")
|
||||
.contains("confirmationStatus")
|
||||
.contains("canConfirm")
|
||||
.contains("blockingReasons")
|
||||
@@ -116,6 +119,7 @@ class LoadingListControllerContractTest {
|
||||
assertThat(paths).containsOnlyKeys(
|
||||
"/api/platform/v1/first-leg/loading-plans",
|
||||
"/api/platform/v1/first-leg/loading-plans/{planId}",
|
||||
"/api/platform/v1/first-leg/loading-plans/{planId}/lifecycle",
|
||||
"/api/platform/v1/first-leg/loading-plans/{planId}/transport",
|
||||
"/api/platform/v1/first-leg/loading-plans/{planId}/confirm",
|
||||
"/api/platform/v1/first-leg/loading-lists",
|
||||
@@ -126,7 +130,11 @@ class LoadingListControllerContractTest {
|
||||
"LongId", "PreloadPage", "ConfirmedPage", "Customer", "PreloadSummary",
|
||||
"ConfirmedSummary", "LoadingItem", "OperationHistory", "PreloadDetail",
|
||||
"ConfirmedDetail", "TransportUpdateRequest", "PreloadReadiness",
|
||||
"ConfirmPreloadRequest", "PreloadConfirmation", "PreloadConfirmationEnvelope");
|
||||
"ConfirmPreloadRequest", "PreloadConfirmation", "PreloadConfirmationEnvelope",
|
||||
"LifecycleResolution", "LifecycleResolutionEnvelope");
|
||||
assertThat(properties(schemas, "LifecycleResolution")).containsOnlyKeys(
|
||||
"planId", "containerBookingId", "warehouseId", "planNo", "planStatus",
|
||||
"detailResource", "requiredPermission");
|
||||
assertThat(paths)
|
||||
.doesNotContainKey("/api/platform/v1/first-leg/loading-plans/{planId}/complete");
|
||||
assertThat(stringMap(schemas.get("LongId"))).containsEntry("type", "string");
|
||||
|
||||
+9
@@ -67,6 +67,15 @@ class LoadingListQueryMapperContractTest {
|
||||
.contains("i.deleted = 0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void lifecycleAggregateKeepsTheSamePlanIdAcrossEveryStatus() throws Exception {
|
||||
String aggregate = sql("selectAggregate", Select.class);
|
||||
assertThat(aggregate)
|
||||
.contains("WHERE p.id = #{planId}")
|
||||
.contains("p.plan_status")
|
||||
.doesNotContain("plan_status = 'COMPLETED'", "plan_status IN ('EDITING', 'LOADING')");
|
||||
}
|
||||
|
||||
@Test
|
||||
void mutationsShouldUseStatusAndOptimisticVersionConditions() throws Exception {
|
||||
String touch = sql("touchEditable", Update.class);
|
||||
|
||||
@@ -361,7 +361,42 @@ class LoadingListServiceTest {
|
||||
assertThatThrownBy(() -> service.preloadDetail(10L, 200L))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(error -> ((BizException) error).getResultCode())
|
||||
.isEqualTo(ResultCode.NOT_FOUND);
|
||||
.isEqualTo(ResultCode.FORBIDDEN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolvesStablePlanIdToPreloadOrCompletedLoadingListWithoutGuessingFrom404() {
|
||||
when(repository.aggregate(10L)).thenReturn(row("LOADING", 2), row("COMPLETED", 3));
|
||||
|
||||
var preload = service.lifecycle(10L, 100L);
|
||||
var completed = service.lifecycle(10L, 100L);
|
||||
|
||||
assertThat(preload.planId()).isEqualTo(10L);
|
||||
assertThat(preload.planStatus()).isEqualTo("LOADING");
|
||||
assertThat(preload.detailResource()).isEqualTo("PRELOAD");
|
||||
assertThat(preload.requiredPermission()).isEqualTo("platform:firstleg:preload:list");
|
||||
assertThat(completed.planId()).isEqualTo(10L);
|
||||
assertThat(completed.planStatus()).isEqualTo("COMPLETED");
|
||||
assertThat(completed.detailResource()).isEqualTo("LOADING_LIST");
|
||||
assertThat(completed.requiredPermission()).isEqualTo("platform:firstleg:loading-list:list");
|
||||
}
|
||||
|
||||
@Test
|
||||
void stageMismatchIsConflictAndOnlyMissingPlanIsNotFound() {
|
||||
when(repository.aggregate(10L)).thenReturn(row("COMPLETED", 3));
|
||||
assertThatThrownBy(() -> service.preloadDetail(10L, 100L))
|
||||
.isInstanceOfSatisfying(BizException.class, error ->
|
||||
assertThat(error.getResultCode()).isEqualTo(ResultCode.CONFLICT));
|
||||
|
||||
when(repository.aggregate(11L)).thenReturn(row("LOADING", 2));
|
||||
assertThatThrownBy(() -> service.confirmedDetail(11L, 100L))
|
||||
.isInstanceOfSatisfying(BizException.class, error ->
|
||||
assertThat(error.getResultCode()).isEqualTo(ResultCode.CONFLICT));
|
||||
|
||||
when(repository.aggregate(12L)).thenReturn(null);
|
||||
assertThatThrownBy(() -> service.lifecycle(12L, 100L))
|
||||
.isInstanceOfSatisfying(BizException.class, error ->
|
||||
assertThat(error.getResultCode()).isEqualTo(ResultCode.NOT_FOUND));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user