This commit is contained in:
2026-08-27 11:07:57 +08:00
parent b4c46280de
commit 4612181ab0
19 changed files with 424 additions and 68 deletions
@@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.PathVariable;
import java.lang.reflect.Method;
@@ -16,11 +17,26 @@ class WarehousePalletLocationClientContractTest {
assertThat(client.path()).isEqualTo("/internal/warehouse/v1");
Method method = WarehousePalletLocationClient.class.getDeclaredMethod(
"palletSnapshots", String.class, long.class);
"palletSnapshots", String.class, long.class, long.class, long.class, String.class);
assertThat(method.getAnnotation(GetMapping.class).value())
.containsExactly("/pallets/snapshots");
assertThat(method.getParameters()[1].getAnnotation(RequestParam.class).value())
.isEqualTo("warehouseId");
assertThat(method.getParameters()[2].getAnnotation(RequestParam.class).value())
.isEqualTo("page");
assertThat(method.getParameters()[3].getAnnotation(RequestParam.class).value())
.isEqualTo("size");
assertThat(method.getParameters()[4].getAnnotation(RequestParam.class).value())
.isEqualTo("keyword");
Method exact = WarehousePalletLocationClient.class.getDeclaredMethod(
"palletSnapshot", String.class, long.class, long.class);
assertThat(exact.getAnnotation(GetMapping.class).value())
.containsExactly("/pallets/{palletId}/snapshot");
assertThat(exact.getParameters()[1].getAnnotation(PathVariable.class).value())
.isEqualTo("palletId");
assertThat(exact.getParameters()[2].getAnnotation(RequestParam.class).value())
.isEqualTo("warehouseId");
var snapshot = new WarehousePalletLocationClient.PalletSnapshot(
101L, "PLT-101", "STANDARD", new java.math.BigDecimal("2.0000"),
@@ -6,10 +6,13 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.multipart.MultipartFile;
import java.lang.reflect.Method;
import java.lang.reflect.RecordComponent;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
@@ -17,6 +20,19 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
@DisplayName("平台入库测量接口权限契约")
class PlatformInboundMeasurementControllerContractTest {
@Test
void palletCandidatesArePaginatedAndBoundedInOpenApi() throws IOException {
String openapi = new ClassPathResource("openapi/firstleg-v1.yaml")
.getContentAsString(StandardCharsets.UTF_8);
assertThat(openapi)
.contains("/api/platform/v1/first-leg/inbounds/{inboundId}/weight-pallet-options:")
.contains("name: keyword")
.contains("maximum: 100")
.contains("maxItems: 100")
.contains("data: {$ref: '#/components/schemas/WeightPalletSnapshotPage'}");
}
@Test
void draftRequestOnlyAcceptsEditableGoodsNameAndMeasurementItems() {
assertThat(Arrays.stream(InboundMeasurementRequests.SaveDraftRequest.class.getRecordComponents())
@@ -41,7 +57,7 @@ class PlatformInboundMeasurementControllerContractTest {
assertAuthority("weightPalletOptions",
"hasAnyAuthority('platform:firstleg:inbound:measure:view',"
+ " 'platform:firstleg:inbound:weight:edit')",
AuthenticatedUser.class, long.class, long.class);
AuthenticatedUser.class, long.class, long.class, long.class, long.class, String.class);
assertAuthority("saveDraft", "hasAuthority('platform:firstleg:inbound:measure:edit')",
AuthenticatedUser.class, long.class, long.class,
InboundMeasurementRequests.SaveDraftRequest.class);
@@ -2,6 +2,7 @@ package com.baiyue.firstleg.service;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.common.core.api.ApiResponse;
import com.baiyue.common.core.api.PageResult;
import com.baiyue.firstleg.client.OrderCargoClient;
import com.baiyue.firstleg.client.MeasurementImageClient;
import com.baiyue.firstleg.client.WarehousePalletLocationClient;
@@ -59,8 +60,8 @@ class InboundMeasurementServiceTest {
@BeforeEach
void stubWarehousePalletSnapshots() {
when(repository.updateInboundWeightSummary(any())).thenReturn(true);
when(warehousePallets.palletSnapshots("internal-token", 100L)).thenReturn(
ApiResponse.success(List.of(palletSnapshot())));
when(warehousePallets.palletSnapshot("internal-token", 501L, 100L)).thenReturn(
ApiResponse.success(palletSnapshot()));
when(orderCargoClient.measurementDeclaration("internal-token", 1L, 80L)).thenReturn(
ApiResponse.success(new OrderCargoClient.MeasurementDeclarationSnapshot(
"REF-50", new BigDecimal("2000"), new BigDecimal("20"), "123123")));
@@ -238,20 +239,28 @@ class InboundMeasurementServiceTest {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
List<InboundMeasurementResponses.PalletSnapshot> result =
service.weightPalletOptions(1L, 10L);
when(warehousePallets.palletSnapshots("internal-token", 100L, 1L, 20L, "TP-5"))
.thenReturn(ApiResponse.success(new PageResult<>(List.of(palletSnapshot()), 1, 20, 1000, 50)));
assertThat(result).singleElement().satisfies(snapshot -> {
PageResult<InboundMeasurementResponses.PalletSnapshot> result =
service.weightPalletOptions(1L, 10L, 1L, 20L, "TP-5");
assertThat(result.records()).singleElement().satisfies(snapshot -> {
assertThat(snapshot.palletId()).isEqualTo(501L);
assertThat(snapshot.tareWeightKg()).isEqualByComparingTo("18.500");
});
verify(warehousePallets).palletSnapshots("internal-token", 100L);
assertThat(result.total()).isEqualTo(1000);
assertThat(result.records()).hasSize(1);
verify(warehousePallets).palletSnapshots("internal-token", 100L, 1L, 20L, "TP-5");
}
@Test
void creatingWeightResultRejectsPalletOutsideTheInboundWarehouse() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(warehousePallets.palletSnapshot("internal-token", 999L, 100L)).thenReturn(
ApiResponse.failure(com.baiyue.common.core.api.ResultCode.NOT_FOUND,
"所选托盘不属于当前入库仓库或当前不可用", null, null));
assertThatThrownBy(() -> service.createWeightResult(1L, 10L, 9L,
new InboundMeasurementRequests.CreateWeightResultRequest(
@@ -263,6 +272,29 @@ class InboundMeasurementServiceTest {
verify(repository, never()).insertWeight(any());
}
@Test
void detailUsesStoredPalletSnapshotAfterCandidateBecomesUnavailable() {
InboundOrderEntity inbound = inbound("WAIT_SPLIT");
InboundWeightResultEntity historical = weight(50L, "30.000", "KG", "CONFIRMED", 2);
historical.setPalletCode("HISTORICAL-501");
historical.setPalletType("LEGACY-STANDARD");
historical.setPalletTareWeightKg(new BigDecimal("18.500"));
historical.setGrossWeightKg(new BigDecimal("30.000"));
historical.setNetWeightKg(new BigDecimal("11.500"));
when(repository.findInbound(1L, 10L)).thenReturn(inbound);
when(repository.listWeights(1L, 10L)).thenReturn(List.of(historical));
InboundMeasurementResponses.Detail result = service.detail(1L, 10L);
assertThat(result.weightResults()).singleElement().satisfies(weight -> {
assertThat(weight.palletCode()).isEqualTo("HISTORICAL-501");
assertThat(weight.palletType()).isEqualTo("LEGACY-STANDARD");
assertThat(weight.palletTareWeightKg()).isEqualByComparingTo("18.500");
});
verify(warehousePallets, never()).palletSnapshot(any(), anyLong(), anyLong());
verify(warehousePallets, never()).palletSnapshots(any(), anyLong(), anyLong(), anyLong(), any());
}
@Test
void confirmingLbWeightConvertsToKgAndRecalculatesOnlyConfirmedImages() {
InboundOrderEntity inbound = inbound("WAIT_MEASURE");