This commit is contained in:
2026-09-15 14:18:18 +08:00
parent 6a2075fe4b
commit a474ca4d93
35 changed files with 751 additions and 228 deletions
@@ -4,6 +4,7 @@ import com.baiyue.common.core.exception.BizException;
import com.baiyue.common.security.AuthenticatedUser;
import com.baiyue.warehouse.entity.WarehouseLocationEntity;
import com.baiyue.warehouse.service.WarehouseResourceService;
import com.baiyue.warehouse.service.PalletLabelPrintService;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
@@ -17,6 +18,20 @@ import static org.mockito.Mockito.when;
class WarehouseResourceControllerTest {
private final WarehouseResourceService service = mock(WarehouseResourceService.class);
@Test
void palletLabelRejectsNonPublicPlatformScopeAndForwardsSelectedResource() {
var controller = platformController();
var labels = mock(PalletLabelPrintService.class);
ReflectionTestUtils.setField(controller, "palletLabels", labels);
assertThatThrownBy(() -> controller.palletLabel(user(10001L, "MERCHANT"), 200L, 9L, "r1"))
.isInstanceOf(BizException.class);
assertThatThrownBy(() -> controller.palletLabel(user(10001L, "PLATFORM"), 200L, 9L, "r1"))
.isInstanceOf(BizException.class);
org.mockito.Mockito.verifyNoInteractions(labels);
controller.palletLabel(user(0L, "PLATFORM"), 200L, 9L, "r1");
verify(labels).print(200L, 9L, "r1");
}
@Test
void merchantTenantAlwaysComesFromAuthenticatedUser() {
MerchantWarehouseResourceController controller = merchantController();
@@ -27,6 +27,7 @@ class WarehouseResourcePermissionContractTest {
assertPermission(methods.get("deleteLocation"), PREFIX + "location:delete");
assertPermission(methods.get("pallets"), PREFIX + "pallet:list");
assertPermission(methods.get("pallet"), PREFIX + "pallet:list");
assertPermission(methods.get("palletLabel"), PREFIX + "pallet:list");
assertPermission(methods.get("createPallet"), PREFIX + "pallet:create");
assertPermission(methods.get("updatePallet"), PREFIX + "pallet:edit");
assertPermission(methods.get("deletePallet"), PREFIX + "pallet:delete");
@@ -0,0 +1,86 @@
package com.baiyue.warehouse.service;
import com.baiyue.common.core.api.ResultCode;
import com.baiyue.common.core.exception.BizException;
import com.baiyue.warehouse.client.PrintPdfClient;
import com.baiyue.warehouse.dto.SharedWarehouseReference;
import com.baiyue.warehouse.entity.WarehousePalletEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
class PalletLabelPrintServiceTest {
private final WarehouseResourceService resources = mock(WarehouseResourceService.class);
private final DomesticWarehouseDirectory warehouses = mock(DomesticWarehouseDirectory.class);
private final PrintPdfClient print = mock(PrintPdfClient.class);
private final PalletLabelPrintService service = new PalletLabelPrintService();
private final WarehousePalletEntity pallet = new WarehousePalletEntity();
@BeforeEach
void setup() {
ReflectionTestUtils.setField(service, "resources", resources);
ReflectionTestUtils.setField(service, "warehouses", warehouses);
ReflectionTestUtils.setField(service, "print", print);
ReflectionTestUtils.setField(service, "internalToken", "test-token");
pallet.setPalletCode("ABCD1234567-ABE3-003");
pallet.setFbaWarehouseCode("ABE3");
when(resources.pallet(0L, 200L, 9L)).thenReturn(pallet);
when(warehouses.required(200L)).thenReturn(new SharedWarehouseReference(200L, "LAX", "洛杉矶仓", "ACTIVE"));
}
@Test
void reusesExistingRendererWithExactlyTheSelectedCode() {
byte[] pdf = "%PDF-label".getBytes(java.nio.charset.StandardCharsets.US_ASCII);
when(print.generateInboundMarks(anyString(), anyString(), any()))
.thenReturn(ResponseEntity.ok().contentType(MediaType.APPLICATION_PDF).body(pdf));
var response = service.print(200L, 9L, "request-1");
var request = ArgumentCaptor.forClass(PrintPdfClient.Request.class);
verify(print).generateInboundMarks(eq("test-token"), eq("request-1"), request.capture());
assertThat(request.getValue().templateCode()).isEqualTo("INBOUND_MARK_V1");
assertThat(request.getValue().pageSpec().widthMm()).isEqualByComparingTo("100");
assertThat(request.getValue().pageSpec().heightMm()).isEqualByComparingTo("100");
assertThat(request.getValue().labels()).singleElement().satisfies(label -> {
assertThat(label.topCode()).isEqualTo("ABCD1234567-ABE3-003");
assertThat(label.qrContent()).isEqualTo(label.topCode());
assertThat(label.warehouseText()).isEqualTo("ABE3");
assertThat(label.routeText()).isEqualTo("洛杉矶仓");
});
assertThat(response.getBody()).isEqualTo(pdf);
verify(resources).pallet(0L, 200L, 9L);
verifyNoMoreInteractions(resources);
}
@Test
void refusesWrongWarehouseBeforeCallingPrint() {
when(resources.pallet(0L, 201L, 9L)).thenThrow(new BizException(ResultCode.NOT_FOUND, "托盘不存在"));
assertThatThrownBy(() -> service.print(201L, 9L, "request-1")).isInstanceOf(BizException.class);
verifyNoInteractions(print);
}
@Test
void rejectsJsonErrorInsteadOfDownloadingItAsPdf() {
when(print.generateInboundMarks(anyString(), anyString(), any()))
.thenReturn(ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body("{}".getBytes()));
assertThatThrownBy(() -> service.print(200L, 9L, "request-1"))
.isInstanceOf(BizException.class).hasMessageContaining("有效 PDF");
}
@Test
void neverTruncatesOrSubstitutesUnsupportedPalletCodes() {
for (String code : new String[] { "", "托盘001", "A".repeat(35) }) {
pallet.setPalletCode(code);
assertThatThrownBy(() -> service.print(200L, 9L, "request-1"))
.isInstanceOf(BizException.class).hasMessageContaining("托盘编码");
}
verifyNoInteractions(print);
}
}